1 /****************************************************************************** 2 * 3 * Module Name: aemain - Main routine for the AcpiExec utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 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 static UINT8 AcpiGbl_ExecutionMode = AE_MODE_COMMAND_LOOP; 94 static char BatchBuffer[AE_BUFFER_SIZE]; /* Batch command buffer */ 95 static AE_TABLE_DESC *AeTableListHead = NULL; 96 97 #define ACPIEXEC_NAME "AML Execution/Debug Utility" 98 #define AE_SUPPORTED_OPTIONS "?b:d:e:f:ghm^orv^:x:" 99 100 101 /****************************************************************************** 102 * 103 * FUNCTION: usage 104 * 105 * PARAMETERS: None 106 * 107 * RETURN: None 108 * 109 * DESCRIPTION: Print a usage message 110 * 111 *****************************************************************************/ 112 113 static void 114 usage ( 115 void) 116 { 117 118 ACPI_USAGE_HEADER ("acpiexec [options] AMLfile1 AMLfile2 ..."); 119 120 ACPI_OPTION ("-b \"CommandLine\"", "Batch mode command line execution (cmd1;cmd2;...)"); 121 ACPI_OPTION ("-h -?", "Display this help message"); 122 ACPI_OPTION ("-m [Method]", "Batch mode method execution. Default=MAIN"); 123 printf ("\n"); 124 125 ACPI_OPTION ("-da", "Disable method abort on error"); 126 ACPI_OPTION ("-di", "Disable execution of STA/INI methods during init"); 127 ACPI_OPTION ("-do", "Disable Operation Region address simulation"); 128 ACPI_OPTION ("-dr", "Disable repair of method return values"); 129 ACPI_OPTION ("-dt", "Disable allocation tracking (performance)"); 130 printf ("\n"); 131 132 ACPI_OPTION ("-ef", "Enable display of final memory statistics"); 133 ACPI_OPTION ("-ei", "Enable additional tests for ACPICA interfaces"); 134 ACPI_OPTION ("-em", "Enable Interpreter Serialized Mode"); 135 ACPI_OPTION ("-es", "Enable Interpreter Slack Mode"); 136 ACPI_OPTION ("-et", "Enable debug semaphore timeout"); 137 printf ("\n"); 138 139 ACPI_OPTION ("-f <Value>", "Operation Region initialization fill value"); 140 ACPI_OPTION ("-r", "Use hardware-reduced FADT V5"); 141 ACPI_OPTION ("-v", "Display version information"); 142 ACPI_OPTION ("-vi", "Verbose initialization output"); 143 ACPI_OPTION ("-vr", "Verbose region handler output"); 144 ACPI_OPTION ("-x <DebugLevel>", "Debug output level"); 145 } 146 147 148 /****************************************************************************** 149 * 150 * FUNCTION: AeDoOptions 151 * 152 * PARAMETERS: argc/argv - Standard argc/argv 153 * 154 * RETURN: Status 155 * 156 * DESCRIPTION: Command line option processing 157 * 158 *****************************************************************************/ 159 160 static int 161 AeDoOptions ( 162 int argc, 163 char **argv) 164 { 165 int j; 166 167 168 while ((j = AcpiGetopt (argc, argv, AE_SUPPORTED_OPTIONS)) != EOF) switch (j) 169 { 170 case 'b': 171 172 if (strlen (AcpiGbl_Optarg) > (AE_BUFFER_SIZE -1)) 173 { 174 printf ("**** The length of command line (%u) exceeded maximum (%u)\n", 175 (UINT32) strlen (AcpiGbl_Optarg), (AE_BUFFER_SIZE -1)); 176 return (-1); 177 } 178 AcpiGbl_ExecutionMode = AE_MODE_BATCH_MULTIPLE; 179 strcpy (BatchBuffer, AcpiGbl_Optarg); 180 break; 181 182 case 'd': 183 184 switch (AcpiGbl_Optarg[0]) 185 { 186 case 'a': 187 188 AcpiGbl_IgnoreErrors = TRUE; 189 break; 190 191 case 'i': 192 193 AcpiGbl_DbOpt_ini_methods = FALSE; 194 break; 195 196 case 'o': 197 198 AcpiGbl_DbOpt_NoRegionSupport = TRUE; 199 break; 200 201 case 'r': 202 203 AcpiGbl_DisableAutoRepair = TRUE; 204 break; 205 206 case 't': 207 208 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 209 AcpiGbl_DisableMemTracking = TRUE; 210 #endif 211 break; 212 213 default: 214 215 printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); 216 return (-1); 217 } 218 break; 219 220 case 'e': 221 222 switch (AcpiGbl_Optarg[0]) 223 { 224 case 'f': 225 226 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 227 AcpiGbl_DisplayFinalMemStats = TRUE; 228 #endif 229 break; 230 231 case 'i': 232 233 AcpiGbl_DoInterfaceTests = TRUE; 234 break; 235 236 case 'm': 237 238 AcpiGbl_AllMethodsSerialized = TRUE; 239 printf ("Enabling AML Interpreter serialized mode\n"); 240 break; 241 242 case 's': 243 244 AcpiGbl_EnableInterpreterSlack = TRUE; 245 printf ("Enabling AML Interpreter slack mode\n"); 246 break; 247 248 case 't': 249 250 AcpiGbl_DebugTimeout = TRUE; 251 break; 252 253 default: 254 255 printf ("Unknown option: -e%s\n", AcpiGbl_Optarg); 256 return (-1); 257 } 258 break; 259 260 case 'f': 261 262 AcpiGbl_RegionFillValue = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); 263 break; 264 265 case 'g': 266 267 AcpiGbl_DbOpt_tables = TRUE; 268 AcpiGbl_DbFilename = NULL; 269 break; 270 271 case 'h': 272 case '?': 273 274 usage(); 275 return (0); 276 277 case 'm': 278 279 AcpiGbl_ExecutionMode = AE_MODE_BATCH_SINGLE; 280 switch (AcpiGbl_Optarg[0]) 281 { 282 case '^': 283 284 strcpy (BatchBuffer, "MAIN"); 285 break; 286 287 default: 288 289 strcpy (BatchBuffer, AcpiGbl_Optarg); 290 break; 291 } 292 break; 293 294 case 'o': 295 296 AcpiGbl_DbOpt_disasm = TRUE; 297 AcpiGbl_DbOpt_stats = TRUE; 298 break; 299 300 case 'r': 301 302 AcpiGbl_UseHwReducedFadt = TRUE; 303 printf ("Using ACPI 5.0 Hardware Reduced Mode via version 5 FADT\n"); 304 break; 305 306 case 'v': 307 308 switch (AcpiGbl_Optarg[0]) 309 { 310 case '^': /* -v: (Version): signon already emitted, just exit */ 311 312 exit (0); 313 314 case 'i': 315 316 AcpiDbgLevel |= ACPI_LV_INIT_NAMES; 317 break; 318 319 case 'r': 320 321 AcpiGbl_DisplayRegionAccess = TRUE; 322 break; 323 324 default: 325 326 printf ("Unknown option: -v%s\n", AcpiGbl_Optarg); 327 return (-1); 328 } 329 break; 330 331 case 'x': 332 333 AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 0); 334 AcpiGbl_DbConsoleDebugLevel = AcpiDbgLevel; 335 printf ("Debug Level: 0x%8.8X\n", AcpiDbgLevel); 336 break; 337 338 default: 339 340 usage(); 341 return (-1); 342 } 343 344 return (0); 345 } 346 347 348 /****************************************************************************** 349 * 350 * FUNCTION: main 351 * 352 * PARAMETERS: argc, argv 353 * 354 * RETURN: Status 355 * 356 * DESCRIPTION: Main routine for AcpiExec utility 357 * 358 *****************************************************************************/ 359 360 int ACPI_SYSTEM_XFACE 361 main ( 362 int argc, 363 char **argv) 364 { 365 ACPI_STATUS Status; 366 UINT32 InitFlags; 367 ACPI_TABLE_HEADER *Table = NULL; 368 UINT32 TableCount; 369 AE_TABLE_DESC *TableDesc; 370 371 372 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 373 374 printf (ACPI_COMMON_SIGNON (ACPIEXEC_NAME)); 375 if (argc < 2) 376 { 377 usage (); 378 return (0); 379 } 380 381 signal (SIGINT, AeCtrlCHandler); 382 383 /* Init globals */ 384 385 AcpiDbgLevel = ACPI_NORMAL_DEFAULT; 386 AcpiDbgLayer = 0xFFFFFFFF; 387 388 /* Init ACPI and start debugger thread */ 389 390 Status = AcpiInitializeSubsystem (); 391 AE_CHECK_OK (AcpiInitializeSubsystem, Status); 392 if (ACPI_FAILURE (Status)) 393 { 394 goto ErrorExit; 395 } 396 397 /* Get the command line options */ 398 399 if (AeDoOptions (argc, argv)) 400 { 401 goto ErrorExit; 402 } 403 404 /* The remaining arguments are filenames for ACPI tables */ 405 406 if (!argv[AcpiGbl_Optind]) 407 { 408 goto EnterDebugger; 409 } 410 411 AcpiGbl_DbOpt_tables = TRUE; 412 TableCount = 0; 413 414 /* Get each of the ACPI table files on the command line */ 415 416 while (argv[AcpiGbl_Optind]) 417 { 418 /* Get one entire table */ 419 420 Status = AcpiDbReadTableFromFile (argv[AcpiGbl_Optind], &Table); 421 if (ACPI_FAILURE (Status)) 422 { 423 printf ("**** Could not get table from file %s, %s\n", 424 argv[AcpiGbl_Optind], AcpiFormatException (Status)); 425 goto ErrorExit; 426 } 427 428 /* Ignore non-AML tables, we can't use them. Except for an FADT */ 429 430 if (!ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FADT) && 431 !AcpiUtIsAmlTable (Table)) 432 { 433 ACPI_INFO ((AE_INFO, 434 "Table [%4.4s] is not an AML table, ignoring", 435 Table->Signature)); 436 AcpiOsFree (Table); 437 } 438 else 439 { 440 /* Allocate and link a table descriptor */ 441 442 TableDesc = AcpiOsAllocate (sizeof (AE_TABLE_DESC)); 443 TableDesc->Table = Table; 444 TableDesc->Next = AeTableListHead; 445 AeTableListHead = TableDesc; 446 447 TableCount++; 448 } 449 450 AcpiGbl_Optind++; 451 } 452 453 /* Build a local RSDT with all tables and let ACPICA process the RSDT */ 454 455 Status = AeBuildLocalTables (TableCount, AeTableListHead); 456 if (ACPI_FAILURE (Status)) 457 { 458 goto ErrorExit; 459 } 460 461 Status = AeInstallTables (); 462 if (ACPI_FAILURE (Status)) 463 { 464 printf ("**** Could not load ACPI tables, %s\n", 465 AcpiFormatException (Status)); 466 goto EnterDebugger; 467 } 468 469 /* 470 * Install most of the handlers. 471 * Override some default region handlers, especially SystemMemory 472 */ 473 Status = AeInstallEarlyHandlers (); 474 if (ACPI_FAILURE (Status)) 475 { 476 goto EnterDebugger; 477 } 478 479 /* Setup initialization flags for ACPICA */ 480 481 InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE); 482 if (!AcpiGbl_DbOpt_ini_methods) 483 { 484 InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT); 485 } 486 487 /* 488 * Main initialization for ACPICA subsystem 489 * TBD: Need a way to call this after the ACPI table "LOAD" command 490 */ 491 Status = AcpiEnableSubsystem (InitFlags); 492 if (ACPI_FAILURE (Status)) 493 { 494 printf ("**** Could not EnableSubsystem, %s\n", 495 AcpiFormatException (Status)); 496 goto EnterDebugger; 497 } 498 499 /* 500 * Install handlers for "device driver" space IDs (EC,SMBus, etc.) 501 * and fixed event handlers 502 */ 503 AeInstallLateHandlers (); 504 505 /* Finish the ACPICA initialization */ 506 507 Status = AcpiInitializeObjects (InitFlags); 508 if (ACPI_FAILURE (Status)) 509 { 510 printf ("**** Could not InitializeObjects, %s\n", 511 AcpiFormatException (Status)); 512 goto EnterDebugger; 513 } 514 515 AeMiscellaneousTests (); 516 517 518 EnterDebugger: 519 520 /* Exit if error above and we are in one of the batch modes */ 521 522 if (ACPI_FAILURE (Status) && (AcpiGbl_ExecutionMode > 0)) 523 { 524 goto ErrorExit; 525 } 526 527 /* Run a batch command or enter the command loop */ 528 529 switch (AcpiGbl_ExecutionMode) 530 { 531 default: 532 case AE_MODE_COMMAND_LOOP: 533 534 AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL); 535 break; 536 537 case AE_MODE_BATCH_MULTIPLE: 538 539 AcpiDbRunBatchMode (); 540 break; 541 542 case AE_MODE_BATCH_SINGLE: 543 544 AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP); 545 Status = AcpiTerminate (); 546 break; 547 } 548 549 return (0); 550 551 552 ErrorExit: 553 554 (void) AcpiOsTerminate (); 555 return (-1); 556 } 557 558 559 /****************************************************************************** 560 * 561 * FUNCTION: AcpiDbRunBatchMode 562 * 563 * PARAMETERS: BatchCommandLine - A semicolon separated list of commands 564 * to be executed. 565 * Use only commas to separate elements of 566 * particular command. 567 * RETURN: Status 568 * 569 * DESCRIPTION: For each command of list separated by ';' prepare the command 570 * buffer and pass it to AcpiDbCommandDispatch. 571 * 572 *****************************************************************************/ 573 574 static ACPI_STATUS 575 AcpiDbRunBatchMode ( 576 void) 577 { 578 ACPI_STATUS Status; 579 char *Ptr = BatchBuffer; 580 char *Cmd = Ptr; 581 UINT8 Run = 0; 582 583 584 AcpiGbl_MethodExecuting = FALSE; 585 AcpiGbl_StepToNextCall = FALSE; 586 587 while (*Ptr) 588 { 589 if (*Ptr == ',') 590 { 591 /* Convert commas to spaces */ 592 *Ptr = ' '; 593 } 594 else if (*Ptr == ';') 595 { 596 *Ptr = '\0'; 597 Run = 1; 598 } 599 600 Ptr++; 601 602 if (Run || (*Ptr == '\0')) 603 { 604 (void) AcpiDbCommandDispatch (Cmd, NULL, NULL); 605 Run = 0; 606 Cmd = Ptr; 607 } 608 } 609 610 Status = AcpiTerminate (); 611 return (Status); 612 }