]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Universal/PCD/Pei/Service.c
Check in the Pcd service Driver/PEIM according to the new way of generating PCD Database
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Pei / Service.c
index 38293252bc52b4be65e30c5ba28bb041fb6acf88..052ff9e91f56dc9975a256e82e2807ff0b49c229 100644 (file)
@@ -14,799 +14,560 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 Module Name: Service.c\r
 \r
 **/\r
-#include "../Common/PcdCommon.h"\r
 #include "Service.h"\r
 \r
 \r
+//\r
+// Build Tool will generate PEI_PCD_DB_INIT_VALUE in Autogen.h\r
+//\r
+/* PEI_PCD_DATABASE_INIT\r
+gPEIPcdDbInit = {\r
+  PEI_PCD_DB_INIT_VALUE\r
+};\r
+*/\r
 \r
 \r
-/**\r
-  This function expand the StateByte\r
-\r
-  @param[out]   StateByte The output StateByte information.\r
-  @param[in]    Byte The StateByte.\r
-\r
-  @retval       VOID\r
---*/\r
-VOID\r
-PcdImageExpandStateByte (\r
-  OUT PCD_STATEBYTE *StateByte,\r
-  IN  UINT8          Byte\r
-)\r
-{\r
-  switch (Byte & PCD_STATEBYTE_DATUMTYPE) {\r
-    case PCD_BYTE8:\r
-      StateByte->DataType = PcdByte8;\r
-      break;\r
-    case PCD_BYTE16:\r
-      StateByte->DataType = PcdByte16;\r
-      break;\r
-    case PCD_BYTE32:\r
-      StateByte->DataType = PcdByte32;\r
-      break;\r
-    case PCD_BYTE64:\r
-      StateByte->DataType = PcdByte64;\r
-      break;\r
-    case PCD_POINTER:\r
-      StateByte->DataType = PcdPointer;\r
-      break;\r
-    case PCD_BOOLEAN:\r
-      StateByte->DataType = PcdBoolean;\r
-      break;\r
-    default:\r
-      ASSERT (FALSE);\r
-  }\r
-\r
-  StateByte->ExtendedGuidPresent = (BOOLEAN) ((Byte & PCD_STATEBYTE_EXTENDEDGUIDPRESENT) != 0);\r
-  StateByte->HiiEnable           = (BOOLEAN) ((Byte & PCD_STATEBYTE_HIIENABLE)           != 0);\r
-  StateByte->SkuDataArrayEnable  = (BOOLEAN) ((Byte & PCD_STATEBYTE_SKUDATAARRAYENABLE)  != 0);\r
-  StateByte->SkuEnable           = (BOOLEAN) ((Byte & PCD_STATEBYTE_SKUENABLE)           != 0);\r
-  StateByte->VpdEnable           = (BOOLEAN) ((Byte & PCD_STATEBYTE_VPDENABLE)           != 0);\r
-\r
-}\r
-\r
 \r
 \r
 /**\r
-  This function locates the <PCD_IMAGE> on the flash and \r
-  return a pointer to the Section Data on flash.\r
+  The function registers the CallBackOnSet fucntion\r
+  according to TokenNumber and EFI_GUID space.\r
 \r
-  @param[in]  VOID\r
+  @param[in]  TokenNumber       The token number.\r
+  @param[in]  Guid              The GUID space.\r
+  @param[in]  CallBackFunction  The Callback function to be registered.\r
 \r
-  @retval     VOID\r
+  @retval EFI_SUCCESS If the Callback function is registered.\r
+  @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
 --*/\r
-UINT8 *\r
-LocatePcdImage (\r
-  VOID\r
+EFI_STATUS\r
+PeiRegisterCallBackWorker (\r
+  IN  UINTN                       ExTokenNumber,\r
+  IN  CONST EFI_GUID              *Guid, OPTIONAL\r
+  IN  PCD_PPI_CALLBACK            CallBackFunction,\r
+  IN  BOOLEAN                     Register\r
 )\r
 {\r
-  EFI_STATUS                 Status;\r
-  EFI_FIRMWARE_VOLUME_HEADER *FvHdr;\r
-  EFI_FFS_FILE_HEADER        *FfsHdr;\r
-  VOID                       *SectionData;\r
-\r
-  Status = PeiCoreFfsFindNextVolume (0, &FvHdr);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  do {\r
-    FfsHdr = NULL;\r
-    Status = PeiCoreFfsFindNextFile (EFI_FV_FILETYPE_FREEFORM, FvHdr, &FfsHdr);\r
-    if (Status == EFI_SUCCESS) {\r
-      if (CompareGuid (&gPcdImageFileGuid, &FfsHdr->Name)) {\r
-\r
-        Status = PeiCoreFfsFindSectionData (EFI_SECTION_RAW, FfsHdr, &SectionData);\r
-        ASSERT_EFI_ERROR (Status);\r
-\r
-        return (UINT8 *)SectionData;\r
-      }\r
-    }\r
-  } while (Status == EFI_SUCCESS);\r
-\r
-  ASSERT (FALSE);\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  The function retrieves the PCD data value according to\r
-  TokenNumber and Guid space given.\r
-\r
-  @param[in]  TokenNumber The token number.\r
-  @param[in]  Guid The Guid space.\r
-  @param[in]  Type The storage type.\r
-  @param[out] Data The output data.\r
-\r
-\r
-  @retval EFI_SUCESS    If data value is found according to SKU_ID.\r
-  @retval EFI_NOT_FOUND If not such a value is found.\r
+  EFI_HOB_GUID_TYPE       *GuidHob;\r
+  PCD_PPI_CALLBACK        *CallbackTable;\r
+  PCD_PPI_CALLBACK        Compare;\r
+  PCD_PPI_CALLBACK        Assign;\r
+  UINT32                  LocalTokenNumber;\r
+  UINTN                   TokenNumber;\r
+  UINTN                   Idx;\r
+  EX_PCD_ENTRY_ATTRIBUTE  Attr;\r
 \r
---*/\r
-VOID\r
-PeiGetPcdEntryWorker (\r
-  IN UINTN TokenNumber,\r
-  IN CONST EFI_GUID       *Guid,  OPTIONAL\r
-  IN PCD_DATA_TYPE        Type,\r
-  OUT VOID                *Data\r
-  )\r
-{\r
-  PCD_DATABASE *Database;\r
-  EFI_HOB_GUID_TYPE *GuidHob;\r
+  if (Guid == NULL) {\r
+    TokenNumber = ExTokenNumber;\r
+    ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);\r
+    LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];\r
+  } else {\r
+    GetExPcdTokenAttributes (Guid, ExTokenNumber, &Attr);\r
+    TokenNumber = Attr.TokenNumber;\r
+    LocalTokenNumber = Attr.LocalTokenNumberAlias;\r
+  }\r
 \r
-  ASSERT (Data != NULL);\r
+  ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);\r
+  ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);\r
 \r
-  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
+  GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
   ASSERT (GuidHob != NULL);\r
+  \r
+  CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
 \r
-  Database = GET_GUID_HOB_DATA (GuidHob);\r
+  Compare = Register? NULL: CallBackFunction;\r
+  Assign  = Register? CallBackFunction: NULL;\r
 \r
-  GetPcdEntryWorker ( &Database->Info,\r
-                      TokenNumber,\r
-                      Guid,\r
-                      Type,\r
-                      Data\r
-                      );\r
+  for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
+    if (CallbackTable[Idx] == Compare) {\r
+      CallbackTable[Idx] = Assign;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
 \r
+  return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;\r
 \r
-  return;\r
 }\r
 \r
 \r
-/**\r
-  The function set the PCD data value according to\r
-  TokenNumber and Guid space given.\r
 \r
-  @param[in] Database     The PCD Database Instance.\r
-  @param[in] TokenNumber  The token number.\r
-  @param[in] Guid         The Guid space.\r
-  @param[in] Type         The storage type.\r
-  @param[in] Data         The output data.\r
 \r
+/**\r
+  The function builds the PCD database based on the\r
+  PCD_IMAGE on the flash.\r
 \r
-  @retval EFI_SUCESS      If data value is found according to SKU_ID.\r
-  @retval EFI_NOT_FOUND   If not such a value is found.\r
+  @param[in] PcdImageOnFlash  The PCD image on flash.\r
 \r
+  @retval VOID\r
 --*/\r
-EFI_STATUS\r
-SetPcdEntryWorker (\r
-  IN CONST PCD_DATABASE     *Database,\r
-  IN UINTN                  TokenNumber,\r
-  IN CONST EFI_GUID         *Guid,  OPTIONAL\r
-  IN PCD_DATA_TYPE          Type,\r
-  IN VOID                   *Data\r
+VOID\r
+BuildPcdDatabase (\r
+  VOID\r
   )\r
 {\r
-  PCD_INDEX               *PcdIndex;\r
-  EFI_STATUS              Status;\r
-  PCD_PPI_CALLBACK        *CallbackTable;\r
-  UINTN                   Idx;\r
-\r
-  ASSERT (Data != NULL);\r
-\r
-  //\r
-  // Find the PCD entry in list in memory first\r
-  //\r
-  PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, &Idx);\r
-\r
-  ASSERT (PcdIndex != NULL);\r
+  PEI_PCD_DATABASE  *Database;\r
+  VOID              *CallbackFnTable;\r
+  UINTN             SizeOfCallbackFnTable;\r
+  \r
+  Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));\r
 \r
-  ASSERT (PcdIndex->StateByte.DataType == Type);\r
+  ZeroMem (Database, sizeof (PEI_PCD_DATABASE));\r
 \r
   //\r
-  // Invoke the callback function.\r
+  // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE\r
   //\r
-  CallbackTable = (PCD_PPI_CALLBACK *)\r
-                              GetAbsoluteAddress (Idx * Database->Info.MaxCallbackNum * sizeof(PCD_PPI_CALLBACK),\r
-                              Database->Info.CallbackTableOffset,\r
-                              &Database->Info\r
-                              );\r
   \r
-  for (Idx = 0; Idx < Database->Info.MaxCallbackNum; Idx++) {\r
-    if (CallbackTable[Idx] != NULL) {\r
-      CallbackTable[Idx] (Guid,\r
-                          PcdIndex->TokenNumber,\r
-                          Data,\r
-                          PcdIndex->DatumSize\r
-                          );\r
-    }\r
-  }\r
+  CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));\r
 \r
-  Status = SetPcdData (PcdIndex, &Database->Info, Data);\r
+  SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
 \r
-  return Status;\r
+  CallbackFnTable = BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid, SizeOfCallbackFnTable);\r
+  \r
+  ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
+  \r
+  return;\r
 }\r
 \r
 \r
 \r
 /**\r
-  (reviewed) The function set the PCD data value according to\r
-  TokenNumber and Guid space given.\r
-\r
-  @param[in] TokenNumber  The token number.\r
-  @param[in] Guid         The Guid space.\r
-  @param[in] Type         The storage type.\r
-  @param[in] Data         The output data.\r
-\r
+  The function is provided by PCD PEIM and PCD DXE driver to\r
+  do the work of reading a HII variable from variable service.\r
 \r
-  @retval EFI_SUCESS    If data value is found according to SKU_ID.\r
-  @retval EFI_NOT_FOUND If not such a value is found.\r
+  @param[in] VariableGuid     The Variable GUID.\r
+  @param[in] VariableName     The Variable Name.\r
+  @param[out] VariableData    The output data.\r
+  @param[out] VariableSize    The size of the variable.\r
 \r
+  @retval EFI_SUCCESS         Operation successful.\r
+  @retval EFI_SUCCESS         Variablel not found.\r
 --*/\r
 EFI_STATUS\r
-PeiSetPcdEntryWorker (\r
-  IN UINTN TokenNumber,\r
-  IN CONST EFI_GUID       *Guid,  OPTIONAL\r
-  IN PCD_DATA_TYPE        Type,\r
-  IN VOID                 *Data\r
+GetHiiVariable (\r
+  IN  CONST EFI_GUID      *VariableGuid,\r
+  IN  UINT16              *VariableName,\r
+  OUT VOID                **VariableData,\r
+  OUT UINTN               *VariableSize\r
   )\r
 {\r
-  PCD_DATABASE *Database;\r
-  EFI_HOB_GUID_TYPE *GuidHob;\r
+  UINTN      Size;\r
+  EFI_STATUS Status;\r
+  VOID       *Buffer;\r
+  EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;\r
 \r
-  ASSERT (Data != NULL);\r
+  Status = PeiCoreLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, &VariablePpi);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
-  ASSERT (GuidHob != NULL);\r
-  \r
-  Database = GET_GUID_HOB_DATA (GuidHob);\r
+  Size = 0;\r
 \r
-  SetPcdEntryWorker (Database,\r
-                     TokenNumber,\r
-                     Guid,\r
-                     Type,\r
-                     Data\r
-                     );\r
+  Status = VariablePpi->PeiGetVariable (\r
+                          GetPeiServicesTablePointer (),\r
+                          VariableName,\r
+                          (EFI_GUID *) VariableGuid,\r
+                          NULL,\r
+                          &Size,\r
+                          NULL\r
+                            );\r
+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
+\r
+  Status = PeiCoreAllocatePool (Size, &Buffer);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  // declare a local for STP.\r
+  //\r
+  Status = VariablePpi->PeiGetVariable (\r
+                            GetPeiServicesTablePointer (),\r
+                            (UINT16 *) VariableName,\r
+                            (EFI_GUID *) VariableGuid,\r
+                            NULL,\r
+                            &Size,\r
+                            Buffer\r
+                            );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  *VariableSize = Size;\r
+  *VariableData = Buffer;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
 \r
-\r
-UINTN\r
-PeiGetPcdEntrySizeWorker (\r
-  IN UINTN                TokenNumber,\r
-  IN CONST EFI_GUID       *Guid  OPTIONAL\r
-  )\r
+UINT32\r
+GetSkuEnabledTokenNumber (\r
+  UINT32 LocalTokenNumber,\r
+  UINTN  Size\r
+  ) \r
 {\r
-  PCD_DATABASE      *Database;\r
-  EFI_HOB_GUID_TYPE *GuidHob;\r
-\r
-  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
-  ASSERT (GuidHob != NULL);\r
+  PEI_PCD_DATABASE      *PeiPcdDb;\r
+  SKU_HEAD              *SkuHead;\r
+  SKU_ID                *SkuIdTable;\r
+  INTN                  i;\r
+  UINT8                 *Value;\r
+\r
+  PeiPcdDb = GetPcdDatabase ();\r
+\r
+  ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
+\r
+  SkuHead     = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
+  Value       = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));\r
+  SkuIdTable  = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));\r
+        \r
+  for (i = 0; i < SkuIdTable[0]; i++) {\r
+    if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) {\r
+      break;\r
+    }\r
+  }\r
 \r
-  Database = GET_GUID_HOB_DATA (GuidHob);\r
+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {\r
+    case PCD_TYPE_VPD:\r
+      Value += sizeof(VPD_HEAD) * i;\r
+      return ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);\r
+\r
+    case PCD_TYPE_HII:\r
+      Value += sizeof(VARIABLE_HEAD) * i;\r
+      return ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);\r
+      \r
+    case 0: //Change to a MACRO PCD_TYPE_DATA\r
+      Value += Size * i;\r
+      return (Value - (UINT8 *) PeiPcdDb);\r
+      \r
+    default:\r
+      ASSERT (FALSE);\r
+  }\r
 \r
-  return GetPcdEntrySizeWorker (&Database->Info,\r
-                                TokenNumber,\r
-                                Guid\r
-                                );\r
+  ASSERT (FALSE);\r
 \r
+  return 0;\r
+  \r
 }\r
 \r
 \r
 \r
-/**\r
-  The function registers the CallBackOnSet fucntion\r
-  according to TokenNumber and EFI_GUID space.\r
-\r
-  @param[in]  TokenNumber       The token number.\r
-  @param[in]  Guid              The GUID space.\r
-  @param[in]  CallBackFunction  The Callback function to be registered.\r
 \r
-  @retval EFI_SUCCESS If the Callback function is registered.\r
-  @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
---*/\r
-EFI_STATUS\r
-PeiRegisterCallBackWorker (\r
-  IN  UINTN                       TokenNumber,\r
-  IN  CONST EFI_GUID              *Guid, OPTIONAL\r
-  IN  PCD_PPI_CALLBACK            CallBackFunction,\r
-  IN  BOOLEAN                     Register\r
-)\r
+VOID\r
+InvokeCallbackOnSet (\r
+  UINT32            ExTokenNumber,\r
+  CONST EFI_GUID    *Guid, OPTIONAL\r
+  UINTN             TokenNumber,\r
+  VOID              *Data,\r
+  UINTN             Size\r
+  )\r
 {\r
-  PCD_DATABASE        *Database;\r
   EFI_HOB_GUID_TYPE   *GuidHob;\r
-  PCD_INDEX           *PcdIndex;\r
-  UINTN               Idx;\r
   PCD_PPI_CALLBACK    *CallbackTable;\r
-  PCD_PPI_CALLBACK    Compare;\r
-  PCD_PPI_CALLBACK    Assign;\r
+  UINTN               Idx;\r
 \r
-  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
+  if (Guid == NULL)\r
+    ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);\r
+\r
+  GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
   ASSERT (GuidHob != NULL);\r
   \r
-  Database = GET_GUID_HOB_DATA (GuidHob);\r
-\r
-  PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, NULL);\r
-\r
-  ASSERT (PcdIndex != NULL);\r
-\r
-  if (PcdIndex->StateByte.VpdEnable) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+  CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
 \r
-  Idx = ((UINTN) PcdIndex - Database->Info.CallbackTableOffset) / sizeof(PCD_INDEX);\r
+  CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
 \r
-  CallbackTable = (PCD_PPI_CALLBACK *) GetAbsoluteAddress (\r
-                                              sizeof (PCD_PPI_CALLBACK) * Idx * Database->Info.MaxCallbackNum,\r
-                                              Database->Info.CallbackTableOffset,\r
-                                              &Database->Info\r
-                                              );\r
-\r
-  Compare = Register? NULL: CallBackFunction;\r
-  Assign  = Register? CallBackFunction: NULL;\r
-\r
-  for (Idx = 0; Idx < Database->Info.MaxCallbackNum; Idx++) {\r
-    if (CallbackTable[Idx] == Compare) {\r
-      CallbackTable[Idx] = Assign;\r
-      return EFI_SUCCESS;\r
+  for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
+    if (CallbackTable[Idx] != NULL) {\r
+      CallbackTable[Idx] (Guid,\r
+                          (Guid == NULL)? TokenNumber: ExTokenNumber,\r
+                          Data,\r
+                          Size\r
+                          );\r
     }\r
   }\r
-\r
-  return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;\r
-\r
+  \r
 }\r
 \r
-\r
-\r
 EFI_STATUS\r
-PeiGetNextTokenWorker (\r
-  IN OUT UINTN                *TokenNumber,\r
-  IN CONST EFI_GUID           *Guid     OPTIONAL\r
+SetWorker (\r
+  UINTN         TokenNumber,\r
+  VOID          *Data,\r
+  UINTN         Size,\r
+  BOOLEAN       PtrType\r
   )\r
 {\r
-  PCD_DATABASE        *Database;\r
-  EFI_HOB_GUID_TYPE   *GuidHob;\r
-\r
-  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
-  ASSERT (GuidHob != NULL);\r
-  \r
-  Database = GET_GUID_HOB_DATA (GuidHob);\r
-\r
-  return GetNextTokenWorker (&Database->Info,\r
-                             TokenNumber,\r
-                             Guid\r
-                             );\r
-\r
-}\r
+  UINT32              LocalTokenNumber;\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
 \r
+  ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);\r
+    \r
+  PeiPcdDb = GetPcdDatabase ();\r
 \r
+  LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
 \r
-VOID\r
-GetPcdImageInfo (\r
-  IN CONST UINT8          *PcdImageOnFlash,\r
-  OUT PCD_IMAGE_RECORD    *ImageInfo\r
-)\r
-{\r
-  PCD_FFS_ENCODING *PcdFfsHdr;\r
-\r
-  PcdFfsHdr = (PCD_FFS_ENCODING *) PcdImageOnFlash;\r
+  if (PtrType) {\r
+    ASSERT (PeiPcdDb->Init.SizeTable[TokenNumber] >= Size);\r
+  } else {\r
+    ASSERT (PeiPcdDb->Init.SizeTable[TokenNumber] == Size);\r
+  }\r
 \r
-  ZeroMem (ImageInfo, sizeof (*ImageInfo));\r
+  InvokeCallbackOnSet (0, NULL, TokenNumber, Data, Size);\r
 \r
-  ImageInfo->ImageStart = PcdImageOnFlash;\r
+  return SetWorkerByLocalTokenNumber (LocalTokenNumber, Data, Size, PtrType);\r
 \r
-  CopyMem (&ImageInfo->EntryCount,              PcdFfsHdr->EntryCount,         3);\r
-  \r
-  CopyMem (&ImageInfo->GlobalDatumLength,       PcdFfsHdr->GlobalDatumLength,  1);\r
-  ASSERT  (ImageInfo->GlobalDatumLength <= 3);\r
-  \r
-  CopyMem (&ImageInfo->GlobalOffsetLength,      PcdFfsHdr->GlobalOffsetLength, 1);\r
-  ASSERT  (ImageInfo->GlobalOffsetLength <= 3);\r
-  \r
-  CopyMem (&ImageInfo->GlobalTokenLength,       PcdFfsHdr->GlobalTokenLength,  1);\r
-  ASSERT  (ImageInfo->GlobalTokenLength <= 4);\r
-\r
-  CopyMem (&ImageInfo->GlobalGuidTabIdxLength,  PcdFfsHdr->GuidLength,         1);\r
-  ASSERT  (ImageInfo->GlobalGuidTabIdxLength <= 2);\r
-\r
-  CopyMem (&ImageInfo->GlobalStrTabIdxLength,   PcdFfsHdr->GlobalStrTabIdxLength, 1);\r
-  ASSERT  (ImageInfo->GlobalStrTabIdxLength <= 2);\r
-\r
-  CopyMem (&ImageInfo->ImageLength,             PcdFfsHdr->ImageLength,        3);\r
-  CopyMem (&ImageInfo->IndexLength,             PcdFfsHdr->PcdIndexLength,     3);\r
-  CopyMem (&ImageInfo->WholeDataDefaultLength,  PcdFfsHdr->WholeDataBufferLength, 3);\r
-  CopyMem (&ImageInfo->DataDefaultLength,       PcdFfsHdr->DataBufferLength, 3);\r
-  CopyMem (&ImageInfo->GuidTableLength,         PcdFfsHdr->GuidTableLength,  3);\r
-\r
-  ImageInfo->StringTableLength = ImageInfo->ImageLength\r
-                                  - sizeof (PCD_FFS_ENCODING)\r
-                                  - ImageInfo->DataDefaultLength\r
-                                  - ImageInfo->IndexLength\r
-                                  - ImageInfo->GuidTableLength;\r
-\r
-  ImageInfo->DataDefaultStart = PcdImageOnFlash + sizeof (PCD_FFS_ENCODING);\r
-  ImageInfo->IndexStart       = ImageInfo->DataDefaultStart + ImageInfo->DataDefaultLength;\r
-  ImageInfo->GuidTableStart   = (CONST EFI_GUID *)(ImageInfo->IndexStart + ImageInfo->IndexLength);\r
-  ImageInfo->StringTableStart = (CONST UINT16 *) ((UINT8 *) ImageInfo->GuidTableStart + ImageInfo->GuidTableLength);\r
-  \r
-  return;\r
 }\r
 \r
 \r
 \r
-/**\r
-  The function builds the PCD database based on the\r
-  PCD_IMAGE on the flash.\r
-\r
-  The layout of the PCD_DATABASE is as follows:\r
-\r
-  ---------------------------\r
-  |  PCD_DATABASE_HEADER    |\r
-  ---------------------------\r
-  |  GUID_TABLE             |  Aligned on GUID    (128 bits)\r
-  ---------------------------\r
-  |  PCD_CALL_BACK_TABLE    |  Aligned on Pointer (32 bits or 64 bits)\r
-  ---------------------------\r
-  |  PCD_INDEX_TABLE        |  Aligned on PCD_INDEX (see PCD_INDEX's declaration)\r
-  ---------------------------\r
-  |  IMAGE_STRING_TABLE     |  Aligned on 16 Bits\r
-  ---------------------------\r
-  |  IMAGE_PCD_INDEX        |  Unaligned\r
-  ---------------------------\r
-  |  Data Defaults          |  Unaligned\r
-  ---------------------------\r
-  |  Data Buffer            |\r
-  |  for entries without    |\r
-  |  defaults               |\r
-  ---------------------------\r
-\r
-  @param[in] PcdImageOnFlash  The PCD image on flash.\r
 \r
-  @retval VOID\r
---*/\r
-UINTN\r
-GetPcdDatabaseLen (\r
-  IN CONST UINT8          *PcdImageOnFlash,\r
-  OUT PCD_DATABASE_HEADER *Info,\r
-  OUT PCD_IMAGE_RECORD    *ImageInfo\r
+EFI_STATUS\r
+ExSetWorker (\r
+  IN UINT32               ExTokenNumber,\r
+  IN CONST EFI_GUID       *Guid,\r
+  VOID                    *Data,\r
+  UINTN                   Size,\r
+  BOOLEAN                 PtrType\r
   )\r
 {\r
-  UINTN DatabaseLen;\r
-  UINTN DatabaseHeaderLength;\r
-  UINTN PcdIndexLength;\r
-  UINTN CallbackBufferLength;\r
-\r
-\r
-  GetPcdImageInfo (PcdImageOnFlash, ImageInfo);\r
-\r
-  Info->MaxCallbackNum = FixedPcdGet32(PcdMaxPcdCallBackNumber) ;\r
+  PEI_PCD_DATABASE          *PeiPcdDb;\r
+  EX_PCD_ENTRY_ATTRIBUTE    Attr;\r
 \r
-  DatabaseHeaderLength = sizeof (PCD_DATABASE) - sizeof(UINT8);\r
 \r
-  PcdIndexLength       = sizeof (PCD_INDEX) * ImageInfo->EntryCount;\r
-  CallbackBufferLength = sizeof (PCD_PPI_CALLBACK) * Info->MaxCallbackNum * ImageInfo->EntryCount;\r
+  PeiPcdDb = GetPcdDatabase ();\r
 \r
-  Info->EntryCount          = ImageInfo->EntryCount;\r
-  Info->GuidTableOffset     = DatabaseHeaderLength;\r
-  Info->CallbackTableOffset = Info->GuidTableOffset + ImageInfo->GuidTableLength;\r
-  Info->PcdIndexOffset      = Info->PcdIndexOffset + PcdIndexLength;\r
-  Info->ImageIndexOffset    = Info->CallbackTableOffset + CallbackBufferLength;\r
-  Info->DataBufferOffset    = Info->ImageIndexOffset + ImageInfo->DataDefaultLength;\r
+  GetExPcdTokenAttributes (Guid, ExTokenNumber, &Attr);\r
 \r
-  Info->HiiGuidOffsetLength = ImageInfo->GlobalGuidTabIdxLength;\r
-  Info->HiiVariableOffsetLength = ImageInfo->GlobalStrTabIdxLength;\r
-  Info->ExtendedOffsetLength    = ImageInfo->GlobalOffsetLength;\r
+  ASSERT (!PtrType && Attr.Size);\r
 \r
-  Info->SkuId = 0;\r
+  ASSERT (PtrType && Attr.Size >= Size);\r
 \r
-  DatabaseLen = DatabaseHeaderLength\r
-              + ImageInfo->GuidTableLength\r
-              + PcdIndexLength\r
-              + CallbackBufferLength\r
-              + ImageInfo->IndexLength\r
-              + ImageInfo->WholeDataDefaultLength;\r
+  InvokeCallbackOnSet (ExTokenNumber, Guid, Attr.TokenNumber, Data, Size);\r
 \r
-  Info->DatabaseLen = DatabaseLen;\r
+  SetWorkerByLocalTokenNumber (Attr.LocalTokenNumberAlias, Data, Size, PtrType);\r
 \r
-  return DatabaseLen;\r
+  return EFI_SUCCESS;\r
+  \r
 }\r
 \r
 \r
-/**\r
-  The function constructs a single PCD_INDEX according a index in\r
-  <PCD_IMAGE>.\r
 \r
-  @param[in] ImageIndex  The starting address of a PCD index defined in PCD spec 0.51.\r
-  @param[in] Index       The output PCD_INDEX. \r
-  @param[in] ImageInfo   The attributes of the PCD_IMAGE as this binary stream is highly\r
-                          optimized for size.\r
 \r
-  @retval UINTN The length of the current PCD index.\r
-**/\r
-UINTN\r
-BuildPcdIndex (\r
-  IN CONST UINT8            *ImageIndex,\r
-  OUT PCD_INDEX             *Index,\r
-  IN CONST PCD_IMAGE_RECORD *ImageInfo\r
-)\r
+EFI_STATUS\r
+SetWorkerByLocalTokenNumber (\r
+  UINT32        LocalTokenNumber,\r
+  VOID          *Data,\r
+  UINTN         Size,\r
+  BOOLEAN       PtrType\r
+  )\r
 {\r
-  UINTN       SkuCount;\r
-  CONST UINT8 *ImageIndexBackUp;\r
-\r
-  ImageIndexBackUp = ImageIndex;\r
+  PEI_PCD_DATABASE      *PeiPcdDb;\r
+  UINT8                 *PeiPcdDbRaw;\r
+  UINT16                StringTableIdx;\r
+  UINTN                 Offset;\r
+  VOID                  *InternalData;\r
\r
+\r
+  PeiPcdDb    =    GetPcdDatabase ();\r
+  PeiPcdDbRaw =    (UINT8 *) PeiPcdDb;\r
   \r
-  //\r
-  // Token Number\r
-  //\r
-  CopyMem (&Index->TokenNumber,\r
-            ImageIndex,\r
-            ImageInfo->GlobalTokenLength\r
-            );\r
-\r
-  ImageIndex += ImageInfo->GlobalTokenLength;\r
-  \r
-  //\r
-  // State Byte\r
-  //\r
-  PcdImageExpandStateByte (&Index->StateByte,\r
-                           *ImageIndex\r
-                           );\r
+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size);\r
+  }\r
 \r
-  ImageIndex += 1;\r
+  Offset          = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+  InternalData    = (VOID *) (PeiPcdDbRaw + Offset);\r
   \r
-  //\r
-  // Dataum Size\r
-  //\r
-  CopyMem (&Index->DatumSize,\r
-          ImageIndex,\r
-          ImageInfo->GlobalDatumLength\r
-          );\r
+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {\r
+    case PCD_TYPE_VPD:\r
+    case PCD_TYPE_HII:\r
+    {\r
+      ASSERT (FALSE);\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
 \r
-  ImageIndex += ImageInfo->GlobalDatumLength;\r
+    case PCD_TYPE_STRING:\r
+      StringTableIdx = *((UINT16 *)InternalData);\r
+      CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, Size);\r
+      break;\r
 \r
-  //\r
-  // SKU_DATA\r
-  //\r
-  if (Index->StateByte.SkuEnable) {\r
-    Index->SkuCount     = *ImageIndex;\r
-    SkuCount            = *ImageIndex;\r
-    ImageIndex++;\r
-    Index->SkuIdArray   = (UINT32) ImageIndex - (UINT32) ImageInfo->IndexStart;\r
-    ImageIndex         += Index->SkuCount;\r
-  } else {\r
-    //\r
-    // There is always a default SKU_ID of zero even \r
-    // if SKU is not enabled for this PCD entry.\r
-    // \r
-    //\r
-    SkuCount = 1;\r
-  }\r
+    case PCD_TYPE_DATA:\r
+    {\r
+      \r
+      if (PtrType) {\r
+        CopyMem (InternalData, Data, Size);\r
+        return EFI_SUCCESS;\r
+      }\r
 \r
-  //\r
-  // Extended Offset\r
-  //\r
-  CopyMem (&Index->ExtendedDataOffset,\r
-           ImageIndex,\r
-           ImageInfo->GlobalOffsetLength\r
-           );\r
+      switch (Size) {\r
+        case sizeof(UINT8):\r
+          *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
+          return EFI_SUCCESS;\r
 \r
-  ImageIndex += ImageInfo->GlobalOffsetLength * SkuCount;\r
+        case sizeof(UINT16):\r
+          *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
+          return EFI_SUCCESS;\r
 \r
-  //\r
-  // DynamicEX Guid Offset\r
-  //\r
-  if (Index->StateByte.ExtendedGuidPresent) {\r
-    CopyMem (&Index->DynamicExGuid,\r
-             ImageIndex,\r
-             ImageInfo->GlobalGuidTabIdxLength\r
-             );\r
+        case sizeof(UINT32):\r
+          *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
+          return EFI_SUCCESS;\r
 \r
-    ImageIndex += ImageInfo->GlobalGuidTabIdxLength;\r
-  }\r
+        case sizeof(UINT64):\r
+          *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
+          return EFI_SUCCESS;\r
 \r
-  //\r
-  // HII_DATA\r
-  //\r
-  if (Index->StateByte.HiiEnable) {\r
-    Index->HiiData = (UINT32) ImageIndex - (UINT32) ImageInfo->IndexStart;\r
-    ImageIndex += ((ImageInfo->GlobalStrTabIdxLength + ImageInfo->GlobalGuidTabIdxLength) * SkuCount);\r
+        default:\r
+          ASSERT (FALSE);\r
+          return EFI_NOT_FOUND;\r
+      }\r
+    }\r
+      \r
   }\r
 \r
-  return (UINTN) (ImageIndex - ImageIndexBackUp);\r
+  ASSERT (FALSE);\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 \r
-\r
-\r
-/**\r
-  The function builds the PCD database based on the\r
-  PCD_IMAGE on the flash.\r
-\r
-  @param[in] Database  The database instance.\r
-  @param[in] ImageIndex The starting address of a PCD index defined in PCD spec 0.51.\r
-  @param[in] ImageInfo The attributes of the PCD_IMAGE as this binary stream is highly\r
-              optimized for size.\r
-\r
-  @retval VOID\r
-**/\r
-VOID\r
-BuildPcdDatabaseIndex (\r
-  PCD_DATABASE     *Database,\r
-  UINT8            *ImageIndex,\r
-  PCD_IMAGE_RECORD *ImageInfo\r
+VOID *\r
+GetWorkerByLocalTokenNumber (\r
+  PEI_PCD_DATABASE    *PeiPcdDb,\r
+  UINT32              LocalTokenNumber,\r
+  UINTN               Size\r
   )\r
 {\r
-  UINTN     Idx;\r
-  UINTN     Len;\r
-  PCD_INDEX *IndexTable;\r
+  UINT32              Offset;\r
+  EFI_GUID            *Guid;\r
+  UINT16              *Name;\r
+  VARIABLE_HEAD       *VariableHead;\r
+  EFI_STATUS          Status;\r
+  UINTN               DataSize;\r
+  VOID                *Data;\r
+  UINT16              *StringTable;\r
+  UINT16              StringTableIdx;\r
+      \r
+  PeiPcdDb        = GetPcdDatabase ();\r
+\r
+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size);\r
+  }\r
 \r
-  IndexTable = (PCD_INDEX *) GetAbsoluteAddress (0, Database->Info.PcdIndexOffset, Database);\r
+  Offset      = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+  StringTable = PeiPcdDb->Init.StringTable;\r
+  \r
+  switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {\r
+    case PCD_TYPE_VPD:\r
+    {\r
+      VPD_HEAD *VpdHead;\r
+      VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
+      return (VOID *) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
+    }\r
+      \r
+    case PCD_TYPE_HII:\r
+    {\r
+      VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
+      \r
+      Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);\r
+      Name = &StringTable[VariableHead->StringIndex];\r
+\r
+      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
+      ASSERT_EFI_ERROR (Status);\r
+      ASSERT (DataSize >= (UINTN) (VariableHead->Offset + Size));\r
+\r
+      return (VOID *) ((UINT8 *) Data + VariableHead->Offset);\r
+    }\r
 \r
-  for (Idx = 0; Idx < Database->Info.EntryCount; Idx++) {\r
-    Len = BuildPcdIndex (ImageIndex, &IndexTable[Idx], ImageInfo);\r
-    ImageIndex += Len;\r
-  }\r
+    case PCD_TYPE_DATA:\r
+      return (VOID *) ((UINT8 *)PeiPcdDb + Offset);\r
+      break;\r
 \r
-  return;\r
-}\r
+    case PCD_TYPE_STRING:\r
+      StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);\r
+      return (VOID *) (&StringTable[StringTableIdx]);\r
 \r
+    default:\r
+      ASSERT (FALSE);\r
+      break;\r
+      \r
+  }\r
 \r
-/**\r
-  The function builds the PCD database based on the\r
-  PCD_IMAGE on the flash.\r
+  ASSERT (FALSE);\r
+      \r
+  return NULL;\r
+  \r
+}\r
 \r
-  @param[in] PcdImageOnFlash  The PCD image on flash.\r
 \r
-  @retval VOID\r
---*/\r
-VOID\r
-BuildPcdDatabase (\r
-  UINT8 *PcdImageOnFlash\r
+VOID *\r
+ExGetWorker (\r
+  IN CONST  EFI_GUID  *Guid,\r
+  IN UINT32           ExTokenNumber,\r
+  IN UINTN            GetSize\r
   )\r
 {\r
-  PCD_DATABASE        *Database;\r
-  UINTN               Len;\r
-  PCD_IMAGE_RECORD    ImageInfo;\r
-  UINT8               *ImageIndex;\r
-  PCD_DATABASE_HEADER DatabaseHeader;\r
-\r
-  Len = GetPcdDatabaseLen(PcdImageOnFlash, &DatabaseHeader, &ImageInfo);\r
-\r
-  Database = BuildGuidHob (&gPcdDataBaseHobGuid, Len);\r
-  ASSERT (Database != NULL);\r
+  EX_PCD_ENTRY_ATTRIBUTE      Attr;\r
 \r
-  ZeroMem (Database, Len);\r
-\r
-  //\r
-  // Update Database header\r
-  //\r
-  CopyMem (&Database->Info, &DatabaseHeader, sizeof (DatabaseHeader));\r
-\r
-  //\r
-  // I need this to get the GuidTableOffset as we don't\r
-  // know if Database field of PCD_DATABASE starts from an aligned\r
-  // address. The compilor may add padding after PCD_DATABASE_HEADER field.\r
-  //\r
-  Database->Info.GuidTableOffset = ((UINTN) &Database->GuidTable) - (UINTN)Database;\r
+  GetExPcdTokenAttributes (Guid, ExTokenNumber, &Attr);\r
   \r
-  //\r
-  // Copy Guid Table from Flash\r
-  //\r
-  CopyMem ((UINT8 *) Database + Database->Info.GuidTableOffset,\r
-            ImageInfo.GuidTableStart,\r
-            ImageInfo.GuidTableLength\r
-            );\r
-\r
-  //\r
-  // Copy ImageIndex from Flash\r
-  //\r
-  CopyMem ((UINT8 *) Database + Database->Info.ImageIndexOffset,\r
-            ImageInfo.IndexStart,\r
-            ImageInfo.IndexLength\r
-            );\r
+  ASSERT ((GetSize == Attr.Size) || (GetSize == 0));\r
 \r
-  //\r
-  // Copy Default Value\r
-  //\r
-  CopyMem ((UINT8 *) Database + Database->Info.DataBufferOffset,\r
-           ImageInfo.DataDefaultStart,\r
-           ImageInfo.DataDefaultLength\r
-           );\r
-\r
-  //\r
-  // Copy String Table\r
-  //\r
-  CopyMem ((UINT8 *) Database + Database->Info.StringTableOffset,\r
-           ImageInfo.StringTableStart,\r
-           ImageInfo.StringTableLength\r
-           );\r
-\r
-  ImageIndex = GetAbsoluteAddress (0, Database->Info.ImageIndexOffset, Database);\r
-\r
-  BuildPcdDatabaseIndex (Database, ImageIndex, &ImageInfo);\r
-\r
-  return;\r
+  return GetWorkerByLocalTokenNumber (GetPcdDatabase(),\r
+                                      Attr.LocalTokenNumberAlias,\r
+                                      Attr.Size\r
+                                      );\r
 }\r
 \r
-\r
-\r
-/**\r
-  The function is provided by PCD PEIM and PCD DXE driver to\r
-  do the work of reading a HII variable from variable service.\r
-\r
-  @param[in] VariableGuid     The Variable GUID.\r
-  @param[in] VariableName     The Variable Name.\r
-  @param[out] VariableData    The output data.\r
-  @param[out] VariableSize    The size of the variable.\r
-\r
-  @retval EFI_SUCCESS         Operation successful.\r
-  @retval EFI_SUCCESS         Variablel not found.\r
---*/\r
-EFI_STATUS\r
-GetHiiVariable (\r
-  IN  EFI_GUID     *VariableGuid,\r
-  IN  UINT16       *VariableName,\r
-  OUT VOID         **VariableData,\r
-  OUT UINTN        *VariableSize\r
+VOID *\r
+GetWorker (\r
+  UINTN  TokenNumber,\r
+  UINTN   GetSize\r
   )\r
 {\r
-  UINTN      Size;\r
-  EFI_STATUS Status;\r
-  VOID       *Buffer;\r
-  EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;\r
-\r
-  Status = PeiCoreLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, &VariablePpi);\r
-  ASSERT_EFI_ERROR (Status);\r
+  PEI_PCD_DATABASE      *PeiPcdDb;\r
 \r
-  Size = 0;\r
+  ASSERT (TokenNumber < PEI_LOCAL_TOKEN_NUMBER);\r
 \r
-  Status = VariablePpi->PeiGetVariable (\r
-                          GetPeiServicesTablePointer (),\r
-                          VariableName,\r
-                          VariableGuid,\r
-                          NULL,\r
-                          &Size,\r
-                          NULL\r
-                            );\r
-  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
+  ASSERT (GetSize == PeiPcdGetSize (TokenNumber) || GetSize == 0);\r
 \r
-  Status = PeiCoreAllocatePool (Size, &Buffer);\r
-  ASSERT_EFI_ERROR (Status);\r
+  PeiPcdDb = GetPcdDatabase ();\r
+  \r
+  return  GetWorkerByLocalTokenNumber (PeiPcdDb, PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber], GetSize);\r
+}\r
 \r
-  // declare a local for STP.\r
-  //\r
-  Status = VariablePpi->PeiGetVariable (\r
-                            GetPeiServicesTablePointer (),\r
-                            (UINT16 *) VariableName,\r
-                            VariableGuid,\r
-                            NULL,\r
-                            &Size,\r
-                            Buffer\r
-                            );\r
-  ASSERT_EFI_ERROR (Status);\r
 \r
-  *VariableSize = Size;\r
-  *VariableData = Buffer;\r
+VOID\r
+GetExPcdTokenAttributes (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINT32                     ExTokenNumber,\r
+  OUT EX_PCD_ENTRY_ATTRIBUTE    *ExAttr\r
+  )\r
+{\r
+  UINT32              i;\r
+  DYNAMICEX_MAPPING   *ExMap;\r
+  EFI_GUID            *GuidTable;\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
 \r
-  return EFI_SUCCESS;\r
+  PeiPcdDb    = GetPcdDatabase();\r
+  \r
+  ExMap       = PeiPcdDb->Init.ExMapTable;\r
+  GuidTable   = PeiPcdDb->Init.GuidTable;\r
+  \r
+  for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
+    if ((ExTokenNumber == ExMap[i].ExTokenNumber) && \r
+        CompareGuid (Guid, (CONST EFI_GUID *) &GuidTable[ExMap[i].ExGuidIndex])) {\r
+      ExAttr->TokenNumber               = i + PEI_NEX_TOKEN_NUMBER;\r
+      ExAttr->Size                      = PeiPcdDb->Init.SizeTable[i + PEI_NEX_TOKEN_NUMBER];\r
+      ExAttr->LocalTokenNumberAlias     = ExMap[i].LocalTokenNumber;\r
+    }\r
+  }\r
+  \r
+  ASSERT (FALSE);\r
+  \r
+  return;\r
 }\r
 \r
 \r
 \r
-/**\r
-  The function is provided by PCD PEIM and PCD DXE driver to\r
-  do the work of reading a HII variable from variable service.\r
-\r
-  @param[in] VariableGuid     The Variable GUID.\r
-  @param[in] VariableName     The Variable Name.\r
-  @param[in] Data             The input data.\r
-  @param[out] VariableSize    The size of the variable.\r
-  @param[in] Offset           The offset of the variable data that a PCD entry will starts from.\r
-\r
-  @retval EFI_SUCCESS         Operation successful.\r
-  @retval EFI_SUCCESS         Variablel not found.\r
---*/\r
-EFI_STATUS\r
-SetHiiVariable (\r
-  IN  EFI_GUID     *VariableGuid,\r
-  IN  UINT16       *VariableName,\r
-  IN  CONST VOID   *Data,\r
-  IN  UINTN        VariableSize,\r
-  IN  UINTN        Offset\r
+PEI_PCD_DATABASE *\r
+GetPcdDatabase (\r
+  VOID\r
   )\r
 {\r
-  ASSERT (FALSE);\r
-  return EFI_INVALID_PARAMETER;\r
-}\r
+  EFI_HOB_GUID_TYPE *GuidHob;\r
 \r
+  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
+  ASSERT (GuidHob != NULL);\r
+  \r
+  return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
+}\r
 \r