]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PCD/Pei/Service.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Pei / Service.c
index 5bc1dc8205f9d7d75518504b4f13b8aed527894c..0a570a4cbe9d6b553657d2a880fff9b0d741aea3 100644 (file)
   The driver internal functions are implmented here.\r
   They build Pei PCD database, and provide access service to PCD database.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "Service.h"\r
 \r
+/**\r
+  Get Local Token Number by Token Number.\r
+\r
+  @param[in]    Database    PCD database.\r
+  @param[in]    TokenNumber The PCD token number.\r
+\r
+  @return       Local Token Number.\r
+**/\r
+UINT32\r
+GetLocalTokenNumber (\r
+  IN PEI_PCD_DATABASE  *Database,\r
+  IN UINTN             TokenNumber\r
+  )\r
+{\r
+  UINT32  LocalTokenNumber;\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
+  LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);\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
+\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]    Database            PCD database.\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 PEI_PCD_DATABASE  *Database,\r
+  IN UINTN             TokenNumber\r
+  )\r
+{\r
+  UINT8           *StringTable;\r
+  UINTN           NameSize;\r
+  PCD_NAME_INDEX  *PcdNameIndex;\r
+  CHAR8           *TokenSpaceName;\r
+  CHAR8           *PcdName;\r
+  CHAR8           *Name;\r
+\r
+  //\r
+  // Return NULL when PCD name table is absent.\r
+  //\r
+  if (Database->PcdNameTableOffset == 0) {\r
+    return NULL;\r
+  }\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
+  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
+    NameSize = AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName);\r
+    Name     = AllocateZeroPool (NameSize);\r
+    ASSERT (Name != NULL);\r
+    //\r
+    // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.\r
+    //\r
+    AsciiStrCatS (Name, NameSize, TokenSpaceName);\r
+    Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';\r
+    AsciiStrCatS (Name, NameSize, 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]    Database    PCD database.\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        PEI_PCD_DATABASE  *Database,\r
+  IN CONST  EFI_GUID          *Guid,\r
+  IN        UINTN             TokenNumber,\r
+  OUT       EFI_PCD_INFO      *PcdInfo\r
+  )\r
+{\r
+  UINTN              GuidTableIdx;\r
+  EFI_GUID           *MatchGuid;\r
+  EFI_GUID           *GuidTable;\r
+  DYNAMICEX_MAPPING  *ExMapTable;\r
+  UINTN              Index;\r
+  UINT32             LocalTokenNumber;\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, Database, ExMapTable[Index].TokenNumber);\r
+        return EFI_SUCCESS;\r
+      } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {\r
+        PcdInfo->PcdSize = PeiPcdGetSize (ExMapTable[Index].TokenNumber);\r
+        LocalTokenNumber = GetLocalTokenNumber (Database, ExMapTable[Index].TokenNumber);\r
+        PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
+        PcdInfo->PcdName = GetPcdName (FALSE, Database, 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
+PeiGetPcdInfo (\r
+  IN CONST  EFI_GUID      *Guid,\r
+  IN        UINTN         TokenNumber,\r
+  OUT       EFI_PCD_INFO  *PcdInfo\r
+  )\r
+{\r
+  PEI_PCD_DATABASE  *PeiPcdDb;\r
+  BOOLEAN           PeiExMapTableEmpty;\r
+  UINTN             PeiNexTokenNumber;\r
+  UINT32            LocalTokenNumber;\r
+\r
+  ASSERT (PcdInfo != NULL);\r
+\r
+  PeiPcdDb          = GetPcdDatabase ();\r
+  PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
+\r
+  if (PeiPcdDb->ExTokenCount == 0) {\r
+    PeiExMapTableEmpty = TRUE;\r
+  } else {\r
+    PeiExMapTableEmpty = FALSE;\r
+  }\r
+\r
+  if (Guid == NULL) {\r
+    if (TokenNumber > PeiNexTokenNumber) {\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 = PeiPcdGetSize (TokenNumber);\r
+      LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber);\r
+      PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
+      PcdInfo->PcdName = GetPcdName (FALSE, PeiPcdDb, TokenNumber);\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    if (PeiExMapTableEmpty) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    return ExGetPcdInfo (\r
+             PeiPcdDb,\r
+             Guid,\r
+             TokenNumber,\r
+             PcdInfo\r
+             );\r
+  }\r
+}\r
+\r
 /**\r
   The function registers the CallBackOnSet fucntion\r
   according to TokenNumber and EFI_GUID space.\r
@@ -28,35 +296,45 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
   @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free\r
                                 slot left in the CallbackFnTable.\r
+  @retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found.\r
 **/\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
+  IN  UINTN             ExTokenNumber,\r
+  IN  CONST EFI_GUID    *Guid  OPTIONAL,\r
+  IN  PCD_PPI_CALLBACK  CallBackFunction,\r
+  IN  BOOLEAN           Register\r
+  )\r
 {\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
+  EFI_HOB_GUID_TYPE  *GuidHob;\r
+  PCD_PPI_CALLBACK   *CallbackTable;\r
+  PCD_PPI_CALLBACK   Compare;\r
+  PCD_PPI_CALLBACK   Assign;\r
+  UINT32             LocalTokenNumber;\r
+  UINT32             LocalTokenCount;\r
+  UINTN              PeiNexTokenNumber;\r
+  UINTN              TokenNumber;\r
+  UINTN              Idx;\r
+  PEI_PCD_DATABASE   *PeiPcdDb;\r
+\r
+  PeiPcdDb          = GetPcdDatabase ();\r
+  LocalTokenCount   = PeiPcdDb->LocalTokenCount;\r
+  PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
 \r
   if (Guid == NULL) {\r
     TokenNumber = ExTokenNumber;\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
-    ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1);\r
+    ASSERT (TokenNumber + 1 < (PeiNexTokenNumber + 1));\r
   } else {\r
     TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
+    if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
 \r
     //\r
     // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
@@ -65,13 +343,12 @@ PeiRegisterCallBackWorker (
     //\r
     TokenNumber--;\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
+    // between UINTN and 0 . So we add 1 in each size of the\r
     // comparison.\r
-    ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+    ASSERT ((TokenNumber + 1) < (LocalTokenCount + 1));\r
   }\r
 \r
-\r
-  LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];\r
+  LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber);\r
 \r
   //\r
   // We don't support SET for HII and VPD type PCD entry in PEI phase.\r
@@ -82,52 +359,98 @@ PeiRegisterCallBackWorker (
 \r
   GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);\r
   ASSERT (GuidHob != NULL);\r
-  \r
-  CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
-  CallbackTable = CallbackTable + (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
 \r
-  Compare = Register? NULL: CallBackFunction;\r
-  Assign  = Register? CallBackFunction: NULL;\r
+  CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
+  CallbackTable = CallbackTable + (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
 \r
+  Compare = Register ? NULL : CallBackFunction;\r
+  Assign  = Register ? CallBackFunction : NULL;\r
 \r
-  for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
+  for (Idx = 0; Idx < PcdGet32 (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
+  return Register ? EFI_OUT_OF_RESOURCES : EFI_INVALID_PARAMETER;\r
+}\r
+\r
+/**\r
+  Find the Pcd database.\r
+\r
+  @param  FileHandle  Handle of the file the external PCD database binary located.\r
 \r
+  @retval The base address of external PCD database binary.\r
+  @retval NULL         Return NULL if not find.\r
+**/\r
+VOID *\r
+LocateExPcdBinary (\r
+  IN EFI_PEI_FILE_HANDLE  FileHandle\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  VOID        *PcdDb;\r
+\r
+  PcdDb = NULL;\r
+\r
+  ASSERT (FileHandle != NULL);\r
+\r
+  Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Check the first bytes (Header Signature Guid) and build version.\r
+  //\r
+  if (!CompareGuid (PcdDb, &gPcdDataBaseSignatureGuid) ||\r
+      (((PEI_PCD_DATABASE *)PcdDb)->BuildVersion != PCD_SERVICE_PEIM_VERSION))\r
+  {\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+  return PcdDb;\r
 }\r
 \r
 /**\r
   The function builds the PCD database.\r
+\r
+  @param  FileHandle  Handle of the file the external PCD database binary located.\r
+\r
+  @return Pointer to PCD database.\r
 **/\r
-VOID\r
+PEI_PCD_DATABASE *\r
 BuildPcdDatabase (\r
-  VOID\r
+  IN EFI_PEI_FILE_HANDLE  FileHandle\r
   )\r
 {\r
   PEI_PCD_DATABASE  *Database;\r
+  PEI_PCD_DATABASE  *PeiPcdDbBinary;\r
   VOID              *CallbackFnTable;\r
   UINTN             SizeOfCallbackFnTable;\r
-  \r
-  Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));\r
 \r
-  ZeroMem (Database, sizeof (PEI_PCD_DATABASE));\r
+  //\r
+  // Locate the external PCD database binary for one section of current FFS\r
+  //\r
+  PeiPcdDbBinary = LocateExPcdBinary (FileHandle);\r
+\r
+  ASSERT (PeiPcdDbBinary != NULL);\r
+\r
+  Database = BuildGuidHob (&gPcdDataBaseHobGuid, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);\r
+\r
+  ZeroMem (Database, PeiPcdDbBinary->Length  + PeiPcdDbBinary->UninitDataBaseSize);\r
 \r
   //\r
-  // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE\r
+  // PeiPcdDbBinary is smaller than Database\r
   //\r
-  \r
-  CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));\r
+  CopyMem (Database, PeiPcdDbBinary, PeiPcdDbBinary->Length);\r
 \r
-  SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
+  SizeOfCallbackFnTable = Database->LocalTokenCount * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
 \r
   CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable);\r
-  \r
+\r
   ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
+\r
+  return Database;\r
 }\r
 \r
 /**\r
@@ -144,25 +467,25 @@ BuildPcdDatabase (
 **/\r
 EFI_STATUS\r
 GetHiiVariable (\r
-  IN  CONST EFI_GUID      *VariableGuid,\r
-  IN  UINT16              *VariableName,\r
-  OUT VOID                **VariableData,\r
-  OUT UINTN               *VariableSize\r
+  IN  CONST EFI_GUID  *VariableGuid,\r
+  IN  UINT16          *VariableName,\r
+  OUT VOID            **VariableData,\r
+  OUT UINTN           *VariableSize\r
   )\r
 {\r
-  UINTN      Size;\r
-  EFI_STATUS Status;\r
-  VOID       *Buffer;\r
-  EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;\r
+  UINTN                            Size;\r
+  EFI_STATUS                       Status;\r
+  VOID                             *Buffer;\r
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *VariablePpi;\r
 \r
-  Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
+  Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&VariablePpi);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  Size = 0;\r
+  Size   = 0;\r
   Status = VariablePpi->GetVariable (\r
                           VariablePpi,\r
                           VariableName,\r
-                          (EFI_GUID *) VariableGuid,\r
+                          (EFI_GUID *)VariableGuid,\r
                           NULL,\r
                           &Size,\r
                           NULL\r
@@ -173,13 +496,13 @@ GetHiiVariable (
     ASSERT_EFI_ERROR (Status);\r
 \r
     Status = VariablePpi->GetVariable (\r
-                              VariablePpi,\r
-                              (UINT16 *) VariableName,\r
-                              (EFI_GUID *) VariableGuid,\r
-                              NULL,\r
-                              &Size,\r
-                              Buffer\r
-                              );\r
+                            VariablePpi,\r
+                            (UINT16 *)VariableName,\r
+                            (EFI_GUID *)VariableGuid,\r
+                            NULL,\r
+                            &Size,\r
+                            Buffer\r
+                            );\r
     ASSERT_EFI_ERROR (Status);\r
 \r
     *VariableSize = Size;\r
@@ -192,68 +515,7 @@ GetHiiVariable (
 }\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
-\r
-  @return Token number according to system SKU ID.\r
-\r
-**/\r
-UINT32\r
-GetSkuEnabledTokenNumber (\r
-  UINT32 LocalTokenNumber,\r
-  UINTN  Size\r
-  ) \r
-{\r
-  PEI_PCD_DATABASE      *PeiPcdDb;\r
-  SKU_HEAD              *SkuHead;\r
-  SKU_ID                *SkuIdTable;\r
-  INTN                  Index;\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 (Index = 0; Index < SkuIdTable[0]; Index++) {\r
-    if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[Index + 1]) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
-    case PCD_TYPE_VPD:\r
-      Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);\r
-      return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);\r
-\r
-    case PCD_TYPE_HII:\r
-      Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);\r
-      return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);\r
-      \r
-    case PCD_TYPE_STRING:\r
-      Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);\r
-      return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);\r
-\r
-    case PCD_TYPE_DATA:\r
-      Value += Size * Index;\r
-      return (UINT32) (Value - (UINT8 *) PeiPcdDb);\r
-\r
-    default:\r
-      ASSERT (FALSE);\r
-  }\r
-\r
-  ASSERT (FALSE);\r
-\r
-  return 0;\r
-}\r
-\r
-/**\r
-  Invoke the callback function when dynamic PCD entry was set, if this PCD entry \r
+  Invoke the callback function when dynamic PCD entry was set, if this PCD entry\r
   has registered callback function.\r
 \r
   @param ExTokenNumber   DynamicEx PCD's token number, if this PCD entry is dyanmicEx\r
@@ -267,16 +529,18 @@ GetSkuEnabledTokenNumber (
 **/\r
 VOID\r
 InvokeCallbackOnSet (\r
-  UINTN             ExTokenNumber,\r
-  CONST EFI_GUID    *Guid, OPTIONAL\r
-  UINTN             TokenNumber,\r
-  VOID              *Data,\r
-  UINTN             Size\r
+  UINTN           ExTokenNumber,\r
+  CONST EFI_GUID  *Guid  OPTIONAL,\r
+  UINTN           TokenNumber,\r
+  VOID            *Data,\r
+  UINTN           Size\r
   )\r
 {\r
-  EFI_HOB_GUID_TYPE   *GuidHob;\r
-  PCD_PPI_CALLBACK    *CallbackTable;\r
-  UINTN               Idx;\r
+  EFI_HOB_GUID_TYPE  *GuidHob;\r
+  PCD_PPI_CALLBACK   *CallbackTable;\r
+  UINTN              Idx;\r
+  PEI_PCD_DATABASE   *PeiPcdDb;\r
+  UINT32             LocalTokenCount;\r
 \r
   //\r
   // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
@@ -284,28 +548,31 @@ InvokeCallbackOnSet (
   // as the array index.\r
   //\r
   TokenNumber--;\r
-  \r
+\r
+  PeiPcdDb        = GetPcdDatabase ();\r
+  LocalTokenCount = PeiPcdDb->LocalTokenCount;\r
+\r
   if (Guid == NULL) {\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
+    // between UINTN and 0 . So we add 1 in each size of the\r
     // comparison.\r
-    ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+    ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
   }\r
 \r
   GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);\r
   ASSERT (GuidHob != NULL);\r
-  \r
+\r
   CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
 \r
-  CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
+  CallbackTable += (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
 \r
-  for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
+  for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
     if (CallbackTable[Idx] != NULL) {\r
-      CallbackTable[Idx] (Guid,\r
-                          (Guid == NULL)? TokenNumber: ExTokenNumber,\r
-                          Data,\r
-                          Size\r
-                          );\r
+      CallbackTable[Idx](Guid,\r
+                         (Guid == NULL) ? (TokenNumber + 1) : ExTokenNumber,\r
+                         Data,\r
+                         Size\r
+                         );\r
     }\r
   }\r
 }\r
@@ -322,9 +589,9 @@ InvokeCallbackOnSet (
 **/\r
 EFI_STATUS\r
 SetValueWorker (\r
-  IN          UINTN              TokenNumber,\r
-  IN          VOID               *Data,\r
-  IN          UINTN              Size\r
+  IN          UINTN  TokenNumber,\r
+  IN          VOID   *Data,\r
+  IN          UINTN  Size\r
   )\r
 {\r
   return SetWorker (TokenNumber, Data, &Size, FALSE);\r
@@ -341,47 +608,59 @@ SetValueWorker (
 \r
   @retval EFI_INVALID_PARAMETER  If this PCD type is VPD, VPD PCD can not be set.\r
   @retval EFI_INVALID_PARAMETER  If Size can not be set to size table.\r
+  @retval EFI_INVALID_PARAMETER  If Size of non-Ptr type PCD does not match the size information in PCD database.\r
   @retval EFI_NOT_FOUND          If value type of PCD entry is intergrate, but not in\r
                                  range of UINT8, UINT16, UINT32, UINT64\r
-  @retval EFI_NOT_FOUND          Can not find the PCD type according to token number.                                \r
+  @retval EFI_NOT_FOUND          Can not find the PCD type according to token number.\r
 **/\r
 EFI_STATUS\r
 SetWorker (\r
-  IN          UINTN               TokenNumber,\r
-  IN          VOID                *Data,\r
-  IN OUT      UINTN               *Size,\r
-  IN          BOOLEAN             PtrType\r
+  IN          UINTN    TokenNumber,\r
+  IN          VOID     *Data,\r
+  IN OUT      UINTN    *Size,\r
+  IN          BOOLEAN  PtrType\r
   )\r
 {\r
-  UINT32              LocalTokenNumber;\r
-  PEI_PCD_DATABASE    *PeiPcdDb;\r
-  UINT16              StringTableIdx;\r
-  UINTN               Offset;\r
-  VOID                *InternalData;\r
-  UINTN               MaxSize;\r
-\r
-  if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) {\r
+  UINT32            LocalTokenNumber;\r
+  UINTN             PeiNexTokenNumber;\r
+  PEI_PCD_DATABASE  *PeiPcdDb;\r
+  STRING_HEAD       StringTableIdx;\r
+  UINTN             Offset;\r
+  VOID              *InternalData;\r
+  UINTN             MaxSize;\r
+  UINT32            LocalTokenCount;\r
+\r
+  if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
-  \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
+  PeiPcdDb        = GetPcdDatabase ();\r
+  LocalTokenCount = PeiPcdDb->LocalTokenCount;\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
+  // between UINTN and 0 . So we add 1 in each size of the\r
   // comparison.\r
-  ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
-    \r
-  PeiPcdDb = GetPcdDatabase ();\r
-\r
-  LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
+  ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
 \r
-  if (!PtrType) {\r
-    ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);\r
+  if (PtrType) {\r
+    //\r
+    // Get MaxSize first, then check new size with max buffer size.\r
+    //\r
+    GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
+    if (*Size > MaxSize) {\r
+      *Size = MaxSize;\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  } else {\r
+    if (*Size != PeiPcdGetSize (TokenNumber + 1)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
   }\r
 \r
   //\r
@@ -389,25 +668,20 @@ SetWorker (
   // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r
   // type PCD entry in ExSetWorker.\r
   //\r
-  if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {\r
+  PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
+  if (TokenNumber + 1 < PeiNexTokenNumber + 1) {\r
     InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
   }\r
 \r
-  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
-    if (PtrType) {\r
-      MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
-    } else {\r
-      MaxSize = *Size;\r
-    }\r
-    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
-  }\r
+  LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);\r
+\r
+  Offset       = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+  InternalData = (VOID *)((UINT8 *)PeiPcdDb + Offset);\r
 \r
-  Offset          = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
-  InternalData    = (VOID *) ((UINT8 *) PeiPcdDb + Offset);\r
-  \r
   switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
     case PCD_TYPE_VPD:\r
     case PCD_TYPE_HII:\r
+    case PCD_TYPE_HII|PCD_TYPE_STRING:\r
     {\r
       ASSERT (FALSE);\r
       return EFI_INVALID_PARAMETER;\r
@@ -415,8 +689,8 @@ SetWorker (
 \r
     case PCD_TYPE_STRING:\r
       if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
-        StringTableIdx = *((UINT16 *)InternalData);\r
-        CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);\r
+        StringTableIdx = *((STRING_HEAD *)InternalData);\r
+        CopyMem ((UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset + StringTableIdx, Data, *Size);\r
         return EFI_SUCCESS;\r
       } else {\r
         return EFI_INVALID_PARAMETER;\r
@@ -434,20 +708,20 @@ SetWorker (
       }\r
 \r
       switch (*Size) {\r
-        case sizeof(UINT8):\r
-          *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
+        case sizeof (UINT8):\r
+          *((UINT8 *)InternalData) = *((UINT8 *)Data);\r
           return EFI_SUCCESS;\r
 \r
-        case sizeof(UINT16):\r
-          *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
+        case sizeof (UINT16):\r
+          *((UINT16 *)InternalData) = *((UINT16 *)Data);\r
           return EFI_SUCCESS;\r
 \r
-        case sizeof(UINT32):\r
-          *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
+        case sizeof (UINT32):\r
+          *((UINT32 *)InternalData) = *((UINT32 *)Data);\r
           return EFI_SUCCESS;\r
 \r
-        case sizeof(UINT64):\r
-          *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
+        case sizeof (UINT64):\r
+          *((UINT64 *)InternalData) = *((UINT64 *)Data);\r
           return EFI_SUCCESS;\r
 \r
         default:\r
@@ -455,12 +729,10 @@ SetWorker (
           return EFI_NOT_FOUND;\r
       }\r
     }\r
-      \r
   }\r
 \r
   ASSERT (FALSE);\r
   return EFI_NOT_FOUND;\r
-\r
 }\r
 \r
 /**\r
@@ -476,23 +748,23 @@ SetWorker (
 **/\r
 EFI_STATUS\r
 ExSetValueWorker (\r
-  IN          UINTN                ExTokenNumber,\r
-  IN          CONST EFI_GUID       *Guid,\r
-  IN          VOID                 *Data,\r
-  IN          UINTN                Size\r
+  IN          UINTN           ExTokenNumber,\r
+  IN          CONST EFI_GUID  *Guid,\r
+  IN          VOID            *Data,\r
+  IN          UINTN           Size\r
   )\r
 {\r
   return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r
 }\r
 \r
 /**\r
-  Set value for a dynamic PCD entry.\r
-  \r
-  This routine find the local token number according to dynamic-ex PCD's token \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
   entry registered callback function. Finally, invoken general SetWorker to set\r
   PCD value.\r
-  \r
+\r
   @param ExTokenNumber   Dynamic-ex PCD token number.\r
   @param Guid            Token space guid for dynamic-ex PCD.\r
   @param Data            PCD value want to be set\r
@@ -505,25 +777,27 @@ ExSetValueWorker (
 **/\r
 EFI_STATUS\r
 ExSetWorker (\r
-  IN            UINTN                ExTokenNumber,\r
-  IN            CONST EFI_GUID       *Guid,\r
-  IN            VOID                 *Data,\r
-  IN OUT        UINTN                *Size,\r
-  IN            BOOLEAN              PtrType\r
+  IN            UINTN           ExTokenNumber,\r
+  IN            CONST EFI_GUID  *Guid,\r
+  IN            VOID            *Data,\r
+  IN OUT        UINTN           *Size,\r
+  IN            BOOLEAN         PtrType\r
   )\r
 {\r
-  UINTN                     TokenNumber;\r
+  UINTN  TokenNumber;\r
 \r
-  if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) {\r
+  if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
   TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
+  if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 \r
   InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r
 \r
   return SetWorker (TokenNumber, Data, Size, PtrType);\r
-\r
 }\r
 \r
 /**\r
@@ -542,16 +816,16 @@ ExGetWorker (
   IN UINTN            ExTokenNumber,\r
   IN UINTN            GetSize\r
   )\r
-{ \r
+{\r
   return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
 }\r
 \r
 /**\r
   Get the PCD entry pointer in PCD database.\r
-  \r
+\r
   This routine will visit PCD database to find the PCD entry according to given\r
-  token number. The given token number is autogened by build tools and it will be \r
-  translated to local token number. Local token number contains PCD's type and \r
+  token number. The given token number is autogened by build tools and it will be\r
+  translated to local token number. Local token number contains PCD's type and\r
   offset of PCD entry in PCD database.\r
 \r
   @param TokenNumber     Token's number, it is autogened by build tools\r
@@ -562,22 +836,24 @@ ExGetWorker (
 **/\r
 VOID *\r
 GetWorker (\r
-  IN UINTN               TokenNumber,\r
-  IN UINTN               GetSize\r
+  IN UINTN  TokenNumber,\r
+  IN UINTN  GetSize\r
   )\r
 {\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
-  PEI_PCD_DATABASE    *PeiPcdDb;\r
-  UINT32              LocalTokenNumber;\r
-  UINTN               MaxSize;\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
+  UINT8             *StringTable;\r
+  STRING_HEAD       StringTableIdx;\r
+  PEI_PCD_DATABASE  *PeiPcdDb;\r
+  UINT32            LocalTokenNumber;\r
+  UINT32            LocalTokenCount;\r
+  UINT8             *VaraiableDefaultBuffer;\r
+  UINTN             VpdBaseAddress;\r
 \r
   //\r
   // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
@@ -586,125 +862,152 @@ GetWorker (
   //\r
   TokenNumber--;\r
 \r
+  PeiPcdDb        = GetPcdDatabase ();\r
+  LocalTokenCount = PeiPcdDb->LocalTokenCount;\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
+  // between UINTN and 0 . So we add 1 in each size of the\r
   // comparison.\r
-  ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+  ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
 \r
-  ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));\r
-\r
-  PeiPcdDb        = GetPcdDatabase ();\r
+  ASSERT ((GetSize == PeiPcdGetSize (TokenNumber + 1)) || (GetSize == 0));\r
 \r
-  LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
-\r
-  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
-    if (GetSize == 0) {\r
-      MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
-    } else {\r
-      MaxSize = GetSize;\r
-    }\r
-    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
-  }\r
+  LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);\r
 \r
   Offset      = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
-  StringTable = PeiPcdDb->Init.StringTable;\r
-  \r
+  StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset;\r
+\r
   switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
     case PCD_TYPE_VPD:\r
     {\r
-      VPD_HEAD *VpdHead;\r
-      VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
-      return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
+      VPD_HEAD  *VpdHead;\r
+      VpdHead = (VPD_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r
+\r
+      //\r
+      // PcdVpdBaseAddress64 is DynamicEx PCD only. So, PeiPcdGet64Ex() is used to get its value.\r
+      //\r
+      VpdBaseAddress = (UINTN)PeiPcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdVpdBaseAddress64));\r
+      if (VpdBaseAddress == 0) {\r
+        //\r
+        // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress.\r
+        //\r
+        VpdBaseAddress = (UINTN)PcdGet32 (PcdVpdBaseAddress);\r
+      }\r
+\r
+      ASSERT (VpdBaseAddress != 0);\r
+      return (VOID *)(VpdBaseAddress + VpdHead->Offset);\r
     }\r
-      \r
+\r
+    case PCD_TYPE_HII|PCD_TYPE_STRING:\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
+      VariableHead = (VARIABLE_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r
 \r
-      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
+      Guid = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex;\r
+      Name = (UINT16 *)&StringTable[VariableHead->StringIndex];\r
 \r
-      if (Status == EFI_SUCCESS) {\r
-        return (VOID *) ((UINT8 *) Data + VariableHead->Offset);\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
+        VaraiableDefaultBuffer = (UINT8 *)&StringTable[*(STRING_HEAD *)((UINT8 *)PeiPcdDb + VariableHead->DefaultValueOffset)];\r
       } else {\r
+        VaraiableDefaultBuffer = (UINT8 *)PeiPcdDb + VariableHead->DefaultValueOffset;\r
+      }\r
+\r
+      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
+      if ((Status == EFI_SUCCESS) && (DataSize >= (VariableHead->Offset + GetSize))) {\r
+        if (GetSize == 0) {\r
+          //\r
+          // It is a pointer type. So get the MaxSize reserved for\r
+          // this PCD entry.\r
+          //\r
+          GetPtrTypeSize (TokenNumber, &GetSize, PeiPcdDb);\r
+          if (GetSize > (DataSize - VariableHead->Offset)) {\r
+            //\r
+            // Use actual valid size.\r
+            //\r
+            GetSize = DataSize - VariableHead->Offset;\r
+          }\r
+        }\r
+\r
         //\r
-        // Return the default value specified by Platform Integrator \r
+        // If the operation is successful, we copy the data\r
+        // to the default value buffer in the PCD Database.\r
         //\r
-        return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);\r
+        CopyMem (VaraiableDefaultBuffer, (UINT8 *)Data + VariableHead->Offset, GetSize);\r
       }\r
+\r
+      return (VOID *)VaraiableDefaultBuffer;\r
     }\r
 \r
     case PCD_TYPE_DATA:\r
-      return (VOID *) ((UINT8 *)PeiPcdDb + Offset);\r
+      return (VOID *)((UINT8 *)PeiPcdDb + Offset);\r
 \r
     case PCD_TYPE_STRING:\r
-      StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);\r
-      return (VOID *) (&StringTable[StringTableIdx]);\r
+      StringTableIdx = *(STRING_HEAD *)((UINT8 *)PeiPcdDb + Offset);\r
+      return (VOID *)(&StringTable[StringTableIdx]);\r
 \r
     default:\r
       ASSERT (FALSE);\r
       break;\r
-      \r
   }\r
 \r
   ASSERT (FALSE);\r
-      \r
+\r
   return NULL;\r
-  \r
 }\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
-  \r
+  space guid: token number} to Token Number.\r
+\r
   @param Guid            Token space guid for dynamic-ex PCD entry.\r
-  @param ExTokenNumber   EDES_TODO: Add parameter description\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
+UINTN\r
 GetExPcdTokenNumber (\r
-  IN CONST EFI_GUID             *Guid,\r
-  IN UINTN                      ExTokenNumber\r
+  IN CONST EFI_GUID  *Guid,\r
+  IN UINTN           ExTokenNumber\r
   )\r
 {\r
-  UINT32              Index;\r
-  DYNAMICEX_MAPPING   *ExMap;\r
-  EFI_GUID            *GuidTable;\r
-  EFI_GUID            *MatchGuid;\r
-  UINTN               MatchGuidIdx;\r
-  PEI_PCD_DATABASE    *PeiPcdDb;\r
-\r
-  PeiPcdDb    = GetPcdDatabase();\r
-  \r
-  ExMap       = PeiPcdDb->Init.ExMapTable;\r
-  GuidTable   = PeiPcdDb->Init.GuidTable;\r
-\r
-  MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
+  UINT32             Index;\r
+  DYNAMICEX_MAPPING  *ExMap;\r
+  EFI_GUID           *GuidTable;\r
+  EFI_GUID           *MatchGuid;\r
+  UINTN              MatchGuidIdx;\r
+  PEI_PCD_DATABASE   *PeiPcdDb;\r
+\r
+  PeiPcdDb = GetPcdDatabase ();\r
+\r
+  ExMap     = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);\r
+  GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);\r
+\r
+  MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof (EFI_GUID), 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
   //\r
   ASSERT (MatchGuid != NULL);\r
-  \r
+\r
   MatchGuidIdx = MatchGuid - GuidTable;\r
-  \r
-  for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {\r
-    if ((ExTokenNumber == ExMap[Index].ExTokenNumber) && \r
-        (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {\r
-      return ExMap[Index].LocalTokenNumber;\r
+\r
+  for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {\r
+    if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&\r
+        (MatchGuidIdx == ExMap[Index].ExGuidIndex))\r
+    {\r
+      return ExMap[Index].TokenNumber;\r
     }\r
   }\r
-  \r
-  ASSERT (FALSE);\r
-  \r
-  return 0;\r
+\r
+  return PCD_INVALID_TOKEN_NUMBER;\r
 }\r
 \r
 /**\r
@@ -718,40 +1021,12 @@ GetPcdDatabase (
   VOID\r
   )\r
 {\r
-  EFI_HOB_GUID_TYPE *GuidHob;\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
-/**\r
-  Get SKU ID tabble from PCD database.\r
-\r
-  @param LocalTokenNumberTableIdx Index of local token number in token number table.\r
-  @param Database                 PCD database.\r
-\r
-  @return Pointer to SKU ID array table\r
-\r
-**/\r
-SKU_ID *\r
-GetSkuIdArray (\r
-  IN    UINTN             LocalTokenNumberTableIdx,\r
-  IN    PEI_PCD_DATABASE  *Database\r
-  )\r
-{\r
-  SKU_HEAD *SkuHead;\r
-  UINTN     LocalTokenNumber;\r
 \r
-  LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\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 *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);\r
-  \r
+  return (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob);\r
 }\r
 \r
 /**\r
@@ -769,48 +1044,37 @@ GetSizeTableIndex (
   IN    PEI_PCD_DATABASE  *Database\r
   )\r
 {\r
-  UINTN       Index;\r
-  UINTN        SizeTableIdx;\r
-  UINTN       LocalTokenNumber;\r
-  SKU_ID      *SkuIdTable;\r
-  \r
+  UINTN  Index;\r
+  UINTN  SizeTableIdx;\r
+  UINTN  LocalTokenNumber;\r
+\r
   SizeTableIdx = 0;\r
 \r
-  for (Index=0; Index<LocalTokenNumberTableIdx; Index++) {\r
-    LocalTokenNumber = Database->Init.LocalTokenNumberTable[Index];\r
+  for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {\r
+    LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + Index);\r
 \r
     if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
       //\r
-      // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
+      // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type\r
       // PCD entry.\r
       //\r
       if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {\r
-          //\r
-          // We have only one entry for VPD enabled PCD entry:\r
-          // 1) MAX Size.\r
-          // We consider current size is equal to MAX size.\r
-          //\r
-          SizeTableIdx++;\r
+        //\r
+        // We have only two entry for VPD enabled PCD entry:\r
+        // 1) MAX Size.\r
+        // 2) Current Size\r
+        // Current size is equal to MAX size.\r
+        //\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, Database);\r
-          SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
-        }\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
       }\r
     }\r
-\r
   }\r
 \r
   return SizeTableIdx;\r