]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PCD/Dxe/Service.c
MdeModulePkg: Update PCD driver to support the optimized PcdDataBase
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Dxe / Service.c
index efe72483c5e65be554f7cfb99fb7ee10b1d57ec0..2745cf54d6becffe0af6a994b822707fe8769b2d 100644 (file)
@@ -37,6 +37,11 @@ LIST_ENTRY    *mCallbackFnTable;
 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
@@ -52,11 +57,7 @@ GetLocalTokenNumber (
   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
@@ -65,29 +66,11 @@ GetLocalTokenNumber (
   //\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
@@ -753,11 +736,8 @@ LocateExPcdBinary (
   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
@@ -765,20 +745,95 @@ LocateExPcdBinary (
   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
@@ -798,6 +853,7 @@ BuildPcdDxeDataBase (
   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
@@ -808,7 +864,6 @@ BuildPcdDxeDataBase (
   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
@@ -820,8 +875,17 @@ BuildPcdDxeDataBase (
     // 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
@@ -829,6 +893,10 @@ BuildPcdDxeDataBase (
     //\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
@@ -939,94 +1007,6 @@ GetHiiVariable (
   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
@@ -1640,41 +1620,6 @@ GetExPcdTokenNumber (
   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
@@ -1694,7 +1639,6 @@ GetSizeTableIndex (
   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
@@ -1721,22 +1665,12 @@ GetSizeTableIndex (
           //\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
@@ -1762,9 +1696,7 @@ GetPtrTypeSize (
 {\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
@@ -1803,27 +1735,12 @@ GetPtrTypeSize (
       //\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
@@ -1845,9 +1762,7 @@ SetPtrTypeSize (
 {\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
@@ -1892,30 +1807,13 @@ SetPtrTypeSize (
        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