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