1 /****************************************************************************** 2 * 3 * Module Name: aemain - Main routine for the AcpiExec utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 #include "errno.h" 46 47 #define _COMPONENT ACPI_TOOLS 48 ACPI_MODULE_NAME ("aemain") 49 50 51 /* 52 * Main routine for the ACPI user-space execution utility. 53 * 54 * Portability note: The utility depends upon the host for command-line 55 * wildcard support - it is not implemented locally. For example: 56 * 57 * Linux/Unix systems: Shell expands wildcards automatically. 58 * 59 * Windows: The setargv.obj module must be linked in to automatically 60 * expand wildcards. 61 */ 62 extern BOOLEAN AcpiGbl_DebugTimeout; 63 64 /* Local prototypes */ 65 66 static int 67 AeDoOptions ( 68 int argc, 69 char **argv); 70 71 static ACPI_STATUS 72 AcpiDbRunBatchMode ( 73 void); 74 75 76 #define AE_BUFFER_SIZE 1024 77 #define ASL_MAX_FILES 256 78 79 /* Execution modes */ 80 81 #define AE_MODE_COMMAND_LOOP 0 /* Normal command execution loop */ 82 #define AE_MODE_BATCH_MULTIPLE 1 /* -b option to execute a command line */ 83 #define AE_MODE_BATCH_SINGLE 2 /* -m option to execute a single control method */ 84 85 86 /* Globals */ 87 88 UINT8 AcpiGbl_RegionFillValue = 0; 89 BOOLEAN AcpiGbl_IgnoreErrors = FALSE; 90 BOOLEAN AcpiGbl_DbOpt_NoRegionSupport = FALSE; 91 UINT8 AcpiGbl_UseHwReducedFadt = FALSE; 92 BOOLEAN AcpiGbl_DoInterfaceTests = FALSE; 93 BOOLEAN AcpiGbl_LoadTestTables = FALSE; 94 BOOLEAN AcpiGbl_AeLoadOnly = FALSE; 95 static UINT8 AcpiGbl_ExecutionMode = AE_MODE_COMMAND_LOOP; 96 static char BatchBuffer[AE_BUFFER_SIZE]; /* Batch command buffer */ 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 ("-ed", "Enable timer output for Debug Object"); 156 ACPI_OPTION ("-ef", "Enable display of final memory statistics"); 157 ACPI_OPTION ("-ei", "Enable additional tests for ACPICA interfaces"); 158 ACPI_OPTION ("-el", "Enable loading of additional test tables"); 159 ACPI_OPTION ("-em", "Enable grouping of module-level code"); 160 ACPI_OPTION ("-es", "Enable Interpreter Slack Mode"); 161 ACPI_OPTION ("-et", "Enable debug semaphore timeout"); 162 printf ("\n"); 163 164 ACPI_OPTION ("-fi <File>", "Specify namespace initialization file"); 165 ACPI_OPTION ("-fv <Value>", "Operation Region initialization fill value"); 166 printf ("\n"); 167 168 ACPI_OPTION ("-i <Count>", "Maximum iterations for AML while loops"); 169 ACPI_OPTION ("-l", "Load tables and namespace only"); 170 ACPI_OPTION ("-r", "Use hardware-reduced FADT V5"); 171 ACPI_OPTION ("-v", "Display version information"); 172 ACPI_OPTION ("-vi", "Verbose initialization output"); 173 ACPI_OPTION ("-vr", "Verbose region handler output"); 174 ACPI_OPTION ("-x <DebugLevel>", "Debug output level"); 175 176 printf ("\n From within the interactive mode, use '?' or \"help\" to see\n" 177 " a list of available AML Debugger commands\n"); 178 } 179 180 181 /****************************************************************************** 182 * 183 * FUNCTION: AeDoOptions 184 * 185 * PARAMETERS: argc/argv - Standard argc/argv 186 * 187 * RETURN: Status 188 * 189 * DESCRIPTION: Command line option processing 190 * 191 *****************************************************************************/ 192 193 static int 194 AeDoOptions ( 195 int argc, 196 char **argv) 197 { 198 int j; 199 UINT32 Temp; 200 201 202 while ((j = AcpiGetopt (argc, argv, AE_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) 203 { 204 case 'b': 205 206 if (strlen (AcpiGbl_Optarg) > (AE_BUFFER_SIZE -1)) 207 { 208 printf ("**** The length of command line (%u) exceeded maximum (%u)\n", 209 (UINT32) strlen (AcpiGbl_Optarg), (AE_BUFFER_SIZE -1)); 210 return (-1); 211 } 212 AcpiGbl_ExecutionMode = AE_MODE_BATCH_MULTIPLE; 213 strcpy (BatchBuffer, AcpiGbl_Optarg); 214 break; 215 216 case 'd': 217 218 switch (AcpiGbl_Optarg[0]) 219 { 220 case 'a': 221 222 AcpiGbl_IgnoreErrors = TRUE; 223 break; 224 225 case 'i': 226 227 AcpiGbl_DbOpt_NoIniMethods = TRUE; 228 break; 229 230 case 'o': 231 232 AcpiGbl_DbOpt_NoRegionSupport = TRUE; 233 break; 234 235 case 'r': 236 237 AcpiGbl_DisableAutoRepair = TRUE; 238 break; 239 240 case 's': 241 242 AcpiGbl_AutoSerializeMethods = FALSE; 243 break; 244 245 case 't': 246 247 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 248 AcpiGbl_DisableMemTracking = TRUE; 249 #endif 250 break; 251 252 default: 253 254 printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); 255 return (-1); 256 } 257 break; 258 259 case 'e': 260 261 switch (AcpiGbl_Optarg[0]) 262 { 263 case 'd': 264 265 AcpiGbl_DisplayDebugTimer = TRUE; 266 break; 267 268 case 'f': 269 270 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 271 AcpiGbl_DisplayFinalMemStats = TRUE; 272 #endif 273 break; 274 275 case 'i': 276 277 AcpiGbl_DoInterfaceTests = TRUE; 278 break; 279 280 case 'l': 281 282 AcpiGbl_LoadTestTables = TRUE; 283 break; 284 285 case 'm': 286 287 AcpiGbl_GroupModuleLevelCode = TRUE; 288 break; 289 290 case 's': 291 292 AcpiGbl_EnableInterpreterSlack = TRUE; 293 printf ("Enabling AML Interpreter slack mode\n"); 294 break; 295 296 case 't': 297 298 AcpiGbl_DebugTimeout = TRUE; 299 break; 300 301 default: 302 303 printf ("Unknown option: -e%s\n", AcpiGbl_Optarg); 304 return (-1); 305 } 306 break; 307 308 case 'f': 309 310 switch (AcpiGbl_Optarg[0]) 311 { 312 case 'v': /* -fv: region fill value */ 313 314 if (AcpiGetoptArgument (argc, argv)) 315 { 316 return (-1); 317 } 318 319 AcpiGbl_RegionFillValue = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 320 break; 321 322 case 'i': /* -fi: specify initialization file */ 323 324 if (AcpiGetoptArgument (argc, argv)) 325 { 326 return (-1); 327 } 328 329 if (AeOpenInitializationFile (AcpiGbl_Optarg)) 330 { 331 return (-1); 332 } 333 break; 334 335 default: 336 337 printf ("Unknown option: -f%s\n", AcpiGbl_Optarg); 338 return (-1); 339 } 340 break; 341 342 case 'g': 343 344 AcpiGbl_DbFilename = NULL; 345 break; 346 347 case 'h': 348 case '?': 349 350 usage(); 351 return (1); 352 353 case 'i': 354 355 Temp = strtoul (AcpiGbl_Optarg, NULL, 0); 356 if (!Temp || (Temp > ACPI_UINT16_MAX)) 357 { 358 printf ("%s: Invalid max loops value\n", AcpiGbl_Optarg); 359 return (-1); 360 } 361 362 AcpiGbl_MaxLoopIterations = (UINT16) Temp; 363 printf ("Max Loop Iterations is %u (0x%X)\n", 364 AcpiGbl_MaxLoopIterations, AcpiGbl_MaxLoopIterations); 365 break; 366 367 case 'l': 368 369 AcpiGbl_AeLoadOnly = TRUE; 370 break; 371 372 case 'm': 373 374 AcpiGbl_ExecutionMode = AE_MODE_BATCH_SINGLE; 375 switch (AcpiGbl_Optarg[0]) 376 { 377 case '^': 378 379 strcpy (BatchBuffer, "MAIN"); 380 break; 381 382 default: 383 384 strcpy (BatchBuffer, AcpiGbl_Optarg); 385 break; 386 } 387 break; 388 389 case 'r': 390 391 AcpiGbl_UseHwReducedFadt = TRUE; 392 printf ("Using ACPI 5.0 Hardware Reduced Mode via version 5 FADT\n"); 393 break; 394 395 case 'v': 396 397 switch (AcpiGbl_Optarg[0]) 398 { 399 case '^': /* -v: (Version): signon already emitted, just exit */ 400 401 (void) AcpiOsTerminate (); 402 return (1); 403 404 case 'i': 405 406 AcpiDbgLevel |= ACPI_LV_INIT_NAMES; 407 break; 408 409 case 'r': 410 411 AcpiGbl_DisplayRegionAccess = TRUE; 412 break; 413 414 default: 415 416 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 417 return (-1); 418 } 419 break; 420 421 case 'x': 422 423 AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 0); 424 AcpiGbl_DbConsoleDebugLevel = AcpiDbgLevel; 425 printf ("Debug Level: 0x%8.8X\n", AcpiDbgLevel); 426 break; 427 428 default: 429 430 usage(); 431 return (-1); 432 } 433 434 return (0); 435 } 436 437 438 /****************************************************************************** 439 * 440 * FUNCTION: main 441 * 442 * PARAMETERS: argc, argv 443 * 444 * RETURN: Status 445 * 446 * DESCRIPTION: Main routine for AcpiExec utility 447 * 448 *****************************************************************************/ 449 450 int ACPI_SYSTEM_XFACE 451 main ( 452 int argc, 453 char **argv) 454 { 455 ACPI_NEW_TABLE_DESC *ListHead = NULL; 456 ACPI_STATUS Status; 457 UINT32 InitFlags; 458 int ExitCode = 0; 459 460 461 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 462 signal (SIGINT, AeCtrlCHandler); 463 464 /* Init debug globals */ 465 466 AcpiDbgLevel = ACPI_NORMAL_DEFAULT; 467 AcpiDbgLayer = 0xFFFFFFFF; 468 469 /* Init ACPICA and start debugger thread */ 470 471 AcpiGbl_OverrideDefaultRegionHandlers = TRUE; 472 Status = AcpiInitializeSubsystem (); 473 ACPI_CHECK_OK (AcpiInitializeSubsystem, Status); 474 if (ACPI_FAILURE (Status)) 475 { 476 goto ErrorExit; 477 } 478 479 /* ACPICA runtime configuration */ 480 481 AcpiGbl_MaxLoopIterations = 400; 482 483 484 /* Initialize the AML debugger */ 485 486 Status = AcpiInitializeDebugger (); 487 ACPI_CHECK_OK (AcpiInitializeDebugger, Status); 488 if (ACPI_FAILURE (Status)) 489 { 490 goto ErrorExit; 491 } 492 493 printf (ACPI_COMMON_SIGNON (ACPIEXEC_NAME)); 494 if (argc < 2) 495 { 496 usage (); 497 (void) AcpiOsTerminate (); 498 return (0); 499 } 500 501 /* Get the command line options */ 502 503 ExitCode = AeDoOptions (argc, argv); 504 if (ExitCode) 505 { 506 if (ExitCode > 0) 507 { 508 ExitCode = 0; 509 } 510 511 goto ErrorExit; 512 } 513 514 /* The remaining arguments are filenames for ACPI tables */ 515 516 if (!argv[AcpiGbl_Optind]) 517 { 518 goto EnterDebugger; 519 } 520 521 AcpiGbl_CstyleDisassembly = FALSE; /* Not supported for AcpiExec */ 522 523 /* Get each of the ACPI table files on the command line */ 524 525 while (argv[AcpiGbl_Optind]) 526 { 527 /* Get all ACPI AML tables in this file */ 528 529 Status = AcGetAllTablesFromFile (argv[AcpiGbl_Optind], 530 ACPI_GET_ONLY_AML_TABLES, &ListHead); 531 if (ACPI_FAILURE (Status)) 532 { 533 ExitCode = -1; 534 goto ErrorExit; 535 } 536 537 AcpiGbl_Optind++; 538 } 539 540 printf ("\n"); 541 542 /* Build a local RSDT with all tables and let ACPICA process the RSDT */ 543 544 Status = AeBuildLocalTables (ListHead); 545 if (ACPI_FAILURE (Status)) 546 { 547 goto ErrorExit; 548 } 549 550 /* Install all of the ACPI tables */ 551 552 Status = AeInstallTables (); 553 554 if (ACPI_FAILURE (Status)) 555 { 556 printf ("**** Could not install ACPI tables, %s\n", 557 AcpiFormatException (Status)); 558 goto EnterDebugger; 559 } 560 561 /* 562 * Install most of the handlers (Regions, Notify, Table, etc.) 563 * Override the default region handlers, especially SystemMemory, 564 * which is simulated in this utility. 565 */ 566 Status = AeInstallEarlyHandlers (); 567 if (ACPI_FAILURE (Status)) 568 { 569 goto EnterDebugger; 570 } 571 572 /* Setup initialization flags for ACPICA */ 573 574 InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); 575 if (AcpiGbl_DbOpt_NoIniMethods) 576 { 577 InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); 578 } 579 580 /* 581 * Main initialization for ACPICA subsystem 582 * TBD: Need a way to call this after the ACPI table "LOAD" command 583 */ 584 Status = AcpiEnableSubsystem (InitFlags); 585 if (ACPI_FAILURE (Status)) 586 { 587 printf ("**** Could not EnableSubsystem, %s\n", 588 AcpiFormatException (Status)); 589 goto EnterDebugger; 590 } 591 592 Status = AeLoadTables (); 593 594 /* 595 * Exit namespace initialization for the "load namespace only" option. 596 * No control methods will be executed. However, still enter the 597 * the debugger. 598 */ 599 if (AcpiGbl_AeLoadOnly) 600 { 601 goto EnterDebugger; 602 } 603 604 if (ACPI_FAILURE (Status)) 605 { 606 printf ("**** Could not load ACPI tables, %s\n", 607 AcpiFormatException (Status)); 608 goto EnterDebugger; 609 } 610 611 /* 612 * Install handlers for "device driver" space IDs (EC,SMBus, etc.) 613 * and fixed event handlers 614 */ 615 AeInstallLateHandlers (); 616 617 /* Finish the ACPICA initialization */ 618 619 Status = AcpiInitializeObjects (InitFlags); 620 if (ACPI_FAILURE (Status)) 621 { 622 printf ("**** Could not InitializeObjects, %s\n", 623 AcpiFormatException (Status)); 624 goto EnterDebugger; 625 } 626 627 AeMiscellaneousTests (); 628 629 630 EnterDebugger: 631 632 /* Exit if error above and we are in one of the batch modes */ 633 634 if (ACPI_FAILURE (Status) && (AcpiGbl_ExecutionMode > 0)) 635 { 636 goto ErrorExit; 637 } 638 639 /* Run a batch command or enter the command loop */ 640 641 switch (AcpiGbl_ExecutionMode) 642 { 643 default: 644 case AE_MODE_COMMAND_LOOP: 645 646 AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL); 647 break; 648 649 case AE_MODE_BATCH_MULTIPLE: 650 651 AcpiDbRunBatchMode (); 652 break; 653 654 case AE_MODE_BATCH_SINGLE: 655 656 AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); 657 658 /* Shut down the debugger */ 659 660 AcpiTerminateDebugger (); 661 Status = AcpiTerminate (); 662 break; 663 } 664 665 (void) AcpiOsTerminate (); 666 return (0); 667 668 669 ErrorExit: 670 (void) AcpiOsTerminate (); 671 return (ExitCode); 672 } 673 674 675 /****************************************************************************** 676 * 677 * FUNCTION: AcpiDbRunBatchMode 678 * 679 * PARAMETERS: BatchCommandLine - A semicolon separated list of commands 680 * to be executed. 681 * Use only commas to separate elements of 682 * particular command. 683 * RETURN: Status 684 * 685 * DESCRIPTION: For each command of list separated by ';' prepare the command 686 * buffer and pass it to AcpiDbCommandDispatch. 687 * 688 *****************************************************************************/ 689 690 static ACPI_STATUS 691 AcpiDbRunBatchMode ( 692 void) 693 { 694 ACPI_STATUS Status; 695 char *Ptr = BatchBuffer; 696 char *Cmd = Ptr; 697 UINT8 Run = 0; 698 699 700 AcpiGbl_MethodExecuting = FALSE; 701 AcpiGbl_StepToNextCall = FALSE; 702 703 while (*Ptr) 704 { 705 if (*Ptr == ',') 706 { 707 /* Convert commas to spaces */ 708 *Ptr = ' '; 709 } 710 else if (*Ptr == ';') 711 { 712 *Ptr = '\0'; 713 Run = 1; 714 } 715 716 Ptr++; 717 718 if (Run || (*Ptr == '\0')) 719 { 720 (void) AcpiDbCommandDispatch (Cmd, NULL, NULL); 721 Run = 0; 722 Cmd = Ptr; 723 } 724 } 725 726 /* Shut down the debugger */ 727 728 AcpiTerminateDebugger (); 729 Status = AcpiTerminate (); 730 return (Status); 731 } 732