]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PCD/Pei/Pcd.c
MdeModulePkg PCD: Enable Firmware to retrieve the default setting
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Pei / Pcd.c
index a3f7337ceca3b6665f8563d2a2b83c418eff10a0..91eb9d6ccf4c67d319d71d71313ce3eb3e63a4ab 100644 (file)
@@ -129,6 +129,105 @@ EFI_PEI_PPI_DESCRIPTOR  mPpiList2[] = {
   }\r
 };\r
 \r
+/**\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
 /**\r
   Main entry for PCD PEIM driver.\r
   \r
@@ -163,6 +262,13 @@ PcdPeimInit (
   Status = PeiServicesInstallPpi (&mPpiList2[0]);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  Status = PeiRegisterCallBackOnSet (\r
+             &gEfiMdeModulePkgTokenSpaceGuid,\r
+             PcdToken(PcdSetNvStoreDefaultId),\r
+             PcdSetNvStoreDefaultIdCallBack\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   return Status;\r
 }\r
 \r