0,0 → 1,614 |
/****************************************************************************** |
* |
* Module Name: dtcompile.c - Front-end for data table compiler |
* |
*****************************************************************************/ |
|
/****************************************************************************** |
* |
* 1. Copyright Notice |
* |
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. |
* All rights reserved. |
* |
* 2. License |
* |
* 2.1. This is your license from Intel Corp. under its intellectual property |
* rights. You may have additional license terms from the party that provided |
* you this software, covering your right to use that party's intellectual |
* property rights. |
* |
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a |
* copy of the source code appearing in this file ("Covered Code") an |
* irrevocable, perpetual, worldwide license under Intel's copyrights in the |
* base code distributed originally by Intel ("Original Intel Code") to copy, |
* make derivatives, distribute, use and display any portion of the Covered |
* Code in any form, with the right to sublicense such rights; and |
* |
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent |
* license (with the right to sublicense), under only those claims of Intel |
* patents that are infringed by the Original Intel Code, to make, use, sell, |
* offer to sell, and import the Covered Code and derivative works thereof |
* solely to the minimum extent necessary to exercise the above copyright |
* license, and in no event shall the patent license extend to any additions |
* to or modifications of the Original Intel Code. No other license or right |
* is granted directly or by implication, estoppel or otherwise; |
* |
* The above copyright and patent license is granted only if the following |
* conditions are met: |
* |
* 3. Conditions |
* |
* 3.1. Redistribution of Source with Rights to Further Distribute Source. |
* Redistribution of source code of any substantial portion of the Covered |
* Code or modification with rights to further distribute source must include |
* the above Copyright Notice, the above License, this list of Conditions, |
* and the following Disclaimer and Export Compliance provision. In addition, |
* Licensee must cause all Covered Code to which Licensee contributes to |
* contain a file documenting the changes Licensee made to create that Covered |
* Code and the date of any change. Licensee must include in that file the |
* documentation of any changes made by any predecessor Licensee. Licensee |
* must include a prominent statement that the modification is derived, |
* directly or indirectly, from Original Intel Code. |
* |
* 3.2. Redistribution of Source with no Rights to Further Distribute Source. |
* Redistribution of source code of any substantial portion of the Covered |
* Code or modification without rights to further distribute source must |
* include the following Disclaimer and Export Compliance provision in the |
* documentation and/or other materials provided with distribution. In |
* addition, Licensee may not authorize further sublicense of source of any |
* portion of the Covered Code, and must include terms to the effect that the |
* license from Licensee to its licensee is limited to the intellectual |
* property embodied in the software Licensee provides to its licensee, and |
* not to intellectual property embodied in modifications its licensee may |
* make. |
* |
* 3.3. Redistribution of Executable. Redistribution in executable form of any |
* substantial portion of the Covered Code or modification must reproduce the |
* above Copyright Notice, and the following Disclaimer and Export Compliance |
* provision in the documentation and/or other materials provided with the |
* distribution. |
* |
* 3.4. Intel retains all right, title, and interest in and to the Original |
* Intel Code. |
* |
* 3.5. Neither the name Intel nor any other trademark owned or controlled by |
* Intel shall be used in advertising or otherwise to promote the sale, use or |
* other dealings in products derived from or relating to the Covered Code |
* without prior written authorization from Intel. |
* |
* 4. Disclaimer and Export Compliance |
* |
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED |
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE |
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, |
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY |
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY |
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A |
* PARTICULAR PURPOSE. |
* |
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES |
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR |
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, |
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY |
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL |
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS |
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY |
* LIMITED REMEDY. |
* |
* 4.3. Licensee shall not export, either directly or indirectly, any of this |
* software or system incorporating such software without first obtaining any |
* required license or other approval from the U. S. Department of Commerce or |
* any other agency or department of the United States Government. In the |
* event Licensee exports any such software from the United States or |
* re-exports any such software from a foreign destination, Licensee shall |
* ensure that the distribution and export/re-export of the software is in |
* compliance with all laws, regulations, orders, or other restrictions of the |
* U.S. Export Administration Regulations. Licensee agrees that neither it nor |
* any of its subsidiaries will export/re-export any technical data, process, |
* software, or service, directly or indirectly, to any country for which the |
* United States government or any agency thereof requires an export license, |
* other governmental approval, or letter of assurance, without first obtaining |
* such license, approval or letter. |
* |
*****************************************************************************/ |
|
#define __DTCOMPILE_C__ |
#define _DECLARE_DT_GLOBALS |
|
#include "aslcompiler.h" |
#include "dtcompiler.h" |
|
#define _COMPONENT DT_COMPILER |
ACPI_MODULE_NAME ("dtcompile") |
|
static char VersionString[9]; |
|
|
/* Local prototypes */ |
|
static void |
DtInitialize ( |
void); |
|
static ACPI_STATUS |
DtCompileDataTable ( |
DT_FIELD **Field); |
|
static void |
DtInsertCompilerIds ( |
DT_FIELD *FieldList); |
|
|
/****************************************************************************** |
* |
* FUNCTION: DtDoCompile |
* |
* PARAMETERS: None |
* |
* RETURN: Status |
* |
* DESCRIPTION: Main entry point for the data table compiler. |
* |
* Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is |
* open at seek offset zero. |
* |
*****************************************************************************/ |
|
ACPI_STATUS |
DtDoCompile ( |
void) |
{ |
ACPI_STATUS Status; |
UINT8 Event; |
DT_FIELD *FieldList; |
|
|
/* Initialize globals */ |
|
DtInitialize (); |
|
/* |
* Scan the input file (file is already open) and |
* build the parse tree |
*/ |
Event = UtBeginEvent ("Scan and parse input file"); |
FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle); |
UtEndEvent (Event); |
|
/* Did the parse tree get successfully constructed? */ |
|
if (!FieldList) |
{ |
/* TBD: temporary error message. Msgs should come from function above */ |
|
DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, |
"Could not parse input file"); |
return (AE_ERROR); |
} |
|
Event = UtBeginEvent ("Compile parse tree"); |
|
/* |
* Compile the parse tree |
*/ |
Status = DtCompileDataTable (&FieldList); |
UtEndEvent (Event); |
|
DtFreeFieldList (); |
|
if (ACPI_FAILURE (Status)) |
{ |
/* TBD: temporary error message. Msgs should come from function above */ |
|
DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, |
"Could not compile input file"); |
goto CleanupAndExit; |
} |
|
/* Create/open the binary output file */ |
|
Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL; |
Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix); |
if (ACPI_FAILURE (Status)) |
{ |
goto CleanupAndExit; |
} |
|
/* Write the binary, then the optional hex file */ |
|
DtOutputBinary (Gbl_RootTable); |
LsDoHexOutput (); |
|
CleanupAndExit: |
|
CmCleanupAndExit (); |
return (Status); |
} |
|
|
/****************************************************************************** |
* |
* FUNCTION: DtInitialize |
* |
* PARAMETERS: None |
* |
* RETURN: None |
* |
* DESCRIPTION: Initialize data table compiler globals. Enables multiple |
* compiles per invocation. |
* |
*****************************************************************************/ |
|
static void |
DtInitialize ( |
void) |
{ |
|
Gbl_FieldList = NULL; |
Gbl_RootTable = NULL; |
Gbl_SubtableStack = NULL; |
|
sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION); |
} |
|
|
/****************************************************************************** |
* |
* FUNCTION: DtInsertCompilerIds |
* |
* PARAMETERS: FieldList - Current field list pointer |
* |
* RETURN: None |
* |
* DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into |
* the original ACPI table header. |
* |
*****************************************************************************/ |
|
static void |
DtInsertCompilerIds ( |
DT_FIELD *FieldList) |
{ |
DT_FIELD *Next; |
UINT32 i; |
|
|
/* |
* Don't insert current compiler ID if requested. Used for compiler |
* debug/validation only. |
*/ |
if (Gbl_UseOriginalCompilerId) |
{ |
return; |
} |
|
/* Walk to the Compiler fields at the end of the header */ |
|
Next = FieldList; |
for (i = 0; i < 7; i++) |
{ |
Next = Next->Next; |
} |
|
Next->Value = CompilerCreatorId; |
Next->Flags = DT_FIELD_NOT_ALLOCATED; |
|
Next = Next->Next; |
Next->Value = VersionString; |
Next->Flags = DT_FIELD_NOT_ALLOCATED; |
} |
|
|
/****************************************************************************** |
* |
* FUNCTION: DtCompileDataTable |
* |
* PARAMETERS: FieldList - Current field list pointer |
* |
* RETURN: Status |
* |
* DESCRIPTION: Entry point to compile one data table |
* |
*****************************************************************************/ |
|
static ACPI_STATUS |
DtCompileDataTable ( |
DT_FIELD **FieldList) |
{ |
ACPI_DMTABLE_DATA *TableData; |
DT_SUBTABLE *Subtable; |
char *Signature; |
ACPI_TABLE_HEADER *AcpiTableHeader; |
ACPI_STATUS Status; |
|
|
/* Verify that we at least have a table signature and save it */ |
|
Signature = DtGetFieldValue (*FieldList, "Signature"); |
if (!Signature) |
{ |
DtError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, *FieldList, NULL); |
return (AE_ERROR); |
} |
|
Gbl_Signature = UtLocalCalloc (ACPI_STRLEN (Signature) + 1); |
strcpy (Gbl_Signature, Signature); |
|
/* |
* Handle tables that don't use the common ACPI table header structure. |
* Currently, these are the FACS and RSDP. Also check for an OEMx table, |
* these tables have user-defined contents. |
*/ |
if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS)) |
{ |
Status = DtCompileFacs (FieldList); |
if (ACPI_FAILURE (Status)) |
{ |
return (Status); |
} |
|
DtSetTableLength (); |
return (Status); |
} |
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDP)) |
{ |
Status = DtCompileRsdp (FieldList); |
return (Status); |
} |
else if (!ACPI_STRNCMP (Signature, "OEM", 3)) |
{ |
DtFatal (ASL_MSG_OEM_TABLE, *FieldList, Signature); |
return (AE_ERROR); |
} |
|
/* |
* All other tables must use the common ACPI table header. Insert the |
* current iASL IDs (name, version), and compile the header now. |
*/ |
DtInsertCompilerIds (*FieldList); |
|
Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader, |
&Gbl_RootTable, TRUE); |
if (ACPI_FAILURE (Status)) |
{ |
return (Status); |
} |
|
DtPushSubtable (Gbl_RootTable); |
|
/* Match signature and dispatch appropriately */ |
|
TableData = AcpiDmGetTableData (Signature); |
if (!TableData) |
{ |
DtFatal (ASL_MSG_UNKNOWN_TABLE, *FieldList, Signature); |
return (AE_ERROR); |
} |
|
if (TableData->CmTableHandler) |
{ |
/* Complex table, has a handler */ |
|
Status = TableData->CmTableHandler ((void **) FieldList); |
if (ACPI_FAILURE (Status)) |
{ |
return (Status); |
} |
} |
else if (TableData->TableInfo) |
{ |
/* Simple table, just walk the info table */ |
|
Subtable = NULL; |
Status = DtCompileTable (FieldList, TableData->TableInfo, |
&Subtable, TRUE); |
if (ACPI_FAILURE (Status)) |
{ |
return (Status); |
} |
|
DtInsertSubtable (Gbl_RootTable, Subtable); |
DtPopSubtable (); |
} |
else |
{ |
DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList, |
"Missing table dispatch info"); |
return (AE_ERROR); |
} |
|
/* Set the final table length and then the checksum */ |
|
DtSetTableLength (); |
AcpiTableHeader = ACPI_CAST_PTR ( |
ACPI_TABLE_HEADER, Gbl_RootTable->Buffer); |
DtSetTableChecksum (&AcpiTableHeader->Checksum); |
|
return (AE_OK); |
} |
|
|
/****************************************************************************** |
* |
* FUNCTION: DtCompileTable |
* |
* PARAMETERS: Field - Current field list pointer |
* Info - Info table for this ACPI table |
* RetSubtable - Compile result of table |
* Required - If this subtable must exist |
* |
* RETURN: Status |
* |
* DESCRIPTION: Compile a subtable |
* |
*****************************************************************************/ |
|
ACPI_STATUS |
DtCompileTable ( |
DT_FIELD **Field, |
ACPI_DMTABLE_INFO *Info, |
DT_SUBTABLE **RetSubtable, |
BOOLEAN Required) |
{ |
DT_FIELD *LocalField; |
UINT32 Length; |
DT_SUBTABLE *Subtable; |
DT_SUBTABLE *InlineSubtable; |
UINT32 FieldLength = 0; |
UINT8 FieldType; |
UINT8 *Buffer; |
UINT8 *FlagBuffer = NULL; |
UINT32 FlagBitPosition = 0; |
ACPI_STATUS Status; |
|
|
if (!Field || !*Field) |
{ |
return (AE_BAD_PARAMETER); |
} |
|
Length = DtGetSubtableLength (*Field, Info); |
Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE)); |
|
Subtable->Buffer = UtLocalCalloc (Length); |
Subtable->Length = Length; |
Subtable->TotalLength = Length; |
Buffer = Subtable->Buffer; |
|
LocalField = *Field; |
|
/* |
* Main loop walks the info table for this ACPI table or subtable |
*/ |
for (; Info->Name; Info++) |
{ |
if (!LocalField) |
{ |
sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", |
Info->Name); |
DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); |
Status = AE_BAD_DATA; |
goto Error; |
} |
|
/* Does input field name match what is expected? */ |
|
if (ACPI_STRCMP (LocalField->Name, Info->Name)) |
{ |
/* |
* If Required = TRUE, the subtable must exist. |
* If Required = FALSE, the subtable is optional |
* (For example, AcpiDmTableInfoDmarScope in DMAR table is |
* optional) |
*/ |
if (Required) |
{ |
sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); |
DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, |
LocalField, MsgBuffer); |
} |
else |
{ |
Status = AE_NOT_FOUND; |
goto Error; |
} |
} |
|
FieldLength = DtGetFieldLength (LocalField, Info); |
FieldType = DtGetFieldType (Info); |
Gbl_InputFieldCount++; |
|
switch (FieldType) |
{ |
case DT_FIELD_TYPE_FLAGS_INTEGER: |
/* |
* Start of the definition of a flags field. |
* This master flags integer starts at value zero, in preparation |
* to compile and insert the flag fields from the individual bits |
*/ |
LocalField = LocalField->Next; |
*Field = LocalField; |
|
FlagBitPosition = 0; |
FlagBuffer = Buffer; |
break; |
|
case DT_FIELD_TYPE_FLAG: |
|
/* Individual Flag field, can be multiple bits */ |
|
if (FlagBuffer) |
{ |
FlagBitPosition = DtCompileFlag (FlagBuffer, |
LocalField, Info, FlagBitPosition); |
} |
else |
{ |
/* TBD - this is an internal error */ |
} |
|
LocalField = LocalField->Next; |
*Field = LocalField; |
break; |
|
case DT_FIELD_TYPE_INLINE_SUBTABLE: |
/* |
* Recursion (one level max): compile GAS (Generic Address) |
* or Notify in-line subtable |
*/ |
LocalField = LocalField->Next; |
*Field = LocalField; |
|
if (Info->Opcode == ACPI_DMT_GAS) |
{ |
Status = DtCompileTable (Field, AcpiDmTableInfoGas, |
&InlineSubtable, TRUE); |
} |
else |
{ |
Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify, |
&InlineSubtable, TRUE); |
} |
|
if (ACPI_FAILURE (Status)) |
{ |
goto Error; |
} |
|
ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength); |
ACPI_FREE (InlineSubtable->Buffer); |
ACPI_FREE (InlineSubtable); |
LocalField = *Field; |
break; |
|
default: |
|
/* Normal case for most field types (Integer, String, etc.) */ |
|
DtCompileOneField (Buffer, LocalField, |
FieldLength, FieldType, Info->Flags); |
LocalField = LocalField->Next; |
|
if (Info->Flags & DT_LENGTH) |
{ |
/* Field is an Integer that will contain a subtable length */ |
|
Subtable->LengthField = Buffer; |
Subtable->SizeOfLengthField = FieldLength; |
} |
break; |
} |
|
Buffer += FieldLength; |
} |
|
*Field = LocalField; |
*RetSubtable = Subtable; |
return (AE_OK); |
|
Error: |
ACPI_FREE (Subtable->Buffer); |
ACPI_FREE (Subtable); |
return (Status); |
} |