]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PCD/Dxe/Service.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Dxe / Service.c
index 43a3bda7760d45ecc165da430164a5d63321f24f..5ade8d988bacc17c37f735a8f71288e54c47d861 100644 (file)
@@ -1,39 +1,40 @@
 /** @file\r
     Help functions used by PCD DXE driver.\r
 \r
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
-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) 2014, Hewlett-Packard Development Company, L.P.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016-2021 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\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
-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
+BOOLEAN  mPeiExMapTableEmpty;\r
+BOOLEAN  mDxeExMapTableEmpty;\r
+BOOLEAN  mPeiDatabaseEmpty;\r
 \r
-BOOLEAN        mPeiExMapTableEmpty; \r
-BOOLEAN        mDxeExMapTableEmpty; \r
-BOOLEAN        mPeiDatabaseEmpty;\r
+LIST_ENTRY  *mCallbackFnTable;\r
+EFI_GUID    **TmpTokenSpaceBuffer;\r
+UINTN       TmpTokenSpaceBufferCount;\r
 \r
-LIST_ENTRY    *mCallbackFnTable;\r
-EFI_GUID     **TmpTokenSpaceBuffer;\r
-UINTN          TmpTokenSpaceBufferCount; \r
+UINTN             mPeiPcdDbSize    = 0;\r
+PEI_PCD_DATABASE  *mPeiPcdDbBinary = NULL;\r
+UINTN             mDxePcdDbSize    = 0;\r
+DXE_PCD_DATABASE  *mDxePcdDbBinary = NULL;\r
 \r
 /**\r
   Get Local Token Number by Token Number.\r
@@ -46,14 +47,11 @@ UINTN          TmpTokenSpaceBufferCount;
 **/\r
 UINT32\r
 GetLocalTokenNumber (\r
-  IN BOOLEAN            IsPeiDb,\r
-  IN UINTN              TokenNumber\r
+  IN BOOLEAN  IsPeiDb,\r
+  IN UINTN    TokenNumber\r
   )\r
 {\r
-  UINT32                *LocalTokenNumberTable;\r
-  UINT32                LocalTokenNumber;\r
-  UINTN                 Size;\r
-  UINTN                 MaxSize;\r
+  UINT32  *LocalTokenNumberTable;\r
 \r
   //\r
   // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
@@ -62,24 +60,11 @@ GetLocalTokenNumber (
   //\r
   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 (TokenNumber, &MaxSize);\r
-    } else {\r
-      MaxSize = Size;\r
-    }\r
-    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\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
-  return LocalTokenNumber;\r
+  return LocalTokenNumberTable[TokenNumber];\r
 }\r
 \r
 /**\r
@@ -91,18 +76,19 @@ GetLocalTokenNumber (
 **/\r
 EFI_PCD_TYPE\r
 GetPcdType (\r
-  IN UINT32             LocalTokenNumber\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) {\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
@@ -128,17 +114,31 @@ GetPcdType (
 **/\r
 CHAR8 *\r
 GetPcdName (\r
-  IN BOOLEAN            OnlyTokenSpaceName,\r
-  IN BOOLEAN            IsPeiDb,\r
-  IN UINTN              TokenNumber\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
+  PCD_DATABASE_INIT  *Database;\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 (IsPeiDb) {\r
+    if (mPcdDatabase.PeiDb->PcdNameTableOffset == 0) {\r
+      return NULL;\r
+    }\r
+  } else {\r
+    if (mPcdDatabase.DxeDb->PcdNameTableOffset == 0) {\r
+      return NULL;\r
+    }\r
+  }\r
 \r
   //\r
   // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
@@ -147,17 +147,17 @@ GetPcdName (
   //\r
   TokenNumber--;\r
 \r
-  Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;\r
+  Database    = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb;\r
   TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;\r
 \r
-  StringTable = (UINT8 *) Database + Database->StringTableOffset;\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
+  PcdNameIndex   = (PCD_NAME_INDEX *)((UINT8 *)Database + Database->PcdNameTableOffset) + TokenNumber;\r
   TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];\r
-  PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];\r
+  PcdName        = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];\r
 \r
   if (OnlyTokenSpaceName) {\r
     //\r
@@ -168,13 +168,15 @@ GetPcdName (
     //\r
     // Need to get the full PCD name.\r
     //\r
-    Name = AllocateZeroPool (AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName));\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
-    AsciiStrCat (Name, TokenSpaceName);\r
+    AsciiStrCatS (Name, NameSize, TokenSpaceName);\r
     Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';\r
-    AsciiStrCat (Name, PcdName);  \r
+    AsciiStrCatS (Name, NameSize, PcdName);\r
   }\r
 \r
   return Name;\r
@@ -191,31 +193,31 @@ GetPcdName (
   @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
+                            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
+  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
+  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
+  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
+  MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof (EFI_GUID), Guid);\r
 \r
   if (MatchGuid == NULL) {\r
     return EFI_NOT_FOUND;\r
@@ -240,7 +242,7 @@ ExGetPcdInfo (
         PcdInfo->PcdSize = 0;\r
         //\r
         // Here use one representative in the token space to get the TokenSpaceCName.\r
-        // \r
+        //\r
         PcdInfo->PcdName = GetPcdName (TRUE, IsPeiDb, ExMapTable[Index].TokenNumber);\r
         return EFI_SUCCESS;\r
       } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {\r
@@ -272,30 +274,27 @@ ExGetPcdInfo (
 **/\r
 EFI_STATUS\r
 DxeGetPcdInfo (\r
-  IN CONST  EFI_GUID        *Guid,\r
-  IN        UINTN           TokenNumber,\r
-  OUT       EFI_PCD_INFO    *PcdInfo\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
-  if (!FeaturePcdGet (PcdPcdInfoGeneration)) {\r
-    return EFI_UNSUPPORTED;\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
+  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
+        ((TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1))))\r
+    {\r
       return EFI_NOT_FOUND;\r
     } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
       //\r
@@ -307,14 +306,16 @@ DxeGetPcdInfo (
       PcdInfo->PcdName = NULL;\r
     } else {\r
       PcdInfo->PcdSize = DxePcdGetSize (TokenNumber);\r
-      IsPeiDb = FALSE;\r
+      IsPeiDb          = FALSE;\r
       if ((TokenNumber + 1 <= mPeiNexTokenCount + 1)) {\r
         IsPeiDb = TRUE;\r
       }\r
+\r
       LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);\r
       PcdInfo->PcdType = GetPcdType (LocalTokenNumber);\r
       PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, TokenNumber);\r
     }\r
+\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -349,10 +350,10 @@ DxeGetPcdInfo (
 \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
@@ -363,27 +364,27 @@ DxeGetPcdInfo (
 **/\r
 VOID *\r
 GetWorker (\r
-  IN UINTN             TokenNumber,\r
-  IN UINTN             GetSize\r
+  IN UINTN  TokenNumber,\r
+  IN UINTN  GetSize\r
   )\r
 {\r
-  EFI_GUID            *GuidTable;\r
-  UINT8               *StringTable;\r
-  EFI_GUID            *Guid;\r
-  UINT16              *Name;\r
-  VARIABLE_HEAD       *VariableHead;\r
-  UINT8               *VaraiableDefaultBuffer;\r
-  UINT8               *Data;\r
-  VPD_HEAD            *VpdHead;\r
-  UINT8               *PcdDb;\r
-  VOID                *RetPtr;\r
-  UINTN               TmpTokenNumber;\r
-  UINTN               DataSize;\r
-  EFI_STATUS          Status;\r
-  UINT32              LocalTokenNumber;\r
-  UINT32              Offset;\r
-  STRING_HEAD         StringTableIdx;      \r
-  BOOLEAN             IsPeiDb;\r
+  EFI_GUID       *GuidTable;\r
+  UINT8          *StringTable;\r
+  EFI_GUID       *Guid;\r
+  UINT16         *Name;\r
+  VARIABLE_HEAD  *VariableHead;\r
+  UINT8          *VaraiableDefaultBuffer;\r
+  UINT8          *Data;\r
+  VPD_HEAD       *VpdHead;\r
+  UINT8          *PcdDb;\r
+  VOID           *RetPtr;\r
+  UINTN          TmpTokenNumber;\r
+  UINTN          DataSize;\r
+  EFI_STATUS     Status;\r
+  UINT32         LocalTokenNumber;\r
+  UINT32         Offset;\r
+  STRING_HEAD    StringTableIdx;\r
+  BOOLEAN        IsPeiDb;\r
 \r
   //\r
   // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
@@ -404,7 +405,7 @@ GetWorker (
 \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
   //\r
   ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);\r
@@ -412,91 +413,101 @@ GetWorker (
   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
+  // between UINTN and 0 . So we add 1 in each size of the\r
   // comparison.\r
-  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);\r
+  IsPeiDb = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);\r
 \r
   LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);\r
 \r
-  PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);\r
-                                    \r
+  PcdDb = IsPeiDb ? ((UINT8 *)mPcdDatabase.PeiDb) : ((UINT8 *)mPcdDatabase.DxeDb);\r
+\r
   if (IsPeiDb) {\r
-    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);\r
+    StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);\r
   } else {\r
-    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);\r
+    StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);\r
   }\r
 \r
-\r
-  Offset     = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+  Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\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
+      VpdHead = (VPD_HEAD *)((UINT8 *)PcdDb + Offset);\r
+      ASSERT (mVpdBaseAddress != 0);\r
+      RetPtr = (VOID *)(mVpdBaseAddress + VpdHead->Offset);\r
 \r
       break;\r
 \r
     case PCD_TYPE_HII|PCD_TYPE_STRING:\r
     case PCD_TYPE_HII:\r
       if (IsPeiDb) {\r
-        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);\r
+        GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);\r
       } else {\r
-        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);\r
+        GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);\r
       }\r
 \r
-      VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
-      Guid = GuidTable + VariableHead->GuidTableIndex;\r
-      Name = (UINT16*)(StringTable + VariableHead->StringIndex);\r
+      VariableHead = (VARIABLE_HEAD *)(PcdDb + Offset);\r
+      Guid         = GuidTable + VariableHead->GuidTableIndex;\r
+      Name         = (UINT16 *)(StringTable + VariableHead->StringIndex);\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
+        // 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
+        StringTableIdx         = *(STRING_HEAD *)((UINT8 *)PcdDb + VariableHead->DefaultValueOffset);\r
+        VaraiableDefaultBuffer = (UINT8 *)(StringTable + StringTableIdx);\r
       } else {\r
-        VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;\r
+        VaraiableDefaultBuffer = (UINT8 *)PcdDb + VariableHead->DefaultValueOffset;\r
       }\r
+\r
       Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
       if (Status == EFI_SUCCESS) {\r
-        if (GetSize == 0) {\r
+        if (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 (TmpTokenNumber, &GetSize);\r
+            if (GetSize > (DataSize - VariableHead->Offset)) {\r
+              //\r
+              // Use actual valid size.\r
+              //\r
+              GetSize = DataSize - VariableHead->Offset;\r
+            }\r
+          }\r
+\r
           //\r
-          // It is a pointer type. So get the MaxSize reserved for\r
-          // this PCD entry.\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
-          GetPtrTypeSize (TmpTokenNumber, &GetSize);\r
+          CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, 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
+\r
         FreePool (Data);\r
       }\r
-      RetPtr = (VOID *) VaraiableDefaultBuffer;\r
+\r
+      RetPtr = (VOID *)VaraiableDefaultBuffer;\r
       break;\r
 \r
     case PCD_TYPE_STRING:\r
-      StringTableIdx = *(STRING_HEAD*)((UINT8 *) PcdDb + Offset);\r
-      RetPtr = (VOID *) (StringTable + StringTableIdx);\r
+      StringTableIdx = *(STRING_HEAD *)((UINT8 *)PcdDb + Offset);\r
+      RetPtr         = (VOID *)(StringTable + StringTableIdx);\r
       break;\r
 \r
     case PCD_TYPE_DATA:\r
-      RetPtr = (VOID *) ((UINT8 *) PcdDb + Offset);\r
+      RetPtr = (VOID *)((UINT8 *)PcdDb + Offset);\r
       break;\r
 \r
     default:\r
       ASSERT (FALSE);\r
       break;\r
-      \r
   }\r
 \r
   EfiReleaseLock (&mPcdDatabaseLock);\r
 \r
   return RetPtr;\r
-\r
 }\r
 \r
 /**\r
@@ -504,9 +515,9 @@ GetWorker (
 \r
   This routine will register a callback function to a PCD entry by given token number\r
   and token space guid.\r
-  \r
+\r
   @param TokenNumber        PCD token's number, it is autogened by build tools.\r
-  @param Guid               PCD token space's guid, \r
+  @param Guid               PCD token space's guid,\r
                             if not NULL, this PCD is dynamicEx type PCD.\r
   @param CallBackFunction   Callback function pointer\r
 \r
@@ -515,17 +526,17 @@ GetWorker (
 **/\r
 EFI_STATUS\r
 DxeRegisterCallBackWorker (\r
-  IN  UINTN                   TokenNumber,\r
-  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
-  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction\r
-)\r
+  IN  UINTN                  TokenNumber,\r
+  IN  CONST EFI_GUID         *Guid  OPTIONAL,\r
+  IN  PCD_PROTOCOL_CALLBACK  CallBackFunction\r
+  )\r
 {\r
-  CALLBACK_FN_ENTRY       *FnTableEntry;\r
-  LIST_ENTRY              *ListHead;\r
-  LIST_ENTRY              *ListNode;\r
+  CALLBACK_FN_ENTRY  *FnTableEntry;\r
+  LIST_ENTRY         *ListHead;\r
+  LIST_ENTRY         *ListNode;\r
 \r
   if (Guid != NULL) {\r
-    TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
+    TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)TokenNumber);\r
   }\r
 \r
   //\r
@@ -537,7 +548,7 @@ DxeRegisterCallBackWorker (
   ListNode = GetFirstNode (ListHead);\r
 \r
   while (ListNode != ListHead) {\r
-    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
+    FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node);\r
 \r
     if (FnTableEntry->CallbackFn == CallBackFunction) {\r
       //\r
@@ -546,15 +557,16 @@ DxeRegisterCallBackWorker (
       //\r
       return EFI_SUCCESS;\r
     }\r
+\r
     ListNode = GetNextNode (ListHead, ListNode);\r
   }\r
 \r
-  FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY));\r
+  FnTableEntry = AllocatePool (sizeof (CALLBACK_FN_ENTRY));\r
   ASSERT (FnTableEntry != NULL);\r
 \r
   FnTableEntry->CallbackFn = CallBackFunction;\r
   InsertTailList (ListHead, &FnTableEntry->Node);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -574,17 +586,17 @@ DxeRegisterCallBackWorker (
 **/\r
 EFI_STATUS\r
 DxeUnRegisterCallBackWorker (\r
-  IN  UINTN                   TokenNumber,\r
-  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
-  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction\r
-)\r
+  IN  UINTN                  TokenNumber,\r
+  IN  CONST EFI_GUID         *Guid  OPTIONAL,\r
+  IN  PCD_PROTOCOL_CALLBACK  CallBackFunction\r
+  )\r
 {\r
-  CALLBACK_FN_ENTRY       *FnTableEntry;\r
-  LIST_ENTRY              *ListHead;\r
-  LIST_ENTRY              *ListNode;\r
+  CALLBACK_FN_ENTRY  *FnTableEntry;\r
+  LIST_ENTRY         *ListHead;\r
+  LIST_ENTRY         *ListNode;\r
 \r
   if (Guid != NULL) {\r
-    TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
+    TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)TokenNumber);\r
   }\r
 \r
   //\r
@@ -596,7 +608,7 @@ DxeUnRegisterCallBackWorker (
   ListNode = GetFirstNode (ListHead);\r
 \r
   while (ListNode != ListHead) {\r
-    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
+    FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node);\r
 \r
     if (FnTableEntry->CallbackFn == CallBackFunction) {\r
       //\r
@@ -606,9 +618,10 @@ DxeUnRegisterCallBackWorker (
       //\r
       RemoveEntryList (ListNode);\r
       FreePool (FnTableEntry);\r
-      \r
+\r
       return EFI_SUCCESS;\r
     }\r
+\r
     ListNode = GetNextNode (ListHead, ListNode);\r
   }\r
 \r
@@ -617,16 +630,16 @@ DxeUnRegisterCallBackWorker (
 \r
 /**\r
   Get next token number in given token space.\r
-  \r
+\r
   This routine is used for dynamicEx type PCD. It will firstly scan token space\r
-  table to get token space according to given token space guid. Then scan given \r
-  token number in found token space, if found, then return next token number in \r
+  table to get token space according to given token space guid. Then scan given\r
+  token number in found token space, if found, then return next token number in\r
   this token space.\r
 \r
-  @param Guid            Token space guid. Next token number will be scaned in \r
+  @param Guid            Token space guid. Next token number will be scaned in\r
                          this token space.\r
-  @param TokenNumber     Token number. \r
-                         If PCD_INVALID_TOKEN_NUMBER, return first token number in \r
+  @param TokenNumber     Token number.\r
+                         If PCD_INVALID_TOKEN_NUMBER, return first token number in\r
                          token space table.\r
                          If not PCD_INVALID_TOKEN_NUMBER, return next token number\r
                          in token space table.\r
@@ -642,23 +655,23 @@ DxeUnRegisterCallBackWorker (
 **/\r
 EFI_STATUS\r
 ExGetNextTokeNumber (\r
-  IN      CONST EFI_GUID         *Guid,\r
-  IN OUT  UINTN                  *TokenNumber,\r
-  IN      EFI_GUID               *GuidTable,\r
-  IN      UINTN                  SizeOfGuidTable,\r
-  IN      DYNAMICEX_MAPPING      *ExMapTable,\r
-  IN      UINTN                  SizeOfExMapTable\r
+  IN      CONST EFI_GUID     *Guid,\r
+  IN OUT  UINTN              *TokenNumber,\r
+  IN      EFI_GUID           *GuidTable,\r
+  IN      UINTN              SizeOfGuidTable,\r
+  IN      DYNAMICEX_MAPPING  *ExMapTable,\r
+  IN      UINTN              SizeOfExMapTable\r
   )\r
 {\r
-  EFI_GUID         *MatchGuid;\r
-  UINTN            Index;\r
-  UINTN            GuidTableIdx;\r
-  BOOLEAN          Found;\r
-  UINTN            ExMapTableCount;\r
+  EFI_GUID  *MatchGuid;\r
+  UINTN     Index;\r
+  UINTN     GuidTableIdx;\r
+  BOOLEAN   Found;\r
+  UINTN     ExMapTableCount;\r
 \r
   //\r
-  // Scan token space guid \r
-  // \r
+  // Scan token space guid\r
+  //\r
   MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);\r
   if (MatchGuid == NULL) {\r
     return EFI_NOT_FOUND;\r
@@ -667,9 +680,9 @@ ExGetNextTokeNumber (
   //\r
   // Find the token space table in dynamicEx mapping table.\r
   //\r
-  Found = FALSE;\r
-  GuidTableIdx = MatchGuid - GuidTable;\r
-  ExMapTableCount = SizeOfExMapTable / sizeof(ExMapTable[0]);\r
+  Found           = FALSE;\r
+  GuidTableIdx    = MatchGuid - GuidTable;\r
+  ExMapTableCount = SizeOfExMapTable / sizeof (ExMapTable[0]);\r
   for (Index = 0; Index < ExMapTableCount; Index++) {\r
     if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
       Found = TRUE;\r
@@ -688,7 +701,7 @@ ExGetNextTokeNumber (
     }\r
 \r
     for ( ; Index < ExMapTableCount; Index++) {\r
-      if (ExMapTable[Index].ExTokenNumber == *TokenNumber) {\r
+      if ((ExMapTable[Index].ExTokenNumber == *TokenNumber) && (ExMapTable[Index].ExGuidIndex == GuidTableIdx)) {\r
         break;\r
       }\r
     }\r
@@ -723,39 +736,120 @@ ExGetNextTokeNumber (
 DXE_PCD_DATABASE *\r
 LocateExPcdBinary (\r
   VOID\r
-) \r
+  )\r
 {\r
-  DXE_PCD_DATABASE      *DxePcdDbBinary;\r
-  UINTN                 DxePcdDbSize;\r
-  EFI_STATUS            Status;\r
\r
-  DxePcdDbBinary = NULL;\r
+  EFI_STATUS  Status;\r
+\r
   //\r
-  // Search the External Pcd database from one section of current FFS, \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
+             (VOID **)&mDxePcdDbBinary,\r
+             &mDxePcdDbSize\r
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   // Check the first bytes (Header Signature Guid) and build version.\r
   //\r
-  if (!CompareGuid ((VOID *)DxePcdDbBinary, &gPcdDataBaseSignatureGuid) ||\r
-      (DxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) {\r
+  if (!CompareGuid ((VOID *)mDxePcdDbBinary, &gPcdDataBaseSignatureGuid) ||\r
+      (mDxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION))\r
+  {\r
     ASSERT (FALSE);\r
   }\r
 \r
-  return DxePcdDbBinary;\r
+  return mDxePcdDbBinary;\r
+}\r
+\r
+/**\r
+  Update PCD database base on current SkuId\r
+\r
+  @param   SkuId     Current SkuId\r
+  @param   IsPeiDb   Whether to update PEI PCD database.\r
+\r
+  @retval EFI_SUCCESS    Update PCD database successfully.\r
+  @retval EFI_NOT_FOUND  Not found PCD database for current SkuId.\r
+**/\r
+EFI_STATUS\r
+UpdatePcdDatabase (\r
+  IN SKU_ID   SkuId,\r
+  IN BOOLEAN  IsPeiDb\r
+  )\r
+{\r
+  UINTN                   Index;\r
+  PCD_DATABASE_SKU_DELTA  *SkuDelta;\r
+  PCD_DATA_DELTA          *SkuDeltaData;\r
+\r
+  if (IsPeiDb && (mPeiPcdDbBinary != NULL)) {\r
+    //\r
+    // Find the delta data for PEI DB\r
+    //\r
+    Index    = (mPcdDatabase.PeiDb->Length + 7) & (~7);\r
+    SkuDelta = NULL;\r
+    while (Index < mPeiPcdDbSize) {\r
+      SkuDelta = (PCD_DATABASE_SKU_DELTA *)((UINT8 *)mPeiPcdDbBinary + Index);\r
+      if ((SkuDelta->SkuId == SkuId) && (SkuDelta->SkuIdCompared == 0)) {\r
+        break;\r
+      }\r
+\r
+      Index = (Index + SkuDelta->Length + 7) & (~7);\r
+    }\r
+\r
+    //\r
+    // Patch the delta data into current PCD database\r
+    //\r
+    if ((Index < mPeiPcdDbSize) && (SkuDelta != NULL)) {\r
+      SkuDeltaData = (PCD_DATA_DELTA *)(SkuDelta + 1);\r
+      while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length) {\r
+        *((UINT8 *)mPcdDatabase.PeiDb + SkuDeltaData->Offset) = (UINT8)SkuDeltaData->Value;\r
+        SkuDeltaData++;\r
+      }\r
+    } else {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Find the delta data for DXE DB\r
+  //\r
+  Index    = (mPcdDatabase.DxeDb->Length + 7) & (~7);\r
+  SkuDelta = NULL;\r
+\r
+  if (Index == mDxePcdDbSize) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  while (Index < mDxePcdDbSize) {\r
+    SkuDelta = (PCD_DATABASE_SKU_DELTA *)((UINT8 *)mDxePcdDbBinary + Index);\r
+    if ((SkuDelta->SkuId == SkuId) && (SkuDelta->SkuIdCompared == 0)) {\r
+      break;\r
+    }\r
+\r
+    Index = (Index + SkuDelta->Length + 7) & (~7);\r
+  }\r
+\r
+  //\r
+  // Patch the delta data into current PCD database\r
+  //\r
+  if ((Index < mDxePcdDbSize) && (SkuDelta != NULL)) {\r
+    SkuDeltaData = (PCD_DATA_DELTA *)(SkuDelta + 1);\r
+    while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length) {\r
+      *((UINT8 *)mPcdDatabase.DxeDb + SkuDeltaData->Offset) = (UINT8)SkuDeltaData->Value;\r
+      SkuDeltaData++;\r
+    }\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 /**\r
   Initialize the PCD database in DXE phase.\r
-  \r
+\r
   PCD database in DXE phase also contains PCD database in PEI phase which is copied\r
   from GUID Hob.\r
 \r
@@ -765,72 +859,92 @@ BuildPcdDxeDataBase (
   VOID\r
   )\r
 {\r
-  PEI_PCD_DATABASE    *PeiDatabase;\r
-  EFI_HOB_GUID_TYPE   *GuidHob;\r
-  UINTN               Index;\r
-  UINT32              PcdDxeDbLen;\r
-  VOID                *PcdDxeDb;\r
+  PEI_PCD_DATABASE   *PeiDatabase;\r
+  EFI_HOB_GUID_TYPE  *GuidHob;\r
+  UINTN              Index;\r
+  UINT32             PcdDxeDbLen;\r
+  VOID               *PcdDxeDb;\r
+  EFI_STATUS         Status;\r
+\r
+  //\r
+  // Assign PCD Entries with default value to PCD DATABASE\r
+  //\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
+  mPcdDatabase.DxeDb = PcdDxeDb;\r
 \r
   GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
   if (GuidHob != NULL) {\r
-\r
-    // \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
     // be NULL. If it is NULL, we just copy over the DXE Default\r
     // Value to PCD Database.\r
     //\r
-    \r
-    PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
+    PeiDatabase = (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob);\r
+\r
+    //\r
+    // Get next one that stores full PEI data\r
+    //\r
+    GuidHob = GetNextGuidHob (&gPcdDataBaseHobGuid, GET_NEXT_HOB (GuidHob));\r
+    if (GuidHob != NULL) {\r
+      mPeiPcdDbBinary = (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob);\r
+      mPeiPcdDbSize   = (UINTN)GET_GUID_HOB_DATA_SIZE (GuidHob);\r
+    }\r
+\r
     //\r
     // Assign PCD Entries refereneced in PEI phase to PCD DATABASE\r
     //\r
     mPcdDatabase.PeiDb = PeiDatabase;\r
-  }\r
+    //\r
+    // Inherit the SystemSkuId from PEI phase.\r
+    //\r
+    if (mPcdDatabase.PeiDb->SystemSkuId != 0) {\r
+      Status = UpdatePcdDatabase (mPcdDatabase.PeiDb->SystemSkuId, FALSE);\r
+      ASSERT_EFI_ERROR (Status);\r
+    }\r
 \r
-  //\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
+    mPcdDatabase.DxeDb->SystemSkuId = mPcdDatabase.PeiDb->SystemSkuId;\r
+  } else {\r
+    mPcdDatabase.PeiDb = AllocateZeroPool (sizeof (PEI_PCD_DATABASE));\r
+    ASSERT (mPcdDatabase.PeiDb != NULL);\r
+  }\r
 \r
   //\r
   // Initialized the external PCD database local variables\r
   //\r
-  mPeiLocalTokenCount     = mPcdDatabase.PeiDb->LocalTokenCount;\r
-  mDxeLocalTokenCount     = mPcdDatabase.DxeDb->LocalTokenCount;\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
+  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
+  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
+  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
+  TmpTokenSpaceBuffer      = (EFI_GUID **)AllocateZeroPool (TmpTokenSpaceBufferCount * sizeof (EFI_GUID *));\r
 \r
   //\r
   // Initialized the Callback Function Table\r
   //\r
   mCallbackFnTable = AllocateZeroPool (mPcdTotalTokenCount * sizeof (LIST_ENTRY));\r
-  ASSERT(mCallbackFnTable != NULL);\r
+  ASSERT (mCallbackFnTable != NULL);\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
+  // between UINTN and 0 . So we add 1 in each size of the\r
   // comparison.\r
   //\r
   for (Index = 0; Index + 1 < mPcdTotalTokenCount + 1; Index++) {\r
@@ -843,59 +957,59 @@ BuildPcdDxeDataBase (
 \r
   @param VariableGuid    Variable's guid\r
   @param VariableName    Variable's unicode name string\r
-  @param VariableData    Variable's data pointer, \r
+  @param VariableData    Variable's data pointer,\r
   @param VariableSize    Variable's size.\r
 \r
   @return the status of gRT->GetVariable\r
 **/\r
 EFI_STATUS\r
 GetHiiVariable (\r
-  IN  EFI_GUID      *VariableGuid,\r
-  IN  UINT16        *VariableName,\r
-  OUT UINT8         **VariableData,\r
-  OUT UINTN         *VariableSize\r
+  IN  EFI_GUID  *VariableGuid,\r
+  IN  UINT16    *VariableName,\r
+  OUT UINT8     **VariableData,\r
+  OUT UINTN     *VariableSize\r
   )\r
 {\r
-  UINTN      Size;\r
-  EFI_STATUS Status;\r
-  UINT8      *Buffer;\r
+  UINTN       Size;\r
+  EFI_STATUS  Status;\r
+  UINT8       *Buffer;\r
 \r
-  Size = 0;\r
+  Size   = 0;\r
   Buffer = NULL;\r
-  \r
+\r
   //\r
   // Firstly get the real size of HII variable\r
   //\r
   Status = gRT->GetVariable (\r
-    (UINT16 *)VariableName,\r
-    VariableGuid,\r
-    NULL,\r
-    &Size,\r
-    Buffer\r
-    );\r
-  \r
+                  (UINT16 *)VariableName,\r
+                  VariableGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  Buffer\r
+                  );\r
+\r
   //\r
   // Allocate buffer to hold whole variable data according to variable size.\r
   //\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    Buffer = (UINT8 *) AllocatePool (Size);\r
+    Buffer = (UINT8 *)AllocatePool (Size);\r
 \r
     ASSERT (Buffer != NULL);\r
 \r
     Status = gRT->GetVariable (\r
-      VariableName,\r
-      VariableGuid,\r
-      NULL,\r
-      &Size,\r
-      Buffer\r
-      );\r
+                    VariableName,\r
+                    VariableGuid,\r
+                    NULL,\r
+                    &Size,\r
+                    Buffer\r
+                    );\r
 \r
     ASSERT (Status == EFI_SUCCESS);\r
     *VariableData = Buffer;\r
     *VariableSize = Size;\r
   } else {\r
     //\r
-    // Use Default Data only when variable is not found. \r
+    // Use Default Data only when variable is not found.\r
     // For other error status, correct data can't be got, and trig ASSERT().\r
     //\r
     ASSERT (Status == EFI_NOT_FOUND);\r
@@ -905,95 +1019,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
-  @param IsPeiDb          If TRUE, the PCD entry is initialized in PEI phase.\r
-                          If False, the PCD entry is initialized in DXE phase.\r
-\r
-  @return Token number according to system SKU ID.\r
-\r
-**/\r
-UINT32\r
-GetSkuEnabledTokenNumber (\r
-  UINT32    LocalTokenNumber,\r
-  UINTN     Size,\r
-  BOOLEAN   IsPeiDb\r
-  ) \r
-{\r
-  SKU_HEAD              *SkuHead;\r
-  SKU_ID                *SkuIdTable;\r
-  INTN                  Index;\r
-  UINT8                 *Value;\r
-  UINT8                 *PcdDb;\r
-  BOOLEAN               FoundSku;\r
-\r
-  ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
-\r
-  PcdDb = IsPeiDb ? (UINT8 *) mPcdDatabase.PeiDb : (UINT8 *) mPcdDatabase.DxeDb;\r
-\r
-  SkuHead     = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
-  Value       = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); \r
-\r
-  SkuIdTable =  (SKU_ID *)(PcdDb + SkuHead->SkuIdTableOffset);\r
-  //\r
-  // Find the current system's SKU ID entry in SKU ID table.\r
-  //\r
-  FoundSku = FALSE;\r
-  for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
-    if (mPcdDatabase.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
-    case PCD_TYPE_VPD:\r
-      Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);\r
-      return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);\r
-\r
-    case PCD_TYPE_HII:\r
-      Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);\r
-      return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);\r
-\r
-    case PCD_TYPE_HII|PCD_TYPE_STRING:\r
-      Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);\r
-      return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING);\r
-\r
-    case PCD_TYPE_STRING:\r
-      Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);\r
-      return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING);\r
-      \r
-    case PCD_TYPE_DATA:\r
-      Value += Size * Index;\r
-      return (UINT32) ((Value - PcdDb) | PCD_TYPE_DATA);\r
-\r
-    default:\r
-      ASSERT (FALSE);\r
-  }\r
-\r
-  ASSERT (FALSE);\r
-\r
-  return 0;\r
-  \r
-}\r
-\r
-/**\r
-  Invoke the callback function when dynamic PCD entry was set, if this PCD entry \r
+  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
@@ -1007,16 +1033,16 @@ GetSkuEnabledTokenNumber (
 **/\r
 VOID\r
 InvokeCallbackOnSet (\r
-  UINT32            ExTokenNumber,\r
-  CONST EFI_GUID    *Guid, OPTIONAL\r
-  UINTN             TokenNumber,\r
-  VOID              *Data,\r
-  UINTN             Size\r
+  UINT32          ExTokenNumber,\r
+  CONST EFI_GUID  *Guid  OPTIONAL,\r
+  UINTN           TokenNumber,\r
+  VOID            *Data,\r
+  UINTN           Size\r
   )\r
 {\r
-  CALLBACK_FN_ENTRY       *FnTableEntry;\r
-  LIST_ENTRY              *ListHead;\r
-  LIST_ENTRY              *ListNode;\r
+  CALLBACK_FN_ENTRY  *FnTableEntry;\r
+  LIST_ENTRY         *ListHead;\r
+  LIST_ENTRY         *ListNode;\r
 \r
   //\r
   // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
@@ -1029,18 +1055,19 @@ InvokeCallbackOnSet (
   while (ListNode != ListHead) {\r
     FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node);\r
 \r
-    FnTableEntry->CallbackFn(Guid, \r
+    FnTableEntry->CallbackFn (\r
+                    Guid,\r
                     (Guid == NULL) ? TokenNumber : ExTokenNumber,\r
                     Data,\r
-                    Size);\r
-    \r
+                    Size\r
+                    );\r
+\r
     ListNode = GetNextNode (ListHead, ListNode);\r
   }\r
-  \r
+\r
   return;\r
 }\r
 \r
-\r
 /**\r
   Wrapper function for setting non-pointer type value for a PCD entry.\r
 \r
@@ -1053,15 +1080,14 @@ 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
 }\r
 \r
-\r
 /**\r
   Set value for an PCD entry\r
 \r
@@ -1073,33 +1099,34 @@ 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_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
-  BOOLEAN             IsPeiDb;\r
-  UINT32              LocalTokenNumber;\r
-  EFI_GUID            *GuidTable;\r
-  UINT8               *StringTable;\r
-  EFI_GUID            *Guid;\r
-  UINT16              *Name;\r
-  UINTN               VariableOffset;\r
-  VOID                *InternalData;\r
-  VARIABLE_HEAD       *VariableHead;\r
-  UINTN               Offset;\r
-  UINT8               *PcdDb;\r
-  EFI_STATUS          Status;\r
-  UINTN               MaxSize;\r
-  UINTN               TmpTokenNumber;\r
+  BOOLEAN        IsPeiDb;\r
+  UINT32         LocalTokenNumber;\r
+  EFI_GUID       *GuidTable;\r
+  UINT8          *StringTable;\r
+  EFI_GUID       *Guid;\r
+  UINT16         *Name;\r
+  UINTN          VariableOffset;\r
+  UINT32         Attributes;\r
+  VOID           *InternalData;\r
+  VARIABLE_HEAD  *VariableHead;\r
+  UINTN          Offset;\r
+  UINT8          *PcdDb;\r
+  EFI_STATUS     Status;\r
+  UINTN          MaxSize;\r
+  UINTN          TmpTokenNumber;\r
 \r
   //\r
   // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
@@ -1109,10 +1136,10 @@ SetWorker (
   TokenNumber--;\r
 \r
   TmpTokenNumber = TokenNumber;\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
+  // between UINTN and 0 . So we add 1 in each size of the\r
   // comparison.\r
   //\r
   ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);\r
@@ -1134,11 +1161,12 @@ SetWorker (
 \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
   //\r
   if ((TokenNumber + 1 < mPeiNexTokenCount + 1) ||\r
-      (TokenNumber + 1 >= mPeiLocalTokenCount + 1 && TokenNumber + 1 < (mPeiLocalTokenCount + mDxeNexTokenCount + 1))) {\r
+      ((TokenNumber + 1 >= mPeiLocalTokenCount + 1) && (TokenNumber + 1 < (mPeiLocalTokenCount + mDxeNexTokenCount + 1))))\r
+  {\r
     InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
   }\r
 \r
@@ -1149,24 +1177,23 @@ SetWorker (
 \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
   //\r
-  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);\r
+  IsPeiDb = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);\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 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);\r
+    StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);\r
   } else {\r
-    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);\r
+    StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);\r
   }\r
 \r
-  \r
   InternalData = PcdDb + Offset;\r
 \r
   switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
@@ -1174,7 +1201,7 @@ SetWorker (
       ASSERT (FALSE);\r
       Status = EFI_INVALID_PARAMETER;\r
       break;\r
-    \r
+\r
     case PCD_TYPE_STRING:\r
       if (SetPtrTypeSize (TmpTokenNumber, Size)) {\r
         CopyMem (StringTable + *((STRING_HEAD *)InternalData), Data, *Size);\r
@@ -1182,6 +1209,7 @@ SetWorker (
       } else {\r
         Status = EFI_INVALID_PARAMETER;\r
       }\r
+\r
       break;\r
 \r
     case PCD_TYPE_HII|PCD_TYPE_STRING:\r
@@ -1194,32 +1222,20 @@ SetWorker (
       }\r
 \r
       if (IsPeiDb) {\r
-        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);\r
+        GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);\r
       } else {\r
-        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);\r
+        GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);\r
       }\r
 \r
-      VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
+      VariableHead = (VARIABLE_HEAD *)(PcdDb + Offset);\r
 \r
-      Guid = GuidTable + VariableHead->GuidTableIndex;\r
-      Name = (UINT16*) (StringTable + VariableHead->StringIndex);\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
-      if (EFI_NOT_FOUND == Status) {\r
-        if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING))  {\r
-          CopyMem (\r
-            StringTable + *(STRING_HEAD *)(PcdDb + VariableHead->DefaultValueOffset),\r
-            Data,\r
-            *Size\r
-            );\r
-        } else {\r
-          CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size);\r
-        } \r
-        Status = EFI_SUCCESS;\r
-      }\r
+      Attributes     = VariableHead->Attributes;\r
+      Status         = SetHiiVariable (Guid, Name, Attributes, Data, *Size, VariableOffset);\r
       break;\r
-      \r
+\r
     case PCD_TYPE_DATA:\r
       if (PtrType) {\r
         if (SetPtrTypeSize (TmpTokenNumber, Size)) {\r
@@ -1228,25 +1244,26 @@ SetWorker (
         } else {\r
           Status = EFI_INVALID_PARAMETER;\r
         }\r
+\r
         break;\r
       }\r
 \r
       Status = EFI_SUCCESS;\r
       switch (*Size) {\r
-        case sizeof(UINT8):\r
-          *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
+        case sizeof (UINT8):\r
+          *((UINT8 *)InternalData) = *((UINT8 *)Data);\r
           break;\r
 \r
-        case sizeof(UINT16):\r
-          *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
+        case sizeof (UINT16):\r
+          *((UINT16 *)InternalData) = *((UINT16 *)Data);\r
           break;\r
 \r
-        case sizeof(UINT32):\r
-          *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
+        case sizeof (UINT32):\r
+          *((UINT32 *)InternalData) = *((UINT32 *)Data);\r
           break;\r
 \r
-        case sizeof(UINT64):\r
-          *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
+        case sizeof (UINT64):\r
+          *((UINT64 *)InternalData) = *((UINT64 *)Data);\r
           break;\r
 \r
         default:\r
@@ -1254,16 +1271,17 @@ SetWorker (
           Status = EFI_NOT_FOUND;\r
           break;\r
       }\r
+\r
       break;\r
 \r
     default:\r
       ASSERT (FALSE);\r
       Status = EFI_NOT_FOUND;\r
       break;\r
-    }\r
+  }\r
 \r
   EfiReleaseLock (&mPcdDatabaseLock);\r
-  \r
+\r
   return Status;\r
 }\r
 \r
@@ -1279,12 +1297,12 @@ SetWorker (
 **/\r
 VOID *\r
 ExGetWorker (\r
-  IN CONST EFI_GUID         *Guid,\r
-  IN UINTN                  ExTokenNumber,\r
-  IN UINTN                  GetSize\r
-  ) \r
+  IN CONST EFI_GUID  *Guid,\r
+  IN UINTN           ExTokenNumber,\r
+  IN UINTN           GetSize\r
+  )\r
 {\r
-  return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);\r
+  return GetWorker (GetExPcdTokenNumber (Guid, (UINT32)ExTokenNumber), GetSize);\r
 }\r
 \r
 /**\r
@@ -1300,10 +1318,10 @@ ExGetWorker (
 **/\r
 EFI_STATUS\r
 ExSetValueWorker (\r
-  IN          UINTN                ExTokenNumber,\r
-  IN          CONST EFI_GUID       *Guid,\r
-  IN          VOID                 *Data,\r
-  IN          UINTN                SetSize\r
+  IN          UINTN           ExTokenNumber,\r
+  IN          CONST EFI_GUID  *Guid,\r
+  IN          VOID            *Data,\r
+  IN          UINTN           SetSize\r
   )\r
 {\r
   return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, FALSE);\r
@@ -1311,12 +1329,12 @@ ExSetValueWorker (
 \r
 /**\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
+\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
@@ -1329,31 +1347,111 @@ ExSetValueWorker (
 **/\r
 EFI_STATUS\r
 ExSetWorker (\r
-  IN          UINTN                ExTokenNumber,\r
-  IN          CONST EFI_GUID       *Guid,\r
-  IN          VOID                 *Data,\r
-  IN OUT      UINTN                *SetSize,\r
-  IN          BOOLEAN              PtrType\r
+  IN          UINTN           ExTokenNumber,\r
+  IN          CONST EFI_GUID  *Guid,\r
+  IN          VOID            *Data,\r
+  IN OUT      UINTN           *SetSize,\r
+  IN          BOOLEAN         PtrType\r
   )\r
 {\r
-  UINTN                   TokenNumber;\r
-  \r
-  TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);\r
+  UINTN  TokenNumber;\r
 \r
-  InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, *SetSize);\r
+  TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)ExTokenNumber);\r
+\r
+  InvokeCallbackOnSet ((UINT32)ExTokenNumber, Guid, TokenNumber, Data, *SetSize);\r
 \r
   return SetWorker (TokenNumber, Data, SetSize, PtrType);\r
+}\r
 \r
+/**\r
+  Get variable size and data from HII-type PCDs.\r
+\r
+  @param[in]  VariableGuid   Guid of variable which stored value of a HII-type PCD.\r
+  @param[in]  VariableName   Unicode name of variable which stored value of a HII-type PCD.\r
+  @param[out] VariableSize   Pointer to variable size got from HII-type PCDs.\r
+  @param[out] VariableData   Pointer to variable data got from HII-type PCDs.\r
+\r
+**/\r
+VOID\r
+GetVariableSizeAndDataFromHiiPcd (\r
+  IN EFI_GUID  *VariableGuid,\r
+  IN UINT16    *VariableName,\r
+  OUT UINTN    *VariableSize,\r
+  OUT VOID     *VariableData OPTIONAL\r
+  )\r
+{\r
+  BOOLEAN            IsPeiDb;\r
+  PCD_DATABASE_INIT  *Database;\r
+  UINTN              TokenNumber;\r
+  UINT32             LocalTokenNumber;\r
+  UINTN              Offset;\r
+  EFI_GUID           *GuidTable;\r
+  UINT8              *StringTable;\r
+  VARIABLE_HEAD      *VariableHead;\r
+  EFI_GUID           *Guid;\r
+  UINT16             *Name;\r
+  UINTN              PcdDataSize;\r
+  UINTN              Size;\r
+  UINT8              *VaraiableDefaultBuffer;\r
+  STRING_HEAD        StringTableIdx;\r
+\r
+  *VariableSize = 0;\r
+\r
+  //\r
+  // Go through PCD database to find out DynamicHii PCDs.\r
+  //\r
+  for (TokenNumber = 1; TokenNumber <= mPcdTotalTokenCount; TokenNumber++) {\r
+    IsPeiDb          = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);\r
+    Database         = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb;\r
+    LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);\r
+    if ((LocalTokenNumber & PCD_TYPE_HII) != 0) {\r
+      //\r
+      // Get the Variable Guid and Name pointer.\r
+      //\r
+      Offset       = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+      VariableHead = (VARIABLE_HEAD *)((UINT8 *)Database + Offset);\r
+      StringTable  = (UINT8 *)((UINT8 *)Database + Database->StringTableOffset);\r
+      GuidTable    = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);\r
+      Guid         = GuidTable + VariableHead->GuidTableIndex;\r
+      Name         = (UINT16 *)(StringTable + VariableHead->StringIndex);\r
+      if (CompareGuid (VariableGuid, Guid) && (StrCmp (VariableName, Name) == 0)) {\r
+        //\r
+        // It is the matched DynamicHii PCD.\r
+        //\r
+        PcdDataSize = DxePcdGetSize (TokenNumber);\r
+        Size        = VariableHead->Offset + PcdDataSize;\r
+        if (Size > *VariableSize) {\r
+          *VariableSize = Size;\r
+        }\r
+\r
+        if (VariableData != NULL) {\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
+            StringTableIdx         = *(STRING_HEAD *)((UINT8 *)Database + VariableHead->DefaultValueOffset);\r
+            VaraiableDefaultBuffer = (UINT8 *)(StringTable + StringTableIdx);\r
+          } else {\r
+            VaraiableDefaultBuffer = (UINT8 *)Database + VariableHead->DefaultValueOffset;\r
+          }\r
+\r
+          CopyMem ((UINT8 *)VariableData + VariableHead->Offset, VaraiableDefaultBuffer, PcdDataSize);\r
+        }\r
+      }\r
+    }\r
+  }\r
 }\r
 \r
 /**\r
   Set value for HII-type PCD.\r
 \r
-  A HII-type PCD's value is stored in a variable. Setting/Getting the value of \r
+  A HII-type PCD's value is stored in a variable. Setting/Getting the value of\r
   HII-type PCD is to visit this variable.\r
-  \r
+\r
   @param VariableGuid    Guid of variable which stored value of a HII-type PCD.\r
   @param VariableName    Unicode name of variable which stored value of a HII-type PCD.\r
+  @param SetAttributes   Attributes bitmask to set for the variable.\r
   @param Data            Value want to be set.\r
   @param DataSize        Size of value\r
   @param Offset          Value offset of HII-type PCD in variable.\r
@@ -1363,11 +1461,12 @@ ExSetWorker (
 **/\r
 EFI_STATUS\r
 SetHiiVariable (\r
-  IN  EFI_GUID     *VariableGuid,\r
-  IN  UINT16       *VariableName,\r
-  IN  CONST VOID   *Data,\r
-  IN  UINTN        DataSize,\r
-  IN  UINTN        Offset\r
+  IN  EFI_GUID    *VariableGuid,\r
+  IN  UINT16      *VariableName,\r
+  IN  UINT32      SetAttributes,\r
+  IN  CONST VOID  *Data,\r
+  IN  UINTN       DataSize,\r
+  IN  UINTN       Offset\r
   )\r
 {\r
   UINTN       Size;\r
@@ -1376,51 +1475,56 @@ SetHiiVariable (
   UINT32      Attribute;\r
   UINTN       SetSize;\r
 \r
-  Size = 0;\r
+  Size    = 0;\r
   SetSize = 0;\r
 \r
   //\r
   // Try to get original variable size information.\r
   //\r
   Status = gRT->GetVariable (\r
-    (UINT16 *)VariableName,\r
-    VariableGuid,\r
-    NULL,\r
-    &Size,\r
-    NULL\r
-    );\r
-  \r
+                  (UINT16 *)VariableName,\r
+                  VariableGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  NULL\r
+                  );\r
+\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
     //\r
     // Patch new PCD's value to offset in given HII variable.\r
     //\r
-    if  (Size >= (DataSize + Offset)) {\r
+    if (Size >= (DataSize + Offset)) {\r
       SetSize = Size;\r
     } else {\r
       SetSize = DataSize + Offset;\r
     }\r
+\r
     Buffer = AllocatePool (SetSize);\r
     ASSERT (Buffer != NULL);\r
 \r
     Status = gRT->GetVariable (\r
-      VariableName,\r
-      VariableGuid,\r
-      &Attribute,\r
-      &Size,\r
-      Buffer\r
-      );\r
-    \r
+                    VariableName,\r
+                    VariableGuid,\r
+                    &Attribute,\r
+                    &Size,\r
+                    Buffer\r
+                    );\r
+\r
     ASSERT_EFI_ERROR (Status);\r
 \r
     CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);\r
 \r
+    if (SetAttributes == 0) {\r
+      SetAttributes = Attribute;\r
+    }\r
+\r
     Status = gRT->SetVariable (\r
-              VariableName,\r
-              VariableGuid,\r
-              Attribute,\r
-              SetSize,\r
-              Buffer\r
-              );\r
+                    VariableName,\r
+                    VariableGuid,\r
+                    SetAttributes,\r
+                    SetSize,\r
+                    Buffer\r
+                    );\r
 \r
     FreePool (Buffer);\r
     return Status;\r
@@ -1428,29 +1532,38 @@ SetHiiVariable (
     //\r
     // If variable does not exist, a new variable need to be created.\r
     //\r
-    \r
-    Size = Offset + DataSize;\r
-    \r
+\r
+    //\r
+    // Get size, allocate buffer and get data.\r
+    //\r
+    GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, NULL);\r
     Buffer = AllocateZeroPool (Size);\r
     ASSERT (Buffer != NULL);\r
-    \r
+    GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, Buffer);\r
+\r
+    //\r
+    // Update buffer.\r
+    //\r
     CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);\r
-    \r
+\r
+    if (SetAttributes == 0) {\r
+      SetAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
+    }\r
+\r
     Status = gRT->SetVariable (\r
-              VariableName,\r
-              VariableGuid,\r
-              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-              Size,\r
-              Buffer\r
-              );\r
+                    VariableName,\r
+                    VariableGuid,\r
+                    SetAttributes,\r
+                    Size,\r
+                    Buffer\r
+                    );\r
 \r
     FreePool (Buffer);\r
-    return Status;    \r
+    return Status;\r
   }\r
-  \r
+\r
   //\r
-  // If we drop to here, the value is failed to be written in to variable area\r
-  // So, we will save the data in the PCD Database's volatile area.\r
+  // If we drop to here, the value is failed to be written in to variable area.\r
   //\r
   return Status;\r
 }\r
@@ -1461,48 +1574,48 @@ SetHiiVariable (
   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 Token Number.\r
-  \r
+\r
   @param Guid            Token space guid for dynamic-ex PCD entry.\r
   @param ExTokenNumber   Dynamic-ex PCD token number.\r
 \r
   @return Token Number for dynamic-ex PCD.\r
 \r
 **/\r
-UINTN           \r
+UINTN\r
 GetExPcdTokenNumber (\r
-  IN CONST EFI_GUID             *Guid,\r
-  IN UINT32                     ExTokenNumber\r
+  IN CONST EFI_GUID  *Guid,\r
+  IN UINT32          ExTokenNumber\r
   )\r
 {\r
-  UINT32              Index;\r
-  DYNAMICEX_MAPPING   *ExMap;\r
-  EFI_GUID            *GuidTable;\r
-  EFI_GUID            *MatchGuid;\r
-  UINTN               MatchGuidIdx;\r
+  UINT32             Index;\r
+  DYNAMICEX_MAPPING  *ExMap;\r
+  EFI_GUID           *GuidTable;\r
+  EFI_GUID           *MatchGuid;\r
+  UINTN              MatchGuidIdx;\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
+    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
+    MatchGuid = ScanGuid (GuidTable, mPeiGuidTableSize, Guid);\r
 \r
     if (MatchGuid != NULL) {\r
-\r
       MatchGuidIdx = MatchGuid - GuidTable;\r
 \r
-      for (Index = 0; Index < mPeiExMapppingTableSize; Index++) {\r
+      for (Index = 0; Index < mPcdDatabase.PeiDb->ExTokenCount; Index++) {\r
         if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&\r
-            (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {\r
-            return ExMap[Index].TokenNumber;\r
+            (MatchGuidIdx == ExMap[Index].ExGuidIndex))\r
+        {\r
+          return ExMap[Index].TokenNumber;\r
         }\r
       }\r
     }\r
   }\r
 \r
-  ExMap       = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset);\r
-  GuidTable   = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);\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
+  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
@@ -1511,56 +1624,23 @@ GetExPcdTokenNumber (
 \r
   MatchGuidIdx = MatchGuid - GuidTable;\r
 \r
-  for (Index = 0; Index < mDxeExMapppingTableSize; Index++) {\r
+  for (Index = 0; Index < mPcdDatabase.DxeDb->ExTokenCount; Index++) {\r
     if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&\r
-         (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {\r
-        return ExMap[Index].TokenNumber;\r
+        (MatchGuidIdx == ExMap[Index].ExGuidIndex))\r
+    {\r
+      return ExMap[Index].TokenNumber;\r
     }\r
   }\r
 \r
+  DEBUG ((DEBUG_ERROR, "%a: Failed to find PCD with GUID: %g and token number: %d\n", __FUNCTION__, Guid, ExTokenNumber));\r
   ASSERT (FALSE);\r
 \r
   return 0;\r
 }\r
 \r
-/**\r
-  Get SKU ID table from PCD database.\r
-\r
-  @param LocalTokenNumberTableIdx Index of local token number in token number table.\r
-  @param IsPeiDb                  If TRUE, the pcd entry is initialized in PEI phase,\r
-                                  If FALSE, the pcd entry is initialized in DXE phase.\r
-  @return Pointer to SKU ID array table\r
-\r
-**/\r
-SKU_ID *\r
-GetSkuIdArray (\r
-  IN    UINTN             LocalTokenNumberTableIdx,\r
-  IN    BOOLEAN           IsPeiDb\r
-  )\r
-{\r
-  SKU_HEAD  *SkuHead;\r
-  UINTN     LocalTokenNumber;\r
-  UINT8     *Database;\r
-\r
-  if (IsPeiDb) {\r
-    LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
-    Database         = (UINT8 *) mPcdDatabase.PeiDb;\r
-  } else {\r
-    LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
-    Database         = (UINT8 *) mPcdDatabase.DxeDb;\r
-  }\r
-\r
-  ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
-\r
-  SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
-\r
-  return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset);\r
-  \r
-}\r
-\r
 /**\r
   Wrapper function of getting index of PCD entry in size table.\r
-  \r
+\r
   @param LocalTokenNumberTableIdx Index of this PCD in local token number table.\r
   @param IsPeiDb                  If TRUE, the pcd entry is initialized in PEI phase,\r
                                   If FALSE, the pcd entry is initialized in DXE phase.\r
@@ -1569,16 +1649,15 @@ GetSkuIdArray (
 **/\r
 UINTN\r
 GetSizeTableIndex (\r
-  IN    UINTN             LocalTokenNumberTableIdx,\r
-  IN    BOOLEAN           IsPeiDb\r
+  IN    UINTN    LocalTokenNumberTableIdx,\r
+  IN    BOOLEAN  IsPeiDb\r
   )\r
 {\r
-  UINT32 *LocalTokenNumberTable;\r
-  UINTN  LocalTokenNumber;\r
-  UINTN  Index;\r
-  UINTN  SizeTableIdx;\r
-  SKU_ID *SkuIdTable;\r
-  \r
+  UINT32  *LocalTokenNumberTable;\r
+  UINTN   LocalTokenNumber;\r
+  UINTN   Index;\r
+  UINTN   SizeTableIdx;\r
+\r
   if (IsPeiDb) {\r
     LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);\r
   } else {\r
@@ -1587,45 +1666,34 @@ GetSizeTableIndex (
 \r
   SizeTableIdx = 0;\r
 \r
-  for (Index = 0; Index < LocalTokenNumberTableIdx; Index ++) {\r
+  for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {\r
     LocalTokenNumber = LocalTokenNumberTable[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 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
+        //\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, IsPeiDb);\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
+  return SizeTableIdx;\r
 }\r
 \r
 /**\r
@@ -1639,74 +1707,56 @@ GetSizeTableIndex (
 **/\r
 UINTN\r
 GetPtrTypeSize (\r
-  IN    UINTN             LocalTokenNumberTableIdx,\r
-  OUT   UINTN             *MaxSize\r
+  IN    UINTN  LocalTokenNumberTableIdx,\r
+  OUT   UINTN  *MaxSize\r
   )\r
 {\r
-  INTN        SizeTableIdx;\r
-  UINTN       LocalTokenNumber;\r
-  SKU_ID      *SkuIdTable;\r
-  SIZE_INFO   *SizeTable;\r
-  UINTN       Index;\r
-  BOOLEAN     IsPeiDb;\r
-  UINT32      *LocalTokenNumberTable;\r
+  INTN       SizeTableIdx;\r
+  UINTN      LocalTokenNumber;\r
+  SIZE_INFO  *SizeTable;\r
+  BOOLEAN    IsPeiDb;\r
+  UINT32     *LocalTokenNumberTable;\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
-  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);\r
-\r
+  IsPeiDb = (BOOLEAN)(LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);\r
 \r
   if (IsPeiDb) {\r
     LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);\r
-    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);\r
+    SizeTable             = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);\r
   } else {\r
     LocalTokenNumberTableIdx -= mPeiLocalTokenCount;\r
-    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
-    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);\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
 \r
   ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
-  \r
+\r
   SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);\r
 \r
   *MaxSize = SizeTable[SizeTableIdx];\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 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
+    //\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
   } else {\r
-    if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
-      //\r
-      // We have only two entry for Non-Sku enabled PCD entry:\r
-      // 1) MAX SIZE\r
-      // 2) Current Size\r
-      //\r
-      return SizeTable[SizeTableIdx + 1];\r
-    } else {\r
-      //\r
-      // We have these entry for SKU enabled PCD entry\r
-      // 1) MAX SIZE\r
-      // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
-      //\r
-      SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
-      for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
-        if (SkuIdTable[1 + Index] == mPcdDatabase.PeiDb->SystemSkuId) {\r
-          return SizeTable[SizeTableIdx + 1 + Index];\r
-        }\r
-      }\r
-      return SizeTable[SizeTableIdx + 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
+    return SizeTable[SizeTableIdx + 1];\r
   }\r
 }\r
 \r
@@ -1722,82 +1772,152 @@ GetPtrTypeSize (
 **/\r
 BOOLEAN\r
 SetPtrTypeSize (\r
-  IN          UINTN             LocalTokenNumberTableIdx,\r
-  IN    OUT   UINTN             *CurrentSize\r
+  IN          UINTN  LocalTokenNumberTableIdx,\r
+  IN    OUT   UINTN  *CurrentSize\r
   )\r
 {\r
-  INTN        SizeTableIdx;\r
-  UINTN       LocalTokenNumber;\r
-  SKU_ID      *SkuIdTable;\r
-  SIZE_INFO   *SizeTable;\r
-  UINTN       Index;\r
-  UINTN       MaxSize;\r
-  BOOLEAN     IsPeiDb;\r
-  UINT32      *LocalTokenNumberTable;\r
+  INTN       SizeTableIdx;\r
+  UINTN      LocalTokenNumber;\r
+  SIZE_INFO  *SizeTable;\r
+  UINTN      MaxSize;\r
+  BOOLEAN    IsPeiDb;\r
+  UINT32     *LocalTokenNumberTable;\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
+  // between UINTN and 0 . So we add 1 in each size of the\r
   // comparison.\r
   //\r
-  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);\r
+  IsPeiDb = (BOOLEAN)(LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);\r
 \r
   if (IsPeiDb) {\r
     LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);\r
-    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);\r
+    SizeTable             = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);\r
   } else {\r
     LocalTokenNumberTableIdx -= mPeiLocalTokenCount;\r
-    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);\r
-    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);\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
 \r
   ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
-  \r
+\r
   SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);\r
 \r
   MaxSize = SizeTable[SizeTableIdx];\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 shouldn't come here as we don't support SET for VPD\r
-      //\r
-      ASSERT (FALSE);\r
-      return FALSE;\r
+    //\r
+    // We shouldn't come here as we don't support SET for VPD\r
+    //\r
+    ASSERT (FALSE);\r
+    return FALSE;\r
   } else {\r
     if ((*CurrentSize > MaxSize) ||\r
-      (*CurrentSize == MAX_ADDRESS)) {\r
-       *CurrentSize = MaxSize;\r
-       return FALSE;\r
-    } \r
-    \r
-    if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
-      //\r
-      // We have only two entry for Non-Sku enabled PCD entry:\r
-      // 1) MAX SIZE\r
-      // 2) Current Size\r
-      //\r
-      SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
-      return TRUE;\r
+        (*CurrentSize == MAX_ADDRESS))\r
+    {\r
+      *CurrentSize = MaxSize;\r
+      return FALSE;\r
+    }\r
+\r
+    //\r
+    // We have only two entry for Non-Sku enabled PCD entry:\r
+    // 1) MAX SIZE\r
+    // 2) Current Size\r
+    //\r
+    SizeTable[SizeTableIdx + 1] = (SIZE_INFO)*CurrentSize;\r
+    return TRUE;\r
+  }\r
+}\r
+\r
+/**\r
+  VariableLock DynamicHiiPcd.\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] VariableLock   Pointer to VariableLockProtocol.\r
+\r
+**/\r
+VOID\r
+VariableLockDynamicHiiPcd (\r
+  IN BOOLEAN                       IsPeiDb,\r
+  IN EDKII_VARIABLE_LOCK_PROTOCOL  *VariableLock\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  PCD_DATABASE_INIT  *Database;\r
+  UINT32             LocalTokenCount;\r
+  UINTN              TokenNumber;\r
+  UINT32             LocalTokenNumber;\r
+  UINTN              Offset;\r
+  EFI_GUID           *GuidTable;\r
+  UINT8              *StringTable;\r
+  VARIABLE_HEAD      *VariableHead;\r
+  EFI_GUID           *Guid;\r
+  UINT16             *Name;\r
+\r
+  Database        = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb;\r
+  LocalTokenCount = IsPeiDb ? mPeiLocalTokenCount : mDxeLocalTokenCount;\r
+\r
+  //\r
+  // Go through PCD database to find out DynamicHii PCDs.\r
+  //\r
+  for (TokenNumber = 1; TokenNumber <= LocalTokenCount; TokenNumber++) {\r
+    if (IsPeiDb) {\r
+      LocalTokenNumber = GetLocalTokenNumber (TRUE, TokenNumber);\r
     } else {\r
+      LocalTokenNumber = GetLocalTokenNumber (FALSE, TokenNumber + mPeiLocalTokenCount);\r
+    }\r
+\r
+    if ((LocalTokenNumber & PCD_TYPE_HII) != 0) {\r
+      Offset       = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+      VariableHead = (VARIABLE_HEAD *)((UINT8 *)Database + Offset);\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
+      // Why not to set property by VarCheckProtocol with Attributes and Property directly here?\r
+      // It is because that set property by VarCheckProtocol will indicate the variable to\r
+      // be a system variable, but the unknown max size of the variable is dangerous to\r
+      // the system variable region.\r
       //\r
-      SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
-      for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
-        if (SkuIdTable[1 + Index] == mPcdDatabase.PeiDb->SystemSkuId) {\r
-          SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;\r
-          return TRUE;\r
-        }\r
+      if ((VariableHead->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0) {\r
+        //\r
+        // DynamicHii PCD with RO property set in *.dsc.\r
+        //\r
+        StringTable = (UINT8 *)((UINT8 *)Database + Database->StringTableOffset);\r
+        GuidTable   = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);\r
+        Guid        = GuidTable + VariableHead->GuidTableIndex;\r
+        Name        = (UINT16 *)(StringTable + VariableHead->StringIndex);\r
+        Status      = VariableLock->RequestToLock (VariableLock, Name, Guid);\r
+        ASSERT_EFI_ERROR (Status);\r
       }\r
-      SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
-      return TRUE;\r
     }\r
   }\r
 }\r
+\r
+/**\r
+  VariableLockProtocol callback\r
+  to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.\r
+\r
+  @param[in] Event      Event whose notification function is being invoked.\r
+  @param[in] Context    Pointer to the notification function's context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+VariableLockCallBack (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EDKII_VARIABLE_LOCK_PROTOCOL  *VariableLock;\r
+\r
+  Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock);\r
+  if (!EFI_ERROR (Status)) {\r
+    VariableLockDynamicHiiPcd (TRUE, VariableLock);\r
+    VariableLockDynamicHiiPcd (FALSE, VariableLock);\r
+  }\r
+}\r