Bugzilla: 3773 (https://bugzilla.tianocore.org/show_bug.cgi?id=3773)
Add a store for useful ACPI data that can be used in validation. This data will be collected from the parsers, stored in the data store and then can be accessed by validators once all parsing is complete. The data is stored dynamically as nodes in a linked list that is accessed by META_DATA_TYPE. Signed-off-by: Chris Jones <[email protected]> --- ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c | 6 + ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf | 2 + ShellPkg/Library/UefiShellAcpiViewCommandLib/Validators/AcpiDataStore.c | 179 ++++++++++++++++++++ ShellPkg/Library/UefiShellAcpiViewCommandLib/Validators/AcpiDataStore.h | 101 +++++++++++ 4 files changed, 288 insertions(+) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c index d4d5d907f613589c400544533e950460eed2ce3f..a8e0342591931ea3c91e18a6c5cdfa23073b1dcc 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c @@ -23,6 +23,7 @@ #include "AcpiView.h" #include "AcpiViewConfig.h" #include "Validators/AcpiValidation.h" +#include "Validators/AcpiDataStore.h" STATIC UINT32 mTableCount; STATIC UINT32 mBinTableCount; @@ -218,6 +219,9 @@ AcpiView ( ResetErrorCount (); ResetWarningCount (); + // Initialise the ACPI data store + InitAcpiDataStore (); + // Retrieve the user selection of ACPI table to process GetSelectedAcpiTable (&SelectedTable); @@ -294,6 +298,8 @@ AcpiView ( RunValidator (ValidatorId); } + FreeAcpiDataStore (); + OriginalAttribute = gST->ConOut->Mode->Attribute; Print (L"\nTable Statistics:\n"); diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf index 245ccc811e199ebc511a42989a2024433cbb1a84..04913451289ebaf013e8290e46b462a554c9d825 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf @@ -51,6 +51,8 @@ [Sources.common] Parsers/Xsdt/XsdtParser.c Validators/AcpiValidation.c Validators/AcpiValidation.h + Validators/AcpiDataStore.c + Validators/AcpiDataStore.h Validators/AcpiStandard/AcpiStandardValidator.c UefiShellAcpiViewCommandLib.c UefiShellAcpiViewCommandLib.uni diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Validators/AcpiDataStore.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Validators/AcpiDataStore.c new file mode 100644 index 0000000000000000000000000000000000000000..3a89e814d2b2e8761cb4ea6567aa941800dea96b --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Validators/AcpiDataStore.c @@ -0,0 +1,179 @@ +/** @file + Storing and accessing ACPI data collected from parsers. + + Copyright (c) 2021, Arm Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <Library/MemoryAllocationLib.h> +#include "AcpiDataStore.h" + +STATIC META_DATA_NODE mAcpiData[MetaDataMax]; + +/** + Initialise the ACPI data store. +**/ +VOID +EFIAPI +InitAcpiDataStore ( + VOID + ) +{ + UINTN Index; + + for (Index = 0; Index < MetaDataMax; Index++) { + InitializeListHead (&mAcpiData[Index].Link); + } +} + +/** + Return the number of meta data nodes in a linked list of meta data. + + @param [in] Type META_DATA_TYPE of data to get length of. + @param [out] Length Length of the linked list. + + @retval EFI_NOT_FOUND ACPI data with the given type cannot be found. + @retval EFI_SUCCESS Successfully returned the length of the linked list. +**/ +EFI_STATUS +EFIAPI +GetMetaDataCount ( + IN META_DATA_TYPE Type, + OUT UINTN *Length + ) +{ + META_DATA_NODE *Node; + + *Length = 0; + + if (Type >= MetaDataMax) { + Print (L"ERROR: Meta data type is not recognised.\n"); + return EFI_INVALID_PARAMETER; + } + + Node = (META_DATA_NODE *)GetFirstNode (&mAcpiData[Type].Link); + + while (!IsNull (&mAcpiData[Type].Link, &Node->Link)) { + (*Length)++; + Node = (META_DATA_NODE *)GetNextNode (&mAcpiData[Type].Link, &Node->Link); + } + + return EFI_SUCCESS; +} + +/** + Get ACPI meta data of the given type. + + @param [in] Type META_DATA_TYPE of data to return. + @param [out] ListHead The head of a linked list of META_DATA_NODE's. + + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND ACPI data with the given type cannot be found. + @retval EFI_SUCCESS Successfully returned the desired list of Nodes. +**/ +EFI_STATUS +EFIAPI +GetMetaDataListHead ( + IN META_DATA_TYPE Type, + OUT META_DATA_NODE **ListHead + ) +{ + if (Type >= MetaDataMax) { + Print (L"ERROR: Meta data type is not recognised.\n"); + return EFI_INVALID_PARAMETER; + } + + if (ListHead == NULL) { + Print (L"ERROR: List head is NULL.\n"); + return EFI_INVALID_PARAMETER; + } + + if (IsListEmpty (&mAcpiData[Type].Link)) { + *ListHead = NULL; + return EFI_NOT_FOUND; + } + + *ListHead = &mAcpiData[Type]; + + return EFI_SUCCESS; +} + +/** + Store ACPI meta data as a new node in the data store. + + @param [in] ListType Type of linked list to store the data in. + @param [in] NodeType Type to give to the node that stores the data. + @param [in] Ptr Pointer to the data to store. + @param [in] Length Length of the data being stored (Ptr). + + @retval EFI_OUT_OF_RESOURCES Not enough resources to allocate the data. + @retval EFI_SUCCESS Successfully stored the data. +**/ +EFI_STATUS +EFIAPI +StoreAcpiMetaData ( + IN META_DATA_TYPE ListType, + IN META_DATA_TYPE NodeType, + IN VOID *Ptr, + IN UINT8 Length + ) +{ + META_DATA_NODE *Node; + UINT8 *Data; + + if ((ListType >= MetaDataMax) || (NodeType >= MetaDataMax)) { + Print (L"ERROR: Meta data type is not recognised.\n"); + return EFI_INVALID_PARAMETER; + } + + Node = AllocateZeroPool (sizeof (META_DATA_NODE)); + if (Node == NULL) { + Print (L"ERROR: Failed to allocate resources for new node.\n"); + return EFI_OUT_OF_RESOURCES; + } + + // Allocate and assign memory for the data to be stored. + Data = AllocateCopyPool (Length, Ptr); + if (Data == NULL) { + FreePool (Node); + Print (L"ERROR: Failed to allocate resources for node data.\n"); + return EFI_OUT_OF_RESOURCES; + } + + // Assign fields. + Node->Type = NodeType; + Node->Data = Data; + Node->Length = Length; + + InsertTailList (&mAcpiData[ListType].Link, &Node->Link); + + return EFI_SUCCESS; +} + +/** + Free all ACPI data currently stored in the data store. +**/ +VOID +EFIAPI +FreeAcpiDataStore ( + VOID + ) +{ + UINTN Index; + META_DATA_NODE *Node; + META_DATA_NODE *TmpNode; + + for (Index = 0; Index < MetaDataMax; Index++) { + Node = (META_DATA_NODE *)GetFirstNode (&mAcpiData[Index].Link); + + while (!IsNull (&mAcpiData[Index].Link, &Node->Link)) { + TmpNode = Node; + Node = (META_DATA_NODE *)RemoveEntryList (&TmpNode->Link); + FreePool (TmpNode->Data); + FreePool (TmpNode); + } + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Validators/AcpiDataStore.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Validators/AcpiDataStore.h new file mode 100644 index 0000000000000000000000000000000000000000..dfe45665372bae2516860d6c4e8d360ba88f906c --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Validators/AcpiDataStore.h @@ -0,0 +1,101 @@ +/** @file + Header file for storing and accessing ACPI data from parsers. + + Copyright (c) 2021, Arm Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef ACPI_DATA_STORE_H_ +#define ACPI_DATA_STORE_H_ + +/** + Types of data that can be stored and accessed in the ACPI data store. +**/ +typedef enum MetaDataType { + MetaDataPpttProcs = 0, ///< List of all PPTT processor structures. + MetaDataMadtGicC = 1, ///< List of all MADT GICC structures. + MetaDataMax +} META_DATA_TYPE; + +/** + A node containing data about an ACPI table. +**/ +typedef struct MetaDataNode { + LIST_ENTRY Link; ///< Linked list entry. + META_DATA_TYPE Type; ///< Type of meta data. + UINT8 Length; ///< Length of meta data. + VOID *Data; ///< Pointer to the meta data. +} META_DATA_NODE; + +/** + Initialise the ACPI data store. +**/ +VOID +EFIAPI +InitAcpiDataStore ( + VOID + ); + +/** + Return the number of meta data nodes in a linked list of meta data. + + @param [in] Type META_DATA_TYPE of data to get length of. + @param [out] Length Length of the linked list. + + @retval EFI_NOT_FOUND ACPI data with the given type cannot be found. + @retval EFI_SUCCESS Successfully returned the length of the linked list. +**/ +EFI_STATUS +EFIAPI +GetMetaDataCount ( + IN META_DATA_TYPE Type, + OUT UINTN *Length + ); + +/** + Get ACPI meta data of the given type. + + @param [in] Type META_DATA_TYPE of data to return. + @param [out] ListHead The head of a linked list of META_DATA_NODE's. + + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND ACPI data with the given type cannot be found. + @retval EFI_SUCCESS Successfully returned the desired list of Nodes. +**/ +EFI_STATUS +EFIAPI +GetMetaDataListHead ( + IN META_DATA_TYPE Type, + OUT META_DATA_NODE **ListHead + ); + +/** + Store ACPI meta data as a new node in the data store. + + @param [in] ListType Type of linked list to store the data in. + @param [in] NodeType Type to give to the node that stores the data. + @param [in] Ptr Pointer to the data to store. + @param [in] Length Length of the data being stored (Ptr). + + @retval EFI_OUT_OF_RESOURCES Not enough resources to allocate the data. + @retval EFI_SUCCESS Successfully stored the data. +**/ +EFI_STATUS +EFIAPI +StoreAcpiMetaData ( + IN META_DATA_TYPE ListType, + IN META_DATA_TYPE NodeType, + IN VOID *Ptr, + IN UINT8 Length + ); + +/** + Free all ACPI data currently stored in the data store. +**/ +VOID +EFIAPI +FreeAcpiDataStore ( + VOID + ); + +#endif -- Guid("CE165669-3EF3-493F-B85D-6190EE5B9759") -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#84916): https://edk2.groups.io/g/devel/message/84916 Mute This Topic: https://groups.io/mt/87748588/21656 Group Owner: [email protected] Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
