Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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