Home | History | Annotate | Line # | Download | only in common
dmtables.c revision 1.1.1.3
      1 /******************************************************************************
      2  *
      3  * Module Name: dmtables - disassembler ACPI table support
      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 "aslcompiler.h"
     45 #include "acdispat.h"
     46 #include "acnamesp.h"
     47 #include "actables.h"
     48 #include "acparser.h"
     49 #include "acapps.h"
     50 
     51 
     52 #define _COMPONENT          ACPI_TOOLS
     53         ACPI_MODULE_NAME    ("dmtables")
     54 
     55 
     56 /* Local prototypes */
     57 
     58 static void
     59 AdCreateTableHeader (
     60     char                    *Filename,
     61     ACPI_TABLE_HEADER       *Table);
     62 
     63 static ACPI_STATUS
     64 AdStoreTable (
     65     ACPI_TABLE_HEADER       *Table,
     66     UINT32                  *TableIndex);
     67 
     68 
     69 extern ACPI_TABLE_DESC      LocalTables[1];
     70 extern ACPI_PARSE_OBJECT    *AcpiGbl_ParseOpRoot;
     71 
     72 
     73 /******************************************************************************
     74  *
     75  * FUNCTION:    AdDisassemblerHeader
     76  *
     77  * PARAMETERS:  Filename            - Input file for the table
     78  *              TableType           - Either AML or DataTable
     79  *
     80  * RETURN:      None
     81  *
     82  * DESCRIPTION: Create the disassembler header, including ACPICA signon with
     83  *              current time and date.
     84  *
     85  *****************************************************************************/
     86 
     87 void
     88 AdDisassemblerHeader (
     89     char                    *Filename,
     90     UINT8                   TableType)
     91 {
     92     time_t                  Timer;
     93 
     94 
     95     time (&Timer);
     96 
     97     /* Header and input table info */
     98 
     99     AcpiOsPrintf ("/*\n");
    100     AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * "));
    101 
    102     if (TableType == ACPI_IS_AML_TABLE)
    103     {
    104         if (AcpiGbl_CstyleDisassembly)
    105         {
    106             AcpiOsPrintf (
    107                 " * Disassembling to symbolic ASL+ operators\n"
    108                 " *\n");
    109         }
    110         else
    111         {
    112             AcpiOsPrintf (
    113                 " * Disassembling to non-symbolic legacy ASL operators\n"
    114                 " *\n");
    115         }
    116     }
    117 
    118     AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
    119     AcpiOsPrintf (" *\n");
    120 }
    121 
    122 
    123 /******************************************************************************
    124  *
    125  * FUNCTION:    AdCreateTableHeader
    126  *
    127  * PARAMETERS:  Filename            - Input file for the table
    128  *              Table               - Pointer to the raw table
    129  *
    130  * RETURN:      None
    131  *
    132  * DESCRIPTION: Create the ASL table header, including ACPICA signon with
    133  *              current time and date.
    134  *
    135  *****************************************************************************/
    136 
    137 static void
    138 AdCreateTableHeader (
    139     char                    *Filename,
    140     ACPI_TABLE_HEADER       *Table)
    141 {
    142     UINT8                   Checksum;
    143 
    144 
    145     /* Reset globals for External statements */
    146 
    147     AcpiGbl_NumExternalMethods = 0;
    148     AcpiGbl_ResolvedExternalMethods = 0;
    149 
    150     /*
    151      * Print file header and dump original table header
    152      */
    153     AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE);
    154 
    155     AcpiOsPrintf (" * Original Table Header:\n");
    156     AcpiOsPrintf (" *     Signature        \"%4.4s\"\n",    Table->Signature);
    157     AcpiOsPrintf (" *     Length           0x%8.8X (%u)\n", Table->Length, Table->Length);
    158 
    159     /* Print and validate the revision */
    160 
    161     AcpiOsPrintf (" *     Revision         0x%2.2X",      Table->Revision);
    162 
    163     switch (Table->Revision)
    164     {
    165     case 0:
    166 
    167         AcpiOsPrintf (" **** Invalid Revision");
    168         break;
    169 
    170     case 1:
    171 
    172         /* Revision of DSDT controls the ACPI integer width */
    173 
    174         if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
    175         {
    176             AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
    177         }
    178         break;
    179 
    180     default:
    181 
    182         break;
    183     }
    184 
    185     /* Print and validate the table checksum */
    186 
    187     AcpiOsPrintf ("\n *     Checksum         0x%2.2X",        Table->Checksum);
    188 
    189     Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
    190     if (Checksum)
    191     {
    192         AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
    193             (UINT8) (Table->Checksum - Checksum));
    194     }
    195 
    196     AcpiOsPrintf ("\n");
    197     AcpiOsPrintf (" *     OEM ID           \"%.6s\"\n",     Table->OemId);
    198     AcpiOsPrintf (" *     OEM Table ID     \"%.8s\"\n",     Table->OemTableId);
    199     AcpiOsPrintf (" *     OEM Revision     0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
    200     AcpiOsPrintf (" *     Compiler ID      \"%.4s\"\n",     Table->AslCompilerId);
    201     AcpiOsPrintf (" *     Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
    202     AcpiOsPrintf (" */\n");
    203 
    204     /*
    205      * Open the ASL definition block.
    206      *
    207      * Note: the AMLFilename string is left zero-length in order to just let
    208      * the compiler create it when the disassembled file is compiled. This
    209      * makes it easier to rename the disassembled ASL file if needed.
    210      */
    211     AcpiOsPrintf (
    212         "DefinitionBlock (\"\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
    213         Table->Signature, Table->Revision,
    214         Table->OemId, Table->OemTableId, Table->OemRevision);
    215 }
    216 
    217 
    218 /******************************************************************************
    219  *
    220  * FUNCTION:    AdDisplayTables
    221  *
    222  * PARAMETERS:  Filename            - Input file for the table
    223  *              Table               - Pointer to the raw table
    224  *
    225  * RETURN:      Status
    226  *
    227  * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
    228  *
    229  *****************************************************************************/
    230 
    231 ACPI_STATUS
    232 AdDisplayTables (
    233     char                    *Filename,
    234     ACPI_TABLE_HEADER       *Table)
    235 {
    236 
    237 
    238     if (!AcpiGbl_ParseOpRoot)
    239     {
    240         return (AE_NOT_EXIST);
    241     }
    242 
    243     if (!AcpiGbl_DmOpt_Listing)
    244     {
    245         AdCreateTableHeader (Filename, Table);
    246     }
    247 
    248     AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
    249     MpEmitMappingInfo ();
    250 
    251     if (AcpiGbl_DmOpt_Listing)
    252     {
    253         AcpiOsPrintf ("\n\nTable Header:\n");
    254         AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
    255             DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    256 
    257         AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
    258         AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)),
    259             Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    260     }
    261 
    262     return (AE_OK);
    263 }
    264 
    265 
    266 /*******************************************************************************
    267  *
    268  * FUNCTION:    AdStoreTable
    269  *
    270  * PARAMETERS:  Table               - Table header
    271  *              TableIndex          - Where the table index is returned
    272  *
    273  * RETURN:      Status and table index.
    274  *
    275  * DESCRIPTION: Add an ACPI table to the global table list
    276  *
    277  ******************************************************************************/
    278 
    279 static ACPI_STATUS
    280 AdStoreTable (
    281     ACPI_TABLE_HEADER       *Table,
    282     UINT32                  *TableIndex)
    283 {
    284     ACPI_STATUS             Status;
    285     ACPI_TABLE_DESC         *TableDesc;
    286 
    287 
    288     Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc);
    289     if (ACPI_FAILURE (Status))
    290     {
    291         return (Status);
    292     }
    293 
    294     /* Initialize added table */
    295 
    296     AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table),
    297         ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table);
    298     Status = AcpiTbValidateTable (TableDesc);
    299     return (Status);
    300 }
    301 
    302 
    303 /******************************************************************************
    304  *
    305  * FUNCTION:    AdGetLocalTables
    306  *
    307  * PARAMETERS:  None
    308  *
    309  * RETURN:      Status
    310  *
    311  * DESCRIPTION: Get the ACPI tables from either memory or a file
    312  *
    313  *****************************************************************************/
    314 
    315 ACPI_STATUS
    316 AdGetLocalTables (
    317     void)
    318 {
    319     ACPI_STATUS             Status;
    320     ACPI_TABLE_HEADER       TableHeader;
    321     ACPI_TABLE_HEADER       *NewTable;
    322     UINT32                  TableIndex;
    323 
    324 
    325     /* Get the DSDT via table override */
    326 
    327     ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
    328     AcpiOsTableOverride (&TableHeader, &NewTable);
    329     if (!NewTable)
    330     {
    331         fprintf (stderr, "Could not obtain DSDT\n");
    332         return (AE_NO_ACPI_TABLES);
    333     }
    334 
    335     AdWriteTable (NewTable, NewTable->Length,
    336         ACPI_SIG_DSDT, NewTable->OemTableId);
    337 
    338     /* Store DSDT in the Table Manager */
    339 
    340     Status = AdStoreTable (NewTable, &TableIndex);
    341     if (ACPI_FAILURE (Status))
    342     {
    343         fprintf (stderr, "Could not store DSDT\n");
    344         return (AE_NO_ACPI_TABLES);
    345     }
    346 
    347     return (AE_OK);
    348 }
    349 
    350 
    351 /******************************************************************************
    352  *
    353  * FUNCTION:    AdParseTable
    354  *
    355  * PARAMETERS:  Table               - Pointer to the raw table
    356  *              OwnerId             - Returned OwnerId of the table
    357  *              LoadTable           - If add table to the global table list
    358  *              External            - If this is an external table
    359  *
    360  * RETURN:      Status
    361  *
    362  * DESCRIPTION: Parse an ACPI AML table
    363  *
    364  *****************************************************************************/
    365 
    366 ACPI_STATUS
    367 AdParseTable (
    368     ACPI_TABLE_HEADER       *Table,
    369     ACPI_OWNER_ID           *OwnerId,
    370     BOOLEAN                 LoadTable,
    371     BOOLEAN                 External)
    372 {
    373     ACPI_STATUS             Status = AE_OK;
    374     ACPI_WALK_STATE         *WalkState;
    375     UINT8                   *AmlStart;
    376     UINT32                  AmlLength;
    377     UINT32                  TableIndex;
    378 
    379 
    380     if (!Table)
    381     {
    382         return (AE_NOT_EXIST);
    383     }
    384 
    385     /* Pass 1:  Parse everything except control method bodies */
    386 
    387     fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
    388 
    389     AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
    390     AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
    391 
    392     /* Create the root object */
    393 
    394     AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (AmlStart);
    395     if (!AcpiGbl_ParseOpRoot)
    396     {
    397         return (AE_NO_MEMORY);
    398     }
    399 
    400     /* Create and initialize a new walk state */
    401 
    402     WalkState = AcpiDsCreateWalkState (0, AcpiGbl_ParseOpRoot, NULL, NULL);
    403     if (!WalkState)
    404     {
    405         return (AE_NO_MEMORY);
    406     }
    407 
    408     Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
    409         NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    410     if (ACPI_FAILURE (Status))
    411     {
    412         return (Status);
    413     }
    414 
    415     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
    416     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
    417 
    418     Status = AcpiPsParseAml (WalkState);
    419     if (ACPI_FAILURE (Status))
    420     {
    421         return (Status);
    422     }
    423 
    424     /* If LoadTable is FALSE, we are parsing the last loaded table */
    425 
    426     TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
    427 
    428     /* Pass 2 */
    429 
    430     if (LoadTable)
    431     {
    432         Status = AdStoreTable (Table, &TableIndex);
    433         if (ACPI_FAILURE (Status))
    434         {
    435             return (Status);
    436         }
    437         Status = AcpiTbAllocateOwnerId (TableIndex);
    438         if (ACPI_FAILURE (Status))
    439         {
    440             return (Status);
    441         }
    442         if (OwnerId)
    443         {
    444             Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
    445             if (ACPI_FAILURE (Status))
    446             {
    447                 return (Status);
    448             }
    449         }
    450     }
    451 
    452     fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
    453 
    454     Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
    455     if (ACPI_FAILURE (Status))
    456     {
    457         return (Status);
    458     }
    459 
    460     /* No need to parse control methods of external table */
    461 
    462     if (External)
    463     {
    464         return (AE_OK);
    465     }
    466 
    467     /*
    468      * Pass 3: Parse control methods and link their parse trees
    469      * into the main parse tree
    470      */
    471     fprintf (stderr,
    472         "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
    473 
    474     Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot);
    475     fprintf (stderr, "\n");
    476 
    477     /* Process Resource Templates */
    478 
    479     AcpiDmFindResources (AcpiGbl_ParseOpRoot);
    480 
    481     fprintf (stderr, "Parsing completed\n");
    482     return (AE_OK);
    483 }
    484