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