Home | History | Annotate | Line # | Download | only in acpiexec
aemain.c revision 1.1.1.3
      1 /******************************************************************************
      2  *
      3  * Module Name: aemain - Main routine for the AcpiExec utility
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2011, 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 #ifdef _DEBUG
     47 #include <crtdbg.h>
     48 #endif
     49 
     50 #define _COMPONENT          PARSER
     51         ACPI_MODULE_NAME    ("aemain")
     52 
     53 
     54 UINT8                   AcpiGbl_RegionFillValue = 0;
     55 BOOLEAN                 AcpiGbl_IgnoreErrors = FALSE;
     56 BOOLEAN                 AcpiGbl_DbOpt_NoRegionSupport = FALSE;
     57 BOOLEAN                 AcpiGbl_DebugTimeout = FALSE;
     58 
     59 static UINT8            AcpiGbl_BatchMode = 0;
     60 static char             BatchBuffer[128];
     61 static AE_TABLE_DESC    *AeTableListHead = NULL;
     62 
     63 #define ASL_MAX_FILES   256
     64 static char             *FileList[ASL_MAX_FILES];
     65 
     66 
     67 #define AE_SUPPORTED_OPTIONS    "?b:d:e:f:gm^ovx:"
     68 
     69 
     70 /******************************************************************************
     71  *
     72  * FUNCTION:    usage
     73  *
     74  * PARAMETERS:  None
     75  *
     76  * RETURN:      None
     77  *
     78  * DESCRIPTION: Print a usage message
     79  *
     80  *****************************************************************************/
     81 
     82 static void
     83 usage (void)
     84 {
     85     printf ("Usage: acpiexec [options] AMLfile1 AMLfile2 ...\n\n");
     86 
     87     printf ("Where:\n");
     88     printf ("   -?                  Display this message\n");
     89     printf ("   -b <CommandLine>    Batch mode command execution\n");
     90     printf ("   -m [Method]         Batch mode method execution. Default=MAIN\n");
     91     printf ("\n");
     92 
     93     printf ("   -da                 Disable method abort on error\n");
     94     printf ("   -di                 Disable execution of STA/INI methods during init\n");
     95     printf ("   -do                 Disable Operation Region address simulation\n");
     96     printf ("   -dr                 Disable repair of method return values\n");
     97     printf ("   -dt                 Disable allocation tracking (performance)\n");
     98     printf ("\n");
     99 
    100     printf ("   -ef                 Enable display of final memory statistics\n");
    101     printf ("   -em                 Enable Interpreter Serialized Mode\n");
    102     printf ("   -es                 Enable Interpreter Slack Mode\n");
    103     printf ("   -et                 Enable debug semaphore timeout\n");
    104     printf ("\n");
    105 
    106     printf ("   -f <Value>          Operation Region initialization fill value\n");
    107     printf ("   -v                  Verbose initialization output\n");
    108     printf ("   -x <DebugLevel>     Debug output level\n");
    109 }
    110 
    111 
    112 /******************************************************************************
    113  *
    114  * FUNCTION:    AcpiDbRunBatchMode
    115  *
    116  * PARAMETERS:  BatchCommandLine    - A semicolon separated list of commands
    117  *                                    to be executed.
    118  *                                    Use only commas to separate elements of
    119  *                                    particular command.
    120  * RETURN:      Status
    121  *
    122  * DESCRIPTION: For each command of list separated by ';' prepare the command
    123  *              buffer and pass it to AcpiDbCommandDispatch.
    124  *
    125  *****************************************************************************/
    126 
    127 static ACPI_STATUS
    128 AcpiDbRunBatchMode (
    129     void)
    130 {
    131     ACPI_STATUS             Status;
    132     char                    *Ptr = BatchBuffer;
    133     char                    *Cmd = Ptr;
    134     UINT8                   Run = 0;
    135 
    136 
    137     AcpiGbl_MethodExecuting = FALSE;
    138     AcpiGbl_StepToNextCall = FALSE;
    139 
    140     while (*Ptr)
    141     {
    142         if (*Ptr == ',')
    143         {
    144             /* Convert commas to spaces */
    145             *Ptr = ' ';
    146         }
    147         else if (*Ptr == ';')
    148         {
    149             *Ptr = '\0';
    150             Run = 1;
    151         }
    152 
    153         Ptr++;
    154 
    155         if (Run || (*Ptr == '\0'))
    156         {
    157             (void) AcpiDbCommandDispatch (Cmd, NULL, NULL);
    158             Run = 0;
    159             Cmd = Ptr;
    160         }
    161     }
    162 
    163     Status = AcpiTerminate ();
    164     return (Status);
    165 }
    166 
    167 
    168 /*******************************************************************************
    169  *
    170  * FUNCTION:    FlStrdup
    171  *
    172  * DESCRIPTION: Local strdup function
    173  *
    174  ******************************************************************************/
    175 
    176 static char *
    177 FlStrdup (
    178     char                *String)
    179 {
    180     char                *NewString;
    181 
    182 
    183     NewString = AcpiOsAllocate (strlen (String) + 1);
    184     if (!NewString)
    185     {
    186         return (NULL);
    187     }
    188 
    189     strcpy (NewString, String);
    190     return (NewString);
    191 }
    192 
    193 
    194 /*******************************************************************************
    195  *
    196  * FUNCTION:    FlSplitInputPathname
    197  *
    198  * PARAMETERS:  InputFilename       - The user-specified ASL source file to be
    199  *                                    compiled
    200  *              OutDirectoryPath    - Where the directory path prefix is
    201  *                                    returned
    202  *              OutFilename         - Where the filename part is returned
    203  *
    204  * RETURN:      Status
    205  *
    206  * DESCRIPTION: Split the input path into a directory and filename part
    207  *              1) Directory part used to open include files
    208  *              2) Filename part used to generate output filenames
    209  *
    210  ******************************************************************************/
    211 
    212 ACPI_STATUS
    213 FlSplitInputPathname (
    214     char                    *InputPath,
    215     char                    **OutDirectoryPath,
    216     char                    **OutFilename)
    217 {
    218     char                    *Substring;
    219     char                    *DirectoryPath;
    220     char                    *Filename;
    221 
    222 
    223     *OutDirectoryPath = NULL;
    224     *OutFilename = NULL;
    225 
    226     if (!InputPath)
    227     {
    228         return (AE_OK);
    229     }
    230 
    231     /* Get the path to the input filename's directory */
    232 
    233     DirectoryPath = FlStrdup (InputPath);
    234     if (!DirectoryPath)
    235     {
    236         return (AE_NO_MEMORY);
    237     }
    238 
    239     Substring = strrchr (DirectoryPath, '\\');
    240     if (!Substring)
    241     {
    242         Substring = strrchr (DirectoryPath, '/');
    243         if (!Substring)
    244         {
    245             Substring = strrchr (DirectoryPath, ':');
    246         }
    247     }
    248 
    249     if (!Substring)
    250     {
    251         DirectoryPath[0] = 0;
    252         Filename = FlStrdup (InputPath);
    253     }
    254     else
    255     {
    256         Filename = FlStrdup (Substring + 1);
    257         *(Substring+1) = 0;
    258     }
    259 
    260     if (!Filename)
    261     {
    262         return (AE_NO_MEMORY);
    263     }
    264 
    265     *OutDirectoryPath = DirectoryPath;
    266     *OutFilename = Filename;
    267 
    268     return (AE_OK);
    269 }
    270 
    271 
    272 /******************************************************************************
    273  *
    274  * FUNCTION:    AsDoWildcard
    275  *
    276  * PARAMETERS:  DirectoryPathname   - Path to parent directory
    277  *              FileSpecifier       - the wildcard specification (*.c, etc.)
    278  *
    279  * RETURN:      Pointer to a list of filenames
    280  *
    281  * DESCRIPTION: Process files via wildcards. This function is for the Windows
    282  *              case only.
    283  *
    284  ******************************************************************************/
    285 
    286 static char **
    287 AsDoWildcard (
    288     char                    *DirectoryPathname,
    289     char                    *FileSpecifier)
    290 {
    291 #ifdef WIN32
    292     void                    *DirInfo;
    293     char                    *Filename;
    294     int                     FileCount;
    295 
    296 
    297     FileCount = 0;
    298 
    299     /* Open parent directory */
    300 
    301     DirInfo = AcpiOsOpenDirectory (DirectoryPathname, FileSpecifier, REQUEST_FILE_ONLY);
    302     if (!DirInfo)
    303     {
    304         /* Either the directory or file does not exist */
    305 
    306         printf ("File or directory %s%s does not exist\n", DirectoryPathname, FileSpecifier);
    307         return (NULL);
    308     }
    309 
    310     /* Process each file that matches the wildcard specification */
    311 
    312     while ((Filename = AcpiOsGetNextFilename (DirInfo)))
    313     {
    314         /* Add the filename to the file list */
    315 
    316         FileList[FileCount] = AcpiOsAllocate (strlen (Filename) + 1);
    317         strcpy (FileList[FileCount], Filename);
    318         FileCount++;
    319 
    320         if (FileCount >= ASL_MAX_FILES)
    321         {
    322             printf ("Max files reached\n");
    323             FileList[0] = NULL;
    324             return (FileList);
    325         }
    326     }
    327 
    328     /* Cleanup */
    329 
    330     AcpiOsCloseDirectory (DirInfo);
    331     FileList[FileCount] = NULL;
    332     return (FileList);
    333 
    334 #else
    335     if (!FileSpecifier)
    336     {
    337         return (NULL);
    338     }
    339 
    340     /*
    341      * Linux/Unix cases - Wildcards are expanded by the shell automatically.
    342      * Just return the filename in a null terminated list
    343      */
    344     FileList[0] = AcpiOsAllocate (strlen (FileSpecifier) + 1);
    345     strcpy (FileList[0], FileSpecifier);
    346     FileList[1] = NULL;
    347 
    348     return (FileList);
    349 #endif
    350 }
    351 
    352 
    353 /******************************************************************************
    354  *
    355  * FUNCTION:    main
    356  *
    357  * PARAMETERS:  argc, argv
    358  *
    359  * RETURN:      Status
    360  *
    361  * DESCRIPTION: Main routine for AcpiDump utility
    362  *
    363  *****************************************************************************/
    364 
    365 int ACPI_SYSTEM_XFACE
    366 main (
    367     int                     argc,
    368     char                    **argv)
    369 {
    370     int                     j;
    371     ACPI_STATUS             Status;
    372     UINT32                  InitFlags;
    373     ACPI_TABLE_HEADER       *Table = NULL;
    374     UINT32                  TableCount;
    375     AE_TABLE_DESC           *TableDesc;
    376     char                    **WildcardList;
    377     char                    *Filename;
    378     char                    *Directory;
    379     char                    *FullPathname;
    380 
    381 
    382 #ifdef _DEBUG
    383     _CrtSetDbgFlag (_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF |
    384                     _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
    385 #endif
    386 
    387     printf (ACPI_COMMON_SIGNON ("AML Execution/Debug Utility"));
    388 
    389     if (argc < 2)
    390     {
    391         usage ();
    392         return (0);
    393     }
    394 
    395     signal (SIGINT, AeCtrlCHandler);
    396 
    397     /* Init globals */
    398 
    399     AcpiDbgLevel = ACPI_NORMAL_DEFAULT;
    400     AcpiDbgLayer = 0xFFFFFFFF;
    401 
    402     /* Init ACPI and start debugger thread */
    403 
    404     Status = AcpiInitializeSubsystem ();
    405     AE_CHECK_OK (AcpiInitializeSubsystem, Status);
    406 
    407     /* Get the command line options */
    408 
    409     while ((j = AcpiGetopt (argc, argv, AE_SUPPORTED_OPTIONS)) != EOF) switch(j)
    410     {
    411     case 'b':
    412         if (strlen (AcpiGbl_Optarg) > 127)
    413         {
    414             printf ("**** The length of command line (%u) exceeded maximum (127)\n",
    415                 (UINT32) strlen (AcpiGbl_Optarg));
    416             return (-1);
    417         }
    418         AcpiGbl_BatchMode = 1;
    419         strcpy (BatchBuffer, AcpiGbl_Optarg);
    420         break;
    421 
    422     case 'd':
    423         switch (AcpiGbl_Optarg[0])
    424         {
    425         case 'a':
    426             AcpiGbl_IgnoreErrors = TRUE;
    427             break;
    428 
    429         case 'i':
    430             AcpiGbl_DbOpt_ini_methods = FALSE;
    431             break;
    432 
    433         case 'o':
    434             AcpiGbl_DbOpt_NoRegionSupport = TRUE;
    435             break;
    436 
    437         case 'r':
    438             AcpiGbl_DisableAutoRepair = TRUE;
    439             break;
    440 
    441         case 't':
    442             #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    443                 AcpiGbl_DisableMemTracking = TRUE;
    444             #endif
    445             break;
    446 
    447         default:
    448             printf ("Unknown option: -d%s\n", AcpiGbl_Optarg);
    449             return (-1);
    450         }
    451         break;
    452 
    453     case 'e':
    454         switch (AcpiGbl_Optarg[0])
    455         {
    456         case 'f':
    457             #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    458                 AcpiGbl_DisplayFinalMemStats = TRUE;
    459             #endif
    460             break;
    461 
    462         case 'm':
    463             AcpiGbl_AllMethodsSerialized = TRUE;
    464             printf ("Enabling AML Interpreter serialized mode\n");
    465             break;
    466 
    467         case 's':
    468             AcpiGbl_EnableInterpreterSlack = TRUE;
    469             printf ("Enabling AML Interpreter slack mode\n");
    470             break;
    471 
    472         case 't':
    473             AcpiGbl_DebugTimeout = TRUE;
    474             break;
    475 
    476         default:
    477             printf ("Unknown option: -e%s\n", AcpiGbl_Optarg);
    478             return (-1);
    479         }
    480         break;
    481 
    482     case 'f':
    483         AcpiGbl_RegionFillValue = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);
    484         break;
    485 
    486     case 'g':
    487         AcpiGbl_DbOpt_tables = TRUE;
    488         AcpiGbl_DbFilename = NULL;
    489         break;
    490 
    491     case 'm':
    492         AcpiGbl_BatchMode = 2;
    493         switch (AcpiGbl_Optarg[0])
    494         {
    495         case '^':
    496             strcpy (BatchBuffer, "MAIN");
    497             break;
    498 
    499         default:
    500             strcpy (BatchBuffer, AcpiGbl_Optarg);
    501             break;
    502         }
    503         break;
    504 
    505     case 'o':
    506         AcpiGbl_DbOpt_disasm = TRUE;
    507         AcpiGbl_DbOpt_stats = TRUE;
    508         break;
    509 
    510     case 'v':
    511         AcpiDbgLevel |= ACPI_LV_INIT_NAMES;
    512         break;
    513 
    514     case 'x':
    515         AcpiDbgLevel = strtoul (AcpiGbl_Optarg, NULL, 0);
    516         AcpiGbl_DbConsoleDebugLevel = AcpiDbgLevel;
    517         printf ("Debug Level: 0x%8.8X\n", AcpiDbgLevel);
    518         break;
    519 
    520     case '?':
    521     case 'h':
    522     default:
    523         usage();
    524         return (-1);
    525     }
    526 
    527 
    528     InitFlags = (ACPI_NO_HANDLER_INIT | ACPI_NO_ACPI_ENABLE);
    529     if (!AcpiGbl_DbOpt_ini_methods)
    530     {
    531         InitFlags |= (ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT);
    532     }
    533 
    534     /* The remaining arguments are filenames for ACPI tables */
    535 
    536     if (argv[AcpiGbl_Optind])
    537     {
    538         AcpiGbl_DbOpt_tables = TRUE;
    539         TableCount = 0;
    540 
    541         /* Get each of the ACPI table files on the command line */
    542 
    543         while (argv[AcpiGbl_Optind])
    544         {
    545             /* Split incoming path into a directory/filename combo */
    546 
    547             Status = FlSplitInputPathname (argv[AcpiGbl_Optind], &Directory, &Filename);
    548             if (ACPI_FAILURE (Status))
    549             {
    550                 return (Status);
    551             }
    552 
    553             /* Expand wildcards (Windows only) */
    554 
    555             WildcardList = AsDoWildcard (Directory, Filename);
    556             if (!WildcardList)
    557             {
    558                 return (-1);
    559             }
    560 
    561             while (*WildcardList)
    562             {
    563                 FullPathname = AcpiOsAllocate (
    564                     strlen (Directory) + strlen (*WildcardList) + 1);
    565 
    566                 /* Construct a full path to the file */
    567 
    568                 strcpy (FullPathname, Directory);
    569                 strcat (FullPathname, *WildcardList);
    570 
    571                 /* Get one table */
    572 
    573                 Status = AcpiDbReadTableFromFile (FullPathname, &Table);
    574                 if (ACPI_FAILURE (Status))
    575                 {
    576                     printf ("**** Could not get input table %s, %s\n", FullPathname,
    577                         AcpiFormatException (Status));
    578                     goto enterloop;
    579                 }
    580 
    581                 AcpiOsFree (FullPathname);
    582                 AcpiOsFree (*WildcardList);
    583                 *WildcardList = NULL;
    584                 WildcardList++;
    585 
    586                 /*
    587                  * Ignore an FACS or RSDT, we can't use them.
    588                  */
    589                 if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS) ||
    590                     ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDT))
    591                 {
    592                     AcpiOsFree (Table);
    593                     continue;
    594                 }
    595 
    596                 /* Allocate and link a table descriptor */
    597 
    598                 TableDesc = AcpiOsAllocate (sizeof (AE_TABLE_DESC));
    599                 TableDesc->Table = Table;
    600                 TableDesc->Next = AeTableListHead;
    601                 AeTableListHead = TableDesc;
    602 
    603                 TableCount++;
    604             }
    605 
    606             AcpiGbl_Optind++;
    607         }
    608 
    609         /* Build a local RSDT with all tables and let ACPICA process the RSDT */
    610 
    611         Status = AeBuildLocalTables (TableCount, AeTableListHead);
    612         if (ACPI_FAILURE (Status))
    613         {
    614             return (-1);
    615         }
    616 
    617         Status = AeInstallTables ();
    618         if (ACPI_FAILURE (Status))
    619         {
    620             printf ("**** Could not load ACPI tables, %s\n", AcpiFormatException (Status));
    621             goto enterloop;
    622         }
    623 
    624          /*
    625           * Install most of the handlers.
    626           * Override some default region handlers, especially SystemMemory
    627           */
    628         Status = AeInstallEarlyHandlers ();
    629         if (ACPI_FAILURE (Status))
    630         {
    631             goto enterloop;
    632         }
    633 
    634         /*
    635          * TBD: Need a way to call this after the "LOAD" command
    636          */
    637         Status = AcpiEnableSubsystem (InitFlags);
    638         if (ACPI_FAILURE (Status))
    639         {
    640             printf ("**** Could not EnableSubsystem, %s\n", AcpiFormatException (Status));
    641             goto enterloop;
    642         }
    643 
    644         Status = AcpiInitializeObjects (InitFlags);
    645         if (ACPI_FAILURE (Status))
    646         {
    647             printf ("**** Could not InitializeObjects, %s\n", AcpiFormatException (Status));
    648             goto enterloop;
    649         }
    650 
    651         /*
    652          * Install handlers for "device driver" space IDs (EC,SMBus, etc.)
    653          * and fixed event handlers
    654          */
    655         AeInstallLateHandlers ();
    656         AeMiscellaneousTests ();
    657     }
    658 
    659 enterloop:
    660 
    661     if (AcpiGbl_BatchMode == 1)
    662     {
    663         AcpiDbRunBatchMode ();
    664     }
    665     else if (AcpiGbl_BatchMode == 2)
    666     {
    667         AcpiDbExecute (BatchBuffer, NULL, NULL, EX_NO_SINGLE_STEP);
    668     }
    669     else
    670     {
    671         /* Enter the debugger command loop */
    672 
    673         AcpiDbUserCommands (ACPI_DEBUGGER_COMMAND_PROMPT, NULL);
    674     }
    675 
    676     return (0);
    677 }
    678 
    679