diff --git a/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h index 9b1cb22bbb..d670af14e9 100644 --- a/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h +++ b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h @@ -61,11 +61,6 @@ typedef struct { UINT16 ExGuidIndex; // Index of GuidTable in units of GUID. } DYNAMICEX_MAPPING; -typedef struct { - UINT32 SkuDataStartOffset; // Offset(with DATUM TYPE info) from the PCD_DB. - UINT32 SkuIdTableOffset; // Offset from the PCD_DB. -} SKU_HEAD; - typedef struct { UINT32 StringIndex; // Offset in String Table in units of UINT8. UINT32 DefaultValueOffset; // Offset of the Default Value. @@ -94,8 +89,9 @@ typedef UINT32 TABLE_OFFSET; typedef struct { GUID Signature; // PcdDataBaseGuid. UINT32 BuildVersion; - UINT32 Length; + UINT32 Length; // Length of DEFAULT SKU PCD DB SKU_ID SystemSkuId; // Current SkuId value. + UINT32 LengthForAllSkus; // Length of all SKU PCD DB UINT32 UninitDataBaseSize; // Total size for PCD those default value with 0. TABLE_OFFSET LocalTokenNumberTableOffset; TABLE_OFFSET ExMapTableOffset; @@ -107,7 +103,7 @@ typedef struct { UINT16 LocalTokenCount; // LOCAL_TOKEN_NUMBER for all. UINT16 ExTokenCount; // EX_TOKEN_NUMBER for DynamicEx. UINT16 GuidTableCount; // The Number of Guid in GuidTable. - UINT8 Pad[2]; // Pad bytes to satisfy the alignment. + UINT8 Pad[6]; // Pad bytes to satisfy the alignment. // // Default initialized external PCD database binary structure @@ -115,7 +111,6 @@ typedef struct { // Padding is needed to keep necessary alignment // //SKU_ID SkuIdTable[]; // SkuIds system supports. - //SKU_ID SkuIndexTable[]; // SkuIds for each PCD with SKU enable. //UINT64 ValueUint64[]; //UINT32 ValueUint32[]; //VPD_HEAD VpdHead[]; // VPD Offset @@ -125,7 +120,6 @@ typedef struct { //STRING_HEAD StringHead[]; // String PCD //PCD_NAME_INDEX PcdNameTable[]; // PCD name index info. It can be accessed by the PcdNameTableOffset. //VARIABLE_HEAD VariableHead[]; // HII PCD - //SKU_HEAD SkuHead[]; // Store SKU info for each PCD with SKU enable. //UINT8 StringTable[]; // String for String PCD value and HII PCD Variable Name. It can be accessed by StringTableOffset. //SIZE_INFO SizeTable[]; // MaxSize and CurSize for String PCD. It can be accessed by SizeTableOffset. //UINT16 ValueUint16[]; @@ -216,4 +210,26 @@ typedef struct { // +-------------------------------------+ // +#pragma pack(1) +typedef struct { + SKU_ID SkuId; + SKU_ID SkuIdCompared; + UINT32 Length; + // PCD_DATA_DELTA DeltaData[] +} PCD_DATABASE_SKU_DELTA; + +// +// PCD database layout: +// +---------------------------------+ +// | PCD_DATABASE_INIT (DEFAULT SKU) | +// +---------------------------------+ +// | PCD_DATABASE_SKU_DELTA (SKU A) | +// +---------------------------------+ +// | PCD_DATABASE_SKU_DELTA (SKU B) | +// +---------------------------------+ +// | ...... | +// +---------------------------------+ +// +#pragma pack() + #endif diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c index 326644c531..ee53ae332b 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c @@ -269,8 +269,9 @@ DxePcdSetSku ( IN UINTN SkuId ) { - SKU_ID *SkuIdTable; - UINTN Index; + SKU_ID *SkuIdTable; + UINTN Index; + EFI_STATUS Status; if (SkuId == mPcdDatabase.DxeDb->SystemSkuId) { // @@ -294,16 +295,19 @@ DxePcdSetSku ( SkuIdTable = (SKU_ID *) ((UINT8 *) mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SkuIdTableOffset); for (Index = 0; Index < SkuIdTable[0]; Index++) { if (SkuId == SkuIdTable[Index + 1]) { - DEBUG ((EFI_D_INFO, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId)); - mPcdDatabase.DxeDb->SystemSkuId = (SKU_ID) SkuId; - return; + Status = UpdatePcdDatabase (SkuId, TRUE); + if (!EFI_ERROR (Status)) { + mPcdDatabase.DxeDb->SystemSkuId = (SKU_ID) SkuId; + DEBUG ((DEBUG_INFO, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId)); + return; + } } } // // Invalid input SkuId, the default SKU Id will be still used for the system. // - DEBUG ((EFI_D_INFO, "PcdDxe - Invalid input SkuId, the default SKU Id will be still used.\n")); + DEBUG ((DEBUG_INFO, "PcdDxe - Invalid input SkuId, the default SKU Id will be still used.\n")); return; } diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c index efe72483c5..2745cf54d6 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Service.c +++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c @@ -37,6 +37,11 @@ LIST_ENTRY *mCallbackFnTable; EFI_GUID **TmpTokenSpaceBuffer; UINTN TmpTokenSpaceBufferCount; +UINTN mPeiPcdDbSize = 0; +PEI_PCD_DATABASE *mPeiPcdDbBinary = NULL; +UINTN mDxePcdDbSize = 0; +DXE_PCD_DATABASE *mDxePcdDbBinary = NULL; + /** Get Local Token Number by Token Number. @@ -52,11 +57,7 @@ GetLocalTokenNumber ( IN UINTN TokenNumber ) { - UINTN TmpTokenNumber; UINT32 *LocalTokenNumberTable; - UINT32 LocalTokenNumber; - UINTN Size; - UINTN MaxSize; // // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. @@ -65,29 +66,11 @@ GetLocalTokenNumber ( // TokenNumber--; - // - // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber - // - TmpTokenNumber = TokenNumber; - LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset); TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount; - LocalTokenNumber = LocalTokenNumberTable[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 (TmpTokenNumber, &MaxSize); - } else { - MaxSize = Size; - } - LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb); - } - - return LocalTokenNumber; + return LocalTokenNumberTable[TokenNumber]; } /** @@ -753,11 +736,8 @@ LocateExPcdBinary ( VOID ) { - DXE_PCD_DATABASE *DxePcdDbBinary; - UINTN DxePcdDbSize; EFI_STATUS Status; - DxePcdDbBinary = NULL; // // Search the External Pcd database from one section of current FFS, // and read it to memory @@ -765,20 +745,95 @@ LocateExPcdBinary ( Status = GetSectionFromFfs ( EFI_SECTION_RAW, 0, - (VOID **) &DxePcdDbBinary, - &DxePcdDbSize + (VOID **) &mDxePcdDbBinary, + &mDxePcdDbSize ); ASSERT_EFI_ERROR (Status); // // Check the first bytes (Header Signature Guid) and build version. // - if (!CompareGuid ((VOID *)DxePcdDbBinary, &gPcdDataBaseSignatureGuid) || - (DxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) { + if (!CompareGuid ((VOID *)mDxePcdDbBinary, &gPcdDataBaseSignatureGuid) || + (mDxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) { ASSERT (FALSE); } - return DxePcdDbBinary; + return mDxePcdDbBinary; +} + +/** + Update PCD database base on current SkuId + + @param SkuId Current SkuId + @param IsPeiDb Whether to update PEI PCD database. + + @retval EFI_SUCCESS Update PCD database successfully. + @retval EFI_NOT_FOUND Not found PCD database for current SkuId. +**/ +EFI_STATUS +UpdatePcdDatabase ( + IN SKU_ID SkuId, + IN BOOLEAN IsPeiDb + ) +{ + UINTN Index; + PCD_DATABASE_SKU_DELTA *SkuDelta; + PCD_DATA_DELTA *SkuDeltaData; + + if (IsPeiDb && mPeiPcdDbBinary != NULL) { + // + // Find the delta data for PEI DB + // + Index = (mPcdDatabase.PeiDb->Length + 7) & (~7); + SkuDelta = NULL; + while (Index < mPeiPcdDbSize) { + SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) mPeiPcdDbBinary + Index); + if (SkuDelta->SkuId == (UINT16) SkuId && SkuDelta->SkuIdCompared == 0) { + break; + } + Index = (Index + SkuDelta->Length + 7) & (~7); + } + + // + // Patch the delta data into current PCD database + // + if (Index < mPeiPcdDbSize && SkuDelta != NULL) { + SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1); + while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) { + *((UINT8 *) mPcdDatabase.PeiDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value; + SkuDeltaData ++; + } + } else { + return EFI_NOT_FOUND; + } + } + + // + // Find the delta data for DXE DB + // + Index = (mPcdDatabase.DxeDb->Length + 7) & (~7); + SkuDelta = NULL; + while (Index < mDxePcdDbSize) { + SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) mDxePcdDbBinary + Index); + if (SkuDelta->SkuId == SkuId && SkuDelta->SkuIdCompared == 0) { + break; + } + Index = (Index + SkuDelta->Length + 7) & (~7); + } + + // + // Patch the delta data into current PCD database + // + if (Index < mDxePcdDbSize && SkuDelta != NULL) { + SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1); + while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) { + *((UINT8 *) mPcdDatabase.DxeDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value; + SkuDeltaData ++; + } + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; } /** @@ -798,6 +853,7 @@ BuildPcdDxeDataBase ( UINTN Index; UINT32 PcdDxeDbLen; VOID *PcdDxeDb; + EFI_STATUS Status; // // Assign PCD Entries with default value to PCD DATABASE @@ -808,7 +864,6 @@ BuildPcdDxeDataBase ( PcdDxeDb = AllocateZeroPool (PcdDxeDbLen); ASSERT (PcdDxeDb != NULL); CopyMem (PcdDxeDb, mPcdDatabase.DxeDb, mPcdDatabase.DxeDb->Length); - FreePool (mPcdDatabase.DxeDb); mPcdDatabase.DxeDb = PcdDxeDb; GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); @@ -820,8 +875,17 @@ BuildPcdDxeDataBase ( // be NULL. If it is NULL, we just copy over the DXE Default // Value to PCD Database. // - PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); + + // + // Get next one that stores full PEI data + // + GuidHob = GetNextGuidHob (&gPcdDataBaseHobGuid, GET_NEXT_HOB (GuidHob)); + if (GuidHob != NULL) { + mPeiPcdDbBinary = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); + mPeiPcdDbSize = (UINTN) GET_GUID_HOB_DATA_SIZE (GuidHob); + } + // // Assign PCD Entries refereneced in PEI phase to PCD DATABASE // @@ -829,6 +893,10 @@ BuildPcdDxeDataBase ( // // Inherit the SystemSkuId from PEI phase. // + if (mPcdDatabase.PeiDb->SystemSkuId != 0) { + Status = UpdatePcdDatabase (mPcdDatabase.PeiDb->SystemSkuId, FALSE); + ASSERT_EFI_ERROR (Status); + } mPcdDatabase.DxeDb->SystemSkuId = mPcdDatabase.PeiDb->SystemSkuId; } else { mPcdDatabase.PeiDb = AllocateZeroPool (sizeof (PEI_PCD_DATABASE)); @@ -939,94 +1007,6 @@ GetHiiVariable ( return Status; } -/** - Find the local token number according to system SKU ID. - - @param LocalTokenNumber PCD token number - @param Size The size of PCD entry. - @param IsPeiDb If TRUE, the PCD entry is initialized in PEI phase. - If False, the PCD entry is initialized in DXE phase. - - @return Token number according to system SKU ID. - -**/ -UINT32 -GetSkuEnabledTokenNumber ( - UINT32 LocalTokenNumber, - UINTN Size, - BOOLEAN IsPeiDb - ) -{ - SKU_HEAD *SkuHead; - SKU_ID *SkuIdTable; - UINTN Index; - UINT8 *Value; - UINT8 *PcdDb; - BOOLEAN FoundSku; - - ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0); - - PcdDb = IsPeiDb ? (UINT8 *) mPcdDatabase.PeiDb : (UINT8 *) mPcdDatabase.DxeDb; - - SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); - Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); - - SkuIdTable = (SKU_ID *)(PcdDb + SkuHead->SkuIdTableOffset); - // - // Find the current system's SKU ID entry in SKU ID table. - // - FoundSku = FALSE; - for (Index = 0; Index < SkuIdTable[0]; Index++) { - if (mPcdDatabase.DxeDb->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 - PcdDb) | PCD_TYPE_VPD); - - case PCD_TYPE_HII: - Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]); - return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII); - - case PCD_TYPE_HII|PCD_TYPE_STRING: - Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]); - return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING); - - case PCD_TYPE_STRING: - Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]); - return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING); - - case PCD_TYPE_DATA: - Value += Size * Index; - return (UINT32) ((Value - PcdDb) | 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. @@ -1640,41 +1620,6 @@ GetExPcdTokenNumber ( return 0; } -/** - Get SKU ID table from PCD database. - - @param LocalTokenNumberTableIdx Index of local token number in token number table. - @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase, - If FALSE, the pcd entry is initialized in DXE phase. - @return Pointer to SKU ID array table - -**/ -SKU_ID * -GetSkuIdArray ( - IN UINTN LocalTokenNumberTableIdx, - IN BOOLEAN IsPeiDb - ) -{ - SKU_HEAD *SkuHead; - UINTN LocalTokenNumber; - UINT8 *Database; - - if (IsPeiDb) { - LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx); - Database = (UINT8 *) mPcdDatabase.PeiDb; - } else { - LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx); - Database = (UINT8 *) mPcdDatabase.DxeDb; - } - - ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0); - - SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); - - return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset); - -} - /** Wrapper function of getting index of PCD entry in size table. @@ -1694,7 +1639,6 @@ GetSizeTableIndex ( UINTN LocalTokenNumber; UINTN Index; UINTN SizeTableIdx; - SKU_ID *SkuIdTable; if (IsPeiDb) { LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset); @@ -1721,22 +1665,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, IsPeiDb); - SizeTableIdx += (UINTN)*SkuIdTable + 1; - } } } @@ -1762,9 +1696,7 @@ GetPtrTypeSize ( { INTN SizeTableIdx; UINTN LocalTokenNumber; - SKU_ID *SkuIdTable; SIZE_INFO *SizeTable; - UINTN Index; BOOLEAN IsPeiDb; UINT32 *LocalTokenNumberTable; @@ -1803,27 +1735,12 @@ GetPtrTypeSize ( // return *MaxSize; } 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 // return SizeTable[SizeTableIdx + 1]; - } 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 (LocalTokenNumberTableIdx, IsPeiDb); - for (Index = 0; Index < SkuIdTable[0]; Index++) { - if (SkuIdTable[1 + Index] == mPcdDatabase.DxeDb->SystemSkuId) { - return SizeTable[SizeTableIdx + 1 + Index]; - } - } - return SizeTable[SizeTableIdx + 1]; - } } } @@ -1845,9 +1762,7 @@ SetPtrTypeSize ( { INTN SizeTableIdx; UINTN LocalTokenNumber; - SKU_ID *SkuIdTable; SIZE_INFO *SizeTable; - UINTN Index; UINTN MaxSize; BOOLEAN IsPeiDb; UINT32 *LocalTokenNumberTable; @@ -1892,30 +1807,13 @@ SetPtrTypeSize ( return FALSE; } - if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { - // - // We have only two entry for Non-Sku enabled PCD entry: - // 1) MAX SIZE - // 2) Current Size - // - SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; - return TRUE; - } 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 (LocalTokenNumberTableIdx, IsPeiDb); - for (Index = 0; Index < SkuIdTable[0]; Index++) { - if (SkuIdTable[1 + Index] == mPcdDatabase.DxeDb->SystemSkuId) { - SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize; - return TRUE; - } - } - SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; - return TRUE; - } + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; } } diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.h b/MdeModulePkg/Universal/PCD/Dxe/Service.h index 0257a3487c..cd0e227705 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Service.h +++ b/MdeModulePkg/Universal/PCD/Dxe/Service.h @@ -39,7 +39,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // Please make sure the PCD Serivce DXE Version is consistent with // the version of the generated DXE PCD Database by build tool. // -#define PCD_SERVICE_DXE_VERSION 6 +#define PCD_SERVICE_DXE_VERSION 7 // // PCD_DXE_SERVICE_DRIVER_VERSION is defined in Autogen.h. @@ -961,24 +961,6 @@ ExGetWorker ( IN UINTN GetSize ); -/** - Find the local token number according to system SKU ID. - - @param LocalTokenNumber PCD token number - @param Size The size of PCD entry. - @param IsPeiDb If TRUE, the PCD entry is initialized in PEI phase. - If False, the PCD entry is initialized in DXE phase. - - @return Token number according to system SKU ID. - -**/ -UINT32 -GetSkuEnabledTokenNumber ( - UINT32 LocalTokenNumber, - UINTN Size, - BOOLEAN IsPeiDb - ); - /** Get Variable which contains HII type PCD entry. @@ -1177,6 +1159,21 @@ VariableLockCallBack ( IN VOID *Context ); +/** + Update PCD database base on current SkuId + + @param SkuId Current SkuId + @param IsPeiDb Whether to update PEI PCD database. + + @retval EFI_SUCCESS Update PCD database successfully. + @retval EFI_NOT_FOUND Not found PCD database for current SkuId. +**/ +EFI_STATUS +UpdatePcdDatabase ( + IN SKU_ID SkuId, + IN BOOLEAN IsPeiDb + ); + extern PCD_DATABASE mPcdDatabase; extern UINT32 mPcdTotalTokenCount; diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.c b/MdeModulePkg/Universal/PCD/Pei/Pcd.c index 91eb9d6ccf..f8213953fa 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Pcd.c +++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.c @@ -228,6 +228,103 @@ PcdSetNvStoreDefaultIdCallBack ( ASSERT_EFI_ERROR (Status); } +/** + Report Pei PCD database of all SKUs as Guid HOB so that DxePcd can access it. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS Successfully update the Boot records. +**/ +EFI_STATUS +EFIAPI +EndOfPeiSignalPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + PEI_PCD_DATABASE *Database; + EFI_BOOT_MODE BootMode; + EFI_STATUS Status; + UINTN Instance; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *PcdDb; + UINT32 Length; + PEI_PCD_DATABASE *PeiPcdDb; + + Status = PeiServicesGetBootMode(&BootMode); + ASSERT_EFI_ERROR (Status); + + // + // Don't need to report it on S3 boot. + // + if (BootMode == BOOT_ON_S3_RESUME) { + return EFI_SUCCESS; + } + + PeiPcdDb = GetPcdDatabase(); + if (PeiPcdDb->SystemSkuId != (SKU_ID) 0) { + // + // SkuId has been set. Don't need to report it to DXE phase. + // + return EFI_SUCCESS; + } + + // + // Get full PCD database from PcdPeim FileHandle + // + Instance = 0; + FileHandle = NULL; + while (TRUE) { + // + // Traverse all firmware volume instances + // + Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); + // + // Error should not happen + // + ASSERT_EFI_ERROR (Status); + + // + // Find PcdDb file from the beginning in this firmware volume. + // + FileHandle = NULL; + Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle); + if (!EFI_ERROR (Status)) { + // + // Find PcdPeim FileHandle in this volume + // + break; + } + // + // We cannot find PcdPeim in this firmware volume, then search the next volume. + // + Instance++; + } + + // + // Find PEI PcdDb and Build second PcdDB GuidHob + // + Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb); + ASSERT_EFI_ERROR (Status); + Length = PeiPcdDb->LengthForAllSkus; + Database = BuildGuidHob (&gPcdDataBaseHobGuid, Length); + CopyMem (Database, PcdDb, Length); + + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + EndOfPeiSignalPpiNotifyCallback + } +}; + /** Main entry for PCD PEIM driver. @@ -262,6 +359,9 @@ PcdPeimInit ( Status = PeiServicesInstallPpi (&mPpiList2[0]); ASSERT_EFI_ERROR (Status); + Status = PeiServicesNotifyPpi (&mEndOfPeiSignalPpiNotifyList[0]); + ASSERT_EFI_ERROR (Status); + Status = PeiRegisterCallBackOnSet ( &gEfiMdeModulePkgTokenSpaceGuid, PcdToken(PcdSetNvStoreDefaultId), @@ -366,6 +466,14 @@ PeiPcdSetSku ( PEI_PCD_DATABASE *PeiPcdDb; SKU_ID *SkuIdTable; UINTN Index; + EFI_STATUS Status; + UINTN Instance; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *PcdDb; + UINT32 Length; + PCD_DATABASE_SKU_DELTA *SkuDelta; + PCD_DATA_DELTA *SkuDeltaData; PeiPcdDb = GetPcdDatabase(); @@ -391,8 +499,70 @@ PeiPcdSetSku ( SkuIdTable = (SKU_ID *) ((UINT8 *) PeiPcdDb + PeiPcdDb->SkuIdTableOffset); for (Index = 0; Index < SkuIdTable[0]; Index++) { if (SkuId == SkuIdTable[Index + 1]) { - DEBUG ((EFI_D_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId)); + break; + } + } + + if (Index < SkuIdTable[0]) { + // + // Get full PCD database from PcdPeim FileHandle + // + Instance = 0; + FileHandle = NULL; + while (TRUE) { + // + // Traverse all firmware volume instances + // + Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); + // + // Error should not happen + // + ASSERT_EFI_ERROR (Status); + + // + // Find PcdDb file from the beginning in this firmware volume. + // + FileHandle = NULL; + Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle); + if (!EFI_ERROR (Status)) { + // + // Find PcdPeim FileHandle in this volume + // + break; + } + // + // We cannot find PcdPeim in this firmware volume, then search the next volume. + // + Instance++; + } + + // + // Find the delta data between the different Skus + // + Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb); + ASSERT_EFI_ERROR (Status); + Length = PeiPcdDb->LengthForAllSkus; + Index = (PeiPcdDb->Length + 7) & (~7); + SkuDelta = NULL; + while (Index < Length) { + SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) PcdDb + Index); + if (SkuDelta->SkuId == SkuId && SkuDelta->SkuIdCompared == 0) { + break; + } + Index = (Index + SkuDelta->Length + 7) & (~7); + } + + // + // Patch the delta data into current PCD database + // + if (Index < Length && SkuDelta != NULL) { + SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1); + while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) { + *((UINT8 *) PeiPcdDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value; + SkuDeltaData ++; + } PeiPcdDb->SystemSkuId = (SKU_ID) SkuId; + DEBUG ((DEBUG_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId)); return; } } @@ -401,6 +571,7 @@ PeiPcdSetSku ( // Invalid input SkuId, the default SKU Id will be still used for the system. // DEBUG ((EFI_D_INFO, "PcdPei - Invalid input SkuId, the default SKU Id will be still used.\n")); + return; } @@ -1406,9 +1577,7 @@ GetPtrTypeSize ( { INTN SizeTableIdx; UINTN LocalTokenNumber; - SKU_ID *SkuIdTable; SIZE_INFO *SizeTable; - UINTN Index; SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database); @@ -1432,27 +1601,12 @@ GetPtrTypeSize ( // return *MaxSize; } 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 - // - return SizeTable[SizeTableIdx + 1]; - } 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 (LocalTokenNumberTableIdx, Database); - for (Index = 0; Index < SkuIdTable[0]; Index++) { - if (SkuIdTable[1 + Index] == Database->SystemSkuId) { - return SizeTable[SizeTableIdx + 1 + Index]; - } - } - return SizeTable[SizeTableIdx + 1]; - } + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + return SizeTable[SizeTableIdx + 1]; } } @@ -1479,9 +1633,7 @@ SetPtrTypeSize ( { INTN SizeTableIdx; UINTN LocalTokenNumber; - SKU_ID *SkuIdTable; SIZE_INFO *SizeTable; - UINTN Index; UINTN MaxSize; SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database); @@ -1510,30 +1662,13 @@ SetPtrTypeSize ( return FALSE; } - if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { - // - // We have only two entry for Non-Sku enabled PCD entry: - // 1) MAX SIZE - // 2) Current Size - // - SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; - return TRUE; - } 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 (LocalTokenNumberTableIdx, Database); - for (Index = 0; Index < SkuIdTable[0]; Index++) { - if (SkuIdTable[1 + Index] == Database->SystemSkuId) { - SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize; - return TRUE; - } - } - SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; - return TRUE; - } + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; } } diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf index 8f778e1927..e1ea5be17f 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf +++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf @@ -338,6 +338,7 @@ gEfiPeiPcdPpiGuid ## PRODUCES gGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES gEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES + gEfiEndOfPeiSignalPpiGuid ## NOTIFY [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## CONSUMES diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.c b/MdeModulePkg/Universal/PCD/Pei/Service.c index 5e1cb72ba5..e8a0b6ca10 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Service.c +++ b/MdeModulePkg/Universal/PCD/Pei/Service.c @@ -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; - } } } diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.h b/MdeModulePkg/Universal/PCD/Pei/Service.h index e3b68aabc4..3a7910a900 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Service.h +++ b/MdeModulePkg/Universal/PCD/Pei/Service.h @@ -993,21 +993,6 @@ GetExPcdTokenNumber ( IN UINTN ExTokenNumber ); -/** - 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 - ); - /** The function registers the CallBackOnSet fucntion according to TokenNumber and EFI_GUID space. @@ -1043,21 +1028,6 @@ BuildPcdDatabase ( IN EFI_PEI_FILE_HANDLE FileHandle ); -/** - Get SKU ID tabble from PCD database. - - @param LocalTokenNumberTableIdx Index of local token number in token number table. - @param Database PCD Database in PEI phase - - @return Pointer to SKU ID array table - -**/ -SKU_ID * -GetSkuIdArray ( - IN UINTN LocalTokenNumberTableIdx, - IN PEI_PCD_DATABASE *Database - ); - /** Get index of PCD entry in size table.