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