Bugzilla: 3697 (https://bugzilla.tianocore.org/show_bug.cgi?id=3697)

Update the PPTT generator with the CacheId field as defined in table
5.140 of the ACPI 6.4 specification.

Also add validations to ensure that the cache id generated is unique.

Signed-off-by: Chris Jones <christopher.jo...@arm.com>
---
 DynamicTablesPkg/Include/ArmNameSpaceObjects.h                   |   4 +-
 DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c | 102 
++++++++++++++++++--
 2 files changed, 96 insertions(+), 10 deletions(-)

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h 
b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 
6bc5ab6b2b28424c1afddc26cc89a54b81941aeb..6e27158d720947efb22a350a7e5ffcfdd3005361
 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -740,10 +740,12 @@ typedef struct CmArmCacheInfo {
   /// PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX. Therfore this field
   /// is 32-bit wide.
   UINT32            Associativity;
-  /// Cache attributes (ACPI 6.3 - January 2019, PPTT, Table 5-156)
+  /// Cache attributes (ACPI 6.4 - January 2021, PPTT, Table 5.140)
   UINT8             Attributes;
   /// Line size in bytes
   UINT16            LineSize;
+  /// Unique ID for the cache
+  UINT32            CacheId;
 } CM_ARM_CACHE_INFO;
 
 /** A structure that describes a reference to another Configuration Manager
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c 
b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
index 
18f093998db57ea4698953ed06a9826df559c1b7..0c22de11c584cfebfcc1600d86290c758a99140a
 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
@@ -722,6 +722,35 @@ AddProcHierarchyNodes (
   return Status;
 }
 
+/**
+  Test whether CacheId is unique among the CacheIdList.
+
+  @param [in]  CacheId          Cache ID to check.
+  @param [in]  CacheIdList      List of already existing cache IDs.
+  @param [in]  CacheIdListSize  Size of CacheIdList.
+
+  @retval TRUE                  CacheId does not exist in CacheIdList.
+  @retval FALSE                 CacheId already exists in CacheIdList.
+**/
+STATIC
+EFI_STATUS
+IsCacheIdUnique(
+  IN CONST UINT32  CacheId,
+  IN CONST UINT32 *CacheIdList,
+  IN CONST UINT32  CacheIdListSize
+  )
+{
+  UINT32 Index;
+
+  for (Index = 0; Index < CacheIdListSize; Index++) {
+    if (CacheIdList[Index] == CacheId) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
 /**
   Update the Cache Type Structure (Type 1) information.
 
@@ -734,10 +763,12 @@ AddProcHierarchyNodes (
   @param [in]  Pptt                 Pointer to PPTT table structure.
   @param [in]  NodesStartOffset     Offset from the start of PPTT table to the
                                     start of Cache Type Structures.
+  @param [in]  Revision             Revision of the PPTT table being requested.
 
   @retval EFI_SUCCESS               Structures updated successfully.
   @retval EFI_INVALID_PARAMETER     A parameter is invalid.
   @retval EFI_NOT_FOUND             A required object was not found.
+  @retval EFI_OUT_OF_RESOURCES      Out of resources.
 **/
 STATIC
 EFI_STATUS
@@ -745,7 +776,8 @@ AddCacheTypeStructures (
   IN  CONST ACPI_PPTT_GENERATOR                   * CONST Generator,
   IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
   IN  CONST EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER * Pptt,
-  IN  CONST UINT32                                        NodesStartOffset
+  IN  CONST UINT32                                        NodesStartOffset,
+  IN  CONST UINT32                                        Revision
   )
 {
   EFI_STATUS                            Status;
@@ -754,6 +786,9 @@ AddCacheTypeStructures (
   CM_ARM_CACHE_INFO                   * CacheInfoNode;
   PPTT_NODE_INDEXER                   * CacheNodeIterator;
   UINT32                                NodeCount;
+  BOOLEAN                               CacheIdUnique;
+  UINT32                                TotalNodeCount;
+  UINT32                              * FoundCacheIds;
 
   ASSERT (
     (Generator != NULL) &&
@@ -766,6 +801,13 @@ AddCacheTypeStructures (
 
   CacheNodeIterator = Generator->CacheStructIndexedList;
   NodeCount = Generator->CacheStructCount;
+  TotalNodeCount = NodeCount;
+
+  FoundCacheIds = AllocateZeroPool (TotalNodeCount * sizeof (*FoundCacheIds));
+  if (FoundCacheIds == NULL) {
+    DEBUG ((DEBUG_ERROR, "ERROR: PPTT: Failed to allocate resources.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
 
   while (NodeCount-- != 0) {
     CacheInfoNode = (CM_ARM_CACHE_INFO*)CacheNodeIterator->Object;
@@ -785,6 +827,7 @@ AddCacheTypeStructures (
     CacheStruct->Flags.CacheTypeValid = 1;
     CacheStruct->Flags.WritePolicyValid = 1;
     CacheStruct->Flags.LineSizeValid = 1;
+    CacheStruct->Flags.CacheIdValid = 1;
     CacheStruct->Flags.Reserved = 0;
 
     // Populate the reference to the next level of cache
@@ -807,7 +850,7 @@ AddCacheTypeStructures (
           CacheInfoNode->Token,
           Status
           ));
-        return Status;
+        goto cleanup;
       }
 
       // Update Cache Structure with the offset for the next level of cache
@@ -831,7 +874,7 @@ AddCacheTypeStructures (
         CacheInfoNode->NumberOfSets,
         Status
         ));
-      return Status;
+      goto cleanup;
     }
 
     if (CacheInfoNode->NumberOfSets > PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX) {
@@ -858,7 +901,7 @@ AddCacheTypeStructures (
         CacheInfoNode->Associativity,
         Status
         ));
-      return Status;
+      goto cleanup;
     }
 
     // Validate the Associativity field based on the architecture specification
@@ -877,7 +920,7 @@ AddCacheTypeStructures (
         CacheInfoNode->Associativity,
         Status
         ));
-      return Status;
+      goto cleanup;
     }
 
     if (CacheInfoNode->Associativity > PPTT_ARM_CACHE_ASSOCIATIVITY_MAX) {
@@ -918,7 +961,7 @@ AddCacheTypeStructures (
         CacheInfoNode->LineSize,
         Status
         ));
-      return Status;
+      goto cleanup;
     }
 
     if ((CacheInfoNode->LineSize & (CacheInfoNode->LineSize - 1)) != 0) {
@@ -930,18 +973,58 @@ AddCacheTypeStructures (
         CacheInfoNode->LineSize,
         Status
         ));
-      return Status;
+      goto cleanup;
     }
 
     CacheStruct->LineSize = CacheInfoNode->LineSize;
 
+    if (Revision >= 3) {
+      // Validate and populate cache id
+      if (CacheInfoNode->CacheId == 0) {
+        Status = EFI_INVALID_PARAMETER;
+        DEBUG ((
+          DEBUG_ERROR,
+          "ERROR: PPTT: The cache id cannot be zero. Status = %r\n",
+          Status
+          ));
+        goto cleanup;
+      }
+
+      CacheIdUnique = IsCacheIdUnique (
+                          CacheInfoNode->CacheId,
+                          FoundCacheIds,
+                          TotalNodeCount
+                          );
+      if (!CacheIdUnique) {
+        Status = EFI_INVALID_PARAMETER;
+        DEBUG ((
+          DEBUG_ERROR,
+          "ERROR: PPTT: The cache id is not unique. " \
+          "CacheId = %d. Status = %r\n",
+          CacheInfoNode->CacheId,
+          Status
+          ));
+        goto cleanup;
+      }
+
+      // Store the cache id so we can check future cache ids for uniqueness
+      FoundCacheIds[NodeCount] = CacheInfoNode->CacheId;
+
+      CacheStruct->CacheId = CacheInfoNode->CacheId;
+    }
+
     // Next Cache Type Structure
     CacheStruct = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE*)((UINT8*)CacheStruct +
                    CacheStruct->Length);
     CacheNodeIterator++;
   } // Cache Type Structure
 
-  return EFI_SUCCESS;
+  Status = EFI_SUCCESS;
+
+cleanup:
+  FreePool (FoundCacheIds);
+
+  return Status;
 }
 
 /**
@@ -1200,7 +1283,8 @@ BuildPpttTable (
                Generator,
                CfgMgrProtocol,
                Pptt,
-               CacheStructOffset
+               CacheStructOffset,
+               AcpiTableInfo->AcpiTableRevision
                );
     if (EFI_ERROR (Status)) {
       DEBUG ((
-- 
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#82235): https://edk2.groups.io/g/devel/message/82235
Mute This Topic: https://groups.io/mt/86416278/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to