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]]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to