1 /****************************************************************************** 2 * 3 * Module Name: aemain - Main routine for the AcpiExec utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aecommon.h" 45 46 #define _COMPONENT ACPI_TOOLS 47 ACPI_MODULE_NAME ("aemain") 48 49 50 /* 51 * Main routine for the ACPI user-space execution utility. 52 * 53 * Portability note: The utility depends upon the host for command-line 54 * wildcard support - it is not implemented locally. For example: 55 * 56 * Linux/Unix systems: Shell expands wildcards automatically. 57 * 58 * Windows: The setargv.obj module must be linked in to automatically 59 * expand wildcards. 60 */ 61 extern BOOLEAN AcpiGbl_DebugTimeout; 62 63 /* Local prototypes */ 64 65 static int 66 AeDoOptions ( 67 int argc, 68 char **argv); 69 70 static ACPI_STATUS 71 AcpiDbRunBatchMode ( 72 void); 73 74 75 #define AE_BUFFER_SIZE 1024 76 #define ASL_MAX_FILES 256 77 78 /* Execution modes */ 79 80 #define AE_MODE_COMMAND_LOOP 0 /* Normal command execution loop */ 81 #define AE_MODE_BATCH_MULTIPLE 1 /* -b option to execute a command line */ 82 #define AE_MODE_BATCH_SINGLE 2 /* -m option to execute a single control method */ 83 84 85 /* Globals */ 86 87 UINT8 AcpiGbl_RegionFillValue = 0; 88 BOOLEAN AcpiGbl_IgnoreErrors = FALSE; 89 BOOLEAN AcpiGbl_DbOpt_NoRegionSupport = FALSE; 90 UINT8 AcpiGbl_UseHwReducedFadt = FALSE; 91 BOOLEAN AcpiGbl_DoInterfaceTests = FALSE; 92 BOOLEAN AcpiGbl_LoadTestTables = FALSE; 93 static UINT8 AcpiGbl_ExecutionMode = AE_MODE_COMMAND_LOOP; 94 static char BatchBuffer[AE_BUFFER_SIZE]; /* Batch command buffer */ 95 static AE_TABLE_DESC *AeTableListHead = NULL; 96 97 #define ACPIEXEC_NAME "AML Execution/Debug Utility" 98 #define AE_SUPPORTED_OPTIONS "?b:d:e:f:ghm^orv^:x:" 99 100 101 /****************************************************************************** 102 * 103 * FUNCTION: usage 104 * 105 * PARAMETERS: None 106 * 107 * RETURN: None 108 * 109 * DESCRIPTION: Print a usage message 110 * 111 *****************************************************************************/ 112 113 static void 114 usage ( 115 void) 116 { 117 118 ACPI_USAGE_HEADER ("acpiexec [options] AMLfile1 AMLfile2 ..."); 119 120 ACPI_OPTION ("-b \"CommandLine\"", "Batch mode command line execution (cmd1;cmd2;...)"); 121 ACPI_OPTION ("-h -?", "Display this help message"); 122 ACPI_OPTION ("-m [Method]", "Batch mode method execution. Default=MAIN"); 123 printf ("\n"); 124 125 ACPI_OPTION ("-da", "Disable method abort on error"); 126 ACPI_OPTION ("-di", "Disable execution of STA/INI methods during init"); 127 ACPI_OPTION ("-do", "Disable Operation Region address simulation"); 128 ACPI_OPTION ("-dr", "Disable repair of method return values"); 129 ACPI_OPTION ("-ds", "Disable method auto-serialization"); 130 ACPI_OPTION ("-dt", "Disable allocation tracking (performance)"); 131 printf ("\n"); 132 133 ACPI_OPTION ("-ef", "Enable display of final memory statistics"); 134 ACPI_OPTION ("-ei", "Enable additional tests for ACPICA interfaces"); 135 ACPI_OPTION ("-el", "Enable loading of additional test tables"); 136 ACPI_OPTION ("-es", "Enable Interpreter Slack Mode"); 137 ACPI_OPTION ("-et", "Enable debug semaphore timeout"); 138 printf ("\n"); 139 140 ACPI_OPTION ("-f <Value>", "Operation Region initialization fill value"); 141 ACPI_OPTION ("-r", "Use hardware-reduced FADT V5"); 142 ACPI_OPTION ("-v", "Display version information"); 143 ACPI_OPTION ("-vi", "Verbose initialization output"); 144 ACPI_OPTION ("-vr", "Verbose region handler output"); 145 ACPI_OPTION ("-x <DebugLevel>", "Debug output level"); 146 } 147 148 149 /****************************************************************************** 150 * 151 * FUNCTION: AeDoOptions 152 * 153 * PARAMETERS: argc/argv - Standard argc/argv 154 * 155 * RETURN: Status 156 * 157 * DESCRIPTION: Command line option processing 158 * 159 *****************************************************************************/ 160 161 static int 162 AeDoOptions ( 163 int argc, 164 char **argv) 165 { 166 int j; 167 168 169 while ((j = AcpiGetopt (argc, argv, AE_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) 170 { 171 case 'b': 172 173 if (strlen (AcpiGbl_Optarg) > (AE_BUFFER_SIZE -1)) 174 { 175 printf ("**** The length of command line (%u) exceeded maximum (%u)\n", 176 (UINT32) strlen (AcpiGbl_Optarg), (AE_BUFFER_SIZE -1)); 177 return (-1); 178 } 179 AcpiGbl_ExecutionMode = AE_MODE_BATCH_MULTIPLE; 180 strcpy (BatchBuffer, AcpiGbl_Optarg); 181 break; 182 183 case 'd': 184 185 switch (AcpiGbl_Optarg[0]) 186 { 187 case 'a': 188 189 AcpiGbl_IgnoreErrors = TRUE; 190 break; 191 192 case 'i': 193 194 AcpiGbl_DbOpt_ini_methods = FALSE; 195 break; 196 197 case 'o': 198 199 AcpiGbl_DbOpt_NoRegionSupport = TRUE; 200 break; 201 202 case 'r': 203 204 AcpiGbl_DisableAutoRepair = TRUE; 205 break; 206 207 case 's': 208 209 AcpiGbl_AutoSerializeMethods = FALSE; 210 break; 211 212 case 't': 213 214 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 215 AcpiGbl_DisableMemTracking = TRUE; 216 #endif 217 break; 218 219 default: 220 221 printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); 222 return (-1); 223 } 224 break; 225 226 case 'e': 227 228 switch (AcpiGbl_Optarg[0]) 229 { 230 case 'f': 231 232 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 233 AcpiGbl_DisplayFinalMemStats = TRUE; 234 #endif 235 break; 236 237 case 'i': 238 239 AcpiGbl_DoInterfaceTests = TRUE; 240 break; 241 242 case 'l': 243 244 AcpiGbl_LoadTestTables = TRUE; 245 break; 246 247 case 's': 248 249 AcpiGbl_EnableInterpreterSlack = TRUE; 250 printf ("Enabling AML Interpreter slack mode\n"); 251 break; 252 253 case 't': 254 255 AcpiGbl_DebugTimeout = TRUE; 256 break; 257 258 default: 259 260 printf ("Unknown option: -e%s\n", AcpiGbl_Optarg); 261 return (-1); 262 } 263 break; 264 265 case 'f': 266 267 AcpiGbl_RegionFillValue = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 268 break; 269 270 case 'g': 271 272 AcpiGbl_DbOpt_tables = TRUE; 273 AcpiGbl_DbFilename = NULL; 274 break; 275 276 case 'h': 277 case '?': 278 279 usage(); 280 return (0); 281 282 case 'm': 283 284 AcpiGbl_ExecutionMode = AE_MODE_BATCH_SINGLE; 285 switch (AcpiGbl_Optarg[0]) 286 { 287 case '^': 288 289 strcpy (BatchBuffer, "MAIN"); 290 break; 291 292 default: 293 294 strcpy (BatchBuffer, AcpiGbl_Optarg); 295 break; 296 } 297 break; 298 299 case 'o': 300 301 AcpiGbl_DbOpt_disasm = TRUE; 302 AcpiGbl_DbOpt_stats = TRUE; 303 break; 304 305 case 'r': 306 307 AcpiGbl_UseHwReducedFadt = TRUE; 308 printf ("Using ACPI 5.0 Hardware Reduced Mode via version 5 FADT\n"); 309 break; 310 311 case 'v': 312 313 switch (AcpiGbl_Optarg[0]) 314 { 315 case '^': /* -v: (Version): signon already emitted, just exit */ 316 317 (void) AcpiOsTerminate (); 318 exit (0); 319 320 case 'i': 321 322 AcpiDbgLevel |= ACPI_LV_INIT_NAMES; 323 break; 324 325 case 'r': 326 327 AcpiGbl_DisplayRegionAccess = TRUE; 328 break; 329 330 default: 331 332 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 333 return (-1); 334 } 335 break; 336 337 case 'x': 338 339 AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 0); 340 AcpiGbl_DbConsoleDebugLevel = AcpiDbgLevel; 341 printf ("Debug Level: 0x%8.8X\n", AcpiDbgLevel); 342 break; 343 344 default: 345 346 usage(); 347 return (-1); 348 } 349 350 return (0); 351 } 352 353 354 /****************************************************************************** 355 * 356 * FUNCTION: main 357 * 358 * PARAMETERS: argc, argv 359 * 360 * RETURN: Status 361 * 362 * DESCRIPTION: Main routine for AcpiExec utility 363 * 364 *****************************************************************************/ 365 366 int ACPI_SYSTEM_XFACE 367 main ( 368 int argc, 369 char **argv) 370 { 371 ACPI_STATUS Status; 372 UINT32 InitFlags; 373 ACPI_TABLE_HEADER *Table = NULL; 374 UINT32 TableCount; 375 AE_TABLE_DESC *TableDesc; 376 377 378 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 379 signal (SIGINT, AeCtrlCHandler); 380 381 /* Init debug globals */ 382 383 AcpiDbgLevel = ACPI_NORMAL_DEFAULT; 384 AcpiDbgLayer = 0xFFFFFFFF; 385 386 /* Init ACPICA and start debugger thread */ 387 388 Status = AcpiInitializeSubsystem (); 389 AE_CHECK_OK (AcpiInitializeSubsystem, Status); 390 if (ACPI_FAILURE (Status)) 391 { 392 goto ErrorExit; 393 } 394 395 printf (ACPI_COMMON_SIGNON (ACPIEXEC_NAME)); 396 if (argc < 2) 397 { 398 usage (); 399 (void) AcpiOsTerminate (); 400 return (0); 401 } 402 403 /* Get the command line options */ 404 405 if (AeDoOptions (argc, argv)) 406 { 407 goto ErrorExit; 408 } 409 410 /* The remaining arguments are filenames for ACPI tables */ 411 412 if (!argv[AcpiGbl_Optind]) 413 { 414 goto EnterDebugger; 415 } 416 417 AcpiGbl_DbOpt_tables = TRUE; 418 TableCount = 0; 419 420 /* Get each of the ACPI table files on the command line */ 421 422 while (argv[AcpiGbl_Optind]) 423 { 424 /* Get one entire table */ 425 426 Status = AcpiUtReadTableFromFile (argv[AcpiGbl_Optind], &Table); 427 if (ACPI_FAILURE (Status)) 428 { 429 printf ("**** Could not get table from file %s, %s\n", 430 argv[AcpiGbl_Optind], AcpiFormatException (Status)); 431 goto ErrorExit; 432 } 433 434 /* Ignore non-AML tables, we can't use them. Except for an FADT */ 435 436 if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FADT) && 437 !AcpiUtIsAmlTable (Table)) 438 { 439 ACPI_INFO ((AE_INFO, 440 "Table [%4.4s] is not an AML table, ignoring", 441 Table->Signature)); 442 AcpiOsFree (Table); 443 } 444 else 445 { 446 /* Allocate and link a table descriptor */ 447 448 TableDesc = AcpiOsAllocate (sizeof (AE_TABLE_DESC)); 449 TableDesc->Table = Table; 450 TableDesc->Next = AeTableListHead; 451 AeTableListHead = TableDesc; 452 453 TableCount++; 454 } 455 456 AcpiGbl_Optind++; 457 } 458 459 printf ("\n"); 460 461 /* Build a local RSDT with all tables and let ACPICA process the RSDT */ 462 463 Status = AeBuildLocalTables (TableCount, AeTableListHead); 464 if (ACPI_FAILURE (Status)) 465 { 466 goto ErrorExit; 467 } 468 469 Status = AeInstallTables (); 470 if (ACPI_FAILURE (Status)) 471 { 472 printf ("**** Could not load ACPI tables, %s\n", 473 AcpiFormatException (Status)); 474 goto EnterDebugger; 475 } 476 477 /* 478 * Install most of the handlers. 479 * Override some default region handlers, especially SystemMemory 480 */ 481 Status = AeInstallEarlyHandlers (); 482 if (ACPI_FAILURE (Status)) 483 { 484 goto EnterDebugger; 485 } 486 487 /* Setup initialization flags for ACPICA */ 488 489 InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); 490 if (!AcpiGbl_DbOpt_ini_methods) 491 { 492 InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); 493 } 494 495 /* 496 * Main initialization for ACPICA subsystem 497 * TBD: Need a way to call this after the ACPI table "LOAD" command 498 */ 499 Status = AcpiEnableSubsystem (InitFlags); 500 if (ACPI_FAILURE (Status)) 501 { 502 printf ("**** Could not EnableSubsystem, %s\n", 503 AcpiFormatException (Status)); 504 goto EnterDebugger; 505 } 506 507 /* 508 * Install handlers for "device driver" space IDs (EC,SMBus, etc.) 509 * and fixed event handlers 510 */ 511 AeInstallLateHandlers (); 512 513 /* Finish the ACPICA initialization */ 514 515 Status = AcpiInitializeObjects (InitFlags); 516 if (ACPI_FAILURE (Status)) 517 { 518 printf ("**** Could not InitializeObjects, %s\n", 519 AcpiFormatException (Status)); 520 goto EnterDebugger; 521 } 522 523 AeMiscellaneousTests (); 524 525 526 EnterDebugger: 527 528 /* Exit if error above and we are in one of the batch modes */ 529 530 if (ACPI_FAILURE (Status) && (AcpiGbl_ExecutionMode > 0)) 531 { 532 goto ErrorExit; 533 } 534 535 /* Run a batch command or enter the command loop */ 536 537 switch (AcpiGbl_ExecutionMode) 538 { 539 default: 540 case AE_MODE_COMMAND_LOOP: 541 542 AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL); 543 break; 544 545 case AE_MODE_BATCH_MULTIPLE: 546 547 AcpiDbRunBatchMode (); 548 break; 549 550 case AE_MODE_BATCH_SINGLE: 551 552 AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); 553 Status = AcpiTerminate (); 554 break; 555 } 556 557 return (0); 558 559 560 ErrorExit: 561 562 (void) AcpiOsTerminate (); 563 return (-1); 564 } 565 566 567 /****************************************************************************** 568 * 569 * FUNCTION: AcpiDbRunBatchMode 570 * 571 * PARAMETERS: BatchCommandLine - A semicolon separated list of commands 572 * to be executed. 573 * Use only commas to separate elements of 574 * particular command. 575 * RETURN: Status 576 * 577 * DESCRIPTION: For each command of list separated by ';' prepare the command 578 * buffer and pass it to AcpiDbCommandDispatch. 579 * 580 *****************************************************************************/ 581 582 static ACPI_STATUS 583 AcpiDbRunBatchMode ( 584 void) 585 { 586 ACPI_STATUS Status; 587 char *Ptr = BatchBuffer; 588 char *Cmd = Ptr; 589 UINT8 Run = 0; 590 591 592 AcpiGbl_MethodExecuting = FALSE; 593 AcpiGbl_StepToNextCall = FALSE; 594 595 while (*Ptr) 596 { 597 if (*Ptr == ',') 598 { 599 /* Convert commas to spaces */ 600 *Ptr = ' '; 601 } 602 else if (*Ptr == ';') 603 { 604 *Ptr = '\0'; 605 Run = 1; 606 } 607 608 Ptr++; 609 610 if (Run || (*Ptr == '\0')) 611 { 612 (void) AcpiDbCommandDispatch (Cmd, NULL, NULL); 613 Run = 0; 614 Cmd = Ptr; 615 } 616 } 617 618 Status = AcpiTerminate (); 619 return (Status); 620 } 621