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 Status = AcpiInitializeSubsystem (); 472 ACPI_CHECK_OK (AcpiInitializeSubsystem, Status); 473 if (ACPI_FAILURE (Status)) 474 { 475 goto ErrorExit; 476 } 477 478 /* ACPICA runtime configuration */ 479 480 AcpiGbl_MaxLoopIterations = 400; 481 482 483 /* Initialize the AML debugger */ 484 485 Status = AcpiInitializeDebugger (); 486 ACPI_CHECK_OK (AcpiInitializeDebugger, Status); 487 if (ACPI_FAILURE (Status)) 488 { 489 goto ErrorExit; 490 } 491 492 printf (ACPI_COMMON_SIGNON (ACPIEXEC_NAME)); 493 if (argc < 2) 494 { 495 usage (); 496 (void) AcpiOsTerminate (); 497 return (0); 498 } 499 500 /* Get the command line options */ 501 502 ExitCode = AeDoOptions (argc, argv); 503 if (ExitCode) 504 { 505 if (ExitCode > 0) 506 { 507 ExitCode = 0; 508 } 509 510 goto ErrorExit; 511 } 512 513 /* The remaining arguments are filenames for ACPI tables */ 514 515 if (!argv[AcpiGbl_Optind]) 516 { 517 goto EnterDebugger; 518 } 519 520 AcpiGbl_CstyleDisassembly = FALSE; /* Not supported for AcpiExec */ 521 522 /* Get each of the ACPI table files on the command line */ 523 524 while (argv[AcpiGbl_Optind]) 525 { 526 /* Get all ACPI AML tables in this file */ 527 528 Status = AcGetAllTablesFromFile (argv[AcpiGbl_Optind], 529 ACPI_GET_ONLY_AML_TABLES, &ListHead); 530 if (ACPI_FAILURE (Status)) 531 { 532 ExitCode = -1; 533 goto ErrorExit; 534 } 535 536 AcpiGbl_Optind++; 537 } 538 539 printf ("\n"); 540 541 /* Build a local RSDT with all tables and let ACPICA process the RSDT */ 542 543 Status = AeBuildLocalTables (ListHead); 544 if (ACPI_FAILURE (Status)) 545 { 546 goto ErrorExit; 547 } 548 549 /* Install all of the ACPI tables */ 550 551 Status = AeInstallTables (); 552 553 if (ACPI_FAILURE (Status)) 554 { 555 printf ("**** Could not install ACPI tables, %s\n", 556 AcpiFormatException (Status)); 557 goto EnterDebugger; 558 } 559 560 /* 561 * Install most of the handlers (Regions, Notify, Table, etc.) 562 * Override the default region handlers, especially SystemMemory, 563 * which is simulated in this utility. 564 */ 565 Status = AeInstallEarlyHandlers (); 566 if (ACPI_FAILURE (Status)) 567 { 568 goto EnterDebugger; 569 } 570 571 /* Setup initialization flags for ACPICA */ 572 573 InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); 574 if (AcpiGbl_DbOpt_NoIniMethods) 575 { 576 InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); 577 } 578 579 /* 580 * Main initialization for ACPICA subsystem 581 * TBD: Need a way to call this after the ACPI table "LOAD" command 582 */ 583 Status = AcpiEnableSubsystem (InitFlags); 584 if (ACPI_FAILURE (Status)) 585 { 586 printf ("**** Could not EnableSubsystem, %s\n", 587 AcpiFormatException (Status)); 588 goto EnterDebugger; 589 } 590 591 Status = AeLoadTables (); 592 593 /* 594 * Exit namespace initialization for the "load namespace only" option. 595 * No control methods will be executed. However, still enter the 596 * the debugger. 597 */ 598 if (AcpiGbl_AeLoadOnly) 599 { 600 goto EnterDebugger; 601 } 602 603 if (ACPI_FAILURE (Status)) 604 { 605 printf ("**** Could not load ACPI tables, %s\n", 606 AcpiFormatException (Status)); 607 goto EnterDebugger; 608 } 609 610 /* 611 * Install handlers for "device driver" space IDs (EC,SMBus, etc.) 612 * and fixed event handlers 613 */ 614 AeInstallLateHandlers (); 615 616 /* Finish the ACPICA initialization */ 617 618 Status = AcpiInitializeObjects (InitFlags); 619 if (ACPI_FAILURE (Status)) 620 { 621 printf ("**** Could not InitializeObjects, %s\n", 622 AcpiFormatException (Status)); 623 goto EnterDebugger; 624 } 625 626 AeMiscellaneousTests (); 627 628 629 EnterDebugger: 630 631 /* Exit if error above and we are in one of the batch modes */ 632 633 if (ACPI_FAILURE (Status) && (AcpiGbl_ExecutionMode > 0)) 634 { 635 goto ErrorExit; 636 } 637 638 /* Run a batch command or enter the command loop */ 639 640 switch (AcpiGbl_ExecutionMode) 641 { 642 default: 643 case AE_MODE_COMMAND_LOOP: 644 645 AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL); 646 break; 647 648 case AE_MODE_BATCH_MULTIPLE: 649 650 AcpiDbRunBatchMode (); 651 break; 652 653 case AE_MODE_BATCH_SINGLE: 654 655 AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); 656 657 /* Shut down the debugger */ 658 659 AcpiTerminateDebugger (); 660 Status = AcpiTerminate (); 661 break; 662 } 663 664 (void) AcpiOsTerminate (); 665 return (0); 666 667 668 ErrorExit: 669 (void) AcpiOsTerminate (); 670 return (ExitCode); 671 } 672 673 674 /****************************************************************************** 675 * 676 * FUNCTION: AcpiDbRunBatchMode 677 * 678 * PARAMETERS: BatchCommandLine - A semicolon separated list of commands 679 * to be executed. 680 * Use only commas to separate elements of 681 * particular command. 682 * RETURN: Status 683 * 684 * DESCRIPTION: For each command of list separated by ';' prepare the command 685 * buffer and pass it to AcpiDbCommandDispatch. 686 * 687 *****************************************************************************/ 688 689 static ACPI_STATUS 690 AcpiDbRunBatchMode ( 691 void) 692 { 693 ACPI_STATUS Status; 694 char *Ptr = BatchBuffer; 695 char *Cmd = Ptr; 696 UINT8 Run = 0; 697 698 699 AcpiGbl_MethodExecuting = FALSE; 700 AcpiGbl_StepToNextCall = FALSE; 701 702 while (*Ptr) 703 { 704 if (*Ptr == ',') 705 { 706 /* Convert commas to spaces */ 707 *Ptr = ' '; 708 } 709 else if (*Ptr == ';') 710 { 711 *Ptr = '\0'; 712 Run = 1; 713 } 714 715 Ptr++; 716 717 if (Run || (*Ptr == '\0')) 718 { 719 (void) AcpiDbCommandDispatch (Cmd, NULL, NULL); 720 Run = 0; 721 Cmd = Ptr; 722 } 723 } 724 725 /* Shut down the debugger */ 726 727 AcpiTerminateDebugger (); 728 Status = AcpiTerminate (); 729 return (Status); 730 } 731