]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
ShellPkg/AcpiView: ERST Parser
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / UefiShellAcpiViewCommandLib.c
index c2f40009eeb9b3ac401b481b283f5803797e8261..bbac125bb9aca45768c5d13c52225b549bd38537 100644 (file)
@@ -1,52 +1,78 @@
 /** @file\r
   Main file for 'acpiview' Shell command function.\r
 \r
-  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\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
+  Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.\r
+  Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 **/\r
 \r
 #include <Guid/ShellLibHiiGuid.h>\r
 #include <IndustryStandard/Acpi.h>\r
+#include <IndustryStandard/ArmErrorSourceTable.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
 #include <Library/HiiLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
 #include <Library/ShellCommandLib.h>\r
-#include <Library/UefiLib.h>\r
+#include <Library/ShellLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/AcpiViewCommandLib.h>\r
 #include <Uefi.h>\r
+\r
 #include "AcpiParser.h"\r
 #include "AcpiTableParser.h"\r
 #include "AcpiView.h"\r
-#include "UefiShellAcpiViewCommandLib.h"\r
+#include "AcpiViewConfig.h"\r
 \r
-CONST CHAR16 gShellAcpiViewFileName[] = L"ShellCommand";\r
+CONST CHAR16    gShellAcpiViewFileName[] = L"ShellCommand";\r
+EFI_HII_HANDLE  gShellAcpiViewHiiHandle  = NULL;\r
+\r
+/**\r
+  An array of acpiview command line parameters.\r
+**/\r
+STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {\r
+  { L"-q", TypeFlag  },\r
+  { L"-d", TypeFlag  },\r
+  { L"-h", TypeFlag  },\r
+  { L"-l", TypeFlag  },\r
+  { L"-s", TypeValue },\r
+  { L"-r", TypeValue },\r
+  { NULL,  TypeMax   }\r
+};\r
 \r
 /**\r
   A list of available table parsers.\r
 */\r
 STATIC\r
 CONST\r
-ACPI_TABLE_PARSER ParserList[] = {\r
-  {EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE, ParseAcpiBgrt},\r
-  {EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, ParseAcpiDbg2},\r
-  {EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,\r
-   ParseAcpiDsdt},\r
-  {EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt},\r
-  {EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt},\r
-  {EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, ParseAcpiIort},\r
-  {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt},\r
-  {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,\r
-   ParseAcpiMcfg},\r
-  {RSDP_TABLE_INFO, ParseAcpiRsdp},\r
-  {EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, ParseAcpiSlit},\r
-  {EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, ParseAcpiSpcr},\r
-  {EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, ParseAcpiSrat},\r
-  {EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiSsdt},\r
-  {EFI_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiXsdt}\r
+ACPI_TABLE_PARSER  ParserList[] = {\r
+  { EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE,                                                       ParseAcpiAest },\r
+  { EFI_ACPI_6_4_ARM_PERFORMANCE_MONITORING_UNIT_TABLE_SIGNATURE,                                        ParseAcpiApmt },\r
+  { EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,                                                 ParseAcpiBgrt },\r
+  { EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE,                                                           ParseAcpiDbg2 },\r
+  { EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,\r
+    ParseAcpiDsdt },\r
+  { EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE,                                             ParseAcpiErst },\r
+  { EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,                                              ParseAcpiFacs },\r
+  { EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,                                                 ParseAcpiFadt },\r
+  { EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,                                              ParseAcpiGtdt },\r
+  { EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE,                                         ParseAcpiHmat },\r
+  { EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE,                                                           ParseAcpiIort },\r
+  { EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,                                              ParseAcpiMadt },\r
+  { EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,\r
+    ParseAcpiMcfg },\r
+  { EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,\r
+    ParseAcpiPcct },\r
+  { EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,\r
+    ParseAcpiPptt },\r
+  { RSDP_TABLE_INFO,                                                                                     ParseAcpiRsdp },\r
+  { EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE,                                            ParseAcpiSlit },\r
+  { EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,                                        ParseAcpiSpcr },\r
+  { EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,                                               ParseAcpiSrat },\r
+  { EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,                                           ParseAcpiSsdt },\r
+  { EFI_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,                                            ParseAcpiXsdt }\r
 };\r
 \r
 /**\r
@@ -63,10 +89,11 @@ EFI_STATUS
 RegisterAllParsers (\r
   )\r
 {\r
-  EFI_STATUS Status;\r
-  UINTN Count;\r
+  EFI_STATUS  Status;\r
+  UINTN       Count;\r
 \r
-  Count = sizeof (ParserList) / sizeof (ParserList[0]);\r
+  Status = EFI_SUCCESS;\r
+  Count  = sizeof (ParserList) / sizeof (ParserList[0]);\r
 \r
   while (Count-- != 0) {\r
     Status = RegisterParser (\r
@@ -77,15 +104,74 @@ RegisterAllParsers (
       return Status;\r
     }\r
   }\r
+\r
   return Status;\r
 }\r
 \r
+/**\r
+  Dump a buffer to a file. Print error message if a file cannot be created.\r
+\r
+  @param[in] FileName   The filename that shall be created to contain the buffer.\r
+  @param[in] Buffer     Pointer to buffer that shall be dumped.\r
+  @param[in] BufferSize The size of buffer to be dumped in bytes.\r
+\r
+  @return The number of bytes that were written\r
+**/\r
+UINTN\r
+EFIAPI\r
+ShellDumpBufferToFile (\r
+  IN CONST CHAR16  *FileNameBuffer,\r
+  IN CONST VOID    *Buffer,\r
+  IN CONST UINTN   BufferSize\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  SHELL_FILE_HANDLE  DumpFileHandle;\r
+  UINTN              TransferBytes;\r
+\r
+  Status = ShellOpenFileByName (\r
+             FileNameBuffer,\r
+             &DumpFileHandle,\r
+             EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,\r
+             0\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_GEN_READONLY_MEDIA),\r
+      gShellAcpiViewHiiHandle,\r
+      L"acpiview"\r
+      );\r
+    return 0;\r
+  }\r
+\r
+  TransferBytes = BufferSize;\r
+  Status        = ShellWriteFile (\r
+                    DumpFileHandle,\r
+                    &TransferBytes,\r
+                    (VOID *)Buffer\r
+                    );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    Print (L"ERROR: Failed to write binary file.\n");\r
+    TransferBytes = 0;\r
+  } else {\r
+    Print (L"DONE.\n");\r
+  }\r
+\r
+  ShellCloseFile (&DumpFileHandle);\r
+  return TransferBytes;\r
+}\r
+\r
 /**\r
   Return the file name of the help text file if not using HII.\r
 \r
   @return The string pointer to the file name.\r
 **/\r
-CONST CHAR16*\r
+CONST CHAR16 *\r
 EFIAPI\r
 ShellCommandGetManFileNameAcpiView (\r
   VOID\r
@@ -94,6 +180,207 @@ ShellCommandGetManFileNameAcpiView (
   return gShellAcpiViewFileName;\r
 }\r
 \r
+/**\r
+  Function for 'acpiview' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if internal).\r
+\r
+  @retval SHELL_INVALID_PARAMETER The command line invocation could not be parsed\r
+  @retval SHELL_NOT_FOUND         The command failed\r
+  @retval SHELL_SUCCESS           The command was successful\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunAcpiView (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  SHELL_STATUS       ShellStatus;\r
+  LIST_ENTRY         *Package;\r
+  CHAR16             *ProblemParam;\r
+  SHELL_FILE_HANDLE  TmpDumpFileHandle;\r
+  CONST CHAR16       *MandatoryTableSpecStr;\r
+  CONST CHAR16       *SelectedTableName;\r
+\r
+  // Set configuration defaults\r
+  AcpiConfigSetDefaults ();\r
+\r
+  ShellStatus       = SHELL_SUCCESS;\r
+  Package           = NULL;\r
+  TmpDumpFileHandle = NULL;\r
+\r
+  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
+  if (EFI_ERROR (Status)) {\r
+    if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_PROBLEM),\r
+        gShellAcpiViewHiiHandle,\r
+        L"acpiview",\r
+        ProblemParam\r
+        );\r
+      FreePool (ProblemParam);\r
+    } else {\r
+      Print (L"acpiview: Error processing input parameter(s)\n");\r
+    }\r
+\r
+    ShellStatus = SHELL_INVALID_PARAMETER;\r
+  } else {\r
+    if (ShellCommandLineGetCount (Package) > 1) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_TOO_MANY),\r
+        gShellAcpiViewHiiHandle,\r
+        L"acpiview"\r
+        );\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+    } else if (ShellCommandLineGetFlag (Package, L"-?")) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GET_HELP_ACPIVIEW),\r
+        gShellAcpiViewHiiHandle,\r
+        L"acpiview"\r
+        );\r
+    } else if (ShellCommandLineGetFlag (Package, L"-s") &&\r
+               (ShellCommandLineGetValue (Package, L"-s") == NULL))\r
+    {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_NO_VALUE),\r
+        gShellAcpiViewHiiHandle,\r
+        L"acpiview",\r
+        L"-s"\r
+        );\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+    } else if (ShellCommandLineGetFlag (Package, L"-r") &&\r
+               (ShellCommandLineGetValue (Package, L"-r") == NULL))\r
+    {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_NO_VALUE),\r
+        gShellAcpiViewHiiHandle,\r
+        L"acpiview",\r
+        L"-r"\r
+        );\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+    } else if ((ShellCommandLineGetFlag (Package, L"-s") &&\r
+                ShellCommandLineGetFlag (Package, L"-l")))\r
+    {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_TOO_MANY),\r
+        gShellAcpiViewHiiHandle,\r
+        L"acpiview"\r
+        );\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+    } else if (ShellCommandLineGetFlag (Package, L"-d") &&\r
+               !ShellCommandLineGetFlag (Package, L"-s"))\r
+    {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_GEN_MISSING_OPTION),\r
+        gShellAcpiViewHiiHandle,\r
+        L"acpiview",\r
+        L"-s",\r
+        L"-d"\r
+        );\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+    } else {\r
+      // Turn on colour highlighting if requested\r
+      SetColourHighlighting (ShellCommandLineGetFlag (Package, L"-h"));\r
+\r
+      // Surpress consistency checking if requested\r
+      SetConsistencyChecking (!ShellCommandLineGetFlag (Package, L"-q"));\r
+\r
+      // Evaluate the parameters for mandatory ACPI table presence checks\r
+      SetMandatoryTableValidate (ShellCommandLineGetFlag (Package, L"-r"));\r
+      MandatoryTableSpecStr = ShellCommandLineGetValue (Package, L"-r");\r
+\r
+      if (MandatoryTableSpecStr != NULL) {\r
+        SetMandatoryTableSpec (ShellHexStrToUintn (MandatoryTableSpecStr));\r
+      }\r
+\r
+      if (ShellCommandLineGetFlag (Package, L"-l")) {\r
+        SetReportOption (ReportTableList);\r
+      } else {\r
+        SelectedTableName = ShellCommandLineGetValue (Package, L"-s");\r
+        if (SelectedTableName != NULL) {\r
+          SelectAcpiTable (SelectedTableName);\r
+          SetReportOption (ReportSelected);\r
+\r
+          if (ShellCommandLineGetFlag (Package, L"-d")) {\r
+            // Create a temporary file to check if the media is writable.\r
+            CHAR16  FileNameBuffer[MAX_FILE_NAME_LEN];\r
+            SetReportOption (ReportDumpBinFile);\r
+\r
+            UnicodeSPrint (\r
+              FileNameBuffer,\r
+              sizeof (FileNameBuffer),\r
+              L".\\%s0000.tmp",\r
+              SelectedTableName\r
+              );\r
+\r
+            Status = ShellOpenFileByName (\r
+                       FileNameBuffer,\r
+                       &TmpDumpFileHandle,\r
+                       EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |\r
+                       EFI_FILE_MODE_CREATE,\r
+                       0\r
+                       );\r
+\r
+            if (EFI_ERROR (Status)) {\r
+              ShellStatus       = SHELL_INVALID_PARAMETER;\r
+              TmpDumpFileHandle = NULL;\r
+              ShellPrintHiiEx (\r
+                -1,\r
+                -1,\r
+                NULL,\r
+                STRING_TOKEN (STR_GEN_READONLY_MEDIA),\r
+                gShellAcpiViewHiiHandle,\r
+                L"acpiview"\r
+                );\r
+              goto Done;\r
+            }\r
+\r
+            // Delete Temporary file.\r
+            ShellDeleteFile (&TmpDumpFileHandle);\r
+          } // -d\r
+        } // -s\r
+      }\r
+\r
+      // Parse ACPI Table information\r
+      Status = AcpiView (SystemTable);\r
+      if (EFI_ERROR (Status)) {\r
+        ShellStatus = SHELL_NOT_FOUND;\r
+      }\r
+    }\r
+  }\r
+\r
+Done:\r
+  if (Package != NULL) {\r
+    ShellCommandLineFreeVarList (Package);\r
+  }\r
+\r
+  return ShellStatus;\r
+}\r
+\r
 /**\r
   Constructor for the Shell AcpiView Command library.\r
 \r
@@ -113,11 +400,12 @@ UefiShellAcpiViewCommandLibConstructor (
   IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
-  EFI_STATUS Status;\r
+  EFI_STATUS  Status;\r
+\r
   gShellAcpiViewHiiHandle = NULL;\r
 \r
   // Check Shell Profile Debug1 bit of the profiles mask\r
-  if ((FixedPcdGet8 (PcdShellProfileMask) & BIT1) == 0) {\r
+  if ((PcdGet8 (PcdShellProfileMask) & BIT1) == 0) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -136,6 +424,7 @@ UefiShellAcpiViewCommandLibConstructor (
   if (gShellAcpiViewHiiHandle == NULL) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
+\r
   // Install our Shell command handler\r
   ShellCommandRegisterCommandName (\r
     L"acpiview",\r
@@ -167,5 +456,6 @@ UefiShellAcpiViewCommandLibDestructor (
   if (gShellAcpiViewHiiHandle != NULL) {\r
     HiiRemovePackages (gShellAcpiViewHiiHandle);\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r