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 /* Stubs for the disassembler */ 102 103 void 104 MpSaveGpioInfo ( 105 ACPI_PARSE_OBJECT *Op, 106 AML_RESOURCE *Resource, 107 UINT32 PinCount, 108 UINT16 *PinList, 109 char *DeviceName) 110 { 111 } 112 113 void 114 MpSaveSerialInfo ( 115 ACPI_PARSE_OBJECT *Op, 116 AML_RESOURCE *Resource, 117 char *DeviceName) 118 { 119 } 120 121 122 /****************************************************************************** 123 * 124 * FUNCTION: usage 125 * 126 * PARAMETERS: None 127 * 128 * RETURN: None 129 * 130 * DESCRIPTION: Print a usage message 131 * 132 *****************************************************************************/ 133 134 static void 135 usage ( 136 void) 137 { 138 139 ACPI_USAGE_HEADER ("acpiexec [options] AMLfile1 AMLfile2 ..."); 140 141 ACPI_OPTION ("-b \"CommandLine\"", "Batch mode command line execution (cmd1;cmd2;...)"); 142 ACPI_OPTION ("-h -?", "Display this help message"); 143 ACPI_OPTION ("-m [Method]", "Batch mode method execution. Default=MAIN"); 144 printf ("\n"); 145 146 ACPI_OPTION ("-da", "Disable method abort on error"); 147 ACPI_OPTION ("-di", "Disable execution of STA/INI methods during init"); 148 ACPI_OPTION ("-do", "Disable Operation Region address simulation"); 149 ACPI_OPTION ("-dr", "Disable repair of method return values"); 150 ACPI_OPTION ("-ds", "Disable method auto-serialization"); 151 ACPI_OPTION ("-dt", "Disable allocation tracking (performance)"); 152 printf ("\n"); 153 154 ACPI_OPTION ("-ef", "Enable display of final memory statistics"); 155 ACPI_OPTION ("-ei", "Enable additional tests for ACPICA interfaces"); 156 ACPI_OPTION ("-el", "Enable loading of additional test tables"); 157 ACPI_OPTION ("-es", "Enable Interpreter Slack Mode"); 158 ACPI_OPTION ("-et", "Enable debug semaphore timeout"); 159 printf ("\n"); 160 161 ACPI_OPTION ("-fv <Value>", "Operation Region initialization fill value"); 162 ACPI_OPTION ("-fi <file>", "Specify namespace initialization file"); 163 ACPI_OPTION ("-r", "Use hardware-reduced FADT V5"); 164 ACPI_OPTION ("-v", "Display version information"); 165 ACPI_OPTION ("-vi", "Verbose initialization output"); 166 ACPI_OPTION ("-vr", "Verbose region handler output"); 167 ACPI_OPTION ("-x <DebugLevel>", "Debug output level"); 168 169 printf ("\n From within the interactive mode, use '?' or \"help\" to see\n" 170 " a list of available AML Debugger commands\n"); 171 } 172 173 174 /****************************************************************************** 175 * 176 * FUNCTION: AeDoOptions 177 * 178 * PARAMETERS: argc/argv - Standard argc/argv 179 * 180 * RETURN: Status 181 * 182 * DESCRIPTION: Command line option processing 183 * 184 *****************************************************************************/ 185 186 static int 187 AeDoOptions ( 188 int argc, 189 char **argv) 190 { 191 int j; 192 193 194 while ((j = AcpiGetopt (argc, argv, AE_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) 195 { 196 case 'b': 197 198 if (strlen (AcpiGbl_Optarg) > (AE_BUFFER_SIZE -1)) 199 { 200 printf ("**** The length of command line (%u) exceeded maximum (%u)\n", 201 (UINT32) strlen (AcpiGbl_Optarg), (AE_BUFFER_SIZE -1)); 202 return (-1); 203 } 204 AcpiGbl_ExecutionMode = AE_MODE_BATCH_MULTIPLE; 205 strcpy (BatchBuffer, AcpiGbl_Optarg); 206 break; 207 208 case 'd': 209 210 switch (AcpiGbl_Optarg[0]) 211 { 212 case 'a': 213 214 AcpiGbl_IgnoreErrors = TRUE; 215 break; 216 217 case 'i': 218 219 AcpiGbl_DbOpt_ini_methods = FALSE; 220 break; 221 222 case 'o': 223 224 AcpiGbl_DbOpt_NoRegionSupport = TRUE; 225 break; 226 227 case 'r': 228 229 AcpiGbl_DisableAutoRepair = TRUE; 230 break; 231 232 case 's': 233 234 AcpiGbl_AutoSerializeMethods = FALSE; 235 break; 236 237 case 't': 238 239 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 240 AcpiGbl_DisableMemTracking = TRUE; 241 #endif 242 break; 243 244 default: 245 246 printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); 247 return (-1); 248 } 249 break; 250 251 case 'e': 252 253 switch (AcpiGbl_Optarg[0]) 254 { 255 case 'f': 256 257 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 258 AcpiGbl_DisplayFinalMemStats = TRUE; 259 #endif 260 break; 261 262 case 'i': 263 264 AcpiGbl_DoInterfaceTests = TRUE; 265 break; 266 267 case 'l': 268 269 AcpiGbl_LoadTestTables = TRUE; 270 break; 271 272 case 's': 273 274 AcpiGbl_EnableInterpreterSlack = TRUE; 275 printf ("Enabling AML Interpreter slack mode\n"); 276 break; 277 278 case 't': 279 280 AcpiGbl_DebugTimeout = TRUE; 281 break; 282 283 default: 284 285 printf ("Unknown option: -e%s\n", AcpiGbl_Optarg); 286 return (-1); 287 } 288 break; 289 290 case 'f': 291 292 switch (AcpiGbl_Optarg[0]) 293 { 294 case 'v': /* -fv: region fill value */ 295 296 if (AcpiGetoptArgument (argc, argv)) 297 { 298 return (-1); 299 } 300 301 AcpiGbl_RegionFillValue = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 302 break; 303 304 case 'i': /* -fi: specify initialization file */ 305 306 if (AcpiGetoptArgument (argc, argv)) 307 { 308 return (-1); 309 } 310 311 if (AeOpenInitializationFile (AcpiGbl_Optarg)) 312 { 313 return (-1); 314 } 315 break; 316 317 default: 318 319 printf ("Unknown option: -f%s\n", AcpiGbl_Optarg); 320 return (-1); 321 } 322 break; 323 324 case 'g': 325 326 AcpiGbl_DbOpt_tables = TRUE; 327 AcpiGbl_DbFilename = NULL; 328 break; 329 330 case 'h': 331 case '?': 332 333 usage(); 334 return (0); 335 336 case 'm': 337 338 AcpiGbl_ExecutionMode = AE_MODE_BATCH_SINGLE; 339 switch (AcpiGbl_Optarg[0]) 340 { 341 case '^': 342 343 strcpy (BatchBuffer, "MAIN"); 344 break; 345 346 default: 347 348 strcpy (BatchBuffer, AcpiGbl_Optarg); 349 break; 350 } 351 break; 352 353 case 'o': 354 355 AcpiGbl_DbOpt_disasm = TRUE; 356 AcpiGbl_DbOpt_stats = TRUE; 357 break; 358 359 case 'r': 360 361 AcpiGbl_UseHwReducedFadt = TRUE; 362 printf ("Using ACPI 5.0 Hardware Reduced Mode via version 5 FADT\n"); 363 break; 364 365 case 'v': 366 367 switch (AcpiGbl_Optarg[0]) 368 { 369 case '^': /* -v: (Version): signon already emitted, just exit */ 370 371 (void) AcpiOsTerminate (); 372 exit (0); 373 374 case 'i': 375 376 AcpiDbgLevel |= ACPI_LV_INIT_NAMES; 377 break; 378 379 case 'r': 380 381 AcpiGbl_DisplayRegionAccess = TRUE; 382 break; 383 384 default: 385 386 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 387 return (-1); 388 } 389 break; 390 391 case 'x': 392 393 AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 0); 394 AcpiGbl_DbConsoleDebugLevel = AcpiDbgLevel; 395 printf ("Debug Level: 0x%8.8X\n", AcpiDbgLevel); 396 break; 397 398 default: 399 400 usage(); 401 return (-1); 402 } 403 404 return (0); 405 } 406 407 408 /****************************************************************************** 409 * 410 * FUNCTION: main 411 * 412 * PARAMETERS: argc, argv 413 * 414 * RETURN: Status 415 * 416 * DESCRIPTION: Main routine for AcpiExec utility 417 * 418 *****************************************************************************/ 419 420 int ACPI_SYSTEM_XFACE 421 main ( 422 int argc, 423 char **argv) 424 { 425 ACPI_STATUS Status; 426 UINT32 InitFlags; 427 ACPI_TABLE_HEADER *Table = NULL; 428 UINT32 TableCount; 429 AE_TABLE_DESC *TableDesc; 430 431 432 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 433 signal (SIGINT, AeCtrlCHandler); 434 435 /* Init debug globals */ 436 437 AcpiDbgLevel = ACPI_NORMAL_DEFAULT; 438 AcpiDbgLayer = 0xFFFFFFFF; 439 440 /* Init ACPICA and start debugger thread */ 441 442 Status = AcpiInitializeSubsystem (); 443 AE_CHECK_OK (AcpiInitializeSubsystem, Status); 444 if (ACPI_FAILURE (Status)) 445 { 446 goto ErrorExit; 447 } 448 449 printf (ACPI_COMMON_SIGNON (ACPIEXEC_NAME)); 450 if (argc < 2) 451 { 452 usage (); 453 (void) AcpiOsTerminate (); 454 return (0); 455 } 456 457 /* Get the command line options */ 458 459 if (AeDoOptions (argc, argv)) 460 { 461 goto ErrorExit; 462 } 463 464 /* The remaining arguments are filenames for ACPI tables */ 465 466 if (!argv[AcpiGbl_Optind]) 467 { 468 goto EnterDebugger; 469 } 470 471 AcpiGbl_DbOpt_tables = TRUE; 472 AcpiGbl_CstyleDisassembly = FALSE; /* Not supported for AcpiExec */ 473 TableCount = 0; 474 475 /* Get each of the ACPI table files on the command line */ 476 477 while (argv[AcpiGbl_Optind]) 478 { 479 /* Get one entire table */ 480 481 Status = AcpiUtReadTableFromFile (argv[AcpiGbl_Optind], &Table); 482 if (ACPI_FAILURE (Status)) 483 { 484 printf ("**** Could not get table from file %s, %s\n", 485 argv[AcpiGbl_Optind], AcpiFormatException (Status)); 486 goto ErrorExit; 487 } 488 489 /* Ignore non-AML tables, we can't use them. Except for an FADT */ 490 491 if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FADT) && 492 !AcpiUtIsAmlTable (Table)) 493 { 494 ACPI_INFO ((AE_INFO, 495 "Table [%4.4s] is not an AML table, ignoring", 496 Table->Signature)); 497 AcpiOsFree (Table); 498 } 499 else 500 { 501 /* Allocate and link a table descriptor */ 502 503 TableDesc = AcpiOsAllocate (sizeof (AE_TABLE_DESC)); 504 TableDesc->Table = Table; 505 TableDesc->Next = AeTableListHead; 506 AeTableListHead = TableDesc; 507 508 TableCount++; 509 } 510 511 AcpiGbl_Optind++; 512 } 513 514 printf ("\n"); 515 516 /* Build a local RSDT with all tables and let ACPICA process the RSDT */ 517 518 Status = AeBuildLocalTables (TableCount, AeTableListHead); 519 if (ACPI_FAILURE (Status)) 520 { 521 goto ErrorExit; 522 } 523 524 Status = AeInstallTables (); 525 if (ACPI_FAILURE (Status)) 526 { 527 printf ("**** Could not load ACPI tables, %s\n", 528 AcpiFormatException (Status)); 529 goto EnterDebugger; 530 } 531 532 /* 533 * Install most of the handlers. 534 * Override some default region handlers, especially SystemMemory 535 */ 536 Status = AeInstallEarlyHandlers (); 537 if (ACPI_FAILURE (Status)) 538 { 539 goto EnterDebugger; 540 } 541 542 /* Setup initialization flags for ACPICA */ 543 544 InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); 545 if (!AcpiGbl_DbOpt_ini_methods) 546 { 547 InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); 548 } 549 550 /* 551 * Main initialization for ACPICA subsystem 552 * TBD: Need a way to call this after the ACPI table "LOAD" command 553 */ 554 Status = AcpiEnableSubsystem (InitFlags); 555 if (ACPI_FAILURE (Status)) 556 { 557 printf ("**** Could not EnableSubsystem, %s\n", 558 AcpiFormatException (Status)); 559 goto EnterDebugger; 560 } 561 562 /* 563 * Install handlers for "device driver" space IDs (EC,SMBus, etc.) 564 * and fixed event handlers 565 */ 566 AeInstallLateHandlers (); 567 568 /* Finish the ACPICA initialization */ 569 570 Status = AcpiInitializeObjects (InitFlags); 571 if (ACPI_FAILURE (Status)) 572 { 573 printf ("**** Could not InitializeObjects, %s\n", 574 AcpiFormatException (Status)); 575 goto EnterDebugger; 576 } 577 578 AeMiscellaneousTests (); 579 580 581 EnterDebugger: 582 583 /* Exit if error above and we are in one of the batch modes */ 584 585 if (ACPI_FAILURE (Status) && (AcpiGbl_ExecutionMode > 0)) 586 { 587 goto ErrorExit; 588 } 589 590 /* Run a batch command or enter the command loop */ 591 592 switch (AcpiGbl_ExecutionMode) 593 { 594 default: 595 case AE_MODE_COMMAND_LOOP: 596 597 AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL); 598 break; 599 600 case AE_MODE_BATCH_MULTIPLE: 601 602 AcpiDbRunBatchMode (); 603 break; 604 605 case AE_MODE_BATCH_SINGLE: 606 607 AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); 608 Status = AcpiTerminate (); 609 break; 610 } 611 612 return (0); 613 614 615 ErrorExit: 616 (void) AcpiOsTerminate (); 617 return (-1); 618 } 619 620 621 /****************************************************************************** 622 * 623 * FUNCTION: AcpiDbRunBatchMode 624 * 625 * PARAMETERS: BatchCommandLine - A semicolon separated list of commands 626 * to be executed. 627 * Use only commas to separate elements of 628 * particular command. 629 * RETURN: Status 630 * 631 * DESCRIPTION: For each command of list separated by ';' prepare the command 632 * buffer and pass it to AcpiDbCommandDispatch. 633 * 634 *****************************************************************************/ 635 636 static ACPI_STATUS 637 AcpiDbRunBatchMode ( 638 void) 639 { 640 ACPI_STATUS Status; 641 char *Ptr = BatchBuffer; 642 char *Cmd = Ptr; 643 UINT8 Run = 0; 644 645 646 AcpiGbl_MethodExecuting = FALSE; 647 AcpiGbl_StepToNextCall = FALSE; 648 649 while (*Ptr) 650 { 651 if (*Ptr == ',') 652 { 653 /* Convert commas to spaces */ 654 *Ptr = ' '; 655 } 656 else if (*Ptr == ';') 657 { 658 *Ptr = '\0'; 659 Run = 1; 660 } 661 662 Ptr++; 663 664 if (Run || (*Ptr == '\0')) 665 { 666 (void) AcpiDbCommandDispatch (Cmd, NULL, NULL); 667 Run = 0; 668 Cmd = Ptr; 669 } 670 } 671 672 Status = AcpiTerminate (); 673 return (Status); 674 } 675