]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
ShellPkg: Add acpiview tool to dump ACPI tables
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / AcpiTableParser.c
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
new file mode 100644 (file)
index 0000000..14a8b14
--- /dev/null
@@ -0,0 +1,215 @@
+/**\r
+  ACPI 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
+\r
+#include <Uefi.h>\r
+#include <IndustryStandard/Acpi.h>\r
+#include <Library/UefiLib.h>\r
+#include "AcpiParser.h"\r
+#include "AcpiTableParser.h"\r
+#include "AcpiView.h"\r
+\r
+/** A list of registered ACPI table parsers.\r
+*/\r
+STATIC ACPI_TABLE_PARSER mTableParserList[MAX_ACPI_TABLE_PARSERS];\r
+\r
+/** Register the ACPI table Parser\r
+\r
+  This function registers the ACPI table parser.\r
+\r
+  @param [in] Signature   The ACPI table signature.\r
+  @param [in] ParserProc  The ACPI table parser.\r
+\r
+  @retval EFI_SUCCESS           The parser is registered.\r
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+  @retval EFI_ALREADY_STARTED   The parser for the Table\r
+                                was already registered.\r
+  @retval EFI_OUT_OF_RESOURCES  No space to register the\r
+                                parser.\r
+*/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterParser (\r
+  IN  UINT32                  Signature,\r
+  IN  PARSE_ACPI_TABLE_PROC   ParserProc\r
+  )\r
+{\r
+  UINT32 index;\r
+\r
+  if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // Search if a parser is already installed\r
+  for (index = 0;\r
+       index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));\r
+       index++)\r
+  {\r
+    if (Signature == mTableParserList[index].Signature) {\r
+      if (mTableParserList[index].Parser != NULL) {\r
+        return EFI_ALREADY_STARTED;\r
+      }\r
+    }\r
+  }\r
+\r
+  // Find the first free slot and register the parser\r
+  for (index = 0;\r
+      index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));\r
+      index++)\r
+  {\r
+    if (mTableParserList[index].Signature == ACPI_PARSER_SIGNATURE_NULL) {\r
+      mTableParserList[index].Signature = Signature;\r
+      mTableParserList[index].Parser = ParserProc;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  // No free slot found\r
+  return EFI_OUT_OF_RESOURCES;\r
+}\r
+\r
+/** Deregister the ACPI table Parser\r
+\r
+  This function deregisters the ACPI table parser.\r
+\r
+  @param [in] Signature   The ACPI table signature.\r
+\r
+  @retval EFI_SUCCESS           The parser was deregistered.\r
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+  @retval EFI_NOT_FOUND         A registered parser was not found.\r
+*/\r
+EFI_STATUS\r
+EFIAPI\r
+DeregisterParser (\r
+  IN  UINT32                  Signature\r
+  )\r
+{\r
+  UINT32 index;\r
+\r
+  if (Signature == ACPI_PARSER_SIGNATURE_NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  for (index = 0;\r
+       index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));\r
+       index++)\r
+  {\r
+    if (Signature == mTableParserList[index].Signature) {\r
+      mTableParserList[index].Signature = ACPI_PARSER_SIGNATURE_NULL;\r
+      mTableParserList[index].Parser = NULL;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  // No matching registered parser found.\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/** Get the ACPI table Parser\r
+\r
+  This function returns the ACPI table parser proc from the list of\r
+  registered parsers.\r
+\r
+  @param [in]  Signature   The ACPI table signature.\r
+  @param [out] ParserProc  Pointer to a ACPI table parser proc.\r
+\r
+  @retval EFI_SUCCESS           The parser was returned successfully.\r
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+  @retval EFI_NOT_FOUND         A registered parser was not found.\r
+*/\r
+EFI_STATUS\r
+EFIAPI\r
+GetParser (\r
+  IN  UINT32                   Signature,\r
+  OUT PARSE_ACPI_TABLE_PROC *  ParserProc\r
+  )\r
+{\r
+  UINT32 index;\r
+\r
+  if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  for (index = 0;\r
+       index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));\r
+       index++)\r
+  {\r
+    if (Signature == mTableParserList[index].Signature) {\r
+      *ParserProc = mTableParserList[index].Parser;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  // No matching registered parser found.\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/** This function processes the ACPI tables.\r
+  This function calls ProcessTableReportOptions() to list the ACPI\r
+  tables, perform binary dump of the tables and determine if the\r
+  ACPI fields should be traced.\r
+\r
+  This function also invokes the parser for the ACPI tables.\r
+\r
+  This function also performs a RAW dump of the ACPI table including\r
+  the unknown/unparsed ACPI tables and validates the checksum.\r
+\r
+  @param [in] Ptr                Pointer to the start of the ACPI\r
+                                 table data buffer.\r
+*/\r
+VOID\r
+EFIAPI\r
+ProcessAcpiTable (\r
+  IN UINT8* Ptr\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  BOOLEAN       Trace;\r
+  CONST UINT32* AcpiTableSignature;\r
+  CONST UINT32* AcpiTableLength;\r
+  CONST UINT8*  AcpiTableRevision;\r
+  PARSE_ACPI_TABLE_PROC ParserProc;\r
+\r
+  ParseAcpiHeader (\r
+    Ptr,\r
+    &AcpiTableSignature,\r
+    &AcpiTableLength,\r
+    &AcpiTableRevision\r
+    );\r
+\r
+  Trace = ProcessTableReportOptions (\r
+            *AcpiTableSignature,\r
+            Ptr,\r
+            *AcpiTableLength\r
+            );\r
+\r
+  if (Trace) {\r
+    DumpRaw (Ptr, *AcpiTableLength);\r
+    VerifyChecksum (TRUE, Ptr, *AcpiTableLength);\r
+  }\r
+\r
+  Status = GetParser (*AcpiTableSignature, &ParserProc);\r
+  if (EFI_ERROR (Status)) {\r
+    // No registered parser found, do default handling.\r
+    if (Trace) {\r
+      DumpAcpiHeader (Ptr);\r
+    }\r
+    return;\r
+  }\r
+\r
+  ParserProc (\r
+    Trace,\r
+    Ptr,\r
+    *AcpiTableLength,\r
+    *AcpiTableRevision\r
+    );\r
+}\r