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