aemain.c revision 1.1.1.19
1/****************************************************************************** 2 * 3 * Module Name: aemain - Main routine for the AcpiExec utility 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2020, 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; 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 */ 93INIT_FILE_ENTRY *AcpiGbl_InitEntries = NULL; 94UINT32 AcpiGbl_InitFileLineCount = 0; 95 96#define ACPIEXEC_NAME "AML Execution/Debug Utility" 97#define AE_SUPPORTED_OPTIONS "?b:d:e:f^ghlm^rt^v^:x:" 98 99 100/* Stubs for the disassembler */ 101 102void 103MpSaveGpioInfo ( 104 ACPI_PARSE_OBJECT *Op, 105 AML_RESOURCE *Resource, 106 UINT32 PinCount, 107 UINT16 *PinList, 108 char *DeviceName) 109{ 110} 111 112void 113MpSaveSerialInfo ( 114 ACPI_PARSE_OBJECT *Op, 115 AML_RESOURCE *Resource, 116 char *DeviceName) 117{ 118} 119 120 121/****************************************************************************** 122 * 123 * FUNCTION: usage 124 * 125 * PARAMETERS: None 126 * 127 * RETURN: None 128 * 129 * DESCRIPTION: Print a usage message 130 * 131 *****************************************************************************/ 132 133static void 134usage ( 135 void) 136{ 137 138 ACPI_USAGE_HEADER ("acpiexec [options] AMLfile1 AMLfile2 ..."); 139 140 ACPI_OPTION ("-b \"CommandLine\"", "Batch mode command line execution (cmd1;cmd2;...)"); 141 ACPI_OPTION ("-h -?", "Display this help message"); 142 ACPI_OPTION ("-m [Method]", "Batch mode method execution. Default=MAIN"); 143 printf ("\n"); 144 145 ACPI_OPTION ("-da", "Disable method abort on error"); 146 ACPI_OPTION ("-df", "Disable Local fault handler"); 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 ("-ed", "Enable timer output for Debug Object"); 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 ("-eo", "Enable object evaluation log"); 159 ACPI_OPTION ("-es", "Enable Interpreter Slack Mode"); 160 ACPI_OPTION ("-et", "Enable debug semaphore timeout"); 161 printf ("\n"); 162 163 ACPI_OPTION ("-fi <File>", "Specify namespace initialization file"); 164 ACPI_OPTION ("-fv <Value>", "Operation Region initialization fill value"); 165 printf ("\n"); 166 167 ACPI_OPTION ("-l", "Load tables and namespace only"); 168 ACPI_OPTION ("-r", "Use hardware-reduced FADT V5"); 169 ACPI_OPTION ("-te", "Exit loop on timeout instead of aborting method"); 170 ACPI_OPTION ("-to <Seconds>", "Set timeout period for AML while loops"); 171 printf ("\n"); 172 173 ACPI_OPTION ("-v", "Display version information"); 174 ACPI_OPTION ("-va", "Display verbose dump of any memory leaks"); 175 ACPI_OPTION ("-vd", "Display build date and time"); 176 ACPI_OPTION ("-vh", "Verbose exception handler output"); 177 ACPI_OPTION ("-vi", "Verbose initialization output"); 178 ACPI_OPTION ("-vr", "Verbose region handler output"); 179 ACPI_OPTION ("-x <DebugLevel>", "Debug output level"); 180 181 printf ("\n From within the interactive mode, use '?' or \"help\" to see\n" 182 " a list of available AML Debugger commands\n"); 183} 184 185 186/****************************************************************************** 187 * 188 * FUNCTION: AeDoOptions 189 * 190 * PARAMETERS: argc/argv - Standard argc/argv 191 * 192 * RETURN: Status 193 * 194 * DESCRIPTION: Command line option processing 195 * 196 *****************************************************************************/ 197 198static int 199AeDoOptions ( 200 int argc, 201 char **argv) 202{ 203 int j; 204 UINT32 Temp; 205 206 207 while ((j = AcpiGetopt (argc, argv, AE_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) 208 { 209 case 'b': 210 211 if (strlen (AcpiGbl_Optarg) > (AE_BUFFER_SIZE -1)) 212 { 213 printf ("**** The length of command line (%u) exceeded maximum (%d)\n", 214 (UINT32) strlen (AcpiGbl_Optarg), (AE_BUFFER_SIZE -1)); 215 return (-1); 216 } 217 AcpiGbl_ExecutionMode = AE_MODE_BATCH_MULTIPLE; 218 strcpy (BatchBuffer, AcpiGbl_Optarg); 219 break; 220 221 case 'd': 222 223 switch (AcpiGbl_Optarg[0]) 224 { 225 case 'a': 226 227 AcpiGbl_IgnoreErrors = TRUE; 228 break; 229 230 case 'f': 231 232 AcpiGbl_UseLocalFaultHandler = FALSE; 233 break; 234 235 case 'i': 236 237 AcpiGbl_DbOpt_NoIniMethods = TRUE; 238 break; 239 240 case 'o': 241 242 AcpiGbl_DbOpt_NoRegionSupport = TRUE; 243 break; 244 245 case 'r': 246 247 AcpiGbl_DisableAutoRepair = TRUE; 248 break; 249 250 case 's': 251 252 AcpiGbl_AutoSerializeMethods = FALSE; 253 break; 254 255 case 't': 256 257 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 258 AcpiGbl_DisableMemTracking = TRUE; 259 #endif 260 break; 261 262 default: 263 264 printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); 265 return (-1); 266 } 267 break; 268 269 case 'e': 270 271 switch (AcpiGbl_Optarg[0]) 272 { 273 case 'd': 274 275 AcpiGbl_DisplayDebugTimer = TRUE; 276 break; 277 278 case 'f': 279 280 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 281 AcpiGbl_DisplayFinalMemStats = TRUE; 282 #endif 283 break; 284 285 case 'i': 286 287 AcpiGbl_DoInterfaceTests = TRUE; 288 break; 289 290 case 'l': 291 292 AcpiGbl_LoadTestTables = TRUE; 293 break; 294 295 case 'o': 296 297 AcpiDbgLevel |= ACPI_LV_EVALUATION; 298 AcpiGbl_DbConsoleDebugLevel |= ACPI_LV_EVALUATION; 299 break; 300 301 case 's': 302 303 AcpiGbl_EnableInterpreterSlack = TRUE; 304 printf ("Enabling AML Interpreter slack mode\n"); 305 break; 306 307 case 't': 308 309 AcpiGbl_DebugTimeout = TRUE; 310 break; 311 312 default: 313 314 printf ("Unknown option: -e%s\n", AcpiGbl_Optarg); 315 return (-1); 316 } 317 break; 318 319 case 'f': 320 321 switch (AcpiGbl_Optarg[0]) 322 { 323 case 'v': /* -fv: region fill value */ 324 325 if (AcpiGetoptArgument (argc, argv)) 326 { 327 return (-1); 328 } 329 330 AcpiGbl_RegionFillValue = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 331 break; 332 333 case 'i': /* -fi: specify initialization file */ 334 335 if (AcpiGetoptArgument (argc, argv)) 336 { 337 return (-1); 338 } 339 340 if (AeOpenInitializationFile (AcpiGbl_Optarg)) 341 { 342 return (-1); 343 } 344 break; 345 346 default: 347 348 printf ("Unknown option: -f%s\n", AcpiGbl_Optarg); 349 return (-1); 350 } 351 break; 352 353 case 'g': 354 355 AcpiGbl_DbFilename = NULL; 356 break; 357 358 case 'h': 359 case '?': 360 361 usage(); 362 return (1); 363 364 case 'l': 365 366 AcpiGbl_AeLoadOnly = TRUE; 367 break; 368 369 case 'm': 370 371 AcpiGbl_ExecutionMode = AE_MODE_BATCH_SINGLE; 372 switch (AcpiGbl_Optarg[0]) 373 { 374 case '^': 375 376 strcpy (BatchBuffer, "MAIN"); 377 break; 378 379 default: 380 381 strcpy (BatchBuffer, AcpiGbl_Optarg); 382 break; 383 } 384 break; 385 386 case 'r': 387 388 AcpiGbl_UseHwReducedFadt = TRUE; 389 printf ("Using ACPI 5.0 Hardware Reduced Mode via version 5 FADT\n"); 390 break; 391 392 case 't': 393 394 switch (AcpiGbl_Optarg[0]) 395 { 396 case 'o': /* -to: Set loop timeout in seconds */ 397 398 if (AcpiGetoptArgument (argc, argv)) 399 { 400 return (-1); 401 } 402 403 Temp = strtoul (AcpiGbl_Optarg, NULL, 0); 404 if (!Temp || (Temp > ACPI_UINT16_MAX)) 405 { 406 printf ("%s: Invalid loop timeout value\n", 407 AcpiGbl_Optarg); 408 return (-1); 409 } 410 411 AcpiGbl_MaxLoopIterations = (UINT16) Temp; 412 printf ("Automatic loop timeout after %u seconds\n", 413 AcpiGbl_MaxLoopIterations); 414 break; 415 416 case 'e': 417 418 AcpiGbl_AbortLoopOnTimeout = TRUE; 419 break; 420 421 default: 422 423 printf ("Unknown option: -t%s\n", AcpiGbl_Optarg); 424 return (-1); 425 } 426 break; 427 428 case 'v': 429 430 switch (AcpiGbl_Optarg[0]) 431 { 432 case '^': /* -v: (Version): signon already emitted, just exit */ 433 434 return (1); 435 436 case 'a': 437 438 AcpiGbl_VerboseLeakDump = TRUE; 439 break; 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 /* 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 if (AcpiGbl_UseLocalFaultHandler) 565 { 566 signal (SIGSEGV, AeSignalHandler); 567 } 568 569 /* The remaining arguments are filenames for ACPI tables */ 570 571 if (!argv[AcpiGbl_Optind]) 572 { 573 goto EnterDebugger; 574 } 575 576 AcpiGbl_CstyleDisassembly = FALSE; /* Not supported for AcpiExec */ 577 578 /* Get each of the ACPI table files on the command line */ 579 580 while (argv[AcpiGbl_Optind]) 581 { 582 /* Get all ACPI AML tables in this file */ 583 584 Status = AcGetAllTablesFromFile (argv[AcpiGbl_Optind], 585 ACPI_GET_ALL_TABLES, &ListHead); 586 if (ACPI_FAILURE (Status)) 587 { 588 ExitCode = -1; 589 goto ErrorExit; 590 } 591 592 AcpiGbl_Optind++; 593 } 594 595 printf ("\n"); 596 597 /* Build a local RSDT with all tables and let ACPICA process the RSDT */ 598 599 Status = AeBuildLocalTables (ListHead); 600 if (ACPI_FAILURE (Status)) 601 { 602 goto ErrorExit; 603 } 604 605 /* Install all of the ACPI tables */ 606 607 Status = AeInstallTables (); 608 if (ACPI_FAILURE (Status)) 609 { 610 printf ("**** Could not install ACPI tables, %s\n", 611 AcpiFormatException (Status)); 612 goto EnterDebugger; 613 } 614 615 /* 616 * Install most of the handlers (Regions, Notify, Table, etc.) 617 * Override the default region handlers, especially SystemMemory, 618 * which is simulated in this utility. 619 */ 620 Status = AeInstallEarlyHandlers (); 621 if (ACPI_FAILURE (Status)) 622 { 623 goto EnterDebugger; 624 } 625 626 /* Read the entire namespace initialization file if requested */ 627 628 Status = AeProcessInitFile(); 629 if (ACPI_FAILURE (Status)) 630 { 631 ExitCode = -1; 632 goto ErrorExit; 633 } 634 635 Status = AeLoadTables (); 636 if (ACPI_FAILURE (Status)) 637 { 638 ExitCode = -1; 639 goto ErrorExit; 640 } 641 642 /* 643 * Exit namespace initialization for the "load namespace only" option. 644 * No control methods will be executed. However, still enter the 645 * the debugger. 646 */ 647 if (AcpiGbl_AeLoadOnly) 648 { 649 goto EnterDebugger; 650 } 651 652 if (ACPI_FAILURE (Status)) 653 { 654 printf ("**** Could not load ACPI tables, %s\n", 655 AcpiFormatException (Status)); 656 goto EnterDebugger; 657 } 658 659 /* Setup initialization flags for ACPICA */ 660 661 InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); 662 if (AcpiGbl_DbOpt_NoIniMethods) 663 { 664 InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); 665 } 666 667 /* 668 * Main initialization for ACPICA subsystem 669 * TBD: Need a way to call this after the ACPI table "LOAD" command? 670 * 671 * NOTE: This initialization does not match the _Lxx and _Exx methods 672 * to individual GPEs, as there are no real GPEs when the hardware 673 * is simulated - because there is no namespace until AeLoadTables is 674 * executed. This may have to change if AcpiExec is ever run natively 675 * on actual hardware (such as under UEFI). 676 */ 677 Status = AcpiEnableSubsystem (InitFlags); 678 if (ACPI_FAILURE (Status)) 679 { 680 printf ("**** Could not EnableSubsystem, %s\n", 681 AcpiFormatException (Status)); 682 goto EnterDebugger; 683 } 684 685 /* 686 * Install handlers for "device driver" space IDs (EC,SMBus, etc.) 687 * and fixed event handlers 688 */ 689 AeInstallLateHandlers (); 690 691 /* Finish the ACPICA initialization */ 692 693 Status = AcpiInitializeObjects (InitFlags); 694 if (ACPI_FAILURE (Status)) 695 { 696 printf ("**** Could not InitializeObjects, %s\n", 697 AcpiFormatException (Status)); 698 goto EnterDebugger; 699 } 700 701 AeDisplayUnusedInitFileItems (); 702 AeMiscellaneousTests (); 703 704 705EnterDebugger: 706 707 /* Exit if error above and we are in one of the batch modes */ 708 709 if (ACPI_FAILURE (Status) && (AcpiGbl_ExecutionMode > 0)) 710 { 711 goto ErrorExit; 712 } 713 714 /* Run a batch command or enter the command loop */ 715 716 switch (AcpiGbl_ExecutionMode) 717 { 718 default: 719 case AE_MODE_COMMAND_LOOP: 720 721 AcpiRunDebugger (NULL); 722 break; 723 724 case AE_MODE_BATCH_MULTIPLE: 725 726 AcpiRunDebugger (BatchBuffer); 727 break; 728 729 case AE_MODE_BATCH_SINGLE: 730 731 AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); 732 break; 733 } 734 735 /* Shut down the debugger and ACPICA */ 736 737 AcpiTerminateDebugger (); 738 739 /* re-enable debug output for AcpiTerminate output */ 740 741 AcpiGbl_DbOutputFlags = ACPI_DB_CONSOLE_OUTPUT; 742 743NormalExit: 744 ExitCode = 0; 745 746ErrorExit: 747 AeLateTest (); 748 749 AeDeleteInitFileList (); 750 751 (void) AcpiTerminate (); 752 AcDeleteTableList (ListHead); 753 return (ExitCode); 754} 755