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