Add a new parser for the Error Record Serialization Table. The ERST table describes how an OS can save and retrieve hardware error information to and from a persistent store. Signed-off-by: Jeshua Smith <jeshuas@nvidia.com> Reviewed-by: Zhichao Gao <zhichao.gao@intel.com>
		
			
				
	
	
		
			462 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			462 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Main file for 'acpiview' Shell command function.
 | |
| 
 | |
|   Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
 | |
|   Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| **/
 | |
| 
 | |
| #include <Guid/ShellLibHiiGuid.h>
 | |
| #include <IndustryStandard/Acpi.h>
 | |
| #include <IndustryStandard/ArmErrorSourceTable.h>
 | |
| 
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/HiiLib.h>
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| #include <Library/PrintLib.h>
 | |
| #include <Library/ShellCommandLib.h>
 | |
| #include <Library/ShellLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/UefiLib.h>
 | |
| #include <Library/AcpiViewCommandLib.h>
 | |
| #include <Uefi.h>
 | |
| 
 | |
| #include "AcpiParser.h"
 | |
| #include "AcpiTableParser.h"
 | |
| #include "AcpiView.h"
 | |
| #include "AcpiViewConfig.h"
 | |
| 
 | |
| CONST CHAR16    gShellAcpiViewFileName[] = L"ShellCommand";
 | |
| EFI_HII_HANDLE  gShellAcpiViewHiiHandle  = NULL;
 | |
| 
 | |
| /**
 | |
|   An array of acpiview command line parameters.
 | |
| **/
 | |
| STATIC CONST SHELL_PARAM_ITEM  ParamList[] = {
 | |
|   { L"-q", TypeFlag  },
 | |
|   { L"-d", TypeFlag  },
 | |
|   { L"-h", TypeFlag  },
 | |
|   { L"-l", TypeFlag  },
 | |
|   { L"-s", TypeValue },
 | |
|   { L"-r", TypeValue },
 | |
|   { NULL,  TypeMax   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   A list of available table parsers.
 | |
| */
 | |
| STATIC
 | |
| CONST
 | |
| ACPI_TABLE_PARSER  ParserList[] = {
 | |
|   { EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE,                                                       ParseAcpiAest },
 | |
|   { EFI_ACPI_6_4_ARM_PERFORMANCE_MONITORING_UNIT_TABLE_SIGNATURE,                                        ParseAcpiApmt },
 | |
|   { EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,                                                 ParseAcpiBgrt },
 | |
|   { EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE,                                                           ParseAcpiDbg2 },
 | |
|   { EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
 | |
|     ParseAcpiDsdt },
 | |
|   { EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE,                                             ParseAcpiErst },
 | |
|   { EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,                                              ParseAcpiFacs },
 | |
|   { EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,                                                 ParseAcpiFadt },
 | |
|   { EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,                                              ParseAcpiGtdt },
 | |
|   { EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE,                                         ParseAcpiHmat },
 | |
|   { EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE,                                                           ParseAcpiIort },
 | |
|   { EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,                                              ParseAcpiMadt },
 | |
|   { EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
 | |
|     ParseAcpiMcfg },
 | |
|   { EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
 | |
|     ParseAcpiPcct },
 | |
|   { EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
 | |
|     ParseAcpiPptt },
 | |
|   { RSDP_TABLE_INFO,                                                                                     ParseAcpiRsdp },
 | |
|   { EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE,                                            ParseAcpiSlit },
 | |
|   { EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,                                        ParseAcpiSpcr },
 | |
|   { EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,                                               ParseAcpiSrat },
 | |
|   { EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,                                           ParseAcpiSsdt },
 | |
|   { EFI_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,                                            ParseAcpiXsdt }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   This function registers all the available table parsers.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The parser is registered.
 | |
|   @retval EFI_ALREADY_STARTED   The parser for the ACPI Table
 | |
|                                 was already registered.
 | |
|   @retval EFI_INVALID_PARAMETER A parameter is invalid.
 | |
|   @retval EFI_OUT_OF_RESOURCES  No space to register the
 | |
|                                 parser.
 | |
| **/
 | |
| EFI_STATUS
 | |
| RegisterAllParsers (
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINTN       Count;
 | |
| 
 | |
|   Status = EFI_SUCCESS;
 | |
|   Count  = sizeof (ParserList) / sizeof (ParserList[0]);
 | |
| 
 | |
|   while (Count-- != 0) {
 | |
|     Status = RegisterParser (
 | |
|                ParserList[Count].Signature,
 | |
|                ParserList[Count].Parser
 | |
|                );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump a buffer to a file. Print error message if a file cannot be created.
 | |
| 
 | |
|   @param[in] FileName   The filename that shall be created to contain the buffer.
 | |
|   @param[in] Buffer     Pointer to buffer that shall be dumped.
 | |
|   @param[in] BufferSize The size of buffer to be dumped in bytes.
 | |
| 
 | |
|   @return The number of bytes that were written
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| ShellDumpBufferToFile (
 | |
|   IN CONST CHAR16  *FileNameBuffer,
 | |
|   IN CONST VOID    *Buffer,
 | |
|   IN CONST UINTN   BufferSize
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS         Status;
 | |
|   SHELL_FILE_HANDLE  DumpFileHandle;
 | |
|   UINTN              TransferBytes;
 | |
| 
 | |
|   Status = ShellOpenFileByName (
 | |
|              FileNameBuffer,
 | |
|              &DumpFileHandle,
 | |
|              EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
 | |
|              0
 | |
|              );
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ShellPrintHiiEx (
 | |
|       -1,
 | |
|       -1,
 | |
|       NULL,
 | |
|       STRING_TOKEN (STR_GEN_READONLY_MEDIA),
 | |
|       gShellAcpiViewHiiHandle,
 | |
|       L"acpiview"
 | |
|       );
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   TransferBytes = BufferSize;
 | |
|   Status        = ShellWriteFile (
 | |
|                     DumpFileHandle,
 | |
|                     &TransferBytes,
 | |
|                     (VOID *)Buffer
 | |
|                     );
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"ERROR: Failed to write binary file.\n");
 | |
|     TransferBytes = 0;
 | |
|   } else {
 | |
|     Print (L"DONE.\n");
 | |
|   }
 | |
| 
 | |
|   ShellCloseFile (&DumpFileHandle);
 | |
|   return TransferBytes;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Return the file name of the help text file if not using HII.
 | |
| 
 | |
|   @return The string pointer to the file name.
 | |
| **/
 | |
| CONST CHAR16 *
 | |
| EFIAPI
 | |
| ShellCommandGetManFileNameAcpiView (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   return gShellAcpiViewFileName;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Function for 'acpiview' command.
 | |
| 
 | |
|   @param[in] ImageHandle  Handle to the Image (NULL if internal).
 | |
|   @param[in] SystemTable  Pointer to the System Table (NULL if internal).
 | |
| 
 | |
|   @retval SHELL_INVALID_PARAMETER The command line invocation could not be parsed
 | |
|   @retval SHELL_NOT_FOUND         The command failed
 | |
|   @retval SHELL_SUCCESS           The command was successful
 | |
| **/
 | |
| SHELL_STATUS
 | |
| EFIAPI
 | |
| ShellCommandRunAcpiView (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS         Status;
 | |
|   SHELL_STATUS       ShellStatus;
 | |
|   LIST_ENTRY         *Package;
 | |
|   CHAR16             *ProblemParam;
 | |
|   SHELL_FILE_HANDLE  TmpDumpFileHandle;
 | |
|   CONST CHAR16       *MandatoryTableSpecStr;
 | |
|   CONST CHAR16       *SelectedTableName;
 | |
| 
 | |
|   // Set configuration defaults
 | |
|   AcpiConfigSetDefaults ();
 | |
| 
 | |
|   ShellStatus       = SHELL_SUCCESS;
 | |
|   Package           = NULL;
 | |
|   TmpDumpFileHandle = NULL;
 | |
| 
 | |
|   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
 | |
|       ShellPrintHiiEx (
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_GEN_PROBLEM),
 | |
|         gShellAcpiViewHiiHandle,
 | |
|         L"acpiview",
 | |
|         ProblemParam
 | |
|         );
 | |
|       FreePool (ProblemParam);
 | |
|     } else {
 | |
|       Print (L"acpiview: Error processing input parameter(s)\n");
 | |
|     }
 | |
| 
 | |
|     ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|   } else {
 | |
|     if (ShellCommandLineGetCount (Package) > 1) {
 | |
|       ShellPrintHiiEx (
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_GEN_TOO_MANY),
 | |
|         gShellAcpiViewHiiHandle,
 | |
|         L"acpiview"
 | |
|         );
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     } else if (ShellCommandLineGetFlag (Package, L"-?")) {
 | |
|       ShellPrintHiiEx (
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_GET_HELP_ACPIVIEW),
 | |
|         gShellAcpiViewHiiHandle,
 | |
|         L"acpiview"
 | |
|         );
 | |
|     } else if (ShellCommandLineGetFlag (Package, L"-s") &&
 | |
|                (ShellCommandLineGetValue (Package, L"-s") == NULL))
 | |
|     {
 | |
|       ShellPrintHiiEx (
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_GEN_NO_VALUE),
 | |
|         gShellAcpiViewHiiHandle,
 | |
|         L"acpiview",
 | |
|         L"-s"
 | |
|         );
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     } else if (ShellCommandLineGetFlag (Package, L"-r") &&
 | |
|                (ShellCommandLineGetValue (Package, L"-r") == NULL))
 | |
|     {
 | |
|       ShellPrintHiiEx (
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_GEN_NO_VALUE),
 | |
|         gShellAcpiViewHiiHandle,
 | |
|         L"acpiview",
 | |
|         L"-r"
 | |
|         );
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     } else if ((ShellCommandLineGetFlag (Package, L"-s") &&
 | |
|                 ShellCommandLineGetFlag (Package, L"-l")))
 | |
|     {
 | |
|       ShellPrintHiiEx (
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_GEN_TOO_MANY),
 | |
|         gShellAcpiViewHiiHandle,
 | |
|         L"acpiview"
 | |
|         );
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     } else if (ShellCommandLineGetFlag (Package, L"-d") &&
 | |
|                !ShellCommandLineGetFlag (Package, L"-s"))
 | |
|     {
 | |
|       ShellPrintHiiEx (
 | |
|         -1,
 | |
|         -1,
 | |
|         NULL,
 | |
|         STRING_TOKEN (STR_GEN_MISSING_OPTION),
 | |
|         gShellAcpiViewHiiHandle,
 | |
|         L"acpiview",
 | |
|         L"-s",
 | |
|         L"-d"
 | |
|         );
 | |
|       ShellStatus = SHELL_INVALID_PARAMETER;
 | |
|     } else {
 | |
|       // Turn on colour highlighting if requested
 | |
|       SetColourHighlighting (ShellCommandLineGetFlag (Package, L"-h"));
 | |
| 
 | |
|       // Surpress consistency checking if requested
 | |
|       SetConsistencyChecking (!ShellCommandLineGetFlag (Package, L"-q"));
 | |
| 
 | |
|       // Evaluate the parameters for mandatory ACPI table presence checks
 | |
|       SetMandatoryTableValidate (ShellCommandLineGetFlag (Package, L"-r"));
 | |
|       MandatoryTableSpecStr = ShellCommandLineGetValue (Package, L"-r");
 | |
| 
 | |
|       if (MandatoryTableSpecStr != NULL) {
 | |
|         SetMandatoryTableSpec (ShellHexStrToUintn (MandatoryTableSpecStr));
 | |
|       }
 | |
| 
 | |
|       if (ShellCommandLineGetFlag (Package, L"-l")) {
 | |
|         SetReportOption (ReportTableList);
 | |
|       } else {
 | |
|         SelectedTableName = ShellCommandLineGetValue (Package, L"-s");
 | |
|         if (SelectedTableName != NULL) {
 | |
|           SelectAcpiTable (SelectedTableName);
 | |
|           SetReportOption (ReportSelected);
 | |
| 
 | |
|           if (ShellCommandLineGetFlag (Package, L"-d")) {
 | |
|             // Create a temporary file to check if the media is writable.
 | |
|             CHAR16  FileNameBuffer[MAX_FILE_NAME_LEN];
 | |
|             SetReportOption (ReportDumpBinFile);
 | |
| 
 | |
|             UnicodeSPrint (
 | |
|               FileNameBuffer,
 | |
|               sizeof (FileNameBuffer),
 | |
|               L".\\%s0000.tmp",
 | |
|               SelectedTableName
 | |
|               );
 | |
| 
 | |
|             Status = ShellOpenFileByName (
 | |
|                        FileNameBuffer,
 | |
|                        &TmpDumpFileHandle,
 | |
|                        EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |
 | |
|                        EFI_FILE_MODE_CREATE,
 | |
|                        0
 | |
|                        );
 | |
| 
 | |
|             if (EFI_ERROR (Status)) {
 | |
|               ShellStatus       = SHELL_INVALID_PARAMETER;
 | |
|               TmpDumpFileHandle = NULL;
 | |
|               ShellPrintHiiEx (
 | |
|                 -1,
 | |
|                 -1,
 | |
|                 NULL,
 | |
|                 STRING_TOKEN (STR_GEN_READONLY_MEDIA),
 | |
|                 gShellAcpiViewHiiHandle,
 | |
|                 L"acpiview"
 | |
|                 );
 | |
|               goto Done;
 | |
|             }
 | |
| 
 | |
|             // Delete Temporary file.
 | |
|             ShellDeleteFile (&TmpDumpFileHandle);
 | |
|           } // -d
 | |
|         } // -s
 | |
|       }
 | |
| 
 | |
|       // Parse ACPI Table information
 | |
|       Status = AcpiView (SystemTable);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         ShellStatus = SHELL_NOT_FOUND;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
| Done:
 | |
|   if (Package != NULL) {
 | |
|     ShellCommandLineFreeVarList (Package);
 | |
|   }
 | |
| 
 | |
|   return ShellStatus;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Constructor for the Shell AcpiView Command library.
 | |
| 
 | |
|   Install the handlers for acpiview UEFI Shell command.
 | |
| 
 | |
|   @param ImageHandle            The image handle of the process.
 | |
|   @param SystemTable            The EFI System Table pointer.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The Shell command handlers were installed
 | |
|                                 successfully.
 | |
|   @retval EFI_DEVICE_ERROR      Hii package failed to install.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| UefiShellAcpiViewCommandLibConstructor (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   gShellAcpiViewHiiHandle = NULL;
 | |
| 
 | |
|   // Check Shell Profile Debug1 bit of the profiles mask
 | |
|   if ((PcdGet8 (PcdShellProfileMask) & BIT1) == 0) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   Status = RegisterAllParsers ();
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"acpiview: Error failed to register parser.\n");
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   gShellAcpiViewHiiHandle = HiiAddPackages (
 | |
|                               &gShellAcpiViewHiiGuid,
 | |
|                               gImageHandle,
 | |
|                               UefiShellAcpiViewCommandLibStrings,
 | |
|                               NULL
 | |
|                               );
 | |
|   if (gShellAcpiViewHiiHandle == NULL) {
 | |
|     return EFI_DEVICE_ERROR;
 | |
|   }
 | |
| 
 | |
|   // Install our Shell command handler
 | |
|   ShellCommandRegisterCommandName (
 | |
|     L"acpiview",
 | |
|     ShellCommandRunAcpiView,
 | |
|     ShellCommandGetManFileNameAcpiView,
 | |
|     0,
 | |
|     L"acpiview",
 | |
|     TRUE,
 | |
|     gShellAcpiViewHiiHandle,
 | |
|     STRING_TOKEN (STR_GET_HELP_ACPIVIEW)
 | |
|     );
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Destructor for the library. free any resources.
 | |
| 
 | |
|   @param ImageHandle            The image handle of the process.
 | |
|   @param SystemTable            The EFI System Table pointer.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| UefiShellAcpiViewCommandLibDestructor (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   if (gShellAcpiViewHiiHandle != NULL) {
 | |
|     HiiRemovePackages (gShellAcpiViewHiiHandle);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |