diff options
Diffstat (limited to 'source/common')
-rw-r--r-- | source/common/adfile.c | 333 | ||||
-rw-r--r-- | source/common/adisasm.c | 1156 | ||||
-rw-r--r-- | source/common/adwalk.c | 1004 | ||||
-rw-r--r-- | source/common/dmextern.c | 672 | ||||
-rw-r--r-- | source/common/dmrestag.c | 1045 | ||||
-rw-r--r-- | source/common/dmtable.c | 1204 | ||||
-rw-r--r-- | source/common/dmtbdump.c | 2146 | ||||
-rw-r--r-- | source/common/dmtbinfo.c | 2065 | ||||
-rw-r--r-- | source/common/getopt.c | 173 |
9 files changed, 9798 insertions, 0 deletions
diff --git a/source/common/adfile.c b/source/common/adfile.c new file mode 100644 index 0000000000000..d971e6895bfdc --- /dev/null +++ b/source/common/adfile.c @@ -0,0 +1,333 @@ +/****************************************************************************** + * + * Module Name: adfile - Application-level disassembler file support routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include "acpi.h" +#include "accommon.h" +#include "acapps.h" + +#include <stdio.h> + + +#define _COMPONENT ACPI_TOOLS + ACPI_MODULE_NAME ("adfile") + +/* Local prototypes */ + +static INT32 +AdWriteBuffer ( + char *Filename, + char *Buffer, + UINT32 Length); + +static char FilenameBuf[20]; + + +/****************************************************************************** + * + * FUNCTION: AfGenerateFilename + * + * PARAMETERS: Prefix - prefix string + * TableId - The table ID + * + * RETURN: Pointer to the completed string + * + * DESCRIPTION: Build an output filename from an ACPI table ID string + * + ******************************************************************************/ + +char * +AdGenerateFilename ( + char *Prefix, + char *TableId) +{ + UINT32 i; + UINT32 j; + + + for (i = 0; Prefix[i]; i++) + { + FilenameBuf[i] = Prefix[i]; + } + + FilenameBuf[i] = '_'; + i++; + + for (j = 0; j < 8 && (TableId[j] != ' ') && (TableId[j] != 0); i++, j++) + { + FilenameBuf[i] = TableId[j]; + } + + FilenameBuf[i] = 0; + strcat (FilenameBuf, ACPI_TABLE_FILE_SUFFIX); + return FilenameBuf; +} + + +/****************************************************************************** + * + * FUNCTION: AfWriteBuffer + * + * PARAMETERS: Filename - name of file + * Buffer - data to write + * Length - length of data + * + * RETURN: Actual number of bytes written + * + * DESCRIPTION: Open a file and write out a single buffer + * + ******************************************************************************/ + +static INT32 +AdWriteBuffer ( + char *Filename, + char *Buffer, + UINT32 Length) +{ + FILE *fp; + ACPI_SIZE Actual; + + + fp = fopen (Filename, "wb"); + if (!fp) + { + printf ("Couldn't open %s\n", Filename); + return (-1); + } + + Actual = fwrite (Buffer, (size_t) Length, 1, fp); + fclose (fp); + return ((INT32) Actual); +} + + +/****************************************************************************** + * + * FUNCTION: AfWriteTable + * + * PARAMETERS: Table - pointer to the ACPI table + * Length - length of the table + * TableName - the table signature + * OemTableID - from the table header + * + * RETURN: None + * + * DESCRIPTION: Dump the loaded tables to a file (or files) + * + ******************************************************************************/ + +void +AdWriteTable ( + ACPI_TABLE_HEADER *Table, + UINT32 Length, + char *TableName, + char *OemTableId) +{ + char *Filename; + + + Filename = AdGenerateFilename (TableName, OemTableId); + AdWriteBuffer (Filename, (char *) Table, Length); + + AcpiOsPrintf ("Table [%s] written to \"%s\"\n", TableName, Filename); +} + + +/******************************************************************************* + * + * FUNCTION: FlGenerateFilename + * + * PARAMETERS: InputFilename - Original ASL source filename + * Suffix - New extension. + * + * RETURN: New filename containing the original base + the new suffix + * + * DESCRIPTION: Generate a new filename from the ASL source filename and a new + * extension. Used to create the *.LST, *.TXT, etc. files. + * + ******************************************************************************/ + +char * +FlGenerateFilename ( + char *InputFilename, + char *Suffix) +{ + char *Position; + char *NewFilename; + + + /* + * Copy the original filename to a new buffer. Leave room for the worst case + * where we append the suffix, an added dot and the null terminator. + */ + NewFilename = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) + strlen (InputFilename) + strlen (Suffix) + 2); + strcpy (NewFilename, InputFilename); + + /* Try to find the last dot in the filename */ + + Position = strrchr (NewFilename, '.'); + if (Position) + { + /* Tack on the new suffix */ + + Position++; + *Position = 0; + strcat (Position, Suffix); + } + else + { + /* No dot, add one and then the suffix */ + + strcat (NewFilename, "."); + strcat (NewFilename, Suffix); + } + + return NewFilename; +} + + +/******************************************************************************* + * + * FUNCTION: FlStrdup + * + * DESCRIPTION: Local strdup function + * + ******************************************************************************/ + +static char * +FlStrdup ( + char *String) +{ + char *NewString; + + + NewString = ACPI_ALLOCATE ((ACPI_SIZE) strlen (String) + 1); + if (!NewString) + { + return (NULL); + } + + strcpy (NewString, String); + return (NewString); +} + + +/******************************************************************************* + * + * FUNCTION: FlSplitInputPathname + * + * PARAMETERS: InputFilename - The user-specified ASL source file to be + * compiled + * OutDirectoryPath - Where the directory path prefix is + * returned + * OutFilename - Where the filename part is returned + * + * RETURN: Status + * + * DESCRIPTION: Split the input path into a directory and filename part + * 1) Directory part used to open include files + * 2) Filename part used to generate output filenames + * + ******************************************************************************/ + +ACPI_STATUS +FlSplitInputPathname ( + char *InputPath, + char **OutDirectoryPath, + char **OutFilename) +{ + char *Substring; + char *DirectoryPath; + char *Filename; + + + *OutDirectoryPath = NULL; + *OutFilename = NULL; + + if (!InputPath) + { + return (AE_OK); + } + + /* Get the path to the input filename's directory */ + + DirectoryPath = FlStrdup (InputPath); + if (!DirectoryPath) + { + return (AE_NO_MEMORY); + } + + Substring = strrchr (DirectoryPath, '\\'); + if (!Substring) + { + Substring = strrchr (DirectoryPath, '/'); + if (!Substring) + { + Substring = strrchr (DirectoryPath, ':'); + } + } + + if (!Substring) + { + DirectoryPath[0] = 0; + Filename = FlStrdup (InputPath); + } + else + { + Filename = FlStrdup (Substring + 1); + *(Substring+1) = 0; + } + + if (!Filename) + { + return (AE_NO_MEMORY); + } + + *OutDirectoryPath = DirectoryPath; + *OutFilename = Filename; + + return (AE_OK); +} + + diff --git a/source/common/adisasm.c b/source/common/adisasm.c new file mode 100644 index 0000000000000..2509ca67e948e --- /dev/null +++ b/source/common/adisasm.c @@ -0,0 +1,1156 @@ +/****************************************************************************** + * + * Module Name: adisasm - Application-level disassembler routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include "acpi.h" +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdebug.h" +#include "acdisasm.h" +#include "acdispat.h" +#include "acnamesp.h" +#include "actables.h" +#include "acapps.h" + +#include <stdio.h> +#include <time.h> + + +#define _COMPONENT ACPI_TOOLS + ACPI_MODULE_NAME ("adisasm") + + +extern int AslCompilerdebug; + + +ACPI_STATUS +LsDisplayNamespace ( + void); + +void +LsSetupNsList ( + void *Handle); + + +/* Local prototypes */ + +static void +AdCreateTableHeader ( + char *Filename, + ACPI_TABLE_HEADER *Table); + +static ACPI_STATUS +AdDeferredParse ( + ACPI_PARSE_OBJECT *Op, + UINT8 *Aml, + UINT32 AmlLength); + +static ACPI_STATUS +AdParseDeferredOps ( + ACPI_PARSE_OBJECT *Root); + + +/* Stubs for ASL compiler */ + +#ifndef ACPI_ASL_COMPILER +BOOLEAN +AcpiDsIsResultUsed ( + ACPI_PARSE_OBJECT *Op, + ACPI_WALK_STATE *WalkState) +{ + return TRUE; +} + +ACPI_STATUS +AcpiDsMethodError ( + ACPI_STATUS Status, + ACPI_WALK_STATE *WalkState) +{ + return (Status); +} +#endif + +ACPI_STATUS +AcpiNsLoadTable ( + UINT32 TableIndex, + ACPI_NAMESPACE_NODE *Node) +{ + return (AE_NOT_IMPLEMENTED); +} + +ACPI_STATUS +AcpiDsRestartControlMethod ( + ACPI_WALK_STATE *WalkState, + ACPI_OPERAND_OBJECT *ReturnDesc) +{ + return (AE_OK); +} + +void +AcpiDsTerminateControlMethod ( + ACPI_OPERAND_OBJECT *MethodDesc, + ACPI_WALK_STATE *WalkState) +{ + return; +} + +ACPI_STATUS +AcpiDsCallControlMethod ( + ACPI_THREAD_STATE *Thread, + ACPI_WALK_STATE *WalkState, + ACPI_PARSE_OBJECT *Op) +{ + return (AE_OK); +} + +ACPI_STATUS +AcpiDsMethodDataInitArgs ( + ACPI_OPERAND_OBJECT **Params, + UINT32 MaxParamCount, + ACPI_WALK_STATE *WalkState) +{ + return (AE_OK); +} + + +static ACPI_TABLE_DESC LocalTables[1]; +static ACPI_PARSE_OBJECT *AcpiGbl_ParseOpRoot; + + +/******************************************************************************* + * + * FUNCTION: AdInitialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: ACPICA and local initialization + * + ******************************************************************************/ + +ACPI_STATUS +AdInitialize ( + void) +{ + ACPI_STATUS Status; + + + /* ACPI CA subsystem initialization */ + + Status = AcpiOsInitialize (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Status = AcpiUtInitGlobals (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Status = AcpiUtMutexInitialize (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Status = AcpiNsRootInitialize (); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Setup the Table Manager (cheat - there is no RSDT) */ + + AcpiGbl_RootTableList.MaxTableCount = 1; + AcpiGbl_RootTableList.CurrentTableCount = 0; + AcpiGbl_RootTableList.Tables = LocalTables; + + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AdAmlDisassemble + * + * PARAMETERS: Filename - AML input filename + * OutToFile - TRUE if output should go to a file + * Prefix - Path prefix for output + * OutFilename - where the filename is returned + * GetAllTables - TRUE if all tables are desired + * + * RETURN: Status + * + * DESCRIPTION: Disassemble an entire ACPI table + * + *****************************************************************************/ + +ACPI_STATUS +AdAmlDisassemble ( + BOOLEAN OutToFile, + char *Filename, + char *Prefix, + char **OutFilename, + BOOLEAN GetAllTables) +{ + ACPI_STATUS Status; + char *DisasmFilename = NULL; + char *ExternalFilename; + ACPI_EXTERNAL_FILE *ExternalFileList = AcpiGbl_ExternalFileList; + FILE *File = NULL; + ACPI_TABLE_HEADER *Table = NULL; + ACPI_TABLE_HEADER *ExternalTable; + ACPI_OWNER_ID OwnerId; + + + /* + * Input: AML code from either a file or via GetTables (memory or + * registry) + */ + if (Filename) + { + Status = AcpiDbGetTableFromFile (Filename, &Table); + if (ACPI_FAILURE (Status)) + { + return Status; + } + + /* + * External filenames separated by commas + * Example: iasl -e file1,file2,file3 -d xxx.aml + */ + while (ExternalFileList) + { + ExternalFilename = ExternalFileList->Path; + if (!ACPI_STRCMP (ExternalFilename, Filename)) + { + /* Next external file */ + + ExternalFileList = ExternalFileList->Next; + + continue; + } + + Status = AcpiDbGetTableFromFile (ExternalFilename, &ExternalTable); + if (ACPI_FAILURE (Status)) + { + return Status; + } + + /* Load external table for symbol resolution */ + + if (ExternalTable) + { + Status = AdParseTable (ExternalTable, &OwnerId, TRUE, TRUE); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not parse external ACPI tables, %s\n", + AcpiFormatException (Status)); + return Status; + } + + /* + * Load namespace from names created within control methods + * Set owner id of nodes in external table + */ + AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, + AcpiGbl_RootNode, OwnerId); + AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); + } + + /* Next external file */ + + ExternalFileList = ExternalFileList->Next; + } + + /* Clear external list generated by Scope in external tables */ + + if (AcpiGbl_ExternalFileList) + { + AcpiDmClearExternalList (); + } + } + else + { + Status = AdGetLocalTables (Filename, GetAllTables); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not get ACPI tables, %s\n", + AcpiFormatException (Status)); + return Status; + } + + if (!AcpiGbl_DbOpt_disasm) + { + return AE_OK; + } + + /* Obtained the local tables, just disassemble the DSDT */ + + Status = AcpiGetTable (ACPI_SIG_DSDT, 0, &Table); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not get DSDT, %s\n", + AcpiFormatException (Status)); + return Status; + } + + AcpiOsPrintf ("\nDisassembly of DSDT\n"); + Prefix = AdGenerateFilename ("dsdt", Table->OemTableId); + } + + /* + * Output: ASL code. Redirect to a file if requested + */ + if (OutToFile) + { + /* Create/Open a disassembly output file */ + + DisasmFilename = FlGenerateFilename (Prefix, FILE_SUFFIX_DISASSEMBLY); + if (!OutFilename) + { + fprintf (stderr, "Could not generate output filename\n"); + Status = AE_ERROR; + goto Cleanup; + } + + File = fopen (DisasmFilename, "w+"); + if (!File) + { + fprintf (stderr, "Could not open output file %s\n", DisasmFilename); + Status = AE_ERROR; + goto Cleanup; + } + + AcpiOsRedirectOutput (File); + } + + *OutFilename = DisasmFilename; + + if (!AcpiUtIsAmlTable (Table)) + { + AdDisassemblerHeader (Filename); + AcpiOsPrintf (" * ACPI Data Table [%4.4s]\n *\n", + Table->Signature); + AcpiOsPrintf (" * Format: [HexOffset DecimalOffset ByteLength] " + "FieldName : FieldValue\n */\n\n"); + + AcpiDmDumpDataTable (Table); + fprintf (stderr, "Acpi Data Table [%4.4s] decoded, written to \"%s\"\n", + Table->Signature, DisasmFilename); + } + else + { + /* Always parse the tables, only option is what to display */ + + Status = AdParseTable (Table, &OwnerId, TRUE, FALSE); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not parse ACPI tables, %s\n", + AcpiFormatException (Status)); + goto Cleanup; + } + + if (AslCompilerdebug) + { + AcpiOsPrintf ("/**** Before second load\n"); + + LsSetupNsList (File); + LsDisplayNamespace (); + AcpiOsPrintf ("*****/\n"); + } + + /* Load namespace from names created within control methods */ + + AcpiDmFinishNamespaceLoad (AcpiGbl_ParseOpRoot, + AcpiGbl_RootNode, OwnerId); + + /* + * Cross reference the namespace here, in order to + * generate External() statements + */ + AcpiDmCrossReferenceNamespace (AcpiGbl_ParseOpRoot, + AcpiGbl_RootNode, OwnerId); + + if (AslCompilerdebug) + { + AcpiDmDumpTree (AcpiGbl_ParseOpRoot); + } + + /* Find possible calls to external control methods */ + + AcpiDmFindOrphanMethods (AcpiGbl_ParseOpRoot); + + /* + * If we found any external control methods, we must reparse + * the entire tree with the new information (namely, the + * number of arguments per method) + */ + if (AcpiDmGetExternalMethodCount ()) + { + fprintf (stderr, + "\nFound %u external control methods, " + "reparsing with new information\n", + AcpiDmGetExternalMethodCount ()); + + /* Reparse, rebuild namespace. no need to xref namespace */ + + AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); + AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); + + AcpiGbl_RootNode = NULL; + AcpiGbl_RootNodeStruct.Name.Integer = ACPI_ROOT_NAME; + AcpiGbl_RootNodeStruct.DescriptorType = ACPI_DESC_TYPE_NAMED; + AcpiGbl_RootNodeStruct.Type = ACPI_TYPE_DEVICE; + AcpiGbl_RootNodeStruct.Parent = NULL; + AcpiGbl_RootNodeStruct.Child = NULL; + AcpiGbl_RootNodeStruct.Peer = NULL; + AcpiGbl_RootNodeStruct.Object = NULL; + AcpiGbl_RootNodeStruct.Flags = 0; + + Status = AcpiNsRootInitialize (); + AcpiDmAddExternalsToNamespace (); + + /* Parse the table again. No need to reload it, however */ + + Status = AdParseTable (Table, NULL, FALSE, FALSE); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not parse ACPI tables, %s\n", + AcpiFormatException (Status)); + goto Cleanup; + } + + if (AslCompilerdebug) + { + AcpiOsPrintf ("/**** After second load and resource conversion\n"); + LsSetupNsList (File); + LsDisplayNamespace (); + AcpiOsPrintf ("*****/\n"); + + AcpiDmDumpTree (AcpiGbl_ParseOpRoot); + } + } + + /* + * Now that the namespace is finalized, we can perform namespace + * transforms. + * + * 1) Convert fixed-offset references to resource descriptors + * to symbolic references (Note: modifies namespace) + */ + AcpiDmConvertResourceIndexes (AcpiGbl_ParseOpRoot, AcpiGbl_RootNode); + + /* Optional displays */ + + if (AcpiGbl_DbOpt_disasm) + { + AdDisplayTables (Filename, Table); + fprintf (stderr, + "Disassembly completed, written to \"%s\"\n", + DisasmFilename); + } + } + +Cleanup: + + if (Table && !AcpiUtIsAmlTable (Table)) + { + ACPI_FREE (Table); + } + + if (DisasmFilename) + { + ACPI_FREE (DisasmFilename); + } + + if (OutToFile && File) + { + if (AslCompilerdebug) /* Display final namespace, with transforms */ + { + LsSetupNsList (File); + LsDisplayNamespace (); + } + + fclose (File); + AcpiOsRedirectOutput (stdout); + } + + AcpiPsDeleteParseTree (AcpiGbl_ParseOpRoot); + AcpiGbl_ParseOpRoot = NULL; + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AdDisassemblerHeader + * + * PARAMETERS: Filename - Input file for the table + * + * RETURN: None + * + * DESCRIPTION: Create the disassembler header, including ACPI CA signon with + * current time and date. + * + *****************************************************************************/ + +void +AdDisassemblerHeader ( + char *Filename) +{ + time_t Timer; + + time (&Timer); + + /* Header and input table info */ + + AcpiOsPrintf ("/*\n"); + AcpiOsPrintf (ACPI_COMMON_HEADER ("AML Disassembler", " * ")); + + AcpiOsPrintf (" * Disassembly of %s, %s", Filename, ctime (&Timer)); + AcpiOsPrintf (" *\n"); +} + + +/****************************************************************************** + * + * FUNCTION: AdCreateTableHeader + * + * PARAMETERS: Filename - Input file for the table + * Table - Pointer to the raw table + * + * RETURN: None + * + * DESCRIPTION: Create the ASL table header, including ACPI CA signon with + * current time and date. + * + *****************************************************************************/ + +static void +AdCreateTableHeader ( + char *Filename, + ACPI_TABLE_HEADER *Table) +{ + char *NewFilename; + UINT8 Checksum; + + + /* + * Print file header and dump original table header + */ + AdDisassemblerHeader (Filename); + + AcpiOsPrintf (" * Original Table Header:\n"); + AcpiOsPrintf (" * Signature \"%4.4s\"\n", Table->Signature); + AcpiOsPrintf (" * Length 0x%8.8X (%u)\n", Table->Length, Table->Length); + + /* Print and validate the revision */ + + AcpiOsPrintf (" * Revision 0x%2.2X", Table->Revision); + + switch (Table->Revision) + { + case 0: + AcpiOsPrintf (" **** Invalid Revision"); + break; + + case 1: + /* Revision of DSDT controls the ACPI integer width */ + + if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT)) + { + AcpiOsPrintf (" **** 32-bit table (V1), no 64-bit math support"); + } + break; + + default: + break; + } + AcpiOsPrintf ("\n"); + + /* Print and validate the table checksum */ + + AcpiOsPrintf (" * Checksum 0x%2.2X", Table->Checksum); + + Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Table->Length); + if (Checksum) + { + AcpiOsPrintf (" **** Incorrect checksum, should be 0x%2.2X", + (UINT8) (Table->Checksum - Checksum)); + } + AcpiOsPrintf ("\n"); + + AcpiOsPrintf (" * OEM ID \"%.6s\"\n", Table->OemId); + AcpiOsPrintf (" * OEM Table ID \"%.8s\"\n", Table->OemTableId); + AcpiOsPrintf (" * OEM Revision 0x%8.8X (%u)\n", Table->OemRevision, Table->OemRevision); + AcpiOsPrintf (" * Compiler ID \"%.4s\"\n", Table->AslCompilerId); + AcpiOsPrintf (" * Compiler Version 0x%8.8X (%u)\n", Table->AslCompilerRevision, Table->AslCompilerRevision); + AcpiOsPrintf (" */\n\n"); + + /* Create AML output filename based on input filename */ + + if (Filename) + { + NewFilename = FlGenerateFilename (Filename, "aml"); + } + else + { + NewFilename = ACPI_ALLOCATE_ZEROED (9); + strncat (NewFilename, Table->Signature, 4); + strcat (NewFilename, ".aml"); + } + + /* Open the ASL definition block */ + + AcpiOsPrintf ( + "DefinitionBlock (\"%s\", \"%4.4s\", %hu, \"%.6s\", \"%.8s\", 0x%8.8X)\n", + NewFilename, Table->Signature, Table->Revision, + Table->OemId, Table->OemTableId, Table->OemRevision); + + ACPI_FREE (NewFilename); +} + + +/****************************************************************************** + * + * FUNCTION: AdDisplayTables + * + * PARAMETERS: Filename - Input file for the table + * Table - Pointer to the raw table + * + * RETURN: Status + * + * DESCRIPTION: Display (disassemble) loaded tables and dump raw tables + * + *****************************************************************************/ + +ACPI_STATUS +AdDisplayTables ( + char *Filename, + ACPI_TABLE_HEADER *Table) +{ + + + if (!AcpiGbl_ParseOpRoot) + { + return AE_NOT_EXIST; + } + + if (!AcpiGbl_DbOpt_verbose) + { + AdCreateTableHeader (Filename, Table); + } + + AcpiDmDisassemble (NULL, AcpiGbl_ParseOpRoot, ACPI_UINT32_MAX); + + if (AcpiGbl_DbOpt_verbose) + { + AcpiOsPrintf ("\n\nTable Header:\n"); + AcpiUtDumpBuffer ((UINT8 *) Table, sizeof (ACPI_TABLE_HEADER), + DB_BYTE_DISPLAY, ACPI_UINT32_MAX); + + AcpiOsPrintf ("Table Body (Length 0x%X)\n", Table->Length); + AcpiUtDumpBuffer (((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)), Table->Length, + DB_BYTE_DISPLAY, ACPI_UINT32_MAX); + } + + return AE_OK; +} + + +/****************************************************************************** + * + * FUNCTION: AdDeferredParse + * + * PARAMETERS: Op - Root Op of the deferred opcode + * Aml - Pointer to the raw AML + * AmlLength - Length of the AML + * + * RETURN: Status + * + * DESCRIPTION: Parse one deferred opcode + * (Methods, operation regions, etc.) + * + *****************************************************************************/ + +static ACPI_STATUS +AdDeferredParse ( + ACPI_PARSE_OBJECT *Op, + UINT8 *Aml, + UINT32 AmlLength) +{ + ACPI_WALK_STATE *WalkState; + ACPI_STATUS Status; + ACPI_PARSE_OBJECT *SearchOp; + ACPI_PARSE_OBJECT *StartOp; + UINT32 BaseAmlOffset; + ACPI_PARSE_OBJECT *ExtraOp; + + + ACPI_FUNCTION_TRACE (AdDeferredParse); + + + fprintf (stderr, "."); + + if (!Aml || !AmlLength) + { + return_ACPI_STATUS (AE_OK); + } + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing %s [%4.4s]\n", + Op->Common.AmlOpName, (char *) &Op->Named.Name)); + + WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); + if (!WalkState) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml, + AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + /* Parse the method */ + + WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; + WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; + Status = AcpiPsParseAml (WalkState); + + /* + * We need to update all of the Aml offsets, since the parser thought + * that the method began at offset zero. In reality, it began somewhere + * within the ACPI table, at the BaseAmlOffset. Walk the entire tree that + * was just created and update the AmlOffset in each Op + */ + BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1; + StartOp = (Op->Common.Value.Arg)->Common.Next; + SearchOp = StartOp; + + /* Walk the parse tree */ + + while (SearchOp) + { + SearchOp->Common.AmlOffset += BaseAmlOffset; + SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); + } + + /* + * Link the newly parsed subtree into the main parse tree + */ + switch (Op->Common.AmlOpcode) + { + case AML_BUFFER_OP: + case AML_PACKAGE_OP: + case AML_VAR_PACKAGE_OP: + + switch (Op->Common.AmlOpcode) + { + case AML_PACKAGE_OP: + ExtraOp = Op->Common.Value.Arg; + ExtraOp = ExtraOp->Common.Next; + Op->Common.Value.Arg = ExtraOp->Common.Value.Arg; + break; + + case AML_VAR_PACKAGE_OP: + case AML_BUFFER_OP: + default: + ExtraOp = Op->Common.Value.Arg; + Op->Common.Value.Arg = ExtraOp->Common.Value.Arg; + break; + } + + /* Must point all parents to the main tree */ + + StartOp = Op; + SearchOp = StartOp; + while (SearchOp) + { + if (SearchOp->Common.Parent == ExtraOp) + { + SearchOp->Common.Parent = Op; + } + SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); + } + break; + + default: + break; + } + + return_ACPI_STATUS (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AdParseDeferredOps + * + * PARAMETERS: Root - Root of the parse tree + * + * RETURN: Status + * + * DESCRIPTION: Parse the deferred opcodes (Methods, regions, etc.) + * + *****************************************************************************/ + +static ACPI_STATUS +AdParseDeferredOps ( + ACPI_PARSE_OBJECT *Root) +{ + ACPI_PARSE_OBJECT *Op = Root; + ACPI_STATUS Status = AE_OK; + const ACPI_OPCODE_INFO *OpInfo; + + + ACPI_FUNCTION_NAME (AdParseDeferredOps); + fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); + + while (Op) + { + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + if (!(OpInfo->Flags & AML_DEFER)) + { + Op = AcpiPsGetDepthNext (Root, Op); + continue; + } + + switch (Op->Common.AmlOpcode) + { + case AML_METHOD_OP: + case AML_BUFFER_OP: + case AML_PACKAGE_OP: + case AML_VAR_PACKAGE_OP: + + Status = AdDeferredParse (Op, Op->Named.Data, Op->Named.Length); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + break; + + case AML_REGION_OP: + case AML_DATA_REGION_OP: + case AML_CREATE_QWORD_FIELD_OP: + case AML_CREATE_DWORD_FIELD_OP: + case AML_CREATE_WORD_FIELD_OP: + case AML_CREATE_BYTE_FIELD_OP: + case AML_CREATE_BIT_FIELD_OP: + case AML_CREATE_FIELD_OP: + case AML_BANK_FIELD_OP: + + /* Nothing to do in these cases */ + + break; + + default: + ACPI_ERROR ((AE_INFO, "Unhandled deferred opcode [%s]", + Op->Common.AmlOpName)); + break; + } + + Op = AcpiPsGetDepthNext (Root, Op); + } + + fprintf (stderr, "\n"); + return Status; +} + + +/****************************************************************************** + * + * FUNCTION: AdGetLocalTables + * + * PARAMETERS: Filename - Not used + * GetAllTables - TRUE if all tables are desired + * + * RETURN: Status + * + * DESCRIPTION: Get the ACPI tables from either memory or a file + * + *****************************************************************************/ + +ACPI_STATUS +AdGetLocalTables ( + char *Filename, + BOOLEAN GetAllTables) +{ + ACPI_STATUS Status; + ACPI_TABLE_HEADER TableHeader; + ACPI_TABLE_HEADER *NewTable; + UINT32 NumTables; + UINT32 PointerSize; + UINT32 TableIndex; + + + if (GetAllTables) + { + ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_RSDT); + AcpiOsTableOverride (&TableHeader, &NewTable); + if (!NewTable) + { + fprintf (stderr, "Could not obtain RSDT\n"); + return AE_NO_ACPI_TABLES; + } + else + { + AdWriteTable (NewTable, NewTable->Length, + ACPI_SIG_RSDT, NewTable->OemTableId); + } + + if (ACPI_COMPARE_NAME (NewTable->Signature, ACPI_SIG_RSDT)) + { + PointerSize = sizeof (UINT32); + } + else + { + PointerSize = sizeof (UINT64); + } + + /* + * Determine the number of tables pointed to by the RSDT/XSDT. + * This is defined by the ACPI Specification to be the number of + * pointers contained within the RSDT/XSDT. The size of the pointers + * is architecture-dependent. + */ + NumTables = (NewTable->Length - sizeof (ACPI_TABLE_HEADER)) / PointerSize; + AcpiOsPrintf ("There are %u tables defined in the %4.4s\n\n", + NumTables, NewTable->Signature); + + /* Get the FADT */ + + ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_FADT); + AcpiOsTableOverride (&TableHeader, &NewTable); + if (NewTable) + { + AdWriteTable (NewTable, NewTable->Length, + ACPI_SIG_FADT, NewTable->OemTableId); + } + AcpiOsPrintf ("\n"); + + /* Don't bother with FACS, it is usually all zeros */ + } + + /* Always get the DSDT */ + + ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_DSDT); + AcpiOsTableOverride (&TableHeader, &NewTable); + if (NewTable) + { + AdWriteTable (NewTable, NewTable->Length, + ACPI_SIG_DSDT, NewTable->OemTableId); + + /* Store DSDT in the Table Manager */ + + Status = AcpiTbStoreTable (0, NewTable, NewTable->Length, + 0, &TableIndex); + if (ACPI_FAILURE (Status)) + { + fprintf (stderr, "Could not store DSDT\n"); + return AE_NO_ACPI_TABLES; + } + } + else + { + fprintf (stderr, "Could not obtain DSDT\n"); + return AE_NO_ACPI_TABLES; + } + +#if 0 + /* TBD: Future implementation */ + + AcpiOsPrintf ("\n"); + + /* Get all SSDTs */ + + ACPI_MOVE_32_TO_32 (TableHeader.Signature, ACPI_SIG_SSDT); + do + { + NewTable = NULL; + Status = AcpiOsTableOverride (&TableHeader, &NewTable); + + } while (NewTable); +#endif + + return AE_OK; +} + + +/****************************************************************************** + * + * FUNCTION: AdParseTable + * + * PARAMETERS: Table - Pointer to the raw table + * OwnerId - Returned OwnerId of the table + * LoadTable - If add table to the global table list + * External - If this is an external table + * + * RETURN: Status + * + * DESCRIPTION: Parse the DSDT. + * + *****************************************************************************/ + +ACPI_STATUS +AdParseTable ( + ACPI_TABLE_HEADER *Table, + ACPI_OWNER_ID *OwnerId, + BOOLEAN LoadTable, + BOOLEAN External) +{ + ACPI_STATUS Status = AE_OK; + ACPI_WALK_STATE *WalkState; + UINT8 *AmlStart; + UINT32 AmlLength; + UINT32 TableIndex; + + + if (!Table) + { + return AE_NOT_EXIST; + } + + /* Pass 1: Parse everything except control method bodies */ + + fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); + + AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); + AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); + + /* Create the root object */ + + AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (); + if (!AcpiGbl_ParseOpRoot) + { + return AE_NO_MEMORY; + } + + /* Create and initialize a new walk state */ + + WalkState = AcpiDsCreateWalkState (0, + AcpiGbl_ParseOpRoot, NULL, NULL); + if (!WalkState) + { + return (AE_NO_MEMORY); + } + + Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, + NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; + WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; + + Status = AcpiPsParseAml (WalkState); + if (ACPI_FAILURE (Status)) + { + return Status; + } + + /* If LoadTable is FALSE, we are parsing the last loaded table */ + + TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; + + /* Pass 2 */ + + if (LoadTable) + { + Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table, + Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex); + if (ACPI_FAILURE (Status)) + { + return Status; + } + Status = AcpiTbAllocateOwnerId (TableIndex); + if (ACPI_FAILURE (Status)) + { + return Status; + } + if (OwnerId) + { + Status = AcpiTbGetOwnerId (TableIndex, OwnerId); + if (ACPI_FAILURE (Status)) + { + return Status; + } + } + } + + fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); + + Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* No need to parse control methods of external table */ + + if (External) + { + return AE_OK; + } + + /* Pass 3: Parse control methods and link their parse trees into the main parse tree */ + + Status = AdParseDeferredOps (AcpiGbl_ParseOpRoot); + + /* Process Resource Templates */ + + AcpiDmFindResources (AcpiGbl_ParseOpRoot); + + fprintf (stderr, "Parsing completed\n"); + return AE_OK; +} + + diff --git a/source/common/adwalk.c b/source/common/adwalk.c new file mode 100644 index 0000000000000..efda35a8be23c --- /dev/null +++ b/source/common/adwalk.c @@ -0,0 +1,1004 @@ +/****************************************************************************** + * + * Module Name: adwalk - Application-level disassembler parse tree walk routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include "acpi.h" +#include "accommon.h" +#include "acparser.h" +#include "amlcode.h" +#include "acdisasm.h" +#include "acdispat.h" +#include "acnamesp.h" +#include "acapps.h" + + +#define _COMPONENT ACPI_TOOLS + ACPI_MODULE_NAME ("adwalk") + +/* + * aslmap - opcode mappings and reserved method names + */ +ACPI_OBJECT_TYPE +AslMapNamedOpcodeToDataType ( + UINT16 Opcode); + +/* Local prototypes */ + +static ACPI_STATUS +AcpiDmFindOrphanDescending ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context); + +static ACPI_STATUS +AcpiDmDumpDescending ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context); + +static ACPI_STATUS +AcpiDmXrefDescendingOp ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context); + +static ACPI_STATUS +AcpiDmCommonAscendingOp ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context); + +static ACPI_STATUS +AcpiDmLoadDescendingOp ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context); + +static UINT32 +AcpiDmInspectPossibleArgs ( + UINT32 CurrentOpArgCount, + UINT32 TargetCount, + ACPI_PARSE_OBJECT *Op); + +static ACPI_STATUS +AcpiDmResourceDescendingOp ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context); + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpTree + * + * PARAMETERS: Origin - Starting object + * + * RETURN: None + * + * DESCRIPTION: Parse tree walk to format and output the nodes + * + ******************************************************************************/ + +void +AcpiDmDumpTree ( + ACPI_PARSE_OBJECT *Origin) +{ + ACPI_OP_WALK_INFO Info; + + + if (!Origin) + { + return; + } + + AcpiOsPrintf ("/*\nAML Parse Tree\n\n"); + Info.Flags = 0; + Info.Count = 0; + Info.Level = 0; + Info.WalkState = NULL; + AcpiDmWalkParseTree (Origin, AcpiDmDumpDescending, NULL, &Info); + AcpiOsPrintf ("*/\n\n"); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmFindOrphanMethods + * + * PARAMETERS: Origin - Starting object + * + * RETURN: None + * + * DESCRIPTION: Parse tree walk to find "orphaned" method invocations -- methods + * that are not resolved in the namespace + * + ******************************************************************************/ + +void +AcpiDmFindOrphanMethods ( + ACPI_PARSE_OBJECT *Origin) +{ + ACPI_OP_WALK_INFO Info; + + + if (!Origin) + { + return; + } + + Info.Flags = 0; + Info.Level = 0; + Info.WalkState = NULL; + AcpiDmWalkParseTree (Origin, AcpiDmFindOrphanDescending, NULL, &Info); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmFinishNamespaceLoad + * + * PARAMETERS: ParseTreeRoot - Root of the parse tree + * NamespaceRoot - Root of the internal namespace + * OwnerId - OwnerId of the table to be disassembled + * + * RETURN: None + * + * DESCRIPTION: Load all namespace items that are created within control + * methods. Used before namespace cross reference + * + ******************************************************************************/ + +void +AcpiDmFinishNamespaceLoad ( + ACPI_PARSE_OBJECT *ParseTreeRoot, + ACPI_NAMESPACE_NODE *NamespaceRoot, + ACPI_OWNER_ID OwnerId) +{ + ACPI_STATUS Status; + ACPI_OP_WALK_INFO Info; + ACPI_WALK_STATE *WalkState; + + + if (!ParseTreeRoot) + { + return; + } + + /* Create and initialize a new walk state */ + + WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL); + if (!WalkState) + { + return; + } + + Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); + if (ACPI_FAILURE (Status)) + { + return; + } + + Info.Flags = 0; + Info.Level = 0; + Info.WalkState = WalkState; + AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmLoadDescendingOp, + AcpiDmCommonAscendingOp, &Info); + ACPI_FREE (WalkState); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmCrossReferenceNamespace + * + * PARAMETERS: ParseTreeRoot - Root of the parse tree + * NamespaceRoot - Root of the internal namespace + * OwnerId - OwnerId of the table to be disassembled + * + * RETURN: None + * + * DESCRIPTION: Cross reference the namespace to create externals + * + ******************************************************************************/ + +void +AcpiDmCrossReferenceNamespace ( + ACPI_PARSE_OBJECT *ParseTreeRoot, + ACPI_NAMESPACE_NODE *NamespaceRoot, + ACPI_OWNER_ID OwnerId) +{ + ACPI_STATUS Status; + ACPI_OP_WALK_INFO Info; + ACPI_WALK_STATE *WalkState; + + + if (!ParseTreeRoot) + { + return; + } + + /* Create and initialize a new walk state */ + + WalkState = AcpiDsCreateWalkState (OwnerId, ParseTreeRoot, NULL, NULL); + if (!WalkState) + { + return; + } + + Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); + if (ACPI_FAILURE (Status)) + { + return; + } + + Info.Flags = 0; + Info.Level = 0; + Info.WalkState = WalkState; + AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmXrefDescendingOp, + AcpiDmCommonAscendingOp, &Info); + ACPI_FREE (WalkState); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmConvertResourceIndexes + * + * PARAMETERS: ParseTreeRoot - Root of the parse tree + * NamespaceRoot - Root of the internal namespace + * + * RETURN: None + * + * DESCRIPTION: Convert fixed-offset references to resource descriptors to + * symbolic references. Should only be called after namespace has + * been cross referenced. + * + ******************************************************************************/ + +void +AcpiDmConvertResourceIndexes ( + ACPI_PARSE_OBJECT *ParseTreeRoot, + ACPI_NAMESPACE_NODE *NamespaceRoot) +{ + ACPI_STATUS Status; + ACPI_OP_WALK_INFO Info; + ACPI_WALK_STATE *WalkState; + + + if (!ParseTreeRoot) + { + return; + } + + /* Create and initialize a new walk state */ + + WalkState = AcpiDsCreateWalkState (0, ParseTreeRoot, NULL, NULL); + if (!WalkState) + { + return; + } + + Status = AcpiDsScopeStackPush (NamespaceRoot, NamespaceRoot->Type, WalkState); + if (ACPI_FAILURE (Status)) + { + return; + } + + Info.Flags = 0; + Info.Level = 0; + Info.WalkState = WalkState; + AcpiDmWalkParseTree (ParseTreeRoot, AcpiDmResourceDescendingOp, + AcpiDmCommonAscendingOp, &Info); + ACPI_FREE (WalkState); + return; +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpDescending + * + * PARAMETERS: ASL_WALK_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Format and print contents of one parse Op. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDmDumpDescending ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context) +{ + ACPI_OP_WALK_INFO *Info = Context; + char *Path; + + + if (!Op) + { + return (AE_OK); + } + + /* Most of the information (count, level, name) here */ + + Info->Count++; + AcpiOsPrintf ("% 5d [%2.2d] ", Info->Count, Level); + AcpiDmIndent (Level); + AcpiOsPrintf ("%-28s", AcpiPsGetOpcodeName (Op->Common.AmlOpcode)); + + /* Extra info is helpful */ + + switch (Op->Common.AmlOpcode) + { + case AML_BYTE_OP: + case AML_WORD_OP: + case AML_DWORD_OP: + AcpiOsPrintf ("%X", (UINT32) Op->Common.Value.Integer); + break; + + case AML_QWORD_OP: + AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); + break; + + case AML_INT_NAMEPATH_OP: + if (Op->Common.Value.String) + { + AcpiNsExternalizeName (ACPI_UINT32_MAX, Op->Common.Value.String, + NULL, &Path); + AcpiOsPrintf ("%s %p", Path, Op->Common.Node); + ACPI_FREE (Path); + } + else + { + AcpiOsPrintf ("[NULL]"); + } + break; + + case AML_NAME_OP: + case AML_METHOD_OP: + case AML_DEVICE_OP: + case AML_INT_NAMEDFIELD_OP: + AcpiOsPrintf ("%4.4s", ACPI_CAST_PTR (char, &Op->Named.Name)); + break; + + default: + break; + } + + AcpiOsPrintf ("\n"); + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmFindOrphanDescending + * + * PARAMETERS: ASL_WALK_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Check namepath Ops for orphaned method invocations + * + * Note: Experimental. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDmFindOrphanDescending ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context) +{ + const ACPI_OPCODE_INFO *OpInfo; + ACPI_PARSE_OBJECT *ChildOp; + ACPI_PARSE_OBJECT *NextOp; + ACPI_PARSE_OBJECT *ParentOp; + UINT32 ArgCount; + + + if (!Op) + { + return (AE_OK); + } + + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + + switch (Op->Common.AmlOpcode) + { +#ifdef ACPI_UNDER_DEVELOPMENT + case AML_ADD_OP: + ChildOp = Op->Common.Value.Arg; + if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && + !ChildOp->Common.Node) + { + AcpiNsExternalizeName (ACPI_UINT32_MAX, ChildOp->Common.Value.String, + NULL, &Path); + AcpiOsPrintf ("/* %-16s A-NAMEPATH: %s */\n", Op->Common.AmlOpName, Path); + ACPI_FREE (Path); + + NextOp = Op->Common.Next; + if (!NextOp) + { + /* This NamePath has no args, assume it is an integer */ + + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); + return (AE_OK); + } + + ArgCount = AcpiDmInspectPossibleArgs (3, 1, NextOp); + AcpiOsPrintf ("/* A-CHILDREN: %u Actual %u */\n", ArgCount, AcpiDmCountChildren (Op)); + + if (ArgCount < 1) + { + /* One Arg means this is just a Store(Name,Target) */ + + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); + return (AE_OK); + } + + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); + } + break; +#endif + + case AML_STORE_OP: + + ChildOp = Op->Common.Value.Arg; + if ((ChildOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) && + !ChildOp->Common.Node) + { + NextOp = Op->Common.Next; + if (!NextOp) + { + /* This NamePath has no args, assume it is an integer */ + + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); + return (AE_OK); + } + + ArgCount = AcpiDmInspectPossibleArgs (2, 1, NextOp); + if (ArgCount <= 1) + { + /* One Arg means this is just a Store(Name,Target) */ + + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_INTEGER, 0); + return (AE_OK); + } + + AcpiDmAddToExternalList (ChildOp, ChildOp->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); + } + break; + + case AML_INT_NAMEPATH_OP: + + /* Must examine parent to see if this namepath is an argument */ + + ParentOp = Op->Common.Parent; + OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode); + + if ((OpInfo->Class != AML_CLASS_EXECUTE) && + (OpInfo->Class != AML_CLASS_CREATE) && + (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) && + !Op->Common.Node) + { + ArgCount = AcpiDmInspectPossibleArgs (0, 0, Op->Common.Next); + + /* + * Check if namepath is a predicate for if/while or lone parameter to + * a return. + */ + if (ArgCount == 0) + { + if (((ParentOp->Common.AmlOpcode == AML_IF_OP) || + (ParentOp->Common.AmlOpcode == AML_WHILE_OP) || + (ParentOp->Common.AmlOpcode == AML_RETURN_OP)) && + + /* And namepath is the first argument */ + (ParentOp->Common.Value.Arg == Op)) + { + AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_INTEGER, 0); + break; + } + } + + /* + * This is a standalone namestring (not a parameter to another + * operator) - it *must* be a method invocation, nothing else is + * grammatically possible. + */ + AcpiDmAddToExternalList (Op, Op->Common.Value.String, ACPI_TYPE_METHOD, ArgCount); + + } + break; + + default: + break; + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmLoadDescendingOp + * + * PARAMETERS: ASL_WALK_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Descending handler for namespace control method object load + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDmLoadDescendingOp ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context) +{ + ACPI_OP_WALK_INFO *Info = Context; + const ACPI_OPCODE_INFO *OpInfo; + ACPI_WALK_STATE *WalkState; + ACPI_OBJECT_TYPE ObjectType; + ACPI_STATUS Status; + char *Path = NULL; + ACPI_PARSE_OBJECT *NextOp; + ACPI_NAMESPACE_NODE *Node; + char FieldPath[5]; + BOOLEAN PreDefined = FALSE; + UINT8 PreDefineIndex = 0; + + + WalkState = Info->WalkState; + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + ObjectType = OpInfo->ObjectType; + ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); + + /* Only interested in operators that create new names */ + + if (!(OpInfo->Flags & AML_NAMED) && + !(OpInfo->Flags & AML_CREATE)) + { + goto Exit; + } + + /* Get the NamePath from the appropriate place */ + + if (OpInfo->Flags & AML_NAMED) + { + /* For all named operators, get the new name */ + + Path = (char *) Op->Named.Path; + + if (!Path && Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP) + { + *ACPI_CAST_PTR (UINT32, &FieldPath[0]) = Op->Named.Name; + FieldPath[4] = 0; + Path = FieldPath; + } + } + else if (OpInfo->Flags & AML_CREATE) + { + /* New name is the last child */ + + NextOp = Op->Common.Value.Arg; + + while (NextOp->Common.Next) + { + NextOp = NextOp->Common.Next; + } + Path = NextOp->Common.Value.String; + } + + if (!Path) + { + goto Exit; + } + + /* Insert the name into the namespace */ + + Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, + ACPI_IMODE_LOAD_PASS2, ACPI_NS_DONT_OPEN_SCOPE, + WalkState, &Node); + + Op->Common.Node = Node; + + if (ACPI_SUCCESS (Status)) + { + /* Check if it's a predefined node */ + + while (AcpiGbl_PreDefinedNames[PreDefineIndex].Name) + { + if (!ACPI_STRNCMP (Node->Name.Ascii, + AcpiGbl_PreDefinedNames[PreDefineIndex].Name, 4)) + { + PreDefined = TRUE; + break; + } + + PreDefineIndex++; + } + + /* + * Set node owner id if it satisfies all the following conditions: + * 1) Not a predefined node, _SB_ etc + * 2) Not the root node + * 3) Not a node created by Scope + */ + + if (!PreDefined && Node != AcpiGbl_RootNode && + Op->Common.AmlOpcode != AML_SCOPE_OP) + { + Node->OwnerId = WalkState->OwnerId; + } + } + + +Exit: + + if (AcpiNsOpensScope (ObjectType)) + { + if (Op->Common.Node) + { + Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmXrefDescendingOp + * + * PARAMETERS: ASL_WALK_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Descending handler for namespace cross reference + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDmXrefDescendingOp ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context) +{ + ACPI_OP_WALK_INFO *Info = Context; + const ACPI_OPCODE_INFO *OpInfo; + ACPI_WALK_STATE *WalkState; + ACPI_OBJECT_TYPE ObjectType; + ACPI_OBJECT_TYPE ObjectType2; + ACPI_STATUS Status; + char *Path = NULL; + ACPI_PARSE_OBJECT *NextOp; + ACPI_NAMESPACE_NODE *Node; + ACPI_OPERAND_OBJECT *Object; + UINT32 ParamCount = 0; + + + WalkState = Info->WalkState; + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + ObjectType = OpInfo->ObjectType; + ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); + + if ((!(OpInfo->Flags & AML_NAMED)) && + (!(OpInfo->Flags & AML_CREATE)) && + (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP)) + { + goto Exit; + } + + /* Get the NamePath from the appropriate place */ + + if (OpInfo->Flags & AML_NAMED) + { + if ((Op->Common.AmlOpcode == AML_ALIAS_OP) || + (Op->Common.AmlOpcode == AML_SCOPE_OP)) + { + /* + * Only these two operators refer to an existing name, + * first argument + */ + Path = (char *) Op->Named.Path; + } + } + else if (OpInfo->Flags & AML_CREATE) + { + /* Referenced Buffer Name is the first child */ + + NextOp = Op->Common.Value.Arg; + if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP) + { + Path = NextOp->Common.Value.String; + } + } + else + { + Path = Op->Common.Value.String; + } + + if (!Path) + { + goto Exit; + } + + /* + * Lookup the name in the namespace. Name must exist at this point, or it + * is an invalid reference. + * + * The namespace is also used as a lookup table for references to resource + * descriptors and the fields within them. + */ + Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, + ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, + WalkState, &Node); + if (ACPI_FAILURE (Status)) + { + if (Status == AE_NOT_FOUND) + { + AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType, 0); + + /* + * We could install this into the namespace, but we catch duplicate + * externals when they are added to the list. + */ +#if 0 + Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, + ACPI_IMODE_LOAD_PASS1, ACPI_NS_DONT_OPEN_SCOPE, + WalkState, &Node); +#endif + } + } + + /* + * Found the node in external table, add it to external list + * Node->OwnerId == 0 indicates built-in ACPI Names, _OS_ etc + */ + else if (Node->OwnerId && WalkState->OwnerId != Node->OwnerId) + { + ObjectType2 = ObjectType; + + Object = AcpiNsGetAttachedObject (Node); + if (Object) + { + ObjectType2 = Object->Common.Type; + if (ObjectType2 == ACPI_TYPE_METHOD) + { + ParamCount = Object->Method.ParamCount; + } + } + + AcpiDmAddToExternalList (Op, Path, (UINT8) ObjectType2, ParamCount); + Op->Common.Node = Node; + } + else + { + Op->Common.Node = Node; + } + + +Exit: + /* Open new scope if necessary */ + + if (AcpiNsOpensScope (ObjectType)) + { + if (Op->Common.Node) + { + Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmResourceDescendingOp + * + * PARAMETERS: ASL_WALK_CALLBACK + * + * RETURN: None + * + * DESCRIPTION: Process one parse op during symbolic resource index conversion. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDmResourceDescendingOp ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context) +{ + ACPI_OP_WALK_INFO *Info = Context; + const ACPI_OPCODE_INFO *OpInfo; + ACPI_WALK_STATE *WalkState; + ACPI_OBJECT_TYPE ObjectType; + ACPI_STATUS Status; + + + WalkState = Info->WalkState; + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + + /* Open new scope if necessary */ + + ObjectType = OpInfo->ObjectType; + if (AcpiNsOpensScope (ObjectType)) + { + if (Op->Common.Node) + { + + Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType, WalkState); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + } + + /* + * Check if this operator contains a reference to a resource descriptor. + * If so, convert the reference into a symbolic reference. + */ + AcpiDmCheckResourceReference (Op, WalkState); + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmCommonAscendingOp + * + * PARAMETERS: ASL_WALK_CALLBACK + * + * RETURN: None + * + * DESCRIPTION: Ascending handler for combined parse/namespace walks. Closes + * scope if necessary. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDmCommonAscendingOp ( + ACPI_PARSE_OBJECT *Op, + UINT32 Level, + void *Context) +{ + ACPI_OP_WALK_INFO *Info = Context; + const ACPI_OPCODE_INFO *OpInfo; + ACPI_OBJECT_TYPE ObjectType; + + + /* Close scope if necessary */ + + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + ObjectType = OpInfo->ObjectType; + ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); + + if (AcpiNsOpensScope (ObjectType)) + { + (void) AcpiDsScopeStackPop (Info->WalkState); + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmInspectPossibleArgs + * + * PARAMETERS: CurrentOpArgCount - Which arg of the current op was the + * possible method invocation found + * TargetCount - Number of targets (0,1,2) for this op + * Op - Parse op + * + * RETURN: Status + * + * DESCRIPTION: Examine following args and next ops for possible arguments + * for an unrecognized method invocation. + * + ******************************************************************************/ + +static UINT32 +AcpiDmInspectPossibleArgs ( + UINT32 CurrentOpArgCount, + UINT32 TargetCount, + ACPI_PARSE_OBJECT *Op) +{ + const ACPI_OPCODE_INFO *OpInfo; + UINT32 i; + UINT32 Last = 0; + UINT32 Lookahead; + + + Lookahead = (ACPI_METHOD_NUM_ARGS + TargetCount) - CurrentOpArgCount; + + /* Lookahead for the maximum number of possible arguments */ + + for (i = 0; i < Lookahead; i++) + { + if (!Op) + { + break; + } + + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + + /* + * Any one of these operators is "very probably" not a method arg + */ + if ((Op->Common.AmlOpcode == AML_STORE_OP) || + (Op->Common.AmlOpcode == AML_NOTIFY_OP)) + { + break; + } + + if ((OpInfo->Class != AML_CLASS_EXECUTE) && + (OpInfo->Class != AML_CLASS_CONTROL)) + { + Last = i+1; + } + + Op = Op->Common.Next; + } + + return (Last); +} + + diff --git a/source/common/dmextern.c b/source/common/dmextern.c new file mode 100644 index 0000000000000..37c34fc5dab18 --- /dev/null +++ b/source/common/dmextern.c @@ -0,0 +1,672 @@ +/****************************************************************************** + * + * Module Name: dmextern - Support for External() ASL statements + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" +#include "amlcode.h" +#include "acnamesp.h" +#include "acdisasm.h" + + +/* + * This module is used for application-level code (iASL disassembler) only. + * + * It contains the code to create and emit any necessary External() ASL + * statements for the module being disassembled. + */ +#define _COMPONENT ACPI_CA_DISASSEMBLER + ACPI_MODULE_NAME ("dmextern") + + +/* + * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL + * ObjectTypeKeyword. Used to generate typed external declarations + */ +static const char *AcpiGbl_DmTypeNames[] = +{ + /* 00 */ "", /* Type ANY */ + /* 01 */ ", IntObj", + /* 02 */ ", StrObj", + /* 03 */ ", BuffObj", + /* 04 */ ", PkgObj", + /* 05 */ ", FieldUnitObj", + /* 06 */ ", DeviceObj", + /* 07 */ ", EventObj", + /* 08 */ ", MethodObj", + /* 09 */ ", MutexObj", + /* 10 */ ", OpRegionObj", + /* 11 */ ", PowerResObj", + /* 12 */ ", ProcessorObj", + /* 13 */ ", ThermalZoneObj", + /* 14 */ ", BuffFieldObj", + /* 15 */ ", DDBHandleObj", + /* 16 */ "", /* Debug object */ + /* 17 */ ", FieldUnitObj", + /* 18 */ ", FieldUnitObj", + /* 19 */ ", FieldUnitObj" +}; + + +/* Local prototypes */ + +static const char * +AcpiDmGetObjectTypeName ( + ACPI_OBJECT_TYPE Type); + +static char * +AcpiDmNormalizeParentPrefix ( + ACPI_PARSE_OBJECT *Op, + char *Path); + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGetObjectTypeName + * + * PARAMETERS: Type - An ACPI_OBJECT_TYPE + * + * RETURN: Pointer to a string + * + * DESCRIPTION: Map an object type to the ASL object type string. + * + ******************************************************************************/ + +static const char * +AcpiDmGetObjectTypeName ( + ACPI_OBJECT_TYPE Type) +{ + + if (Type == ACPI_TYPE_LOCAL_SCOPE) + { + Type = ACPI_TYPE_DEVICE; + } + + else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) + { + return (""); + } + + return (AcpiGbl_DmTypeNames[Type]); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmNormalizeParentPrefix + * + * PARAMETERS: Op - Parse op + * Path - Path with parent prefix + * + * RETURN: The full pathname to the object (from the namespace root) + * + * DESCRIPTION: Returns the full pathname of a path with parent prefix + * The caller must free the fullpath returned. + * + ******************************************************************************/ + +static char * +AcpiDmNormalizeParentPrefix ( + ACPI_PARSE_OBJECT *Op, + char *Path) +{ + ACPI_NAMESPACE_NODE *Node; + char *Fullpath; + char *ParentPath; + ACPI_SIZE Length; + + + /* Search upwards in the parse tree until we reach a namespace node */ + + while (Op) + { + if (Op->Common.Node) + { + break; + } + + Op = Op->Common.Parent; + } + + if (!Op) + { + return (NULL); + } + + /* + * Find the actual parent node for the reference: + * Remove all carat prefixes from the input path. + * There may be multiple parent prefixes (For example, ^^^M000) + */ + Node = Op->Common.Node; + while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) + { + Node = Node->Parent; + Path++; + } + + if (!Node) + { + return (NULL); + } + + /* Get the full pathname for the parent node */ + + ParentPath = AcpiNsGetExternalPathname (Node); + if (!ParentPath) + { + return (NULL); + } + + Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); + if (ParentPath[1]) + { + /* + * If ParentPath is not just a simple '\', increment the length + * for the required dot separator (ParentPath.Path) + */ + Length++; + } + + Fullpath = ACPI_ALLOCATE_ZEROED (Length); + if (!Fullpath) + { + goto Cleanup; + } + + /* + * Concatenate parent fullpath and path. For example, + * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" + * + * Copy the parent path + */ + ACPI_STRCAT (Fullpath, ParentPath); + + /* Add dot separator (don't need dot if parent fullpath is a single "\") */ + + if (ParentPath[1]) + { + ACPI_STRCAT (Fullpath, "."); + } + + /* Copy child path (carat parent prefix(es) were skipped above) */ + + ACPI_STRCAT (Fullpath, Path); + +Cleanup: + ACPI_FREE (ParentPath); + return (Fullpath); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmAddToExternalFileList + * + * PARAMETERS: PathList - Single path or list separated by comma + * + * RETURN: None + * + * DESCRIPTION: Add external files to global list + * + ******************************************************************************/ + +ACPI_STATUS +AcpiDmAddToExternalFileList ( + char *PathList) +{ + ACPI_EXTERNAL_FILE *ExternalFile; + char *Path; + char *TmpPath; + + + if (!PathList) + { + return (AE_OK); + } + + Path = strtok (PathList, ","); + + while (Path) + { + TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1); + if (!TmpPath) + { + return (AE_NO_MEMORY); + } + + ACPI_STRCPY (TmpPath, Path); + + ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE)); + if (!ExternalFile) + { + ACPI_FREE (TmpPath); + return (AE_NO_MEMORY); + } + + ExternalFile->Path = TmpPath; + + if (AcpiGbl_ExternalFileList) + { + ExternalFile->Next = AcpiGbl_ExternalFileList; + } + + AcpiGbl_ExternalFileList = ExternalFile; + Path = strtok (NULL, ","); + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmClearExternalFileList + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Clear the external file list + * + ******************************************************************************/ + +void +AcpiDmClearExternalFileList ( + void) +{ + ACPI_EXTERNAL_FILE *NextExternal; + + + while (AcpiGbl_ExternalFileList) + { + NextExternal = AcpiGbl_ExternalFileList->Next; + ACPI_FREE (AcpiGbl_ExternalFileList->Path); + ACPI_FREE (AcpiGbl_ExternalFileList); + AcpiGbl_ExternalFileList = NextExternal; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmAddToExternalList + * + * PARAMETERS: Op - Current parser Op + * Path - Internal (AML) path to the object + * Type - ACPI object type to be added + * Value - Arg count if adding a Method object + * + * RETURN: None + * + * DESCRIPTION: Insert a new name into the global list of Externals which + * will in turn be later emitted as an External() declaration + * in the disassembled output. + * + ******************************************************************************/ + +void +AcpiDmAddToExternalList ( + ACPI_PARSE_OBJECT *Op, + char *Path, + UINT8 Type, + UINT32 Value) +{ + char *ExternalPath; + char *Fullpath = NULL; + ACPI_EXTERNAL_LIST *NewExternal; + ACPI_EXTERNAL_LIST *NextExternal; + ACPI_EXTERNAL_LIST *PrevExternal = NULL; + ACPI_STATUS Status; + + + if (!Path) + { + return; + } + + /* Externalize the ACPI path */ + + Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, + NULL, &ExternalPath); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Get the full pathname from root if "Path" has a parent prefix */ + + if (*Path == (UINT8) AML_PARENT_PREFIX) + { + Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath); + if (Fullpath) + { + /* Set new external path */ + + ACPI_FREE (ExternalPath); + ExternalPath = Fullpath; + } + } + + /* Check all existing externals to ensure no duplicates */ + + NextExternal = AcpiGbl_ExternalList; + while (NextExternal) + { + if (!ACPI_STRCMP (ExternalPath, NextExternal->Path)) + { + /* Duplicate method, check that the Value (ArgCount) is the same */ + + if ((NextExternal->Type == ACPI_TYPE_METHOD) && + (NextExternal->Value != Value)) + { + ACPI_ERROR ((AE_INFO, + "Argument count mismatch for method %s %u %u", + NextExternal->Path, NextExternal->Value, Value)); + } + + /* Allow upgrade of type from ANY */ + + else if (NextExternal->Type == ACPI_TYPE_ANY) + { + NextExternal->Type = Type; + NextExternal->Value = Value; + } + + ACPI_FREE (ExternalPath); + return; + } + + NextExternal = NextExternal->Next; + } + + /* Allocate and init a new External() descriptor */ + + NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); + if (!NewExternal) + { + ACPI_FREE (ExternalPath); + return; + } + + NewExternal->Path = ExternalPath; + NewExternal->Type = Type; + NewExternal->Value = Value; + NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath); + + /* Was the external path with parent prefix normalized to a fullpath? */ + + if (Fullpath == ExternalPath) + { + /* Get new internal path */ + + Status = AcpiNsInternalizeName (ExternalPath, &Path); + if (ACPI_FAILURE (Status)) + { + ACPI_FREE (ExternalPath); + ACPI_FREE (NewExternal); + return; + } + + /* Set flag to indicate External->InternalPath need to be freed */ + + NewExternal->Flags |= ACPI_IPATH_ALLOCATED; + } + + NewExternal->InternalPath = Path; + + /* Link the new descriptor into the global list, ordered by string length */ + + NextExternal = AcpiGbl_ExternalList; + while (NextExternal) + { + if (NewExternal->Length <= NextExternal->Length) + { + if (PrevExternal) + { + PrevExternal->Next = NewExternal; + } + else + { + AcpiGbl_ExternalList = NewExternal; + } + + NewExternal->Next = NextExternal; + return; + } + + PrevExternal = NextExternal; + NextExternal = NextExternal->Next; + } + + if (PrevExternal) + { + PrevExternal->Next = NewExternal; + } + else + { + AcpiGbl_ExternalList = NewExternal; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmAddExternalsToNamespace + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Add all externals to the namespace. Allows externals to be + * "resolved". + * + ******************************************************************************/ + +void +AcpiDmAddExternalsToNamespace ( + void) +{ + ACPI_STATUS Status; + ACPI_NAMESPACE_NODE *Node; + ACPI_OPERAND_OBJECT *MethodDesc; + ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; + + + while (External) + { + /* Add the external name (object) into the namespace */ + + Status = AcpiNsLookup (NULL, External->InternalPath, External->Type, + ACPI_IMODE_LOAD_PASS1, + ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, + NULL, &Node); + + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, + "while adding external to namespace [%s]", + External->Path)); + } + else if (External->Type == ACPI_TYPE_METHOD) + { + /* For methods, we need to save the argument count */ + + MethodDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); + MethodDesc->Method.ParamCount = (UINT8) External->Value; + Node->Object = MethodDesc; + } + + External = External->Next; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGetExternalMethodCount + * + * PARAMETERS: None + * + * RETURN: The number of control method externals in the external list + * + * DESCRIPTION: Return the number of method externals that have been generated. + * If any control method externals have been found, we must + * re-parse the entire definition block with the new information + * (number of arguments for the methods.) This is limitation of + * AML, we don't know the number of arguments from the control + * method invocation itself. + * + ******************************************************************************/ + +UINT32 +AcpiDmGetExternalMethodCount ( + void) +{ + ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; + UINT32 Count = 0; + + + while (External) + { + if (External->Type == ACPI_TYPE_METHOD) + { + Count++; + } + + External = External->Next; + } + + return (Count); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmClearExternalList + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Free the entire External info list + * + ******************************************************************************/ + +void +AcpiDmClearExternalList ( + void) +{ + ACPI_EXTERNAL_LIST *NextExternal; + + + while (AcpiGbl_ExternalList) + { + NextExternal = AcpiGbl_ExternalList->Next; + ACPI_FREE (AcpiGbl_ExternalList->Path); + ACPI_FREE (AcpiGbl_ExternalList); + AcpiGbl_ExternalList = NextExternal; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmEmitExternals + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Emit an External() ASL statement for each of the externals in + * the global external info list. + * + ******************************************************************************/ + +void +AcpiDmEmitExternals ( + void) +{ + ACPI_EXTERNAL_LIST *NextExternal; + + + if (!AcpiGbl_ExternalList) + { + return; + } + + /* + * Walk the list of externals (unresolved references) + * found during the AML parsing + */ + while (AcpiGbl_ExternalList) + { + AcpiOsPrintf (" External (%s%s", + AcpiGbl_ExternalList->Path, + AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); + + if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) + { + AcpiOsPrintf (") // %u Arguments\n", + AcpiGbl_ExternalList->Value); + } + else + { + AcpiOsPrintf (")\n"); + } + + /* Free this external info block and move on to next external */ + + NextExternal = AcpiGbl_ExternalList->Next; + if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED) + { + ACPI_FREE (AcpiGbl_ExternalList->InternalPath); + } + + ACPI_FREE (AcpiGbl_ExternalList->Path); + ACPI_FREE (AcpiGbl_ExternalList); + AcpiGbl_ExternalList = NextExternal; + } + + AcpiOsPrintf ("\n"); +} + diff --git a/source/common/dmrestag.c b/source/common/dmrestag.c new file mode 100644 index 0000000000000..13b3bbc3d46db --- /dev/null +++ b/source/common/dmrestag.c @@ -0,0 +1,1045 @@ +/****************************************************************************** + * + * Module Name: dmrestag - Add tags to resource descriptors (Application-level) + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include "acpi.h" +#include "accommon.h" +#include "acparser.h" +#include "acdisasm.h" +#include "acnamesp.h" +#include "amlcode.h" + +/* This module used for application-level code only */ + +#define _COMPONENT ACPI_CA_DISASSEMBLER + ACPI_MODULE_NAME ("dmrestag") + +/* Local prototypes */ + +static void +AcpiDmUpdateResourceName ( + ACPI_NAMESPACE_NODE *ResourceNode); + +static char * +AcpiDmSearchTagList ( + UINT32 BitIndex, + const ACPI_RESOURCE_TAG *TagList); + +static char * +AcpiDmGetResourceTag ( + UINT32 BitIndex, + AML_RESOURCE *Resource, + UINT8 ResourceIndex); + +static char * +AcpiGetTagPathname ( + ACPI_NAMESPACE_NODE *BufferNode, + ACPI_NAMESPACE_NODE *ResourceNode, + UINT32 BitIndex); + +static ACPI_NAMESPACE_NODE * +AcpiDmGetResourceNode ( + ACPI_NAMESPACE_NODE *BufferNode, + UINT32 BitIndex); + +static ACPI_STATUS +AcpiDmAddResourceToNamespace ( + UINT8 *Aml, + UINT32 Length, + UINT32 Offset, + UINT8 ResourceIndex, + void *Context); + +static void +AcpiDmAddResourcesToNamespace ( + ACPI_NAMESPACE_NODE *BufferNode, + ACPI_PARSE_OBJECT *Op); + + +/****************************************************************************** + * + * Resource Tag tables + * + * These are the predefined tags that refer to elements of a resource + * descriptor. Each name and offset is defined in the ACPI specification. + * + * Each table entry contains the bit offset of the field and the associated + * name. + * + ******************************************************************************/ + +static const ACPI_RESOURCE_TAG AcpiDmIrqTags[] = +{ + {( 1 * 8), ACPI_RESTAG_INTERRUPT}, + {( 3 * 8) + 0, ACPI_RESTAG_INTERRUPTTYPE}, + {( 3 * 8) + 3, ACPI_RESTAG_INTERRUPTLEVEL}, + {( 3 * 8) + 4, ACPI_RESTAG_INTERRUPTSHARE}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmDmaTags[] = +{ + {( 1 * 8), ACPI_RESTAG_DMA}, + {( 2 * 8) + 0, ACPI_RESTAG_XFERTYPE}, + {( 2 * 8) + 2, ACPI_RESTAG_BUSMASTER}, + {( 2 * 8) + 5, ACPI_RESTAG_DMATYPE}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmIoTags[] = +{ + {( 1 * 8) + 0, ACPI_RESTAG_DECODE}, + {( 2 * 8), ACPI_RESTAG_MINADDR}, + {( 4 * 8), ACPI_RESTAG_MAXADDR}, + {( 6 * 8), ACPI_RESTAG_ALIGNMENT}, + {( 7 * 8), ACPI_RESTAG_LENGTH}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmFixedIoTags[] = +{ + {( 1 * 8), ACPI_RESTAG_BASEADDRESS}, + {( 3 * 8), ACPI_RESTAG_LENGTH}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmFixedDmaTags[] = +{ + {( 1 * 8), ACPI_RESTAG_DMA}, + {( 3 * 8), ACPI_RESTAG_DMATYPE}, + {( 5 * 8), ACPI_RESTAG_XFERTYPE}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmMemory24Tags[] = +{ + {( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE}, + {( 4 * 8), ACPI_RESTAG_MINADDR}, + {( 6 * 8), ACPI_RESTAG_MAXADDR}, + {( 8 * 8), ACPI_RESTAG_ALIGNMENT}, + {(10 * 8), ACPI_RESTAG_LENGTH}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmRegisterTags[] = +{ + {( 3 * 8), ACPI_RESTAG_ADDRESSSPACE}, + {( 4 * 8), ACPI_RESTAG_REGISTERBITWIDTH}, + {( 5 * 8), ACPI_RESTAG_REGISTERBITOFFSET}, + {( 6 * 8), ACPI_RESTAG_ACCESSSIZE}, + {( 7 * 8), ACPI_RESTAG_ADDRESS}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmMemory32Tags[] = +{ + {( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE}, + {( 4 * 8), ACPI_RESTAG_MINADDR}, + {( 8 * 8), ACPI_RESTAG_MAXADDR}, + {(12 * 8), ACPI_RESTAG_ALIGNMENT}, + {(16 * 8), ACPI_RESTAG_LENGTH}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmFixedMemory32Tags[] = +{ + {( 3 * 8) + 0, ACPI_RESTAG_READWRITETYPE}, + {( 4 * 8), ACPI_RESTAG_BASEADDRESS}, + {( 8 * 8), ACPI_RESTAG_LENGTH}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmInterruptTags[] = +{ + {( 3 * 8) + 1, ACPI_RESTAG_INTERRUPTTYPE}, + {( 3 * 8) + 2, ACPI_RESTAG_INTERRUPTLEVEL}, + {( 3 * 8) + 3, ACPI_RESTAG_INTERRUPTSHARE}, + {( 5 * 8), ACPI_RESTAG_INTERRUPT}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmAddress16Tags[] = +{ + {( 4 * 8) + 1, ACPI_RESTAG_DECODE}, + {( 4 * 8) + 2, ACPI_RESTAG_MINTYPE}, + {( 4 * 8) + 3, ACPI_RESTAG_MAXTYPE}, + {( 6 * 8), ACPI_RESTAG_GRANULARITY}, + {( 8 * 8), ACPI_RESTAG_MINADDR}, + {(10 * 8), ACPI_RESTAG_MAXADDR}, + {(12 * 8), ACPI_RESTAG_TRANSLATION}, + {(14 * 8), ACPI_RESTAG_LENGTH}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmAddress32Tags[] = +{ + {( 4 * 8) + 1, ACPI_RESTAG_DECODE}, + {( 4 * 8) + 2, ACPI_RESTAG_MINTYPE}, + {( 4 * 8) + 3, ACPI_RESTAG_MAXTYPE}, + {( 6 * 8), ACPI_RESTAG_GRANULARITY}, + {(10 * 8), ACPI_RESTAG_MINADDR}, + {(14 * 8), ACPI_RESTAG_MAXADDR}, + {(18 * 8), ACPI_RESTAG_TRANSLATION}, + {(22 * 8), ACPI_RESTAG_LENGTH}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmAddress64Tags[] = +{ + {( 4 * 8) + 1, ACPI_RESTAG_DECODE}, + {( 4 * 8) + 2, ACPI_RESTAG_MINTYPE}, + {( 4 * 8) + 3, ACPI_RESTAG_MAXTYPE}, + {( 6 * 8), ACPI_RESTAG_GRANULARITY}, + {(14 * 8), ACPI_RESTAG_MINADDR}, + {(22 * 8), ACPI_RESTAG_MAXADDR}, + {(30 * 8), ACPI_RESTAG_TRANSLATION}, + {(38 * 8), ACPI_RESTAG_LENGTH}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmExtendedAddressTags[] = +{ + {( 4 * 8) + 1, ACPI_RESTAG_DECODE}, + {( 4 * 8) + 2, ACPI_RESTAG_MINTYPE}, + {( 4 * 8) + 3, ACPI_RESTAG_MAXTYPE}, + {( 8 * 8), ACPI_RESTAG_GRANULARITY}, + {(16 * 8), ACPI_RESTAG_MINADDR}, + {(24 * 8), ACPI_RESTAG_MAXADDR}, + {(32 * 8), ACPI_RESTAG_TRANSLATION}, + {(40 * 8), ACPI_RESTAG_LENGTH}, + {(48 * 8), ACPI_RESTAG_TYPESPECIFICATTRIBUTES}, + {0, NULL} +}; + +/* Subtype tables for GPIO descriptors */ + +static const ACPI_RESOURCE_TAG AcpiDmGpioIntTags[] = +{ + {( 7 * 8) + 0, ACPI_RESTAG_MODE}, + {( 7 * 8) + 1, ACPI_RESTAG_POLARITY}, + {( 7 * 8) + 3, ACPI_RESTAG_INTERRUPTSHARE}, + {( 9 * 8), ACPI_RESTAG_PINCONFIG}, + {(10 * 8), ACPI_RESTAG_DRIVESTRENGTH}, + {(12 * 8), ACPI_RESTAG_DEBOUNCETIME}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmGpioIoTags[] = +{ + {( 7 * 8) + 0, ACPI_RESTAG_IORESTRICTION}, + {( 7 * 8) + 3, ACPI_RESTAG_INTERRUPTSHARE}, + {( 9 * 8), ACPI_RESTAG_PINCONFIG}, + {(10 * 8), ACPI_RESTAG_DRIVESTRENGTH}, + {(12 * 8), ACPI_RESTAG_DEBOUNCETIME}, + {0, NULL} +}; + +/* Subtype tables for SerialBus descriptors */ + +static const ACPI_RESOURCE_TAG AcpiDmI2cSerialBusTags[] = +{ + {( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE}, + {( 7 * 8) + 0, ACPI_RESTAG_MODE}, + {(12 * 8), ACPI_RESTAG_SPEED}, + {(16 * 8), ACPI_RESTAG_ADDRESS}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmSpiSerialBusTags[] = +{ + {( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE}, + {( 7 * 8) + 0, ACPI_RESTAG_MODE}, + {( 7 * 8) + 1, ACPI_RESTAG_DEVICEPOLARITY}, + {(12 * 8), ACPI_RESTAG_SPEED}, + {(16 * 8), ACPI_RESTAG_LENGTH}, + {(17 * 8), ACPI_RESTAG_PHASE}, + {(18 * 8), ACPI_RESTAG_POLARITY}, + {(19 * 8), ACPI_RESTAG_ADDRESS}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmUartSerialBusTags[] = +{ + {( 6 * 8) + 0, ACPI_RESTAG_SLAVEMODE}, /* Note: not part of original macro */ + {( 7 * 8) + 0, ACPI_RESTAG_FLOWCONTROL}, + {( 7 * 8) + 2, ACPI_RESTAG_STOPBITS}, + {( 7 * 8) + 4, ACPI_RESTAG_LENGTH}, + {( 7 * 8) + 7, ACPI_RESTAG_ENDIANNESS}, + {(12 * 8), ACPI_RESTAG_SPEED}, + {(16 * 8), ACPI_RESTAG_LENGTH_RX}, + {(18 * 8), ACPI_RESTAG_LENGTH_TX}, + {(20 * 8), ACPI_RESTAG_PARITY}, + {(21 * 8), ACPI_RESTAG_LINE}, + {0, NULL} +}; + +/* Subtype tables for Address descriptor type-specific flags */ + +static const ACPI_RESOURCE_TAG AcpiDmMemoryFlagTags[] = +{ + {( 5 * 8) + 0, ACPI_RESTAG_READWRITETYPE}, + {( 5 * 8) + 1, ACPI_RESTAG_MEMTYPE}, + {( 5 * 8) + 3, ACPI_RESTAG_MEMATTRIBUTES}, + {( 5 * 8) + 5, ACPI_RESTAG_TYPE}, + {0, NULL} +}; + +static const ACPI_RESOURCE_TAG AcpiDmIoFlagTags[] = +{ + {( 5 * 8) + 0, ACPI_RESTAG_RANGETYPE}, + {( 5 * 8) + 4, ACPI_RESTAG_TYPE}, + {( 5 * 8) + 5, ACPI_RESTAG_TRANSTYPE}, + {0, NULL} +}; + + +/* + * Dispatch table used to obtain the correct tag table for a descriptor. + * + * A NULL in this table means one of three things: + * 1) The descriptor ID is reserved and invalid + * 2) The descriptor has no tags associated with it + * 3) The descriptor has subtypes and a separate table will be used. + */ +static const ACPI_RESOURCE_TAG *AcpiGbl_ResourceTags[] = +{ + /* Small descriptors */ + + NULL, /* 0x00, Reserved */ + NULL, /* 0x01, Reserved */ + NULL, /* 0x02, Reserved */ + NULL, /* 0x03, Reserved */ + AcpiDmIrqTags, /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */ + AcpiDmDmaTags, /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */ + NULL, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */ + NULL, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */ + AcpiDmIoTags, /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */ + AcpiDmFixedIoTags, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */ + AcpiDmFixedDmaTags, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */ + NULL, /* 0x0B, Reserved */ + NULL, /* 0x0C, Reserved */ + NULL, /* 0x0D, Reserved */ + NULL, /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */ + NULL, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */ + + /* Large descriptors */ + + NULL, /* 0x00, Reserved */ + AcpiDmMemory24Tags, /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */ + AcpiDmRegisterTags, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */ + NULL, /* 0x03, Reserved */ + NULL, /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */ + AcpiDmMemory32Tags, /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */ + AcpiDmFixedMemory32Tags, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */ + AcpiDmAddress32Tags, /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */ + AcpiDmAddress16Tags, /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */ + AcpiDmInterruptTags, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */ + AcpiDmAddress64Tags, /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */ + AcpiDmExtendedAddressTags, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */ + NULL, /* 0x0C, ACPI_RESOURCE_NAME_GPIO - Use Subtype table below */ + NULL, /* 0x0D, Reserved */ + NULL /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS - Use Subtype table below */ +}; + +/* GPIO Subtypes */ + +static const ACPI_RESOURCE_TAG *AcpiGbl_GpioResourceTags[] = +{ + AcpiDmGpioIntTags, /* 0x00 Interrupt Connection */ + AcpiDmGpioIoTags /* 0x01 I/O Connection */ +}; + +/* Serial Bus Subtypes */ + +static const ACPI_RESOURCE_TAG *AcpiGbl_SerialResourceTags[] = +{ + NULL, /* 0x00 Reserved */ + AcpiDmI2cSerialBusTags, /* 0x01 I2C SerialBus */ + AcpiDmSpiSerialBusTags, /* 0x02 SPI SerialBus */ + AcpiDmUartSerialBusTags /* 0x03 UART SerialBus */ +}; + +/* + * Globals used to generate unique resource descriptor names. We use names that + * start with underscore and a prefix letter that is not used by other ACPI + * reserved names. To this, we append hex 0x00 through 0xFF. These 5 prefixes + * allow for 5*256 = 1280 unique names, probably sufficient for any single ASL + * file. If this becomes too small, we can use alpha+numerals for a total + * of 5*36*36 = 6480. + */ +#define ACPI_NUM_RES_PREFIX 5 + +static UINT32 AcpiGbl_NextResourceId = 0; +static UINT8 AcpiGbl_NextPrefix = 0; +static char AcpiGbl_Prefix[ACPI_NUM_RES_PREFIX] = + {'Y','Z','J','K','X'}; + + +/******************************************************************************* + * + * FUNCTION: AcpiDmCheckResourceReference + * + * PARAMETERS: Op - Parse Op for the AML opcode + * WalkState - Current walk state (with valid scope) + * + * RETURN: None + * + * DESCRIPTION: Convert a reference to a resource descriptor to a symbolic + * reference if possible + * + * NOTE: Bit index is used to transparently handle both resource bit + * fields and byte fields. + * + ******************************************************************************/ + +void +AcpiDmCheckResourceReference ( + ACPI_PARSE_OBJECT *Op, + ACPI_WALK_STATE *WalkState) +{ + ACPI_STATUS Status; + ACPI_PARSE_OBJECT *BufferNameOp; + ACPI_PARSE_OBJECT *IndexOp; + ACPI_NAMESPACE_NODE *BufferNode; + ACPI_NAMESPACE_NODE *ResourceNode; + const ACPI_OPCODE_INFO *OpInfo; + char *Pathname; + UINT32 BitIndex; + + + /* We are only interested in the CreateXxxxField opcodes */ + + OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); + if (OpInfo->Type != AML_TYPE_CREATE_FIELD) + { + return; + } + + /* Get the buffer term operand */ + + BufferNameOp = AcpiPsGetDepthNext (NULL, Op); + + /* Must be a named buffer, not an arg or local or method call */ + + if (BufferNameOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP) + { + return; + } + + /* Get the Index term, must be an integer constant to convert */ + + IndexOp = BufferNameOp->Common.Next; + OpInfo = AcpiPsGetOpcodeInfo (IndexOp->Common.AmlOpcode); + if (OpInfo->ObjectType != ACPI_TYPE_INTEGER) + { + return; + } + + /* Get the bit offset of the descriptor within the buffer */ + + if ((Op->Common.AmlOpcode == AML_CREATE_BIT_FIELD_OP) || + (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)) + { + /* Index operand is a bit offset */ + + BitIndex = (UINT32) IndexOp->Common.Value.Integer; + } + else + { + /* Index operand is a byte offset, convert to bits */ + + BitIndex = (UINT32) ACPI_MUL_8 (IndexOp->Common.Value.Integer); + } + + /* Lookup the buffer in the namespace */ + + Status = AcpiNsLookup (WalkState->ScopeInfo, + BufferNameOp->Common.Value.String, ACPI_TYPE_BUFFER, + ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, + &BufferNode); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Validate object type, we must have a buffer */ + + if (BufferNode->Type != ACPI_TYPE_BUFFER) + { + return; + } + + /* Find the resource descriptor node corresponding to the index */ + + ResourceNode = AcpiDmGetResourceNode (BufferNode, BitIndex); + if (!ResourceNode) + { + return; + } + + /* Translate the Index to a resource tag pathname */ + + Pathname = AcpiGetTagPathname (BufferNode, ResourceNode, BitIndex); + if (Pathname) + { + /* Complete the conversion of the Index to a symbol */ + + IndexOp->Common.AmlOpcode = AML_INT_NAMEPATH_OP; + IndexOp->Common.Value.String = Pathname; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGetResourceNode + * + * PARAMETERS: BufferNode - Node for the parent buffer + * BitIndex - Index into the resource descriptor + * + * RETURN: Namespace node for the resource descriptor. NULL if not found + * + * DESCRIPTION: Find a resource descriptor that corresponds to the bit index + * + ******************************************************************************/ + +static ACPI_NAMESPACE_NODE * +AcpiDmGetResourceNode ( + ACPI_NAMESPACE_NODE *BufferNode, + UINT32 BitIndex) +{ + ACPI_NAMESPACE_NODE *Node; + UINT32 ByteIndex = ACPI_DIV_8 (BitIndex); + + + /* + * Child list contains an entry for each resource descriptor. Find + * the descriptor that corresponds to the Index. + * + * If there are no children, this is not a resource template + */ + Node = BufferNode->Child; + while (Node) + { + /* + * Check if the Index falls within this resource. + * + * Value contains the resource offset, Object contains the resource + * length (both in bytes) + */ + if ((ByteIndex >= Node->Value) && + (ByteIndex < (Node->Value + Node->Length))) + { + return (Node); + } + + Node = Node->Peer; + } + + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiGetTagPathname + * + * PARAMETERS: BufferNode - Node for the parent buffer + * ResourceNode - Node for a resource descriptor + * BitIndex - Index into the resource descriptor + * + * RETURN: Full pathname for a resource tag. NULL if no match. + * Path is returned in AML (packed) format. + * + * DESCRIPTION: Convert a BitIndex into a symbolic resource tag (full pathname) + * + ******************************************************************************/ + +static char * +AcpiGetTagPathname ( + ACPI_NAMESPACE_NODE *BufferNode, + ACPI_NAMESPACE_NODE *ResourceNode, + UINT32 BitIndex) +{ + ACPI_STATUS Status; + UINT32 ResourceBitIndex; + UINT8 ResourceTableIndex; + ACPI_SIZE RequiredSize; + char *Pathname; + AML_RESOURCE *Aml; + ACPI_PARSE_OBJECT *Op; + char *InternalPath; + char *Tag; + + + /* Get the Op that contains the actual buffer data */ + + Op = BufferNode->Op->Common.Value.Arg; + Op = Op->Common.Next; + if (!Op) + { + return (NULL); + } + + /* Get the individual resource descriptor and validate it */ + + Aml = ACPI_CAST_PTR (AML_RESOURCE, + &Op->Named.Data[ResourceNode->Value]); + + Status = AcpiUtValidateResource (Aml, &ResourceTableIndex); + if (ACPI_FAILURE (Status)) + { + return (NULL); + } + + /* Get offset into this descriptor (from offset into entire buffer) */ + + ResourceBitIndex = BitIndex - ACPI_MUL_8 (ResourceNode->Value); + + /* Get the tag associated with this resource descriptor and offset */ + + Tag = AcpiDmGetResourceTag (ResourceBitIndex, Aml, ResourceTableIndex); + if (!Tag) + { + return (NULL); + } + + /* + * Now that we know that we have a reference that can be converted to a + * symbol, change the name of the resource to a unique name. + */ + AcpiDmUpdateResourceName (ResourceNode); + + /* Get the full pathname to the parent buffer */ + + RequiredSize = AcpiNsGetPathnameLength (BufferNode); + if (!RequiredSize) + { + return (NULL); + } + + Pathname = ACPI_ALLOCATE_ZEROED (RequiredSize + ACPI_PATH_SEGMENT_LENGTH); + if (!Pathname) + { + return (NULL); + } + + Status = AcpiNsBuildExternalPath (BufferNode, RequiredSize, Pathname); + if (ACPI_FAILURE (Status)) + { + return (NULL); + } + + /* + * Create the full path to the resource and tag by: remove the buffer name, + * append the resource descriptor name, append a dot, append the tag name. + * + * TBD: Always using the full path is a bit brute force, the path can be + * often be optimized with carats (if the original buffer namepath is a + * single nameseg). This doesn't really matter, because these paths do not + * end up in the final compiled AML, it's just an appearance issue for the + * disassembled code. + */ + Pathname[ACPI_STRLEN (Pathname) - ACPI_NAME_SIZE] = 0; + ACPI_STRNCAT (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE); + ACPI_STRCAT (Pathname, "."); + ACPI_STRNCAT (Pathname, Tag, ACPI_NAME_SIZE); + + /* Internalize the namepath to AML format */ + + AcpiNsInternalizeName (Pathname, &InternalPath); + ACPI_FREE (Pathname); + return (InternalPath); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmUpdateResourceName + * + * PARAMETERS: ResourceNode - Node for a resource descriptor + * + * RETURN: Stores new name in the ResourceNode + * + * DESCRIPTION: Create a new, unique name for a resource descriptor. Used by + * both the disassembly of the descriptor itself and any symbolic + * references to the descriptor. Ignored if a unique name has + * already been assigned to the resource. + * + * NOTE: Single threaded, suitable for applications only! + * + ******************************************************************************/ + +static void +AcpiDmUpdateResourceName ( + ACPI_NAMESPACE_NODE *ResourceNode) +{ + char Name[ACPI_NAME_SIZE]; + + + /* Ignore if a unique name has already been assigned */ + + if (ResourceNode->Name.Integer != ACPI_DEFAULT_RESNAME) + { + return; + } + + /* Generate a new ACPI name for the descriptor */ + + Name[0] = '_'; + Name[1] = AcpiGbl_Prefix[AcpiGbl_NextPrefix]; + Name[2] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 4); + Name[3] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 0); + + /* Update globals for next name */ + + AcpiGbl_NextResourceId++; + if (AcpiGbl_NextResourceId >= 256) + { + AcpiGbl_NextResourceId = 0; + AcpiGbl_NextPrefix++; + if (AcpiGbl_NextPrefix > ACPI_NUM_RES_PREFIX) + { + AcpiGbl_NextPrefix = 0; + } + } + + /* Change the resource descriptor name */ + + ResourceNode->Name.Integer = *ACPI_CAST_PTR (UINT32, &Name[0]); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGetResourceTag + * + * PARAMETERS: BitIndex - Index into the resource descriptor + * Resource - Pointer to the raw resource data + * ResourceIndex - Index correspoinding to the resource type + * + * RETURN: Pointer to the resource tag (ACPI_NAME). NULL if no match. + * + * DESCRIPTION: Convert a BitIndex into a symbolic resource tag. + * + * Note: ResourceIndex should be previously validated and guaranteed to ve + * valid. + * + ******************************************************************************/ + +static char * +AcpiDmGetResourceTag ( + UINT32 BitIndex, + AML_RESOURCE *Resource, + UINT8 ResourceIndex) +{ + const ACPI_RESOURCE_TAG *TagList; + char *Tag = NULL; + + + /* Get the tag list for this resource descriptor type */ + + TagList = AcpiGbl_ResourceTags[ResourceIndex]; + + /* + * Handle descriptors that have multiple subtypes + */ + switch (Resource->DescriptorType) + { + case ACPI_RESOURCE_NAME_ADDRESS16: + case ACPI_RESOURCE_NAME_ADDRESS32: + case ACPI_RESOURCE_NAME_ADDRESS64: + case ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64: + + /* + * Subtype differentiation is the flags. + * Kindof brute force, but just blindly search for an index match + */ + if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_MEMORY_RANGE) + { + Tag = AcpiDmSearchTagList (BitIndex, AcpiDmMemoryFlagTags); + } + else if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_IO_RANGE) + { + Tag = AcpiDmSearchTagList (BitIndex, AcpiDmIoFlagTags); + } + + /* If we found a match, all done. Else, drop to normal search below */ + + if (Tag) + { + return (Tag); + } + break; + + case ACPI_RESOURCE_NAME_GPIO: + + /* GPIO connection has 2 subtypes: Interrupt and I/O */ + + if (Resource->Gpio.ConnectionType > AML_RESOURCE_MAX_GPIOTYPE) + { + return (NULL); + } + + TagList = AcpiGbl_GpioResourceTags[Resource->Gpio.ConnectionType]; + break; + + case ACPI_RESOURCE_NAME_SERIAL_BUS: + + /* SerialBus has 3 subtypes: I2C, SPI, and UART */ + + if ((Resource->CommonSerialBus.Type == 0) || + (Resource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE)) + { + return (NULL); + } + + TagList = AcpiGbl_SerialResourceTags[Resource->CommonSerialBus.Type]; + break; + + default: + break; + } + + /* Search for a match against the BitIndex */ + + if (TagList) + { + Tag = AcpiDmSearchTagList (BitIndex, TagList); + } + + return (Tag); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmSearchTagList + * + * PARAMETERS: BitIndex - Index into the resource descriptor + * TagList - List to search + * + * RETURN: Pointer to a tag (ACPI_NAME). NULL if no match found. + * + * DESCRIPTION: Search a tag list for a match to the input BitIndex. Matches + * a fixed offset to a symbolic resource tag name. + * + ******************************************************************************/ + +static char * +AcpiDmSearchTagList ( + UINT32 BitIndex, + const ACPI_RESOURCE_TAG *TagList) +{ + + /* + * Walk the null-terminated tag list to find a matching bit offset. + * We are looking for an exact match. + */ + for ( ; TagList->Tag; TagList++) + { + if (BitIndex == TagList->BitIndex) + { + return (TagList->Tag); + } + } + + /* A matching offset was not found */ + + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmFindResources + * + * PARAMETERS: Root - Root of the parse tree + * + * RETURN: None + * + * DESCRIPTION: Add all ResourceTemplate declarations to the namespace. Each + * resource descriptor in each template is given a node -- used + * for later conversion of resource references to symbolic refs. + * + ******************************************************************************/ + +void +AcpiDmFindResources ( + ACPI_PARSE_OBJECT *Root) +{ + ACPI_PARSE_OBJECT *Op = Root; + ACPI_PARSE_OBJECT *Parent; + + + /* Walk the entire parse tree */ + + while (Op) + { + /* We are interested in Buffer() declarations */ + + if (Op->Common.AmlOpcode == AML_BUFFER_OP) + { + /* And only declarations of the form Name (XXXX, Buffer()... ) */ + + Parent = Op->Common.Parent; + if (Parent->Common.AmlOpcode == AML_NAME_OP) + { + /* + * If the buffer is a resource template, add the individual + * resource descriptors to the namespace, as children of the + * buffer node. + */ + if (ACPI_SUCCESS (AcpiDmIsResourceTemplate (Op))) + { + Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE; + AcpiDmAddResourcesToNamespace (Parent->Common.Node, Op); + } + } + } + + Op = AcpiPsGetDepthNext (Root, Op); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmAddResourcesToNamespace + * + * PARAMETERS: BufferNode - Node for the parent buffer + * Op - Parse op for the buffer + * + * RETURN: None + * + * DESCRIPTION: Add an entire resource template to the namespace. Each + * resource descriptor is added as a namespace node. + * + ******************************************************************************/ + +static void +AcpiDmAddResourcesToNamespace ( + ACPI_NAMESPACE_NODE *BufferNode, + ACPI_PARSE_OBJECT *Op) +{ + ACPI_PARSE_OBJECT *NextOp; + + + /* Get to the ByteData list */ + + NextOp = Op->Common.Value.Arg; + NextOp = NextOp->Common.Next; + if (!NextOp) + { + return; + } + + /* Set Node and Op to point to each other */ + + BufferNode->Op = Op; + Op->Common.Node = BufferNode; + + /* + * Insert each resource into the namespace + * NextOp contains the Aml pointer and the Aml length + */ + AcpiUtWalkAmlResources ((UINT8 *) NextOp->Named.Data, + (ACPI_SIZE) NextOp->Common.Value.Integer, + AcpiDmAddResourceToNamespace, BufferNode); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmAddResourceToNamespace + * + * PARAMETERS: ACPI_WALK_AML_CALLBACK + * BufferNode - Node for the parent buffer + * + * RETURN: Status + * + * DESCRIPTION: Add one resource descriptor to the namespace as a child of the + * parent buffer. The same name is used for each descriptor. This + * is changed later to a unique name if the resource is actually + * referenced by an AML operator. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDmAddResourceToNamespace ( + UINT8 *Aml, + UINT32 Length, + UINT32 Offset, + UINT8 ResourceIndex, + void *Context) +{ + ACPI_STATUS Status; + ACPI_GENERIC_STATE ScopeInfo; + ACPI_NAMESPACE_NODE *Node; + + + /* TBD: Don't need to add descriptors that have no tags defined? */ + + /* Add the resource to the namespace, as child of the buffer */ + + ScopeInfo.Scope.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Context); + Status = AcpiNsLookup (&ScopeInfo, "_TMP", ACPI_TYPE_LOCAL_RESOURCE, + ACPI_IMODE_LOAD_PASS2, + ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_PREFIX_IS_SCOPE, + NULL, &Node); + if (ACPI_FAILURE (Status)) + { + return (AE_OK); + } + + /* Set the name to the default, changed later if resource is referenced */ + + Node->Name.Integer = ACPI_DEFAULT_RESNAME; + + /* Save the offset of the descriptor (within the original buffer) */ + + Node->Value = Offset; + Node->Length = Length; + return (AE_OK); +} + diff --git a/source/common/dmtable.c b/source/common/dmtable.c new file mode 100644 index 0000000000000..eceef4f51bf09 --- /dev/null +++ b/source/common/dmtable.c @@ -0,0 +1,1204 @@ +/****************************************************************************** + * + * Module Name: dmtable - Support for ACPI tables that contain no AML code + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" +#include "acdisasm.h" +#include "actables.h" +#include "aslcompiler.h" +#include "dtcompiler.h" + +/* This module used for application-level code only */ + +#define _COMPONENT ACPI_CA_DISASSEMBLER + ACPI_MODULE_NAME ("dmtable") + +/* Local Prototypes */ + +static void +AcpiDmCheckAscii ( + UINT8 *Target, + char *RepairedName, + UINT32 Count); + + +/* Common format strings for commented values */ + +#define UINT8_FORMAT "%2.2X [%s]\n" +#define UINT16_FORMAT "%4.4X [%s]\n" +#define UINT32_FORMAT "%8.8X [%s]\n" +#define STRING_FORMAT "[%s]\n" + +/* These tables map a subtable type to a description string */ + +static const char *AcpiDmAsfSubnames[] = +{ + "ASF Information", + "ASF Alerts", + "ASF Remote Control", + "ASF RMCP Boot Options", + "ASF Address", + "Unknown SubTable Type" /* Reserved */ +}; + +static const char *AcpiDmDmarSubnames[] = +{ + "Hardware Unit Definition", + "Reserved Memory Region", + "Root Port ATS Capability", + "Remapping Hardware Static Affinity", + "Unknown SubTable Type" /* Reserved */ +}; + +static const char *AcpiDmEinjActions[] = +{ + "Begin Operation", + "Get Trigger Table", + "Set Error Type", + "Get Error Type", + "End Operation", + "Execute Operation", + "Check Busy Status", + "Get Command Status", + "Unknown Action" +}; + +static const char *AcpiDmEinjInstructions[] = +{ + "Read Register", + "Read Register Value", + "Write Register", + "Write Register Value", + "Noop", + "Unknown Instruction" +}; + +static const char *AcpiDmErstActions[] = +{ + "Begin Write Operation", + "Begin Read Operation", + "Begin Clear Operation", + "End Operation", + "Set Record Offset", + "Execute Operation", + "Check Busy Status", + "Get Command Status", + "Get Record Identifier", + "Set Record Identifier", + "Get Record Count", + "Begin Dummy Write", + "Unused/Unknown Action", + "Get Error Address Range", + "Get Error Address Length", + "Get Error Attributes", + "Unknown Action" +}; + +static const char *AcpiDmErstInstructions[] = +{ + "Read Register", + "Read Register Value", + "Write Register", + "Write Register Value", + "Noop", + "Load Var1", + "Load Var2", + "Store Var1", + "Add", + "Subtract", + "Add Value", + "Subtract Value", + "Stall", + "Stall While True", + "Skip Next If True", + "GoTo", + "Set Source Address", + "Set Destination Address", + "Move Data", + "Unknown Instruction" +}; + +static const char *AcpiDmHestSubnames[] = +{ + "IA-32 Machine Check Exception", + "IA-32 Corrected Machine Check", + "IA-32 Non-Maskable Interrupt", + "Unknown SubTable Type", /* 3 - Reserved */ + "Unknown SubTable Type", /* 4 - Reserved */ + "Unknown SubTable Type", /* 5 - Reserved */ + "PCI Express Root Port AER", + "PCI Express AER (AER Endpoint)", + "PCI Express/PCI-X Bridge AER", + "Generic Hardware Error Source", + "Unknown SubTable Type" /* Reserved */ +}; + +static const char *AcpiDmHestNotifySubnames[] = +{ + "Polled", + "External Interrupt", + "Local Interrupt", + "SCI", + "NMI", + "Unknown Notify Type" /* Reserved */ +}; + +static const char *AcpiDmMadtSubnames[] = +{ + "Processor Local APIC", /* ACPI_MADT_TYPE_LOCAL_APIC */ + "I/O APIC", /* ACPI_MADT_TYPE_IO_APIC */ + "Interrupt Source Override", /* ACPI_MADT_TYPE_INTERRUPT_OVERRIDE */ + "NMI Source", /* ACPI_MADT_TYPE_NMI_SOURCE */ + "Local APIC NMI", /* ACPI_MADT_TYPE_LOCAL_APIC_NMI */ + "Local APIC Address Override", /* ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE */ + "I/O SAPIC", /* ACPI_MADT_TYPE_IO_SAPIC */ + "Local SAPIC", /* ACPI_MADT_TYPE_LOCAL_SAPIC */ + "Platform Interrupt Sources", /* ACPI_MADT_TYPE_INTERRUPT_SOURCE */ + "Processor Local x2APIC", /* ACPI_MADT_TYPE_LOCAL_X2APIC */ + "Local x2APIC NMI", /* ACPI_MADT_TYPE_LOCAL_X2APIC_NMI */ + "Generic Interrupt Controller", /* ACPI_MADT_GENERIC_INTERRUPT */ + "Generic Interrupt Distributor",/* ACPI_MADT_GENERIC_DISTRIBUTOR */ + "Unknown SubTable Type" /* Reserved */ +}; + +static const char *AcpiDmPmttSubnames[] = +{ + "Socket", /* ACPI_PMTT_TYPE_SOCKET */ + "Memory Controller", /* ACPI_PMTT_TYPE_CONTROLLER */ + "Physical Component (DIMM)", /* ACPI_PMTT_TYPE_DIMM */ + "Unknown SubTable Type" /* Reserved */ +}; + +static const char *AcpiDmSlicSubnames[] = +{ + "Public Key Structure", + "Windows Marker Structure", + "Unknown SubTable Type" /* Reserved */ +}; + +static const char *AcpiDmSratSubnames[] = +{ + "Processor Local APIC/SAPIC Affinity", + "Memory Affinity", + "Processor Local x2APIC Affinity", + "Unknown SubTable Type" /* Reserved */ +}; + +static const char *AcpiDmIvrsSubnames[] = +{ + "Hardware Definition Block", + "Memory Definition Block", + "Unknown SubTable Type" /* Reserved */ +}; + + +#define ACPI_FADT_PM_RESERVED 9 + +static const char *AcpiDmFadtProfiles[] = +{ + "Unspecified", + "Desktop", + "Mobile", + "Workstation", + "Enterprise Server", + "SOHO Server", + "Appliance PC", + "Performance Server", + "Tablet", + "Unknown Profile Type" +}; + +#define ACPI_GAS_WIDTH_RESERVED 5 + +static const char *AcpiDmGasAccessWidth[] = +{ + "Undefined/Legacy", + "Byte Access:8", + "Word Access:16", + "DWord Access:32", + "QWord Access:64", + "Unknown Width Encoding" +}; + + +/******************************************************************************* + * + * ACPI Table Data, indexed by signature. + * + * Each entry contains: Signature, Table Info, Handler, DtHandler, + * Template, Description + * + * Simple tables have only a TableInfo structure, complex tables have a + * handler. This table must be NULL terminated. RSDP and FACS are + * special-cased elsewhere. + * + ******************************************************************************/ + +ACPI_DMTABLE_DATA AcpiDmTableData[] = +{ + {ACPI_SIG_ASF, NULL, AcpiDmDumpAsf, DtCompileAsf, TemplateAsf, "Alert Standard Format table"}, + {ACPI_SIG_BOOT, AcpiDmTableInfoBoot, NULL, NULL, TemplateBoot, "Simple Boot Flag Table"}, + {ACPI_SIG_BERT, AcpiDmTableInfoBert, NULL, NULL, TemplateBert, "Boot Error Record Table"}, + {ACPI_SIG_BGRT, AcpiDmTableInfoBgrt, NULL, NULL, TemplateBgrt, "Boot Graphics Resource Table"}, + {ACPI_SIG_CPEP, NULL, AcpiDmDumpCpep, DtCompileCpep, TemplateCpep, "Corrected Platform Error Polling table"}, + {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp, NULL, NULL, TemplateDbgp, "Debug Port table"}, + {ACPI_SIG_DMAR, NULL, AcpiDmDumpDmar, DtCompileDmar, TemplateDmar, "DMA Remapping table"}, + {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt, NULL, NULL, TemplateEcdt, "Embedded Controller Boot Resources Table"}, + {ACPI_SIG_EINJ, NULL, AcpiDmDumpEinj, DtCompileEinj, TemplateEinj, "Error Injection table"}, + {ACPI_SIG_ERST, NULL, AcpiDmDumpErst, DtCompileErst, TemplateErst, "Error Record Serialization Table"}, + {ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, DtCompileFadt, TemplateFadt, "Fixed ACPI Description Table"}, + {ACPI_SIG_FPDT, NULL, AcpiDmDumpFpdt, DtCompileFpdt, TemplateFpdt, "Firmware Performance Data Table"}, + {ACPI_SIG_GTDT, AcpiDmTableInfoGtdt, NULL, NULL, TemplateGtdt, "Generic Timer Description Table"}, + {ACPI_SIG_HEST, NULL, AcpiDmDumpHest, DtCompileHest, TemplateHest, "Hardware Error Source Table"}, + {ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, NULL, TemplateHpet, "High Precision Event Timer table"}, + {ACPI_SIG_IVRS, NULL, AcpiDmDumpIvrs, DtCompileIvrs, TemplateIvrs, "I/O Virtualization Reporting Structure"}, + {ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, DtCompileMadt, TemplateMadt, "Multiple APIC Description Table"}, + {ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, DtCompileMcfg, TemplateMcfg, "Memory Mapped Configuration table"}, + {ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, NULL, TemplateMchi, "Management Controller Host Interface table"}, + {ACPI_SIG_MPST, AcpiDmTableInfoMpst, AcpiDmDumpMpst, DtCompileMpst, TemplateMpst, "Memory Power State Table"}, + {ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, DtCompileMsct, TemplateMsct, "Maximum System Characteristics Table"}, + {ACPI_SIG_PCCT, NULL, AcpiDmDumpPcct, NULL, NULL, "Platform Communications Channel Table"}, + {ACPI_SIG_PMTT, NULL, AcpiDmDumpPmtt, DtCompilePmtt, TemplatePmtt, "Platform Memory Topology Table"}, + {ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, DtCompileRsdt, TemplateRsdt, "Root System Description Table"}, + {ACPI_SIG_S3PT, NULL, NULL, NULL, TemplateS3pt, "S3 Performance Table"}, + {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, NULL, TemplateSbst, "Smart Battery Specification Table"}, + {ACPI_SIG_SLIC, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateSlic, "Software Licensing Description Table"}, + {ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, DtCompileSlit, TemplateSlit, "System Locality Information Table"}, + {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, NULL, TemplateSpcr, "Serial Port Console Redirection table"}, + {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi, NULL, NULL, TemplateSpmi, "Server Platform Management Interface table"}, + {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, DtCompileSrat, TemplateSrat, "System Resource Affinity Table"}, + {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa, NULL, NULL, TemplateTcpa, "Trusted Computing Platform Alliance table"}, + {ACPI_SIG_UEFI, AcpiDmTableInfoUefi, NULL, DtCompileUefi, TemplateUefi, "UEFI Boot Optimization Table"}, + {ACPI_SIG_WAET, AcpiDmTableInfoWaet, NULL, NULL, TemplateWaet, "Windows ACPI Emulated Devices Table"}, + {ACPI_SIG_WDAT, NULL, AcpiDmDumpWdat, DtCompileWdat, TemplateWdat, "Watchdog Action Table"}, + {ACPI_SIG_WDDT, AcpiDmTableInfoWddt, NULL, NULL, TemplateWddt, "Watchdog Description Table"}, + {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt, NULL, NULL, TemplateWdrt, "Watchdog Resource Table"}, + {ACPI_SIG_XSDT, NULL, AcpiDmDumpXsdt, DtCompileXsdt, TemplateXsdt, "Extended System Description Table"}, + {NULL, NULL, NULL, NULL, NULL, NULL} +}; + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGenerateChecksum + * + * PARAMETERS: Table - Pointer to table to be checksummed + * Length - Length of the table + * OriginalChecksum - Value of the checksum field + * + * RETURN: 8 bit checksum of buffer + * + * DESCRIPTION: Computes an 8 bit checksum of the table. + * + ******************************************************************************/ + +UINT8 +AcpiDmGenerateChecksum ( + void *Table, + UINT32 Length, + UINT8 OriginalChecksum) +{ + UINT8 Checksum; + + + /* Sum the entire table as-is */ + + Checksum = AcpiTbChecksum ((UINT8 *) Table, Length); + + /* Subtract off the existing checksum value in the table */ + + Checksum = (UINT8) (Checksum - OriginalChecksum); + + /* Compute the final checksum */ + + Checksum = (UINT8) (0 - Checksum); + return (Checksum); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmGetTableData + * + * PARAMETERS: Signature - ACPI signature (4 chars) to match + * + * RETURN: Pointer to a valid ACPI_DMTABLE_DATA. Null if no match found. + * + * DESCRIPTION: Find a match in the global table of supported ACPI tables + * + ******************************************************************************/ + +ACPI_DMTABLE_DATA * +AcpiDmGetTableData ( + char *Signature) +{ + ACPI_DMTABLE_DATA *TableData; + + + for (TableData = AcpiDmTableData; TableData->Signature; TableData++) + { + if (ACPI_COMPARE_NAME (Signature, TableData->Signature)) + { + return (TableData); + } + } + + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpDataTable + * + * PARAMETERS: Table - An ACPI table + * + * RETURN: None. + * + * DESCRIPTION: Format the contents of an ACPI data table (any table other + * than an SSDT or DSDT that does not contain executable AML code) + * + ******************************************************************************/ + +void +AcpiDmDumpDataTable ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_DMTABLE_DATA *TableData; + UINT32 Length; + + + /* Ignore tables that contain AML */ + + if (AcpiUtIsAmlTable (Table)) + { + return; + } + + /* + * Handle tables that don't use the common ACPI table header structure. + * Currently, these are the FACS, RSDP, and S3PT. + */ + if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS)) + { + Length = Table->Length; + AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs); + } + else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP)) + { + Length = AcpiDmDumpRsdp (Table); + } + else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT)) + { + Length = AcpiDmDumpS3pt (Table); + } + else + { + /* + * All other tables must use the common ACPI table header, dump it now + */ + Length = Table->Length; + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader); + if (ACPI_FAILURE (Status)) + { + return; + } + AcpiOsPrintf ("\n"); + + /* Match signature and dispatch appropriately */ + + TableData = AcpiDmGetTableData (Table->Signature); + if (!TableData) + { + if (!ACPI_STRNCMP (Table->Signature, "OEM", 3)) + { + AcpiOsPrintf ("\n**** OEM-defined ACPI table [%4.4s], unknown contents\n\n", + Table->Signature); + } + else + { + AcpiOsPrintf ("\n**** Unknown ACPI table type [%4.4s]\n\n", + Table->Signature); + } + } + else if (TableData->TableHandler) + { + /* Complex table, has a handler */ + + TableData->TableHandler (Table); + } + else if (TableData->TableInfo) + { + /* Simple table, just walk the info table */ + + AcpiDmDumpTable (Length, 0, Table, 0, TableData->TableInfo); + } + } + + if (!Gbl_DoTemplates || Gbl_VerboseTemplates) + { + /* Dump the raw table data */ + + AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n", + ACPI_RAW_TABLE_DATA_HEADER, Length, Length); + AcpiUtDumpBuffer2 (ACPI_CAST_PTR (UINT8, Table), Length, DB_BYTE_DISPLAY); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmLineHeader + * + * PARAMETERS: Offset - Current byte offset, from table start + * ByteLength - Length of the field in bytes, 0 for flags + * Name - Name of this field + * Value - Optional value, displayed on left of ':' + * + * RETURN: None + * + * DESCRIPTION: Utility routines for formatting output lines. Displays the + * current table offset in hex and decimal, the field length, + * and the field name. + * + ******************************************************************************/ + +void +AcpiDmLineHeader ( + UINT32 Offset, + UINT32 ByteLength, + char *Name) +{ + + /* Allow a null name for fields that span multiple lines (large buffers) */ + + if (!Name) + { + Name = ""; + } + + if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */ + { + if (ByteLength) + { + AcpiOsPrintf ("[%.4d] %34s : ", ByteLength, Name); + } + else + { + if (*Name) + { + AcpiOsPrintf ("%41s : ", Name); + } + else + { + AcpiOsPrintf ("%41s ", Name); + } + } + } + else /* Normal disassembler or verbose template */ + { + if (ByteLength) + { + AcpiOsPrintf ("[%3.3Xh %4.4d% 4d] %28s : ", + Offset, Offset, ByteLength, Name); + } + else + { + if (*Name) + { + AcpiOsPrintf ("%44s : ", Name); + } + else + { + AcpiOsPrintf ("%44s ", Name); + } + } + } +} + +void +AcpiDmLineHeader2 ( + UINT32 Offset, + UINT32 ByteLength, + char *Name, + UINT32 Value) +{ + + if (Gbl_DoTemplates && !Gbl_VerboseTemplates) /* Terse template */ + { + if (ByteLength) + { + AcpiOsPrintf ("[%.4d] %30s %3d : ", + ByteLength, Name, Value); + } + else + { + AcpiOsPrintf ("%36s % 3d : ", + Name, Value); + } + } + else /* Normal disassembler or verbose template */ + { + if (ByteLength) + { + AcpiOsPrintf ("[%3.3Xh %4.4d %3d] %24s %3d : ", + Offset, Offset, ByteLength, Name, Value); + } + else + { + AcpiOsPrintf ("[%3.3Xh %4.4d ] %24s %3d : ", + Offset, Offset, Name, Value); + } + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpTable + * + * PARAMETERS: TableLength - Length of the entire ACPI table + * TableOffset - Starting offset within the table for this + * sub-descriptor (0 if main table) + * Table - The ACPI table + * SubtableLength - Length of this sub-descriptor + * Info - Info table for this ACPI table + * + * RETURN: None + * + * DESCRIPTION: Display ACPI table contents by walking the Info table. + * + * Note: This function must remain in sync with DtGetFieldLength. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiDmDumpTable ( + UINT32 TableLength, + UINT32 TableOffset, + void *Table, + UINT32 SubtableLength, + ACPI_DMTABLE_INFO *Info) +{ + UINT8 *Target; + UINT32 CurrentOffset; + UINT32 ByteLength; + UINT8 Temp8; + UINT16 Temp16; + ACPI_DMTABLE_DATA *TableData; + const char *Name; + BOOLEAN LastOutputBlankLine = FALSE; + char RepairedName[8]; + + + if (!Info) + { + AcpiOsPrintf ("Display not implemented\n"); + return (AE_NOT_IMPLEMENTED); + } + + /* Walk entire Info table; Null name terminates */ + + for (; Info->Name; Info++) + { + /* + * Target points to the field within the ACPI Table. CurrentOffset is + * the offset of the field from the start of the main table. + */ + Target = ACPI_ADD_PTR (UINT8, Table, Info->Offset); + CurrentOffset = TableOffset + Info->Offset; + + /* Check for beyond EOT or beyond subtable end */ + + if ((CurrentOffset >= TableLength) || + (SubtableLength && (Info->Offset >= SubtableLength))) + { + AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n"); + return (AE_BAD_DATA); + } + + /* Generate the byte length for this field */ + + switch (Info->Opcode) + { + case ACPI_DMT_UINT8: + case ACPI_DMT_CHKSUM: + case ACPI_DMT_SPACEID: + case ACPI_DMT_ACCWIDTH: + case ACPI_DMT_IVRS: + case ACPI_DMT_MADT: + case ACPI_DMT_PMTT: + case ACPI_DMT_SRAT: + case ACPI_DMT_ASF: + case ACPI_DMT_HESTNTYP: + case ACPI_DMT_FADTPM: + case ACPI_DMT_EINJACT: + case ACPI_DMT_EINJINST: + case ACPI_DMT_ERSTACT: + case ACPI_DMT_ERSTINST: + ByteLength = 1; + break; + case ACPI_DMT_UINT16: + case ACPI_DMT_DMAR: + case ACPI_DMT_HEST: + ByteLength = 2; + break; + case ACPI_DMT_UINT24: + ByteLength = 3; + break; + case ACPI_DMT_UINT32: + case ACPI_DMT_NAME4: + case ACPI_DMT_SIG: + case ACPI_DMT_SLIC: + ByteLength = 4; + break; + case ACPI_DMT_UINT40: + ByteLength = 5; + break; + case ACPI_DMT_UINT48: + case ACPI_DMT_NAME6: + ByteLength = 6; + break; + case ACPI_DMT_UINT56: + case ACPI_DMT_BUF7: + ByteLength = 7; + break; + case ACPI_DMT_UINT64: + case ACPI_DMT_NAME8: + ByteLength = 8; + break; + case ACPI_DMT_BUF16: + case ACPI_DMT_UUID: + ByteLength = 16; + break; + case ACPI_DMT_BUF128: + ByteLength = 128; + break; + case ACPI_DMT_STRING: + ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1; + break; + case ACPI_DMT_GAS: + if (!LastOutputBlankLine) + { + AcpiOsPrintf ("\n"); + LastOutputBlankLine = TRUE; + } + ByteLength = sizeof (ACPI_GENERIC_ADDRESS); + break; + case ACPI_DMT_HESTNTFY: + if (!LastOutputBlankLine) + { + AcpiOsPrintf ("\n"); + LastOutputBlankLine = TRUE; + } + ByteLength = sizeof (ACPI_HEST_NOTIFY); + break; + default: + ByteLength = 0; + break; + } + + if (CurrentOffset + ByteLength > TableLength) + { + AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n"); + return (AE_BAD_DATA); + } + + if (Info->Opcode == ACPI_DMT_EXTRA_TEXT) + { + AcpiOsPrintf ("%s", Info->Name); + continue; + } + + /* Start a new line and decode the opcode */ + + AcpiDmLineHeader (CurrentOffset, ByteLength, Info->Name); + + switch (Info->Opcode) + { + /* Single-bit Flag fields. Note: Opcode is the bit position */ + + case ACPI_DMT_FLAG0: + case ACPI_DMT_FLAG1: + case ACPI_DMT_FLAG2: + case ACPI_DMT_FLAG3: + case ACPI_DMT_FLAG4: + case ACPI_DMT_FLAG5: + case ACPI_DMT_FLAG6: + case ACPI_DMT_FLAG7: + + AcpiOsPrintf ("%1.1X\n", (*Target >> Info->Opcode) & 0x01); + break; + + /* 2-bit Flag fields */ + + case ACPI_DMT_FLAGS0: + + AcpiOsPrintf ("%1.1X\n", *Target & 0x03); + break; + + case ACPI_DMT_FLAGS1: + + AcpiOsPrintf ("%1.1X\n", (*Target >> 1) & 0x03); + break; + + case ACPI_DMT_FLAGS2: + + AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03); + break; + + case ACPI_DMT_FLAGS4: + + AcpiOsPrintf ("%1.1X\n", (*Target >> 4) & 0x03); + break; + + /* Integer Data Types */ + + case ACPI_DMT_UINT8: + case ACPI_DMT_UINT16: + case ACPI_DMT_UINT24: + case ACPI_DMT_UINT32: + case ACPI_DMT_UINT40: + case ACPI_DMT_UINT48: + case ACPI_DMT_UINT56: + case ACPI_DMT_UINT64: + /* + * Dump bytes - high byte first, low byte last. + * Note: All ACPI tables are little-endian. + */ + for (Temp8 = (UINT8) ByteLength; Temp8 > 0; Temp8--) + { + AcpiOsPrintf ("%2.2X", Target[Temp8 - 1]); + } + AcpiOsPrintf ("\n"); + break; + + case ACPI_DMT_BUF7: + case ACPI_DMT_BUF16: + case ACPI_DMT_BUF128: + + /* + * Buffer: Size depends on the opcode and was set above. + * Each hex byte is separated with a space. + * Multiple lines are separated by line continuation char. + */ + for (Temp16 = 0; Temp16 < ByteLength; Temp16++) + { + AcpiOsPrintf ("%2.2X", Target[Temp16]); + if ((UINT32) (Temp16 + 1) < ByteLength) + { + if ((Temp16 > 0) && (!((Temp16+1) % 16))) + { + AcpiOsPrintf (" \\\n"); /* Line continuation */ + AcpiDmLineHeader (0, 0, NULL); + } + else + { + AcpiOsPrintf (" "); + } + } + } + AcpiOsPrintf ("\n"); + break; + + case ACPI_DMT_UUID: + + /* Convert 16-byte UUID buffer to 36-byte formatted UUID string */ + + (void) AuConvertUuidToString ((char *) Target, MsgBuffer); + + AcpiOsPrintf ("%s\n", MsgBuffer); + break; + + case ACPI_DMT_STRING: + + AcpiOsPrintf ("\"%s\"\n", ACPI_CAST_PTR (char, Target)); + break; + + /* Fixed length ASCII name fields */ + + case ACPI_DMT_SIG: + + AcpiDmCheckAscii (Target, RepairedName, 4); + AcpiOsPrintf ("\"%.4s\" ", RepairedName); + TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target)); + if (TableData) + { + AcpiOsPrintf (STRING_FORMAT, TableData->Name); + } + else + { + AcpiOsPrintf ("\n"); + } + break; + + case ACPI_DMT_NAME4: + + AcpiDmCheckAscii (Target, RepairedName, 4); + AcpiOsPrintf ("\"%.4s\"\n", RepairedName); + break; + + case ACPI_DMT_NAME6: + + AcpiDmCheckAscii (Target, RepairedName, 6); + AcpiOsPrintf ("\"%.6s\"\n", RepairedName); + break; + + case ACPI_DMT_NAME8: + + AcpiDmCheckAscii (Target, RepairedName, 8); + AcpiOsPrintf ("\"%.8s\"\n", RepairedName); + break; + + /* Special Data Types */ + + case ACPI_DMT_CHKSUM: + + /* Checksum, display and validate */ + + AcpiOsPrintf ("%2.2X", *Target); + Temp8 = AcpiDmGenerateChecksum (Table, + ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length, + ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum); + if (Temp8 != ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Checksum) + { + AcpiOsPrintf ( + " /* Incorrect checksum, should be %2.2X */", Temp8); + } + AcpiOsPrintf ("\n"); + break; + + case ACPI_DMT_SPACEID: + + /* Address Space ID */ + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiUtGetRegionName (*Target)); + break; + + case ACPI_DMT_ACCWIDTH: + + /* Encoded Access Width */ + + Temp8 = *Target; + if (Temp8 > ACPI_GAS_WIDTH_RESERVED) + { + Temp8 = ACPI_GAS_WIDTH_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, Temp8, AcpiDmGasAccessWidth[Temp8]); + break; + + case ACPI_DMT_GAS: + + /* Generic Address Structure */ + + AcpiOsPrintf (STRING_FORMAT, "Generic Address Structure"); + AcpiDmDumpTable (TableLength, CurrentOffset, Target, + sizeof (ACPI_GENERIC_ADDRESS), AcpiDmTableInfoGas); + AcpiOsPrintf ("\n"); + LastOutputBlankLine = TRUE; + break; + + case ACPI_DMT_ASF: + + /* ASF subtable types */ + + Temp16 = (UINT16) ((*Target) & 0x7F); /* Top bit can be zero or one */ + if (Temp16 > ACPI_ASF_TYPE_RESERVED) + { + Temp16 = ACPI_ASF_TYPE_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmAsfSubnames[Temp16]); + break; + + case ACPI_DMT_DMAR: + + /* DMAR subtable types */ + + Temp16 = ACPI_GET16 (Target); + if (Temp16 > ACPI_DMAR_TYPE_RESERVED) + { + Temp16 = ACPI_DMAR_TYPE_RESERVED; + } + + AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmDmarSubnames[Temp16]); + break; + + case ACPI_DMT_EINJACT: + + /* EINJ Action types */ + + Temp8 = *Target; + if (Temp8 > ACPI_EINJ_ACTION_RESERVED) + { + Temp8 = ACPI_EINJ_ACTION_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjActions[Temp8]); + break; + + case ACPI_DMT_EINJINST: + + /* EINJ Instruction types */ + + Temp8 = *Target; + if (Temp8 > ACPI_EINJ_INSTRUCTION_RESERVED) + { + Temp8 = ACPI_EINJ_INSTRUCTION_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmEinjInstructions[Temp8]); + break; + + case ACPI_DMT_ERSTACT: + + /* ERST Action types */ + + Temp8 = *Target; + if (Temp8 > ACPI_ERST_ACTION_RESERVED) + { + Temp8 = ACPI_ERST_ACTION_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstActions[Temp8]); + break; + + case ACPI_DMT_ERSTINST: + + /* ERST Instruction types */ + + Temp8 = *Target; + if (Temp8 > ACPI_ERST_INSTRUCTION_RESERVED) + { + Temp8 = ACPI_ERST_INSTRUCTION_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmErstInstructions[Temp8]); + break; + + case ACPI_DMT_HEST: + + /* HEST subtable types */ + + Temp16 = ACPI_GET16 (Target); + if (Temp16 > ACPI_HEST_TYPE_RESERVED) + { + Temp16 = ACPI_HEST_TYPE_RESERVED; + } + + AcpiOsPrintf (UINT16_FORMAT, ACPI_GET16 (Target), AcpiDmHestSubnames[Temp16]); + break; + + case ACPI_DMT_HESTNTFY: + + AcpiOsPrintf (STRING_FORMAT, "Hardware Error Notification Structure"); + AcpiDmDumpTable (TableLength, CurrentOffset, Target, + sizeof (ACPI_HEST_NOTIFY), AcpiDmTableInfoHestNotify); + AcpiOsPrintf ("\n"); + LastOutputBlankLine = TRUE; + break; + + case ACPI_DMT_HESTNTYP: + + /* HEST Notify types */ + + Temp8 = *Target; + if (Temp8 > ACPI_HEST_NOTIFY_RESERVED) + { + Temp8 = ACPI_HEST_NOTIFY_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmHestNotifySubnames[Temp8]); + break; + + case ACPI_DMT_MADT: + + /* MADT subtable types */ + + Temp8 = *Target; + if (Temp8 > ACPI_MADT_TYPE_RESERVED) + { + Temp8 = ACPI_MADT_TYPE_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmMadtSubnames[Temp8]); + break; + + case ACPI_DMT_PMTT: + + /* PMTT subtable types */ + + Temp8 = *Target; + if (Temp8 > ACPI_PMTT_TYPE_RESERVED) + { + Temp8 = ACPI_PMTT_TYPE_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmPmttSubnames[Temp8]); + break; + + case ACPI_DMT_SLIC: + + /* SLIC subtable types */ + + Temp8 = *Target; + if (Temp8 > ACPI_SLIC_TYPE_RESERVED) + { + Temp8 = ACPI_SLIC_TYPE_RESERVED; + } + + AcpiOsPrintf (UINT32_FORMAT, *Target, AcpiDmSlicSubnames[Temp8]); + break; + + case ACPI_DMT_SRAT: + + /* SRAT subtable types */ + + Temp8 = *Target; + if (Temp8 > ACPI_SRAT_TYPE_RESERVED) + { + Temp8 = ACPI_SRAT_TYPE_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmSratSubnames[Temp8]); + break; + + case ACPI_DMT_FADTPM: + + /* FADT Preferred PM Profile names */ + + Temp8 = *Target; + if (Temp8 > ACPI_FADT_PM_RESERVED) + { + Temp8 = ACPI_FADT_PM_RESERVED; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, AcpiDmFadtProfiles[Temp8]); + break; + + case ACPI_DMT_IVRS: + + /* IVRS subtable types */ + + Temp8 = *Target; + switch (Temp8) + { + case ACPI_IVRS_TYPE_HARDWARE: + Name = AcpiDmIvrsSubnames[0]; + break; + + case ACPI_IVRS_TYPE_MEMORY1: + case ACPI_IVRS_TYPE_MEMORY2: + case ACPI_IVRS_TYPE_MEMORY3: + Name = AcpiDmIvrsSubnames[1]; + break; + + default: + Name = AcpiDmIvrsSubnames[2]; + break; + } + + AcpiOsPrintf (UINT8_FORMAT, *Target, Name); + break; + + case ACPI_DMT_EXIT: + return (AE_OK); + + default: + ACPI_ERROR ((AE_INFO, + "**** Invalid table opcode [0x%X] ****\n", Info->Opcode)); + return (AE_SUPPORT); + } + } + + if (TableOffset && !SubtableLength) + { + /* If this table is not the main table, subtable must have valid length */ + + AcpiOsPrintf ("Invalid zero length subtable\n"); + return (AE_BAD_DATA); + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmCheckAscii + * + * PARAMETERS: Name - Ascii string + * Count - Number of characters to check + * + * RETURN: None + * + * DESCRIPTION: Ensure that the requested number of characters are printable + * Ascii characters. Sets non-printable and null chars to <space>. + * + ******************************************************************************/ + +static void +AcpiDmCheckAscii ( + UINT8 *Name, + char *RepairedName, + UINT32 Count) +{ + UINT32 i; + + + for (i = 0; i < Count; i++) + { + RepairedName[i] = (char) Name[i]; + + if (!Name[i]) + { + return; + } + if (!isprint (Name[i])) + { + RepairedName[i] = ' '; + } + } +} diff --git a/source/common/dmtbdump.c b/source/common/dmtbdump.c new file mode 100644 index 0000000000000..5ea0ea34e6adb --- /dev/null +++ b/source/common/dmtbdump.c @@ -0,0 +1,2146 @@ +/****************************************************************************** + * + * Module Name: dmtbdump - Dump ACPI data tables that contain no AML code + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" +#include "acdisasm.h" +#include "actables.h" + +/* This module used for application-level code only */ + +#define _COMPONENT ACPI_CA_DISASSEMBLER + ACPI_MODULE_NAME ("dmtbdump") + + +static void +AcpiDmValidateFadtLength ( + UINT32 Revision, + UINT32 Length); + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpRsdp + * + * PARAMETERS: Table - A RSDP + * + * RETURN: Length of the table (there is not always a length field, + * use revision or length if available (ACPI 2.0+)) + * + * DESCRIPTION: Format the contents of a RSDP + * + ******************************************************************************/ + +UINT32 +AcpiDmDumpRsdp ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_TABLE_RSDP *Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); + UINT32 Length = sizeof (ACPI_RSDP_COMMON); + UINT8 Checksum; + + + /* Dump the common ACPI 1.0 portion */ + + AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp1); + + /* Validate the first checksum */ + + Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_RSDP_COMMON), + Rsdp->Checksum); + if (Checksum != Rsdp->Checksum) + { + AcpiOsPrintf ("/* Incorrect Checksum above, should be 0x%2.2X */\n", + Checksum); + } + + /* The RSDP for ACPI 2.0+ contains more data and has a Length field */ + + if (Rsdp->Revision > 0) + { + Length = Rsdp->Length; + AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoRsdp2); + + /* Validate the extended checksum over entire RSDP */ + + Checksum = AcpiDmGenerateChecksum (Rsdp, sizeof (ACPI_TABLE_RSDP), + Rsdp->ExtendedChecksum); + if (Checksum != Rsdp->ExtendedChecksum) + { + AcpiOsPrintf ( + "/* Incorrect Extended Checksum above, should be 0x%2.2X */\n", + Checksum); + } + } + + return (Length); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpRsdt + * + * PARAMETERS: Table - A RSDT + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a RSDT + * + ******************************************************************************/ + +void +AcpiDmDumpRsdt ( + ACPI_TABLE_HEADER *Table) +{ + UINT32 *Array; + UINT32 Entries; + UINT32 Offset; + UINT32 i; + + + /* Point to start of table pointer array */ + + Array = ACPI_CAST_PTR (ACPI_TABLE_RSDT, Table)->TableOffsetEntry; + Offset = sizeof (ACPI_TABLE_HEADER); + + /* RSDT uses 32-bit pointers */ + + Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT32); + + for (i = 0; i < Entries; i++) + { + AcpiDmLineHeader2 (Offset, sizeof (UINT32), "ACPI Table Address", i); + AcpiOsPrintf ("%8.8X\n", Array[i]); + Offset += sizeof (UINT32); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpXsdt + * + * PARAMETERS: Table - A XSDT + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a XSDT + * + ******************************************************************************/ + +void +AcpiDmDumpXsdt ( + ACPI_TABLE_HEADER *Table) +{ + UINT64 *Array; + UINT32 Entries; + UINT32 Offset; + UINT32 i; + + + /* Point to start of table pointer array */ + + Array = ACPI_CAST_PTR (ACPI_TABLE_XSDT, Table)->TableOffsetEntry; + Offset = sizeof (ACPI_TABLE_HEADER); + + /* XSDT uses 64-bit pointers */ + + Entries = (Table->Length - sizeof (ACPI_TABLE_HEADER)) / sizeof (UINT64); + + for (i = 0; i < Entries; i++) + { + AcpiDmLineHeader2 (Offset, sizeof (UINT64), "ACPI Table Address", i); + AcpiOsPrintf ("%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Array[i])); + Offset += sizeof (UINT64); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpFadt + * + * PARAMETERS: Table - A FADT + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a FADT + * + * NOTE: We cannot depend on the FADT version to indicate the actual + * contents of the FADT because of BIOS bugs. The table length + * is the only reliable indicator. + * + ******************************************************************************/ + +void +AcpiDmDumpFadt ( + ACPI_TABLE_HEADER *Table) +{ + + /* Always dump the minimum FADT revision 1 fields (ACPI 1.0) */ + + AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt1); + + /* Check for FADT revision 2 fields (ACPI 1.0B MS extensions) */ + + if ((Table->Length > ACPI_FADT_V1_SIZE) && + (Table->Length <= ACPI_FADT_V2_SIZE)) + { + AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt2); + } + + /* Check for FADT revision 3/4 fields and up (ACPI 2.0+ extended data) */ + + else if (Table->Length > ACPI_FADT_V2_SIZE) + { + AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt3); + + /* Check for FADT revision 5 fields and up (ACPI 5.0+) */ + + if (Table->Length > ACPI_FADT_V3_SIZE) + { + AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoFadt5); + } + } + + /* Validate various fields in the FADT, including length */ + + AcpiTbCreateLocalFadt (Table, Table->Length); + + /* Validate FADT length against the revision */ + + AcpiDmValidateFadtLength (Table->Revision, Table->Length); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmValidateFadtLength + * + * PARAMETERS: Revision - FADT revision (Header->Revision) + * Length - FADT length (Header->Length + * + * RETURN: None + * + * DESCRIPTION: Check the FADT revision against the expected table length for + * that revision. Issue a warning if the length is not what was + * expected. This seems to be such a common BIOS bug that the + * FADT revision has been rendered virtually meaningless. + * + ******************************************************************************/ + +static void +AcpiDmValidateFadtLength ( + UINT32 Revision, + UINT32 Length) +{ + UINT32 ExpectedLength; + + + switch (Revision) + { + case 0: + AcpiOsPrintf ("// ACPI Warning: Invalid FADT revision: 0\n"); + return; + + case 1: + ExpectedLength = ACPI_FADT_V1_SIZE; + break; + + case 2: + ExpectedLength = ACPI_FADT_V2_SIZE; + break; + + case 3: + case 4: + ExpectedLength = ACPI_FADT_V3_SIZE; + break; + + case 5: + ExpectedLength = ACPI_FADT_V5_SIZE; + break; + + default: + return; + } + + if (Length == ExpectedLength) + { + return; + } + + AcpiOsPrintf ( + "\n// ACPI Warning: FADT revision %X does not match length: found %X expected %X\n", + Revision, Length, ExpectedLength); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpAsf + * + * PARAMETERS: Table - A ASF table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a ASF table + * + ******************************************************************************/ + +void +AcpiDmDumpAsf ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_HEADER); + ACPI_ASF_INFO *SubTable; + ACPI_DMTABLE_INFO *InfoTable; + ACPI_DMTABLE_INFO *DataInfoTable = NULL; + UINT8 *DataTable = NULL; + UINT32 DataCount = 0; + UINT32 DataLength = 0; + UINT32 DataOffset = 0; + UINT32 i; + UINT8 Type; + + + /* No main table, only sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Header.Length, AcpiDmTableInfoAsfHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* The actual type is the lower 7 bits of Type */ + + Type = (UINT8) (SubTable->Header.Type & 0x7F); + + switch (Type) + { + case ACPI_ASF_TYPE_INFO: + InfoTable = AcpiDmTableInfoAsf0; + break; + + case ACPI_ASF_TYPE_ALERT: + InfoTable = AcpiDmTableInfoAsf1; + DataInfoTable = AcpiDmTableInfoAsf1a; + DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ALERT)); + DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->Alerts; + DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, SubTable)->DataLength; + DataOffset = Offset + sizeof (ACPI_ASF_ALERT); + break; + + case ACPI_ASF_TYPE_CONTROL: + InfoTable = AcpiDmTableInfoAsf2; + DataInfoTable = AcpiDmTableInfoAsf2a; + DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_REMOTE)); + DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->Controls; + DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, SubTable)->DataLength; + DataOffset = Offset + sizeof (ACPI_ASF_REMOTE); + break; + + case ACPI_ASF_TYPE_BOOT: + InfoTable = AcpiDmTableInfoAsf3; + break; + + case ACPI_ASF_TYPE_ADDRESS: + InfoTable = AcpiDmTableInfoAsf4; + DataTable = ACPI_ADD_PTR (UINT8, SubTable, sizeof (ACPI_ASF_ADDRESS)); + DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, SubTable)->Devices; + DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS); + break; + + default: + AcpiOsPrintf ("\n**** Unknown ASF sub-table type 0x%X\n", SubTable->Header.Type); + return; + } + + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Header.Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Dump variable-length extra data */ + + switch (Type) + { + case ACPI_ASF_TYPE_ALERT: + case ACPI_ASF_TYPE_CONTROL: + + for (i = 0; i < DataCount; i++) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, DataOffset, + DataTable, DataLength, DataInfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + + DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength); + DataOffset += DataLength; + } + break; + + case ACPI_ASF_TYPE_ADDRESS: + + for (i = 0; i < DataLength; i++) + { + if (!(i % 16)) + { + AcpiDmLineHeader (DataOffset, 1, "Addresses"); + } + + AcpiOsPrintf ("%2.2X ", *DataTable); + DataTable++; + DataOffset++; + if (DataOffset > Table->Length) + { + AcpiOsPrintf ("**** ACPI table terminates in the middle of a data structure!\n"); + return; + } + } + + AcpiOsPrintf ("\n"); + break; + + default: + break; + } + + AcpiOsPrintf ("\n"); + + /* Point to next sub-table */ + + if (!SubTable->Header.Length) + { + AcpiOsPrintf ("Invalid zero subtable header length\n"); + return; + } + + Offset += SubTable->Header.Length; + SubTable = ACPI_ADD_PTR (ACPI_ASF_INFO, SubTable, SubTable->Header.Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpCpep + * + * PARAMETERS: Table - A CPEP table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a CPEP. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpCpep ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_CPEP_POLLING *SubTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_CPEP); + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset); + while (Offset < Table->Length) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Header.Length, AcpiDmTableInfoCpep0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table */ + + Offset += SubTable->Header.Length; + SubTable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, SubTable, + SubTable->Header.Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpDmar + * + * PARAMETERS: Table - A DMAR table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a DMAR. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpDmar ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_DMAR_HEADER *SubTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_DMAR); + ACPI_DMTABLE_INFO *InfoTable; + ACPI_DMAR_DEVICE_SCOPE *ScopeTable; + UINT32 ScopeOffset; + UINT8 *PciPath; + UINT32 PathOffset; + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoDmarHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (SubTable->Type) + { + case ACPI_DMAR_TYPE_HARDWARE_UNIT: + InfoTable = AcpiDmTableInfoDmar0; + ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT); + break; + case ACPI_DMAR_TYPE_RESERVED_MEMORY: + InfoTable = AcpiDmTableInfoDmar1; + ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY); + break; + case ACPI_DMAR_TYPE_ATSR: + InfoTable = AcpiDmTableInfoDmar2; + ScopeOffset = sizeof (ACPI_DMAR_ATSR); + break; + case ACPI_DMAR_HARDWARE_AFFINITY: + InfoTable = AcpiDmTableInfoDmar3; + ScopeOffset = sizeof (ACPI_DMAR_RHSA); + break; + default: + AcpiOsPrintf ("\n**** Unknown DMAR sub-table type 0x%X\n\n", SubTable->Type); + return; + } + + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Dump the device scope entries (if any) */ + + ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, SubTable, ScopeOffset); + while (ScopeOffset < SubTable->Length) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable, + ScopeTable->Length, AcpiDmTableInfoDmarScope); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Dump the PCI Path entries for this device scope */ + + PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */ + + PciPath = ACPI_ADD_PTR (UINT8, ScopeTable, + sizeof (ACPI_DMAR_DEVICE_SCOPE)); + + while (PathOffset < ScopeTable->Length) + { + AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2, "PCI Path"); + AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]); + + /* Point to next PCI Path entry */ + + PathOffset += 2; + PciPath += 2; + } + + /* Point to next device scope entry */ + + ScopeOffset += ScopeTable->Length; + ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, + ScopeTable, ScopeTable->Length); + } + + /* Point to next sub-table */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, SubTable, SubTable->Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpEinj + * + * PARAMETERS: Table - A EINJ table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a EINJ. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpEinj ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_WHEA_HEADER *SubTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_EINJ); + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset); + while (Offset < Table->Length) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table (each subtable is of fixed length) */ + + Offset += sizeof (ACPI_WHEA_HEADER); + SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable, + sizeof (ACPI_WHEA_HEADER)); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpErst + * + * PARAMETERS: Table - A ERST table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a ERST. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpErst ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_WHEA_HEADER *SubTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_ERST); + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset); + while (Offset < Table->Length) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table (each subtable is of fixed length) */ + + Offset += sizeof (ACPI_WHEA_HEADER); + SubTable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, SubTable, + sizeof (ACPI_WHEA_HEADER)); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpFpdt + * + * PARAMETERS: Table - A FPDT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a FPDT. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpFpdt ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_FPDT_HEADER *SubTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_FPDT); + ACPI_DMTABLE_INFO *InfoTable; + + + /* There is no main table (other than the standard ACPI header) */ + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoFpdtHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (SubTable->Type) + { + case ACPI_FPDT_TYPE_BOOT: + InfoTable = AcpiDmTableInfoFpdt0; + break; + case ACPI_FPDT_TYPE_S3PERF: + InfoTable = AcpiDmTableInfoFpdt1; + break; + default: + AcpiOsPrintf ("\n**** Unknown FPDT sub-table type 0x%X\n\n", SubTable->Type); + + /* Attempt to continue */ + + if (!SubTable->Length) + { + AcpiOsPrintf ("Invalid zero length subtable\n"); + return; + } + goto NextSubTable; + } + + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + +NextSubTable: + /* Point to next sub-table */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, SubTable, SubTable->Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpHest + * + * PARAMETERS: Table - A HEST table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a HEST. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpHest ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_HEST_HEADER *SubTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_HEST); + ACPI_DMTABLE_INFO *InfoTable; + UINT32 SubTableLength; + UINT32 BankCount; + ACPI_HEST_IA_ERROR_BANK *BankTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset); + while (Offset < Table->Length) + { + BankCount = 0; + switch (SubTable->Type) + { + case ACPI_HEST_TYPE_IA32_CHECK: + InfoTable = AcpiDmTableInfoHest0; + SubTableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK); + BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, + SubTable))->NumHardwareBanks; + break; + + case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: + InfoTable = AcpiDmTableInfoHest1; + SubTableLength = sizeof (ACPI_HEST_IA_CORRECTED); + BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, + SubTable))->NumHardwareBanks; + break; + + case ACPI_HEST_TYPE_IA32_NMI: + InfoTable = AcpiDmTableInfoHest2; + SubTableLength = sizeof (ACPI_HEST_IA_NMI); + break; + + case ACPI_HEST_TYPE_AER_ROOT_PORT: + InfoTable = AcpiDmTableInfoHest6; + SubTableLength = sizeof (ACPI_HEST_AER_ROOT); + break; + + case ACPI_HEST_TYPE_AER_ENDPOINT: + InfoTable = AcpiDmTableInfoHest7; + SubTableLength = sizeof (ACPI_HEST_AER); + break; + + case ACPI_HEST_TYPE_AER_BRIDGE: + InfoTable = AcpiDmTableInfoHest8; + SubTableLength = sizeof (ACPI_HEST_AER_BRIDGE); + break; + + case ACPI_HEST_TYPE_GENERIC_ERROR: + InfoTable = AcpiDmTableInfoHest9; + SubTableLength = sizeof (ACPI_HEST_GENERIC); + break; + + default: + /* Cannot continue on unknown type - no length */ + + AcpiOsPrintf ("\n**** Unknown HEST sub-table type 0x%X\n", SubTable->Type); + return; + } + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTableLength, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to end of current subtable (each subtable above is of fixed length) */ + + Offset += SubTableLength; + + /* If there are any (fixed-length) Error Banks from above, dump them now */ + + if (BankCount) + { + BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, SubTable, SubTableLength); + SubTableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK); + + while (BankCount) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, BankTable, + sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank); + if (ACPI_FAILURE (Status)) + { + return; + } + Offset += sizeof (ACPI_HEST_IA_ERROR_BANK); + BankTable++; + BankCount--; + } + } + + /* Point to next sub-table */ + + SubTable = ACPI_ADD_PTR (ACPI_HEST_HEADER, SubTable, SubTableLength); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpIvrs + * + * PARAMETERS: Table - A IVRS table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a IVRS + * + ******************************************************************************/ + +static UINT8 EntrySizes[] = {4,8,16,32}; + +void +AcpiDmDumpIvrs ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_IVRS); + UINT32 EntryOffset; + UINT32 EntryLength; + UINT32 EntryType; + ACPI_IVRS_DE_HEADER *DeviceEntry; + ACPI_IVRS_HEADER *SubTable; + ACPI_DMTABLE_INFO *InfoTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoIvrsHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (SubTable->Type) + { + case ACPI_IVRS_TYPE_HARDWARE: + InfoTable = AcpiDmTableInfoIvrs0; + break; + case ACPI_IVRS_TYPE_MEMORY1: + case ACPI_IVRS_TYPE_MEMORY2: + case ACPI_IVRS_TYPE_MEMORY3: + InfoTable = AcpiDmTableInfoIvrs1; + break; + default: + AcpiOsPrintf ("\n**** Unknown IVRS sub-table type 0x%X\n", + SubTable->Type); + + /* Attempt to continue */ + + if (!SubTable->Length) + { + AcpiOsPrintf ("Invalid zero length subtable\n"); + return; + } + goto NextSubTable; + } + + /* Dump the subtable */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* The hardware subtable can contain multiple device entries */ + + if (SubTable->Type == ACPI_IVRS_TYPE_HARDWARE) + { + EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE); + DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, SubTable, + sizeof (ACPI_IVRS_HARDWARE)); + + while (EntryOffset < (Offset + SubTable->Length)) + { + AcpiOsPrintf ("\n"); + /* + * Upper 2 bits of Type encode the length of the device entry + * + * 00 = 4 byte + * 01 = 8 byte + * 10 = 16 byte - currently no entries defined + * 11 = 32 byte - currently no entries defined + */ + EntryType = DeviceEntry->Type; + EntryLength = EntrySizes [EntryType >> 6]; + + switch (EntryType) + { + /* 4-byte device entries */ + + case ACPI_IVRS_TYPE_PAD4: + case ACPI_IVRS_TYPE_ALL: + case ACPI_IVRS_TYPE_SELECT: + case ACPI_IVRS_TYPE_START: + case ACPI_IVRS_TYPE_END: + + InfoTable = AcpiDmTableInfoIvrs4; + break; + + /* 8-byte entries, type A */ + + case ACPI_IVRS_TYPE_ALIAS_SELECT: + case ACPI_IVRS_TYPE_ALIAS_START: + + InfoTable = AcpiDmTableInfoIvrs8a; + break; + + /* 8-byte entries, type B */ + + case ACPI_IVRS_TYPE_PAD8: + case ACPI_IVRS_TYPE_EXT_SELECT: + case ACPI_IVRS_TYPE_EXT_START: + + InfoTable = AcpiDmTableInfoIvrs8b; + break; + + /* 8-byte entries, type C */ + + case ACPI_IVRS_TYPE_SPECIAL: + + InfoTable = AcpiDmTableInfoIvrs8c; + break; + + default: + InfoTable = AcpiDmTableInfoIvrs4; + AcpiOsPrintf ( + "\n**** Unknown IVRS device entry type/length: " + "0x%.2X/0x%X at offset 0x%.4X: (header below)\n", + EntryType, EntryLength, EntryOffset); + break; + } + + /* Dump the Device Entry */ + + Status = AcpiDmDumpTable (Table->Length, EntryOffset, + DeviceEntry, EntryLength, InfoTable); + + EntryOffset += EntryLength; + DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, DeviceEntry, + EntryLength); + } + } + +NextSubTable: + /* Point to next sub-table */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, SubTable, SubTable->Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpMadt + * + * PARAMETERS: Table - A MADT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a MADT. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpMadt ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_SUBTABLE_HEADER *SubTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_MADT); + ACPI_DMTABLE_INFO *InfoTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoMadtHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (SubTable->Type) + { + case ACPI_MADT_TYPE_LOCAL_APIC: + InfoTable = AcpiDmTableInfoMadt0; + break; + case ACPI_MADT_TYPE_IO_APIC: + InfoTable = AcpiDmTableInfoMadt1; + break; + case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: + InfoTable = AcpiDmTableInfoMadt2; + break; + case ACPI_MADT_TYPE_NMI_SOURCE: + InfoTable = AcpiDmTableInfoMadt3; + break; + case ACPI_MADT_TYPE_LOCAL_APIC_NMI: + InfoTable = AcpiDmTableInfoMadt4; + break; + case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: + InfoTable = AcpiDmTableInfoMadt5; + break; + case ACPI_MADT_TYPE_IO_SAPIC: + InfoTable = AcpiDmTableInfoMadt6; + break; + case ACPI_MADT_TYPE_LOCAL_SAPIC: + InfoTable = AcpiDmTableInfoMadt7; + break; + case ACPI_MADT_TYPE_INTERRUPT_SOURCE: + InfoTable = AcpiDmTableInfoMadt8; + break; + case ACPI_MADT_TYPE_LOCAL_X2APIC: + InfoTable = AcpiDmTableInfoMadt9; + break; + case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: + InfoTable = AcpiDmTableInfoMadt10; + break; + case ACPI_MADT_TYPE_GENERIC_INTERRUPT: + InfoTable = AcpiDmTableInfoMadt11; + break; + case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: + InfoTable = AcpiDmTableInfoMadt12; + break; + default: + AcpiOsPrintf ("\n**** Unknown MADT sub-table type 0x%X\n\n", SubTable->Type); + + /* Attempt to continue */ + + if (!SubTable->Length) + { + AcpiOsPrintf ("Invalid zero length subtable\n"); + return; + } + goto NextSubTable; + } + + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + +NextSubTable: + /* Point to next sub-table */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpMcfg + * + * PARAMETERS: Table - A MCFG Table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a MCFG table + * + ******************************************************************************/ + +void +AcpiDmDumpMcfg ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_MCFG); + ACPI_MCFG_ALLOCATION *SubTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset); + while (Offset < Table->Length) + { + if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length) + { + AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n", + sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length)); + return; + } + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table (each subtable is of fixed length) */ + + Offset += sizeof (ACPI_MCFG_ALLOCATION); + SubTable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, SubTable, + sizeof (ACPI_MCFG_ALLOCATION)); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpMpst + * + * PARAMETERS: Table - A MPST Table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a MPST table + * + ******************************************************************************/ + +void +AcpiDmDumpMpst ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_MPST); + ACPI_MPST_POWER_NODE *SubTable0; + ACPI_MPST_POWER_STATE *SubTable0A; + ACPI_MPST_COMPONENT *SubTable0B; + ACPI_MPST_DATA_HDR *SubTable1; + ACPI_MPST_POWER_DATA *SubTable2; + UINT16 SubtableCount; + UINT8 PowerStateCount; + UINT8 ComponentCount; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Subtable: Memory Power Node(s) */ + + SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount; + SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset); + + while ((Offset < Table->Length) && SubtableCount) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0, + sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Extract the sub-subtable counts */ + + PowerStateCount = SubTable0->NumPowerStates; + ComponentCount = SubTable0->NumPhysicalComponents; + Offset += sizeof (ACPI_MPST_POWER_NODE); + + /* Sub-subtables - Memory Power State Structure(s) */ + + SubTable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, SubTable0, + sizeof (ACPI_MPST_POWER_NODE)); + + while (PowerStateCount) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0A, + sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A); + if (ACPI_FAILURE (Status)) + { + return; + } + + SubTable0A++; + PowerStateCount--; + Offset += sizeof (ACPI_MPST_POWER_STATE); + } + + /* Sub-subtables - Physical Component ID Structure(s) */ + + SubTable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, SubTable0A); + + if (ComponentCount) + { + AcpiOsPrintf ("\n"); + } + + while (ComponentCount) + { + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable0B, + sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B); + if (ACPI_FAILURE (Status)) + { + return; + } + + SubTable0B++; + ComponentCount--; + Offset += sizeof (ACPI_MPST_COMPONENT); + } + + /* Point to next Memory Power Node subtable */ + + SubtableCount--; + SubTable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, SubTable0, + sizeof (ACPI_MPST_POWER_NODE) + + (sizeof (ACPI_MPST_POWER_STATE) * SubTable0->NumPowerStates) + + (sizeof (ACPI_MPST_COMPONENT) * SubTable0->NumPhysicalComponents)); + } + + /* Subtable: Count of Memory Power State Characteristic structures */ + + AcpiOsPrintf ("\n"); + SubTable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, SubTable0); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable1, + sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1); + if (ACPI_FAILURE (Status)) + { + return; + } + + SubtableCount = SubTable1->CharacteristicsCount; + Offset += sizeof (ACPI_MPST_DATA_HDR); + + /* Subtable: Memory Power State Characteristics structure(s) */ + + SubTable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, SubTable1, sizeof (ACPI_MPST_DATA_HDR)); + + while ((Offset < Table->Length) && SubtableCount) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable2, + sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2); + if (ACPI_FAILURE (Status)) + { + return; + } + + SubTable2++; + SubtableCount--; + Offset += sizeof (ACPI_MPST_POWER_DATA); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpMsct + * + * PARAMETERS: Table - A MSCT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a MSCT + * + ******************************************************************************/ + +void +AcpiDmDumpMsct ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_MSCT); + ACPI_MSCT_PROXIMITY *SubTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table */ + + Offset += sizeof (ACPI_MSCT_PROXIMITY); + SubTable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, SubTable, sizeof (ACPI_MSCT_PROXIMITY)); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpPcct + * + * PARAMETERS: Table - A PCCT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a PCCT. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpPcct ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_PCCT_SUBSPACE *SubTable; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_PCCT); + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset); + while (Offset < Table->Length) + { + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Header.Length, AcpiDmTableInfoPcct0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table */ + + Offset += SubTable->Header.Length; + SubTable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, SubTable, + SubTable->Header.Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpPmtt + * + * PARAMETERS: Table - A PMTT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a PMTT. This table type consists + * of an open-ended number of subtables. + * + ******************************************************************************/ + +void +AcpiDmDumpPmtt ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_PMTT_HEADER *SubTable; + ACPI_PMTT_HEADER *MemSubTable; + ACPI_PMTT_HEADER *DimmSubTable; + ACPI_PMTT_DOMAIN *DomainArray; + UINT32 Length = Table->Length; + UINT32 Offset = sizeof (ACPI_TABLE_PMTT); + UINT32 MemOffset; + UINT32 DimmOffset; + UINT32 DomainOffset; + UINT32 DomainCount; + + + /* Main table */ + + Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Subtables */ + + SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common subtable header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoPmttHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Only Socket subtables are expected at this level */ + + if (SubTable->Type != ACPI_PMTT_TYPE_SOCKET) + { + AcpiOsPrintf ( + "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n", + SubTable->Type); + return; + } + + /* Dump the fixed-length portion of the subtable */ + + Status = AcpiDmDumpTable (Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoPmtt0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Walk the memory controller subtables */ + + MemOffset = sizeof (ACPI_PMTT_SOCKET); + MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, SubTable, + sizeof (ACPI_PMTT_SOCKET)); + + while (((Offset + MemOffset) < Table->Length) && + (MemOffset < SubTable->Length)) + { + /* Common subtable header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, + Offset + MemOffset, MemSubTable, + MemSubTable->Length, AcpiDmTableInfoPmttHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Only memory controller subtables are expected at this level */ + + if (MemSubTable->Type != ACPI_PMTT_TYPE_CONTROLLER) + { + AcpiOsPrintf ( + "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n", + MemSubTable->Type); + return; + } + + /* Dump the fixed-length portion of the controller subtable */ + + Status = AcpiDmDumpTable (Length, + Offset + MemOffset, MemSubTable, + MemSubTable->Length, AcpiDmTableInfoPmtt1); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Walk the variable count of proximity domains */ + + DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubTable)->DomainCount; + DomainOffset = sizeof (ACPI_PMTT_CONTROLLER); + DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubTable, + sizeof (ACPI_PMTT_CONTROLLER)); + + while (((Offset + MemOffset + DomainOffset) < Table->Length) && + ((MemOffset + DomainOffset) < SubTable->Length) && + DomainCount) + { + Status = AcpiDmDumpTable (Length, + Offset + MemOffset + DomainOffset, DomainArray, + sizeof (ACPI_PMTT_DOMAIN), AcpiDmTableInfoPmtt1a); + if (ACPI_FAILURE (Status)) + { + return; + } + + DomainOffset += sizeof (ACPI_PMTT_DOMAIN); + DomainArray++; + DomainCount--; + } + + if (DomainCount) + { + AcpiOsPrintf ( + "\n**** DomainCount exceeds subtable length\n\n", + MemSubTable->Type); + } + + /* Walk the physical component (DIMM) subtables */ + + DimmOffset = DomainOffset; + DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubTable, + DomainOffset); + + while (((Offset + MemOffset + DimmOffset) < Table->Length) && + (DimmOffset < MemSubTable->Length)) + { + /* Common subtable header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Length, + Offset + MemOffset + DimmOffset, DimmSubTable, + DimmSubTable->Length, AcpiDmTableInfoPmttHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Only DIMM subtables are expected at this level */ + + if (DimmSubTable->Type != ACPI_PMTT_TYPE_DIMM) + { + AcpiOsPrintf ( + "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n", + DimmSubTable->Type); + return; + } + + /* Dump the fixed-length DIMM subtable */ + + Status = AcpiDmDumpTable (Length, + Offset + MemOffset + DimmOffset, DimmSubTable, + DimmSubTable->Length, AcpiDmTableInfoPmtt2); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next DIMM subtable */ + + DimmOffset += DimmSubTable->Length; + DimmSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, + DimmSubTable, DimmSubTable->Length); + } + + /* Point to next Controller subtable */ + + MemOffset += MemSubTable->Length; + MemSubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, + MemSubTable, MemSubTable->Length); + } + + /* Point to next Socket subtable */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, + SubTable, SubTable->Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpS3pt + * + * PARAMETERS: Table - A S3PT table + * + * RETURN: Length of the table + * + * DESCRIPTION: Format the contents of a S3PT + * + ******************************************************************************/ + +UINT32 +AcpiDmDumpS3pt ( + ACPI_TABLE_HEADER *Tables) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_S3PT); + ACPI_S3PT_HEADER *SubTable; + ACPI_DMTABLE_INFO *InfoTable; + ACPI_TABLE_S3PT *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables); + + + /* Main table */ + + Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt); + if (ACPI_FAILURE (Status)) + { + return 0; + } + + SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, S3ptTable, Offset); + while (Offset < S3ptTable->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoS3ptHdr); + if (ACPI_FAILURE (Status)) + { + return 0; + } + + switch (SubTable->Type) + { + case ACPI_S3PT_TYPE_RESUME: + InfoTable = AcpiDmTableInfoS3pt0; + break; + case ACPI_S3PT_TYPE_SUSPEND: + InfoTable = AcpiDmTableInfoS3pt1; + break; + default: + AcpiOsPrintf ("\n**** Unknown S3PT sub-table type 0x%X\n", SubTable->Type); + + /* Attempt to continue */ + + if (!SubTable->Length) + { + AcpiOsPrintf ("Invalid zero length subtable\n"); + return 0; + } + goto NextSubTable; + } + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (S3ptTable->Length, Offset, SubTable, + SubTable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return 0; + } + +NextSubTable: + /* Point to next sub-table */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_S3PT_HEADER, SubTable, SubTable->Length); + } + + return (S3ptTable->Length); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpSlic + * + * PARAMETERS: Table - A SLIC table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a SLIC + * + ******************************************************************************/ + +void +AcpiDmDumpSlic ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_SLIC); + ACPI_SLIC_HEADER *SubTable; + ACPI_DMTABLE_INFO *InfoTable; + + + /* There is no main SLIC table, only subtables */ + + SubTable = ACPI_ADD_PTR (ACPI_SLIC_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoSlicHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (SubTable->Type) + { + case ACPI_SLIC_TYPE_PUBLIC_KEY: + InfoTable = AcpiDmTableInfoSlic0; + break; + case ACPI_SLIC_TYPE_WINDOWS_MARKER: + InfoTable = AcpiDmTableInfoSlic1; + break; + default: + AcpiOsPrintf ("\n**** Unknown SLIC sub-table type 0x%X\n", SubTable->Type); + + /* Attempt to continue */ + + if (!SubTable->Length) + { + AcpiOsPrintf ("Invalid zero length subtable\n"); + return; + } + goto NextSubTable; + } + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + +NextSubTable: + /* Point to next sub-table */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_SLIC_HEADER, SubTable, SubTable->Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpSlit + * + * PARAMETERS: Table - An SLIT + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a SLIT + * + ******************************************************************************/ + +void +AcpiDmDumpSlit ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset; + UINT8 *Row; + UINT32 Localities; + UINT32 i; + UINT32 j; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSlit); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Display the Locality NxN Matrix */ + + Localities = (UINT32) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->LocalityCount; + Offset = ACPI_OFFSET (ACPI_TABLE_SLIT, Entry[0]); + Row = (UINT8 *) ACPI_CAST_PTR (ACPI_TABLE_SLIT, Table)->Entry; + + for (i = 0; i < Localities; i++) + { + /* Display one row of the matrix */ + + AcpiDmLineHeader2 (Offset, Localities, "Locality", i); + for (j = 0; j < Localities; j++) + { + /* Check for beyond EOT */ + + if (Offset >= Table->Length) + { + AcpiOsPrintf ("\n**** Not enough room in table for all localities\n"); + return; + } + + AcpiOsPrintf ("%2.2X", Row[j]); + Offset++; + + /* Display up to 16 bytes per output row */ + + if ((j+1) < Localities) + { + AcpiOsPrintf (" "); + + if (j && (((j+1) % 16) == 0)) + { + AcpiOsPrintf ("\\\n"); /* With line continuation char */ + AcpiDmLineHeader (Offset, 0, NULL); + } + } + } + + /* Point to next row */ + + AcpiOsPrintf ("\n"); + Row += Localities; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpSrat + * + * PARAMETERS: Table - A SRAT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a SRAT + * + ******************************************************************************/ + +void +AcpiDmDumpSrat ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_SRAT); + ACPI_SUBTABLE_HEADER *SubTable; + ACPI_DMTABLE_INFO *InfoTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoSrat); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Length, AcpiDmTableInfoSratHdr); + if (ACPI_FAILURE (Status)) + { + return; + } + + switch (SubTable->Type) + { + case ACPI_SRAT_TYPE_CPU_AFFINITY: + InfoTable = AcpiDmTableInfoSrat0; + break; + case ACPI_SRAT_TYPE_MEMORY_AFFINITY: + InfoTable = AcpiDmTableInfoSrat1; + break; + case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: + InfoTable = AcpiDmTableInfoSrat2; + break; + default: + AcpiOsPrintf ("\n**** Unknown SRAT sub-table type 0x%X\n", SubTable->Type); + + /* Attempt to continue */ + + if (!SubTable->Length) + { + AcpiOsPrintf ("Invalid zero length subtable\n"); + return; + } + goto NextSubTable; + } + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + SubTable->Length, InfoTable); + if (ACPI_FAILURE (Status)) + { + return; + } + +NextSubTable: + /* Point to next sub-table */ + + Offset += SubTable->Length; + SubTable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, SubTable, SubTable->Length); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDmDumpWdat + * + * PARAMETERS: Table - A WDAT table + * + * RETURN: None + * + * DESCRIPTION: Format the contents of a WDAT + * + ******************************************************************************/ + +void +AcpiDmDumpWdat ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + UINT32 Offset = sizeof (ACPI_TABLE_WDAT); + ACPI_WDAT_ENTRY *SubTable; + + + /* Main table */ + + Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoWdat); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Sub-tables */ + + SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, Table, Offset); + while (Offset < Table->Length) + { + /* Common sub-table header */ + + AcpiOsPrintf ("\n"); + Status = AcpiDmDumpTable (Table->Length, Offset, SubTable, + sizeof (ACPI_WDAT_ENTRY), AcpiDmTableInfoWdat0); + if (ACPI_FAILURE (Status)) + { + return; + } + + /* Point to next sub-table */ + + Offset += sizeof (ACPI_WDAT_ENTRY); + SubTable = ACPI_ADD_PTR (ACPI_WDAT_ENTRY, SubTable, sizeof (ACPI_WDAT_ENTRY)); + } +} diff --git a/source/common/dmtbinfo.c b/source/common/dmtbinfo.c new file mode 100644 index 0000000000000..4600a0aa53d30 --- /dev/null +++ b/source/common/dmtbinfo.c @@ -0,0 +1,2065 @@ +/****************************************************************************** + * + * Module Name: dmtbinfo - Table info for non-AML tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" +#include "acdisasm.h" + +/* This module used for application-level code only */ + +#define _COMPONENT ACPI_CA_DISASSEMBLER + ACPI_MODULE_NAME ("dmtbinfo") + +/* + * How to add a new table: + * + * - Add the C table definition to the actbl1.h or actbl2.h header. + * - Add ACPI_xxxx_OFFSET macro(s) for the table (and subtables) to list below. + * - Define the table in this file (for the disassembler). If any + * new data types are required (ACPI_DMT_*), see below. + * - Add an external declaration for the new table definition (AcpiDmTableInfo*) + * in acdisam.h + * - Add new table definition to the dispatch table in dmtable.c (AcpiDmTableData) + * If a simple table (with no subtables), no disassembly code is needed. + * Otherwise, create the AcpiDmDump* function for to disassemble the table + * and add it to the dmtbdump.c file. + * - Add an external declaration for the new AcpiDmDump* function in acdisasm.h + * - Add the new AcpiDmDump* function to the dispatch table in dmtable.c + * - Create a template for the new table + * - Add data table compiler support + * + * How to add a new data type (ACPI_DMT_*): + * + * - Add new type at the end of the ACPI_DMT list in acdisasm.h + * - Add length and implementation cases in dmtable.c (disassembler) + * - Add type and length cases in dtutils.c (DT compiler) + */ + +/* + * Macros used to generate offsets to specific table fields + */ +#define ACPI_FACS_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_FACS,f) +#define ACPI_GAS_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_GENERIC_ADDRESS,f) +#define ACPI_HDR_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_HEADER,f) +#define ACPI_RSDP_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_RSDP,f) +#define ACPI_BERT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_BERT,f) +#define ACPI_BGRT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_BGRT,f) +#define ACPI_BOOT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_BOOT,f) +#define ACPI_CPEP_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_CPEP,f) +#define ACPI_DBGP_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_DBGP,f) +#define ACPI_DMAR_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_DMAR,f) +#define ACPI_DRTM_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_DRTM,f) +#define ACPI_ECDT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_ECDT,f) +#define ACPI_EINJ_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_EINJ,f) +#define ACPI_ERST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_ERST,f) +#define ACPI_GTDT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_GTDT,f) +#define ACPI_HEST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_HEST,f) +#define ACPI_HPET_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_HPET,f) +#define ACPI_IVRS_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_IVRS,f) +#define ACPI_MADT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MADT,f) +#define ACPI_MCFG_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MCFG,f) +#define ACPI_MCHI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MCHI,f) +#define ACPI_MPST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MPST,f) +#define ACPI_MSCT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_MSCT,f) +#define ACPI_PCCT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PCCT,f) +#define ACPI_PMTT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_PMTT,f) +#define ACPI_S3PT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_S3PT,f) +#define ACPI_SBST_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SBST,f) +#define ACPI_SLIT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SLIT,f) +#define ACPI_SPCR_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPCR,f) +#define ACPI_SPMI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SPMI,f) +#define ACPI_SRAT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_SRAT,f) +#define ACPI_TCPA_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_TCPA,f) +#define ACPI_UEFI_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_UEFI,f) +#define ACPI_WAET_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WAET,f) +#define ACPI_WDAT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WDAT,f) +#define ACPI_WDDT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WDDT,f) +#define ACPI_WDRT_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_TABLE_WDRT,f) + +/* Subtables */ + +#define ACPI_ASF0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_INFO,f) +#define ACPI_ASF1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_ALERT,f) +#define ACPI_ASF1a_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_ALERT_DATA,f) +#define ACPI_ASF2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_REMOTE,f) +#define ACPI_ASF2a_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_CONTROL_DATA,f) +#define ACPI_ASF3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_RMCP,f) +#define ACPI_ASF4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_ASF_ADDRESS,f) +#define ACPI_CPEP0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_CPEP_POLLING,f) +#define ACPI_DMARS_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_DEVICE_SCOPE,f) +#define ACPI_DMAR0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_HARDWARE_UNIT,f) +#define ACPI_DMAR1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_RESERVED_MEMORY,f) +#define ACPI_DMAR2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_ATSR,f) +#define ACPI_DMAR3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_DMAR_RHSA,f) +#define ACPI_EINJ0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_WHEA_HEADER,f) +#define ACPI_ERST0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_WHEA_HEADER,f) +#define ACPI_FPDTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_FPDT_HEADER,f) +#define ACPI_FPDT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_FPDT_BOOT,f) +#define ACPI_FPDT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_FPDT_S3PT_PTR,f) +#define ACPI_HEST0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_IA_MACHINE_CHECK,f) +#define ACPI_HEST1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_IA_CORRECTED,f) +#define ACPI_HEST2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_IA_NMI,f) +#define ACPI_HEST6_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_AER_ROOT,f) +#define ACPI_HEST7_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_AER,f) +#define ACPI_HEST8_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_AER_BRIDGE,f) +#define ACPI_HEST9_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_GENERIC,f) +#define ACPI_HESTN_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_NOTIFY,f) +#define ACPI_HESTB_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_HEST_IA_ERROR_BANK,f) +#define ACPI_IVRSH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_HEADER,f) +#define ACPI_IVRS0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_HARDWARE,f) +#define ACPI_IVRS1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_MEMORY,f) +#define ACPI_IVRSD_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_DE_HEADER,f) +#define ACPI_IVRS8A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_DEVICE8A,f) +#define ACPI_IVRS8B_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_DEVICE8B,f) +#define ACPI_IVRS8C_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_IVRS_DEVICE8C,f) +#define ACPI_MADT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_APIC,f) +#define ACPI_MADT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_IO_APIC,f) +#define ACPI_MADT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_INTERRUPT_OVERRIDE,f) +#define ACPI_MADT3_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_NMI_SOURCE,f) +#define ACPI_MADT4_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_APIC_NMI,f) +#define ACPI_MADT5_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_APIC_OVERRIDE,f) +#define ACPI_MADT6_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_IO_SAPIC,f) +#define ACPI_MADT7_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_SAPIC,f) +#define ACPI_MADT8_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_INTERRUPT_SOURCE,f) +#define ACPI_MADT9_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_X2APIC,f) +#define ACPI_MADT10_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_LOCAL_X2APIC_NMI,f) +#define ACPI_MADT11_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_GENERIC_INTERRUPT,f) +#define ACPI_MADT12_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MADT_GENERIC_DISTRIBUTOR,f) +#define ACPI_MADTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f) +#define ACPI_MCFG0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MCFG_ALLOCATION,f) +#define ACPI_MPST0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_POWER_NODE,f) +#define ACPI_MPST0A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_POWER_STATE,f) +#define ACPI_MPST0B_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_COMPONENT,f) +#define ACPI_MPST1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_DATA_HDR,f) +#define ACPI_MPST2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MPST_POWER_DATA,f) +#define ACPI_MSCT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_MSCT_PROXIMITY,f) +#define ACPI_PCCT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PCCT_SUBSPACE,f) +#define ACPI_PMTT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_SOCKET,f) +#define ACPI_PMTT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_CONTROLLER,f) +#define ACPI_PMTT1A_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_DOMAIN,f) +#define ACPI_PMTT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_PHYSICAL_COMPONENT,f) +#define ACPI_PMTTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_PMTT_HEADER,f) +#define ACPI_S3PTH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_HEADER,f) +#define ACPI_S3PT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_RESUME,f) +#define ACPI_S3PT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_S3PT_SUSPEND,f) +#define ACPI_SLICH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SLIC_HEADER,f) +#define ACPI_SLIC0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SLIC_KEY,f) +#define ACPI_SLIC1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SLIC_MARKER,f) +#define ACPI_SRATH_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SUBTABLE_HEADER,f) +#define ACPI_SRAT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_CPU_AFFINITY,f) +#define ACPI_SRAT1_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_MEM_AFFINITY,f) +#define ACPI_SRAT2_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_SRAT_X2APIC_CPU_AFFINITY,f) +#define ACPI_WDAT0_OFFSET(f) (UINT16) ACPI_OFFSET (ACPI_WDAT_ENTRY,f) + +/* + * Simplify access to flag fields by breaking them up into bytes + */ +#define ACPI_FLAG_OFFSET(d,f,o) (UINT16) (ACPI_OFFSET (d,f) + o) + +/* Flags */ + +#define ACPI_FADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_FADT,f,o) +#define ACPI_FACS_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_FACS,f,o) +#define ACPI_HPET_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_HPET,f,o) +#define ACPI_SRAT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_CPU_AFFINITY,f,o) +#define ACPI_SRAT1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_MEM_AFFINITY,f,o) +#define ACPI_SRAT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_SRAT_X2APIC_CPU_AFFINITY,f,o) +#define ACPI_GTDT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_GTDT,f,o) +#define ACPI_MADT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_MADT,f,o) +#define ACPI_MADT0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_APIC,f,o) +#define ACPI_MADT2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_INTERRUPT_OVERRIDE,f,o) +#define ACPI_MADT3_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_NMI_SOURCE,f,o) +#define ACPI_MADT4_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_APIC_NMI,f,o) +#define ACPI_MADT7_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_SAPIC,f,o) +#define ACPI_MADT8_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_INTERRUPT_SOURCE,f,o) +#define ACPI_MADT9_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_X2APIC,f,o) +#define ACPI_MADT10_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_LOCAL_X2APIC_NMI,f,o) +#define ACPI_MADT11_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MADT_GENERIC_INTERRUPT,f,o) +#define ACPI_MPST0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MPST_POWER_NODE,f,o) +#define ACPI_MPST2_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_MPST_POWER_DATA,f,o) +#define ACPI_PCCT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_PCCT,f,o) +#define ACPI_PMTTH_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_PMTT_HEADER,f,o) +#define ACPI_WDDT_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_TABLE_WDDT,f,o) +#define ACPI_EINJ0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_WHEA_HEADER,f,o) +#define ACPI_ERST0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_WHEA_HEADER,f,o) +#define ACPI_HEST0_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_HEST_IA_MACHINE_CHECK,f,o) +#define ACPI_HEST1_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_HEST_IA_CORRECTED,f,o) +#define ACPI_HEST6_FLAG_OFFSET(f,o) ACPI_FLAG_OFFSET (ACPI_HEST_AER_ROOT,f,o) + +/* + * Required terminator for all tables below + */ +#define ACPI_DMT_TERMINATOR {ACPI_DMT_EXIT, 0, NULL, 0} +#define ACPI_DMT_NEW_LINE {ACPI_DMT_EXTRA_TEXT, 0, "\n", 0} + + +/* + * ACPI Table Information, used to dump formatted ACPI tables + * + * Each entry is of the form: <Field Type, Field Offset, Field Name> + */ + +/******************************************************************************* + * + * Common ACPI table header + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHeader[] = +{ + {ACPI_DMT_SIG, ACPI_HDR_OFFSET (Signature[0]), "Signature", 0}, + {ACPI_DMT_UINT32, ACPI_HDR_OFFSET (Length), "Table Length", DT_LENGTH}, + {ACPI_DMT_UINT8, ACPI_HDR_OFFSET (Revision), "Revision", 0}, + {ACPI_DMT_CHKSUM, ACPI_HDR_OFFSET (Checksum), "Checksum", 0}, + {ACPI_DMT_NAME6, ACPI_HDR_OFFSET (OemId[0]), "Oem ID", 0}, + {ACPI_DMT_NAME8, ACPI_HDR_OFFSET (OemTableId[0]), "Oem Table ID", 0}, + {ACPI_DMT_UINT32, ACPI_HDR_OFFSET (OemRevision), "Oem Revision", 0}, + {ACPI_DMT_NAME4, ACPI_HDR_OFFSET (AslCompilerId[0]), "Asl Compiler ID", 0}, + {ACPI_DMT_UINT32, ACPI_HDR_OFFSET (AslCompilerRevision), "Asl Compiler Revision", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * GAS - Generic Address Structure + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoGas[] = +{ + {ACPI_DMT_SPACEID, ACPI_GAS_OFFSET (SpaceId), "Space ID", 0}, + {ACPI_DMT_UINT8, ACPI_GAS_OFFSET (BitWidth), "Bit Width", 0}, + {ACPI_DMT_UINT8, ACPI_GAS_OFFSET (BitOffset), "Bit Offset", 0}, + {ACPI_DMT_ACCWIDTH, ACPI_GAS_OFFSET (AccessWidth), "Encoded Access Width", 0}, + {ACPI_DMT_UINT64, ACPI_GAS_OFFSET (Address), "Address", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * RSDP - Root System Description Pointer (Signature is "RSD PTR ") + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp1[] = +{ + {ACPI_DMT_NAME8, ACPI_RSDP_OFFSET (Signature[0]), "Signature", 0}, + {ACPI_DMT_UINT8, ACPI_RSDP_OFFSET (Checksum), "Checksum", 0}, + {ACPI_DMT_NAME6, ACPI_RSDP_OFFSET (OemId[0]), "Oem ID", 0}, + {ACPI_DMT_UINT8, ACPI_RSDP_OFFSET (Revision), "Revision", 0}, + {ACPI_DMT_UINT32, ACPI_RSDP_OFFSET (RsdtPhysicalAddress), "RSDT Address", 0}, + ACPI_DMT_TERMINATOR +}; + +/* ACPI 2.0+ Extensions */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoRsdp2[] = +{ + {ACPI_DMT_UINT32, ACPI_RSDP_OFFSET (Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT64, ACPI_RSDP_OFFSET (XsdtPhysicalAddress), "XSDT Address", 0}, + {ACPI_DMT_UINT8, ACPI_RSDP_OFFSET (ExtendedChecksum), "Extended Checksum", 0}, + {ACPI_DMT_UINT24, ACPI_RSDP_OFFSET (Reserved[0]), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * FACS - Firmware ACPI Control Structure + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoFacs[] = +{ + {ACPI_DMT_NAME4, ACPI_FACS_OFFSET (Signature[0]), "Signature", 0}, + {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (HardwareSignature), "Hardware Signature", 0}, + {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (FirmwareWakingVector), "32 Firmware Waking Vector", 0}, + {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (GlobalLock), "Global Lock", 0}, + {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_FACS_FLAG_OFFSET (Flags,0), "S4BIOS Support Present", 0}, + {ACPI_DMT_FLAG1, ACPI_FACS_FLAG_OFFSET (Flags,0), "64-bit Wake Supported (V2)", 0}, + {ACPI_DMT_UINT64, ACPI_FACS_OFFSET (XFirmwareWakingVector), "64 Firmware Waking Vector", 0}, + {ACPI_DMT_UINT8, ACPI_FACS_OFFSET (Version), "Version", 0}, + {ACPI_DMT_UINT24, ACPI_FACS_OFFSET (Reserved[0]), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_FACS_OFFSET (OspmFlags), "OspmFlags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_FACS_FLAG_OFFSET (OspmFlags,0), "64-bit Wake Env Required (V2)", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * FADT - Fixed ACPI Description Table (Signature is FACP) + * + ******************************************************************************/ + +/* ACPI 1.0 FADT (Version 1) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoFadt1[] = +{ + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Facs), "FACS Address", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Dsdt), "DSDT Address", DT_NON_ZERO}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Model), "Model", 0}, + {ACPI_DMT_FADTPM, ACPI_FADT_OFFSET (PreferredProfile), "PM Profile", 0}, + {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (SciInterrupt), "SCI Interrupt", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (SmiCommand), "SMI Command Port", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (AcpiEnable), "ACPI Enable Value", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (AcpiDisable), "ACPI Disable Value", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (S4BiosRequest), "S4BIOS Command", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (PstateControl), "P-State Control", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm1aEventBlock), "PM1A Event Block Address", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm1bEventBlock), "PM1B Event Block Address", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm1aControlBlock), "PM1A Control Block Address", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm1bControlBlock), "PM1B Control Block Address", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Pm2ControlBlock), "PM2 Control Block Address", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (PmTimerBlock), "PM Timer Block Address", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Gpe0Block), "GPE0 Block Address", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Gpe1Block), "GPE1 Block Address", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Pm1EventLength), "PM1 Event Block Length", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Pm1ControlLength), "PM1 Control Block Length", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Pm2ControlLength), "PM2 Control Block Length", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (PmTimerLength), "PM Timer Block Length", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Gpe0BlockLength), "GPE0 Block Length", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Gpe1BlockLength), "GPE1 Block Length", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Gpe1Base), "GPE1 Base Offset", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (CstControl), "_CST Support", 0}, + {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (C2Latency), "C2 Latency", 0}, + {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (C3Latency), "C3 Latency", 0}, + {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (FlushSize), "CPU Cache Size", 0}, + {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (FlushStride), "Cache Flush Stride", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (DutyOffset), "Duty Cycle Offset", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (DutyWidth), "Duty Cycle Width", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (DayAlarm), "RTC Day Alarm Index", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (MonthAlarm), "RTC Month Alarm Index", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Century), "RTC Century Index", 0}, + {ACPI_DMT_UINT16, ACPI_FADT_OFFSET (BootFlags), "Boot Flags (decoded below)", DT_FLAG}, + + /* Boot Architecture Flags byte 0 */ + + {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "Legacy Devices Supported (V2)", 0}, + {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "8042 Present on ports 60/64 (V2)", 0}, + {ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "VGA Not Present (V4)", 0}, + {ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "MSI Not Supported (V4)", 0}, + {ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "PCIe ASPM Not Supported (V4)", 0}, + {ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (BootFlags,0), "CMOS RTC Not Present (V5)", 0}, + + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_FADT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + + /* Flags byte 0 */ + + {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET (Flags,0), "WBINVD instruction is operational (V1)", 0}, + {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (Flags,0), "WBINVD flushes all caches (V1)", 0}, + {ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (Flags,0), "All CPUs support C1 (V1)", 0}, + {ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (Flags,0), "C2 works on MP system (V1)", 0}, + {ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (Flags,0), "Control Method Power Button (V1)", 0}, + {ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (Flags,0), "Control Method Sleep Button (V1)", 0}, + {ACPI_DMT_FLAG6, ACPI_FADT_FLAG_OFFSET (Flags,0), "RTC wake not in fixed reg space (V1)", 0}, + {ACPI_DMT_FLAG7, ACPI_FADT_FLAG_OFFSET (Flags,0), "RTC can wake system from S4 (V1)", 0}, + + /* Flags byte 1 */ + + {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET (Flags,1), "32-bit PM Timer (V1)", 0}, + {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (Flags,1), "Docking Supported (V1)", 0}, + {ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (Flags,1), "Reset Register Supported (V2)", 0}, + {ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (Flags,1), "Sealed Case (V3)", 0}, + {ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (Flags,1), "Headless - No Video (V3)", 0}, + {ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (Flags,1), "Use native instr after SLP_TYPx (V3)", 0}, + {ACPI_DMT_FLAG6, ACPI_FADT_FLAG_OFFSET (Flags,1), "PCIEXP_WAK Bits Supported (V4)", 0}, + {ACPI_DMT_FLAG7, ACPI_FADT_FLAG_OFFSET (Flags,1), "Use Platform Timer (V4)", 0}, + + /* Flags byte 2 */ + + {ACPI_DMT_FLAG0, ACPI_FADT_FLAG_OFFSET (Flags,2), "RTC_STS valid on S4 wake (V4)", 0}, + {ACPI_DMT_FLAG1, ACPI_FADT_FLAG_OFFSET (Flags,2), "Remote Power-on capable (V4)", 0}, + {ACPI_DMT_FLAG2, ACPI_FADT_FLAG_OFFSET (Flags,2), "Use APIC Cluster Model (V4)", 0}, + {ACPI_DMT_FLAG3, ACPI_FADT_FLAG_OFFSET (Flags,2), "Use APIC Physical Destination Mode (V4)", 0}, + {ACPI_DMT_FLAG4, ACPI_FADT_FLAG_OFFSET (Flags,2), "Hardware Reduced (V5)", 0}, + {ACPI_DMT_FLAG5, ACPI_FADT_FLAG_OFFSET (Flags,2), "Low Power S0 Idle (V5)", 0}, + ACPI_DMT_TERMINATOR +}; + +/* ACPI 1.0 MS Extensions (FADT version 2) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoFadt2[] = +{ + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (ResetRegister), "Reset Register", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (ResetValue), "Value to cause reset", 0}, + {ACPI_DMT_UINT24, ACPI_FADT_OFFSET (Reserved4[0]), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* ACPI 2.0+ Extensions (FADT version 3 and 4) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoFadt3[] = +{ + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (ResetRegister), "Reset Register", 0}, + {ACPI_DMT_UINT8, ACPI_FADT_OFFSET (ResetValue), "Value to cause reset", 0}, + {ACPI_DMT_UINT24, ACPI_FADT_OFFSET (Reserved4[0]), "Reserved", 0}, + {ACPI_DMT_UINT64, ACPI_FADT_OFFSET (XFacs), "FACS Address", 0}, + {ACPI_DMT_UINT64, ACPI_FADT_OFFSET (XDsdt), "DSDT Address", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm1aEventBlock), "PM1A Event Block", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm1bEventBlock), "PM1B Event Block", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm1aControlBlock), "PM1A Control Block", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm1bControlBlock), "PM1B Control Block", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPm2ControlBlock), "PM2 Control Block", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XPmTimerBlock), "PM Timer Block", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XGpe0Block), "GPE0 Block", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (XGpe1Block), "GPE1 Block", 0}, + ACPI_DMT_TERMINATOR +}; + +/* ACPI 5.0 Extensions (FADT version 5) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoFadt5[] = +{ + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (SleepControl), "Sleep Control Register", 0}, + {ACPI_DMT_GAS, ACPI_FADT_OFFSET (SleepStatus), "Sleep Status Register", 0}, + ACPI_DMT_TERMINATOR +}; + + +/* + * Remaining tables are not consumed directly by the ACPICA subsystem + */ + +/******************************************************************************* + * + * ASF - Alert Standard Format table (Signature "ASF!") + * + ******************************************************************************/ + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoAsfHdr[] = +{ + {ACPI_DMT_ASF, ACPI_ASF0_OFFSET (Header.Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (Header.Reserved), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_ASF0_OFFSET (Header.Length), "Length", DT_LENGTH}, + ACPI_DMT_TERMINATOR +}; + +/* 0: ASF Information */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoAsf0[] = +{ + {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (MinResetValue), "Minimum Reset Value", 0}, + {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (MinPollInterval), "Minimum Polling Interval", 0}, + {ACPI_DMT_UINT16, ACPI_ASF0_OFFSET (SystemId), "System ID", 0}, + {ACPI_DMT_UINT32, ACPI_ASF0_OFFSET (MfgId), "Manufacturer ID", 0}, + {ACPI_DMT_UINT8, ACPI_ASF0_OFFSET (Flags), "Flags", 0}, + {ACPI_DMT_UINT24, ACPI_ASF0_OFFSET (Reserved2[0]), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: ASF Alerts */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoAsf1[] = +{ + {ACPI_DMT_UINT8, ACPI_ASF1_OFFSET (AssertMask), "AssertMask", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1_OFFSET (DeassertMask), "DeassertMask", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1_OFFSET (Alerts), "Alert Count", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1_OFFSET (DataLength), "Alert Data Length", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1a: ASF Alert data */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoAsf1a[] = +{ + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Address), "Address", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Command), "Command", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Mask), "Mask", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Value), "Value", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (SensorType), "SensorType", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Type), "Type", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Offset), "Offset", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (SourceType), "SourceType", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Severity), "Severity", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (SensorNumber), "SensorNumber", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Entity), "Entity", 0}, + {ACPI_DMT_UINT8, ACPI_ASF1a_OFFSET (Instance), "Instance", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 2: ASF Remote Control */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoAsf2[] = +{ + {ACPI_DMT_UINT8, ACPI_ASF2_OFFSET (Controls), "Control Count", 0}, + {ACPI_DMT_UINT8, ACPI_ASF2_OFFSET (DataLength), "Control Data Length", 0}, + {ACPI_DMT_UINT16, ACPI_ASF2_OFFSET (Reserved2), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 2a: ASF Control data */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoAsf2a[] = +{ + {ACPI_DMT_UINT8, ACPI_ASF2a_OFFSET (Function), "Function", 0}, + {ACPI_DMT_UINT8, ACPI_ASF2a_OFFSET (Address), "Address", 0}, + {ACPI_DMT_UINT8, ACPI_ASF2a_OFFSET (Command), "Command", 0}, + {ACPI_DMT_UINT8, ACPI_ASF2a_OFFSET (Value), "Value", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 3: ASF RMCP Boot Options */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoAsf3[] = +{ + {ACPI_DMT_BUF7, ACPI_ASF3_OFFSET (Capabilities[0]), "Capabilities", 0}, + {ACPI_DMT_UINT8, ACPI_ASF3_OFFSET (CompletionCode), "Completion Code", 0}, + {ACPI_DMT_UINT32, ACPI_ASF3_OFFSET (EnterpriseId), "Enterprise ID", 0}, + {ACPI_DMT_UINT8, ACPI_ASF3_OFFSET (Command), "Command", 0}, + {ACPI_DMT_UINT16, ACPI_ASF3_OFFSET (Parameter), "Parameter", 0}, + {ACPI_DMT_UINT16, ACPI_ASF3_OFFSET (BootOptions), "Boot Options", 0}, + {ACPI_DMT_UINT16, ACPI_ASF3_OFFSET (OemParameters), "Oem Parameters", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 4: ASF Address */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoAsf4[] = +{ + {ACPI_DMT_UINT8, ACPI_ASF4_OFFSET (EpromAddress), "Eprom Address", 0}, + {ACPI_DMT_UINT8, ACPI_ASF4_OFFSET (Devices), "Device Count", DT_COUNT}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * BERT - Boot Error Record table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoBert[] = +{ + {ACPI_DMT_UINT32, ACPI_BERT_OFFSET (RegionLength), "Boot Error Region Length", 0}, + {ACPI_DMT_UINT64, ACPI_BERT_OFFSET (Address), "Boot Error Region Address", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * BGRT - Boot Graphics Resource Table (ACPI 5.0) + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoBgrt[] = +{ + {ACPI_DMT_UINT16, ACPI_BGRT_OFFSET (Version), "Version", 0}, + {ACPI_DMT_UINT8, ACPI_BGRT_OFFSET (Status), "Status", 0}, + {ACPI_DMT_UINT8, ACPI_BGRT_OFFSET (ImageType), "Image Type", 0}, + {ACPI_DMT_UINT64, ACPI_BGRT_OFFSET (ImageAddress), "Image Address", 0}, + {ACPI_DMT_UINT32, ACPI_BGRT_OFFSET (ImageOffsetX), "Image OffsetX", 0}, + {ACPI_DMT_UINT32, ACPI_BGRT_OFFSET (ImageOffsetY), "Image OffsetY", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * BOOT - Simple Boot Flag Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoBoot[] = +{ + {ACPI_DMT_UINT8, ACPI_BOOT_OFFSET (CmosIndex), "Boot Register Index", 0}, + {ACPI_DMT_UINT24, ACPI_BOOT_OFFSET (Reserved[0]), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * CPEP - Corrected Platform Error Polling table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoCpep[] = +{ + {ACPI_DMT_UINT64, ACPI_CPEP_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoCpep0[] = +{ + {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Header.Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Header.Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Id), "Processor ID", 0}, + {ACPI_DMT_UINT8, ACPI_CPEP0_OFFSET (Eid), "Processor EID", 0}, + {ACPI_DMT_UINT32, ACPI_CPEP0_OFFSET (Interval), "Polling Interval", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * DBGP - Debug Port + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDbgp[] = +{ + {ACPI_DMT_UINT8, ACPI_DBGP_OFFSET (Type), "Interface Type", 0}, + {ACPI_DMT_UINT24, ACPI_DBGP_OFFSET (Reserved[0]), "Reserved", 0}, + {ACPI_DMT_GAS, ACPI_DBGP_OFFSET (DebugPort), "Debug Port Register", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * DMAR - DMA Remapping table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDmar[] = +{ + {ACPI_DMT_UINT8, ACPI_DMAR_OFFSET (Width), "Host Address Width", 0}, + {ACPI_DMT_UINT8, ACPI_DMAR_OFFSET (Flags), "Flags", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDmarHdr[] = +{ + {ACPI_DMT_DMAR, ACPI_DMAR0_OFFSET (Header.Type), "Subtable Type", 0}, + {ACPI_DMT_UINT16, ACPI_DMAR0_OFFSET (Header.Length), "Length", DT_LENGTH}, + ACPI_DMT_TERMINATOR +}; + +/* Common device scope entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDmarScope[] = +{ + {ACPI_DMT_UINT8, ACPI_DMARS_OFFSET (EntryType), "Device Scope Entry Type", 0}, + {ACPI_DMT_UINT8, ACPI_DMARS_OFFSET (Length), "Entry Length", DT_LENGTH}, + {ACPI_DMT_UINT16, ACPI_DMARS_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT8, ACPI_DMARS_OFFSET (EnumerationId), "Enumeration ID", 0}, + {ACPI_DMT_UINT8, ACPI_DMARS_OFFSET (Bus), "PCI Bus Number", 0}, + ACPI_DMT_TERMINATOR +}; + +/* DMAR Subtables */ + +/* 0: Hardware Unit Definition */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDmar0[] = +{ + {ACPI_DMT_UINT8, ACPI_DMAR0_OFFSET (Flags), "Flags", 0}, + {ACPI_DMT_UINT8, ACPI_DMAR0_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_DMAR0_OFFSET (Segment), "PCI Segment Number", 0}, + {ACPI_DMT_UINT64, ACPI_DMAR0_OFFSET (Address), "Register Base Address", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: Reserved Memory Definition */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDmar1[] = +{ + {ACPI_DMT_UINT16, ACPI_DMAR1_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_DMAR1_OFFSET (Segment), "PCI Segment Number", 0}, + {ACPI_DMT_UINT64, ACPI_DMAR1_OFFSET (BaseAddress), "Base Address", 0}, + {ACPI_DMT_UINT64, ACPI_DMAR1_OFFSET (EndAddress), "End Address (limit)", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 2: Root Port ATS Capability Definition */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDmar2[] = +{ + {ACPI_DMT_UINT8, ACPI_DMAR2_OFFSET (Flags), "Flags", 0}, + {ACPI_DMT_UINT8, ACPI_DMAR2_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_DMAR2_OFFSET (Segment), "PCI Segment Number", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 3: Remapping Hardware Static Affinity Structure */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDmar3[] = +{ + {ACPI_DMT_UINT32, ACPI_DMAR3_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT64, ACPI_DMAR3_OFFSET (BaseAddress), "Base Address", 0}, + {ACPI_DMT_UINT32, ACPI_DMAR3_OFFSET (ProximityDomain), "Proximity Domain", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * DRTM - Dynamic Root of Trust for Measurement table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoDrtm[] = +{ + + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * ECDT - Embedded Controller Boot Resources Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoEcdt[] = +{ + {ACPI_DMT_GAS, ACPI_ECDT_OFFSET (Control), "Command/Status Register", 0}, + {ACPI_DMT_GAS, ACPI_ECDT_OFFSET (Data), "Data Register", 0}, + {ACPI_DMT_UINT32, ACPI_ECDT_OFFSET (Uid), "UID", 0}, + {ACPI_DMT_UINT8, ACPI_ECDT_OFFSET (Gpe), "GPE Number", 0}, + {ACPI_DMT_STRING, ACPI_ECDT_OFFSET (Id[0]), "Namepath", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * EINJ - Error Injection table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoEinj[] = +{ + {ACPI_DMT_UINT32, ACPI_EINJ_OFFSET (HeaderLength), "Injection Header Length", 0}, + {ACPI_DMT_UINT8, ACPI_EINJ_OFFSET (Flags), "Flags", 0}, + {ACPI_DMT_UINT24, ACPI_EINJ_OFFSET (Reserved[0]), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_EINJ_OFFSET (Entries), "Injection Entry Count", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoEinj0[] = +{ + {ACPI_DMT_EINJACT, ACPI_EINJ0_OFFSET (Action), "Action", 0}, + {ACPI_DMT_EINJINST, ACPI_EINJ0_OFFSET (Instruction), "Instruction", 0}, + {ACPI_DMT_UINT8, ACPI_EINJ0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_EINJ0_FLAG_OFFSET (Flags,0), "Preserve Register Bits", 0}, + + {ACPI_DMT_UINT8, ACPI_EINJ0_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_GAS, ACPI_EINJ0_OFFSET (RegisterRegion), "Register Region", 0}, + {ACPI_DMT_UINT64, ACPI_EINJ0_OFFSET (Value), "Value", 0}, + {ACPI_DMT_UINT64, ACPI_EINJ0_OFFSET (Mask), "Mask", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * ERST - Error Record Serialization table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoErst[] = +{ + {ACPI_DMT_UINT32, ACPI_ERST_OFFSET (HeaderLength), "Serialization Header Length", 0}, + {ACPI_DMT_UINT32, ACPI_ERST_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_ERST_OFFSET (Entries), "Instruction Entry Count", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoErst0[] = +{ + {ACPI_DMT_ERSTACT, ACPI_ERST0_OFFSET (Action), "Action", 0}, + {ACPI_DMT_ERSTINST, ACPI_ERST0_OFFSET (Instruction), "Instruction", 0}, + {ACPI_DMT_UINT8, ACPI_ERST0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_ERST0_FLAG_OFFSET (Flags,0), "Preserve Register Bits", 0}, + + {ACPI_DMT_UINT8, ACPI_ERST0_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_GAS, ACPI_ERST0_OFFSET (RegisterRegion), "Register Region", 0}, + {ACPI_DMT_UINT64, ACPI_ERST0_OFFSET (Value), "Value", 0}, + {ACPI_DMT_UINT64, ACPI_ERST0_OFFSET (Mask), "Mask", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * FPDT - Firmware Performance Data Table (ACPI 5.0) + * + ******************************************************************************/ + +/* Main table consists of only the standard ACPI header - subtables follow */ + +/* FPDT subtable header */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoFpdtHdr[] = +{ + {ACPI_DMT_UINT16, ACPI_FPDTH_OFFSET (Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_FPDTH_OFFSET (Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT8, ACPI_FPDTH_OFFSET (Revision), "Revision", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 0: Firmware Basic Boot Performance Record */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt0[] = +{ + {ACPI_DMT_UINT32, ACPI_FPDT0_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ResetEnd), "Reset End", 0}, + {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (LoadStart), "Load Image Start", 0}, + {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (StartupStart), "Start Image Start", 0}, + {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ExitServicesEntry), "Exit Services Entry", 0}, + {ACPI_DMT_UINT64, ACPI_FPDT0_OFFSET (ExitServicesExit), "Exit Services Exit", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: S3 Performance Table Pointer Record */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoFpdt1[] = +{ + {ACPI_DMT_UINT32, ACPI_FPDT1_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT64, ACPI_FPDT1_OFFSET (Address), "S3PT Address", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * GTDT - Generic Timer Description Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt[] = +{ + {ACPI_DMT_UINT64, ACPI_GTDT_OFFSET (Address), "Timer Address", 0}, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (Flags,0), "Memory Present", 0}, + ACPI_DMT_NEW_LINE, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (SecurePl1Interrupt), "Secure PL1 Interrupt", 0}, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (SecurePl1Flags), "SPL1 Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (SecurePl1Flags,0), "Trigger Mode", 0}, + {ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (SecurePl1Flags,0), "Polarity", 0}, + ACPI_DMT_NEW_LINE, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecurePl1Interrupt), "Non-Secure PL1 Interrupt", 0}, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecurePl1Flags), "NSPL1 Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (NonSecurePl1Flags,0),"Trigger Mode", 0}, + {ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (NonSecurePl1Flags,0),"Polarity", 0}, + ACPI_DMT_NEW_LINE, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (VirtualTimerInterrupt), "Virtual Timer Interrupt", 0}, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (VirtualTimerFlags), "VT Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (VirtualTimerFlags,0),"Trigger Mode", 0}, + {ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (VirtualTimerFlags,0),"Polarity", 0}, + ACPI_DMT_NEW_LINE, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecurePl2Interrupt), "Non-Secure PL2 Interrupt", 0}, + {ACPI_DMT_UINT32, ACPI_GTDT_OFFSET (NonSecurePl2Flags), "NSPL2 Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_GTDT_FLAG_OFFSET (NonSecurePl2Flags,0),"Trigger Mode", 0}, + {ACPI_DMT_FLAG1, ACPI_GTDT_FLAG_OFFSET (NonSecurePl2Flags,0),"Polarity", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * HEST - Hardware Error Source table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHest[] = +{ + {ACPI_DMT_UINT32, ACPI_HEST_OFFSET (ErrorSourceCount), "Error Source Count", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Common HEST structures for subtables */ + +#define ACPI_DM_HEST_HEADER \ + {ACPI_DMT_HEST, ACPI_HEST0_OFFSET (Header.Type), "Subtable Type", 0}, \ + {ACPI_DMT_UINT16, ACPI_HEST0_OFFSET (Header.SourceId), "Source Id", 0} + +#define ACPI_DM_HEST_AER \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved1), "Reserved", 0}, \ + {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Flags), "Flags (decoded below)", DT_FLAG}, \ + {ACPI_DMT_FLAG0, ACPI_HEST6_FLAG_OFFSET (Aer.Flags,0), "Firmware First", 0}, \ + {ACPI_DMT_UINT8, ACPI_HEST6_OFFSET (Aer.Enabled), "Enabled", 0}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.RecordsToPreallocate), "Records To Preallocate", 0}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.MaxSectionsPerRecord), "Max Sections Per Record", 0}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.Bus), "Bus", 0}, \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Device), "Device", 0}, \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Function), "Function", 0}, \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.DeviceControl), "DeviceControl", 0}, \ + {ACPI_DMT_UINT16, ACPI_HEST6_OFFSET (Aer.Reserved2), "Reserved", 0}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableMask), "Uncorrectable Mask", 0}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.UncorrectableSeverity), "Uncorrectable Severity", 0}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.CorrectableMask), "Correctable Mask", 0}, \ + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (Aer.AdvancedCapabilities), "Advanced Capabilities", 0} + + +/* HEST Subtables */ + +/* 0: IA32 Machine Check Exception */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHest0[] = +{ + ACPI_DM_HEST_HEADER, + {ACPI_DMT_UINT16, ACPI_HEST0_OFFSET (Reserved1), "Reserved1", 0}, + {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_HEST0_FLAG_OFFSET (Flags,0), "Firmware First", 0}, + + {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (Enabled), "Enabled", 0}, + {ACPI_DMT_UINT32, ACPI_HEST0_OFFSET (RecordsToPreallocate), "Records To Preallocate", 0}, + {ACPI_DMT_UINT32, ACPI_HEST0_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record", 0}, + {ACPI_DMT_UINT64, ACPI_HEST0_OFFSET (GlobalCapabilityData), "Global Capability Data", 0}, + {ACPI_DMT_UINT64, ACPI_HEST0_OFFSET (GlobalControlData), "Global Control Data", 0}, + {ACPI_DMT_UINT8, ACPI_HEST0_OFFSET (NumHardwareBanks), "Num Hardware Banks", 0}, + {ACPI_DMT_UINT56, ACPI_HEST0_OFFSET (Reserved3[0]), "Reserved2", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: IA32 Corrected Machine Check */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHest1[] = +{ + ACPI_DM_HEST_HEADER, + {ACPI_DMT_UINT16, ACPI_HEST1_OFFSET (Reserved1), "Reserved1", 0}, + {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_HEST1_FLAG_OFFSET (Flags,0), "Firmware First", 0}, + + {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (Enabled), "Enabled", 0}, + {ACPI_DMT_UINT32, ACPI_HEST1_OFFSET (RecordsToPreallocate), "Records To Preallocate", 0}, + {ACPI_DMT_UINT32, ACPI_HEST1_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record", 0}, + {ACPI_DMT_HESTNTFY, ACPI_HEST1_OFFSET (Notify), "Notify", 0}, + {ACPI_DMT_UINT8, ACPI_HEST1_OFFSET (NumHardwareBanks), "Num Hardware Banks", 0}, + {ACPI_DMT_UINT24, ACPI_HEST1_OFFSET (Reserved2[0]), "Reserved2", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 2: IA32 Non-Maskable Interrupt */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHest2[] = +{ + ACPI_DM_HEST_HEADER, + {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (RecordsToPreallocate), "Records To Preallocate", 0}, + {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record", 0}, + {ACPI_DMT_UINT32, ACPI_HEST2_OFFSET (MaxRawDataLength), "Max Raw Data Length", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 6: PCI Express Root Port AER */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHest6[] = +{ + ACPI_DM_HEST_HEADER, + ACPI_DM_HEST_AER, + {ACPI_DMT_UINT32, ACPI_HEST6_OFFSET (RootErrorCommand), "Root Error Command", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 7: PCI Express AER (AER Endpoint) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHest7[] = +{ + ACPI_DM_HEST_HEADER, + ACPI_DM_HEST_AER, + ACPI_DMT_TERMINATOR +}; + +/* 8: PCI Express/PCI-X Bridge AER */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHest8[] = +{ + ACPI_DM_HEST_HEADER, + ACPI_DM_HEST_AER, + {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (UncorrectableMask2), "2nd Uncorrectable Mask", 0}, + {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (UncorrectableSeverity2), "2nd Uncorrectable Severity", 0}, + {ACPI_DMT_UINT32, ACPI_HEST8_OFFSET (AdvancedCapabilities2), "2nd Advanced Capabilities", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 9: Generic Hardware Error Source */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHest9[] = +{ + ACPI_DM_HEST_HEADER, + {ACPI_DMT_UINT16, ACPI_HEST9_OFFSET (RelatedSourceId), "Related Source Id", 0}, + {ACPI_DMT_UINT8, ACPI_HEST9_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT8, ACPI_HEST9_OFFSET (Enabled), "Enabled", 0}, + {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (RecordsToPreallocate), "Records To Preallocate", 0}, + {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (MaxSectionsPerRecord), "Max Sections Per Record", 0}, + {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (MaxRawDataLength), "Max Raw Data Length", 0}, + {ACPI_DMT_GAS, ACPI_HEST9_OFFSET (ErrorStatusAddress), "Error Status Address", 0}, + {ACPI_DMT_HESTNTFY, ACPI_HEST9_OFFSET (Notify), "Notify", 0}, + {ACPI_DMT_UINT32, ACPI_HEST9_OFFSET (ErrorBlockLength), "Error Status Block Length", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoHestNotify[] = +{ + {ACPI_DMT_HESTNTYP, ACPI_HESTN_OFFSET (Type), "Notify Type", 0}, + {ACPI_DMT_UINT8, ACPI_HESTN_OFFSET (Length), "Notify Length", DT_LENGTH}, + {ACPI_DMT_UINT16, ACPI_HESTN_OFFSET (ConfigWriteEnable), "Configuration Write Enable", 0}, + {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (PollInterval), "PollInterval", 0}, + {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (Vector), "Vector", 0}, + {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (PollingThresholdValue), "Polling Threshold Value", 0}, + {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (PollingThresholdWindow), "Polling Threshold Window", 0}, + {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (ErrorThresholdValue), "Error Threshold Value", 0}, + {ACPI_DMT_UINT32, ACPI_HESTN_OFFSET (ErrorThresholdWindow), "Error Threshold Window", 0}, + ACPI_DMT_TERMINATOR +}; + + +/* + * IA32 Error Bank(s) - Follows the ACPI_HEST_IA_MACHINE_CHECK and + * ACPI_HEST_IA_CORRECTED structures. + */ +ACPI_DMTABLE_INFO AcpiDmTableInfoHestBank[] = +{ + {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (BankNumber), "Bank Number", 0}, + {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (ClearStatusOnInit), "Clear Status On Init", 0}, + {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (StatusFormat), "Status Format", 0}, + {ACPI_DMT_UINT8, ACPI_HESTB_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (ControlRegister), "Control Register", 0}, + {ACPI_DMT_UINT64, ACPI_HESTB_OFFSET (ControlData), "Control Data", 0}, + {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (StatusRegister), "Status Register", 0}, + {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (AddressRegister), "Address Register", 0}, + {ACPI_DMT_UINT32, ACPI_HESTB_OFFSET (MiscRegister), "Misc Register", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * HPET - High Precision Event Timer table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoHpet[] = +{ + {ACPI_DMT_UINT32, ACPI_HPET_OFFSET (Id), "Hardware Block ID", 0}, + {ACPI_DMT_GAS, ACPI_HPET_OFFSET (Address), "Timer Block Register", 0}, + {ACPI_DMT_UINT8, ACPI_HPET_OFFSET (Sequence), "Sequence Number", 0}, + {ACPI_DMT_UINT16, ACPI_HPET_OFFSET (MinimumTick), "Minimum Clock Ticks", 0}, + {ACPI_DMT_UINT8, ACPI_HPET_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_HPET_FLAG_OFFSET (Flags,0), "4K Page Protect", 0}, + {ACPI_DMT_FLAG1, ACPI_HPET_FLAG_OFFSET (Flags,0), "64K Page Protect", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * IVRS - I/O Virtualization Reporting Structure + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs[] = +{ + {ACPI_DMT_UINT32, ACPI_IVRS_OFFSET (Info), "Virtualization Info", 0}, + {ACPI_DMT_UINT64, ACPI_IVRS_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrsHdr[] = +{ + {ACPI_DMT_IVRS, ACPI_IVRSH_OFFSET (Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_IVRSH_OFFSET (Flags), "Flags", 0}, + {ACPI_DMT_UINT16, ACPI_IVRSH_OFFSET (Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT16, ACPI_IVRSH_OFFSET (DeviceId), "DeviceId", 0}, + ACPI_DMT_TERMINATOR +}; + +/* IVRS subtables */ + +/* 0x10: I/O Virtualization Hardware Definition (IVHD) Block */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs0[] = +{ + {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (CapabilityOffset), "Capability Offset", 0}, + {ACPI_DMT_UINT64, ACPI_IVRS0_OFFSET (BaseAddress), "Base Address", 0}, + {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (PciSegmentGroup), "PCI Segment Group", 0}, + {ACPI_DMT_UINT16, ACPI_IVRS0_OFFSET (Info), "Virtualization Info", 0}, + {ACPI_DMT_UINT32, ACPI_IVRS0_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 0x20, 0x21, 0x22: I/O Virtualization Memory Definition (IVMD) Block */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs1[] = +{ + {ACPI_DMT_UINT16, ACPI_IVRS1_OFFSET (AuxData), "Auxiliary Data", 0}, + {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (StartAddress), "Start Address", 0}, + {ACPI_DMT_UINT64, ACPI_IVRS1_OFFSET (MemoryLength), "Memory Length", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Device entry header for IVHD block */ + +#define ACPI_DMT_IVRS_DE_HEADER \ + {ACPI_DMT_UINT8, ACPI_IVRSD_OFFSET (Type), "Entry Type", 0}, \ + {ACPI_DMT_UINT16, ACPI_IVRSD_OFFSET (Id), "Device ID", 0}, \ + {ACPI_DMT_UINT8, ACPI_IVRSD_OFFSET (DataSetting), "Data Setting", 0} + +/* 4-byte device entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs4[] = +{ + ACPI_DMT_IVRS_DE_HEADER, + {ACPI_DMT_EXIT, 0, NULL, 0}, +}; + +/* 8-byte device entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8a[] = +{ + ACPI_DMT_IVRS_DE_HEADER, + {ACPI_DMT_UINT8, ACPI_IVRS8A_OFFSET (Reserved1), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_IVRS8A_OFFSET (UsedId), "Source Used Device ID", 0}, + {ACPI_DMT_UINT8, ACPI_IVRS8A_OFFSET (Reserved2), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 8-byte device entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8b[] = +{ + ACPI_DMT_IVRS_DE_HEADER, + {ACPI_DMT_UINT32, ACPI_IVRS8B_OFFSET (ExtendedData), "Extended Data", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 8-byte device entry */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoIvrs8c[] = +{ + ACPI_DMT_IVRS_DE_HEADER, + {ACPI_DMT_UINT8, ACPI_IVRS8C_OFFSET (Handle), "Handle", 0}, + {ACPI_DMT_UINT16, ACPI_IVRS8C_OFFSET (UsedId), "Source Used Device ID", 0}, + {ACPI_DMT_UINT8, ACPI_IVRS8C_OFFSET (Variety), "Variety", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * MADT - Multiple APIC Description Table and subtables + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt[] = +{ + {ACPI_DMT_UINT32, ACPI_MADT_OFFSET (Address), "Local Apic Address", 0}, + {ACPI_DMT_UINT32, ACPI_MADT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_MADT_FLAG_OFFSET (Flags,0), "PC-AT Compatibility", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadtHdr[] = +{ + {ACPI_DMT_MADT, ACPI_MADTH_OFFSET (Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_MADTH_OFFSET (Length), "Length", DT_LENGTH}, + ACPI_DMT_TERMINATOR +}; + +/* MADT Subtables */ + +/* 0: processor APIC */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt0[] = +{ + {ACPI_DMT_UINT8, ACPI_MADT0_OFFSET (ProcessorId), "Processor ID", 0}, + {ACPI_DMT_UINT8, ACPI_MADT0_OFFSET (Id), "Local Apic ID", 0}, + {ACPI_DMT_UINT32, ACPI_MADT0_OFFSET (LapicFlags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_MADT0_FLAG_OFFSET (LapicFlags,0), "Processor Enabled", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: IO APIC */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt1[] = +{ + {ACPI_DMT_UINT8, ACPI_MADT1_OFFSET (Id), "I/O Apic ID", 0}, + {ACPI_DMT_UINT8, ACPI_MADT1_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_MADT1_OFFSET (Address), "Address", 0}, + {ACPI_DMT_UINT32, ACPI_MADT1_OFFSET (GlobalIrqBase), "Interrupt", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 2: Interrupt Override */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt2[] = +{ + {ACPI_DMT_UINT8, ACPI_MADT2_OFFSET (Bus), "Bus", 0}, + {ACPI_DMT_UINT8, ACPI_MADT2_OFFSET (SourceIrq), "Source", 0}, + {ACPI_DMT_UINT32, ACPI_MADT2_OFFSET (GlobalIrq), "Interrupt", 0}, + {ACPI_DMT_UINT16, ACPI_MADT2_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAGS0, ACPI_MADT2_FLAG_OFFSET (IntiFlags,0), "Polarity", 0}, + {ACPI_DMT_FLAGS2, ACPI_MADT2_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 3: NMI Sources */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt3[] = +{ + {ACPI_DMT_UINT16, ACPI_MADT3_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAGS0, ACPI_MADT3_FLAG_OFFSET (IntiFlags,0), "Polarity", 0}, + {ACPI_DMT_FLAGS2, ACPI_MADT3_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0}, + {ACPI_DMT_UINT32, ACPI_MADT3_OFFSET (GlobalIrq), "Interrupt", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 4: Local APIC NMI */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt4[] = +{ + {ACPI_DMT_UINT8, ACPI_MADT4_OFFSET (ProcessorId), "Processor ID", 0}, + {ACPI_DMT_UINT16, ACPI_MADT4_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAGS0, ACPI_MADT4_FLAG_OFFSET (IntiFlags,0), "Polarity", 0}, + {ACPI_DMT_FLAGS2, ACPI_MADT4_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0}, + {ACPI_DMT_UINT8, ACPI_MADT4_OFFSET (Lint), "Interrupt Input LINT", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 5: Address Override */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt5[] = +{ + {ACPI_DMT_UINT16, ACPI_MADT5_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT64, ACPI_MADT5_OFFSET (Address), "APIC Address", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 6: I/O Sapic */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt6[] = +{ + {ACPI_DMT_UINT8, ACPI_MADT6_OFFSET (Id), "I/O Sapic ID", 0}, + {ACPI_DMT_UINT8, ACPI_MADT6_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_MADT6_OFFSET (GlobalIrqBase), "Interrupt Base", 0}, + {ACPI_DMT_UINT64, ACPI_MADT6_OFFSET (Address), "Address", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 7: Local Sapic */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt7[] = +{ + {ACPI_DMT_UINT8, ACPI_MADT7_OFFSET (ProcessorId), "Processor ID", 0}, + {ACPI_DMT_UINT8, ACPI_MADT7_OFFSET (Id), "Local Sapic ID", 0}, + {ACPI_DMT_UINT8, ACPI_MADT7_OFFSET (Eid), "Local Sapic EID", 0}, + {ACPI_DMT_UINT24, ACPI_MADT7_OFFSET (Reserved[0]), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_MADT7_OFFSET (LapicFlags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_MADT7_FLAG_OFFSET (LapicFlags,0), "Processor Enabled", 0}, + {ACPI_DMT_UINT32, ACPI_MADT7_OFFSET (Uid), "Processor UID", 0}, + {ACPI_DMT_STRING, ACPI_MADT7_OFFSET (UidString[0]), "Processor UID String", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 8: Platform Interrupt Source */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt8[] = +{ + {ACPI_DMT_UINT16, ACPI_MADT8_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAGS0, ACPI_MADT8_FLAG_OFFSET (IntiFlags,0), "Polarity", 0}, + {ACPI_DMT_FLAGS2, ACPI_MADT8_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0}, + {ACPI_DMT_UINT8, ACPI_MADT8_OFFSET (Type), "InterruptType", 0}, + {ACPI_DMT_UINT8, ACPI_MADT8_OFFSET (Id), "Processor ID", 0}, + {ACPI_DMT_UINT8, ACPI_MADT8_OFFSET (Eid), "Processor EID", 0}, + {ACPI_DMT_UINT8, ACPI_MADT8_OFFSET (IoSapicVector), "I/O Sapic Vector", 0}, + {ACPI_DMT_UINT32, ACPI_MADT8_OFFSET (GlobalIrq), "Interrupt", 0}, + {ACPI_DMT_UINT32, ACPI_MADT8_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_MADT8_OFFSET (Flags), "CPEI Override", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 9: Processor Local X2_APIC (ACPI 4.0) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt9[] = +{ + {ACPI_DMT_UINT16, ACPI_MADT9_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_MADT9_OFFSET (LocalApicId), "Processor x2Apic ID", 0}, + {ACPI_DMT_UINT32, ACPI_MADT9_OFFSET (LapicFlags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_MADT9_FLAG_OFFSET (LapicFlags,0), "Processor Enabled", 0}, + {ACPI_DMT_UINT32, ACPI_MADT9_OFFSET (Uid), "Processor UID", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 10: Local X2_APIC NMI (ACPI 4.0) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt10[] = +{ + {ACPI_DMT_UINT16, ACPI_MADT10_OFFSET (IntiFlags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAGS0, ACPI_MADT10_FLAG_OFFSET (IntiFlags,0), "Polarity", 0}, + {ACPI_DMT_FLAGS2, ACPI_MADT10_FLAG_OFFSET (IntiFlags,0), "Trigger Mode", 0}, + {ACPI_DMT_UINT32, ACPI_MADT10_OFFSET (Uid), "Processor UID", 0}, + {ACPI_DMT_UINT8, ACPI_MADT10_OFFSET (Lint), "Interrupt Input LINT", 0}, + {ACPI_DMT_UINT24, ACPI_MADT10_OFFSET (Reserved[0]), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 11: Generic Interrupt Controller (ACPI 5.0) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt11[] = +{ + {ACPI_DMT_UINT16, ACPI_MADT11_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (GicId), "Local GIC Hardware ID", 0}, + {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (Uid), "Processor UID", 0}, + {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_MADT11_FLAG_OFFSET (Flags,0), "Processor Enabled", 0}, + {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (ParkingVersion), "Parking Protocol Version", 0}, + {ACPI_DMT_UINT32, ACPI_MADT11_OFFSET (PerformanceInterrupt), "Performance Interrupt", 0}, + {ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (ParkedAddress), "Parked Address", 0}, + {ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (BaseAddress), "Base Address", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 12: Generic Interrupt Distributor (ACPI 5.0) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMadt12[] = +{ + {ACPI_DMT_UINT16, ACPI_MADT12_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_MADT12_OFFSET (GicId), "Local GIC Hardware ID", 0}, + {ACPI_DMT_UINT64, ACPI_MADT12_OFFSET (BaseAddress), "Base Address", 0}, + {ACPI_DMT_UINT32, ACPI_MADT12_OFFSET (GlobalIrqBase), "Interrupt Base", 0}, + {ACPI_DMT_UINT32, ACPI_MADT12_OFFSET (Reserved2), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * MCFG - PCI Memory Mapped Configuration table and Subtable + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg[] = +{ + {ACPI_DMT_UINT64, ACPI_MCFG_OFFSET (Reserved[0]), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoMcfg0[] = +{ + {ACPI_DMT_UINT64, ACPI_MCFG0_OFFSET (Address), "Base Address", 0}, + {ACPI_DMT_UINT16, ACPI_MCFG0_OFFSET (PciSegment), "Segment Group Number", 0}, + {ACPI_DMT_UINT8, ACPI_MCFG0_OFFSET (StartBusNumber), "Start Bus Number", 0}, + {ACPI_DMT_UINT8, ACPI_MCFG0_OFFSET (EndBusNumber), "End Bus Number", 0}, + {ACPI_DMT_UINT32, ACPI_MCFG0_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * MCHI - Management Controller Host Interface table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMchi[] = +{ + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (InterfaceType), "Interface Type", 0}, + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (Protocol), "Protocol", 0}, + {ACPI_DMT_UINT64, ACPI_MCHI_OFFSET (ProtocolData), "Protocol Data", 0}, + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (InterruptType), "Interrupt Type", 0}, + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (Gpe), "Gpe", 0}, + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciDeviceFlag), "Pci Device Flag", 0}, + {ACPI_DMT_UINT32, ACPI_MCHI_OFFSET (GlobalInterrupt), "Global Interrupt", 0}, + {ACPI_DMT_GAS, ACPI_MCHI_OFFSET (ControlRegister), "Control Register", 0}, + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciSegment), "Pci Segment", 0}, + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciBus), "Pci Bus", 0}, + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciDevice), "Pci Device", 0}, + {ACPI_DMT_UINT8, ACPI_MCHI_OFFSET (PciFunction), "Pci Function", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * MPST - Memory Power State Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMpst[] = +{ + {ACPI_DMT_UINT16, ACPI_MPST_OFFSET (Reserved1), "Reserved", 0}, + {ACPI_DMT_UINT8, ACPI_MPST_OFFSET (ChannelId), "Channel ID", 0}, + {ACPI_DMT_UINT8, ACPI_MPST_OFFSET (Reserved2), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_MPST_OFFSET (PowerNodeCount), "Power Node Count", 0}, + ACPI_DMT_TERMINATOR +}; + +/* MPST subtables */ + +/* 0: Memory Power Node Structure */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0[] = +{ + {ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Node Enabled", 0}, + {ACPI_DMT_FLAG1, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Power Managed", 0}, + {ACPI_DMT_FLAG2, ACPI_MPST0_FLAG_OFFSET (Flags,0), "Hot Plug Capable", 0}, + + {ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (Reserved1), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_MPST0_OFFSET (NodeId), "Node ID", 0}, + {ACPI_DMT_UINT32, ACPI_MPST0_OFFSET (Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT64, ACPI_MPST0_OFFSET (RangeAddress), "Range Address", 0}, + {ACPI_DMT_UINT64, ACPI_MPST0_OFFSET (RangeLength), "Range Length", 0}, + {ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (NumPowerStates), "Num Power States", 0}, + {ACPI_DMT_UINT8, ACPI_MPST0_OFFSET (NumPhysicalComponents), "Num Physical Components", 0}, + {ACPI_DMT_UINT16, ACPI_MPST0_OFFSET (Reserved2), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 0A: Sub-subtable - Memory Power State Structure (follows Memory Power Node above) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0A[] = +{ + {ACPI_DMT_UINT8, ACPI_MPST0A_OFFSET (PowerState), "Power State", 0}, + {ACPI_DMT_UINT8, ACPI_MPST0A_OFFSET (InfoIndex), "InfoIndex", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 0B: Sub-subtable - Physical Component ID Structure (follows Memory Power State(s) above) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMpst0B[] = +{ + {ACPI_DMT_UINT16, ACPI_MPST0B_OFFSET (ComponentId), "Component Id", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 01: Power Characteristics Count (follows all Power Node(s) above) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMpst1[] = +{ + {ACPI_DMT_UINT16, ACPI_MPST1_OFFSET (CharacteristicsCount), "Characteristics Count", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 02: Memory Power State Characteristics Structure */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMpst2[] = +{ + {ACPI_DMT_UINT8, ACPI_MPST2_OFFSET (Revision), "Revision", 0}, + {ACPI_DMT_UINT8, ACPI_MPST2_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Memory Preserved", 0}, + {ACPI_DMT_FLAG1, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Auto Entry", 0}, + {ACPI_DMT_FLAG2, ACPI_MPST2_FLAG_OFFSET (Flags,0), "Auto Exit", 0}, + + {ACPI_DMT_UINT16, ACPI_MPST2_OFFSET (Reserved1), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_MPST2_OFFSET (AveragePower), "Average Power", 0}, + {ACPI_DMT_UINT32, ACPI_MPST2_OFFSET (PowerSaving), "Power Saving", 0}, + {ACPI_DMT_UINT64, ACPI_MPST2_OFFSET (ExitLatency), "Exit Latency", 0}, + {ACPI_DMT_UINT64, ACPI_MPST2_OFFSET (Reserved2), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * MSCT - Maximum System Characteristics Table (ACPI 4.0) + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMsct[] = +{ + {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (ProximityOffset), "Proximity Offset", 0}, + {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (MaxProximityDomains), "Max Proximity Domains", 0}, + {ACPI_DMT_UINT32, ACPI_MSCT_OFFSET (MaxClockDomains), "Max Clock Domains", 0}, + {ACPI_DMT_UINT64, ACPI_MSCT_OFFSET (MaxAddress), "Max Physical Address", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Subtable - Maximum Proximity Domain Information. Version 1 */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoMsct0[] = +{ + {ACPI_DMT_UINT8, ACPI_MSCT0_OFFSET (Revision), "Revision", 0}, + {ACPI_DMT_UINT8, ACPI_MSCT0_OFFSET (Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (RangeStart), "Domain Range Start", 0}, + {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (RangeEnd), "Domain Range End", 0}, + {ACPI_DMT_UINT32, ACPI_MSCT0_OFFSET (ProcessorCapacity), "Processor Capacity", 0}, + {ACPI_DMT_UINT64, ACPI_MSCT0_OFFSET (MemoryCapacity), "Memory Capacity", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * PCCT - Platform Communications Channel Table (ACPI 5.0) + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPcct[] = +{ + {ACPI_DMT_UINT32, ACPI_PCCT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_PCCT_FLAG_OFFSET (Flags,0), "Doorbell", 0}, + {ACPI_DMT_UINT32, ACPI_PCCT_OFFSET (Latency), "Command Latency", 0}, + {ACPI_DMT_UINT32, ACPI_PCCT_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* PCCT subtables */ + +/* 0: Generic Communications Subspace */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPcct0[] = +{ + {ACPI_DMT_UINT8, ACPI_PCCT0_OFFSET (Header.Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_PCCT0_OFFSET (Header.Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT48, ACPI_PCCT0_OFFSET (Reserved[0]), "Reserved", 0}, + {ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (BaseAddress), "Base Address", 0}, + {ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (Length), "Address Length", 0}, + {ACPI_DMT_GAS, ACPI_PCCT0_OFFSET (DoorbellRegister), "Doorbell Register", 0}, + {ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (PreserveMask), "Preserve Mask", 0}, + {ACPI_DMT_UINT64, ACPI_PCCT0_OFFSET (WriteMask), "Write Mask", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * PMTT - Platform Memory Topology Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt[] = +{ + {ACPI_DMT_UINT32, ACPI_PMTT_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPmttHdr[] = +{ + {ACPI_DMT_PMTT, ACPI_PMTTH_OFFSET (Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_PMTTH_OFFSET (Reserved1), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Top-level Device", 0}, + {ACPI_DMT_FLAG1, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Physical Element", 0}, + {ACPI_DMT_FLAGS2, ACPI_PMTTH_FLAG_OFFSET (Flags,0), "Memory Type", 0}, + {ACPI_DMT_UINT16, ACPI_PMTTH_OFFSET (Reserved2), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* PMTT Subtables */ + +/* 0: Socket */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt0[] = +{ + {ACPI_DMT_UINT16, ACPI_PMTT0_OFFSET (SocketId), "Socket ID", 0}, + {ACPI_DMT_UINT16, ACPI_PMTT0_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: Memory Controller */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1[] = +{ + {ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (ReadLatency), "Read Latency", 0}, + {ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (WriteLatency), "Write Latency", 0}, + {ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (ReadBandwidth), "Read Bandwidth", 0}, + {ACPI_DMT_UINT32, ACPI_PMTT1_OFFSET (WriteBandwidth), "Write Bandwidth", 0}, + {ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (AccessWidth), "Access Width", 0}, + {ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (Alignment), "Alignment", 0}, + {ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_PMTT1_OFFSET (DomainCount), "Domain Count", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1a: Proximity Domain */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt1a[] = +{ + {ACPI_DMT_UINT32, ACPI_PMTT1A_OFFSET (ProximityDomain), "Proximity Domain", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 2: Physical Component */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoPmtt2[] = +{ + {ACPI_DMT_UINT16, ACPI_PMTT2_OFFSET (ComponentId), "Component ID", 0}, + {ACPI_DMT_UINT16, ACPI_PMTT2_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_PMTT2_OFFSET (MemorySize), "Memory Size", 0}, + {ACPI_DMT_UINT32, ACPI_PMTT2_OFFSET (BiosHandle), "Bios Handle", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * S3PT - S3 Performance Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt[] = +{ + {ACPI_DMT_SIG, ACPI_S3PT_OFFSET (Signature[0]), "Signature", 0}, + {ACPI_DMT_UINT32, ACPI_S3PT_OFFSET (Length), "Length", DT_LENGTH}, + ACPI_DMT_TERMINATOR +}; + +/* S3PT subtable header */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoS3ptHdr[] = +{ + {ACPI_DMT_UINT16, ACPI_S3PTH_OFFSET (Type), "Type", 0}, + {ACPI_DMT_UINT8, ACPI_S3PTH_OFFSET (Length), "Length", DT_LENGTH}, + {ACPI_DMT_UINT8, ACPI_S3PTH_OFFSET (Revision), "Revision", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 0: Basic S3 Resume Performance Record */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt0[] = +{ + {ACPI_DMT_UINT32, ACPI_S3PT0_OFFSET (ResumeCount), "Resume Count", 0}, + {ACPI_DMT_UINT64, ACPI_S3PT0_OFFSET (FullResume), "Full Resume", 0}, + {ACPI_DMT_UINT64, ACPI_S3PT0_OFFSET (AverageResume), "Average Resume", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: Basic S3 Suspend Performance Record */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoS3pt1[] = +{ + {ACPI_DMT_UINT64, ACPI_S3PT1_OFFSET (SuspendStart), "Suspend Start", 0}, + {ACPI_DMT_UINT64, ACPI_S3PT1_OFFSET (SuspendEnd), "Suspend End", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * SBST - Smart Battery Specification Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[] = +{ + {ACPI_DMT_UINT32, ACPI_SBST_OFFSET (WarningLevel), "Warning Level", 0}, + {ACPI_DMT_UINT32, ACPI_SBST_OFFSET (LowLevel), "Low Level", 0}, + {ACPI_DMT_UINT32, ACPI_SBST_OFFSET (CriticalLevel), "Critical Level", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * SLIC - Software Licensing Description Table. There is no common table, just + * the standard ACPI header and then subtables. + * + ******************************************************************************/ + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSlicHdr[] = +{ + {ACPI_DMT_SLIC, ACPI_SLICH_OFFSET (Type), "Subtable Type", 0}, + {ACPI_DMT_UINT32, ACPI_SLICH_OFFSET (Length), "Length", DT_LENGTH}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoSlic0[] = +{ + {ACPI_DMT_UINT8, ACPI_SLIC0_OFFSET (KeyType), "Key Type", 0}, + {ACPI_DMT_UINT8, ACPI_SLIC0_OFFSET (Version), "Version", 0}, + {ACPI_DMT_UINT16, ACPI_SLIC0_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_SLIC0_OFFSET (Algorithm), "Algorithm", 0}, + {ACPI_DMT_NAME4, ACPI_SLIC0_OFFSET (Magic), "Magic", 0}, + {ACPI_DMT_UINT32, ACPI_SLIC0_OFFSET (BitLength), "BitLength", 0}, + {ACPI_DMT_UINT32, ACPI_SLIC0_OFFSET (Exponent), "Exponent", 0}, + {ACPI_DMT_BUF128, ACPI_SLIC0_OFFSET (Modulus[0]), "Modulus", 0}, + ACPI_DMT_TERMINATOR +}; + +ACPI_DMTABLE_INFO AcpiDmTableInfoSlic1[] = +{ + {ACPI_DMT_UINT32, ACPI_SLIC1_OFFSET (Version), "Version", 0}, + {ACPI_DMT_NAME6, ACPI_SLIC1_OFFSET (OemId[0]), "Oem ID", 0}, + {ACPI_DMT_NAME8, ACPI_SLIC1_OFFSET (OemTableId[0]), "Oem Table ID", 0}, + {ACPI_DMT_NAME8, ACPI_SLIC1_OFFSET (WindowsFlag[0]), "Windows Flag", 0}, + {ACPI_DMT_UINT32, ACPI_SLIC1_OFFSET (SlicVersion), "SLIC Version", 0}, + {ACPI_DMT_BUF16, ACPI_SLIC1_OFFSET (Reserved[0]), "Reserved", 0}, + {ACPI_DMT_BUF128, ACPI_SLIC1_OFFSET (Signature[0]), "Signature", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * SLIT - System Locality Information Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSlit[] = +{ + {ACPI_DMT_UINT64, ACPI_SLIT_OFFSET (LocalityCount), "Localities", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * SPCR - Serial Port Console Redirection table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSpcr[] = +{ + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (InterfaceType), "Interface Type", 0}, + {ACPI_DMT_UINT24, ACPI_SPCR_OFFSET (Reserved[0]), "Reserved", 0}, + {ACPI_DMT_GAS, ACPI_SPCR_OFFSET (SerialPort), "Serial Port Register", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (InterruptType), "Interrupt Type", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PcInterrupt), "PCAT-compatible IRQ", 0}, + {ACPI_DMT_UINT32, ACPI_SPCR_OFFSET (Interrupt), "Interrupt", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (BaudRate), "Baud Rate", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (Parity), "Parity", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (StopBits), "Stop Bits", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (FlowControl), "Flow Control", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (TerminalType), "Terminal Type", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (Reserved2), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_SPCR_OFFSET (PciDeviceId), "PCI Device ID", 0}, + {ACPI_DMT_UINT16, ACPI_SPCR_OFFSET (PciVendorId), "PCI Vendor ID", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PciBus), "PCI Bus", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PciDevice), "PCI Device", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PciFunction), "PCI Function", 0}, + {ACPI_DMT_UINT32, ACPI_SPCR_OFFSET (PciFlags), "PCI Flags", 0}, + {ACPI_DMT_UINT8, ACPI_SPCR_OFFSET (PciSegment), "PCI Segment", 0}, + {ACPI_DMT_UINT32, ACPI_SPCR_OFFSET (Reserved2), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * SPMI - Server Platform Management Interface table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSpmi[] = +{ + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (InterfaceType), "Interface Type", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT16, ACPI_SPMI_OFFSET (SpecRevision), "IPMI Spec Version", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (InterruptType), "Interrupt Type", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (GpeNumber), "GPE Number", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved1), "Reserved", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciDeviceFlag), "PCI Device Flag", 0}, + {ACPI_DMT_UINT32, ACPI_SPMI_OFFSET (Interrupt), "Interrupt", 0}, + {ACPI_DMT_GAS, ACPI_SPMI_OFFSET (IpmiRegister), "IPMI Register", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciSegment), "PCI Segment", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciBus), "PCI Bus", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciDevice), "PCI Device", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (PciFunction), "PCI Function", 0}, + {ACPI_DMT_UINT8, ACPI_SPMI_OFFSET (Reserved2), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * SRAT - System Resource Affinity Table and Subtables + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSrat[] = +{ + {ACPI_DMT_UINT32, ACPI_SRAT_OFFSET (TableRevision), "Table Revision", 0}, + {ACPI_DMT_UINT64, ACPI_SRAT_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* Common Subtable header (one per Subtable) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSratHdr[] = +{ + {ACPI_DMT_SRAT, ACPI_SRATH_OFFSET (Type), "Subtable Type", 0}, + {ACPI_DMT_UINT8, ACPI_SRATH_OFFSET (Length), "Length", DT_LENGTH}, + ACPI_DMT_TERMINATOR +}; + +/* SRAT Subtables */ + +/* 0: Processor Local APIC/SAPIC Affinity */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSrat0[] = +{ + {ACPI_DMT_UINT8, ACPI_SRAT0_OFFSET (ProximityDomainLo), "Proximity Domain Low(8)", 0}, + {ACPI_DMT_UINT8, ACPI_SRAT0_OFFSET (ApicId), "Apic ID", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT0_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_SRAT0_FLAG_OFFSET (Flags,0), "Enabled", 0}, + {ACPI_DMT_UINT8, ACPI_SRAT0_OFFSET (LocalSapicEid), "Local Sapic EID", 0}, + {ACPI_DMT_UINT24, ACPI_SRAT0_OFFSET (ProximityDomainHi[0]), "Proximity Domain High(24)", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT0_OFFSET (Reserved), "Reserved", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 1: Memory Affinity */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSrat1[] = +{ + {ACPI_DMT_UINT32, ACPI_SRAT1_OFFSET (ProximityDomain), "Proximity Domain", 0}, + {ACPI_DMT_UINT16, ACPI_SRAT1_OFFSET (Reserved), "Reserved1", 0}, + {ACPI_DMT_UINT64, ACPI_SRAT1_OFFSET (BaseAddress), "Base Address", 0}, + {ACPI_DMT_UINT64, ACPI_SRAT1_OFFSET (Length), "Address Length", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT1_OFFSET (Reserved1), "Reserved2", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT1_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_SRAT1_FLAG_OFFSET (Flags,0), "Enabled", 0}, + {ACPI_DMT_FLAG1, ACPI_SRAT1_FLAG_OFFSET (Flags,0), "Hot Pluggable", 0}, + {ACPI_DMT_FLAG2, ACPI_SRAT1_FLAG_OFFSET (Flags,0), "Non-Volatile", 0}, + {ACPI_DMT_UINT64, ACPI_SRAT1_OFFSET (Reserved2), "Reserved3", 0}, + ACPI_DMT_TERMINATOR +}; + +/* 2: Processor Local X2_APIC Affinity (ACPI 4.0) */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoSrat2[] = +{ + {ACPI_DMT_UINT16, ACPI_SRAT2_OFFSET (Reserved), "Reserved1", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (ProximityDomain), "Proximity Domain", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (ApicId), "Apic ID", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_SRAT2_FLAG_OFFSET (Flags,0), "Enabled", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (ClockDomain), "Clock Domain", 0}, + {ACPI_DMT_UINT32, ACPI_SRAT2_OFFSET (Reserved2), "Reserved2", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * TCPA - Trusted Computing Platform Alliance table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoTcpa[] = +{ + {ACPI_DMT_UINT16, ACPI_TCPA_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_TCPA_OFFSET (MaxLogLength), "Max Event Log Length", 0}, + {ACPI_DMT_UINT64, ACPI_TCPA_OFFSET (LogAddress), "Event Log Address", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * UEFI - UEFI Boot optimization Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoUefi[] = +{ + {ACPI_DMT_UUID, ACPI_UEFI_OFFSET (Identifier[0]), "UUID Identifier", 0}, + {ACPI_DMT_UINT16, ACPI_UEFI_OFFSET (DataOffset), "Data Offset", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * WAET - Windows ACPI Emulated devices Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoWaet[] = +{ + {ACPI_DMT_UINT32, ACPI_WAET_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_WAET_OFFSET (Flags), "RTC needs no INT ack", 0}, + {ACPI_DMT_FLAG1, ACPI_WAET_OFFSET (Flags), "PM timer, one read only", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * WDAT - Watchdog Action Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoWdat[] = +{ + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (HeaderLength), "Header Length", DT_LENGTH}, + {ACPI_DMT_UINT16, ACPI_WDAT_OFFSET (PciSegment), "PCI Segment", 0}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciBus), "PCI Bus", 0}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciDevice), "PCI Device", 0}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (PciFunction), "PCI Function", 0}, + {ACPI_DMT_UINT24, ACPI_WDAT_OFFSET (Reserved[0]), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (TimerPeriod), "Timer Period", 0}, + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (MaxCount), "Max Count", 0}, + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (MinCount), "Min Count", 0}, + {ACPI_DMT_UINT8, ACPI_WDAT_OFFSET (Flags), "Flags (decoded below)", DT_FLAG}, + {ACPI_DMT_FLAG0, ACPI_WDAT_OFFSET (Flags), "Enabled", 0}, + {ACPI_DMT_FLAG7, ACPI_WDAT_OFFSET (Flags), "Stopped When Asleep", 0}, + {ACPI_DMT_UINT24, ACPI_WDAT_OFFSET (Reserved2[0]), "Reserved", 0}, + {ACPI_DMT_UINT32, ACPI_WDAT_OFFSET (Entries), "Watchdog Entry Count", 0}, + ACPI_DMT_TERMINATOR +}; + +/* WDAT Subtables - Watchdog Instruction Entries */ + +ACPI_DMTABLE_INFO AcpiDmTableInfoWdat0[] = +{ + {ACPI_DMT_UINT8, ACPI_WDAT0_OFFSET (Action), "Watchdog Action", 0}, + {ACPI_DMT_UINT8, ACPI_WDAT0_OFFSET (Instruction), "Instruction", 0}, + {ACPI_DMT_UINT16, ACPI_WDAT0_OFFSET (Reserved), "Reserved", 0}, + {ACPI_DMT_GAS, ACPI_WDAT0_OFFSET (RegisterRegion), "Register Region", 0}, + {ACPI_DMT_UINT32, ACPI_WDAT0_OFFSET (Value), "Value", 0}, + {ACPI_DMT_UINT32, ACPI_WDAT0_OFFSET (Mask), "Register Mask", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * WDDT - Watchdog Description Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoWddt[] = +{ + {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (SpecVersion), "Specification Version", 0}, + {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (TableVersion), "Table Version", 0}, + {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (PciVendorId), "PCI Vendor ID", 0}, + {ACPI_DMT_GAS, ACPI_WDDT_OFFSET (Address), "Timer Register", 0}, + {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (MaxCount), "Max Count", 0}, + {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (MinCount), "Min Count", 0}, + {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (Period), "Period", 0}, + {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (Status), "Status (decoded below)", 0}, + + /* Status Flags byte 0 */ + + {ACPI_DMT_FLAG0, ACPI_WDDT_FLAG_OFFSET (Status,0), "Available", 0}, + {ACPI_DMT_FLAG1, ACPI_WDDT_FLAG_OFFSET (Status,0), "Active", 0}, + {ACPI_DMT_FLAG2, ACPI_WDDT_FLAG_OFFSET (Status,0), "OS Owns", 0}, + + /* Status Flags byte 1 */ + + {ACPI_DMT_FLAG3, ACPI_WDDT_FLAG_OFFSET (Status,1), "User Reset", 0}, + {ACPI_DMT_FLAG4, ACPI_WDDT_FLAG_OFFSET (Status,1), "Timeout Reset", 0}, + {ACPI_DMT_FLAG5, ACPI_WDDT_FLAG_OFFSET (Status,1), "Power Fail Reset", 0}, + {ACPI_DMT_FLAG6, ACPI_WDDT_FLAG_OFFSET (Status,1), "Unknown Reset", 0}, + + {ACPI_DMT_UINT16, ACPI_WDDT_OFFSET (Capability), "Capability (decoded below)", 0}, + + /* Capability Flags byte 0 */ + + {ACPI_DMT_FLAG0, ACPI_WDDT_FLAG_OFFSET (Capability,0), "Auto Reset", 0}, + {ACPI_DMT_FLAG1, ACPI_WDDT_FLAG_OFFSET (Capability,0), "Timeout Alert", 0}, + ACPI_DMT_TERMINATOR +}; + + +/******************************************************************************* + * + * WDRT - Watchdog Resource Table + * + ******************************************************************************/ + +ACPI_DMTABLE_INFO AcpiDmTableInfoWdrt[] = +{ + {ACPI_DMT_GAS, ACPI_WDRT_OFFSET (ControlRegister), "Control Register", 0}, + {ACPI_DMT_GAS, ACPI_WDRT_OFFSET (CountRegister), "Count Register", 0}, + {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (PciDeviceId), "PCI Device ID", 0}, + {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (PciVendorId), "PCI Vendor ID", 0}, + {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciBus), "PCI Bus", 0}, + {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciDevice), "PCI Device", 0}, + {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciFunction), "PCI Function", 0}, + {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (PciSegment), "PCI Segment", 0}, + {ACPI_DMT_UINT16, ACPI_WDRT_OFFSET (MaxCount), "Max Count", 0}, + {ACPI_DMT_UINT8, ACPI_WDRT_OFFSET (Units), "Counter Units", 0}, + ACPI_DMT_TERMINATOR +}; + +/*! [Begin] no source code translation */ + +/* + * Generic types (used in UEFI and custom tables) + * + * Examples: + * + * Buffer : cc 04 ff bb + * UINT8 : 11 + * UINT16 : 1122 + * UINT24 : 112233 + * UINT32 : 11223344 + * UINT56 : 11223344556677 + * UINT64 : 1122334455667788 + * + * String : "This is string" + * Unicode : "This string encoded to Unicode" + * + * GUID : 11223344-5566-7788-99aa-bbccddeeff00 + * DevicePath : "\PciRoot(0)\Pci(0x1f,1)\Usb(0,0)" + */ + +#define ACPI_DM_GENERIC_ENTRY(FieldType, FieldName) \ + {{FieldType, 0, FieldName, 0}, ACPI_DMT_TERMINATOR} + +ACPI_DMTABLE_INFO AcpiDmTableInfoGeneric[][2] = +{ + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT8, "UINT8"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT16, "UINT16"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT24, "UINT24"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT32, "UINT32"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT40, "UINT40"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT48, "UINT48"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT56, "UINT56"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UINT64, "UINT64"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_STRING, "String"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UNICODE, "Unicode"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_BUFFER, "Buffer"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_UUID, "GUID"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_STRING, "DevicePath"), + ACPI_DM_GENERIC_ENTRY (ACPI_DMT_LABEL, "Label"), + {ACPI_DMT_TERMINATOR} +}; +/*! [End] no source code translation !*/ diff --git a/source/common/getopt.c b/source/common/getopt.c new file mode 100644 index 0000000000000..b253e8a01d6a9 --- /dev/null +++ b/source/common/getopt.c @@ -0,0 +1,173 @@ + +/****************************************************************************** + * + * Module Name: getopt + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#include <stdio.h> +#include <string.h> +#include "acpi.h" +#include "accommon.h" +#include "acapps.h" + +#define ERR(szz,czz) if(AcpiGbl_Opterr){fprintf(stderr,"%s%s%c\n",argv[0],szz,czz);} + + +int AcpiGbl_Opterr = 1; +int AcpiGbl_Optind = 1; +char *AcpiGbl_Optarg; + + +/******************************************************************************* + * + * FUNCTION: AcpiGetopt + * + * PARAMETERS: argc, argv - from main + * opts - options info list + * + * RETURN: Option character or EOF + * + * DESCRIPTION: Get the next option + * + ******************************************************************************/ + +int +AcpiGetopt( + int argc, + char **argv, + char *opts) +{ + static int CurrentCharPtr = 1; + int CurrentChar; + char *OptsPtr; + + + if (CurrentCharPtr == 1) + { + if (AcpiGbl_Optind >= argc || + argv[AcpiGbl_Optind][0] != '-' || + argv[AcpiGbl_Optind][1] == '\0') + { + return(EOF); + } + else if (strcmp (argv[AcpiGbl_Optind], "--") == 0) + { + AcpiGbl_Optind++; + return(EOF); + } + } + + /* Get the option */ + + CurrentChar = argv[AcpiGbl_Optind][CurrentCharPtr]; + + /* Make sure that the option is legal */ + + if (CurrentChar == ':' || + (OptsPtr = strchr (opts, CurrentChar)) == NULL) + { + ERR (": illegal option -- ", CurrentChar); + + if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0') + { + AcpiGbl_Optind++; + CurrentCharPtr = 1; + } + + return ('?'); + } + + /* Option requires an argument? */ + + if (*++OptsPtr == ':') + { + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') + { + AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)]; + } + else if (++AcpiGbl_Optind >= argc) + { + ERR (": option requires an argument -- ", CurrentChar); + + CurrentCharPtr = 1; + return ('?'); + } + else + { + AcpiGbl_Optarg = argv[AcpiGbl_Optind++]; + } + + CurrentCharPtr = 1; + } + + /* Option has optional single-char arguments? */ + + else if (*OptsPtr == '^') + { + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') + { + AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)]; + } + else + { + AcpiGbl_Optarg = "^"; + } + + AcpiGbl_Optind++; + CurrentCharPtr = 1; + } + + /* Option with no arguments */ + + else + { + if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0') + { + CurrentCharPtr = 1; + AcpiGbl_Optind++; + } + + AcpiGbl_Optarg = NULL; + } + + return (CurrentChar); +} |