/** @file XSDT table parser Copyright (c) 2016 - 2018, ARM Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @par Reference(s): - ACPI 6.2 Specification - Errata A, September 2017 **/ #include #include #include #include "AcpiParser.h" #include "AcpiTableParser.h" // Local variables STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; /** An ACPI_PARSER array describing the ACPI XSDT table. */ STATIC CONST ACPI_PARSER XsdtParser[] = { PARSE_ACPI_HEADER (&AcpiHdrInfo) }; /** Get the ACPI XSDT header info. **/ CONST ACPI_DESCRIPTION_HEADER_INFO * EFIAPI GetAcpiXsdtHeaderInfo ( VOID ) { return &AcpiHdrInfo; } /** This function parses the ACPI XSDT table and optionally traces the ACPI table fields. This function also performs validation of the XSDT table. @param [in] Trace If TRUE, trace the ACPI fields. @param [in] Ptr Pointer to the start of the buffer. @param [in] AcpiTableLength Length of the ACPI table. @param [in] AcpiTableRevision Revision of the ACPI table. **/ VOID EFIAPI ParseAcpiXsdt ( IN BOOLEAN Trace, IN UINT8* Ptr, IN UINT32 AcpiTableLength, IN UINT8 AcpiTableRevision ) { UINT32 Offset; UINT32 TableOffset; UINT64* TablePointer; UINTN EntryIndex; CHAR16 Buffer[32]; // Parse the ACPI header to get the length ParseAcpi ( FALSE, 0, "XSDT", Ptr, ACPI_DESCRIPTION_HEADER_LENGTH, PARSER_PARAMS (XsdtParser) ); Offset = ParseAcpi ( Trace, 0, "XSDT", Ptr, *AcpiHdrInfo.Length, PARSER_PARAMS (XsdtParser) ); TableOffset = Offset; if (Trace) { EntryIndex = 0; TablePointer = (UINT64*)(Ptr + TableOffset); while (Offset < (*AcpiHdrInfo.Length)) { CONST UINT32* Signature; CONST UINT32* Length; CONST UINT8* Revision; if ((UINT64*)(UINTN)(*TablePointer) != NULL) { UINT8* SignaturePtr; ParseAcpiHeader ( (UINT8*)(UINTN)(*TablePointer), &Signature, &Length, &Revision ); SignaturePtr = (UINT8*)Signature; UnicodeSPrint ( Buffer, sizeof (Buffer), L"Entry[%d] - %c%c%c%c", EntryIndex++, SignaturePtr[0], SignaturePtr[1], SignaturePtr[2], SignaturePtr[3] ); } else { UnicodeSPrint ( Buffer, sizeof (Buffer), L"Entry[%d]", EntryIndex++ ); } PrintFieldName (2, Buffer); Print (L"0x%lx\n", *TablePointer); // Validate the table pointers are not NULL if ((UINT64*)(UINTN)(*TablePointer) == NULL) { IncrementErrorCount (); Print ( L"ERROR: Invalid table entry at 0x%lx, table address is 0x%lx\n", TablePointer, *TablePointer ); } Offset += sizeof (UINT64); TablePointer++; } // while } // Process the tables Offset = TableOffset; TablePointer = (UINT64*)(Ptr + TableOffset); while (Offset < (*AcpiHdrInfo.Length)) { if ((UINT64*)(UINTN)(*TablePointer) != NULL) { ProcessAcpiTable ((UINT8*)(UINTN)(*TablePointer)); } Offset += sizeof (UINT64); TablePointer++; } // while }