+/**\r
+ Callback on SET PcdSetNvStoreDefaultId\r
+\r
+ Once PcdSetNvStoreDefaultId is set, the default NV storage will be found from\r
+ PcdNvStoreDefaultValueBuffer, and built into VariableHob.\r
+\r
+ @param[in] CallBackGuid The PCD token GUID being set.\r
+ @param[in] CallBackToken The PCD token number being set.\r
+ @param[in, out] TokenData A pointer to the token data being set.\r
+ @param[in] TokenDataSize The size, in bytes, of the data being set.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PcdSetNvStoreDefaultIdCallBack (\r
+ IN CONST EFI_GUID *CallBackGuid, OPTIONAL\r
+ IN UINTN CallBackToken,\r
+ IN OUT VOID *TokenData,\r
+ IN UINTN TokenDataSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT16 DefaultId;\r
+ SKU_ID SkuId;\r
+ UINTN FullSize;\r
+ UINTN Index;\r
+ UINT8 *DataBuffer;\r
+ UINT8 *VarStoreHobData;\r
+ UINT8 *BufferEnd;\r
+ BOOLEAN IsFound;\r
+ VARIABLE_STORE_HEADER *NvStoreBuffer;\r
+ PCD_DEFAULT_DATA *DataHeader;\r
+ PCD_DEFAULT_INFO *DefaultInfo;\r
+ PCD_DATA_DELTA *DeltaData;\r
+\r
+ DefaultId = *(UINT16 *) TokenData;\r
+ SkuId = GetPcdDatabase()->SystemSkuId;\r
+ IsFound = FALSE;\r
+\r
+ if (PeiPcdGetSizeEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvStoreDefaultValueBuffer)) > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {\r
+ DataBuffer = (UINT8 *) PeiPcdGetPtrEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvStoreDefaultValueBuffer));\r
+ FullSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *) DataBuffer)->Length;\r
+ DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));\r
+ //\r
+ // The first section data includes NV storage default setting.\r
+ //\r
+ NvStoreBuffer = (VARIABLE_STORE_HEADER *) ((UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);\r
+ VarStoreHobData = (UINT8 *) BuildGuidHob (&NvStoreBuffer->Signature, NvStoreBuffer->Size);\r
+ ASSERT (VarStoreHobData != NULL);\r
+ CopyMem (VarStoreHobData, NvStoreBuffer, NvStoreBuffer->Size);\r
+ //\r
+ // Find the matched SkuId and DefaultId in the first section\r
+ //\r
+ DefaultInfo = &(DataHeader->DefaultInfo[0]);\r
+ BufferEnd = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
+ while ((UINT8 *) DefaultInfo < BufferEnd) {\r
+ if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == SkuId) {\r
+ IsFound = TRUE;\r
+ break;\r
+ }\r
+ DefaultInfo ++;\r
+ }\r
+ //\r
+ // Find the matched SkuId and DefaultId in the remaining section\r
+ //\r
+ Index = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));\r
+ DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
+ while (!IsFound && Index < FullSize && DataHeader->DataSize != 0xFFFFFFFF) {\r
+ DefaultInfo = &(DataHeader->DefaultInfo[0]);\r
+ BufferEnd = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
+ while ((UINT8 *) DefaultInfo < BufferEnd) {\r
+ if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == SkuId) {\r
+ IsFound = TRUE;\r
+ break;\r
+ }\r
+ DefaultInfo ++;\r
+ }\r
+ if (IsFound) {\r
+ DeltaData = (PCD_DATA_DELTA *) BufferEnd;\r
+ BufferEnd = (UINT8 *) DataHeader + DataHeader->DataSize;\r
+ while ((UINT8 *) DeltaData < BufferEnd) {\r
+ *(VarStoreHobData + DeltaData->Offset) = (UINT8) DeltaData->Value;\r
+ DeltaData ++;\r
+ }\r
+ break;\r
+ }\r
+ Index = (Index + DataHeader->DataSize + 7) & (~7) ;\r
+ DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
+ }\r
+ }\r
+\r
+ Status = PcdUnRegisterCallBackOnSet (\r
+ &gEfiMdeModulePkgTokenSpaceGuid,\r
+ PcdToken(PcdSetNvStoreDefaultId),\r
+ PcdSetNvStoreDefaultIdCallBack\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r