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