public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "levi.yun" <yeoreum.yun@arm.com>
To: devel@edk2.groups.io
Cc: yeoreum.yun@arm.com, sami.mujawar@arm.com,
	pierre.gondois@arm.com, nd@arm.com, thomas.abraham@arm.com
Subject: [edk2-devel] [PATCH v1 edk2-platform 2/2] VExpressPkg/ConfigurationManger: Add PPTT generation.
Date: Fri,  5 Jul 2024 14:22:31 +0100	[thread overview]
Message-ID: <20240705132231.1574767-3-yeoreum.yun@arm.com> (raw)
In-Reply-To: <20240705132231.1574767-2-yeoreum.yun@arm.com>

From: "Levi Yun" <yeoreum.yun@arm.com>

Add PPTT generation information for Base FVP platform.

The Base FVP platform can configure cache size/line size/ways.
PPTT cache description can be modified at build time through PCDs
to match the FVP setup.

Also, whether model is RevC or not, Base FVP use multi thread compatible or not.

Change static definition of hierarchy node information to generate it
dynamically and allocate cache information & private resource
dynamically too.

Signed-off-by: Levi Yun <yeoreum.yun@arm.com>
---
 Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf |  14 +
 Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h      | 154 ++-
 Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c      | 987 +++++++++++++++++++-
 3 files changed, 1147 insertions(+), 8 deletions(-)

diff --git a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
index dd08f8597768d4de62941c5fd74e329c431582b0..c4adb60fd30cbba61fa0b14a07cc6c03b30df533 100644
--- a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
+++ b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManagerDxe.inf
@@ -77,6 +77,20 @@ [FixedPcd]
   gArmTokenSpaceGuid.PcdPciBusMin
   gArmTokenSpaceGuid.PcdPciBusMax
 
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+  gArmPlatformTokenSpaceGuid.PcdClusterCount
+
+  gArmVExpressTokenSpaceGuid.PcdL1DcacheSize
+  gArmVExpressTokenSpaceGuid.PcdL1DcacheWays
+  gArmVExpressTokenSpaceGuid.PcdL1DcacheLineSize
+  gArmVExpressTokenSpaceGuid.PcdL1IcacheSize
+  gArmVExpressTokenSpaceGuid.PcdL1IcacheWays
+  gArmVExpressTokenSpaceGuid.PcdL1IcacheLineSize
+  gArmVExpressTokenSpaceGuid.PcdL2CacheSize
+  gArmVExpressTokenSpaceGuid.PcdL2CacheWays
+  gArmVExpressTokenSpaceGuid.PcdL3CacheSize
+  gArmVExpressTokenSpaceGuid.PcdL3CacheWays
+
 [Pcd]
 
 [Depex]
diff --git a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
index be2b512911f897dc57328673ae4f4a2014ec20fb..b37273edc5d39be8aa211cd78247322c03ffb706 100644
--- a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
+++ b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
@@ -19,6 +19,14 @@
 extern CHAR8  dsdt_aml_code[];
 extern CHAR8  ssdtpci_aml_code[];
 
+// Cache type identifier used to calculate unique cache ID for PPTT
+typedef enum {
+  L1DataCache = 1,
+  L1InstructionCache,
+  L2Cache,
+  L3Cache,
+} CACHE_TYPE;
+
 /** The configuration manager version.
 */
 #define CONFIGURATION_MANAGER_REVISION CREATE_REVISION (1, 0)
@@ -83,13 +91,38 @@ typedef EFI_STATUS (*CM_OBJECT_HANDLER_PROC) (
 #define GET_MPID_MT(Cluster, Core, Thread)                        \
           (((Cluster) << 16) | ((Core) << 8) | (Thread))
 
+/** The number of Packages
+*/
+#define PLAT_PACKAGE_COUNT          1
+
+/** The number of Cluster per Package
+*/
+#define PLAT_CLUSTER_COUNT          FixedPcdGet32 (PcdClusterCount)
+
+/** The number of Core per Cluster
+*/
+#define PLAT_CORE_COUNT             FixedPcdGet32 (PcdCoreCount)
+
+/** The number of Thread per Core (If RevC model)
+*/
+#define PLAT_THREAD_COUNT           1
+
 /** The number of CPUs
 */
-#define PLAT_CPU_COUNT              8
+#define PLAT_CPU_COUNT              \
+  (PLAT_PACKAGE_COUNT * PLAT_CLUSTER_COUNT * PLAT_CORE_COUNT)
+
+/** The number of Processor Hierarchy Nodes
+    - one package node
+    - two cluster nodes
+    - four cores in each cluster
+*/
+#define PLAT_PROC_HIERARCHY_NODE_COUNT  \
+  (PLAT_PACKAGE_COUNT + PLAT_CLUSTER_COUNT + PLAT_CPU_COUNT)
 
 /** The number of ACPI tables to install
 */
-#define PLAT_ACPI_TABLE_COUNT       10
+#define PLAT_ACPI_TABLE_COUNT       11
 
 /** The number of platform generic timer blocks
 */
@@ -99,6 +132,106 @@ typedef EFI_STATUS (*CM_OBJECT_HANDLER_PROC) (
 */
 #define PLAT_GTFRAME_COUNT          2
 
+/** A helper macro for populating the Cache Type Structure's attributes
+*/
+#define CACHE_ATTRIBUTES(                                               \
+          AllocationType,                                               \
+          CacheType,                                                    \
+          WritePolicy                                                   \
+          )                                                             \
+  (                                                                     \
+    AllocationType |                                                    \
+    (CacheType << 2) |                                                  \
+    (WritePolicy << 4)                                                  \
+  )
+
+#define CACHE_ID(ClusterId, CoreId, CacheType)                          \
+    (                                                                   \
+      (((ClusterId) & 0xFF) << 12) |                                    \
+      (((CoreId) & 0xFF) << 4) |                                        \
+      ((CacheType) & 0xF)                                               \
+    )
+
+/** A helper macro for populating the Processor Hierarchy Node flags
+*/
+#define PROC_NODE_FLAGS(                                                \
+          PhysicalPackage,                                              \
+          AcpiProcessorIdValid,                                         \
+          ProcessorIsThread,                                            \
+          NodeIsLeaf,                                                   \
+          IdenticalImplementation                                       \
+          )                                                             \
+  (                                                                     \
+    PhysicalPackage |                                                   \
+    (AcpiProcessorIdValid << 1) |                                       \
+    (ProcessorIsThread << 2) |                                          \
+    (NodeIsLeaf << 3) |                                                 \
+    (IdenticalImplementation << 4)                                      \
+  )
+
+#define PPTT_PROCESSOR_PACKAGE_FLAGS                                    \
+  PROC_NODE_FLAGS (                                                     \
+    EFI_ACPI_6_4_PPTT_PACKAGE_PHYSICAL,                                 \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_ID_INVALID,                             \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_IS_NOT_THREAD,                          \
+    EFI_ACPI_6_4_PPTT_NODE_IS_NOT_LEAF,                                 \
+    EFI_ACPI_6_4_PPTT_IMPLEMENTATION_IDENTICAL                          \
+    )                                                                   \
+
+#define PPTT_PROCESSOR_CLUSTER_FLAGS                                    \
+  PROC_NODE_FLAGS (                                                     \
+    EFI_ACPI_6_4_PPTT_PACKAGE_NOT_PHYSICAL,                             \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_ID_INVALID,                             \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_IS_NOT_THREAD,                          \
+    EFI_ACPI_6_4_PPTT_NODE_IS_NOT_LEAF,                                 \
+    EFI_ACPI_6_4_PPTT_IMPLEMENTATION_IDENTICAL                          \
+    )
+
+#define PPTT_PROCESSOR_CORE_FLAGS                                       \
+  PROC_NODE_FLAGS (                                                     \
+    EFI_ACPI_6_4_PPTT_PACKAGE_NOT_PHYSICAL,                             \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_ID_VALID,                               \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_IS_NOT_THREAD,                          \
+    EFI_ACPI_6_4_PPTT_NODE_IS_LEAF,                                     \
+    EFI_ACPI_6_4_PPTT_IMPLEMENTATION_NOT_IDENTICAL                      \
+    )
+
+#define PPTT_PROCESSOR_CORE_THREADED_FLAGS                              \
+  PROC_NODE_FLAGS (                                                     \
+    EFI_ACPI_6_4_PPTT_PACKAGE_NOT_PHYSICAL,                             \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_ID_INVALID,                             \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_IS_NOT_THREAD,                          \
+    EFI_ACPI_6_4_PPTT_NODE_IS_NOT_LEAF,                                 \
+    EFI_ACPI_6_4_PPTT_IMPLEMENTATION_IDENTICAL                          \
+    )
+
+#define PPTT_PROCESSOR_THREAD_FLAGS                                     \
+  PROC_NODE_FLAGS (                                                     \
+   EFI_ACPI_6_4_PPTT_PACKAGE_NOT_PHYSICAL,                              \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_ID_VALID,                               \
+    EFI_ACPI_6_4_PPTT_PROCESSOR_IS_THREAD,                              \
+    EFI_ACPI_6_4_PPTT_NODE_IS_LEAF,                                     \
+    EFI_ACPI_6_4_PPTT_IMPLEMENTATION_NOT_IDENTICAL                      \
+    )
+
+#define GET_PACKAGE_HNODE(PackageId)                                    \
+  (&VExpressPlatRepositoryInfo.ProcHierarchyInfo[PackageId])
+
+#define GET_CLUSTER_HNODE(ClusterId)                                    \
+  (&VExpressPlatRepositoryInfo.ProcHierarchyInfo[                       \
+     (PLAT_PACKAGE_COUNT + ClusterId)])
+
+#define GET_CORE_HNODE(ClusterId, CoreId)                               \
+  (&VExpressPlatRepositoryInfo.ProcHierarchyInfo[                       \
+     (PLAT_PACKAGE_COUNT + PLAT_CLUSTER_COUNT +                         \
+      (ClusterId * (PLAT_CORE_COUNT)) +                                 \
+      (CoreId))])
+
+#define L1_DCACHE_PRESENT (FixedPcdGet32 (PcdL1DcacheSize) != 0)
+#define L1_ICACHE_PRESENT (FixedPcdGet32 (PcdL1IcacheSize) != 0)
+#define L2_CACHE_PRESENT (FixedPcdGet32 (PcdL2CacheSize) != 0)
+#define L3_CACHE_PRESENT (FixedPcdGet32 (PcdL3CacheSize) != 0)
+
 /** A structure describing the platform configuration
     manager repository information
 */
@@ -175,6 +308,23 @@ typedef struct PlatformRepositoryInfo {
 
   /// System ID
   UINT32                                SysId;
+
+  /// Processor topology information
+  CM_ARM_PROC_HIERARCHY_INFO            *ProcHierarchyInfo;
+  UINT32                                ProcNodeCount;
+
+  /// Cache information
+  CM_ARM_CACHE_INFO                     *CacheInfo;
+  UINT32                                CacheInfoCount;
+
+  /// Cluster private resources
+  CM_ARM_OBJ_REF                        **ClusterResources;
+  UINT32                                PerCluResCnt;
+
+  /// Core private resources
+  CM_ARM_OBJ_REF                        **CoreResources;
+  UINT32                                PerCoreResCnt;
+
 } EDKII_PLATFORM_REPOSITORY_INFO;
 
 #endif // CONFIGURATION_MANAGER_H__
diff --git a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
index 5b5d1f9d04c0f27bf32cca62f51c259152e16711..ee6936cb9f0f4b755c0564634d60d2b25f758e56 100644
--- a/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
+++ b/Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.c
@@ -17,6 +17,7 @@
 #include <Library/ArmLib.h>
 #include <Library/DebugLib.h>
 #include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Protocol/AcpiTable.h>
@@ -26,6 +27,8 @@
 #include "ConfigurationManager.h"
 #include "Platform.h"
 
+STATIC BOOLEAN mIsThreaded = FALSE;
+
 /** The platform configuration repository information.
 */
 STATIC
@@ -106,6 +109,13 @@ EDKII_PLATFORM_REPOSITORY_INFO VExpressPlatRepositoryInfo = {
       CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdt),
       (EFI_ACPI_DESCRIPTION_HEADER*)ssdtpci_aml_code
     },
+    /// PPTT Tabale
+    {
+      EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
+      EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
+      CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPptt),
+      NULL,
+    },
   },
 
   // Boot architecture information
@@ -369,7 +379,7 @@ EDKII_PLATFORM_REPOSITORY_INFO VExpressPlatRepositoryInfo = {
   // Embedded Trace device info
   {
     ArmEtTypeEte
-  }
+  },
 };
 
 /** A helper function for returning the Configuration Manager Objects.
@@ -442,6 +452,7 @@ HandleCmObjectRefByToken (
   )
 {
   EFI_STATUS  Status;
+
   CmObjectDesc->ObjectId = CmObjectId;
   if (Token == CM_NULL_TOKEN) {
     CmObjectDesc->Size = ObjectSize;
@@ -464,6 +475,736 @@ HandleCmObjectRefByToken (
   return Status;
 }
 
+/** A helper function for returning Configuration Manager Object(s) referenced
+    by token when the entire platform repository is in scope and the
+    CM_NULL_TOKEN value is not allowed.
+
+  @param [in]  This               Pointer to the Configuration Manager Protocol.
+  @param [in]  CmObjectId         The Configuration Manager Object ID.
+  @param [in]  Token              A token identifying the object.
+  @param [in]  HandlerProc        A handler function to search the object(s)
+                                  referenced by the token.
+  @param [in, out]  CmObjectDesc  Pointer to the Configuration Manager Object
+                                  descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         The required object information is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+HandleCmObjectSearchPlatformRepo (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token,
+  IN  CONST CM_OBJECT_HANDLER_PROC                        HandlerProc,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObjectDesc
+  )
+{
+  EFI_STATUS  Status;
+
+  CmObjectDesc->ObjectId = CmObjectId;
+
+  if (Token == CM_NULL_TOKEN) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: CM_NULL_TOKEN value is not allowed when searching"
+      " the entire platform repository.\n"
+      ));
+
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = HandlerProc (This, CmObjectId, Token, CmObjectDesc);
+  DEBUG ((
+    DEBUG_INFO,
+    "INFO: Token = 0x%p, CmObjectId = %x, Ptr = 0x%p, Size = %d, Count = %d\n",
+    CmObjectId,
+    (VOID*)Token,
+    CmObjectDesc->Data,
+    CmObjectDesc->Size,
+    CmObjectDesc->Count
+    ));
+
+  return Status;
+}
+
+/** Get matched GicC Token with Mpidr information.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [in]      PackageId        Package Id.
+  @param [in]      ClusterId        Cluster Id.
+  @param [in]      CoreId           Core Id.
+  @param [in]      ThreadId         Thread Id.
+
+  @retval CM_NULL_TOKEN             There's no macthed Gicc entry.
+  @retval Others                    Matched Gicc entry.
+**/
+STATIC
+CM_OBJECT_TOKEN
+EFIAPI
+GetGicCToken (
+  IN  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  IN  INTN                            PackageId,
+  IN  INTN                            ClusterId,
+  IN  INTN                            CoreId,
+  IN  INTN                            ThreadId
+  )
+{
+  UINT64 MpIdr;
+  INTN Idx;
+  CM_ARM_GICC_INFO *GicCInfo;
+
+  if (mIsThreaded == TRUE) {
+    MpIdr = GET_MPID_MT (ClusterId, CoreId, ThreadId);
+  } else {
+    MpIdr = GET_MPID (ClusterId, CoreId);
+  }
+
+  for (Idx = 0; Idx < PLAT_CPU_COUNT; Idx++) {
+    GicCInfo = &PlatformRepo->GicCInfo[Idx];
+
+    if (GicCInfo->MPIDR == MpIdr) {
+      return (CM_OBJECT_TOKEN) GicCInfo;
+    }
+  }
+
+  return CM_NULL_TOKEN;
+}
+
+/** Populate Cluster Hierarchy Info used for generating PPTT.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [in]      StartIdx         Start Index in PlatformRepo->HierarchyInfo
+                                    for generated Thread Hierarchy Info.
+  @param [in]      PackageId        Package Id.
+  @param [out]     NextIdx          Index used to generate next Hierarchy Info
+                                    information.
+**/
+STATIC
+VOID
+EFIAPI
+PopulatePackageNodes (
+  IN  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  IN  INTN                            StartIdx,
+  OUT INTN                            *NextIdx
+  )
+{
+  INTN Idx;
+  CM_ARM_PROC_HIERARCHY_INFO *PackageNode;
+
+  for (Idx = StartIdx; Idx < StartIdx + PLAT_PACKAGE_COUNT; Idx++) {
+    PackageNode = &PlatformRepo->ProcHierarchyInfo[Idx];
+
+    PackageNode->Token = (CM_OBJECT_TOKEN) PackageNode;
+    PackageNode->Flags = PPTT_PROCESSOR_PACKAGE_FLAGS;
+    PackageNode->ParentToken = CM_NULL_TOKEN;
+    PackageNode->GicCToken = CM_NULL_TOKEN;
+  }
+
+  *NextIdx = Idx;
+}
+
+/** Populate Cluster Hierarchy Info used for generating PPTT.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [in]      StartIdx         Start Index in PlatformRepo->HierarchyInfo
+                                    for generated Thread Hierarchy Info.
+  @param [in]      PackageId        Package Id.
+  @param [out]     NextIdx          Index used to generate next Hierarchy Info
+                                    information.
+**/
+STATIC
+VOID
+EFIAPI
+PopulateClusterNodes (
+  IN  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  IN  INTN                            StartIdx,
+  IN  INTN                            PackageId,
+  OUT INTN                            *NextIdx
+  )
+{
+  INTN Idx;
+  CM_ARM_PROC_HIERARCHY_INFO *ClusterNode;
+
+  for (Idx = StartIdx; Idx < StartIdx + PLAT_CLUSTER_COUNT; Idx++) {
+    ClusterNode = &PlatformRepo->ProcHierarchyInfo[Idx];
+
+    ClusterNode->Token = (CM_OBJECT_TOKEN) ClusterNode;
+    ClusterNode->Flags = PPTT_PROCESSOR_CLUSTER_FLAGS;
+    ClusterNode->ParentToken = (CM_OBJECT_TOKEN) GET_PACKAGE_HNODE(PackageId);
+    ClusterNode->GicCToken = CM_NULL_TOKEN;
+  }
+
+  *NextIdx = Idx;
+}
+
+/** Populate Core Hierarchy Info used for generating PPTT.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [in]      StartIdx         Start Index in PlatformRepo->HierarchyInfo
+                                    for generated Thread Hierarchy Info.
+  @param [in]      PackageId        Package Id.
+  @param [in]      ClusterId        Cluster Id.
+  @param [out]     NextIdx          Index used to generate next Hierarchy Info
+                                    information.
+**/
+STATIC
+VOID
+EFIAPI
+PopulateCoreNodes (
+  IN  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  IN  INTN                            StartIdx,
+  IN  INTN                            PackageId,
+  IN  INTN                            ClusterId,
+  OUT INTN                            *NextIdx
+  )
+{
+  INTN Idx;
+  CM_ARM_PROC_HIERARCHY_INFO *CoreNode;
+
+  for (Idx = StartIdx; Idx < StartIdx + PLAT_CORE_COUNT; Idx++) {
+    CoreNode = &PlatformRepo->ProcHierarchyInfo[Idx];
+
+    CoreNode->Token = (CM_OBJECT_TOKEN) CoreNode;
+    CoreNode->ParentToken = (CM_OBJECT_TOKEN) GET_CLUSTER_HNODE(ClusterId);
+
+    if (mIsThreaded == TRUE) {
+      CoreNode->Flags = PPTT_PROCESSOR_CORE_THREADED_FLAGS;
+      CoreNode->GicCToken = CM_NULL_TOKEN;
+    } else {
+      CoreNode->Flags = PPTT_PROCESSOR_CORE_FLAGS;
+      CoreNode->GicCToken = GetGicCToken (PlatformRepo,
+          PackageId, ClusterId, Idx - StartIdx, 0);
+
+      ASSERT (CoreNode->GicCToken != CM_NULL_TOKEN);
+    }
+  }
+
+  *NextIdx = Idx;
+}
+
+/** Populate Thread Hierarchy Info used for generating PPTT.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [in]      StartIdx         Start Index in PlatformRepo->HierarchyInfo
+                                    for generated Thread Hierarchy Info.
+  @param [in]      PackageId        Package Id.
+  @param [in]      ClusterId        Cluster Id.
+  @param [in]      CoreId           Core Id.
+  @param [out]     NextIdx          Index used to generate next Hierarchy Info
+                                    information.
+**/
+STATIC
+VOID
+EFIAPI
+PopulateThreadNodes (
+  IN  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  IN  INTN                            StartIdx,
+  IN  INTN                            PackageId,
+  IN  INTN                            ClusterId,
+  IN  INTN                            CoreId,
+  OUT INTN                            *NextIdx
+  )
+{
+  INTN Idx;
+  CM_ARM_PROC_HIERARCHY_INFO *ThreadNode;
+
+  for (Idx = StartIdx; Idx < StartIdx + PLAT_THREAD_COUNT; Idx++) {
+    ThreadNode = &PlatformRepo->ProcHierarchyInfo[Idx];
+
+    ThreadNode->Token = (CM_OBJECT_TOKEN) ThreadNode;
+    ThreadNode->ParentToken = (CM_OBJECT_TOKEN) GET_CORE_HNODE(ClusterId, CoreId);
+    ThreadNode->Flags = PPTT_PROCESSOR_THREAD_FLAGS;
+    ThreadNode->GicCToken = GetGicCToken (PlatformRepo,
+          PackageId, ClusterId, CoreId, Idx - StartIdx);
+
+    ASSERT (ThreadNode->GicCToken != CM_NULL_TOKEN);
+  }
+
+  *NextIdx = Idx;
+}
+
+/** Populate Hierarchy Info used for generating PPTT.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+
+  @retval EFI_SUCCESS               Success.
+  @retval EFI_OUT_OF_RESOURCES      Out of memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulateHierarchyInfo (
+  IN EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo
+  )
+{
+  INTN StartIdx;
+  INTN NextIdx;
+  INTN Idx;
+  INTN PackageCount;
+  INTN ClusterCount;
+  INTN CoreCount;
+  INTN ThreadCount;
+
+  PackageCount = PLAT_PACKAGE_COUNT;
+  ClusterCount = PackageCount * PLAT_CLUSTER_COUNT;
+  CoreCount = ClusterCount * PLAT_CORE_COUNT;
+  ThreadCount = mIsThreaded == TRUE ? CoreCount * PLAT_THREAD_COUNT : 0;
+  PlatformRepo->ProcNodeCount = PackageCount + ClusterCount + CoreCount + ThreadCount;
+
+  PlatformRepo->ProcHierarchyInfo = AllocateZeroPool (
+      sizeof (CM_ARM_PROC_HIERARCHY_INFO) * PlatformRepo->ProcNodeCount);
+  if (PlatformRepo->ProcHierarchyInfo == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  StartIdx = 0;
+  PopulatePackageNodes (PlatformRepo, StartIdx, &NextIdx);
+
+  for (Idx = 0; Idx < PackageCount; Idx++) {
+    StartIdx = NextIdx;
+    PopulateClusterNodes (PlatformRepo, StartIdx, Idx, &NextIdx);
+  }
+
+  for (Idx = 0; Idx < ClusterCount; Idx++) {
+    StartIdx = NextIdx;
+    PopulateCoreNodes (PlatformRepo, StartIdx,
+        Idx / PLAT_CLUSTER_COUNT,
+        Idx % PLAT_CLUSTER_COUNT,
+        &NextIdx);
+  }
+
+  if (mIsThreaded == TRUE) {
+    for (Idx = 0; Idx < CoreCount; Idx++) {
+      StartIdx = NextIdx;
+      PopulateThreadNodes (PlatformRepo, StartIdx,
+         (Idx / PLAT_CORE_COUNT) / PLAT_CLUSTER_COUNT,
+         (Idx / PLAT_CORE_COUNT) % PLAT_CLUSTER_COUNT,
+         Idx % PLAT_CORE_COUNT,
+         &NextIdx);
+    }
+  }
+
+  ASSERT (NextIdx == PlatformRepo->ProcNodeCount);
+
+  return EFI_SUCCESS;
+}
+
+/** Populate CacheInfo entry used for generating PPTT based on CacheType.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [in]      StartIdx         Start Index in PlatformRepo->CacheInfo
+                                    for generated CacheInfo.
+  @param [in]      CacheType        Type of Cache.
+  @param [out]     NextIdx          Index used to generate next cache type
+                                    information.
+
+  @retval EFI_SUCCESS               Success.
+  @retval EFI_INVALID_PARAMETER     Invalid Cache Information.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulateCacheInfoEntry (
+  IN EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  IN INTN                            StartIdx,
+  IN CACHE_TYPE                      CacheType,
+  OUT INTN                           *NextIdx
+  )
+{
+  INTN    Idx;
+  UINT32  Attributes;
+  UINT32  Size;
+  UINT32  LineSize;
+  UINT32  NumberOfSets;
+  UINT32  Associativity;
+  UINTN   Count;
+  UINT32  ClusterId;
+  UINT32  CoreId;
+
+  Attributes = CACHE_ATTRIBUTES (
+                 EFI_ACPI_6_4_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE,
+                 EFI_ACPI_6_4_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED,
+                 EFI_ACPI_6_4_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK
+                 );
+  LineSize = MAX (
+               FixedPcdGet32 (PcdL1DcacheLineSize),
+               FixedPcdGet32 (PcdL1IcacheLineSize)
+               );
+  Count = PLAT_CLUSTER_COUNT;
+
+  switch (CacheType) {
+    case L1DataCache:
+      Count         = PLAT_CPU_COUNT;
+      Size          = FixedPcdGet32 (PcdL1DcacheSize);
+      LineSize      = FixedPcdGet32 (PcdL1DcacheLineSize);
+      Associativity = FixedPcdGet32 (PcdL1DcacheWays);
+      Attributes    = CACHE_ATTRIBUTES (
+                        EFI_ACPI_6_4_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE,
+                        EFI_ACPI_6_4_CACHE_ATTRIBUTES_CACHE_TYPE_DATA,
+                        EFI_ACPI_6_4_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK
+                        );
+      break;
+    case L1InstructionCache:
+      Count         = PLAT_CPU_COUNT;
+      Size          = FixedPcdGet32 (PcdL1IcacheSize);
+      LineSize      = FixedPcdGet32 (PcdL1IcacheLineSize);
+      Associativity = FixedPcdGet32 (PcdL1IcacheWays);
+      Attributes    = CACHE_ATTRIBUTES (
+                        EFI_ACPI_6_4_CACHE_ATTRIBUTES_ALLOCATION_READ,
+                        EFI_ACPI_6_4_CACHE_ATTRIBUTES_CACHE_TYPE_INSTRUCTION,
+                        EFI_ACPI_6_4_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK
+                        );
+      break;
+    case L2Cache:
+      Size          = FixedPcdGet32 (PcdL2CacheSize);
+      Associativity = FixedPcdGet32 (PcdL2CacheWays);
+      break;
+    case L3Cache:
+      Size          = FixedPcdGet32 (PcdL3CacheSize);
+      Associativity = FixedPcdGet32 (PcdL3CacheWays);
+      break;
+    default:
+      return EFI_INVALID_PARAMETER;
+  }
+
+  if (Size == 0) {
+    *NextIdx = StartIdx;
+
+    return EFI_NOT_FOUND;
+  } else if ((Associativity == 0) || (LineSize == 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  NumberOfSets = (Size / (LineSize * Associativity));
+
+  for (Idx = StartIdx; Idx < StartIdx + Count; Idx++) {
+    PlatformRepo->CacheInfo[Idx].Token =
+      (CM_OBJECT_TOKEN)&PlatformRepo->CacheInfo[Idx];
+
+    if ((CacheType == L2Cache) && L3_CACHE_PRESENT) {
+      PlatformRepo->CacheInfo[Idx].NextLevelOfCacheToken =
+        (CM_OBJECT_TOKEN)&PlatformRepo->CacheInfo[Idx - PLAT_CLUSTER_COUNT];
+    } else {
+      PlatformRepo->CacheInfo[Idx].NextLevelOfCacheToken = CM_NULL_TOKEN;
+    }
+
+    PlatformRepo->CacheInfo[Idx].Size          = Size;
+    PlatformRepo->CacheInfo[Idx].NumberOfSets  = NumberOfSets;
+    PlatformRepo->CacheInfo[Idx].LineSize      = LineSize;
+    PlatformRepo->CacheInfo[Idx].Associativity = Associativity;
+    PlatformRepo->CacheInfo[Idx].Attributes    = Attributes;
+
+    if (Count == PLAT_CLUSTER_COUNT) {
+      ClusterId = Idx - StartIdx;
+      CoreId    = 0;
+    } else {
+      ClusterId = (Idx - StartIdx) / PLAT_CORE_COUNT;
+      CoreId    = (Idx - StartIdx) % PLAT_CORE_COUNT;
+    }
+
+    PlatformRepo->CacheInfo[Idx].CacheId = CACHE_ID (ClusterId, CoreId, CacheType);
+  }
+
+  *NextIdx = Idx;
+
+  return EFI_SUCCESS;
+}
+
+/** Populate CacheInfo field used for generating PPTT.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [out]     L1DStartIdx      L1 dcache info start index in
+                                    PlatformRepo->CacheInfo Array.
+  @param [out]     L1IStartIdx      L1 icache info start index in
+                                    PlatformRepo->CacheInfo Array.
+  @param [out]     L2StartIdx       L2 cache info start index in
+                                    PlatformRepo->CacheInfo Array.
+
+  @retval EFI_SUCCESS               Success.
+  @retval EFI_INVALID_PARAMETER     Invalid Cache Information.
+  @retval EFI_OUT_OF_RESOURCES      Out of memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulateCacheInfo (
+  IN EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  OUT INTN                           *L1DStartIdx,
+  OUT INTN                           *L1IStartIdx,
+  OUT INTN                           *L2StartIdx
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      CacheCnt;
+  INTN        StartIdx;
+  INTN        NextIdx;
+
+  CacheCnt = 0;
+
+  if (L1_DCACHE_PRESENT) {
+    CacheCnt += PLAT_CPU_COUNT;
+  }
+
+  if (L1_ICACHE_PRESENT) {
+    CacheCnt += PLAT_CPU_COUNT;
+  }
+
+  if (L2_CACHE_PRESENT) {
+    CacheCnt += PLAT_CLUSTER_COUNT;
+  }
+
+  if (L3_CACHE_PRESENT) {
+    CacheCnt += PLAT_CLUSTER_COUNT;
+  }
+
+  if (CacheCnt == 0) {
+    return EFI_SUCCESS;
+  }
+
+  PlatformRepo->CacheInfo = AllocateZeroPool (sizeof (CM_ARM_CACHE_INFO) *  CacheCnt);
+  if (PlatformRepo->CacheInfo == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+
+    goto err_handler;
+  }
+
+  StartIdx = 0;
+  Status   = PopulateCacheInfoEntry (PlatformRepo, StartIdx, L3Cache, &NextIdx);
+  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+    goto err_handler;
+  }
+
+  StartIdx = NextIdx;
+  Status   = PopulateCacheInfoEntry (PlatformRepo, StartIdx, L2Cache, &NextIdx);
+  if (EFI_ERROR (Status)) {
+    *L2StartIdx = -1;
+
+    if (Status != EFI_NOT_FOUND) {
+      goto err_handler;
+    }
+  } else {
+    *L2StartIdx = StartIdx;
+  }
+
+  StartIdx = NextIdx;
+  Status   = PopulateCacheInfoEntry (PlatformRepo, StartIdx, L1DataCache, &NextIdx);
+  if (EFI_ERROR (Status)) {
+    *L1DStartIdx = -1;
+
+    if (Status != EFI_NOT_FOUND) {
+      goto err_handler;
+    }
+  } else {
+    *L1DStartIdx = StartIdx;
+  }
+
+  StartIdx = NextIdx;
+  Status   = PopulateCacheInfoEntry (PlatformRepo, StartIdx, L1InstructionCache, &NextIdx);
+  if (EFI_ERROR (Status)) {
+    *L1IStartIdx = -1;
+
+    if (Status != EFI_NOT_FOUND) {
+      goto err_handler;
+    }
+  } else {
+    *L1IStartIdx = StartIdx;
+  }
+
+  ASSERT (NextIdx == CacheCnt);
+
+  PlatformRepo->CacheInfoCount = CacheCnt;
+
+  return EFI_SUCCESS;
+
+err_handler:
+  if (EFI_ERROR (Status)) {
+    PlatformRepo->CacheInfoCount = 0;
+
+    if (PlatformRepo->CacheInfo) {
+      FreePool (PlatformRepo->CacheInfo);
+      PlatformRepo->CacheInfo = NULL;
+    }
+  }
+
+  return Status;
+}
+
+/** Populate Clusters Resources field used for generating PPTT.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [in]      L2StartIdx       L2 cache info start index in
+                                    PlatformRepo->CacheInfo Array.
+
+  @retval EFI_SUCCESS               Success.
+  @retval EFI_OUT_OF_RESOURCES      Out of memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulateClusterResources (
+  IN EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  IN INTN                            L2StartIdx
+  )
+{
+  INTN                        CluIdx;
+  INTN                        Idx;
+  CM_ARM_PROC_HIERARCHY_INFO  *Node;
+  CM_ARM_OBJ_REF              *ClusterResource;
+
+  if (L2StartIdx < 0) {
+    PlatformRepo->ClusterResources = NULL;
+    PlatformRepo->PerCluResCnt     = 0;
+
+    return EFI_SUCCESS;
+  }
+
+  PlatformRepo->PerCluResCnt = 1;
+
+  PlatformRepo->ClusterResources = AllocateZeroPool (
+                                     sizeof (CM_ARM_OBJ_REF *) *
+                                     PLAT_CLUSTER_COUNT
+                                     );
+  if (PlatformRepo->ClusterResources == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (CluIdx = 0; CluIdx < PLAT_CLUSTER_COUNT; CluIdx++) {
+    ClusterResource =  AllocateZeroPool (sizeof (CM_ARM_OBJ_REF));
+    if (ClusterResource == NULL) {
+      goto fail_to_alloc;
+    }
+
+    ClusterResource[0].ReferenceToken =
+      (CM_OBJECT_TOKEN)&PlatformRepo->CacheInfo[CluIdx + L2StartIdx];
+
+    PlatformRepo->ClusterResources[CluIdx] = ClusterResource;
+
+    Node                             = GET_CLUSTER_HNODE (CluIdx);
+    Node->NoOfPrivateResources       = 1;
+    Node->PrivateResourcesArrayToken = (CM_OBJECT_TOKEN) ClusterResource;
+  }
+
+  return EFI_SUCCESS;
+
+fail_to_alloc:
+  for (Idx = 0; Idx < CluIdx; Idx++) {
+    FreePool (PlatformRepo->ClusterResources[Idx]);
+  }
+
+  FreePool (PlatformRepo->ClusterResources);
+  PlatformRepo->ClusterResources = NULL;
+  PlatformRepo->PerCluResCnt     = 0;
+
+  return EFI_OUT_OF_RESOURCES;
+}
+
+/** Populate Core Resources field used for generating PPTT.
+
+  @param [in]      PlatformRepo     Pointer to Platform Repository.
+  @param [in]      L1DStartIdx      L1 dcache info start index in
+                                    PlatformRepo->CacheInfo Array.
+  @param [in]      L1IStartIdx      L1 icache info start index in
+                                    PlatformRepo->CacheInfo Array.
+
+  @retval EFI_SUCCESS               Success.
+  @retval EFI_OUT_OF_RESOURCES      Out of memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulateCoreResources (
+  IN EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo,
+  IN INTN                            L1DStartIdx,
+  IN INTN                            L1IStartIdx
+  )
+{
+  INTN                        CpuIdx;
+  INTN                        Idx;
+  CM_ARM_PROC_HIERARCHY_INFO  *Node;
+  UINTN                       ResCnt;
+  INTN                        ClusterId;
+  INTN                        CoreId;
+  INTN                        CacheIdx;
+  CM_ARM_OBJ_REF              *CoreResource;
+
+  ResCnt = 0;
+
+  if (L1DStartIdx >= 0) {
+    ResCnt++;
+  }
+
+  if (L1IStartIdx >= 0) {
+    ResCnt++;
+  }
+
+  if (ResCnt == 0) {
+    PlatformRepo->CoreResources = NULL;
+
+    return EFI_SUCCESS;
+  }
+
+  PlatformRepo->PerCoreResCnt = ResCnt;
+
+  PlatformRepo->CoreResources = AllocateZeroPool (
+                                  sizeof (CM_ARM_OBJ_REF *) *
+                                  PLAT_CPU_COUNT
+                                  );
+  if (PlatformRepo->CoreResources == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (CpuIdx = 0; CpuIdx < PLAT_CPU_COUNT; CpuIdx++) {
+    CoreResource = AllocateZeroPool (sizeof (CM_ARM_OBJ_REF) * ResCnt);
+    if (CoreResource == NULL) {
+      goto fail_to_alloc;
+    }
+
+    Idx       = 0;
+    ClusterId = CpuIdx / PLAT_CORE_COUNT;
+    CoreId    = CpuIdx % PLAT_CORE_COUNT;
+
+    if (L1DStartIdx >= 0) {
+      CacheIdx = L1DStartIdx + (ClusterId * PLAT_CORE_COUNT) + CoreId;
+
+      CoreResource[Idx].ReferenceToken =
+        (CM_OBJECT_TOKEN) &PlatformRepo->CacheInfo[CacheIdx];
+      Idx++;
+    }
+
+    if (L1IStartIdx >= 0) {
+      CacheIdx = L1IStartIdx + (ClusterId * PLAT_CORE_COUNT) + CoreId;
+
+      CoreResource[Idx].ReferenceToken =
+        (CM_OBJECT_TOKEN) &PlatformRepo->CacheInfo[CacheIdx];
+      Idx++;
+    }
+
+    ASSERT (Idx == ResCnt);
+
+    PlatformRepo->CoreResources[CpuIdx] = CoreResource;
+
+    Node                             = GET_CORE_HNODE (ClusterId, CoreId);
+    Node->NoOfPrivateResources       = ResCnt;
+    Node->PrivateResourcesArrayToken = (CM_OBJECT_TOKEN) CoreResource;
+  }
+
+  return EFI_SUCCESS;
+
+fail_to_alloc:
+  for (Idx = 0; Idx < CpuIdx; Idx++) {
+    FreePool (PlatformRepo->CoreResources[Idx]);
+  }
+
+  FreePool (PlatformRepo->CoreResources);
+  PlatformRepo->CoreResources = NULL;
+  PlatformRepo->PerCoreResCnt = 0;
+
+  return EFI_OUT_OF_RESOURCES;
+}
+
 /** Initialize the platform configuration repository.
 
   @param [in]  This        Pointer to the Configuration Manager Protocol.
@@ -479,9 +1220,13 @@ InitializePlatformRepository (
   )
 {
   EDKII_PLATFORM_REPOSITORY_INFO  * PlatformRepo;
-  UINTN  Index;
-  UINT16 TrbeInterrupt;
-  CM_OBJECT_TOKEN EtToken;
+  EFI_STATUS                      Status;
+  UINTN                           Index;
+  UINT16                          TrbeInterrupt;
+  CM_OBJECT_TOKEN                 EtToken;
+  INTN                            L1DStartIdx;
+  INTN                            L1IStartIdx;
+  INTN                            L2StartIdx;
 
   PlatformRepo = This->PlatRepoInfo;
 
@@ -498,10 +1243,12 @@ InitializePlatformRepository (
     PlatformRepo->GicCInfo[5].MPIDR = GET_MPID_MT (1, 1, 0);
     PlatformRepo->GicCInfo[6].MPIDR = GET_MPID_MT (1, 2, 0);
     PlatformRepo->GicCInfo[7].MPIDR = GET_MPID_MT (1, 3, 0);
+
+    mIsThreaded = TRUE;
   }
 
   TrbeInterrupt = 0;
-  EtToken = CM_NULL_TOKEN;
+  EtToken       = CM_NULL_TOKEN;
 
   // The ID_AA64DFR0_EL1.TraceBuffer field identifies support for FEAT_TRBE.
   if (ArmHasTrbe ()) {
@@ -519,7 +1266,86 @@ InitializePlatformRepository (
     PlatformRepo->GicCInfo[Index].EtToken = EtToken;
   }
 
+  Status = PopulateHierarchyInfo (PlatformRepo);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: Failed to populate hierarchy Info: %r\n",
+      Status
+      ));
+
+    goto fail_to_populate;
+  }
+
+  Status = PopulateCacheInfo (PlatformRepo, &L1DStartIdx, &L1IStartIdx, &L2StartIdx);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: Failed to populate cache Info: %r\n",
+      Status
+      ));
+
+    goto fail_to_populate;
+  }
+
+  Status = PopulateClusterResources (PlatformRepo, L2StartIdx);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: Failed to populate cluster resource Info: %r\n",
+      Status
+      ));
+
+    goto fail_to_populate;
+  }
+
+  Status = PopulateCoreResources (PlatformRepo, L1DStartIdx, L1IStartIdx);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: Failed to populate core resource Info: %r\n",
+      Status
+      ));
+
+    goto fail_to_populate;
+  }
+
   return EFI_SUCCESS;
+
+fail_to_populate:
+  if (PlatformRepo->CoreResources != NULL) {
+    for (Index = 0; Index < PLAT_CPU_COUNT; Index++) {
+      FreePool (PlatformRepo->CoreResources[Index]);
+    }
+
+    FreePool (PlatformRepo->CoreResources);
+    PlatformRepo->CoreResources = NULL;
+    PlatformRepo->PerCoreResCnt = 0;
+  }
+
+  if (PlatformRepo->ClusterResources != NULL) {
+    for (Index = 0; Index < PLAT_CLUSTER_COUNT; Index++) {
+      FreePool (PlatformRepo->ClusterResources[Index]);
+    }
+
+    FreePool (PlatformRepo->ClusterResources);
+    PlatformRepo->ClusterResources = NULL;
+    PlatformRepo->PerCluResCnt     = 0;
+  }
+
+  if (PlatformRepo->CacheInfo != NULL) {
+    FreePool (PlatformRepo->CacheInfo);
+    PlatformRepo->CacheInfo      = NULL;
+    PlatformRepo->CacheInfoCount = 0;
+  }
+
+  if (PlatformRepo->ProcHierarchyInfo != NULL) {
+    FreePool (PlatformRepo->ProcHierarchyInfo);
+    PlatformRepo->ProcHierarchyInfo = NULL;
+    PlatformRepo->ProcNodeCount = 0;
+  }
+
+  return Status;
 }
 
 /** Return a GT Block timer frame info list.
@@ -650,6 +1476,118 @@ GetDeviceIdMappingArray (
   return EFI_SUCCESS;
 }
 
+/** Return GIC CPU Interface Info.
+
+  @param [in]      This           Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId     The Object ID of the CM object requested
+  @param [in]      SearchToken    A unique token for identifying the requested
+                                  CM_ARM_GICC_INFO object.
+  @param [in, out] CmObject       Pointer to the Configuration Manager Object
+                                  descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS             Success.
+  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
+  @retval EFI_NOT_FOUND           The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetGicCInfo (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               SearchToken,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+  UINT32                          TotalObjCount;
+  UINT32                          ObjIndex;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo;
+
+  TotalObjCount = ARRAY_SIZE (PlatformRepo->GicCInfo);
+
+  for (ObjIndex = 0; ObjIndex < TotalObjCount; ObjIndex++) {
+    if (SearchToken == (CM_OBJECT_TOKEN)&PlatformRepo->GicCInfo[ObjIndex]) {
+      CmObject->ObjectId = CmObjectId;
+      CmObject->Size = sizeof (PlatformRepo->GicCInfo[ObjIndex]);
+      CmObject->Data = (VOID*)&PlatformRepo->GicCInfo[ObjIndex];
+      CmObject->Count = 1;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/** Return a list of Configuration Manager object references pointed to by the
+    given input token.
+
+  @param [in]      This           Pointer to the Configuration Manager Protocol.
+  @param [in]      CmObjectId     The Object ID of the CM object requested
+  @param [in]      Token          A unique token for identifying the requested
+                                  CM_ARM_OBJ_REF list.
+  @param [in, out] CmObject       Pointer to the Configuration Manager Object
+                                  descriptor describing the requested Object.
+
+  @retval EFI_SUCCESS             Success.
+  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
+  @retval EFI_NOT_FOUND           The required object information is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetCmObjRefs (
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  This,
+  IN  CONST CM_OBJECT_ID                                  CmObjectId,
+  IN  CONST CM_OBJECT_TOKEN                               Token,
+  IN  OUT   CM_OBJ_DESCRIPTOR                     *CONST  CmObject
+  )
+{
+  UINTN                           Idx;
+  EDKII_PLATFORM_REPOSITORY_INFO  *PlatformRepo;
+
+  if ((This == NULL) || (CmObject == NULL)) {
+    ASSERT (This != NULL);
+    ASSERT (CmObject != NULL);
+
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformRepo = This->PlatRepoInfo;
+
+  if (PlatformRepo->ClusterResources != NULL) {
+    for (Idx = 0; Idx < PLAT_CLUSTER_COUNT; Idx++) {
+      if (Token == (CM_OBJECT_TOKEN)PlatformRepo->ClusterResources[Idx]) {
+        CmObject->Count = PlatformRepo->PerCluResCnt;
+        CmObject->Size  = sizeof (CM_ARM_OBJ_REF) * CmObject->Count;
+        CmObject->Data  = (VOID *)PlatformRepo->ClusterResources[Idx];
+
+        return EFI_SUCCESS;
+      }
+    }
+  }
+
+  if (PlatformRepo->CoreResources != NULL) {
+    for (Idx = 0; Idx < PLAT_CPU_COUNT; Idx++) {
+      if (Token == (CM_OBJECT_TOKEN)PlatformRepo->CoreResources[Idx]) {
+        CmObject->Count = PlatformRepo->PerCoreResCnt;
+        CmObject->Size  = sizeof (CM_ARM_OBJ_REF) * CmObject->Count;
+        CmObject->Data  = (VOID *)PlatformRepo->CoreResources[Idx];
+
+        return EFI_SUCCESS;
+      }
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
 /** Return a standard namespace object.
 
   @param [in]      This        Pointer to the Configuration Manager Protocol.
@@ -863,11 +1801,14 @@ GetArmNameSpaceObject (
       break;
 
     case EArmObjGicCInfo:
-      Status = HandleCmObject (
+      Status = HandleCmObjectRefByToken (
+                 This,
                  CmObjectId,
                  PlatformRepo->GicCInfo,
                  sizeof (PlatformRepo->GicCInfo),
                  ARRAY_SIZE (PlatformRepo->GicCInfo),
+                 Token,
+                 GetGicCInfo,
                  CmObject
                  );
       break;
@@ -1000,6 +1941,40 @@ GetArmNameSpaceObject (
       }
       break;
 
+    case EArmObjProcHierarchyInfo:
+      Status = HandleCmObject (
+                 CmObjectId,
+                 PlatformRepo->ProcHierarchyInfo,
+                 sizeof (CM_ARM_PROC_HIERARCHY_INFO) * PlatformRepo->ProcNodeCount,
+                 PlatformRepo->ProcNodeCount,
+                 CmObject
+                 );
+      break;
+
+    case EArmObjCacheInfo:
+      if (PlatformRepo->CacheInfoCount == 0) {
+        Status = EFI_NOT_FOUND;
+      } else {
+        Status = HandleCmObject (
+                   CmObjectId,
+                   PlatformRepo->CacheInfo,
+                   sizeof (CM_ARM_CACHE_INFO) * PlatformRepo->CacheInfoCount,
+                   PlatformRepo->CacheInfoCount,
+                   CmObject
+                   );
+      }
+      break;
+
+    case EArmObjCmRef:
+      Status = HandleCmObjectSearchPlatformRepo (
+                 This,
+                 CmObjectId,
+                 Token,
+                 GetCmObjRefs,
+                 CmObject
+                 );
+      break;
+
     default: {
       Status = EFI_NOT_FOUND;
       DEBUG ((
--
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119805): https://edk2.groups.io/g/devel/message/119805
Mute This Topic: https://groups.io/mt/107053449/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



      reply	other threads:[~2024-07-05 13:22 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-05 13:22 [edk2-devel] [PATCH v1 edk2-platform] Add PPTT information for Base FVP levi.yun
2024-07-05 13:22 ` [edk2-devel] [PATCH v1 edk2-platform 1/2] VExpressPkg: Add cache information related PCDs levi.yun
2024-07-05 13:22   ` levi.yun [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240705132231.1574767-3-yeoreum.yun@arm.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox