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