DynamicTablesPkg: Update DynamicPlatRepo for Arch Common namespace

Update DynamicPlatRepo to reflect the introduction of the Arch
Common namespace. Also, update the TokenFixer map to reflect the
current state of the ArmNamespace Objects and add a note in the
documentation header for the EARM_OBJECT_ID enum, that the Token
fixer map needs updating whenever the ArmObjectId space is updated.

Cc: Pierre Gondois <Pierre.Gondois@arm.com>
Cc: Yeo Reum Yun <YeoReum.Yun@arm.com>
Cc: AbdulLateef Attar <AbdulLateef.Attar@amd.com>
Cc: Jeshua Smith <jeshuas@nvidia.com>
Cc: Jeff Brasen <jbrasen@nvidia.com>
Cc: Girish Mahadevan <gmahadevan@nvidia.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
This commit is contained in:
Sami Mujawar 2024-03-06 16:45:47 +00:00 committed by mergify[bot]
parent 3c2d524ceb
commit 9c040c003a
4 changed files with 229 additions and 64 deletions

View File

@ -20,6 +20,12 @@
/** The EARM_OBJECT_ID enum describes the Object IDs
in the ARM Namespace
Note: Whenever an entry in this enum is updated,
the following data structures must also be
updated:
- CM_OBJECT_TOKEN_FIXER TokenFixer[] in
Library\Common\DynamicPlatRepoLib\CmObjectTokenFixer.c
*/
typedef enum ArmObjectID {
EArmObjReserved, ///< 0 - Reserved

View File

@ -183,6 +183,17 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = {
NULL, ///< 37 - Lpi Info
NULL, ///< 38 - Pci Address Map Info
NULL, ///< 39 - Pci Interrupt Map Info
NULL, ///< 40 - Reserved Memory Range Node
NULL, ///< 41 - Memory Range Descriptor
NULL, ///< 42 - Continuous Performance Control Info
NULL, ///< 43 - Pcc Subspace Type 0 Info
NULL, ///< 44 - Pcc Subspace Type 2 Info
NULL, ///< 45 - Pcc Subspace Type 2 Info
NULL, ///< 46 - Pcc Subspace Type 3 Info
NULL, ///< 47 - Pcc Subspace Type 4 Info
NULL, ///< 48 - Pcc Subspace Type 5 Info
NULL, ///< 49 - Embedded Trace Extension/Module Info
NULL ///< 50 - P-State Dependency (PSD) Info
};
/** CmObj token fixer.

View File

@ -127,10 +127,12 @@ DynPlatRepoAddObject (
OUT CM_OBJECT_TOKEN *Token OPTIONAL
)
{
EFI_STATUS Status;
CM_OBJ_NODE *ObjNode;
CM_OBJECT_ID ArmNamespaceObjId;
CM_OBJECT_TOKEN NewToken;
EFI_STATUS Status;
CM_OBJ_NODE *ObjNode;
CM_OBJECT_ID ObjId;
CM_OBJECT_TOKEN NewToken;
LIST_ENTRY *ObjList;
EOBJECT_NAMESPACE_ID NamespaceId;
// The dynamic repository must be able to receive objects.
if ((This == NULL) ||
@ -142,15 +144,33 @@ DynPlatRepoAddObject (
}
// Check the CmObjDesc:
// - only Arm objects are supported for now.
// - only Arm objects and Arch Common objects are supported for now.
// - only EArmObjCmRef objects can be added as arrays.
ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
if ((CmObjDesc->Size == 0) ||
(CmObjDesc->Count == 0) ||
(ArmNamespaceObjId >= EArmObjMax) ||
((CmObjDesc->Count > 1) && (ArmNamespaceObjId != EArmObjCmRef)) ||
(GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm))
{
if ((CmObjDesc->Size == 0) || (CmObjDesc->Count == 0)) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
ObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
NamespaceId = GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId);
if (EObjNameSpaceArm == NamespaceId) {
if ((ObjId >= EArmObjMax) ||
((CmObjDesc->Count > 1) && (ObjId != EArmObjCmRef)))
{
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
ObjList = &This->ArmCmObjList[ObjId];
} else if (EObjNameSpaceArchCommon == NamespaceId) {
if (ObjId >= EArchCommonObjMax) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
ObjList = &This->ArchCommonCmObjList[ObjId];
} else {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
@ -166,15 +186,17 @@ DynPlatRepoAddObject (
}
// Fixup self-token if necessary.
Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken);
if (EFI_ERROR (Status)) {
FreeCmObjNode (ObjNode);
ASSERT (0);
return Status;
if (EObjNameSpaceArm == NamespaceId) {
Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken);
if (EFI_ERROR (Status)) {
FreeCmObjNode (ObjNode);
ASSERT (0);
return Status;
}
}
// Add to link list.
InsertTailList (&This->ArmCmObjList[ArmNamespaceObjId], &ObjNode->Link);
InsertTailList (ObjList, &ObjNode->Link);
This->ObjectCount += 1;
if (Token != NULL) {
@ -184,11 +206,14 @@ DynPlatRepoAddObject (
return EFI_SUCCESS;
}
/** Group lists of CmObjNode from the ArmNameSpace to one array.
/** Group lists of CmObjNode from the Arm Namespace or ArchCommon namespace
to one array.
@param [in] This This dynamic platform repository.
@param [in] ArmObjIndex Index in EARM_OBJECT_ID
(must be < EArmObjMax).
@param [in] NamespaceId The namespace ID which can be EObjNameSpaceArm or
EObjNameSpaceArchCommon.
@param [in] ObjIndex Index in EARM_OBJECT_ID (must be < EArmObjMax) or
EARCH_COMMON_OBJECT_ID (must be <EArchCommonObjMax).
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@ -200,7 +225,8 @@ EFI_STATUS
EFIAPI
GroupCmObjNodes (
IN DYNAMIC_PLATFORM_REPOSITORY_INFO *This,
IN UINT32 ArmObjIndex
IN EOBJECT_NAMESPACE_ID NamespaceId,
IN UINT32 ObjIndex
)
{
EFI_STATUS Status;
@ -212,19 +238,38 @@ GroupCmObjNodes (
CM_OBJ_DESCRIPTOR *CmObjDesc;
LIST_ENTRY *ListHead;
LIST_ENTRY *Link;
CM_OBJ_DESCRIPTOR *ObjArray;
if ((This == NULL) ||
(ArmObjIndex >= EArmObjMax))
{
if (This == NULL) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
Count = 0;
Size = 0;
CmObjId = CREATE_CM_ARM_OBJECT_ID (ArmObjIndex);
ListHead = &This->ArmCmObjList[ArmObjIndex];
Link = GetFirstNode (ListHead);
if (NamespaceId == EObjNameSpaceArm) {
if (ObjIndex >= EArmObjMax) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
ListHead = &This->ArmCmObjList[ObjIndex];
ObjArray = &This->ArmCmObjArray[ObjIndex];
} else if (NamespaceId == EObjNameSpaceArchCommon) {
if (ObjIndex >= EArchCommonObjMax) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
ListHead = &This->ArchCommonCmObjList[ObjIndex];
ObjArray = &This->ArchCommonCmObjArray[ObjIndex];
} else {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
Count = 0;
Size = 0;
CmObjId = CREATE_CM_OBJECT_ID (NamespaceId, ObjIndex);
Link = GetFirstNode (ListHead);
// Compute the total count and size of the CmObj in the list.
while (Link != ListHead) {
@ -235,7 +280,10 @@ GroupCmObjNodes (
return EFI_INVALID_PARAMETER;
}
if ((CmObjDesc->Count != 1) && (ArmObjIndex != EArmObjCmRef)) {
if ((CmObjDesc->Count != 1) &&
((NamespaceId != EObjNameSpaceArm) ||
(ObjIndex != EArmObjCmRef)))
{
// We expect each descriptor to contain an individual object.
// EArmObjCmRef objects are counted as groups, so +1 as well.
ASSERT (0);
@ -286,7 +334,7 @@ GroupCmObjNodes (
Link = GetNextNode (ListHead, Link);
} // while
CmObjDesc = &This->ArmCmObjArray[ArmObjIndex];
CmObjDesc = ObjArray;
CmObjDesc->ObjectId = CmObjId;
CmObjDesc->Size = (UINT32)Size;
CmObjDesc->Count = (UINT32)Count;
@ -317,7 +365,7 @@ DynamicPlatRepoFinalise (
)
{
EFI_STATUS Status;
UINTN ArmObjIndex;
UINTN ObjIndex;
if ((This == NULL) ||
(This->RepoState != DynRepoTransient))
@ -340,18 +388,29 @@ DynamicPlatRepoFinalise (
// - Convert the list of nodes to an array
// (the array is wrapped in a CmObjDesc).
// - Add the Token/CmObj binding to the token mapper.
for (ArmObjIndex = 0; ArmObjIndex < EArmObjMax; ArmObjIndex++) {
Status = GroupCmObjNodes (This, (UINT32)ArmObjIndex);
for (ObjIndex = 0; ObjIndex < EArmObjMax; ObjIndex++) {
Status = GroupCmObjNodes (This, EObjNameSpaceArm, (UINT32)ObjIndex);
if (EFI_ERROR (Status)) {
ASSERT (0);
// Free the TokenMapper.
// Ignore the returned Status since we already failed.
TokenMapperShutdown (&This->TokenMapper);
return Status;
goto error_handler;
}
} // for
for (ObjIndex = 0; ObjIndex < EArchCommonObjMax; ObjIndex++) {
Status = GroupCmObjNodes (This, EObjNameSpaceArchCommon, (UINT32)ObjIndex);
if (EFI_ERROR (Status)) {
ASSERT (0);
goto error_handler;
}
} // for
return EFI_SUCCESS;
error_handler:
// Free the TokenMapper.
// Ignore the returned Status since we already failed.
TokenMapperShutdown (&This->TokenMapper);
return Status;
}
/** Get a CmObj from the dynamic repository.
@ -376,9 +435,10 @@ DynamicPlatRepoGetObject (
IN OUT CM_OBJ_DESCRIPTOR *CmObjDesc
)
{
EFI_STATUS Status;
CM_OBJ_DESCRIPTOR *Desc;
CM_OBJECT_ID ArmNamespaceObjId;
EFI_STATUS Status;
CM_OBJ_DESCRIPTOR *Desc;
CM_OBJECT_ID ObjId;
EOBJECT_NAMESPACE_ID NamespaceId;
if ((This == NULL) ||
(CmObjDesc == NULL) ||
@ -388,8 +448,28 @@ DynamicPlatRepoGetObject (
return EFI_INVALID_PARAMETER;
}
ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjectId);
if (ArmNamespaceObjId >= EArmObjMax) {
NamespaceId = GET_CM_NAMESPACE_ID (CmObjectId);
ObjId = GET_CM_OBJECT_ID (CmObjectId);
if (NamespaceId == EObjNameSpaceArm) {
if ((ObjId >= EArmObjMax) ||
((ObjId == EArmObjCmRef) &&
(Token == CM_NULL_TOKEN)))
{
// EArmObjCmRef object must be requested using a valid token.
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
Desc = &This->ArmCmObjArray[ObjId];
} else if (NamespaceId == EObjNameSpaceArchCommon) {
if (ObjId >= EArchCommonObjMax) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
Desc = &This->ArchCommonCmObjArray[ObjId];
} else {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
@ -406,14 +486,6 @@ DynamicPlatRepoGetObject (
return Status;
}
if (ArmNamespaceObjId == EArmObjCmRef) {
// EArmObjCmRef object must be requested using a valid token.
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
Desc = &This->ArmCmObjArray[ArmNamespaceObjId];
// Nothing here.
if (Desc->Count == 0) {
return EFI_NOT_FOUND;
@ -462,6 +534,10 @@ DynamicPlatRepoInit (
InitializeListHead (&Repo->ArmCmObjList[Index]);
}
for (Index = 0; Index < EArchCommonObjMax; Index++) {
InitializeListHead (&Repo->ArchCommonCmObjList[Index]);
}
Repo->ObjectCount = 0;
Repo->RepoState = DynRepoTransient;
@ -470,31 +546,27 @@ DynamicPlatRepoInit (
return EFI_SUCCESS;
}
/** Shutdown the dynamic platform repository.
/** Free Arm Namespace objects.
Free all the memory allocated for the dynamic platform repository.
Free all the memory allocated for the Arm namespace objects in the
dynamic platform repository.
@param [in] DynPlatRepo The dynamic platform repository.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_SUCCESS Success.
**/
EFI_STATUS
STATIC
VOID
EFIAPI
DynamicPlatRepoShutdown (
DynamicPlatRepoFreeArmObjects (
IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo
)
{
EFI_STATUS Status;
UINT32 Index;
LIST_ENTRY *ListHead;
CM_OBJ_DESCRIPTOR *CmObjDesc;
VOID *Data;
if (DynPlatRepo == NULL) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
ASSERT (DynPlatRepo != NULL);
// Free the list of objects.
for (Index = 0; Index < EArmObjMax; Index++) {
@ -513,6 +585,73 @@ DynamicPlatRepoShutdown (
FreePool (Data);
}
} // for
}
/** Free Arch Common Namespace objects.
Free all the memory allocated for the Arch Common namespace objects in the
dynamic platform repository.
@param [in] DynPlatRepo The dynamic platform repository.
**/
STATIC
VOID
EFIAPI
DynamicPlatRepoFreeArchCommonObjects (
IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo
)
{
UINT32 Index;
LIST_ENTRY *ListHead;
CM_OBJ_DESCRIPTOR *CmObjDesc;
VOID *Data;
ASSERT (DynPlatRepo != NULL);
// Free the list of objects.
for (Index = 0; Index < EArchCommonObjMax; Index++) {
// Free all the nodes with this object Id.
ListHead = &DynPlatRepo->ArchCommonCmObjList[Index];
while (!IsListEmpty (ListHead)) {
FreeCmObjNode ((CM_OBJ_NODE *)GetFirstNode (ListHead));
} // while
} // for
// Free the arrays.
CmObjDesc = DynPlatRepo->ArchCommonCmObjArray;
for (Index = 0; Index < EArchCommonObjMax; Index++) {
Data = CmObjDesc[Index].Data;
if (Data != NULL) {
FreePool (Data);
}
} // for
}
/** Shutdown the dynamic platform repository.
Free all the memory allocated for the dynamic platform repository.
@param [in] DynPlatRepo The dynamic platform repository.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_SUCCESS Success.
**/
EFI_STATUS
EFIAPI
DynamicPlatRepoShutdown (
IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo
)
{
EFI_STATUS Status;
if (DynPlatRepo == NULL) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
DynamicPlatRepoFreeArmObjects (DynPlatRepo);
DynamicPlatRepoFreeArchCommonObjects (DynPlatRepo);
// Free the TokenMapper
Status = TokenMapperShutdown (&DynPlatRepo->TokenMapper);

View File

@ -67,7 +67,16 @@ typedef struct DynamicPlatformRepositoryInfo {
/// This array is populated when the Repo is finalized.
CM_OBJ_DESCRIPTOR ArmCmObjArray[EArmObjMax];
/// A token mapper for the objects in the ArmNamespaceObjectArray
/// Link lists of CmObj from the ArchCommon Namespace
/// that are added in the Transient state.
LIST_ENTRY ArchCommonCmObjList[EArchCommonObjMax];
/// Structure Members used in Finalized state.
/// An array of CmObj Descriptors from the ArchCommon Namespace
/// This array is populated when the Repo is finalized.
CM_OBJ_DESCRIPTOR ArchCommonCmObjArray[EArchCommonObjMax];
/// A token mapper for the objects in the <Arm|ArchCommon>CmObjArray
/// The Token mapper is populated when the Repo is finalized in
/// a call to DynamicPlatRepoFinalise ().
TOKEN_MAPPER TokenMapper;