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 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 64 static int 65 AeDoOptions ( 66 int argc, 67 char **argv); 68 69 static void 70 AcpiDbRunBatchMode ( 71 void); 72 73 74 #define AE_BUFFER_SIZE 1024 75 #define ASL_MAX_FILES 256 76 77 /* Execution modes */ 78 79 #define AE_MODE_COMMAND_LOOP 0 /* Normal command execution loop */ 80 #define AE_MODE_BATCH_MULTIPLE 1 /* -b option to execute a command line */ 81 #define AE_MODE_BATCH_SINGLE 2 /* -m option to execute a single control method */ 82 83 84 /* Globals */ 85 86 UINT8 AcpiGbl_RegionFillValue = 0; 87 BOOLEAN AcpiGbl_IgnoreErrors = FALSE; 88 BOOLEAN AcpiGbl_DbOpt_NoRegionSupport = FALSE; 89 UINT8 AcpiGbl_UseHwReducedFadt = FALSE; 90 BOOLEAN AcpiGbl_DoInterfaceTests = FALSE; 91 BOOLEAN AcpiGbl_LoadTestTables = FALSE; 92 BOOLEAN AcpiGbl_AeLoadOnly = FALSE; 93 static UINT8 AcpiGbl_ExecutionMode = AE_MODE_COMMAND_LOOP; 94 static char BatchBuffer[AE_BUFFER_SIZE]; /* Batch command buffer */ 95 96 #define ACPIEXEC_NAME "AML Execution/Debug Utility" 97 #define AE_SUPPORTED_OPTIONS "?b:d:e:f^ghi:lm^rv^:x:" 98 99 100 /* Stubs for the disassembler */ 101 102 void 103 MpSaveGpioInfo ( 104 ACPI_PARSE_OBJECT *Op, 105 AML_RESOURCE *Resource, 106 UINT32 PinCount, 107 UINT16 *PinList, 108 char *DeviceName) 109 { 110 } 111 112 void 113 MpSaveSerialInfo ( 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 133 static void 134 usage ( 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 ("-di", "Disable execution of STA/INI methods during init"); 147 ACPI_OPTION ("-do", "Disable Operation Region address simulation"); 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 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 ("-i <Count>", "Maximum iterations for AML while loops"); 167 ACPI_OPTION ("-l", "Load tables and namespace only"); 168 ACPI_OPTION ("-r", "Use hardware-reduced FADT V5"); 169 ACPI_OPTION ("-v", "Display version information"); 170 ACPI_OPTION ("-vi", "Verbose initialization output"); 171 ACPI_OPTION ("-vr", "Verbose region handler output"); 172 ACPI_OPTION ("-x <DebugLevel>", "Debug output level"); 173 174 printf ("\n From within the interactive mode, use '?' or \"help\" to see\n" 175 " a list of available AML Debugger commands\n"); 176 } 177 178 179 /****************************************************************************** 180 * 181 * FUNCTION: AeDoOptions 182 * 183 * PARAMETERS: argc/argv - Standard argc/argv 184 * 185 * RETURN: Status 186 * 187 * DESCRIPTION: Command line option processing 188 * 189 *****************************************************************************/ 190 191 static int 192 AeDoOptions ( 193 int argc, 194 char **argv) 195 { 196 int j; 197 UINT32 Temp; 198 199 200 while ((j = AcpiGetopt (argc, argv, AE_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) 201 { 202 case 'b': 203 204 if (strlen (AcpiGbl_Optarg) > (AE_BUFFER_SIZE -1)) 205 { 206 printf ("**** The length of command line (%u) exceeded maximum (%u)\n", 207 (UINT32) strlen (AcpiGbl_Optarg), (AE_BUFFER_SIZE -1)); 208 return (-1); 209 } 210 AcpiGbl_ExecutionMode = AE_MODE_BATCH_MULTIPLE; 211 strcpy (BatchBuffer, AcpiGbl_Optarg); 212 break; 213 214 case 'd': 215 216 switch (AcpiGbl_Optarg[0]) 217 { 218 case 'a': 219 220 AcpiGbl_IgnoreErrors = TRUE; 221 break; 222 223 case 'i': 224 225 AcpiGbl_DbOpt_NoIniMethods = TRUE; 226 break; 227 228 case 'o': 229 230 AcpiGbl_DbOpt_NoRegionSupport = TRUE; 231 break; 232 233 case 'r': 234 235 AcpiGbl_DisableAutoRepair = TRUE; 236 break; 237 238 case 's': 239 240 AcpiGbl_AutoSerializeMethods = FALSE; 241 break; 242 243 case 't': 244 245 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 246 AcpiGbl_DisableMemTracking = TRUE; 247 #endif 248 break; 249 250 default: 251 252 printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); 253 return (-1); 254 } 255 break; 256 257 case 'e': 258 259 switch (AcpiGbl_Optarg[0]) 260 { 261 case 'd': 262 263 AcpiGbl_DisplayDebugTimer = TRUE; 264 break; 265 266 case 'f': 267 268 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 269 AcpiGbl_DisplayFinalMemStats = TRUE; 270 #endif 271 break; 272 273 case 'i': 274 275 AcpiGbl_DoInterfaceTests = TRUE; 276 break; 277 278 case 'l': 279 280 AcpiGbl_LoadTestTables = TRUE; 281 break; 282 283 case 'm': 284 285 AcpiGbl_GroupModuleLevelCode = TRUE; 286 break; 287 288 case 's': 289 290 AcpiGbl_EnableInterpreterSlack = TRUE; 291 printf ("Enabling AML Interpreter slack mode\n"); 292 break; 293 294 case 't': 295 296 AcpiGbl_DebugTimeout = TRUE; 297 break; 298 299 default: 300 301 printf ("Unknown option: -e%s\n", AcpiGbl_Optarg); 302 return (-1); 303 } 304 break; 305 306 case 'f': 307 308 switch (AcpiGbl_Optarg[0]) 309 { 310 case 'v': /* -fv: region fill value */ 311 312 if (AcpiGetoptArgument (argc, argv)) 313 { 314 return (-1); 315 } 316 317 AcpiGbl_RegionFillValue = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 318 break; 319 320 case 'i': /* -fi: specify initialization file */ 321 322 if (AcpiGetoptArgument (argc, argv)) 323 { 324 return (-1); 325 } 326 327 if (AeOpenInitializationFile (AcpiGbl_Optarg)) 328 { 329 return (-1); 330 } 331 break; 332 333 default: 334 335 printf ("Unknown option: -f%s\n", AcpiGbl_Optarg); 336 return (-1); 337 } 338 break; 339 340 case 'g': 341 342 AcpiGbl_DbFilename = NULL; 343 break; 344 345 case 'h': 346 case '?': 347 348 usage(); 349 return (1); 350 351 case 'i': 352 353 Temp = strtoul (AcpiGbl_Optarg, NULL, 0); 354 if (!Temp || (Temp > ACPI_UINT16_MAX)) 355 { 356 printf ("%s: Invalid max loops value\n", AcpiGbl_Optarg); 357 return (-1); 358 } 359 360 AcpiGbl_MaxLoopIterations = (UINT16) Temp; 361 printf ("Max Loop Iterations is %u (0x%X)\n", 362 AcpiGbl_MaxLoopIterations, AcpiGbl_MaxLoopIterations); 363 break; 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 'v': 394 395 switch (AcpiGbl_Optarg[0]) 396 { 397 case '^': /* -v: (Version): signon already emitted, just exit */ 398 399 (void) AcpiOsTerminate (); 400 return (1); 401 402 case 'i': 403 404 AcpiDbgLevel |= ACPI_LV_INIT_NAMES; 405 break; 406 407 case 'r': 408 409 AcpiGbl_DisplayRegionAccess = TRUE; 410 break; 411 412 default: 413 414 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 415 return (-1); 416 } 417 break; 418 419 case 'x': 420 421 AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 0); 422 AcpiGbl_DbConsoleDebugLevel = AcpiDbgLevel; 423 printf ("Debug Level: 0x%8.8X\n", AcpiDbgLevel); 424 break; 425 426 default: 427 428 usage(); 429 return (-1); 430 } 431 432 return (0); 433 } 434 435 436 /****************************************************************************** 437 * 438 * FUNCTION: main 439 * 440 * PARAMETERS: argc, argv 441 * 442 * RETURN: Status 443 * 444 * DESCRIPTION: Main routine for AcpiExec utility 445 * 446 *****************************************************************************/ 447 448 int ACPI_SYSTEM_XFACE 449 main ( 450 int argc, 451 char **argv) 452 { 453 ACPI_NEW_TABLE_DESC *ListHead = NULL; 454 ACPI_STATUS Status; 455 UINT32 InitFlags; 456 int ExitCode = 0; 457 458 459 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 460 signal (SIGINT, AeCtrlCHandler); 461 462 /* Init debug globals */ 463 464 AcpiDbgLevel = ACPI_NORMAL_DEFAULT; 465 AcpiDbgLayer = 0xFFFFFFFF; 466 467 /* Init ACPICA and start debugger thread */ 468 469 Status = AcpiInitializeSubsystem (); 470 ACPI_CHECK_OK (AcpiInitializeSubsystem, Status); 471 if (ACPI_FAILURE (Status)) 472 { 473 goto ErrorExit; 474 } 475 476 /* ACPICA runtime configuration */ 477 478 AcpiGbl_MaxLoopIterations = 400; 479 480 481 /* Initialize the AML debugger */ 482 483 Status = AcpiInitializeDebugger (); 484 ACPI_CHECK_OK (AcpiInitializeDebugger, Status); 485 if (ACPI_FAILURE (Status)) 486 { 487 goto ErrorExit; 488 } 489 490 printf (ACPI_COMMON_SIGNON (ACPIEXEC_NAME)); 491 if (argc < 2) 492 { 493 usage (); 494 (void) AcpiOsTerminate (); 495 return (0); 496 } 497 498 /* Get the command line options */ 499 500 ExitCode = AeDoOptions (argc, argv); 501 if (ExitCode) 502 { 503 if (ExitCode > 0) 504 { 505 ExitCode = 0; 506 } 507 508 goto ErrorExit; 509 } 510 511 /* The remaining arguments are filenames for ACPI tables */ 512 513 if (!argv[AcpiGbl_Optind]) 514 { 515 goto EnterDebugger; 516 } 517 518 AcpiGbl_CstyleDisassembly = FALSE; /* Not supported for AcpiExec */ 519 520 /* Get each of the ACPI table files on the command line */ 521 522 while (argv[AcpiGbl_Optind]) 523 { 524 /* Get all ACPI AML tables in this file */ 525 526 Status = AcGetAllTablesFromFile (argv[AcpiGbl_Optind], 527 ACPI_GET_ONLY_AML_TABLES, &ListHead); 528 if (ACPI_FAILURE (Status)) 529 { 530 ExitCode = -1; 531 goto ErrorExit; 532 } 533 534 AcpiGbl_Optind++; 535 } 536 537 printf ("\n"); 538 539 /* Build a local RSDT with all tables and let ACPICA process the RSDT */ 540 541 Status = AeBuildLocalTables (ListHead); 542 if (ACPI_FAILURE (Status)) 543 { 544 goto ErrorExit; 545 } 546 547 /* Install all of the ACPI tables */ 548 549 Status = AeInstallTables (); 550 551 if (ACPI_FAILURE (Status)) 552 { 553 printf ("**** Could not install ACPI tables, %s\n", 554 AcpiFormatException (Status)); 555 goto EnterDebugger; 556 } 557 558 /* 559 * Install most of the handlers (Regions, Notify, Table, etc.) 560 * Override the default region handlers, especially SystemMemory, 561 * which is simulated in this utility. 562 */ 563 Status = AeInstallEarlyHandlers (); 564 if (ACPI_FAILURE (Status)) 565 { 566 goto EnterDebugger; 567 } 568 569 /* Setup initialization flags for ACPICA */ 570 571 InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); 572 if (AcpiGbl_DbOpt_NoIniMethods) 573 { 574 InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); 575 } 576 577 /* 578 * Main initialization for ACPICA subsystem 579 * TBD: Need a way to call this after the ACPI table "LOAD" command 580 */ 581 Status = AcpiEnableSubsystem (InitFlags); 582 if (ACPI_FAILURE (Status)) 583 { 584 printf ("**** Could not EnableSubsystem, %s\n", 585 AcpiFormatException (Status)); 586 goto EnterDebugger; 587 } 588 589 Status = AeLoadTables (); 590 591 /* 592 * Exit namespace initialization for the "load namespace only" option. 593 * No control methods will be executed. However, still enter the 594 * the debugger. 595 */ 596 if (AcpiGbl_AeLoadOnly) 597 { 598 goto EnterDebugger; 599 } 600 601 if (ACPI_FAILURE (Status)) 602 { 603 printf ("**** Could not load ACPI tables, %s\n", 604 AcpiFormatException (Status)); 605 goto EnterDebugger; 606 } 607 608 /* 609 * Install handlers for "device driver" space IDs (EC,SMBus, etc.) 610 * and fixed event handlers 611 */ 612 AeInstallLateHandlers (); 613 614 /* Finish the ACPICA initialization */ 615 616 Status = AcpiInitializeObjects (InitFlags); 617 if (ACPI_FAILURE (Status)) 618 { 619 printf ("**** Could not InitializeObjects, %s\n", 620 AcpiFormatException (Status)); 621 goto EnterDebugger; 622 } 623 624 AeMiscellaneousTests (); 625 626 627 EnterDebugger: 628 629 /* Exit if error above and we are in one of the batch modes */ 630 631 if (ACPI_FAILURE (Status) && (AcpiGbl_ExecutionMode > 0)) 632 { 633 goto ErrorExit; 634 } 635 636 /* Run a batch command or enter the command loop */ 637 638 switch (AcpiGbl_ExecutionMode) 639 { 640 default: 641 case AE_MODE_COMMAND_LOOP: 642 643 AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL); 644 break; 645 646 case AE_MODE_BATCH_MULTIPLE: 647 648 AcpiDbRunBatchMode (); 649 break; 650 651 case AE_MODE_BATCH_SINGLE: 652 653 AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); 654 break; 655 } 656 657 /* Shut down the debugger and ACPICA */ 658 659 #if 0 660 661 /* Temporarily removed */ 662 AcpiTerminateDebugger (); 663 Status = AcpiTerminate (); 664 #endif 665 666 Status = AcpiOsTerminate (); 667 return (0); 668 669 670 ErrorExit: 671 return (ExitCode); 672 } 673 674 675 /****************************************************************************** 676 * 677 * FUNCTION: AcpiDbRunBatchMode 678 * 679 * PARAMETERS: BatchCommandLine - A semicolon separated list of commands 680 * to be executed. 681 * Use only commas to separate elements of 682 * particular command. 683 * RETURN: None 684 * 685 * DESCRIPTION: For each command of list separated by ';' prepare the command 686 * buffer and pass it to AcpiDbCommandDispatch. 687 * 688 *****************************************************************************/ 689 690 static void 691 AcpiDbRunBatchMode ( 692 void) 693 { 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