diff options
Diffstat (limited to '')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c new file mode 100644 index 00000000..d081eb86 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c @@ -0,0 +1,251 @@ +/** @file + ACPI table parser + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Sbbr or SBBR - Server Base Boot Requirements + + @par Reference(s): + - Arm Server Base Boot Requirements 1.2, September 2019 +**/ + +#include <Uefi.h> +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) +#include "Arm/SbbrValidator.h" +#endif + +/** + A list of registered ACPI table parsers. +**/ +STATIC ACPI_TABLE_PARSER mTableParserList[MAX_ACPI_TABLE_PARSERS]; + +/** + Register the ACPI table Parser + + This function registers the ACPI table parser. + + @param [in] Signature The ACPI table signature. + @param [in] ParserProc The ACPI table parser. + + @retval EFI_SUCCESS The parser is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The parser for the Table + was already registered. + @retval EFI_OUT_OF_RESOURCES No space to register the + parser. +**/ +EFI_STATUS +EFIAPI +RegisterParser ( + IN UINT32 Signature, + IN PARSE_ACPI_TABLE_PROC ParserProc + ) +{ + UINT32 Index; + + if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) { + return EFI_INVALID_PARAMETER; + } + + // Search if a parser is already installed + for (Index = 0; + Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0])); + Index++) + { + if (Signature == mTableParserList[Index].Signature) { + if (mTableParserList[Index].Parser != NULL) { + return EFI_ALREADY_STARTED; + } + } + } + + // Find the first free slot and register the parser + for (Index = 0; + Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0])); + Index++) + { + if (mTableParserList[Index].Signature == ACPI_PARSER_SIGNATURE_NULL) { + mTableParserList[Index].Signature = Signature; + mTableParserList[Index].Parser = ParserProc; + return EFI_SUCCESS; + } + } + + // No free slot found + return EFI_OUT_OF_RESOURCES; +} + +/** + Deregister the ACPI table Parser + + This function deregisters the ACPI table parser. + + @param [in] Signature The ACPI table signature. + + @retval EFI_SUCCESS The parser was deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND A registered parser was not found. +**/ +EFI_STATUS +EFIAPI +DeregisterParser ( + IN UINT32 Signature + ) +{ + UINT32 Index; + + if (Signature == ACPI_PARSER_SIGNATURE_NULL) { + return EFI_INVALID_PARAMETER; + } + + for (Index = 0; + Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0])); + Index++) + { + if (Signature == mTableParserList[Index].Signature) { + mTableParserList[Index].Signature = ACPI_PARSER_SIGNATURE_NULL; + mTableParserList[Index].Parser = NULL; + return EFI_SUCCESS; + } + } + + // No matching registered parser found. + return EFI_NOT_FOUND; +} + +/** + Get the ACPI table Parser + + This function returns the ACPI table parser proc from the list of + registered parsers. + + @param [in] Signature The ACPI table signature. + @param [out] ParserProc Pointer to a ACPI table parser proc. + + @retval EFI_SUCCESS The parser was returned successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND A registered parser was not found. +**/ +EFI_STATUS +EFIAPI +GetParser ( + IN UINT32 Signature, + OUT PARSE_ACPI_TABLE_PROC * ParserProc + ) +{ + UINT32 Index; + + if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) { + return EFI_INVALID_PARAMETER; + } + + for (Index = 0; + Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0])); + Index++) + { + if (Signature == mTableParserList[Index].Signature) { + *ParserProc = mTableParserList[Index].Parser; + return EFI_SUCCESS; + } + } + + // No matching registered parser found. + return EFI_NOT_FOUND; +} + +/** + This function processes the ACPI tables. + This function calls ProcessTableReportOptions() to list the ACPI + tables, perform binary dump of the tables and determine if the + ACPI fields should be traced. + + This function also invokes the parser for the ACPI tables. + + This function also performs a RAW dump of the ACPI table including + the unknown/unparsed ACPI tables and validates the checksum. + + @param [in] Ptr Pointer to the start of the ACPI + table data buffer. +**/ +VOID +EFIAPI +ProcessAcpiTable ( + IN UINT8* Ptr + ) +{ + EFI_STATUS Status; + BOOLEAN Trace; + CONST UINT32* AcpiTableSignature; + CONST UINT32* AcpiTableLength; + CONST UINT8* AcpiTableRevision; + CONST UINT8* SignaturePtr; + PARSE_ACPI_TABLE_PROC ParserProc; + + ParseAcpiHeader ( + Ptr, + &AcpiTableSignature, + &AcpiTableLength, + &AcpiTableRevision + ); + + Trace = ProcessTableReportOptions ( + *AcpiTableSignature, + Ptr, + *AcpiTableLength + ); + + if (Trace) { + DumpRaw (Ptr, *AcpiTableLength); + + // Do not process the ACPI table any further if the table length read + // is invalid. The ACPI table should at least contain the table header. + if (*AcpiTableLength < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) { + SignaturePtr = (CONST UINT8*)AcpiTableSignature; + IncrementErrorCount (); + Print ( + L"ERROR: Invalid %c%c%c%c table length. Length = %d\n", + SignaturePtr[0], + SignaturePtr[1], + SignaturePtr[2], + SignaturePtr[3], + *AcpiTableLength + ); + return; + } + + if (GetConsistencyChecking ()) { + VerifyChecksum (TRUE, Ptr, *AcpiTableLength); + } + } + +#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + if (GetMandatoryTableValidate ()) { + ArmSbbrIncrementTableCount (*AcpiTableSignature); + } +#endif + + Status = GetParser (*AcpiTableSignature, &ParserProc); + if (EFI_ERROR (Status)) { + // No registered parser found, do default handling. + if (Trace) { + DumpAcpiHeader (Ptr); + } + return; + } + + ParserProc ( + Trace, + Ptr, + *AcpiTableLength, + *AcpiTableRevision + ); +} |