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