diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c new file mode 100644 index 0000000000..9391e935ee --- /dev/null +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c @@ -0,0 +1,224 @@ +/** @file + Token Mapper + + Copyright (c) 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#include +#include +#include +#include + +#include "TokenMapper.h" + +/** Add a CmObjDesc to the TokenMapper. + + @param [in] TokenMapper The TokenMapper instance. + @param [in] Token CmObj token. + @param [in] ObjectId CmObj ObjectId. + @param [in] Size CmObj Size. + @param [in] Data CmObj Data. + This memory is referenced, not copied. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_BUFFER_TOO_SMALL Buffer too small. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +EFI_STATUS +EFIAPI +TokenMapperAddObject ( + IN TOKEN_MAPPER *TokenMapper, + IN CM_OBJECT_TOKEN Token, + IN CM_OBJECT_ID ObjectId, + IN UINT32 Size, + IN VOID *Data + ) +{ + TOKEN_MAP_DESCRIPTOR *TokenMapDesc; + CM_OBJ_DESCRIPTOR *CmObjDesc; + + if ((TokenMapper == NULL) || + (TokenMapper->TokenDescArray == NULL) || + (Size == 0) || + (Data == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + if (TokenMapper->ItemCount >= TokenMapper->MaxTokenDescCount) { + ASSERT (0); + return EFI_BUFFER_TOO_SMALL; + } + + TokenMapDesc = &TokenMapper->TokenDescArray[TokenMapper->ItemCount++]; + TokenMapDesc->Token = Token; + CmObjDesc = &TokenMapDesc->CmObjDesc; + CmObjDesc->ObjectId = ObjectId; + CmObjDesc->Size = Size; + + // Point inside the finalized array. + CmObjDesc->Data = Data; + + // Only EArmObjCmRef CmObj can be added as arrays (more than 1 elements). + if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArm) && + (GET_CM_OBJECT_ID (ObjectId) == EArmObjCmRef)) + { + CmObjDesc->Count = Size / sizeof (CM_ARM_OBJ_REF); + } else { + CmObjDesc->Count = 1; + } + + return EFI_SUCCESS; +} + +/** Get a CmObjDesc from a ObjectId/Token couple. + + The Token parameter is not optional. An existing token must be provided. + + @param [in] TokenMapper The TokenMapper instance. + @param [in] Token Token of the CmObj to search. + @param [in] ObjectId Object Id of the CmObj to search. + @param [out] CmObjDesc CM_OBJ_DESCRIPTOR containing the CmObj searched. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Not found. +**/ +EFI_STATUS +EFIAPI +TokenMapperGetObject ( + IN TOKEN_MAPPER *TokenMapper, + IN CM_OBJECT_TOKEN Token, + IN CM_OBJECT_ID ObjectId, + OUT CM_OBJ_DESCRIPTOR *CmObjDesc + ) +{ + UINTN Index; + UINTN MaxCount; + TOKEN_MAP_DESCRIPTOR *TokenMapDesc; + + // Nothing to do. + if ((TokenMapper != NULL) && (TokenMapper->MaxTokenDescCount == 0)) { + goto exit_handler; + } + + if ((Token == CM_NULL_TOKEN) || + (CmObjDesc == NULL) || + (TokenMapper == NULL) || + (TokenMapper->TokenDescArray == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + TokenMapDesc = TokenMapper->TokenDescArray; + MaxCount = TokenMapper->MaxTokenDescCount; + for (Index = 0; Index < MaxCount; Index++) { + if ((TokenMapDesc->CmObjDesc.ObjectId == ObjectId) && + (TokenMapDesc->Token == Token)) + { + CopyMem ( + CmObjDesc, + &TokenMapDesc->CmObjDesc, + sizeof (CM_OBJ_DESCRIPTOR) + ); + return EFI_SUCCESS; + } + + TokenMapDesc++; + } // for + +exit_handler: + DEBUG (( + DEBUG_INFO, + "INFO: Requested CmObj of type 0x%x with token 0x%x" + " not found in the dynamic repository\n.", + ObjectId, + Token + )); + return EFI_NOT_FOUND; +} + +/** Initialise a TokenMapper. + + @param [in] TokenMapper The TokenMapper to initialise. + @param [in] DescriptorCount Number of entries to allocate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ALREADY_STARTED Instance already initialised. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +EFI_STATUS +EFIAPI +TokenMapperInitialise ( + IN TOKEN_MAPPER *TokenMapper, + IN UINTN DescriptorCount + ) +{ + if (TokenMapper == NULL) { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // Nothing to do. + if (DescriptorCount == 0) { + return EFI_SUCCESS; + } + + if (TokenMapper->TokenDescArray != NULL) { + DEBUG ((DEBUG_ERROR, "ERROR: Token mapper already initialised\n.")); + ASSERT (0); + return EFI_ALREADY_STARTED; + } + + TokenMapper->TokenDescArray = + AllocateZeroPool (sizeof (TOKEN_MAP_DESCRIPTOR) * DescriptorCount); + if (TokenMapper->TokenDescArray == NULL) { + ASSERT (0); + return EFI_OUT_OF_RESOURCES; + } + + TokenMapper->MaxTokenDescCount = DescriptorCount; + TokenMapper->ItemCount = 0; + + return EFI_SUCCESS; +} + +/** Shutdown a TokenMapper. + + @param [in] TokenMapper The TokenMapper to shutdown. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +EFI_STATUS +EFIAPI +TokenMapperShutdown ( + IN TOKEN_MAPPER *TokenMapper + ) +{ + // Nothing to do. + if ((TokenMapper != NULL) && (TokenMapper->MaxTokenDescCount == 0)) { + return EFI_SUCCESS; + } + + if ((TokenMapper == NULL) || + (TokenMapper->TokenDescArray == NULL)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + FreePool (TokenMapper->TokenDescArray); + TokenMapper->TokenDescArray = NULL; + TokenMapper->MaxTokenDescCount = 0; + + return EFI_SUCCESS; +} diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h new file mode 100644 index 0000000000..a7b1590903 --- /dev/null +++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.h @@ -0,0 +1,123 @@ +/** @file + Token Mapper + + Copyright (c) 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#ifndef TOKEN_MAPPER_H_ +#define TOKEN_MAPPER_H_ + +#pragma pack(1) + +/** Token mapping descriptor. + + Bind a token and a CmObj together. +*/ +typedef struct TokenMapDescriptor { + /// Object Token. + CM_OBJECT_TOKEN Token; + + /// CmObjectDescriptor CM_OBJ_DESCRIPTOR.Data is a reference copy + /// and not allocated. It points to the individual objects in the + /// Dynamic Plat Repo ArmNameSpaceObjectArray. + CM_OBJ_DESCRIPTOR CmObjDesc; +} TOKEN_MAP_DESCRIPTOR; + +/** Token mapper. + + Contain all the Token/CmObj couple mapping. +**/ +typedef struct TokenMapper { + /// Maximum number of TOKEN_MAP_DESCRIPTOR entries in TokenDescArray. + UINTN MaxTokenDescCount; + + /// Next TOKEN_MAP_DESCRIPTOR entry to use in TokenDescArray. + UINTN ItemCount; + + /// Array of TOKEN_MAP_DESCRIPTOR. + TOKEN_MAP_DESCRIPTOR *TokenDescArray; +} TOKEN_MAPPER; + +#pragma pack() + +/** Add a CmObjDesc to the TokenMapper. + + @param [in] TokenMapper The TokenMapper instance. + @param [in] Token CmObj token. + @param [in] ObjectId CmObj ObjectId. + @param [in] Size CmObj Size. + @param [in] Data CmObj Data. + This memory is referenced, not copied. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_BUFFER_TOO_SMALL Buffer too small. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +EFI_STATUS +EFIAPI +TokenMapperAddObject ( + IN TOKEN_MAPPER *TokenMapper, + IN CM_OBJECT_TOKEN Token, + IN CM_OBJECT_ID ObjectId, + IN UINT32 Size, + IN VOID *Data + ); + +/** Get a CmObjDesc from a ObjectId/Token couple. + + The Token parameter is not optional. An existing token must be provided. + + @param [in] TokenMapper The TokenMapper instance. + @param [in] Token Token of the CmObj to search. + @param [in] ObjectId Object Id of the CmObj to search. + @param [out] CmObjDesc CM_OBJ_DESCRIPTOR containing the CmObj searched. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Not found. +**/ +EFI_STATUS +EFIAPI +TokenMapperGetObject ( + IN TOKEN_MAPPER *TokenMapper, + IN CM_OBJECT_TOKEN Token, + IN CM_OBJECT_ID ObjectId, + OUT CM_OBJ_DESCRIPTOR *CmObjDesc + ); + +/** Initialise a TokenMapper. + + @param [in] TokenMapper The TokenMapper to initialise. + @param [in] DescriptorCount Number of entries to allocate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_ALREADY_STARTED Instance already initialised. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +EFI_STATUS +EFIAPI +TokenMapperInitialise ( + IN TOKEN_MAPPER *TokenMapper, + IN UINTN DescriptorCount + ); + +/** Shutdown a TokenMapper. + + @param [in] TokenMapper The TokenMapper to shutdown. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +EFI_STATUS +EFIAPI +TokenMapperShutdown ( + IN TOKEN_MAPPER *TokenMapper + ); + +#endif // TOKEN_MAPPER_H_