Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: dtcompile.c - Front-end for data table compiler
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2010, 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. #define __DTCOMPILE_C__
  117. #define _DECLARE_DT_GLOBALS
  118.  
  119. #include "aslcompiler.h"
  120. #include "dtcompiler.h"
  121.  
  122. #define _COMPONENT          DT_COMPILER
  123.         ACPI_MODULE_NAME    ("dtcompile")
  124.  
  125. static char                 VersionString[9];
  126.  
  127.  
  128. /* Local prototypes */
  129.  
  130. static void
  131. DtInitialize (
  132.     void);
  133.  
  134. static ACPI_STATUS
  135. DtCompileDataTable (
  136.     DT_FIELD                **Field);
  137.  
  138. static void
  139. DtInsertCompilerIds (
  140.     DT_FIELD                *FieldList);
  141.  
  142.  
  143. /******************************************************************************
  144.  *
  145.  * FUNCTION:    DtDoCompile
  146.  *
  147.  * PARAMETERS:  None
  148.  *
  149.  * RETURN:      Status
  150.  *
  151.  * DESCRIPTION: Main entry point for the data table compiler.
  152.  *
  153.  * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is
  154.  *          open at seek offset zero.
  155.  *
  156.  *****************************************************************************/
  157.  
  158. ACPI_STATUS
  159. DtDoCompile (
  160.     void)
  161. {
  162.     ACPI_STATUS             Status;
  163.     UINT8                   Event;
  164.     DT_FIELD                *FieldList;
  165.  
  166.  
  167.     /* Initialize globals */
  168.  
  169.     DtInitialize ();
  170.  
  171.     /*
  172.      * Scan the input file (file is already open) and
  173.      * build the parse tree
  174.      */
  175.     Event = UtBeginEvent ("Scan and parse input file");
  176.     FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
  177.     UtEndEvent (Event);
  178.  
  179.     /* Did the parse tree get successfully constructed? */
  180.  
  181.     if (!FieldList)
  182.     {
  183.         /* TBD: temporary error message. Msgs should come from function above */
  184.  
  185.         DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
  186.             "Could not parse input file");
  187.         return (AE_ERROR);
  188.     }
  189.  
  190.     Event = UtBeginEvent ("Compile parse tree");
  191.  
  192.     /*
  193.      * Compile the parse tree
  194.      */
  195.     Status = DtCompileDataTable (&FieldList);
  196.     UtEndEvent (Event);
  197.  
  198.     DtFreeFieldList ();
  199.  
  200.     if (ACPI_FAILURE (Status))
  201.     {
  202.         /* TBD: temporary error message. Msgs should come from function above */
  203.  
  204.         DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
  205.             "Could not compile input file");
  206.         goto CleanupAndExit;
  207.     }
  208.  
  209.     /* Create/open the binary output file */
  210.  
  211.     Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
  212.     Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
  213.     if (ACPI_FAILURE (Status))
  214.     {
  215.         goto CleanupAndExit;
  216.     }
  217.  
  218.     /* Write the binary, then the optional hex file */
  219.  
  220.     DtOutputBinary (Gbl_RootTable);
  221.     LsDoHexOutput ();
  222.  
  223. CleanupAndExit:
  224.  
  225.     CmCleanupAndExit ();
  226.     return (Status);
  227. }
  228.  
  229.  
  230. /******************************************************************************
  231.  *
  232.  * FUNCTION:    DtInitialize
  233.  *
  234.  * PARAMETERS:  None
  235.  *
  236.  * RETURN:      None
  237.  *
  238.  * DESCRIPTION: Initialize data table compiler globals. Enables multiple
  239.  *              compiles per invocation.
  240.  *
  241.  *****************************************************************************/
  242.  
  243. static void
  244. DtInitialize (
  245.     void)
  246. {
  247.  
  248.     Gbl_FieldList = NULL;
  249.     Gbl_RootTable = NULL;
  250.     Gbl_SubtableStack = NULL;
  251.  
  252.     sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
  253. }
  254.  
  255.  
  256. /******************************************************************************
  257.  *
  258.  * FUNCTION:    DtInsertCompilerIds
  259.  *
  260.  * PARAMETERS:  FieldList           - Current field list pointer
  261.  *
  262.  * RETURN:      None
  263.  *
  264.  * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
  265.  *              the original ACPI table header.
  266.  *
  267.  *****************************************************************************/
  268.  
  269. static void
  270. DtInsertCompilerIds (
  271.     DT_FIELD                *FieldList)
  272. {
  273.     DT_FIELD                *Next;
  274.     UINT32                  i;
  275.  
  276.  
  277.     /*
  278.      * Don't insert current compiler ID if requested. Used for compiler
  279.      * debug/validation only.
  280.      */
  281.     if (Gbl_UseOriginalCompilerId)
  282.     {
  283.         return;
  284.     }
  285.  
  286.     /* Walk to the Compiler fields at the end of the header */
  287.  
  288.     Next = FieldList;
  289.     for (i = 0; i < 7; i++)
  290.     {
  291.         Next = Next->Next;
  292.     }
  293.  
  294.     Next->Value = CompilerCreatorId;
  295.     Next->Flags = DT_FIELD_NOT_ALLOCATED;
  296.  
  297.     Next = Next->Next;
  298.     Next->Value = VersionString;
  299.     Next->Flags = DT_FIELD_NOT_ALLOCATED;
  300. }
  301.  
  302.  
  303. /******************************************************************************
  304.  *
  305.  * FUNCTION:    DtCompileDataTable
  306.  *
  307.  * PARAMETERS:  FieldList           - Current field list pointer
  308.  *
  309.  * RETURN:      Status
  310.  *
  311.  * DESCRIPTION: Entry point to compile one data table
  312.  *
  313.  *****************************************************************************/
  314.  
  315. static ACPI_STATUS
  316. DtCompileDataTable (
  317.     DT_FIELD                **FieldList)
  318. {
  319.     ACPI_DMTABLE_DATA       *TableData;
  320.     DT_SUBTABLE             *Subtable;
  321.     char                    *Signature;
  322.     ACPI_TABLE_HEADER       *AcpiTableHeader;
  323.     ACPI_STATUS             Status;
  324.  
  325.  
  326.     /* Verify that we at least have a table signature and save it */
  327.  
  328.     Signature = DtGetFieldValue (*FieldList, "Signature");
  329.     if (!Signature)
  330.     {
  331.         DtError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, *FieldList, NULL);
  332.         return (AE_ERROR);
  333.     }
  334.  
  335.     Gbl_Signature = UtLocalCalloc (ACPI_STRLEN (Signature) + 1);
  336.     strcpy (Gbl_Signature, Signature);
  337.  
  338.     /*
  339.      * Handle tables that don't use the common ACPI table header structure.
  340.      * Currently, these are the FACS and RSDP. Also check for an OEMx table,
  341.      * these tables have user-defined contents.
  342.      */
  343.     if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
  344.     {
  345.         Status = DtCompileFacs (FieldList);
  346.         if (ACPI_FAILURE (Status))
  347.         {
  348.             return (Status);
  349.         }
  350.  
  351.         DtSetTableLength ();
  352.         return (Status);
  353.     }
  354.     else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDP))
  355.     {
  356.         Status = DtCompileRsdp (FieldList);
  357.         return (Status);
  358.     }
  359.     else if (!ACPI_STRNCMP (Signature, "OEM", 3))
  360.     {
  361.         DtFatal (ASL_MSG_OEM_TABLE, *FieldList, Signature);
  362.         return (AE_ERROR);
  363.     }
  364.  
  365.     /*
  366.      * All other tables must use the common ACPI table header. Insert the
  367.      * current iASL IDs (name, version), and compile the header now.
  368.      */
  369.     DtInsertCompilerIds (*FieldList);
  370.  
  371.     Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
  372.                 &Gbl_RootTable, TRUE);
  373.     if (ACPI_FAILURE (Status))
  374.     {
  375.         return (Status);
  376.     }
  377.  
  378.     DtPushSubtable (Gbl_RootTable);
  379.  
  380.     /* Match signature and dispatch appropriately */
  381.  
  382.     TableData = AcpiDmGetTableData (Signature);
  383.     if (!TableData)
  384.     {
  385.         DtFatal (ASL_MSG_UNKNOWN_TABLE, *FieldList, Signature);
  386.         return (AE_ERROR);
  387.     }
  388.  
  389.     if (TableData->CmTableHandler)
  390.     {
  391.         /* Complex table, has a handler */
  392.  
  393.         Status = TableData->CmTableHandler ((void **) FieldList);
  394.         if (ACPI_FAILURE (Status))
  395.         {
  396.             return (Status);
  397.         }
  398.     }
  399.     else if (TableData->TableInfo)
  400.     {
  401.         /* Simple table, just walk the info table */
  402.  
  403.         Subtable = NULL;
  404.         Status = DtCompileTable (FieldList, TableData->TableInfo,
  405.                     &Subtable, TRUE);
  406.         if (ACPI_FAILURE (Status))
  407.         {
  408.             return (Status);
  409.         }
  410.  
  411.         DtInsertSubtable (Gbl_RootTable, Subtable);
  412.         DtPopSubtable ();
  413.     }
  414.     else
  415.     {
  416.         DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
  417.             "Missing table dispatch info");
  418.         return (AE_ERROR);
  419.     }
  420.  
  421.     /* Set the final table length and then the checksum */
  422.  
  423.     DtSetTableLength ();
  424.     AcpiTableHeader = ACPI_CAST_PTR (
  425.         ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
  426.     DtSetTableChecksum (&AcpiTableHeader->Checksum);
  427.  
  428.     return (AE_OK);
  429. }
  430.  
  431.  
  432. /******************************************************************************
  433.  *
  434.  * FUNCTION:    DtCompileTable
  435.  *
  436.  * PARAMETERS:  Field               - Current field list pointer
  437.  *              Info                - Info table for this ACPI table
  438.  *              RetSubtable         - Compile result of table
  439.  *              Required            - If this subtable must exist
  440.  *
  441.  * RETURN:      Status
  442.  *
  443.  * DESCRIPTION: Compile a subtable
  444.  *
  445.  *****************************************************************************/
  446.  
  447. ACPI_STATUS
  448. DtCompileTable (
  449.     DT_FIELD                **Field,
  450.     ACPI_DMTABLE_INFO       *Info,
  451.     DT_SUBTABLE             **RetSubtable,
  452.     BOOLEAN                 Required)
  453. {
  454.     DT_FIELD                *LocalField;
  455.     UINT32                  Length;
  456.     DT_SUBTABLE             *Subtable;
  457.     DT_SUBTABLE             *InlineSubtable;
  458.     UINT32                  FieldLength = 0;
  459.     UINT8                   FieldType;
  460.     UINT8                   *Buffer;
  461.     UINT8                   *FlagBuffer = NULL;
  462.     UINT32                  FlagBitPosition = 0;
  463.     ACPI_STATUS             Status;
  464.  
  465.  
  466.     if (!Field || !*Field)
  467.     {
  468.         return (AE_BAD_PARAMETER);
  469.     }
  470.  
  471.     Length = DtGetSubtableLength (*Field, Info);
  472.     Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE));
  473.  
  474.     Subtable->Buffer = UtLocalCalloc (Length);
  475.     Subtable->Length = Length;
  476.     Subtable->TotalLength = Length;
  477.     Buffer = Subtable->Buffer;
  478.  
  479.     LocalField = *Field;
  480.  
  481.     /*
  482.      * Main loop walks the info table for this ACPI table or subtable
  483.      */
  484.     for (; Info->Name; Info++)
  485.     {
  486.         if (!LocalField)
  487.         {
  488.             sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
  489.                 Info->Name);
  490.             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
  491.             Status = AE_BAD_DATA;
  492.             goto Error;
  493.         }
  494.  
  495.         /* Does input field name match what is expected? */
  496.  
  497.         if (ACPI_STRCMP (LocalField->Name, Info->Name))
  498.         {
  499.             /*
  500.              * If Required = TRUE, the subtable must exist.
  501.              * If Required = FALSE, the subtable is optional
  502.              * (For example, AcpiDmTableInfoDmarScope in DMAR table is
  503.              * optional)
  504.              */
  505.             if (Required)
  506.             {
  507.                 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
  508.                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
  509.                     LocalField, MsgBuffer);
  510.             }
  511.             else
  512.             {
  513.                 Status = AE_NOT_FOUND;
  514.                 goto Error;
  515.             }
  516.         }
  517.  
  518.         FieldLength = DtGetFieldLength (LocalField, Info);
  519.         FieldType = DtGetFieldType (Info);
  520.         Gbl_InputFieldCount++;
  521.  
  522.         switch (FieldType)
  523.         {
  524.         case DT_FIELD_TYPE_FLAGS_INTEGER:
  525.             /*
  526.              * Start of the definition of a flags field.
  527.              * This master flags integer starts at value zero, in preparation
  528.              * to compile and insert the flag fields from the individual bits
  529.              */
  530.             LocalField = LocalField->Next;
  531.             *Field = LocalField;
  532.  
  533.             FlagBitPosition = 0;
  534.             FlagBuffer = Buffer;
  535.             break;
  536.  
  537.         case DT_FIELD_TYPE_FLAG:
  538.  
  539.             /* Individual Flag field, can be multiple bits */
  540.  
  541.             if (FlagBuffer)
  542.             {
  543.                 FlagBitPosition = DtCompileFlag (FlagBuffer,
  544.                      LocalField, Info, FlagBitPosition);
  545.             }
  546.             else
  547.             {
  548.                 /* TBD - this is an internal error */
  549.             }
  550.  
  551.             LocalField = LocalField->Next;
  552.             *Field = LocalField;
  553.             break;
  554.  
  555.         case DT_FIELD_TYPE_INLINE_SUBTABLE:
  556.             /*
  557.              * Recursion (one level max): compile GAS (Generic Address)
  558.              * or Notify in-line subtable
  559.              */
  560.             LocalField = LocalField->Next;
  561.             *Field = LocalField;
  562.  
  563.             if (Info->Opcode == ACPI_DMT_GAS)
  564.             {
  565.                 Status = DtCompileTable (Field, AcpiDmTableInfoGas,
  566.                     &InlineSubtable, TRUE);
  567.             }
  568.             else
  569.             {
  570.                 Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
  571.                     &InlineSubtable, TRUE);
  572.             }
  573.  
  574.             if (ACPI_FAILURE (Status))
  575.             {
  576.                 goto Error;
  577.             }
  578.  
  579.             ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength);
  580.             ACPI_FREE (InlineSubtable->Buffer);
  581.             ACPI_FREE (InlineSubtable);
  582.             LocalField = *Field;
  583.             break;
  584.  
  585.         default:
  586.  
  587.             /* Normal case for most field types (Integer, String, etc.) */
  588.  
  589.             DtCompileOneField (Buffer, LocalField,
  590.                 FieldLength, FieldType, Info->Flags);
  591.             LocalField = LocalField->Next;
  592.  
  593.             if (Info->Flags & DT_LENGTH)
  594.             {
  595.                 /* Field is an Integer that will contain a subtable length */
  596.  
  597.                 Subtable->LengthField = Buffer;
  598.                 Subtable->SizeOfLengthField = FieldLength;
  599.             }
  600.             break;
  601.         }
  602.  
  603.         Buffer += FieldLength;
  604.     }
  605.  
  606.     *Field = LocalField;
  607.     *RetSubtable = Subtable;
  608.     return (AE_OK);
  609.  
  610. Error:
  611.     ACPI_FREE (Subtable->Buffer);
  612.     ACPI_FREE (Subtable);
  613.     return (Status);
  614. }
  615.