Home | History | Annotate | Line # | Download | only in common
adisasm.c revision 1.1.1.4.2.2
      1 /******************************************************************************
      2  *
      3  * Module Name: adisasm - Application-level disassembler routines
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, 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 "acparser.h"
     46 #include "amlcode.h"
     47 #include "acdisasm.h"
     48 #include "acdispat.h"
     49 #include "acnamesp.h"
     50 #include "actables.h"
     51 #include "acapps.h"
     52 
     53 #include <stdio.h>
     54 #include <time.h>
     55 
     56 
     57 #define _COMPONENT          ACPI_TOOLS
     58         ACPI_MODULE_NAME    ("adisasm")
     59 
     60 /* Local prototypes */
     61 
     62 static void
     63 AdCreateTableHeader (
     64     char                    *Filename,
     65     ACPI_TABLE_HEADER       *Table);
     66 
     67 static ACPI_STATUS
     68 AdStoreTable (
     69     ACPI_TABLE_HEADER       *Table,
     70     UINT32                  *TableIndex);
     71 
     72 /* Stubs for ASL compiler */
     73 
     74 #ifndef ACPI_ASL_COMPILER
     75 BOOLEAN
     76 AcpiDsIsResultUsed (
     77     ACPI_PARSE_OBJECT       *Op,
     78     ACPI_WALK_STATE         *WalkState)
     79 {
     80     return TRUE;
     81 }
     82 
     83 ACPI_STATUS
     84 AcpiDsMethodError (
     85     ACPI_STATUS             Status,
     86     ACPI_WALK_STATE         *WalkState)
     87 {
     88     return (Status);
     89 }
     90 #endif
     91 
     92 ACPI_STATUS
     93 AcpiNsLoadTable (
     94     UINT32                  TableIndex,
     95     ACPI_NAMESPACE_NODE     *Node)
     96 {
     97     return (AE_NOT_IMPLEMENTED);
     98 }
     99 
    100 ACPI_STATUS
    101 AcpiDsRestartControlMethod (
    102     ACPI_WALK_STATE         *WalkState,
    103     ACPI_OPERAND_OBJECT     *ReturnDesc)
    104 {
    105     return (AE_OK);
    106 }
    107 
    108 void
    109 AcpiDsTerminateControlMethod (
    110     ACPI_OPERAND_OBJECT     *MethodDesc,
    111     ACPI_WALK_STATE         *WalkState)
    112 {
    113     return;
    114 }
    115 
    116 ACPI_STATUS
    117 AcpiDsCallControlMethod (
    118     ACPI_THREAD_STATE       *Thread,
    119     ACPI_WALK_STATE         *WalkState,
    120     ACPI_PARSE_OBJECT       *Op)
    121 {
    122     return (AE_OK);
    123 }
    124 
    125 ACPI_STATUS
    126 AcpiDsMethodDataInitArgs (
    127     ACPI_OPERAND_OBJECT     **Params,
    128     UINT32                  MaxParamCount,
    129     ACPI_WALK_STATE         *WalkState)
    130 {
    131     return (AE_OK);
    132 }
    133 
    134 
    135 static ACPI_TABLE_DESC      LocalTables[1];
    136 ACPI_PARSE_OBJECT    *AcpiGbl_ParseOpRoot;
    137 
    138 
    139 /*******************************************************************************
    140  *
    141  * FUNCTION:    AdInitialize
    142  *
    143  * PARAMETERS:  None
    144  *
    145  * RETURN:      Status
    146  *
    147  * DESCRIPTION: ACPICA and local initialization
    148  *
    149  ******************************************************************************/
    150 
    151 ACPI_STATUS
    152 AdInitialize (
    153     void)
    154 {
    155     ACPI_STATUS             Status;
    156 
    157 
    158     /* ACPICA subsystem initialization */
    159 
    160     Status = AcpiOsInitialize ();
    161     if (ACPI_FAILURE (Status))
    162     {
    163         return (Status);
    164     }
    165 
    166     Status = AcpiUtInitGlobals ();
    167     if (ACPI_FAILURE (Status))
    168     {
    169         return (Status);
    170     }
    171 
    172     Status = AcpiUtMutexInitialize ();
    173     if (ACPI_FAILURE (Status))
    174     {
    175         return (Status);
    176     }
    177 
    178     Status = AcpiNsRootInitialize ();
    179     if (ACPI_FAILURE (Status))
    180     {
    181         return (Status);
    182     }
    183 
    184     /* Setup the Table Manager (cheat - there is no RSDT) */
    185 
    186     AcpiGbl_RootTableList.MaxTableCount = 1;
    187     AcpiGbl_RootTableList.CurrentTableCount = 0;
    188     AcpiGbl_RootTableList.Tables = LocalTables;
    189 
    190     AcpiGbl_PreviousOp = NULL;
    191     return (Status);
    192 }
    193 
    194 
    195 /******************************************************************************
    196  *
    197  * FUNCTION:    AdAmlDisassemble
    198  *
    199  * PARAMETERS:  Filename            - AML input filename
    200  *              OutToFile           - TRUE if output should go to a file
    201  *              Prefix              - Path prefix for output
    202  *              OutFilename         - where the filename is returned
    203  *
    204  * RETURN:      Status
    205  *
    206  * DESCRIPTION: Disassemble an entire ACPI table
    207  *
    208  *****************************************************************************/
    209 
    210 ACPI_STATUS
    211 AdAmlDisassemble (
    212     BOOLEAN                 OutToFile,
    213     char                    *Filename,
    214     char                    *Prefix,
    215     char                    **OutFilename)
    216 {
    217     ACPI_STATUS             Status;
    218     ACPI_STATUS             GlobalStatus = AE_OK;
    219     char                    *DisasmFilename = NULL;
    220     char                    *ExternalFilename;
    221     ACPI_EXTERNAL_FILE      *ExternalFileList = AcpiGbl_ExternalFileList;
    222     FILE                    *File = NULL;
    223     ACPI_TABLE_HEADER       *Table = NULL;
    224     ACPI_TABLE_HEADER       *ExternalTable;
    225     ACPI_OWNER_ID           OwnerId;
    226 
    227 
    228     /*
    229      * Input: AML code from either a file or via GetTables (memory or
    230      * registry)
    231      */
    232     if (Filename)
    233     {
    234         Status = AcpiDbGetTableFromFile (Filename, &Table, FALSE);
    235         if (ACPI_FAILURE (Status))
    236         {
    237             return (Status);
    238         }
    239 
    240         /*
    241          * External filenames separated by commas
    242          * Example: iasl -e file1,file2,file3 -d xxx.aml
    243          */
    244         while (ExternalFileList)
    245         {
    246             ExternalFilename = ExternalFileList->Path;
    247             if (!strcmp (ExternalFilename, Filename))
    248             {
    249                 /* Next external file */
    250 
    251                 ExternalFileList = ExternalFileList->Next;
    252                 continue;
    253             }
    254 
    255             Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable, TRUE);
    256             if (ACPI_FAILURE (Status))
    257             {
    258                 if (Status == AE_TYPE)
    259                 {
    260                     ExternalFileList = ExternalFileList->Next;
    261                     GlobalStatus = AE_TYPE;
    262                     Status = AE_OK;
    263                     continue;
    264                 }
    265                 return (Status);
    266             }
    267 
    268             /* Load external table for symbol resolution */
    269 
    270             if (ExternalTable)
    271             {
    272                 Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
    273                 if (ACPI_FAILURE (Status))
    274                 {
    275                     AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
    276                         AcpiFormatException (Status));
    277                     return (Status);
    278                 }
    279 
    280                 /*
    281                  * Load namespace from names created within control methods
    282                  * Set owner id of nodes in external table
    283                  */
    284                 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
    285                     AcpiGbl_RootNode, OwnerId);
    286                 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    287             }
    288 
    289             /* Next external file */
    290 
    291             ExternalFileList = ExternalFileList->Next;
    292         }
    293 
    294         if (ACPI_FAILURE (GlobalStatus))
    295         {
    296             return (GlobalStatus);
    297         }
    298 
    299         /* Clear external list generated by Scope in external tables */
    300 
    301         if (AcpiGbl_ExternalFileList)
    302         {
    303             AcpiDmClearExternalList ();
    304         }
    305 
    306         /* Load any externals defined in the optional external ref file */
    307 
    308         AcpiDmGetExternalsFromFile ();
    309     }
    310     else
    311     {
    312         Status = AdGetLocalTables ();
    313         if (ACPI_FAILURE (Status))
    314         {
    315             AcpiOsPrintf ("Could not get ACPI tables, %s\n",
    316                 AcpiFormatException (Status));
    317             return (Status);
    318         }
    319 
    320         if (!AcpiGbl_DbOpt_Disasm)
    321         {
    322             return (AE_OK);
    323         }
    324 
    325         /* Obtained the local tables, just disassemble the DSDT */
    326 
    327         Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
    328         if (ACPI_FAILURE (Status))
    329         {
    330             AcpiOsPrintf ("Could not get DSDT, %s\n",
    331                 AcpiFormatException (Status));
    332             return (Status);
    333         }
    334 
    335         AcpiOsPrintf ("\nDisassembly of DSDT\n");
    336         Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
    337     }
    338 
    339     /*
    340      * Output: ASL code. Redirect to a file if requested
    341      */
    342     if (OutToFile)
    343     {
    344         /* Create/Open a disassembly output file */
    345 
    346         DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
    347         if (!DisasmFilename)
    348         {
    349             fprintf (stderr, "Could not generate output filename\n");
    350             Status = AE_ERROR;
    351             goto Cleanup;
    352         }
    353 
    354         File = fopen (DisasmFilename, "w+");
    355         if (!File)
    356         {
    357             fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
    358             Status = AE_ERROR;
    359             goto Cleanup;
    360         }
    361 
    362         AcpiOsRedirectOutput (File);
    363     }
    364 
    365     *OutFilename = DisasmFilename;
    366 
    367     /* ForceAmlDisassembly means to assume the table contains valid AML */
    368 
    369     if (!AcpiGbl_ForceAmlDisassembly && !AcpiUtIsAmlTable (Table))
    370     {
    371         AdDisassemblerHeader (Filename, ACPI_IS_DATA_TABLE);
    372         AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
    373             Table->Signature);
    374         AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]  "
    375             "FieldName : FieldValue\n */\n\n");
    376 
    377         AcpiDmDumpDataTable (Table);
    378         fprintf (stderr, "Acpi Data Table [%4.4s] decoded\n",
    379             Table->Signature);
    380 
    381         if (File)
    382         {
    383             fprintf (stderr, "Formatted output:  %s - %u bytes\n",
    384                 DisasmFilename, CmGetFileSize (File));
    385         }
    386     }
    387     else
    388     {
    389         /* Always parse the tables, only option is what to display */
    390 
    391         Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
    392         if (ACPI_FAILURE (Status))
    393         {
    394             AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
    395                 AcpiFormatException (Status));
    396             goto Cleanup;
    397         }
    398 
    399         if (AslCompilerdebug)
    400         {
    401             AcpiOsPrintf ("/**** Before second load\n");
    402 
    403             if (File)
    404             {
    405                 NsSetupNamespaceListing (File);
    406                 NsDisplayNamespace ();
    407             }
    408             AcpiOsPrintf ("*****/\n");
    409         }
    410 
    411         /* Load namespace from names created within control methods */
    412 
    413         AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
    414             AcpiGbl_RootNode, OwnerId);
    415 
    416         /*
    417          * Cross reference the namespace here, in order to
    418          * generate External() statements
    419          */
    420         AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
    421             AcpiGbl_RootNode, OwnerId);
    422 
    423         if (AslCompilerdebug)
    424         {
    425             AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
    426         }
    427 
    428         /* Find possible calls to external control methods */
    429 
    430         AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
    431 
    432         /*
    433          * If we found any external control methods, we must reparse
    434          * the entire tree with the new information (namely, the
    435          * number of arguments per method)
    436          */
    437         if (AcpiDmGetExternalMethodCount ())
    438         {
    439             fprintf (stderr,
    440                 "\nFound %u external control methods, "
    441                 "reparsing with new information\n",
    442                 AcpiDmGetExternalMethodCount ());
    443 
    444             /* Reparse, rebuild namespace */
    445 
    446             AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    447             AcpiGbl_ParseOpRoot = NULL;
    448             AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
    449 
    450             AcpiGbl_RootNode                    = NULL;
    451             AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
    452             AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
    453             AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
    454             AcpiGbl_RootNodeStruct.Parent       = NULL;
    455             AcpiGbl_RootNodeStruct.Child        = NULL;
    456             AcpiGbl_RootNodeStruct.Peer         = NULL;
    457             AcpiGbl_RootNodeStruct.Object       = NULL;
    458             AcpiGbl_RootNodeStruct.Flags        = 0;
    459 
    460             Status = AcpiNsRootInitialize ();
    461 
    462             /* New namespace, add the external definitions first */
    463 
    464             AcpiDmAddExternalsToNamespace ();
    465 
    466             /* Parse the table again. No need to reload it, however */
    467 
    468             Status = AdParseTable (Table, NULL, FALSE, FALSE);
    469             if (ACPI_FAILURE (Status))
    470             {
    471                 AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
    472                     AcpiFormatException (Status));
    473                 goto Cleanup;
    474             }
    475 
    476             /* Cross reference the namespace again */
    477 
    478             AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
    479                 AcpiGbl_RootNode, OwnerId);
    480 
    481             AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot,
    482                 AcpiGbl_RootNode, OwnerId);
    483 
    484             if (AslCompilerdebug)
    485             {
    486                 AcpiOsPrintf ("/**** After second load and resource conversion\n");
    487                 if (File)
    488                 {
    489                     NsSetupNamespaceListing (File);
    490                     NsDisplayNamespace ();
    491                 }
    492                 AcpiOsPrintf ("*****/\n");
    493 
    494                 AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
    495             }
    496         }
    497 
    498         /*
    499          * Now that the namespace is finalized, we can perform namespace
    500          * transforms.
    501          *
    502          * 1) Convert fixed-offset references to resource descriptors
    503          *    to symbolic references (Note: modifies namespace)
    504          */
    505         AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
    506 
    507         /* Optional displays */
    508 
    509         if (AcpiGbl_DbOpt_Disasm)
    510         {
    511             /* This is the real disassembly */
    512 
    513             AdDisplayTables (Filename, Table);
    514 
    515             /* Dump hex table if requested (-vt) */
    516 
    517             AcpiDmDumpDataTable (Table);
    518 
    519             fprintf (stderr, "Disassembly completed\n");
    520             if (File)
    521             {
    522                 fprintf (stderr, "ASL Output:    %s - %u bytes\n",
    523                     DisasmFilename, CmGetFileSize (File));
    524             }
    525 
    526             if (Gbl_MapfileFlag)
    527             {
    528                 fprintf (stderr, "%14s %s - %u bytes\n",
    529                     Gbl_Files[ASL_FILE_MAP_OUTPUT].ShortDescription,
    530                     Gbl_Files[ASL_FILE_MAP_OUTPUT].Filename,
    531                     FlGetFileSize (ASL_FILE_MAP_OUTPUT));
    532             }
    533         }
    534     }
    535 
    536 Cleanup:
    537 
    538     if (Table && !AcpiGbl_ForceAmlDisassembly &&!AcpiUtIsAmlTable (Table))
    539     {
    540         ACPI_FREE (Table);
    541     }
    542 
    543     if (File)
    544     {
    545         if (AslCompilerdebug) /* Display final namespace, with transforms */
    546         {
    547             NsSetupNamespaceListing (File);
    548             NsDisplayNamespace ();
    549         }
    550 
    551         fclose (File);
    552         AcpiOsRedirectOutput (stdout);
    553     }
    554 
    555     AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    556     AcpiGbl_ParseOpRoot = NULL;
    557     return (Status);
    558 }
    559 
    560 
    561 /******************************************************************************
    562  *
    563  * FUNCTION:    AdDisassemblerHeader
    564  *
    565  * PARAMETERS:  Filename            - Input file for the table
    566  *              TableType           - Either AML or DataTable
    567  *
    568  * RETURN:      None
    569  *
    570  * DESCRIPTION: Create the disassembler header, including ACPICA signon with
    571  *              current time and date.
    572  *
    573  *****************************************************************************/
    574 
    575 void
    576 AdDisassemblerHeader (
    577     char                    *Filename,
    578     UINT8                   TableType)
    579 {
    580     time_t                  Timer;
    581 
    582 
    583     time (&Timer);
    584 
    585     /* Header and input table info */
    586 
    587     AcpiOsPrintf ("/*\n");
    588     AcpiOsPrintf (ACPI_COMMON_HEADER (AML_DISASSEMBLER_NAME, " * "));
    589 
    590     if (TableType == ACPI_IS_AML_TABLE)
    591     {
    592         if (AcpiGbl_CstyleDisassembly)
    593         {
    594             AcpiOsPrintf (
    595                 " * Disassembling to symbolic ASL+ operators\n"
    596                 " *\n");
    597         }
    598         else
    599         {
    600             AcpiOsPrintf (
    601                 " * Disassembling to non-symbolic legacy ASL operators\n"
    602                 " *\n");
    603         }
    604     }
    605 
    606     AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
    607     AcpiOsPrintf (" *\n");
    608 }
    609 
    610 
    611 /******************************************************************************
    612  *
    613  * FUNCTION:    AdCreateTableHeader
    614  *
    615  * PARAMETERS:  Filename            - Input file for the table
    616  *              Table               - Pointer to the raw table
    617  *
    618  * RETURN:      None
    619  *
    620  * DESCRIPTION: Create the ASL table header, including ACPICA signon with
    621  *              current time and date.
    622  *
    623  *****************************************************************************/
    624 
    625 static void
    626 AdCreateTableHeader (
    627     char                    *Filename,
    628     ACPI_TABLE_HEADER       *Table)
    629 {
    630     char                    *NewFilename;
    631     UINT8                   Checksum;
    632 
    633 
    634     /*
    635      * Print file header and dump original table header
    636      */
    637     AdDisassemblerHeader (Filename, ACPI_IS_AML_TABLE);
    638 
    639     AcpiOsPrintf (" * Original Table Header:\n");
    640     AcpiOsPrintf (" *     Signature        \"%4.4s\"\n",    Table->Signature);
    641     AcpiOsPrintf (" *     Length           0x%8.8X (%u)\n", Table->Length, Table->Length);
    642 
    643     /* Print and validate the revision */
    644 
    645     AcpiOsPrintf (" *     Revision         0x%2.2X",      Table->Revision);
    646 
    647     switch (Table->Revision)
    648     {
    649     case 0:
    650 
    651         AcpiOsPrintf (" **** Invalid Revision");
    652         break;
    653 
    654     case 1:
    655 
    656         /* Revision of DSDT controls the ACPI integer width */
    657 
    658         if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
    659         {
    660             AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
    661         }
    662         break;
    663 
    664     default:
    665 
    666         break;
    667     }
    668     AcpiOsPrintf ("\n");
    669 
    670     /* Print and validate the table checksum */
    671 
    672     AcpiOsPrintf (" *     Checksum         0x%2.2X",        Table->Checksum);
    673 
    674     Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
    675     if (Checksum)
    676     {
    677         AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
    678             (UINT8) (Table->Checksum - Checksum));
    679     }
    680     AcpiOsPrintf ("\n");
    681 
    682     AcpiOsPrintf (" *     OEM ID           \"%.6s\"\n",     Table->OemId);
    683     AcpiOsPrintf (" *     OEM Table ID     \"%.8s\"\n",     Table->OemTableId);
    684     AcpiOsPrintf (" *     OEM Revision     0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
    685     AcpiOsPrintf (" *     Compiler ID      \"%.4s\"\n",     Table->AslCompilerId);
    686     AcpiOsPrintf (" *     Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
    687     AcpiOsPrintf (" */\n");
    688 
    689     /* Create AML output filename based on input filename */
    690 
    691     if (Filename)
    692     {
    693         NewFilename = FlGenerateFilename (Filename, "aml");
    694     }
    695     else
    696     {
    697         NewFilename = UtStringCacheCalloc (9);
    698         if (NewFilename)
    699         {
    700             strncat (NewFilename, Table->Signature, 4);
    701             strcat (NewFilename, ".aml");
    702         }
    703     }
    704 
    705     if (!NewFilename)
    706     {
    707         AcpiOsPrintf (" **** Could not generate AML output filename\n");
    708         return;
    709     }
    710 
    711     /* Open the ASL definition block */
    712 
    713     AcpiOsPrintf (
    714         "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
    715         NewFilename, Table->Signature, Table->Revision,
    716         Table->OemId, Table->OemTableId, Table->OemRevision);
    717 }
    718 
    719 
    720 /******************************************************************************
    721  *
    722  * FUNCTION:    AdDisplayTables
    723  *
    724  * PARAMETERS:  Filename            - Input file for the table
    725  *              Table               - Pointer to the raw table
    726  *
    727  * RETURN:      Status
    728  *
    729  * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
    730  *
    731  *****************************************************************************/
    732 
    733 ACPI_STATUS
    734 AdDisplayTables (
    735     char                    *Filename,
    736     ACPI_TABLE_HEADER       *Table)
    737 {
    738 
    739 
    740     if (!AcpiGbl_ParseOpRoot)
    741     {
    742         return (AE_NOT_EXIST);
    743     }
    744 
    745     if (!AcpiGbl_DbOpt_Verbose)
    746     {
    747         AdCreateTableHeader (Filename, Table);
    748     }
    749 
    750     AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
    751     MpEmitMappingInfo ();
    752 
    753     if (AcpiGbl_DbOpt_Verbose)
    754     {
    755         AcpiOsPrintf ("\n\nTable Header:\n");
    756         AcpiUtDebugDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
    757             DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    758 
    759         AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
    760         AcpiUtDebugDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)),
    761             Table->Length, DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    762     }
    763 
    764     return (AE_OK);
    765 }
    766 
    767 
    768 /*******************************************************************************
    769  *
    770  * FUNCTION:    AdStoreTable
    771  *
    772  * PARAMETERS:  Table               - Table header
    773  *              TableIndex          - Where the table index is returned
    774  *
    775  * RETURN:      Status and table index.
    776  *
    777  * DESCRIPTION: Add an ACPI table to the global table list
    778  *
    779  ******************************************************************************/
    780 
    781 static ACPI_STATUS
    782 AdStoreTable (
    783     ACPI_TABLE_HEADER       *Table,
    784     UINT32                  *TableIndex)
    785 {
    786     ACPI_STATUS             Status;
    787     ACPI_TABLE_DESC         *TableDesc;
    788 
    789 
    790     Status = AcpiTbGetNextTableDescriptor (TableIndex, &TableDesc);
    791     if (ACPI_FAILURE (Status))
    792     {
    793         return (Status);
    794     }
    795 
    796     /* Initialize added table */
    797 
    798     AcpiTbInitTableDescriptor (TableDesc, ACPI_PTR_TO_PHYSADDR (Table),
    799         ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table);
    800     Status = AcpiTbValidateTable (TableDesc);
    801     return (Status);
    802 }
    803 
    804 
    805 /******************************************************************************
    806  *
    807  * FUNCTION:    AdGetLocalTables
    808  *
    809  * PARAMETERS:  None
    810  *
    811  * RETURN:      Status
    812  *
    813  * DESCRIPTION: Get the ACPI tables from either memory or a file
    814  *
    815  *****************************************************************************/
    816 
    817 ACPI_STATUS
    818 AdGetLocalTables (
    819     void)
    820 {
    821     ACPI_STATUS             Status;
    822     ACPI_TABLE_HEADER       TableHeader;
    823     ACPI_TABLE_HEADER       *NewTable;
    824     UINT32                  TableIndex;
    825 
    826 
    827     /* Get the DSDT via table override */
    828 
    829     ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
    830     AcpiOsTableOverride (&TableHeader, &NewTable);
    831     if (!NewTable)
    832     {
    833         fprintf (stderr, "Could not obtain DSDT\n");
    834         return (AE_NO_ACPI_TABLES);
    835     }
    836 
    837     AdWriteTable (NewTable, NewTable->Length,
    838         ACPI_SIG_DSDT, NewTable->OemTableId);
    839 
    840     /* Store DSDT in the Table Manager */
    841 
    842     Status = AdStoreTable (NewTable, &TableIndex);
    843     if (ACPI_FAILURE (Status))
    844     {
    845         fprintf (stderr, "Could not store DSDT\n");
    846         return (AE_NO_ACPI_TABLES);
    847     }
    848 
    849     return (AE_OK);
    850 }
    851 
    852 
    853 /******************************************************************************
    854  *
    855  * FUNCTION:    AdParseTable
    856  *
    857  * PARAMETERS:  Table               - Pointer to the raw table
    858  *              OwnerId             - Returned OwnerId of the table
    859  *              LoadTable           - If add table to the global table list
    860  *              External            - If this is an external table
    861  *
    862  * RETURN:      Status
    863  *
    864  * DESCRIPTION: Parse the DSDT.
    865  *
    866  *****************************************************************************/
    867 
    868 ACPI_STATUS
    869 AdParseTable (
    870     ACPI_TABLE_HEADER       *Table,
    871     ACPI_OWNER_ID           *OwnerId,
    872     BOOLEAN                 LoadTable,
    873     BOOLEAN                 External)
    874 {
    875     ACPI_STATUS             Status = AE_OK;
    876     ACPI_WALK_STATE         *WalkState;
    877     UINT8                   *AmlStart;
    878     UINT32                  AmlLength;
    879     UINT32                  TableIndex;
    880 
    881 
    882     if (!Table)
    883     {
    884         return (AE_NOT_EXIST);
    885     }
    886 
    887     /* Pass 1:  Parse everything except control method bodies */
    888 
    889     fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
    890 
    891     AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
    892     AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
    893 
    894     /* Create the root object */
    895 
    896     AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (AmlStart);
    897     if (!AcpiGbl_ParseOpRoot)
    898     {
    899         return (AE_NO_MEMORY);
    900     }
    901 
    902     /* Create and initialize a new walk state */
    903 
    904     WalkState = AcpiDsCreateWalkState (0,
    905                         AcpiGbl_ParseOpRoot, NULL, NULL);
    906     if (!WalkState)
    907     {
    908         return (AE_NO_MEMORY);
    909     }
    910 
    911     Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
    912                 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    913     if (ACPI_FAILURE (Status))
    914     {
    915         return (Status);
    916     }
    917 
    918     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
    919     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
    920 
    921     Status = AcpiPsParseAml (WalkState);
    922     if (ACPI_FAILURE (Status))
    923     {
    924         return (Status);
    925     }
    926 
    927     /* If LoadTable is FALSE, we are parsing the last loaded table */
    928 
    929     TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
    930 
    931     /* Pass 2 */
    932 
    933     if (LoadTable)
    934     {
    935         Status = AdStoreTable (Table, &TableIndex);
    936         if (ACPI_FAILURE (Status))
    937         {
    938             return (Status);
    939         }
    940         Status = AcpiTbAllocateOwnerId (TableIndex);
    941         if (ACPI_FAILURE (Status))
    942         {
    943             return (Status);
    944         }
    945         if (OwnerId)
    946         {
    947             Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
    948             if (ACPI_FAILURE (Status))
    949             {
    950                 return (Status);
    951             }
    952         }
    953     }
    954 
    955     fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
    956 
    957     Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
    958     if (ACPI_FAILURE (Status))
    959     {
    960         return (Status);
    961     }
    962 
    963     /* No need to parse control methods of external table */
    964 
    965     if (External)
    966     {
    967         return (AE_OK);
    968     }
    969 
    970     /*
    971      * Pass 3: Parse control methods and link their parse trees
    972      * into the main parse tree
    973      */
    974     fprintf (stderr,
    975         "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
    976     Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot);
    977     fprintf (stderr, "\n");
    978 
    979     /* Process Resource Templates */
    980 
    981     AcpiDmFindResources (AcpiGbl_ParseOpRoot);
    982 
    983     fprintf (stderr, "Parsing completed\n");
    984     return (AE_OK);
    985 }
    986