blob: 9391e935eee02cbfa4b3425db3fcd71df3a21210 [file] [log] [blame]
/** @file
Token Mapper
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Glossary:
- Cm or CM - Configuration Manager
- Obj or OBJ - Object
**/
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
#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;
}