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