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