--- /dev/null
+/**\r
+ XSDT table parser\r
+\r
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ @par Reference(s):\r
+ - ACPI 6.2 Specification - Errata A, September 2017\r
+**/\r
+\r
+#include <IndustryStandard/Acpi.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/PrintLib.h>\r
+#include "AcpiParser.h"\r
+#include "AcpiTableParser.h"\r
+\r
+// Local variables\r
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
+\r
+/** An ACPI_PARSER array describing the ACPI XSDT table.\r
+*/\r
+STATIC CONST ACPI_PARSER XsdtParser[] = {\r
+ PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
+};\r
+\r
+CONST ACPI_DESCRIPTION_HEADER_INFO* CONST\r
+EFIAPI\r
+GetAcpiXsdtHeaderInfo (\r
+ VOID\r
+)\r
+{\r
+ return &AcpiHdrInfo;\r
+}\r
+\r
+/** This function parses the ACPI XSDT table\r
+ and optionally traces the ACPI table fields.\r
+\r
+ This function also performs validation of the XSDT table.\r
+\r
+ @param [in] Trace If TRUE, trace the ACPI fields.\r
+ @param [in] Ptr Pointer to the start of the buffer.\r
+ @param [in] AcpiTableLength Length of the ACPI table.\r
+ @param [in] AcpiTableRevision Revision of the ACPI table.\r
+*/\r
+VOID\r
+EFIAPI\r
+ParseAcpiXsdt (\r
+ IN BOOLEAN Trace,\r
+ IN UINT8* Ptr,\r
+ IN UINT32 AcpiTableLength,\r
+ IN UINT8 AcpiTableRevision\r
+ )\r
+{\r
+ UINT32 Offset;\r
+ UINT32 TableOffset;\r
+ UINT64* TablePointer;\r
+ UINTN EntryIndex;\r
+ CHAR16 Buffer[32];\r
+\r
+ // Parse the ACPI header to get the length\r
+ ParseAcpi (\r
+ FALSE,\r
+ 0,\r
+ "XSDT",\r
+ Ptr,\r
+ ACPI_DESCRIPTION_HEADER_LENGTH,\r
+ PARSER_PARAMS (XsdtParser)\r
+ );\r
+\r
+ Offset = ParseAcpi (\r
+ Trace,\r
+ 0,\r
+ "XSDT",\r
+ Ptr,\r
+ *AcpiHdrInfo.Length,\r
+ PARSER_PARAMS (XsdtParser)\r
+ );\r
+\r
+ TableOffset = Offset;\r
+\r
+ if (Trace) {\r
+ EntryIndex = 0;\r
+ TablePointer = (UINT64*)(Ptr + TableOffset);\r
+ while (Offset < (*AcpiHdrInfo.Length)) {\r
+ CONST UINT32* Signature;\r
+ CONST UINT32* Length;\r
+ CONST UINT8* Revision;\r
+\r
+ if ((UINT64*)(UINTN)(*TablePointer) != NULL) {\r
+ UINT8* Ptr;\r
+\r
+ ParseAcpiHeader (\r
+ (UINT8*)(UINTN)(*TablePointer),\r
+ &Signature,\r
+ &Length,\r
+ &Revision\r
+ );\r
+\r
+ Ptr = (UINT8*)Signature;\r
+\r
+ UnicodeSPrint (\r
+ Buffer,\r
+ sizeof (Buffer),\r
+ L"Entry[%d] - %c%c%c%c",\r
+ EntryIndex++,\r
+ Ptr[0],\r
+ Ptr[1],\r
+ Ptr[2],\r
+ Ptr[3]\r
+ );\r
+ } else {\r
+ UnicodeSPrint (\r
+ Buffer,\r
+ sizeof (Buffer),\r
+ L"Entry[%d]",\r
+ EntryIndex++\r
+ );\r
+ }\r
+\r
+ PrintFieldName (2, Buffer);\r
+ Print (L"0x%lx\n", *TablePointer);\r
+\r
+ // Validate the table pointers are not NULL\r
+ if ((UINT64*)(UINTN)(*TablePointer) == NULL) {\r
+ IncrementErrorCount ();\r
+ Print (\r
+ L"ERROR: Invalid table entry at 0x%lx, table address is 0x%lx\n",\r
+ TablePointer,\r
+ *TablePointer\r
+ );\r
+ }\r
+ Offset += sizeof (UINT64);\r
+ TablePointer++;\r
+ } // while\r
+ }\r
+\r
+ // Process the tables\r
+ Offset = TableOffset;\r
+ TablePointer = (UINT64*)(Ptr + TableOffset);\r
+ while (Offset < (*AcpiHdrInfo.Length)) {\r
+ if ((UINT64*)(UINTN)(*TablePointer) != NULL) {\r
+ ProcessAcpiTable ((UINT8*)(UINTN)(*TablePointer));\r
+ }\r
+ Offset += sizeof (UINT64);\r
+ TablePointer++;\r
+ } // while\r
+}\r