UINT16 ExGuidIndex; // Index of GuidTable in units of GUID.\r
} DYNAMICEX_MAPPING;\r
\r
-typedef struct {\r
- UINT32 SkuDataStartOffset; // Offset(with DATUM TYPE info) from the PCD_DB.\r
- UINT32 SkuIdTableOffset; // Offset from the PCD_DB.\r
-} SKU_HEAD;\r
-\r
typedef struct {\r
UINT32 StringIndex; // Offset in String Table in units of UINT8.\r
UINT32 DefaultValueOffset; // Offset of the Default Value.\r
typedef struct {\r
GUID Signature; // PcdDataBaseGuid.\r
UINT32 BuildVersion;\r
- UINT32 Length;\r
+ UINT32 Length; // Length of DEFAULT SKU PCD DB\r
SKU_ID SystemSkuId; // Current SkuId value.\r
+ UINT32 LengthForAllSkus; // Length of all SKU PCD DB\r
UINT32 UninitDataBaseSize; // Total size for PCD those default value with 0.\r
TABLE_OFFSET LocalTokenNumberTableOffset;\r
TABLE_OFFSET ExMapTableOffset;\r
UINT16 LocalTokenCount; // LOCAL_TOKEN_NUMBER for all.\r
UINT16 ExTokenCount; // EX_TOKEN_NUMBER for DynamicEx.\r
UINT16 GuidTableCount; // The Number of Guid in GuidTable.\r
- UINT8 Pad[2]; // Pad bytes to satisfy the alignment.\r
+ UINT8 Pad[6]; // Pad bytes to satisfy the alignment.\r
\r
//\r
// Default initialized external PCD database binary structure\r
// Padding is needed to keep necessary alignment\r
//\r
//SKU_ID SkuIdTable[]; // SkuIds system supports.\r
- //SKU_ID SkuIndexTable[]; // SkuIds for each PCD with SKU enable.\r
//UINT64 ValueUint64[];\r
//UINT32 ValueUint32[];\r
//VPD_HEAD VpdHead[]; // VPD Offset\r
//STRING_HEAD StringHead[]; // String PCD\r
//PCD_NAME_INDEX PcdNameTable[]; // PCD name index info. It can be accessed by the PcdNameTableOffset.\r
//VARIABLE_HEAD VariableHead[]; // HII PCD\r
- //SKU_HEAD SkuHead[]; // Store SKU info for each PCD with SKU enable.\r
//UINT8 StringTable[]; // String for String PCD value and HII PCD Variable Name. It can be accessed by StringTableOffset.\r
//SIZE_INFO SizeTable[]; // MaxSize and CurSize for String PCD. It can be accessed by SizeTableOffset.\r
//UINT16 ValueUint16[];\r
// +-------------------------------------+\r
//\r
\r
+#pragma pack(1)\r
+typedef struct {\r
+ SKU_ID SkuId;\r
+ SKU_ID SkuIdCompared;\r
+ UINT32 Length;\r
+ // PCD_DATA_DELTA DeltaData[]\r
+} PCD_DATABASE_SKU_DELTA;\r
+\r
+//\r
+// PCD database layout:\r
+// +---------------------------------+\r
+// | PCD_DATABASE_INIT (DEFAULT SKU) |\r
+// +---------------------------------+\r
+// | PCD_DATABASE_SKU_DELTA (SKU A) |\r
+// +---------------------------------+\r
+// | PCD_DATABASE_SKU_DELTA (SKU B) |\r
+// +---------------------------------+\r
+// | ...... |\r
+// +---------------------------------+\r
+//\r
+#pragma pack()\r
+\r
#endif\r
IN UINTN SkuId\r
)\r
{\r
- SKU_ID *SkuIdTable;\r
- UINTN Index;\r
+ SKU_ID *SkuIdTable;\r
+ UINTN Index;\r
+ EFI_STATUS Status;\r
\r
if (SkuId == mPcdDatabase.DxeDb->SystemSkuId) {\r
//\r
SkuIdTable = (SKU_ID *) ((UINT8 *) mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SkuIdTableOffset);\r
for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
if (SkuId == SkuIdTable[Index + 1]) {\r
- DEBUG ((EFI_D_INFO, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId));\r
- mPcdDatabase.DxeDb->SystemSkuId = (SKU_ID) SkuId;\r
- return;\r
+ Status = UpdatePcdDatabase (SkuId, TRUE);\r
+ if (!EFI_ERROR (Status)) {\r
+ mPcdDatabase.DxeDb->SystemSkuId = (SKU_ID) SkuId;\r
+ DEBUG ((DEBUG_INFO, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId));\r
+ return;\r
+ }\r
}\r
}\r
\r
//\r
// Invalid input SkuId, the default SKU Id will be still used for the system.\r
//\r
- DEBUG ((EFI_D_INFO, "PcdDxe - Invalid input SkuId, the default SKU Id will be still used.\n"));\r
+ DEBUG ((DEBUG_INFO, "PcdDxe - Invalid input SkuId, the default SKU Id will be still used.\n"));\r
return;\r
}\r
\r
EFI_GUID **TmpTokenSpaceBuffer;\r
UINTN TmpTokenSpaceBufferCount; \r
\r
+UINTN mPeiPcdDbSize = 0;\r
+PEI_PCD_DATABASE *mPeiPcdDbBinary = NULL;\r
+UINTN mDxePcdDbSize = 0;\r
+DXE_PCD_DATABASE *mDxePcdDbBinary = NULL;\r
+\r
/**\r
Get Local Token Number by Token Number.\r
\r
IN UINTN TokenNumber\r
)\r
{\r
- UINTN TmpTokenNumber;\r
UINT32 *LocalTokenNumberTable;\r
- UINT32 LocalTokenNumber;\r
- UINTN Size;\r
- UINTN MaxSize;\r
\r
//\r
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
//\r
TokenNumber--;\r
\r
- //\r
- // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber\r
- // \r
- TmpTokenNumber = TokenNumber;\r
-\r
LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) : \r
(UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;\r
\r
- LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
-\r
- Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
-\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
- if (Size == 0) {\r
- GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
- } else {\r
- MaxSize = Size;\r
- }\r
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
- }\r
-\r
- return LocalTokenNumber;\r
+ return LocalTokenNumberTable[TokenNumber];\r
}\r
\r
/**\r
VOID\r
) \r
{\r
- DXE_PCD_DATABASE *DxePcdDbBinary;\r
- UINTN DxePcdDbSize;\r
EFI_STATUS Status;\r
\r
- DxePcdDbBinary = NULL;\r
//\r
// Search the External Pcd database from one section of current FFS, \r
// and read it to memory\r
Status = GetSectionFromFfs (\r
EFI_SECTION_RAW,\r
0,\r
- (VOID **) &DxePcdDbBinary,\r
- &DxePcdDbSize\r
+ (VOID **) &mDxePcdDbBinary,\r
+ &mDxePcdDbSize\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Check the first bytes (Header Signature Guid) and build version.\r
//\r
- if (!CompareGuid ((VOID *)DxePcdDbBinary, &gPcdDataBaseSignatureGuid) ||\r
- (DxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) {\r
+ if (!CompareGuid ((VOID *)mDxePcdDbBinary, &gPcdDataBaseSignatureGuid) ||\r
+ (mDxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) {\r
ASSERT (FALSE);\r
}\r
\r
- return DxePcdDbBinary;\r
+ return mDxePcdDbBinary;\r
+}\r
+\r
+/**\r
+ Update PCD database base on current SkuId\r
+\r
+ @param SkuId Current SkuId\r
+ @param IsPeiDb Whether to update PEI PCD database.\r
+\r
+ @retval EFI_SUCCESS Update PCD database successfully.\r
+ @retval EFI_NOT_FOUND Not found PCD database for current SkuId.\r
+**/\r
+EFI_STATUS\r
+UpdatePcdDatabase (\r
+ IN SKU_ID SkuId,\r
+ IN BOOLEAN IsPeiDb\r
+ )\r
+{\r
+ UINTN Index;\r
+ PCD_DATABASE_SKU_DELTA *SkuDelta;\r
+ PCD_DATA_DELTA *SkuDeltaData;\r
+\r
+ if (IsPeiDb && mPeiPcdDbBinary != NULL) {\r
+ //\r
+ // Find the delta data for PEI DB\r
+ //\r
+ Index = (mPcdDatabase.PeiDb->Length + 7) & (~7);\r
+ SkuDelta = NULL;\r
+ while (Index < mPeiPcdDbSize) {\r
+ SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) mPeiPcdDbBinary + Index);\r
+ if (SkuDelta->SkuId == (UINT16) SkuId && SkuDelta->SkuIdCompared == 0) {\r
+ break;\r
+ }\r
+ Index = (Index + SkuDelta->Length + 7) & (~7);\r
+ }\r
+\r
+ //\r
+ // Patch the delta data into current PCD database\r
+ //\r
+ if (Index < mPeiPcdDbSize && SkuDelta != NULL) {\r
+ SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1);\r
+ while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) {\r
+ *((UINT8 *) mPcdDatabase.PeiDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value;\r
+ SkuDeltaData ++;\r
+ }\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Find the delta data for DXE DB\r
+ //\r
+ Index = (mPcdDatabase.DxeDb->Length + 7) & (~7);\r
+ SkuDelta = NULL;\r
+ while (Index < mDxePcdDbSize) {\r
+ SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) mDxePcdDbBinary + Index);\r
+ if (SkuDelta->SkuId == SkuId && SkuDelta->SkuIdCompared == 0) {\r
+ break;\r
+ }\r
+ Index = (Index + SkuDelta->Length + 7) & (~7);\r
+ }\r
+\r
+ //\r
+ // Patch the delta data into current PCD database\r
+ //\r
+ if (Index < mDxePcdDbSize && SkuDelta != NULL) {\r
+ SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1);\r
+ while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) {\r
+ *((UINT8 *) mPcdDatabase.DxeDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value;\r
+ SkuDeltaData ++;\r
+ }\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
}\r
\r
/**\r
UINTN Index;\r
UINT32 PcdDxeDbLen;\r
VOID *PcdDxeDb;\r
+ EFI_STATUS Status;\r
\r
//\r
// Assign PCD Entries with default value to PCD DATABASE\r
PcdDxeDb = AllocateZeroPool (PcdDxeDbLen);\r
ASSERT (PcdDxeDb != NULL);\r
CopyMem (PcdDxeDb, mPcdDatabase.DxeDb, mPcdDatabase.DxeDb->Length);\r
- FreePool (mPcdDatabase.DxeDb);\r
mPcdDatabase.DxeDb = PcdDxeDb;\r
\r
GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
// be NULL. If it is NULL, we just copy over the DXE Default\r
// Value to PCD Database.\r
//\r
- \r
PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
+\r
+ //\r
+ // Get next one that stores full PEI data\r
+ //\r
+ GuidHob = GetNextGuidHob (&gPcdDataBaseHobGuid, GET_NEXT_HOB (GuidHob));\r
+ if (GuidHob != NULL) {\r
+ mPeiPcdDbBinary = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
+ mPeiPcdDbSize = (UINTN) GET_GUID_HOB_DATA_SIZE (GuidHob);\r
+ }\r
+\r
//\r
// Assign PCD Entries refereneced in PEI phase to PCD DATABASE\r
//\r
//\r
// Inherit the SystemSkuId from PEI phase.\r
//\r
+ if (mPcdDatabase.PeiDb->SystemSkuId != 0) {\r
+ Status = UpdatePcdDatabase (mPcdDatabase.PeiDb->SystemSkuId, FALSE);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
mPcdDatabase.DxeDb->SystemSkuId = mPcdDatabase.PeiDb->SystemSkuId;\r
} else {\r
mPcdDatabase.PeiDb = AllocateZeroPool (sizeof (PEI_PCD_DATABASE));\r
return Status;\r
}\r
\r
-/**\r
- Find the local token number according to system SKU ID.\r
-\r
- @param LocalTokenNumber PCD token number\r
- @param Size The size of PCD entry.\r
- @param IsPeiDb If TRUE, the PCD entry is initialized in PEI phase.\r
- If False, the PCD entry is initialized in DXE phase.\r
-\r
- @return Token number according to system SKU ID.\r
-\r
-**/\r
-UINT32\r
-GetSkuEnabledTokenNumber (\r
- UINT32 LocalTokenNumber,\r
- UINTN Size,\r
- BOOLEAN IsPeiDb\r
- ) \r
-{\r
- SKU_HEAD *SkuHead;\r
- SKU_ID *SkuIdTable;\r
- UINTN Index;\r
- UINT8 *Value;\r
- UINT8 *PcdDb;\r
- BOOLEAN FoundSku;\r
-\r
- ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
-\r
- PcdDb = IsPeiDb ? (UINT8 *) mPcdDatabase.PeiDb : (UINT8 *) mPcdDatabase.DxeDb;\r
-\r
- SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
- Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); \r
-\r
- SkuIdTable = (SKU_ID *)(PcdDb + SkuHead->SkuIdTableOffset);\r
- //\r
- // Find the current system's SKU ID entry in SKU ID table.\r
- //\r
- FoundSku = FALSE;\r
- for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
- if (mPcdDatabase.DxeDb->SystemSkuId == SkuIdTable[Index + 1]) {\r
- FoundSku = TRUE;\r
- break;\r
- }\r
- }\r
- \r
- //\r
- // Find the default SKU ID entry in SKU ID table.\r
- //\r
- \r
- if(!FoundSku) {\r
- for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
- if (0 == SkuIdTable[Index + 1]) {\r
- break;\r
- }\r
- }\r
- }\r
- ASSERT (Index < SkuIdTable[0]);\r
-\r
- switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
- case PCD_TYPE_VPD:\r
- Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);\r
- return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);\r
-\r
- case PCD_TYPE_HII:\r
- Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);\r
- return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);\r
-\r
- case PCD_TYPE_HII|PCD_TYPE_STRING:\r
- Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);\r
- return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING);\r
-\r
- case PCD_TYPE_STRING:\r
- Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);\r
- return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING);\r
- \r
- case PCD_TYPE_DATA:\r
- Value += Size * Index;\r
- return (UINT32) ((Value - PcdDb) | PCD_TYPE_DATA);\r
-\r
- default:\r
- ASSERT (FALSE);\r
- }\r
-\r
- ASSERT (FALSE);\r
-\r
- return 0;\r
- \r
-}\r
-\r
/**\r
Invoke the callback function when dynamic PCD entry was set, if this PCD entry \r
has registered callback function.\r
return 0;\r
}\r
\r
-/**\r
- Get SKU ID table from PCD database.\r
-\r
- @param LocalTokenNumberTableIdx Index of local token number in token number table.\r
- @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,\r
- If FALSE, the pcd entry is initialized in DXE phase.\r
- @return Pointer to SKU ID array table\r
-\r
-**/\r
-SKU_ID *\r
-GetSkuIdArray (\r
- IN UINTN LocalTokenNumberTableIdx,\r
- IN BOOLEAN IsPeiDb\r
- )\r
-{\r
- SKU_HEAD *SkuHead;\r
- UINTN LocalTokenNumber;\r
- UINT8 *Database;\r
-\r
- if (IsPeiDb) {\r
- LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
- Database = (UINT8 *) mPcdDatabase.PeiDb;\r
- } else {\r
- LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
- Database = (UINT8 *) mPcdDatabase.DxeDb;\r
- }\r
-\r
- ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
-\r
- SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
-\r
- return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset);\r
- \r
-}\r
-\r
/**\r
Wrapper function of getting index of PCD entry in size table.\r
\r
UINTN LocalTokenNumber;\r
UINTN Index;\r
UINTN SizeTableIdx;\r
- SKU_ID *SkuIdTable;\r
\r
if (IsPeiDb) {\r
LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);\r
//\r
SizeTableIdx += 2;\r
} else {\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
//\r
// We have only two entry for Non-Sku enabled PCD entry:\r
// 1) MAX SIZE\r
// 2) Current Size\r
//\r
SizeTableIdx += 2;\r
- } else {\r
- //\r
- // We have these entry for SKU enabled PCD entry\r
- // 1) MAX SIZE\r
- // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
- //\r
- SkuIdTable = GetSkuIdArray (Index, IsPeiDb);\r
- SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
- }\r
}\r
}\r
\r
{\r
INTN SizeTableIdx;\r
UINTN LocalTokenNumber;\r
- SKU_ID *SkuIdTable;\r
SIZE_INFO *SizeTable;\r
- UINTN Index;\r
BOOLEAN IsPeiDb;\r
UINT32 *LocalTokenNumberTable;\r
\r
//\r
return *MaxSize;\r
} else {\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
//\r
// We have only two entry for Non-Sku enabled PCD entry:\r
// 1) MAX SIZE\r
// 2) Current Size\r
//\r
return SizeTable[SizeTableIdx + 1];\r
- } else {\r
- //\r
- // We have these entry for SKU enabled PCD entry\r
- // 1) MAX SIZE\r
- // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
- //\r
- SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
- for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
- if (SkuIdTable[1 + Index] == mPcdDatabase.DxeDb->SystemSkuId) {\r
- return SizeTable[SizeTableIdx + 1 + Index];\r
- }\r
- }\r
- return SizeTable[SizeTableIdx + 1];\r
- }\r
}\r
}\r
\r
{\r
INTN SizeTableIdx;\r
UINTN LocalTokenNumber;\r
- SKU_ID *SkuIdTable;\r
SIZE_INFO *SizeTable;\r
- UINTN Index;\r
UINTN MaxSize;\r
BOOLEAN IsPeiDb;\r
UINT32 *LocalTokenNumberTable;\r
return FALSE;\r
} \r
\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
- //\r
- // We have only two entry for Non-Sku enabled PCD entry:\r
- // 1) MAX SIZE\r
- // 2) Current Size\r
- //\r
- SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
- return TRUE;\r
- } else {\r
- //\r
- // We have these entry for SKU enabled PCD entry\r
- // 1) MAX SIZE\r
- // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
- //\r
- SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
- for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
- if (SkuIdTable[1 + Index] == mPcdDatabase.DxeDb->SystemSkuId) {\r
- SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;\r
- return TRUE;\r
- }\r
- }\r
- SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
- return TRUE;\r
- }\r
+ //\r
+ // We have only two entry for Non-Sku enabled PCD entry:\r
+ // 1) MAX SIZE\r
+ // 2) Current Size\r
+ //\r
+ SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
+ return TRUE;\r
}\r
}\r
\r
// Please make sure the PCD Serivce DXE Version is consistent with\r
// the version of the generated DXE PCD Database by build tool.\r
//\r
-#define PCD_SERVICE_DXE_VERSION 6\r
+#define PCD_SERVICE_DXE_VERSION 7\r
\r
//\r
// PCD_DXE_SERVICE_DRIVER_VERSION is defined in Autogen.h.\r
IN UINTN GetSize\r
);\r
\r
-/**\r
- Find the local token number according to system SKU ID.\r
-\r
- @param LocalTokenNumber PCD token number\r
- @param Size The size of PCD entry.\r
- @param IsPeiDb If TRUE, the PCD entry is initialized in PEI phase.\r
- If False, the PCD entry is initialized in DXE phase.\r
-\r
- @return Token number according to system SKU ID.\r
-\r
-**/\r
-UINT32\r
-GetSkuEnabledTokenNumber (\r
- UINT32 LocalTokenNumber,\r
- UINTN Size,\r
- BOOLEAN IsPeiDb\r
- );\r
-\r
/**\r
Get Variable which contains HII type PCD entry.\r
\r
IN VOID *Context\r
);\r
\r
+/**\r
+ Update PCD database base on current SkuId\r
+\r
+ @param SkuId Current SkuId\r
+ @param IsPeiDb Whether to update PEI PCD database.\r
+\r
+ @retval EFI_SUCCESS Update PCD database successfully.\r
+ @retval EFI_NOT_FOUND Not found PCD database for current SkuId.\r
+**/\r
+EFI_STATUS\r
+UpdatePcdDatabase (\r
+ IN SKU_ID SkuId,\r
+ IN BOOLEAN IsPeiDb\r
+ );\r
+\r
extern PCD_DATABASE mPcdDatabase;\r
\r
extern UINT32 mPcdTotalTokenCount; \r
ASSERT_EFI_ERROR (Status);\r
}\r
\r
+/**\r
+ Report Pei PCD database of all SKUs as Guid HOB so that DxePcd can access it.\r
+\r
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
+ @param NotifyDescriptor Address of the notification descriptor data structure.\r
+ @param Ppi Address of the PPI that was installed.\r
+\r
+ @retval EFI_SUCCESS Successfully update the Boot records.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndOfPeiSignalPpiNotifyCallback (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ )\r
+{\r
+ PEI_PCD_DATABASE *Database;\r
+ EFI_BOOT_MODE BootMode;\r
+ EFI_STATUS Status;\r
+ UINTN Instance;\r
+ EFI_PEI_FV_HANDLE VolumeHandle;\r
+ EFI_PEI_FILE_HANDLE FileHandle;\r
+ VOID *PcdDb;\r
+ UINT32 Length;\r
+ PEI_PCD_DATABASE *PeiPcdDb;\r
+\r
+ Status = PeiServicesGetBootMode(&BootMode);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Don't need to report it on S3 boot.\r
+ //\r
+ if (BootMode == BOOT_ON_S3_RESUME) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ PeiPcdDb = GetPcdDatabase();\r
+ if (PeiPcdDb->SystemSkuId != (SKU_ID) 0) {\r
+ //\r
+ // SkuId has been set. Don't need to report it to DXE phase.\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Get full PCD database from PcdPeim FileHandle\r
+ //\r
+ Instance = 0;\r
+ FileHandle = NULL;\r
+ while (TRUE) {\r
+ //\r
+ // Traverse all firmware volume instances\r
+ //\r
+ Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);\r
+ //\r
+ // Error should not happen\r
+ //\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Find PcdDb file from the beginning in this firmware volume.\r
+ //\r
+ FileHandle = NULL;\r
+ Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Find PcdPeim FileHandle in this volume\r
+ //\r
+ break;\r
+ }\r
+ //\r
+ // We cannot find PcdPeim in this firmware volume, then search the next volume.\r
+ //\r
+ Instance++;\r
+ }\r
+\r
+ //\r
+ // Find PEI PcdDb and Build second PcdDB GuidHob\r
+ //\r
+ Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);\r
+ ASSERT_EFI_ERROR (Status);\r
+ Length = PeiPcdDb->LengthForAllSkus;\r
+ Database = BuildGuidHob (&gPcdDataBaseHobGuid, Length);\r
+ CopyMem (Database, PcdDb, Length);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[] = {\r
+ {\r
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEfiEndOfPeiSignalPpiGuid,\r
+ EndOfPeiSignalPpiNotifyCallback\r
+ }\r
+};\r
+\r
/**\r
Main entry for PCD PEIM driver.\r
\r
Status = PeiServicesInstallPpi (&mPpiList2[0]);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ Status = PeiServicesNotifyPpi (&mEndOfPeiSignalPpiNotifyList[0]);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
Status = PeiRegisterCallBackOnSet (\r
&gEfiMdeModulePkgTokenSpaceGuid,\r
PcdToken(PcdSetNvStoreDefaultId),\r
PEI_PCD_DATABASE *PeiPcdDb;\r
SKU_ID *SkuIdTable;\r
UINTN Index;\r
+ EFI_STATUS Status;\r
+ UINTN Instance;\r
+ EFI_PEI_FV_HANDLE VolumeHandle;\r
+ EFI_PEI_FILE_HANDLE FileHandle;\r
+ VOID *PcdDb;\r
+ UINT32 Length;\r
+ PCD_DATABASE_SKU_DELTA *SkuDelta;\r
+ PCD_DATA_DELTA *SkuDeltaData;\r
\r
PeiPcdDb = GetPcdDatabase();\r
\r
SkuIdTable = (SKU_ID *) ((UINT8 *) PeiPcdDb + PeiPcdDb->SkuIdTableOffset);\r
for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
if (SkuId == SkuIdTable[Index + 1]) {\r
- DEBUG ((EFI_D_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId));\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (Index < SkuIdTable[0]) {\r
+ //\r
+ // Get full PCD database from PcdPeim FileHandle\r
+ //\r
+ Instance = 0;\r
+ FileHandle = NULL;\r
+ while (TRUE) {\r
+ //\r
+ // Traverse all firmware volume instances\r
+ //\r
+ Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);\r
+ //\r
+ // Error should not happen\r
+ //\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Find PcdDb file from the beginning in this firmware volume.\r
+ //\r
+ FileHandle = NULL;\r
+ Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Find PcdPeim FileHandle in this volume\r
+ //\r
+ break;\r
+ }\r
+ //\r
+ // We cannot find PcdPeim in this firmware volume, then search the next volume.\r
+ //\r
+ Instance++;\r
+ }\r
+\r
+ //\r
+ // Find the delta data between the different Skus\r
+ //\r
+ Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);\r
+ ASSERT_EFI_ERROR (Status);\r
+ Length = PeiPcdDb->LengthForAllSkus;\r
+ Index = (PeiPcdDb->Length + 7) & (~7);\r
+ SkuDelta = NULL;\r
+ while (Index < Length) {\r
+ SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) PcdDb + Index);\r
+ if (SkuDelta->SkuId == SkuId && SkuDelta->SkuIdCompared == 0) {\r
+ break;\r
+ }\r
+ Index = (Index + SkuDelta->Length + 7) & (~7);\r
+ }\r
+\r
+ //\r
+ // Patch the delta data into current PCD database\r
+ //\r
+ if (Index < Length && SkuDelta != NULL) {\r
+ SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1);\r
+ while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) {\r
+ *((UINT8 *) PeiPcdDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value;\r
+ SkuDeltaData ++;\r
+ }\r
PeiPcdDb->SystemSkuId = (SKU_ID) SkuId;\r
+ DEBUG ((DEBUG_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId));\r
return;\r
}\r
}\r
// Invalid input SkuId, the default SKU Id will be still used for the system.\r
//\r
DEBUG ((EFI_D_INFO, "PcdPei - Invalid input SkuId, the default SKU Id will be still used.\n"));\r
+\r
return;\r
}\r
\r
{\r
INTN SizeTableIdx;\r
UINTN LocalTokenNumber;\r
- SKU_ID *SkuIdTable;\r
SIZE_INFO *SizeTable;\r
- UINTN Index;\r
\r
SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
\r
//\r
return *MaxSize;\r
} else {\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
- //\r
- // We have only two entry for Non-Sku enabled PCD entry:\r
- // 1) MAX SIZE\r
- // 2) Current Size\r
- //\r
- return SizeTable[SizeTableIdx + 1];\r
- } else {\r
- //\r
- // We have these entry for SKU enabled PCD entry\r
- // 1) MAX SIZE\r
- // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
- //\r
- SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);\r
- for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
- if (SkuIdTable[1 + Index] == Database->SystemSkuId) {\r
- return SizeTable[SizeTableIdx + 1 + Index];\r
- }\r
- }\r
- return SizeTable[SizeTableIdx + 1];\r
- }\r
+ //\r
+ // We have only two entry for Non-Sku enabled PCD entry:\r
+ // 1) MAX SIZE\r
+ // 2) Current Size\r
+ //\r
+ return SizeTable[SizeTableIdx + 1];\r
}\r
}\r
\r
{\r
INTN SizeTableIdx;\r
UINTN LocalTokenNumber;\r
- SKU_ID *SkuIdTable;\r
SIZE_INFO *SizeTable;\r
- UINTN Index;\r
UINTN MaxSize;\r
\r
SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
return FALSE;\r
}\r
\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
- //\r
- // We have only two entry for Non-Sku enabled PCD entry:\r
- // 1) MAX SIZE\r
- // 2) Current Size\r
- //\r
- SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
- return TRUE;\r
- } else {\r
- //\r
- // We have these entry for SKU enabled PCD entry\r
- // 1) MAX SIZE\r
- // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
- //\r
- SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);\r
- for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
- if (SkuIdTable[1 + Index] == Database->SystemSkuId) {\r
- SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;\r
- return TRUE;\r
- }\r
- }\r
- SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
- return TRUE;\r
- }\r
+ //\r
+ // We have only two entry for Non-Sku enabled PCD entry:\r
+ // 1) MAX SIZE\r
+ // 2) Current Size\r
+ //\r
+ SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
+ return TRUE;\r
}\r
\r
}\r
gEfiPeiPcdPpiGuid ## PRODUCES\r
gGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES\r
gEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES\r
+ gEfiEndOfPeiSignalPpiGuid ## NOTIFY\r
\r
[FeaturePcd]\r
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## CONSUMES\r
)\r
{\r
UINT32 LocalTokenNumber;\r
- UINTN Size;\r
- UINTN MaxSize;\r
\r
//\r
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
\r
LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);\r
\r
- Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
-\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
- if (Size == 0) {\r
- GetPtrTypeSize (TokenNumber, &MaxSize, Database);\r
- } else {\r
- MaxSize = Size;\r
- }\r
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
- }\r
-\r
return LocalTokenNumber;\r
}\r
\r
return EFI_NOT_FOUND;\r
}\r
\r
-/**\r
- Find the local token number according to system SKU ID.\r
-\r
- @param LocalTokenNumber PCD token number\r
- @param Size The size of PCD entry.\r
-\r
- @return Token number according to system SKU ID.\r
-\r
-**/\r
-UINT32\r
-GetSkuEnabledTokenNumber (\r
- UINT32 LocalTokenNumber,\r
- UINTN Size\r
- ) \r
-{\r
- PEI_PCD_DATABASE *PeiPcdDb;\r
- SKU_HEAD *SkuHead;\r
- SKU_ID *SkuIdTable;\r
- UINTN Index;\r
- UINT8 *Value;\r
- BOOLEAN FoundSku;\r
-\r
- PeiPcdDb = GetPcdDatabase ();\r
-\r
- ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
-\r
- SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
- Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));\r
- SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));\r
-\r
- //\r
- // Find the current system's SKU ID entry in SKU ID table.\r
- //\r
- FoundSku = FALSE;\r
- for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
- if (PeiPcdDb->SystemSkuId == SkuIdTable[Index + 1]) {\r
- FoundSku = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Find the default SKU ID entry in SKU ID table.\r
- //\r
- if(!FoundSku) {\r
- for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
- if (0 == SkuIdTable[Index + 1]) {\r
- break;\r
- }\r
- }\r
- }\r
- ASSERT (Index < SkuIdTable[0]);\r
-\r
- switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
- case PCD_TYPE_VPD:\r
- Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);\r
- return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);\r
-\r
- case PCD_TYPE_HII:\r
- Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);\r
- return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);\r
-\r
- case PCD_TYPE_HII|PCD_TYPE_STRING:\r
- Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);\r
- return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING);\r
-\r
- case PCD_TYPE_STRING:\r
- Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);\r
- return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);\r
-\r
- case PCD_TYPE_DATA:\r
- Value += Size * Index;\r
- return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_DATA);\r
-\r
- default:\r
- ASSERT (FALSE);\r
- }\r
-\r
- ASSERT (FALSE);\r
-\r
- return 0;\r
-}\r
-\r
/**\r
Invoke the callback function when dynamic PCD entry was set, if this PCD entry \r
has registered callback function.\r
return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
}\r
\r
-/**\r
- Get SKU ID table from PCD database.\r
-\r
- @param LocalTokenNumberTableIdx Index of local token number in token number table.\r
- @param Database PCD database.\r
-\r
- @return Pointer to SKU ID array table\r
-\r
-**/\r
-SKU_ID *\r
-GetSkuIdArray (\r
- IN UINTN LocalTokenNumberTableIdx,\r
- IN PEI_PCD_DATABASE *Database\r
- )\r
-{\r
- SKU_HEAD *SkuHead;\r
- UINTN LocalTokenNumber;\r
-\r
- LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
-\r
- ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
-\r
- SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
-\r
- return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);\r
- \r
-}\r
-\r
/**\r
Get index of PCD entry in size table.\r
\r
UINTN Index;\r
UINTN SizeTableIdx;\r
UINTN LocalTokenNumber;\r
- SKU_ID *SkuIdTable;\r
- \r
+\r
SizeTableIdx = 0;\r
\r
for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {\r
//\r
SizeTableIdx += 2;\r
} else {\r
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
//\r
// We have only two entry for Non-Sku enabled PCD entry:\r
// 1) MAX SIZE\r
// 2) Current Size\r
//\r
SizeTableIdx += 2;\r
- } else {\r
- //\r
- // We have these entry for SKU enabled PCD entry\r
- // 1) MAX SIZE\r
- // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
- //\r
- SkuIdTable = GetSkuIdArray (Index, Database);\r
- SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
- }\r
}\r
}\r
\r
IN UINTN ExTokenNumber\r
);\r
\r
-/**\r
- Find the local token number according to system SKU ID.\r
-\r
- @param LocalTokenNumber PCD token number\r
- @param Size The size of PCD entry.\r
-\r
- @return Token number according to system SKU ID.\r
-\r
-**/\r
-UINT32\r
-GetSkuEnabledTokenNumber (\r
- UINT32 LocalTokenNumber,\r
- UINTN Size\r
- );\r
-\r
/**\r
The function registers the CallBackOnSet fucntion\r
according to TokenNumber and EFI_GUID space.\r
IN EFI_PEI_FILE_HANDLE FileHandle\r
);\r
\r
-/**\r
- Get SKU ID tabble from PCD database.\r
-\r
- @param LocalTokenNumberTableIdx Index of local token number in token number table.\r
- @param Database PCD Database in PEI phase\r
-\r
- @return Pointer to SKU ID array table\r
-\r
-**/\r
-SKU_ID *\r
-GetSkuIdArray (\r
- IN UINTN LocalTokenNumberTableIdx,\r
- IN PEI_PCD_DATABASE *Database\r
- );\r
-\r
/**\r
Get index of PCD entry in size table.\r
\r