Home | History | Annotate | Line # | Download | only in common
adisasm.c revision 1.1.1.2
      1 /******************************************************************************
      2  *
      3  * Module Name: adisasm - Application-level disassembler routines
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2011, 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 
     45 #include "acpi.h"
     46 #include "accommon.h"
     47 #include "acparser.h"
     48 #include "amlcode.h"
     49 #include "acdebug.h"
     50 #include "acdisasm.h"
     51 #include "acdispat.h"
     52 #include "acnamesp.h"
     53 #include "actables.h"
     54 #include "acapps.h"
     55 
     56 #include <stdio.h>
     57 #include <time.h>
     58 
     59 
     60 #define _COMPONENT          ACPI_TOOLS
     61         ACPI_MODULE_NAME    ("adisasm")
     62 
     63 
     64 extern int                  AslCompilerdebug;
     65 
     66 
     67 ACPI_STATUS
     68 LsDisplayNamespace (
     69     void);
     70 
     71 void
     72 LsSetupNsList (
     73     void                    *Handle);
     74 
     75 
     76 /* Local prototypes */
     77 
     78 static void
     79 AdCreateTableHeader (
     80     char                    *Filename,
     81     ACPI_TABLE_HEADER       *Table);
     82 
     83 static ACPI_STATUS
     84 AdDeferredParse (
     85     ACPI_PARSE_OBJECT       *Op,
     86     UINT8                   *Aml,
     87     UINT32                  AmlLength);
     88 
     89 static ACPI_STATUS
     90 AdParseDeferredOps (
     91     ACPI_PARSE_OBJECT       *Root);
     92 
     93 
     94 /* Stubs for ASL compiler */
     95 
     96 #ifndef ACPI_ASL_COMPILER
     97 BOOLEAN
     98 AcpiDsIsResultUsed (
     99     ACPI_PARSE_OBJECT       *Op,
    100     ACPI_WALK_STATE         *WalkState)
    101 {
    102     return TRUE;
    103 }
    104 
    105 ACPI_STATUS
    106 AcpiDsMethodError (
    107     ACPI_STATUS             Status,
    108     ACPI_WALK_STATE         *WalkState)
    109 {
    110     return (Status);
    111 }
    112 #endif
    113 
    114 ACPI_STATUS
    115 AcpiNsLoadTable (
    116     UINT32                  TableIndex,
    117     ACPI_NAMESPACE_NODE     *Node)
    118 {
    119     return (AE_NOT_IMPLEMENTED);
    120 }
    121 
    122 ACPI_STATUS
    123 AcpiDsRestartControlMethod (
    124     ACPI_WALK_STATE         *WalkState,
    125     ACPI_OPERAND_OBJECT     *ReturnDesc)
    126 {
    127     return (AE_OK);
    128 }
    129 
    130 void
    131 AcpiDsTerminateControlMethod (
    132     ACPI_OPERAND_OBJECT     *MethodDesc,
    133     ACPI_WALK_STATE         *WalkState)
    134 {
    135     return;
    136 }
    137 
    138 ACPI_STATUS
    139 AcpiDsCallControlMethod (
    140     ACPI_THREAD_STATE       *Thread,
    141     ACPI_WALK_STATE         *WalkState,
    142     ACPI_PARSE_OBJECT       *Op)
    143 {
    144     return (AE_OK);
    145 }
    146 
    147 ACPI_STATUS
    148 AcpiDsMethodDataInitArgs (
    149     ACPI_OPERAND_OBJECT     **Params,
    150     UINT32                  MaxParamCount,
    151     ACPI_WALK_STATE         *WalkState)
    152 {
    153     return (AE_OK);
    154 }
    155 
    156 
    157 static ACPI_TABLE_DESC      LocalTables[1];
    158 static ACPI_PARSE_OBJECT    *AcpiGbl_ParseOpRoot;
    159 
    160 
    161 /*******************************************************************************
    162  *
    163  * FUNCTION:    AdInitialize
    164  *
    165  * PARAMETERS:  None
    166  *
    167  * RETURN:      Status
    168  *
    169  * DESCRIPTION: ACPICA and local initialization
    170  *
    171  ******************************************************************************/
    172 
    173 ACPI_STATUS
    174 AdInitialize (
    175     void)
    176 {
    177     ACPI_STATUS             Status;
    178 
    179 
    180     /* ACPI CA subsystem initialization */
    181 
    182     Status = AcpiOsInitialize ();
    183     if (ACPI_FAILURE (Status))
    184     {
    185         return (Status);
    186     }
    187 
    188     Status = AcpiUtInitGlobals ();
    189     if (ACPI_FAILURE (Status))
    190     {
    191         return (Status);
    192     }
    193 
    194     Status = AcpiUtMutexInitialize ();
    195     if (ACPI_FAILURE (Status))
    196     {
    197         return (Status);
    198     }
    199 
    200     Status = AcpiNsRootInitialize ();
    201     if (ACPI_FAILURE (Status))
    202     {
    203         return (Status);
    204     }
    205 
    206     /* Setup the Table Manager (cheat - there is no RSDT) */
    207 
    208     AcpiGbl_RootTableList.MaxTableCount = 1;
    209     AcpiGbl_RootTableList.CurrentTableCount = 0;
    210     AcpiGbl_RootTableList.Tables = LocalTables;
    211 
    212     return (Status);
    213 }
    214 
    215 
    216 /******************************************************************************
    217  *
    218  * FUNCTION:    AdAmlDisassemble
    219  *
    220  * PARAMETERS:  Filename            - AML input filename
    221  *              OutToFile           - TRUE if output should go to a file
    222  *              Prefix              - Path prefix for output
    223  *              OutFilename         - where the filename is returned
    224  *              GetAllTables        - TRUE if all tables are desired
    225  *
    226  * RETURN:      Status
    227  *
    228  * DESCRIPTION: Disassemble an entire ACPI table
    229  *
    230  *****************************************************************************/
    231 
    232 ACPI_STATUS
    233 AdAmlDisassemble (
    234     BOOLEAN                 OutToFile,
    235     char                    *Filename,
    236     char                    *Prefix,
    237     char                    **OutFilename,
    238     BOOLEAN                 GetAllTables)
    239 {
    240     ACPI_STATUS             Status;
    241     char                    *DisasmFilename = NULL;
    242     char                    *ExternalFilename;
    243     ACPI_EXTERNAL_FILE      *ExternalFileList = AcpiGbl_ExternalFileList;
    244     FILE                    *File = NULL;
    245     ACPI_TABLE_HEADER       *Table = NULL;
    246     ACPI_TABLE_HEADER       *ExternalTable;
    247     ACPI_OWNER_ID           OwnerId;
    248 
    249 
    250     /*
    251      * Input: AML code from either a file or via GetTables (memory or
    252      * registry)
    253      */
    254     if (Filename)
    255     {
    256         Status = AcpiDbGetTableFromFile (Filename, &Table);
    257         if (ACPI_FAILURE (Status))
    258         {
    259             return Status;
    260         }
    261 
    262         /*
    263          * External filenames separated by commas
    264          * Example: iasl -e file1,file2,file3 -d xxx.aml
    265          */
    266         while (ExternalFileList)
    267         {
    268             ExternalFilename = ExternalFileList->Path;
    269             if (!ACPI_STRCMP (ExternalFilename, Filename))
    270             {
    271                 /* Next external file */
    272 
    273                 ExternalFileList = ExternalFileList->Next;
    274 
    275                 continue;
    276             }
    277 
    278             Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable);
    279             if (ACPI_FAILURE (Status))
    280             {
    281                 return Status;
    282             }
    283 
    284             /* Load external table for symbol resolution */
    285 
    286             if (ExternalTable)
    287             {
    288                 Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE);
    289                 if (ACPI_FAILURE (Status))
    290                 {
    291                     AcpiOsPrintf ("Could not parse external ACPI tables, %s\n",
    292                         AcpiFormatException (Status));
    293                     return Status;
    294                 }
    295 
    296                 /*
    297                  * Load namespace from names created within control methods
    298                  * Set owner id of nodes in external table
    299                  */
    300                 AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot,
    301                     AcpiGbl_RootNode, OwnerId);
    302                 AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    303             }
    304 
    305             /* Next external file */
    306 
    307             ExternalFileList = ExternalFileList->Next;
    308         }
    309 
    310         /* Clear external list generated by Scope in external tables */
    311 
    312         if (AcpiGbl_ExternalFileList)
    313         {
    314             AcpiDmClearExternalList ();
    315         }
    316     }
    317     else
    318     {
    319         Status = AdGetLocalTables (Filename, GetAllTables);
    320         if (ACPI_FAILURE (Status))
    321         {
    322             AcpiOsPrintf ("Could not get ACPI tables, %s\n",
    323                 AcpiFormatException (Status));
    324             return Status;
    325         }
    326 
    327         if (!AcpiGbl_DbOpt_disasm)
    328         {
    329             return AE_OK;
    330         }
    331 
    332         /* Obtained the local tables, just disassemble the DSDT */
    333 
    334         Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table);
    335         if (ACPI_FAILURE (Status))
    336         {
    337             AcpiOsPrintf ("Could not get DSDT, %s\n",
    338                 AcpiFormatException (Status));
    339             return Status;
    340         }
    341 
    342         AcpiOsPrintf ("\nDisassembly of DSDT\n");
    343         Prefix = AdGenerateFilename ("dsdt", Table->OemTableId);
    344     }
    345 
    346     /*
    347      * Output:  ASL code. Redirect to a file if requested
    348      */
    349     if (OutToFile)
    350     {
    351         /* Create/Open a disassembly output file */
    352 
    353         DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY);
    354         if (!OutFilename)
    355         {
    356             fprintf (stderr, "Could not generate output filename\n");
    357             Status = AE_ERROR;
    358             goto Cleanup;
    359         }
    360 
    361         File = fopen (DisasmFilename, "w+");
    362         if (!File)
    363         {
    364             fprintf (stderr, "Could not open output file %s\n", DisasmFilename);
    365             Status = AE_ERROR;
    366             goto Cleanup;
    367         }
    368 
    369         AcpiOsRedirectOutput (File);
    370     }
    371 
    372     *OutFilename = DisasmFilename;
    373 
    374     if (!AcpiUtIsAmlTable (Table))
    375     {
    376         AdDisassemblerHeader (Filename);
    377         AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n",
    378             Table->Signature);
    379         AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue\n */\n\n");
    380 
    381         AcpiDmDumpDataTable (Table);
    382         fprintf (stderr, "Acpi Data Table [%4.4s] decoded, written to \"%s\"\n",
    383             Table->Signature, DisasmFilename);
    384     }
    385     else
    386     {
    387         /* Always parse the tables, only option is what to display */
    388 
    389         Status = AdParseTable (Table, &OwnerId, TRUE, FALSE);
    390         if (ACPI_FAILURE (Status))
    391         {
    392             AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
    393                 AcpiFormatException (Status));
    394             goto Cleanup;
    395         }
    396 
    397         if (AslCompilerdebug)
    398         {
    399             AcpiOsPrintf ("/**** Before second load\n");
    400 
    401             LsSetupNsList (File);
    402             LsDisplayNamespace ();
    403             AcpiOsPrintf ("*****/\n");
    404         }
    405 
    406         /*
    407          * Load namespace from names created within control methods
    408          */
    409         AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode, OwnerId);
    410 
    411         /*
    412          * Cross reference the namespace here, in order to generate External() statements
    413          */
    414         AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode, OwnerId);
    415 
    416         if (AslCompilerdebug)
    417         {
    418             AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
    419         }
    420 
    421         /* Find possible calls to external control methods */
    422 
    423         AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot);
    424 
    425         /* Convert fixed-offset references to resource descriptors to symbolic references */
    426 
    427         AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode);
    428 
    429         /*
    430          * If we found any external control methods, we must reparse the entire
    431          * tree with the new information (namely, the number of arguments per
    432          * method)
    433          */
    434         if (AcpiDmGetExternalMethodCount ())
    435         {
    436             fprintf (stderr,
    437                 "\nFound %u external control methods, reparsing with new information\n",
    438                 AcpiDmGetExternalMethodCount ());
    439 
    440             /*
    441              * Reparse, rebuild namespace. no need to xref namespace
    442              */
    443             AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    444             AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
    445 
    446             AcpiGbl_RootNode                    = NULL;
    447             AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME;
    448             AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED;
    449             AcpiGbl_RootNodeStruct.Type         = ACPI_TYPE_DEVICE;
    450             AcpiGbl_RootNodeStruct.Parent       = NULL;
    451             AcpiGbl_RootNodeStruct.Child        = NULL;
    452             AcpiGbl_RootNodeStruct.Peer         = NULL;
    453             AcpiGbl_RootNodeStruct.Object       = NULL;
    454             AcpiGbl_RootNodeStruct.Flags        = 0;
    455 
    456             Status = AcpiNsRootInitialize ();
    457             AcpiDmAddExternalsToNamespace ();
    458 
    459             /* Parse table. No need to reload it, however (FALSE) */
    460 
    461             Status = AdParseTable (Table, NULL, FALSE, FALSE);
    462             if (ACPI_FAILURE (Status))
    463             {
    464                 AcpiOsPrintf ("Could not parse ACPI tables, %s\n",
    465                     AcpiFormatException (Status));
    466                 goto Cleanup;
    467             }
    468 
    469             if (AslCompilerdebug)
    470             {
    471                 AcpiOsPrintf ("/**** After second load and resource conversion\n");
    472                 LsSetupNsList (File);
    473                 LsDisplayNamespace ();
    474                 AcpiOsPrintf ("*****/\n");
    475 
    476                 AcpiDmDumpTree (AcpiGbl_ParseOpRoot);
    477             }
    478         }
    479 
    480         /* Optional displays */
    481 
    482         if (AcpiGbl_DbOpt_disasm)
    483         {
    484             AdDisplayTables (Filename, Table);
    485             fprintf (stderr,
    486                 "Disassembly completed, written to \"%s\"\n",
    487                 DisasmFilename);
    488         }
    489     }
    490 
    491 Cleanup:
    492 
    493     if (Table && !AcpiUtIsAmlTable (Table))
    494     {
    495         ACPI_FREE (Table);
    496     }
    497 
    498     if (DisasmFilename)
    499     {
    500         ACPI_FREE (DisasmFilename);
    501     }
    502 
    503     if (OutToFile && File)
    504     {
    505 
    506 #ifdef ASL_DISASM_DEBUG
    507         LsSetupNsList (File);
    508         LsDisplayNamespace ();
    509 #endif
    510         fclose (File);
    511         AcpiOsRedirectOutput (stdout);
    512     }
    513 
    514     AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot);
    515     AcpiGbl_ParseOpRoot = NULL;
    516     return (Status);
    517 }
    518 
    519 
    520 /******************************************************************************
    521  *
    522  * FUNCTION:    AdDisassemblerHeader
    523  *
    524  * PARAMETERS:  Filename            - Input file for the table
    525  *
    526  * RETURN:      None
    527  *
    528  * DESCRIPTION: Create the disassembler header, including ACPI CA signon with
    529  *              current time and date.
    530  *
    531  *****************************************************************************/
    532 
    533 void
    534 AdDisassemblerHeader (
    535     char                    *Filename)
    536 {
    537     time_t                  Timer;
    538 
    539     time (&Timer);
    540 
    541     /* Header and input table info */
    542 
    543     AcpiOsPrintf ("/*\n");
    544     AcpiOsPrintf (ACPI_COMMON_HEADER ("AML Disassembler", " * "));
    545 
    546     AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer));
    547     AcpiOsPrintf (" *\n");
    548 }
    549 
    550 
    551 /******************************************************************************
    552  *
    553  * FUNCTION:    AdCreateTableHeader
    554  *
    555  * PARAMETERS:  Filename            - Input file for the table
    556  *              Table               - Pointer to the raw table
    557  *
    558  * RETURN:      None
    559  *
    560  * DESCRIPTION: Create the ASL table header, including ACPI CA signon with
    561  *              current time and date.
    562  *
    563  *****************************************************************************/
    564 
    565 static void
    566 AdCreateTableHeader (
    567     char                    *Filename,
    568     ACPI_TABLE_HEADER       *Table)
    569 {
    570     char                    *NewFilename;
    571     UINT8                   Checksum;
    572 
    573 
    574     /*
    575      * Print file header and dump original table header
    576      */
    577     AdDisassemblerHeader (Filename);
    578 
    579     AcpiOsPrintf (" * Original Table Header:\n");
    580     AcpiOsPrintf (" *     Signature        \"%4.4s\"\n",    Table->Signature);
    581     AcpiOsPrintf (" *     Length           0x%8.8X (%u)\n", Table->Length, Table->Length);
    582 
    583     /* Print and validate the revision */
    584 
    585     AcpiOsPrintf (" *     Revision         0x%2.2X",      Table->Revision);
    586 
    587     switch (Table->Revision)
    588     {
    589     case 0:
    590         AcpiOsPrintf (" **** Invalid Revision");
    591         break;
    592 
    593     case 1:
    594         /* Revision of DSDT controls the ACPI integer width */
    595 
    596         if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
    597         {
    598             AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support");
    599         }
    600         break;
    601 
    602     default:
    603         break;
    604     }
    605     AcpiOsPrintf ("\n");
    606 
    607     /* Print and validate the table checksum */
    608 
    609     AcpiOsPrintf (" *     Checksum         0x%2.2X",        Table->Checksum);
    610 
    611     Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length);
    612     if (Checksum)
    613     {
    614         AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X",
    615             (UINT8) (Table->Checksum - Checksum));
    616     }
    617     AcpiOsPrintf ("\n");
    618 
    619     AcpiOsPrintf (" *     OEM ID           \"%.6s\"\n",     Table->OemId);
    620     AcpiOsPrintf (" *     OEM Table ID     \"%.8s\"\n",     Table->OemTableId);
    621     AcpiOsPrintf (" *     OEM Revision     0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision);
    622     AcpiOsPrintf (" *     Compiler ID      \"%.4s\"\n",     Table->AslCompilerId);
    623     AcpiOsPrintf (" *     Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision);
    624     AcpiOsPrintf (" */\n\n");
    625 
    626     /* Create AML output filename based on input filename */
    627 
    628     if (Filename)
    629     {
    630         NewFilename = FlGenerateFilename (Filename, "aml");
    631     }
    632     else
    633     {
    634         NewFilename = ACPI_ALLOCATE_ZEROED (9);
    635         strncat (NewFilename, Table->Signature, 4);
    636         strcat (NewFilename, ".aml");
    637     }
    638 
    639     /* Open the ASL definition block */
    640 
    641     AcpiOsPrintf (
    642         "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n",
    643         NewFilename, Table->Signature, Table->Revision,
    644         Table->OemId, Table->OemTableId, Table->OemRevision);
    645 
    646     ACPI_FREE (NewFilename);
    647 }
    648 
    649 
    650 /******************************************************************************
    651  *
    652  * FUNCTION:    AdDisplayTables
    653  *
    654  * PARAMETERS:  Filename            - Input file for the table
    655  *              Table               - Pointer to the raw table
    656  *
    657  * RETURN:      Status
    658  *
    659  * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables
    660  *
    661  *****************************************************************************/
    662 
    663 ACPI_STATUS
    664 AdDisplayTables (
    665     char                    *Filename,
    666     ACPI_TABLE_HEADER       *Table)
    667 {
    668 
    669 
    670     if (!AcpiGbl_ParseOpRoot)
    671     {
    672         return AE_NOT_EXIST;
    673     }
    674 
    675     if (!AcpiGbl_DbOpt_verbose)
    676     {
    677         AdCreateTableHeader (Filename, Table);
    678     }
    679 
    680     AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX);
    681 
    682     if (AcpiGbl_DbOpt_verbose)
    683     {
    684         AcpiOsPrintf ("\n\nTable Header:\n");
    685         AcpiUtDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER),
    686             DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    687 
    688         AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length);
    689         AcpiUtDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), Table->Length,
    690             DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
    691     }
    692 
    693     return AE_OK;
    694 }
    695 
    696 
    697 /******************************************************************************
    698  *
    699  * FUNCTION:    AdDeferredParse
    700  *
    701  * PARAMETERS:  Op                  - Root Op of the deferred opcode
    702  *              Aml                 - Pointer to the raw AML
    703  *              AmlLength           - Length of the AML
    704  *
    705  * RETURN:      Status
    706  *
    707  * DESCRIPTION: Parse one deferred opcode
    708  *              (Methods, operation regions, etc.)
    709  *
    710  *****************************************************************************/
    711 
    712 static ACPI_STATUS
    713 AdDeferredParse (
    714     ACPI_PARSE_OBJECT       *Op,
    715     UINT8                   *Aml,
    716     UINT32                  AmlLength)
    717 {
    718     ACPI_WALK_STATE         *WalkState;
    719     ACPI_STATUS             Status;
    720     ACPI_PARSE_OBJECT       *SearchOp;
    721     ACPI_PARSE_OBJECT       *StartOp;
    722     UINT32                  BaseAmlOffset;
    723     ACPI_PARSE_OBJECT       *ExtraOp;
    724 
    725 
    726     ACPI_FUNCTION_TRACE (AdDeferredParse);
    727 
    728 
    729     fprintf (stderr, ".");
    730 
    731     if (!Aml || !AmlLength)
    732     {
    733         return_ACPI_STATUS (AE_OK);
    734     }
    735 
    736     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing %s [%4.4s]\n",
    737         Op->Common.AmlOpName, (char *) &Op->Named.Name));
    738 
    739     WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
    740     if (!WalkState)
    741     {
    742         return_ACPI_STATUS (AE_NO_MEMORY);
    743     }
    744 
    745     Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml,
    746                     AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
    747     if (ACPI_FAILURE (Status))
    748     {
    749         return_ACPI_STATUS (Status);
    750     }
    751 
    752     /* Parse the method */
    753 
    754     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
    755     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
    756     Status = AcpiPsParseAml (WalkState);
    757 
    758     /*
    759      * We need to update all of the Aml offsets, since the parser thought
    760      * that the method began at offset zero.  In reality, it began somewhere
    761      * within the ACPI table, at the BaseAmlOffset.  Walk the entire tree that
    762      * was just created and update the AmlOffset in each Op
    763      */
    764     BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1;
    765     StartOp = (Op->Common.Value.Arg)->Common.Next;
    766     SearchOp = StartOp;
    767 
    768     /* Walk the parse tree */
    769 
    770     while (SearchOp)
    771     {
    772         SearchOp->Common.AmlOffset += BaseAmlOffset;
    773         SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
    774     }
    775 
    776     /*
    777      * Link the newly parsed subtree into the main parse tree
    778      */
    779     switch (Op->Common.AmlOpcode)
    780     {
    781     case AML_BUFFER_OP:
    782     case AML_PACKAGE_OP:
    783     case AML_VAR_PACKAGE_OP:
    784 
    785         switch (Op->Common.AmlOpcode)
    786         {
    787         case AML_PACKAGE_OP:
    788             ExtraOp = Op->Common.Value.Arg;
    789             ExtraOp = ExtraOp->Common.Next;
    790             Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
    791             break;
    792 
    793         case AML_VAR_PACKAGE_OP:
    794         case AML_BUFFER_OP:
    795         default:
    796             ExtraOp = Op->Common.Value.Arg;
    797             Op->Common.Value.Arg = ExtraOp->Common.Value.Arg;
    798             break;
    799         }
    800 
    801         /* Must point all parents to the main tree */
    802 
    803         StartOp = Op;
    804         SearchOp = StartOp;
    805         while (SearchOp)
    806         {
    807             if (SearchOp->Common.Parent == ExtraOp)
    808             {
    809                 SearchOp->Common.Parent = Op;
    810             }
    811             SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
    812         }
    813         break;
    814 
    815     default:
    816         break;
    817     }
    818 
    819     return_ACPI_STATUS (AE_OK);
    820 }
    821 
    822 
    823 /******************************************************************************
    824  *
    825  * FUNCTION:    AdParseDeferredOps
    826  *
    827  * PARAMETERS:  Root                - Root of the parse tree
    828  *
    829  * RETURN:      Status
    830  *
    831  * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.)
    832  *
    833  *****************************************************************************/
    834 
    835 static ACPI_STATUS
    836 AdParseDeferredOps (
    837     ACPI_PARSE_OBJECT       *Root)
    838 {
    839     ACPI_PARSE_OBJECT       *Op = Root;
    840     ACPI_STATUS             Status = AE_OK;
    841     const ACPI_OPCODE_INFO  *OpInfo;
    842 
    843 
    844     ACPI_FUNCTION_NAME (AdParseDeferredOps);
    845     fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n");
    846 
    847     while (Op)
    848     {
    849         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    850         if (!(OpInfo->Flags & AML_DEFER))
    851         {
    852             Op = AcpiPsGetDepthNext (Root, Op);
    853             continue;
    854         }
    855 
    856         switch (Op->Common.AmlOpcode)
    857         {
    858         case AML_METHOD_OP:
    859         case AML_BUFFER_OP:
    860         case AML_PACKAGE_OP:
    861         case AML_VAR_PACKAGE_OP:
    862 
    863             Status = AdDeferredParse (Op, Op->Named.Data, Op->Named.Length);
    864             if (ACPI_FAILURE (Status))
    865             {
    866                 return_ACPI_STATUS (Status);
    867             }
    868             break;
    869 
    870         case AML_REGION_OP:
    871         case AML_CREATE_QWORD_FIELD_OP:
    872         case AML_CREATE_DWORD_FIELD_OP:
    873         case AML_CREATE_WORD_FIELD_OP:
    874         case AML_CREATE_BYTE_FIELD_OP:
    875         case AML_CREATE_BIT_FIELD_OP:
    876         case AML_CREATE_FIELD_OP:
    877         case AML_BANK_FIELD_OP:
    878 
    879             /* Nothing to do in these cases */
    880 
    881             break;
    882 
    883         default:
    884             ACPI_ERROR ((AE_INFO, "Unhandled deferred opcode [%s]",
    885                 Op->Common.AmlOpName));
    886             break;
    887         }
    888 
    889         Op = AcpiPsGetDepthNext (Root, Op);
    890     }
    891 
    892     fprintf (stderr, "\n");
    893     return Status;
    894 }
    895 
    896 
    897 /******************************************************************************
    898  *
    899  * FUNCTION:    AdGetLocalTables
    900  *
    901  * PARAMETERS:  Filename            - Not used
    902  *              GetAllTables        - TRUE if all tables are desired
    903  *
    904  * RETURN:      Status
    905  *
    906  * DESCRIPTION: Get the ACPI tables from either memory or a file
    907  *
    908  *****************************************************************************/
    909 
    910 ACPI_STATUS
    911 AdGetLocalTables (
    912     char                    *Filename,
    913     BOOLEAN                 GetAllTables)
    914 {
    915     ACPI_STATUS             Status;
    916     ACPI_TABLE_HEADER       TableHeader;
    917     ACPI_TABLE_HEADER       *NewTable;
    918     UINT32                  NumTables;
    919     UINT32                  PointerSize;
    920     UINT32                  TableIndex;
    921 
    922 
    923     if (GetAllTables)
    924     {
    925         ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT);
    926         AcpiOsTableOverride (&TableHeader, &NewTable);
    927         if (!NewTable)
    928         {
    929             fprintf (stderr, "Could not obtain RSDT\n");
    930             return AE_NO_ACPI_TABLES;
    931         }
    932         else
    933         {
    934             AdWriteTable (NewTable, NewTable->Length,
    935                 ACPI_SIG_RSDT, NewTable->OemTableId);
    936         }
    937 
    938         if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT))
    939         {
    940             PointerSize = sizeof (UINT32);
    941         }
    942         else
    943         {
    944             PointerSize = sizeof (UINT64);
    945         }
    946 
    947         /*
    948          * Determine the number of tables pointed to by the RSDT/XSDT.
    949          * This is defined by the ACPI Specification to be the number of
    950          * pointers contained within the RSDT/XSDT.  The size of the pointers
    951          * is architecture-dependent.
    952          */
    953         NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize;
    954         AcpiOsPrintf ("There are %u tables defined in the %4.4s\n\n",
    955             NumTables, NewTable->Signature);
    956 
    957         /* Get the FADT */
    958 
    959         ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT);
    960         AcpiOsTableOverride (&TableHeader, &NewTable);
    961         if (NewTable)
    962         {
    963             AdWriteTable (NewTable, NewTable->Length,
    964                 ACPI_SIG_FADT, NewTable->OemTableId);
    965         }
    966         AcpiOsPrintf ("\n");
    967 
    968         /* Don't bother with FACS, it is usually all zeros */
    969     }
    970 
    971     /* Always get the DSDT */
    972 
    973     ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT);
    974     AcpiOsTableOverride (&TableHeader, &NewTable);
    975     if (NewTable)
    976     {
    977         AdWriteTable (NewTable, NewTable->Length,
    978             ACPI_SIG_DSDT, NewTable->OemTableId);
    979 
    980         /* Store DSDT in the Table Manager */
    981 
    982         Status = AcpiTbStoreTable (0, NewTable, NewTable->Length,
    983                     0, &TableIndex);
    984         if (ACPI_FAILURE (Status))
    985         {
    986             fprintf (stderr, "Could not store DSDT\n");
    987             return AE_NO_ACPI_TABLES;
    988         }
    989     }
    990     else
    991     {
    992         fprintf (stderr, "Could not obtain DSDT\n");
    993         return AE_NO_ACPI_TABLES;
    994     }
    995 
    996 #if 0
    997     /* TBD: Future implementation */
    998 
    999     AcpiOsPrintf ("\n");
   1000 
   1001     /* Get all SSDTs */
   1002 
   1003     ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT);
   1004     do
   1005     {
   1006         NewTable = NULL;
   1007         Status = AcpiOsTableOverride (&TableHeader, &NewTable);
   1008 
   1009     } while (NewTable);
   1010 #endif
   1011 
   1012     return AE_OK;
   1013 }
   1014 
   1015 
   1016 /******************************************************************************
   1017  *
   1018  * FUNCTION:    AdParseTable
   1019  *
   1020  * PARAMETERS:  Table               - Pointer to the raw table
   1021  *              OwnerId             - Returned OwnerId of the table
   1022  *              LoadTable           - If add table to the global table list
   1023  *              External            - If this is an external table
   1024  *
   1025  * RETURN:      Status
   1026  *
   1027  * DESCRIPTION: Parse the DSDT.
   1028  *
   1029  *****************************************************************************/
   1030 
   1031 ACPI_STATUS
   1032 AdParseTable (
   1033     ACPI_TABLE_HEADER       *Table,
   1034     ACPI_OWNER_ID           *OwnerId,
   1035     BOOLEAN                 LoadTable,
   1036     BOOLEAN                 External)
   1037 {
   1038     ACPI_STATUS             Status = AE_OK;
   1039     ACPI_WALK_STATE         *WalkState;
   1040     UINT8                   *AmlStart;
   1041     UINT32                  AmlLength;
   1042     UINT32                  TableIndex;
   1043 
   1044 
   1045     if (!Table)
   1046     {
   1047         return AE_NOT_EXIST;
   1048     }
   1049 
   1050     /* Pass 1:  Parse everything except control method bodies */
   1051 
   1052     fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature);
   1053 
   1054     AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
   1055     AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER));
   1056 
   1057     /* Create the root object */
   1058 
   1059     AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp ();
   1060     if (!AcpiGbl_ParseOpRoot)
   1061     {
   1062         return AE_NO_MEMORY;
   1063     }
   1064 
   1065     /* Create and initialize a new walk state */
   1066 
   1067     WalkState = AcpiDsCreateWalkState (0,
   1068                         AcpiGbl_ParseOpRoot, NULL, NULL);
   1069     if (!WalkState)
   1070     {
   1071         return (AE_NO_MEMORY);
   1072     }
   1073 
   1074     Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot,
   1075                 NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
   1076     if (ACPI_FAILURE (Status))
   1077     {
   1078         return (Status);
   1079     }
   1080 
   1081     WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
   1082     WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
   1083 
   1084     Status = AcpiPsParseAml (WalkState);
   1085     if (ACPI_FAILURE (Status))
   1086     {
   1087         return Status;
   1088     }
   1089 
   1090     /* If LoadTable is FALSE, we are parsing the last loaded table */
   1091 
   1092     TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1;
   1093 
   1094     /* Pass 2 */
   1095 
   1096     if (LoadTable)
   1097     {
   1098         Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table,
   1099                     Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex);
   1100         if (ACPI_FAILURE (Status))
   1101         {
   1102             return Status;
   1103         }
   1104         Status = AcpiTbAllocateOwnerId (TableIndex);
   1105         if (ACPI_FAILURE (Status))
   1106         {
   1107             return Status;
   1108         }
   1109         if (OwnerId)
   1110         {
   1111             Status = AcpiTbGetOwnerId (TableIndex, OwnerId);
   1112             if (ACPI_FAILURE (Status))
   1113             {
   1114                 return Status;
   1115             }
   1116         }
   1117     }
   1118 
   1119     fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature);
   1120 
   1121     Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL);
   1122     if (ACPI_FAILURE (Status))
   1123     {
   1124         return (Status);
   1125     }
   1126 
   1127     /* No need to parse control methods of external table */
   1128 
   1129     if (External)
   1130     {
   1131         return AE_OK;
   1132     }
   1133 
   1134     /* Pass 3: Parse control methods and link their parse trees into the main parse tree */
   1135 
   1136     Status = AdParseDeferredOps (AcpiGbl_ParseOpRoot);
   1137 
   1138     /* Process Resource Templates */
   1139 
   1140     AcpiDmFindResources (AcpiGbl_ParseOpRoot);
   1141 
   1142     fprintf (stderr, "Parsing completed\n");
   1143     return AE_OK;
   1144 }
   1145 
   1146 
   1147