]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PCD/Dxe/Service.c
MdeModulePkg Pcd(DXE): Use correct TokenNumber to call GetPtrTypeSize () when SKU...
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Dxe / Service.c
index 6eaadd6cceef24b8e381c6a7a7a90e7d8e18584d..3a41bf531689d0e94fb4e99f803fe7374edfd502 100644 (file)
@@ -13,10 +13,342 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include "Service.h"\r
+#include <Library/DxeServicesLib.h>\r
 \r
-PCD_DATABASE  *mPcdDatabase;\r
+PCD_DATABASE   mPcdDatabase;\r
+\r
+UINT32         mPcdTotalTokenCount; \r
+UINT32         mPeiLocalTokenCount; \r
+UINT32         mDxeLocalTokenCount; \r
+UINT32         mPeiNexTokenCount;   \r
+UINT32         mDxeNexTokenCount;  \r
+UINT32         mPeiExMapppingTableSize;\r
+UINT32         mDxeExMapppingTableSize;\r
+UINT32         mPeiGuidTableSize;\r
+UINT32         mDxeGuidTableSize;\r
+\r
+BOOLEAN        mPeiExMapTableEmpty; \r
+BOOLEAN        mDxeExMapTableEmpty; \r
+BOOLEAN        mPeiDatabaseEmpty;\r
 \r
 LIST_ENTRY    *mCallbackFnTable;\r
+EFI_GUID     **TmpTokenSpaceBuffer;\r
+UINTN          TmpTokenSpaceBufferCount; \r
+\r
+/**\r
+  Get Local Token Number by Token Number.\r
+\r
+  @param[in]    IsPeiDb     If TRUE, the pcd entry is initialized in PEI phase,\r
+                            If FALSE, the pcd entry is initialized in DXE phase.\r
+  @param[in]    TokenNumber The PCD token number.\r
+\r
+  @return       Local Token Number.\r
+**/\r
+UINT32\r
+GetLocalTokenNumber (\r
+  IN BOOLEAN            IsPeiDb,\r
+  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
+  // We have to decrement TokenNumber by 1 to make it usable\r
+  // as the array index.\r
+  //\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
+}\r
+\r
+/**\r
+  Get PCD type by Local Token Number.\r
+\r
+  @param[in]    LocalTokenNumber The PCD local token number.\r
+\r
+  @return       PCD type.\r
+**/\r
+EFI_PCD_TYPE\r
+GetPcdType (\r
+  IN UINT32             LocalTokenNumber\r
+  )\r
+{\r
+  switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {\r
+    case PCD_DATUM_TYPE_POINTER:\r
+      return EFI_PCD_TYPE_PTR;\r
+    case PCD_DATUM_TYPE_UINT8:\r
+      if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {\r
+        return EFI_PCD_TYPE_BOOL;\r
+      } else {\r
+        return EFI_PCD_TYPE_8;\r
+      }\r
+    case PCD_DATUM_TYPE_UINT16:\r
+      return EFI_PCD_TYPE_16;\r
+    case PCD_DATUM_TYPE_UINT32:\r
+      return EFI_PCD_TYPE_32;\r
+    case PCD_DATUM_TYPE_UINT64:\r
+      return EFI_PCD_TYPE_64;\r
+    default:\r
+      ASSERT (FALSE);\r
+      return EFI_PCD_TYPE_8;\r
+  }\r
+}\r
+\r
+/**\r
+  Get PCD name.\r
+\r
+  @param[in]    OnlyTokenSpaceName  If TRUE, only need to get the TokenSpaceCName.\r
+                                    If FALSE, need to get the full PCD name.\r
+  @param[in]    IsPeiDb             If TRUE, the pcd entry is initialized in PEI phase,\r
+                                    If FALSE, the pcd entry is initialized in DXE phase.\r
+  @param[in]    TokenNumber         The PCD token number.\r
+\r
+  @return       The TokenSpaceCName or full PCD name.\r
+**/\r
+CHAR8 *\r
+GetPcdName (\r
+  IN BOOLEAN            OnlyTokenSpaceName,\r
+  IN BOOLEAN            IsPeiDb,\r
+  IN UINTN              TokenNumber\r
+  )\r
+{\r
+  PCD_DATABASE_INIT *Database;\r
+  UINT8             *StringTable;\r
+  PCD_NAME_INDEX    *PcdNameIndex;\r
+  CHAR8             *TokenSpaceName;\r
+  CHAR8             *PcdName;\r
+  CHAR8             *Name;\r
+\r
+  //\r
+  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+  // We have to decrement TokenNumber by 1 to make it usable\r
+  // as the array index.\r
+  //\r
+  TokenNumber--;\r
+\r
+  Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;\r
+  TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;\r
+\r
+  StringTable = (UINT8 *) Database + Database->StringTableOffset;\r
+\r
+  //\r
+  // Get the PCD name index.\r
+  //\r
+  PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber;\r
+  TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];\r
+  PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];\r
+\r
+  if (OnlyTokenSpaceName) {\r
+    //\r
+    // Only need to get the TokenSpaceCName.\r
+    //\r
+    Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);\r
+  } else {\r
+    //\r
+    // Need to get the full PCD name.\r
+    //\r
+    Name = AllocateZeroPool (AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName));\r
+    ASSERT (Name != NULL);\r
+    //\r
+    // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.\r
+    //\r
+    AsciiStrCat (Name, TokenSpaceName);\r
+    Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';\r
+    AsciiStrCat (Name, PcdName);  \r
+  }\r
+\r
+  return Name;\r
+}\r
+\r
+/**\r
+  Retrieve additional information associated with a PCD token.\r
+\r
+  This includes information such as the type of value the TokenNumber is associated with as well as possible\r
+  human readable name that is associated with the token.\r
+\r
+  @param[in]    IsPeiDb     If TRUE, the pcd entry is initialized in PEI phase,\r
+                            If FALSE, the pcd entry is initialized in DXE phase.\r
+  @param[in]    Guid        The 128-bit unique value that designates the namespace from which to extract the value.\r
+  @param[in]    TokenNumber The PCD token number.\r
+  @param[out]   PcdInfo     The returned information associated with the requested TokenNumber.\r
+                            The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. \r
+\r
+  @retval  EFI_SUCCESS      The PCD information was returned successfully\r
+  @retval  EFI_NOT_FOUND    The PCD service could not find the requested token number.\r
+**/\r
+EFI_STATUS\r
+ExGetPcdInfo (\r
+  IN        BOOLEAN             IsPeiDb,\r
+  IN CONST  EFI_GUID            *Guid,\r
+  IN        UINTN               TokenNumber,\r
+  OUT       EFI_PCD_INFO        *PcdInfo\r
+  )\r
+{\r
+  PCD_DATABASE_INIT     *Database;\r
+  UINTN                 GuidTableIdx;\r
+  EFI_GUID              *MatchGuid;\r
+  EFI_GUID              *GuidTable;\r
+  DYNAMICEX_MAPPING     *ExMapTable;\r
+  UINTN                 Index;\r
+  UINT32                LocalTokenNumber;\r
+\r
+  Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;\r
+\r
+  GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);\r
+  MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof(EFI_GUID), Guid);\r
+\r
+  if (MatchGuid == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  GuidTableIdx = MatchGuid - GuidTable;\r
+\r
+  ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);\r
+\r
+  //\r
+  // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.\r
+  //\r
+  for (Index = 0; Index < Database->ExTokenCount; Index++) {\r
+    if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
+      if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
+        //\r
+        // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,\r
+        // PcdSize to 0 and PcdName to the null-terminated ASCII string\r
+        // associated with the token's namespace Guid.\r
+        //\r
+        PcdInfo->PcdType = EFI_PCD_TYPE_8;\r
+        PcdInfo->PcdSize = 0;\r
+        //\r
+        // Here use one representative in the token space to get the TokenSpaceCName.\r
+        // \r
+        PcdInfo->PcdName = GetPcdName (TRUE, IsPeiDb, ExMapTable[Index].TokenNumber);\r
+        return EFI_SUCCESS;\r
+      } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {\r
+        PcdInfo->PcdSize = DxePcdGetSize (ExMapTable[Index].TokenNumber);\r
+        LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, ExMapTable[Index].TokenNumber);\r
+        PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
+        PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, ExMapTable[Index].TokenNumber);\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Retrieve additional information associated with a PCD token.\r
+\r
+  This includes information such as the type of value the TokenNumber is associated with as well as possible\r
+  human readable name that is associated with the token.\r
+\r
+  @param[in]    Guid        The 128-bit unique value that designates the namespace from which to extract the value.\r
+  @param[in]    TokenNumber The PCD token number.\r
+  @param[out]   PcdInfo     The returned information associated with the requested TokenNumber.\r
+                            The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.\r
+\r
+  @retval  EFI_SUCCESS      The PCD information was returned successfully.\r
+  @retval  EFI_NOT_FOUND    The PCD service could not find the requested token number.\r
+**/\r
+EFI_STATUS\r
+DxeGetPcdInfo (\r
+  IN CONST  EFI_GUID        *Guid,\r
+  IN        UINTN           TokenNumber,\r
+  OUT       EFI_PCD_INFO    *PcdInfo\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  BOOLEAN               PeiExMapTableEmpty;\r
+  BOOLEAN               DxeExMapTableEmpty;\r
+  UINT32                LocalTokenNumber;\r
+  BOOLEAN               IsPeiDb;\r
+\r
+  ASSERT (PcdInfo != NULL);\r
+\r
+  Status = EFI_NOT_FOUND;\r
+  PeiExMapTableEmpty = mPeiExMapTableEmpty;\r
+  DxeExMapTableEmpty = mDxeExMapTableEmpty;\r
+\r
+  if (Guid == NULL) {\r
+    if (((TokenNumber + 1 > mPeiNexTokenCount + 1) && (TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||\r
+        ((TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {\r
+      return EFI_NOT_FOUND;\r
+    } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
+      //\r
+      // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,\r
+      // PcdSize to 0 and PcdName to NULL for default Token Space.\r
+      //\r
+      PcdInfo->PcdType = EFI_PCD_TYPE_8;\r
+      PcdInfo->PcdSize = 0;\r
+      PcdInfo->PcdName = NULL;\r
+    } else {\r
+      PcdInfo->PcdSize = DxePcdGetSize (TokenNumber);\r
+      IsPeiDb = FALSE;\r
+      if ((TokenNumber + 1 <= mPeiNexTokenCount + 1)) {\r
+        IsPeiDb = TRUE;\r
+      }\r
+      LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);\r
+      PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
+      PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, TokenNumber);\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (!PeiExMapTableEmpty) {\r
+    Status = ExGetPcdInfo (\r
+               TRUE,\r
+               Guid,\r
+               TokenNumber,\r
+               PcdInfo\r
+               );\r
+  }\r
+\r
+  if (Status == EFI_SUCCESS) {\r
+    return Status;\r
+  }\r
+\r
+  if (!DxeExMapTableEmpty) {\r
+    Status = ExGetPcdInfo (\r
+               FALSE,\r
+               Guid,\r
+               TokenNumber,\r
+               PcdInfo\r
+               );\r
+  }\r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Get the PCD entry pointer in PCD database.\r
@@ -38,7 +370,6 @@ GetWorker (
   IN UINTN             GetSize\r
   )\r
 {\r
-  UINT32              *LocalTokenNumberTable;\r
   EFI_GUID            *GuidTable;\r
   UINT8               *StringTable;\r
   EFI_GUID            *Guid;\r
@@ -49,7 +380,6 @@ GetWorker (
   VPD_HEAD            *VpdHead;\r
   UINT8               *PcdDb;\r
   VOID                *RetPtr;\r
-  UINTN               MaxSize;\r
   UINTN               TmpTokenNumber;\r
   UINTN               DataSize;\r
   EFI_STATUS          Status;\r
@@ -64,6 +394,8 @@ GetWorker (
   EfiAcquireLock (&mPcdDatabaseLock);\r
 \r
   RetPtr = NULL;\r
+\r
+  ASSERT (TokenNumber > 0);\r
   //\r
   // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
   // We have to decrement TokenNumber by 1 to make it usable\r
@@ -72,115 +404,81 @@ GetWorker (
   TokenNumber--;\r
 \r
   TmpTokenNumber = TokenNumber;\r
-  \r
+\r
   //\r
-  // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant.\r
-  // It could be zero. EBC compiler is very choosy. It may\r
-  // report warning. So we add 1 in each size of the \r
+  // EBC compiler is very choosy. It may report warning about comparison\r
+  // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
   //\r
-  ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
+  ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);\r
 \r
   ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));\r
 \r
   // EBC compiler is very choosy. It may report warning about comparison\r
   // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
-  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);\r
-\r
-  LocalTokenNumberTable  = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
-                                     mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
+  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);\r
 \r
-  TokenNumber            = IsPeiDb ? TokenNumber :\r
-                                     TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
-\r
-  LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
-  \r
-  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
-    if (GetSize == 0) {\r
-      GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
-    } else {\r
-      MaxSize = GetSize;\r
-    }\r
-    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
-  }\r
+  LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);\r
 \r
-  PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
+  PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);\r
                                     \r
   if (IsPeiDb) {\r
-    StringTable = (UINT8 *) (&mPcdDatabase->PeiDb.Init.StringTable[0]);\r
+    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);\r
   } else {\r
-    StringTable = (UINT8 *) (&mPcdDatabase->DxeDb.Init.StringTable[0]);\r
+    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);\r
   }\r
-                                      \r
-  \r
+\r
+\r
   Offset     = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
-  \r
+\r
   switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
     case PCD_TYPE_VPD:\r
       VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);\r
       RetPtr = (VOID *) (UINTN) (PcdGet32 (PcdVpdBaseAddress) + VpdHead->Offset);\r
+\r
       break;\r
-      \r
+\r
     case PCD_TYPE_HII|PCD_TYPE_STRING:\r
     case PCD_TYPE_HII:\r
       if (IsPeiDb) {\r
-        GuidTable = (EFI_GUID *) (&mPcdDatabase->PeiDb.Init.GuidTable[0]);\r
+        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);\r
       } else {\r
-        GuidTable = (EFI_GUID *) (&mPcdDatabase->DxeDb.Init.GuidTable[0]);\r
+        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);\r
       }\r
-                              \r
+\r
       VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
       Guid = GuidTable + VariableHead->GuidTableIndex;\r
       Name = (UINT16*)(StringTable + VariableHead->StringIndex);\r
-      \r
+\r
       if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {\r
-           //\r
-               // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of \r
-               // string array in string table.\r
-               //\r
+        //\r
+        // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of \r
+        // string array in string table.\r
+        //\r
         StringTableIdx = *(STRING_HEAD*)((UINT8 *) PcdDb + VariableHead->DefaultValueOffset);   \r
         VaraiableDefaultBuffer = (VOID *) (StringTable + StringTableIdx);     \r
-        Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
-        if (Status == EFI_SUCCESS) {\r
-          if (GetSize == 0) {\r
-            //\r
-            // It is a pointer type. So get the MaxSize reserved for\r
-            // this PCD entry.\r
-            //\r
-            GetPtrTypeSize (TmpTokenNumber, &GetSize);\r
-          }\r
-          //\r
-          // If the operation is successful, we copy the data\r
-          // to the default value buffer in the PCD Database.\r
-          // So that we can free the Data allocated in GetHiiVariable.\r
-          //\r
-          CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);\r
-          FreePool (Data);\r
-        }\r
-        RetPtr = (VOID *) VaraiableDefaultBuffer;                \r
       } else {\r
         VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;\r
-  \r
-        Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
-        if (Status == EFI_SUCCESS) {\r
-          if (GetSize == 0) {\r
-            //\r
-            // It is a pointer type. So get the MaxSize reserved for\r
-            // this PCD entry.\r
-            //\r
-            GetPtrTypeSize (TmpTokenNumber, &GetSize);\r
-          }\r
+      }\r
+      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
+      if (Status == EFI_SUCCESS) {\r
+        if (GetSize == 0) {\r
           //\r
-          // If the operation is successful, we copy the data\r
-          // to the default value buffer in the PCD Database.\r
-          // So that we can free the Data allocated in GetHiiVariable.\r
+          // It is a pointer type. So get the MaxSize reserved for\r
+          // this PCD entry.\r
           //\r
-          CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);\r
-          FreePool (Data);\r
+          GetPtrTypeSize (TmpTokenNumber, &GetSize);\r
         }\r
-        RetPtr = (VOID *) VaraiableDefaultBuffer;\r
+        //\r
+        // If the operation is successful, we copy the data\r
+        // to the default value buffer in the PCD Database.\r
+        // So that we can free the Data allocated in GetHiiVariable.\r
+        //\r
+        CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);\r
+        FreePool (Data);\r
       }\r
+      RetPtr = (VOID *) VaraiableDefaultBuffer;\r
       break;\r
 \r
     case PCD_TYPE_STRING:\r
@@ -199,9 +497,9 @@ GetWorker (
   }\r
 \r
   EfiReleaseLock (&mPcdDatabaseLock);\r
-  \r
+\r
   return RetPtr;\r
-  \r
+\r
 }\r
 \r
 /**\r
@@ -359,6 +657,7 @@ ExGetNextTokeNumber (
   UINTN            Index;\r
   UINTN            GuidTableIdx;\r
   BOOLEAN          Found;\r
+  UINTN            ExMapTableCount;\r
 \r
   //\r
   // Scan token space guid \r
@@ -373,7 +672,8 @@ ExGetNextTokeNumber (
   //\r
   Found = FALSE;\r
   GuidTableIdx = MatchGuid - GuidTable;\r
-  for (Index = 0; Index < SizeOfExMapTable; Index++) {\r
+  ExMapTableCount = SizeOfExMapTable / sizeof(ExMapTable[0]);\r
+  for (Index = 0; Index < ExMapTableCount; Index++) {\r
     if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
       Found = TRUE;\r
       break;\r
@@ -390,36 +690,71 @@ ExGetNextTokeNumber (
       return EFI_SUCCESS;\r
     }\r
 \r
-    for ( ; Index < SizeOfExMapTable; Index++) {\r
+    for ( ; Index < ExMapTableCount; Index++) {\r
       if (ExMapTable[Index].ExTokenNumber == *TokenNumber) {\r
-        Index ++;\r
-        if (Index == SizeOfExMapTable) {\r
-          //\r
-          // Exceed the length of ExMap Table\r
-          //\r
-          *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
-          return EFI_SUCCESS;\r
-        } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
-          //\r
-          // Found the next match\r
-          //\r
-          *TokenNumber = ExMapTable[Index].ExTokenNumber;\r
-          return EFI_SUCCESS;\r
-        } else {\r
-          //\r
-          // Guid has been changed. It is the next Token Space Guid.\r
-          // We should flag no more TokenNumber.\r
-          //\r
-          *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
-          return EFI_SUCCESS;\r
-        }\r
+        break;\r
+      }\r
+    }\r
+\r
+    while (Index < ExMapTableCount) {\r
+      Index++;\r
+      if (Index == ExMapTableCount) {\r
+        //\r
+        // Exceed the length of ExMap Table\r
+        //\r
+        *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+        return EFI_NOT_FOUND;\r
+      } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
+        //\r
+        // Found the next match\r
+        //\r
+        *TokenNumber = ExMapTable[Index].ExTokenNumber;\r
+        return EFI_SUCCESS;\r
       }\r
     }\r
   }\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
+/**\r
+  Find the PCD database.\r
+\r
+  @retval The base address of external PCD database binary.\r
+  @retval NULL         Return NULL if not find.\r
+**/\r
+DXE_PCD_DATABASE *\r
+LocateExPcdBinary (\r
+  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
+  //\r
+  Status = GetSectionFromFfs (\r
+             EFI_SECTION_RAW,\r
+             0,\r
+             (VOID **) &DxePcdDbBinary,\r
+             &DxePcdDbSize\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
+    ASSERT (FALSE);\r
+  }\r
+\r
+  return DxePcdDbBinary;\r
+}\r
 \r
 /**\r
   Initialize the PCD database in DXE phase.\r
@@ -436,15 +771,12 @@ BuildPcdDxeDataBase (
   PEI_PCD_DATABASE    *PeiDatabase;\r
   EFI_HOB_GUID_TYPE   *GuidHob;\r
   UINTN               Index;\r
-\r
-  mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));\r
-  ASSERT (mPcdDatabase != NULL);\r
+  UINT32              PcdDxeDbLen;\r
+  VOID                *PcdDxeDb;\r
 \r
   GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
   if (GuidHob != NULL) {\r
 \r
-    //\r
-    // We will copy over the PEI phase's PCD Database.\r
     // \r
     // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM\r
     // should not be included at all. So the GuidHob could\r
@@ -454,28 +786,57 @@ BuildPcdDxeDataBase (
     \r
     PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
     //\r
-    // Copy PCD Entries refereneced in PEI phase to PCD DATABASE\r
+    // Assign PCD Entries refereneced in PEI phase to PCD DATABASE\r
     //\r
-    CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));\r
+    mPcdDatabase.PeiDb = PeiDatabase;\r
   }\r
 \r
   //\r
-  // Copy PCD Entries with default value to PCD DATABASE\r
+  // Assign PCD Entries with default value to PCD DATABASE\r
+  //\r
+  mPcdDatabase.DxeDb = LocateExPcdBinary ();\r
+  ASSERT(mPcdDatabase.DxeDb != NULL);\r
+  PcdDxeDbLen = mPcdDatabase.DxeDb->Length + mPcdDatabase.DxeDb->UninitDataBaseSize;\r
+  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
+  //\r
+  // Initialized the external PCD database local variables\r
   //\r
-  CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));\r
+  mPeiLocalTokenCount     = mPcdDatabase.PeiDb->LocalTokenCount;\r
+  mDxeLocalTokenCount     = mPcdDatabase.DxeDb->LocalTokenCount;\r
+\r
+  mPeiExMapppingTableSize = mPcdDatabase.PeiDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);\r
+  mDxeExMapppingTableSize = mPcdDatabase.DxeDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);\r
+  mPeiGuidTableSize       = mPcdDatabase.PeiDb->GuidTableCount * sizeof(GUID);\r
+  mDxeGuidTableSize       = mPcdDatabase.DxeDb->GuidTableCount * sizeof (GUID);\r
+\r
+  mPcdTotalTokenCount     = mPeiLocalTokenCount + mDxeLocalTokenCount;\r
+  mPeiNexTokenCount       = mPeiLocalTokenCount - mPcdDatabase.PeiDb->ExTokenCount;\r
+  mDxeNexTokenCount       = mDxeLocalTokenCount - mPcdDatabase.DxeDb->ExTokenCount;  \r
+\r
+  mPeiExMapTableEmpty     = (mPcdDatabase.PeiDb->ExTokenCount == 0) ? TRUE : FALSE;\r
+  mDxeExMapTableEmpty     = (mPcdDatabase.DxeDb->ExTokenCount == 0) ? TRUE : FALSE;\r
+  mPeiDatabaseEmpty       = (mPeiLocalTokenCount == 0) ? TRUE : FALSE;\r
 \r
+  TmpTokenSpaceBufferCount = mPcdDatabase.PeiDb->ExTokenCount + mPcdDatabase.DxeDb->ExTokenCount;\r
+  TmpTokenSpaceBuffer     = (EFI_GUID **)AllocateZeroPool(TmpTokenSpaceBufferCount * sizeof (EFI_GUID *));\r
 \r
   //\r
   // Initialized the Callback Function Table\r
   //\r
-\r
-  mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));\r
+  mCallbackFnTable = AllocateZeroPool (mPcdTotalTokenCount * sizeof (LIST_ENTRY));\r
   ASSERT(mCallbackFnTable != NULL);\r
-  \r
+\r
+  //\r
   // EBC compiler is very choosy. It may report warning about comparison\r
   // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
-  for (Index = 0; Index + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Index++) {\r
+  //\r
+  for (Index = 0; Index + 1 < mPcdTotalTokenCount + 1; Index++) {\r
     InitializeListHead (&mCallbackFnTable[Index]);\r
   }\r
 }\r
@@ -568,29 +929,39 @@ GetSkuEnabledTokenNumber (
   SKU_ID                *SkuIdTable;\r
   INTN                  Index;\r
   UINT8                 *Value;\r
-  SKU_ID                *PhaseSkuIdTable;\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
+  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
-  PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :\r
-                              mPcdDatabase->DxeDb.Init.SkuIdTable;\r
-                              \r
-  SkuIdTable  = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];\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->PeiDb.Init.SystemSkuId == SkuIdTable[Index + 1]) {\r
+    if (mPcdDatabase.PeiDb->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
@@ -602,13 +973,17 @@ GetSkuEnabledTokenNumber (
       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);\r
+      return (UINT32) ((Value - PcdDb) | PCD_TYPE_DATA);\r
 \r
     default:\r
       ASSERT (FALSE);\r
@@ -714,7 +1089,6 @@ SetWorker (
   IN          BOOLEAN                 PtrType\r
   )\r
 {\r
-  UINT32              *LocalTokenNumberTable;\r
   BOOLEAN             IsPeiDb;\r
   UINT32              LocalTokenNumber;\r
   EFI_GUID            *GuidTable;\r
@@ -744,7 +1118,7 @@ SetWorker (
   // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
   //\r
-  ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
+  ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);\r
 \r
   if (PtrType) {\r
     //\r
@@ -766,8 +1140,8 @@ SetWorker (
   // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
   //\r
-  if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) ||\r
-      (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) {\r
+  if ((TokenNumber + 1 < mPeiNexTokenCount + 1) ||\r
+      (TokenNumber + 1 >= mPeiLocalTokenCount + 1 && TokenNumber + 1 < (mPeiLocalTokenCount + mDxeNexTokenCount + 1))) {\r
     InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
   }\r
 \r
@@ -781,33 +1155,18 @@ SetWorker (
   // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
   //\r
-  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);\r
+  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);\r
 \r
-  LocalTokenNumberTable  = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
-                                     mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
-\r
-  TokenNumber = IsPeiDb ? TokenNumber\r
-                        : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
-\r
-  LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
-  \r
-  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
-    if (PtrType) {\r
-      GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
-    } else {\r
-      MaxSize = *Size;\r
-    }\r
-    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
-  }\r
+  LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);\r
 \r
   Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
 \r
-  PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
+  PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);\r
 \r
   if (IsPeiDb) {\r
-    StringTable = (UINT8 *) (&mPcdDatabase->PeiDb.Init.StringTable[0]);\r
+    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);\r
   } else {\r
-    StringTable = (UINT8 *) (&mPcdDatabase->DxeDb.Init.StringTable[0]);\r
+    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);\r
   }\r
 \r
   \r
@@ -836,20 +1195,20 @@ SetWorker (
           break;\r
         }\r
       }\r
-      \r
+\r
       if (IsPeiDb) {\r
-        GuidTable = (EFI_GUID *) (&mPcdDatabase->PeiDb.Init.GuidTable[0]);\r
+        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);\r
       } else {\r
-        GuidTable = (EFI_GUID *) (&mPcdDatabase->DxeDb.Init.GuidTable[0]);\r
+        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);\r
       }\r
-                              \r
+\r
       VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
-      \r
+\r
       Guid = GuidTable + VariableHead->GuidTableIndex;\r
       Name = (UINT16*) (StringTable + VariableHead->StringIndex);\r
       VariableOffset = VariableHead->Offset;\r
       Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset);\r
-      \r
+\r
       if (EFI_NOT_FOUND == Status) {\r
         if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING))  {\r
           CopyMem (\r
@@ -954,7 +1313,7 @@ ExSetValueWorker (
 }\r
 \r
 /**\r
-  Set value for a dynamic PCD entry.\r
+  Set value for a dynamic-ex PCD entry.\r
   \r
   This routine find the local token number according to dynamic-ex PCD's token \r
   space guid and token number firstly, and invoke callback function if this PCD\r
@@ -1100,16 +1459,16 @@ SetHiiVariable (
 }\r
 \r
 /**\r
-  Get local token number according to dynamic-ex PCD's {token space guid:token number}\r
+  Get Token Number according to dynamic-ex PCD's {token space guid:token number}\r
 \r
   A dynamic-ex type PCD, developer must provide pair of token space guid: token number\r
   in DEC file. PCD database maintain a mapping table that translate pair of {token\r
-  space guid: token number} to local token number.\r
+  space guid: token number} to Token Number.\r
   \r
   @param Guid            Token space guid for dynamic-ex PCD entry.\r
   @param ExTokenNumber   Dynamic-ex PCD token number.\r
 \r
-  @return local token number for dynamic-ex PCD.\r
+  @return Token Number for dynamic-ex PCD.\r
 \r
 **/\r
 UINTN           \r
@@ -1124,29 +1483,29 @@ GetExPcdTokenNumber (
   EFI_GUID            *MatchGuid;\r
   UINTN               MatchGuidIdx;\r
 \r
-  if (!PEI_DATABASE_EMPTY) {\r
-    ExMap       = mPcdDatabase->PeiDb.Init.ExMapTable;\r
-    GuidTable   = mPcdDatabase->PeiDb.Init.GuidTable;\r
-    \r
-    MatchGuid   = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);\r
-    \r
+  if (!mPeiDatabaseEmpty) {\r
+    ExMap       = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset);\r
+    GuidTable   = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);\r
+\r
+    MatchGuid   = ScanGuid (GuidTable, mPeiGuidTableSize, Guid);\r
+\r
     if (MatchGuid != NULL) {\r
 \r
       MatchGuidIdx = MatchGuid - GuidTable;\r
-      \r
-      for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {\r
+\r
+      for (Index = 0; Index < mPeiExMapppingTableSize; Index++) {\r
         if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&\r
             (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {\r
-            return ExMap[Index].LocalTokenNumber;\r
+            return ExMap[Index].TokenNumber;\r
         }\r
       }\r
     }\r
   }\r
-  \r
-  ExMap       = mPcdDatabase->DxeDb.Init.ExMapTable;\r
-  GuidTable   = mPcdDatabase->DxeDb.Init.GuidTable;\r
 \r
-  MatchGuid   = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);\r
+  ExMap       = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset);\r
+  GuidTable   = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);\r
+\r
+  MatchGuid   = ScanGuid (GuidTable, mDxeGuidTableSize, Guid);\r
   //\r
   // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
   // error in the BUILD system.\r
@@ -1154,11 +1513,11 @@ GetExPcdTokenNumber (
   ASSERT (MatchGuid != NULL);\r
 \r
   MatchGuidIdx = MatchGuid - GuidTable;\r
-  \r
-  for (Index = 0; Index < DXE_EXMAPPING_TABLE_SIZE; Index++) {\r
+\r
+  for (Index = 0; Index < mDxeExMapppingTableSize; Index++) {\r
     if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&\r
          (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {\r
-        return ExMap[Index].LocalTokenNumber;\r
+        return ExMap[Index].TokenNumber;\r
     }\r
   }\r
 \r
@@ -1171,27 +1530,27 @@ GetExPcdTokenNumber (
   Get SKU ID table from PCD database.\r
 \r
   @param LocalTokenNumberTableIdx Index of local token number in token number table.\r
-  @param IsPeiPcd                 If TRUE, \r
-\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           IsPeiPcd\r
+  IN    BOOLEAN           IsPeiDb\r
   )\r
 {\r
   SKU_HEAD  *SkuHead;\r
   UINTN     LocalTokenNumber;\r
   UINT8     *Database;\r
 \r
-  if (IsPeiPcd) {\r
-    LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
-    Database         = (UINT8 *) &mPcdDatabase->PeiDb;\r
+  if (IsPeiDb) {\r
+    LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
+    Database         = (UINT8 *) mPcdDatabase.PeiDb;\r
   } else {\r
-    LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER];\r
-    Database         = (UINT8 *) &mPcdDatabase->DxeDb;\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
@@ -1224,9 +1583,9 @@ GetSizeTableIndex (
   SKU_ID *SkuIdTable;\r
   \r
   if (IsPeiDb) {\r
-    LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
+    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);\r
   } else {\r
-    LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
+    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
   }\r
 \r
   SizeTableIdx = 0;\r
@@ -1241,11 +1600,12 @@ GetSizeTableIndex (
       //\r
       if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {\r
           //\r
-          // We have only one entry for VPD enabled PCD entry:\r
+          // We have only two entry for VPD enabled PCD entry:\r
           // 1) MAX Size.\r
-          // We consider current size is equal to MAX size.\r
+          // 2) Current Size\r
+          // Current size is equal to MAX size.\r
           //\r
-          SizeTableIdx++;\r
+          SizeTableIdx += 2;\r
       } else {\r
         if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
           //\r
@@ -1297,16 +1657,16 @@ GetPtrTypeSize (
   // EBC compiler is very choosy. It may report warning about comparison\r
   // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
-  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);\r
 \r
 \r
   if (IsPeiDb) {\r
-    LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
-    SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;\r
+    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);\r
+    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);\r
   } else {\r
-    LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;\r
-    LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
-    SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;\r
+    LocalTokenNumberTableIdx -= mPeiLocalTokenCount;\r
+    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
+    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);\r
   }\r
 \r
   LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
@@ -1322,8 +1682,9 @@ GetPtrTypeSize (
   //\r
   if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {\r
       //\r
-      // We have only one entry for VPD enabled PCD entry:\r
+      // We have only two entry for VPD enabled PCD entry:\r
       // 1) MAX Size.\r
+      // 2) Current Size\r
       // We consider current size is equal to MAX size.\r
       //\r
       return *MaxSize;\r
@@ -1343,7 +1704,7 @@ GetPtrTypeSize (
       //\r
       SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
       for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
-        if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {\r
+        if (SkuIdTable[1 + Index] == mPcdDatabase.PeiDb->SystemSkuId) {\r
           return SizeTable[SizeTableIdx + 1 + Index];\r
         }\r
       }\r
@@ -1382,15 +1743,15 @@ SetPtrTypeSize (
   // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
   //\r
-  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);\r
 \r
   if (IsPeiDb) {\r
-    LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
-    SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;\r
+    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);\r
+    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);\r
   } else {\r
-    LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;\r
-    LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
-    SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;\r
+    LocalTokenNumberTableIdx -= mPeiLocalTokenCount;\r
+    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
+    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);\r
   }\r
 \r
   LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
@@ -1433,7 +1794,7 @@ SetPtrTypeSize (
       //\r
       SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
       for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
-        if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {\r
+        if (SkuIdTable[1 + Index] == mPcdDatabase.PeiDb->SystemSkuId) {\r
           SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;\r
           return TRUE;\r
         }\r