/****************************************************************************** * * Module Name: dmtable - Support for ACPI tables that contain no AML code * $Revision: 1.11 $ * *****************************************************************************/ /****************************************************************************** * * 1. Copyright Notice * * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp. * All rights reserved. * * 2. License * * 2.1. This is your license from Intel Corp. under its intellectual property * rights. You may have additional license terms from the party that provided * you this software, covering your right to use that party's intellectual * property rights. * * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a * copy of the source code appearing in this file ("Covered Code") an * irrevocable, perpetual, worldwide license under Intel's copyrights in the * base code distributed originally by Intel ("Original Intel Code") to copy, * make derivatives, distribute, use and display any portion of the Covered * Code in any form, with the right to sublicense such rights; and * * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent * license (with the right to sublicense), under only those claims of Intel * patents that are infringed by the Original Intel Code, to make, use, sell, * offer to sell, and import the Covered Code and derivative works thereof * solely to the minimum extent necessary to exercise the above copyright * license, and in no event shall the patent license extend to any additions * to or modifications of the Original Intel Code. No other license or right * is granted directly or by implication, estoppel or otherwise; * * The above copyright and patent license is granted only if the following * conditions are met: * * 3. Conditions * * 3.1. Redistribution of Source with Rights to Further Distribute Source. * Redistribution of source code of any substantial portion of the Covered * Code or modification with rights to further distribute source must include * the above Copyright Notice, the above License, this list of Conditions, * and the following Disclaimer and Export Compliance provision. In addition, * Licensee must cause all Covered Code to which Licensee contributes to * contain a file documenting the changes Licensee made to create that Covered * Code and the date of any change. Licensee must include in that file the * documentation of any changes made by any predecessor Licensee. Licensee * must include a prominent statement that the modification is derived, * directly or indirectly, from Original Intel Code. * * 3.2. Redistribution of Source with no Rights to Further Distribute Source. * Redistribution of source code of any substantial portion of the Covered * Code or modification without rights to further distribute source must * include the following Disclaimer and Export Compliance provision in the * documentation and/or other materials provided with distribution. In * addition, Licensee may not authorize further sublicense of source of any * portion of the Covered Code, and must include terms to the effect that the * license from Licensee to its licensee is limited to the intellectual * property embodied in the software Licensee provides to its licensee, and * not to intellectual property embodied in modifications its licensee may * make. * * 3.3. Redistribution of Executable. Redistribution in executable form of any * substantial portion of the Covered Code or modification must reproduce the * above Copyright Notice, and the following Disclaimer and Export Compliance * provision in the documentation and/or other materials provided with the * distribution. * * 3.4. Intel retains all right, title, and interest in and to the Original * Intel Code. * * 3.5. Neither the name Intel nor any other trademark owned or controlled by * Intel shall be used in advertising or otherwise to promote the sale, use or * other dealings in products derived from or relating to the Covered Code * without prior written authorization from Intel. * * 4. Disclaimer and Export Compliance * * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A * PARTICULAR PURPOSE. * * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY * LIMITED REMEDY. * * 4.3. Licensee shall not export, either directly or indirectly, any of this * software or system incorporating such software without first obtaining any * required license or other approval from the U. S. Department of Commerce or * any other agency or department of the United States Government. In the * event Licensee exports any such software from the United States or * re-exports any such software from a foreign destination, Licensee shall * ensure that the distribution and export/re-export of the software is in * compliance with all laws, regulations, orders, or other restrictions of the * U.S. Export Administration Regulations. Licensee agrees that neither it nor * any of its subsidiaries will export/re-export any technical data, process, * software, or service, directly or indirectly, to any country for which the * United States government or any agency thereof requires an export license, * other governmental approval, or letter of assurance, without first obtaining * such license, approval or letter. * *****************************************************************************/ #include "acpi.h" #include "acdisasm.h" #include "actables.h" /* This module used for application-level code only */ #define _COMPONENT ACPI_CA_DISASSEMBLER ACPI_MODULE_NAME ("dmtable") /* Local Prototypes */ static ACPI_DMTABLE_DATA * AcpiDmGetTableData ( char *Signature); static void AcpiDmCheckAscii ( UINT8 *Target, UINT32 Count); /* These tables map a subtable type to a description string */ static const char *AcpiDmDmarSubnames[] = { "Hardware Unit Definition", "Reserved Memory Region", "Unknown SubTable 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 */ "Unknown SubTable Type" /* Reserved */ }; static const char *AcpiDmSratSubnames[] = { "Processor Local APIC/SAPIC Affinity", "Memory Affinity", "Unknown SubTable Type" /* Reserved */ }; /******************************************************************************* * * ACPI Table Data, indexed by signature. * * 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. * ******************************************************************************/ static ACPI_DMTABLE_DATA AcpiDmTableData[] = { {ACPI_SIG_ASF, NULL, AcpiDmDumpAsf, "Alert Standard Format table"}, {ACPI_SIG_BOOT, AcpiDmTableInfoBoot, NULL, "Simple Boot Flag Table"}, {ACPI_SIG_CPEP, NULL, AcpiDmDumpCpep, "Corrected Platform Error Polling table"}, {ACPI_SIG_DBGP, AcpiDmTableInfoDbgp, NULL, "Debug Port table"}, {ACPI_SIG_DMAR, NULL, AcpiDmDumpDmar, "DMA Remapping table"}, {ACPI_SIG_ECDT, AcpiDmTableInfoEcdt, NULL, "Embedded Controller Boot Resources Table"}, {ACPI_SIG_FADT, NULL, AcpiDmDumpFadt, "Fixed ACPI Description Table"}, {ACPI_SIG_HPET, AcpiDmTableInfoHpet, NULL, "High Precision Event Timer table"}, {ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, "Multiple APIC Description Table"}, {ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, "Memory Mapped Configuration table"}, {ACPI_SIG_RSDT, NULL, AcpiDmDumpRsdt, "Root System Description Table"}, {ACPI_SIG_SBST, AcpiDmTableInfoSbst, NULL, "Smart Battery Specification Table"}, {ACPI_SIG_SLIT, NULL, AcpiDmDumpSlit, "System Locality Information Table"}, {ACPI_SIG_SPCR, AcpiDmTableInfoSpcr, NULL, "Serial Port Console Redirection table"}, {ACPI_SIG_SPMI, AcpiDmTableInfoSpmi, NULL, "Server Platform Management Interface table"}, {ACPI_SIG_SRAT, NULL, AcpiDmDumpSrat, "System Resource Affinity Table"}, {ACPI_SIG_TCPA, AcpiDmTableInfoTcpa, NULL, "Trusted Computing Platform Alliance table"}, {ACPI_SIG_WDRT, AcpiDmTableInfoWdrt, NULL, "Watchdog Resource Table"}, {ACPI_SIG_XSDT, NULL, AcpiDmDumpXsdt, "Extended System Description Table"}, {NULL, NULL, NULL, NULL} }; /******************************************************************************* * * FUNCTION: AcpiTbGenerateChecksum * * PARAMETERS: Table - Pointer to a valid ACPI table (with a * standard ACPI header) * * RETURN: 8 bit checksum of buffer * * DESCRIPTION: Computes an 8 bit checksum of the table. * ******************************************************************************/ UINT8 AcpiTbGenerateChecksum ( ACPI_TABLE_HEADER *Table) { UINT8 Checksum; /* Sum the entire table as-is */ Checksum = AcpiTbChecksum ((UINT8 *) Table, Table->Length); /* Subtract off the existing checksum value in the table */ Checksum = (UINT8) (Checksum - Table->Checksum); /* 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 * ******************************************************************************/ static 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_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 and RSDP. */ 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 { /* * All other tables must use the common ACPI table header, dump it now */ Length = Table->Length; AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHeader); 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); } } /* Always dump the raw table data */ AcpiOsPrintf ("\nRaw Table Data\n\n"); 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) { if (ByteLength) { AcpiOsPrintf ("[%3.3Xh %3.3d% 3d] %28s : ", Offset, Offset, ByteLength, Name); } else { AcpiOsPrintf ("%42s : ", Name); } } void AcpiDmLineHeader2 ( UINT32 Offset, UINT32 ByteLength, char *Name, UINT32 Value) { if (ByteLength) { AcpiOsPrintf ("[%3.3Xh %3.3d% 3d] %24s % 3d : ", Offset, Offset, ByteLength, Name, Value); } else { AcpiOsPrintf ("[%3.3Xh %3.3d ] %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 - Lenghth of this sub-descriptor * Info - Info table for this ACPI table * * RETURN: None * * DESCRIPTION: Display ACPI table contents by walking the Info table. * ******************************************************************************/ void 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; if (!Info) { AcpiOsPrintf ("Display not implemented\n"); return; } /* 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))) { return; } /* 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_MADT: case ACPI_DMT_SRAT: ByteLength = 1; break; case ACPI_DMT_UINT16: case ACPI_DMT_DMAR: ByteLength = 2; break; case ACPI_DMT_UINT24: ByteLength = 3; break; case ACPI_DMT_UINT32: case ACPI_DMT_NAME4: case ACPI_DMT_SIG: ByteLength = 4; break; case ACPI_DMT_NAME6: ByteLength = 6; break; case ACPI_DMT_UINT56: ByteLength = 7; break; case ACPI_DMT_UINT64: case ACPI_DMT_NAME8: ByteLength = 8; break; case ACPI_DMT_STRING: ByteLength = ACPI_STRLEN (ACPI_CAST_PTR (char, Target)) + 1; break; case ACPI_DMT_GAS: AcpiOsPrintf ("\n"); ByteLength = sizeof (ACPI_GENERIC_ADDRESS); break; default: ByteLength = 0; break; } /* 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_FLAGS2: AcpiOsPrintf ("%1.1X\n", (*Target >> 2) & 0x03); break; /* Standard Data Types */ case ACPI_DMT_UINT8: AcpiOsPrintf ("%2.2X\n", *Target); break; case ACPI_DMT_UINT16: AcpiOsPrintf ("%4.4X\n", ACPI_GET16 (Target)); break; case ACPI_DMT_UINT24: AcpiOsPrintf ("%2.2X%2.2X%2.2X\n", *Target, *(Target + 1), *(Target + 2)); break; case ACPI_DMT_UINT32: AcpiOsPrintf ("%8.8X\n", ACPI_GET32 (Target)); break; case ACPI_DMT_UINT56: AcpiOsPrintf ("%6.6X%8.8X\n", ACPI_HIDWORD (ACPI_GET64 (Target)) & 0x00FFFFFF, ACPI_LODWORD (ACPI_GET64 (Target))); break; case ACPI_DMT_UINT64: AcpiOsPrintf ("%8.8X%8.8X\n", ACPI_FORMAT_UINT64 (ACPI_GET64 (Target))); 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, 4); AcpiOsPrintf ("\"%4.4s\" ", Target); TableData = AcpiDmGetTableData (ACPI_CAST_PTR (char, Target)); if (TableData) { AcpiOsPrintf ("/* %s */", TableData->Name); } AcpiOsPrintf ("\n"); break; case ACPI_DMT_NAME4: AcpiDmCheckAscii (Target, 4); AcpiOsPrintf ("\"%4.4s\"\n", Target); break; case ACPI_DMT_NAME6: AcpiDmCheckAscii (Target, 6); AcpiOsPrintf ("\"%6.6s\"\n", Target); break; case ACPI_DMT_NAME8: AcpiDmCheckAscii (Target, 8); AcpiOsPrintf ("\"%8.8s\"\n", Target); break; /* Special Data Types */ case ACPI_DMT_CHKSUM: /* Checksum, display and validate */ AcpiOsPrintf ("%2.2X", *Target); Temp8 = AcpiTbGenerateChecksum (Table); 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 ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target)); break; case ACPI_DMT_GAS: /* Generic Address Structure */ AcpiOsPrintf ("\n"); AcpiDmDumpTable (ACPI_CAST_PTR (ACPI_TABLE_HEADER, Table)->Length, CurrentOffset, Target, 0, AcpiDmTableInfoGas); break; case ACPI_DMT_DMAR: /* DMAR subtable types */ Temp16 = *Target; if (Temp16 > ACPI_DMAR_TYPE_RESERVED) { Temp16 = ACPI_DMAR_TYPE_RESERVED; } AcpiOsPrintf ("%4.4X <%s>\n", *Target, AcpiDmDmarSubnames[Temp16]); break; case ACPI_DMT_MADT: /* MADT subtable types */ Temp8 = *Target; if (Temp8 > ACPI_MADT_TYPE_RESERVED) { Temp8 = ACPI_MADT_TYPE_RESERVED; } AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmMadtSubnames[Temp8]); break; case ACPI_DMT_SRAT: /* SRAT subtable types */ Temp8 = *Target; if (Temp8 > ACPI_SRAT_TYPE_RESERVED) { Temp8 = ACPI_SRAT_TYPE_RESERVED; } AcpiOsPrintf ("%2.2X <%s>\n", *Target, AcpiDmSratSubnames[Temp8]); break; case ACPI_DMT_EXIT: return; default: ACPI_ERROR ((AE_INFO, "**** Invalid table opcode [%X] ****\n", Info->Opcode)); return; } } } /******************************************************************************* * * 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 . * ******************************************************************************/ static void AcpiDmCheckAscii ( UINT8 *Name, UINT32 Count) { UINT32 i; for (i = 0; i < Count; i++) { if (!Name[i] || !isprint (Name[i])) { Name[i] = ' '; } } }