Files
slimbootloader/BootloaderCommonPkg/Library/ConfigDataLib/ConfigDataLib.c
T

234 lines
6.5 KiB
C
Raw Normal View History

2019-12-02 15:45:02 -08:00
/** @file
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <Library/DebugLib.h>
#include <Library/BootloaderCommonLib.h>
#include <Library/ConfigDataLib.h>
#include <Library/BaseMemoryLib.h>
/**
Find configuration data header by its tag and platform ID.
@param[in] PidMask Platform ID mask.
@param[in] Tag Configuration TAG ID to find.
@param[in] IsInternal Search for internal data base only if it is non-zero.
@param[in] Level Nested call level.
@retval Configuration data header pointer.
NULL if the tag cannot be found.
**/
CDATA_HEADER *
FindConfigHdrByPidMaskTag (
UINT32 PidMask,
UINT32 Tag,
UINT8 IsInternal,
UINT32 Level
)
{
CDATA_BLOB *CdataBlob;
CDATA_HEADER *CdataHdr;
UINT8 Idx;
REFERENCE_CFG_DATA *Refer;
UINT32 Offset;
CdataBlob = (CDATA_BLOB *) GetConfigDataPtr ();
Offset = IsInternal > 0 ? (CdataBlob->InternalDataOffset * 4) : CdataBlob->HeaderLength;
while (Offset < CdataBlob->UsedLength) {
CdataHdr = (CDATA_HEADER *) ((UINT8 *)CdataBlob + Offset);
if (CdataHdr->Tag == Tag) {
for (Idx = 0; Idx < CdataHdr->ConditionNum; Idx++) {
if ((PidMask & CdataHdr->Condition[Idx].Value) != 0) {
// Found a match
if ((CdataHdr->Flags & CDATA_FLAG_TYPE_MASK) == CDATA_FLAG_TYPE_REFER) {
if (Level > 0) {
// Prevent multiple level nesting
return NULL;
} else {
Refer = (REFERENCE_CFG_DATA *) ((UINT8 *)CdataHdr + sizeof (CDATA_HEADER) + sizeof (
CDATA_COND) * CdataHdr->ConditionNum);
return FindConfigHdrByPidMaskTag (PID_TO_MASK (Refer->PlatformId), \
Refer->Tag, (UINT8)Refer->IsInternal, 1);
}
} else {
return (VOID *)CdataHdr;
}
}
}
}
Offset += (CdataHdr->Length << 2);
}
return NULL;
}
/**
Find configuration data header by its tag.
@param[in] Tag Configuration TAG ID to find.
@retval Configuration data header pointer.
NULL if the tag cannot be found.
**/
CDATA_HEADER *
EFIAPI
FindConfigHdrByTag (
UINT32 Tag
)
{
UINT16 PlatformId;
PlatformId = GetPlatformId ();
return FindConfigHdrByPidMaskTag (PID_TO_MASK (PlatformId), Tag, 0, 0);
}
/**
Find configuration data by its tag and PlatforID.
@param[in] PlatformId Platform ID.
@param[in] Tag Configuration TAG ID to find.
@retval Configuration data pointer.
NULL if the tag cannot be found.
**/
VOID *
EFIAPI
FindConfigDataByPidTag (
UINT16 PlatformId,
UINT32 Tag
)
{
CDATA_HEADER *CdataHdr;
VOID *Cdata;
CdataHdr = FindConfigHdrByPidMaskTag (PID_TO_MASK (PlatformId), Tag, 0, 0);
if (CdataHdr == NULL) {
Cdata = NULL;
} else {
Cdata = (VOID *) ((UINT8 *)CdataHdr + sizeof (CDATA_HEADER) + sizeof (CDATA_COND) * CdataHdr->ConditionNum);
}
return Cdata;
}
/**
Find configuration data by its tag.
@param[in] Tag Configuration TAG ID to find.
@retval Configuration data pointer.
NULL if the tag cannot be found.
**/
VOID *
EFIAPI
FindConfigDataByTag (
UINT32 Tag
)
{
CDATA_HEADER *CdataHdr;
VOID *Cdata;
CdataHdr = FindConfigHdrByTag (Tag);
if (CdataHdr == NULL) {
Cdata = NULL;
} else {
Cdata = (VOID *) ((UINT8 *)CdataHdr + sizeof (CDATA_HEADER) + sizeof (CDATA_COND) * CdataHdr->ConditionNum);
}
return Cdata;
}
/**
Add new Config Data
Ext/Built-In Config Data for a specific board
is added to the Config Data Blob present at the
CfgDataPtr in the LDR_GLOBAL_DATA. Exclude the
CFG_BLOB header here as it is already there with CfgDataPtr.
@param[in] CfgAddPtr Address of the CfgBlob that is to be added
@retval EFI_SUCCESS if the CfgBlob is added successfully
@retval EFI_UNSUPPORTED if not a valid CfgBlob
@retval EFI_OUT_OF_RESOURCES if not enough memory available to add Config Data
**/
EFI_STATUS
EFIAPI
AddConfigData (
IN UINT8 *CfgAddPtr
)
{
CDATA_BLOB *LdrCfgBlob;
CDATA_BLOB *CfgAddBlob;
INT32 CfgAddSize;
LdrCfgBlob = (CDATA_BLOB *) GetConfigDataPtr ();
CfgAddBlob = (CDATA_BLOB *) CfgAddPtr;
if ((CfgAddBlob == NULL) || (CfgAddBlob->Signature != CFG_DATA_SIGNATURE)) {
return EFI_UNSUPPORTED;
}
CfgAddSize = CfgAddBlob->UsedLength - (UINT32) (CfgAddBlob->HeaderLength);
if (CfgAddSize < 0) {
return EFI_UNSUPPORTED;
} else if (CfgAddSize > (INT32) (LdrCfgBlob->TotalLength - LdrCfgBlob->UsedLength)) {
return EFI_OUT_OF_RESOURCES;
}
if (LdrCfgBlob->InternalDataOffset == 0) {
// Append new config data before internal config data is available.
CopyMem ((UINT8 *)LdrCfgBlob + LdrCfgBlob->UsedLength,
(UINT8 *)CfgAddBlob + CfgAddBlob->HeaderLength,
CfgAddSize);
} else {
//
// Newly added config data has high priority
// so move the the old config data firstly,
// then copy new config data just below header
//
CopyMem ((UINT8 *)LdrCfgBlob + LdrCfgBlob->HeaderLength + CfgAddSize,
(UINT8 *)LdrCfgBlob + LdrCfgBlob->HeaderLength,
LdrCfgBlob->UsedLength - LdrCfgBlob->HeaderLength);
CopyMem ((UINT8 *)LdrCfgBlob + LdrCfgBlob->HeaderLength,
(UINT8 *)CfgAddBlob + CfgAddBlob->HeaderLength,
CfgAddSize);
LdrCfgBlob->InternalDataOffset += (UINT16) (CfgAddSize >> 2);
}
LdrCfgBlob->UsedLength += CfgAddSize;
return EFI_SUCCESS;
}
/**
Get the source of the external configuration data to load.
@param[in] Index Index of the source
@retval PDR if external data is loaded from SPI Flash PDR region
@retval BIOS if external data is loaded from SPI Flash BIOS region
@retval NULL if external data is loaded from niether
**/
CHAR8 *
GetCfgDataSource (
IN UINT8 Index
)
{
if (Index == 0) {
return "PDR";
} else if (Index == 1) {
return "BIOS";
} else {
return "NULL";
}
}