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