]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c
ShellPkg: Add acpiview tool to dump ACPI tables
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Xsdt / XsdtParser.c
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c
new file mode 100644 (file)
index 0000000..0ed65d2
--- /dev/null
@@ -0,0 +1,153 @@
+/**\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