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 /** The EARM_OBJECT_ID enum describes the Object IDs
in the ARM Namespace 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 { typedef enum ArmObjectID {
EArmObjReserved, ///< 0 - Reserved EArmObjReserved, ///< 0 - Reserved

View File

@ -183,6 +183,17 @@ CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = {
NULL, ///< 37 - Lpi Info NULL, ///< 37 - Lpi Info
NULL, ///< 38 - Pci Address Map Info NULL, ///< 38 - Pci Address Map Info
NULL, ///< 39 - Pci Interrupt 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. /** CmObj token fixer.

View File

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

View File

@ -67,7 +67,16 @@ typedef struct DynamicPlatformRepositoryInfo {
/// This array is populated when the Repo is finalized. /// This array is populated when the Repo is finalized.
CM_OBJ_DESCRIPTOR ArmCmObjArray[EArmObjMax]; 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 /// The Token mapper is populated when the Repo is finalized in
/// a call to DynamicPlatRepoFinalise (). /// a call to DynamicPlatRepoFinalise ().
TOKEN_MAPPER TokenMapper; TOKEN_MAPPER TokenMapper;