MdeModulePkg: Update PCD driver to support the optimized PcdDataBase

https://bugzilla.tianocore.org/show_bug.cgi?id=546
BaseTools will generate the optimized PCD database to save the image size
at build time for multiple SKUs. The optimized PCD database layout will be like
below, the PCD database will be composed of the full default SKU data
(PCD_DATABASE_INIT) and the non-default SKU delta data(PCD_DATABASE_SKU_DELTA).
PCD driver will build HOB to store the full default SKU data, and patch HOB
data based on non-default SKU delta data for the SKU set by SetSku(),
it can save memory resource at boot time.

//
// PCD database layout:
// +---------------------------------+
// | PCD_DATABASE_INIT (DEFAULT SKU) |
// +---------------------------------+
// | PCD_DATABASE_SKU_DELTA (SKU A)  |
// +---------------------------------+
// | PCD_DATABASE_SKU_DELTA (SKU B)  |
// +---------------------------------+
// | ......                          |
// +---------------------------------+
//

BaseTools, PCD database and driver updates are needed for this proposal.
For single SKU (default) case, this proposal is expected to have no impact.
For multi-SKU case, PCD database format will be changed.
So, PcdDataBase Version is also updated from 6 to 7.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
Liming Gao
2017-12-22 13:41:54 +08:00
parent 219247e164
commit 7c73626513
8 changed files with 346 additions and 460 deletions

View File

@@ -30,8 +30,6 @@ GetLocalTokenNumber (
)
{
UINT32 LocalTokenNumber;
UINTN Size;
UINTN MaxSize;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
@@ -42,17 +40,6 @@ GetLocalTokenNumber (
LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);
Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
if (Size == 0) {
GetPtrTypeSize (TokenNumber, &MaxSize, Database);
} else {
MaxSize = Size;
}
LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
}
return LocalTokenNumber;
}
@@ -532,89 +519,6 @@ GetHiiVariable (
return EFI_NOT_FOUND;
}
/**
Find the local token number according to system SKU ID.
@param LocalTokenNumber PCD token number
@param Size The size of PCD entry.
@return Token number according to system SKU ID.
**/
UINT32
GetSkuEnabledTokenNumber (
UINT32 LocalTokenNumber,
UINTN Size
)
{
PEI_PCD_DATABASE *PeiPcdDb;
SKU_HEAD *SkuHead;
SKU_ID *SkuIdTable;
UINTN Index;
UINT8 *Value;
BOOLEAN FoundSku;
PeiPcdDb = GetPcdDatabase ();
ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);
SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));
SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));
//
// Find the current system's SKU ID entry in SKU ID table.
//
FoundSku = FALSE;
for (Index = 0; Index < SkuIdTable[0]; Index++) {
if (PeiPcdDb->SystemSkuId == SkuIdTable[Index + 1]) {
FoundSku = TRUE;
break;
}
}
//
// Find the default SKU ID entry in SKU ID table.
//
if(!FoundSku) {
for (Index = 0; Index < SkuIdTable[0]; Index++) {
if (0 == SkuIdTable[Index + 1]) {
break;
}
}
}
ASSERT (Index < SkuIdTable[0]);
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
case PCD_TYPE_VPD:
Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);
case PCD_TYPE_HII:
Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);
case PCD_TYPE_HII|PCD_TYPE_STRING:
Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING);
case PCD_TYPE_STRING:
Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);
case PCD_TYPE_DATA:
Value += Size * Index;
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_DATA);
default:
ASSERT (FALSE);
}
ASSERT (FALSE);
return 0;
}
/**
Invoke the callback function when dynamic PCD entry was set, if this PCD entry
has registered callback function.
@@ -1117,34 +1021,6 @@ GetPcdDatabase (
return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
}
/**
Get SKU ID table from PCD database.
@param LocalTokenNumberTableIdx Index of local token number in token number table.
@param Database PCD database.
@return Pointer to SKU ID array table
**/
SKU_ID *
GetSkuIdArray (
IN UINTN LocalTokenNumberTableIdx,
IN PEI_PCD_DATABASE *Database
)
{
SKU_HEAD *SkuHead;
UINTN LocalTokenNumber;
LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);
}
/**
Get index of PCD entry in size table.
@@ -1163,8 +1039,7 @@ GetSizeTableIndex (
UINTN Index;
UINTN SizeTableIdx;
UINTN LocalTokenNumber;
SKU_ID *SkuIdTable;
SizeTableIdx = 0;
for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {
@@ -1184,22 +1059,12 @@ GetSizeTableIndex (
//
SizeTableIdx += 2;
} else {
if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
//
// We have only two entry for Non-Sku enabled PCD entry:
// 1) MAX SIZE
// 2) Current Size
//
SizeTableIdx += 2;
} else {
//
// We have these entry for SKU enabled PCD entry
// 1) MAX SIZE
// 2) Current Size for each SKU_ID (It is equal to MaxSku).
//
SkuIdTable = GetSkuIdArray (Index, Database);
SizeTableIdx += (UINTN)*SkuIdTable + 1;
}
}
}