/** @file
Library functions for Config Block management.
Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
/**
Create config block table.
@param[in] TotalSize - Max size to be allocated for the Config Block Table
@param[out] ConfigBlockTableAddress - On return, points to a pointer to the beginning of Config Block Table Address
@retval EFI_INVALID_PARAMETER - Invalid Parameter
@retval EFI_OUT_OF_RESOURCES - Out of resources
@retval EFI_SUCCESS - Successfully created Config Block Table at ConfigBlockTableAddress
**/
EFI_STATUS
EFIAPI
CreateConfigBlockTable (
IN UINT16 TotalSize,
OUT VOID **ConfigBlockTableAddress
)
{
CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
UINT32 ConfigBlkTblHdrSize;
ConfigBlkTblHdrSize = (UINT32)(sizeof (CONFIG_BLOCK_TABLE_HEADER));
if (TotalSize <= (ConfigBlkTblHdrSize + sizeof (CONFIG_BLOCK_HEADER))) {
return EFI_INVALID_PARAMETER;
}
ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)AllocateZeroPool (TotalSize);
if (ConfigBlkTblAddrPtr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
ConfigBlkTblAddrPtr->NumberOfBlocks = 0;
ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength = TotalSize;
ConfigBlkTblAddrPtr->AvailableSize = TotalSize - ConfigBlkTblHdrSize;
*ConfigBlockTableAddress = (VOID *)ConfigBlkTblAddrPtr;
return EFI_SUCCESS;
}
/**
Add config block into config block table structure.
@param[in] ConfigBlockTableAddress - A pointer to the beginning of Config Block Table Address
@param[out] ConfigBlockAddress - On return, points to a pointer to the beginning of Config Block Address
@retval EFI_OUT_OF_RESOURCES - Config Block Table is full and cannot add new Config Block or
Config Block Offset Table is full and cannot add new Config Block.
@retval EFI_SUCCESS - Successfully added Config Block
**/
EFI_STATUS
EFIAPI
AddConfigBlock (
IN VOID *ConfigBlockTableAddress,
OUT VOID **ConfigBlockAddress
)
{
CONFIG_BLOCK *TempConfigBlk;
CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
CONFIG_BLOCK *ConfigBlkAddrPtr;
UINT16 ConfigBlkSize;
ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)ConfigBlockTableAddress;
ConfigBlkAddrPtr = (CONFIG_BLOCK *)(*ConfigBlockAddress);
ConfigBlkSize = ConfigBlkAddrPtr->Header.GuidHob.Header.HobLength;
if ((ConfigBlkSize % 4) != 0) {
return EFI_INVALID_PARAMETER;
}
if (ConfigBlkTblAddrPtr->AvailableSize < ConfigBlkSize) {
return EFI_OUT_OF_RESOURCES;
}
TempConfigBlk = (CONFIG_BLOCK *)((UINTN)ConfigBlkTblAddrPtr + (UINTN)(ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength - ConfigBlkTblAddrPtr->AvailableSize));
CopyMem (&TempConfigBlk->Header, &ConfigBlkAddrPtr->Header, sizeof(CONFIG_BLOCK_HEADER));
ConfigBlkTblAddrPtr->NumberOfBlocks++;
ConfigBlkTblAddrPtr->AvailableSize = ConfigBlkTblAddrPtr->AvailableSize - ConfigBlkSize;
*ConfigBlockAddress = (VOID *) TempConfigBlk;
return EFI_SUCCESS;
}
/**
Retrieve a specific Config Block data by GUID.
@param[in] ConfigBlockTableAddress - A pointer to the beginning of Config Block Table Address
@param[in] ConfigBlockGuid - A pointer to the GUID uses to search specific Config Block
@param[out] ConfigBlockAddress - On return, points to a pointer to the beginning of Config Block Address
@retval EFI_NOT_FOUND - Could not find the Config Block
@retval EFI_SUCCESS - Config Block found and return
**/
EFI_STATUS
EFIAPI
GetConfigBlock (
IN VOID *ConfigBlockTableAddress,
IN EFI_GUID *ConfigBlockGuid,
OUT VOID **ConfigBlockAddress
)
{
UINT16 OffsetIndex;
CONFIG_BLOCK *TempConfigBlk;
CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
UINT32 ConfigBlkTblHdrSize;
UINT32 ConfigBlkOffset;
UINT16 NumOfBlocks;
ConfigBlkTblHdrSize = (UINT32)(sizeof (CONFIG_BLOCK_TABLE_HEADER));
ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)ConfigBlockTableAddress;
NumOfBlocks = ConfigBlkTblAddrPtr->NumberOfBlocks;
ConfigBlkOffset = 0;
for (OffsetIndex = 0; OffsetIndex < NumOfBlocks; OffsetIndex++) {
if ((ConfigBlkTblHdrSize + ConfigBlkOffset) > (ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength)) {
break;
}
TempConfigBlk = (CONFIG_BLOCK *)((UINTN)ConfigBlkTblAddrPtr + (UINTN)ConfigBlkTblHdrSize + (UINTN)ConfigBlkOffset);
if (CompareGuid (&(TempConfigBlk->Header.GuidHob.Name), ConfigBlockGuid)) {
*ConfigBlockAddress = (VOID *)TempConfigBlk;
return EFI_SUCCESS;
}
ConfigBlkOffset = ConfigBlkOffset + TempConfigBlk->Header.GuidHob.Header.HobLength;
}
return EFI_NOT_FOUND;
}