]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PCD/Pei/Pcd.c
MdeModulePkg and Nt32Pkg Pcd: Add the new EFI_GET_PCD_INFO_PROTOCOL and EFI_GET_PCD_I...
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Pei / Pcd.c
index 28088afc5be14a397b6e3645e75be7aa425bab9e..91e94e263dd3eaed00fc1800718b94654ed2fb23 100644 (file)
@@ -1,9 +1,8 @@
 /** @file \r
-  PCD PEIM manage PCD database to manage all dynamic PCD in PEI phase. PCD PEIM\r
-  also produce PCD_PPI.\r
+  All Pcd Ppi services are implemented here.\r
   \r
-Copyright (c) 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \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
@@ -15,6 +14,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "Service.h"\r
 \r
+///\r
+/// Instance of PCD_PPI protocol is EDKII native implementation.\r
+/// This protocol instance support dynamic and dynamicEx type PCDs.\r
+///\r
 PCD_PPI mPcdPpiInstance = {\r
   PeiPcdSetSku,\r
 \r
@@ -54,19 +57,84 @@ PCD_PPI mPcdPpiInstance = {
   PeiPcdGetNextTokenSpace\r
 };\r
 \r
-STATIC EFI_PEI_PPI_DESCRIPTOR  mPpiPCD = {\r
-  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
-  &gPcdPpiGuid,\r
-  &mPcdPpiInstance\r
+///\r
+/// Instance of EFI_PEI_PCD_PPI which is defined in PI 1.2 Vol 3.\r
+/// This PPI instance only support dyanmicEx type PCD.\r
+///\r
+EFI_PEI_PCD_PPI  mEfiPcdPpiInstance = {\r
+  PeiPcdSetSku,\r
+  \r
+  PeiPcdGet8Ex,\r
+  PeiPcdGet16Ex,\r
+  PeiPcdGet32Ex,\r
+  PeiPcdGet64Ex,\r
+  PeiPcdGetPtrEx,\r
+  PeiPcdGetBoolEx,\r
+  PeiPcdGetSizeEx,\r
+  PeiPcdSet8Ex,\r
+  PeiPcdSet16Ex,\r
+  PeiPcdSet32Ex,\r
+  PeiPcdSet64Ex,\r
+  PeiPcdSetPtrEx,\r
+  PeiPcdSetBoolEx,\r
+  (EFI_PEI_PCD_PPI_CALLBACK_ON_SET) PeiRegisterCallBackOnSet,\r
+  (EFI_PEI_PCD_PPI_CANCEL_CALLBACK) PcdUnRegisterCallBackOnSet,\r
+  PeiPcdGetNextToken,\r
+  PeiPcdGetNextTokenSpace\r
+};\r
+\r
+///\r
+/// Instance of GET_PCD_INFO_PPI protocol is EDKII native implementation.\r
+/// This protocol instance support dynamic and dynamicEx type PCDs.\r
+///\r
+GET_PCD_INFO_PPI mGetPcdInfoInstance = {\r
+  PeiGetPcdInfoGetInfo,\r
+  PeiGetPcdInfoGetInfoEx,\r
+  PeiGetPcdInfoGetSku\r
+};\r
+\r
+///\r
+/// Instance of EFI_GET_PCD_INFO_PPI which is defined in PI 1.2.1 Vol 3.\r
+/// This PPI instance only support dyanmicEx type PCD.\r
+///\r
+EFI_GET_PCD_INFO_PPI  mEfiGetPcdInfoInstance = {\r
+  PeiGetPcdInfoGetInfoEx,\r
+  PeiGetPcdInfoGetSku\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR  mPpiList[] = {\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI,\r
+    &gPcdPpiGuid,\r
+    &mPcdPpiInstance\r
+  },\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiPeiPcdPpiGuid,\r
+    &mEfiPcdPpiInstance\r
+  }\r
+};\r
+\r
+EFI_PEI_PPI_DESCRIPTOR  mPpiList2[] = {\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI,\r
+    &gGetPcdInfoPpiGuid,\r
+    &mGetPcdInfoInstance\r
+  },\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiGetPcdInfoPpiGuid,\r
+    &mEfiGetPcdInfoInstance\r
+  }\r
 };\r
 \r
 /**\r
   Main entry for PCD PEIM driver.\r
   \r
-  This routine initialize the PCD database for PEI phase and install PCD_PPI.\r
+  This routine initialize the PCD database for PEI phase and install PCD_PPI/EFI_PEI_PCD_PPI.\r
 \r
-  @param FfsHeader       Pointer to PEIM FFS header image\r
-  @param PeiServices     Pointer to EFI_PEI_SERVICES\r
+  @param  FileHandle  Handle of the file being invoked.\r
+  @param  PeiServices Describes the list of possible PEI Services.\r
 \r
   @return Status of install PCD_PPI\r
 \r
@@ -74,13 +142,97 @@ STATIC EFI_PEI_PPI_DESCRIPTOR  mPpiPCD = {
 EFI_STATUS\r
 EFIAPI\r
 PcdPeimInit (\r
-  IN EFI_FFS_FILE_HEADER      *FfsHeader,\r
-  IN EFI_PEI_SERVICES         **PeiServices\r
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices\r
   )\r
 {\r
-  BuildPcdDatabase ();\r
+  EFI_STATUS        Status;\r
+  PEI_PCD_DATABASE  *DataBase;\r
+\r
+  DataBase = BuildPcdDatabase (FileHandle);\r
+\r
+  //\r
+  // Install PCD_PPI and EFI_PEI_PCD_PPI.\r
+  //\r
+  Status = PeiServicesInstallPpi (&mPpiList[0]);\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
-  return PeiServicesInstallPpi (&mPpiPCD);\r
+  //\r
+  // Only install PcdInfo PPI when PCD info content is present. \r
+  //\r
+  if (DataBase->PcdNameTableOffset != 0) {\r
+    //\r
+    // Install GET_PCD_INFO_PPI and EFI_GET_PCD_INFO_PPI.\r
+    //\r
+    Status = PeiServicesInstallPpi (&mPpiList2[0]);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Retrieve additional information associated with a PCD token in the default token space.\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]    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
+EFIAPI\r
+PeiGetPcdInfoGetInfo (\r
+  IN        UINTN           TokenNumber,\r
+  OUT       EFI_PCD_INFO    *PcdInfo\r
+  )\r
+{\r
+  return PeiGetPcdInfo (NULL, TokenNumber, PcdInfo);\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
+EFIAPI\r
+PeiGetPcdInfoGetInfoEx (\r
+  IN CONST  EFI_GUID        *Guid,\r
+  IN        UINTN           TokenNumber,\r
+  OUT       EFI_PCD_INFO    *PcdInfo\r
+  )\r
+{\r
+  return PeiGetPcdInfo (Guid, TokenNumber, PcdInfo);\r
+}\r
+\r
+/**\r
+  Retrieve the currently set SKU Id.\r
+\r
+  @return   The currently set SKU Id. If the platform has not set at a SKU Id, then the\r
+            default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU\r
+            Id is returned.\r
+**/\r
+UINTN\r
+EFIAPI\r
+PeiGetPcdInfoGetSku (\r
+  VOID\r
+  )\r
+{\r
+  return GetPcdDatabase()->SystemSkuId;\r
 }\r
 \r
 /**\r
@@ -103,8 +255,6 @@ PcdPeimInit (
   @param[in]  SkuId The SKU value that will be used when the PCD service will retrieve and \r
               set values associated with a PCD token.\r
 \r
-  @retval VOID\r
-\r
 **/\r
 VOID\r
 EFIAPI\r
@@ -113,7 +263,7 @@ PeiPcdSetSku (
   )\r
 {\r
 \r
-  GetPcdDatabase()->Init.SystemSkuId = (SKU_ID) SkuId;\r
+  GetPcdDatabase()->SystemSkuId = (SKU_ID) SkuId;\r
 \r
   return;\r
 }\r
@@ -208,7 +358,7 @@ PeiPcdGet64 (
 \r
   @param[in]  TokenNumber The PCD token number. \r
 \r
-  @return The pointer to the buffer to be retrived.\r
+  @return The pointer to the buffer to be retrieved.\r
   \r
 **/\r
 VOID *\r
@@ -262,17 +412,10 @@ PeiPcdGetSize (
   PEI_PCD_DATABASE    *PeiPcdDb;\r
   UINTN               Size;\r
   UINTN               MaxSize;\r
+  UINT32              LocalTokenCount;\r
 \r
-  //\r
-  // If DebugAssertEnabled is TRUE, we still need to provide the GET size\r
-  // function as GetWorker and SetWoker need this function to do ASSERT.\r
-  //\r
-  if ((!FeaturePcdGet(PcdPeiPcdDatabaseGetSizeEnabled)) &&\r
-      (!DebugAssertEnabled ())) {\r
-    return 0;\r
-  }\r
-\r
-  PeiPcdDb = GetPcdDatabase ();\r
+  PeiPcdDb        = GetPcdDatabase ();\r
+  LocalTokenCount = PeiPcdDb->LocalTokenCount;\r
   //\r
   // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
   // We have to decrement TokenNumber by 1 to make it usable\r
@@ -283,9 +426,9 @@ PeiPcdGetSize (
   // EBC compiler is very choosy. It may report warning about comparison\r
   // between UINTN and 0 . So we add 1 in each size of the \r
   // comparison.\r
-  ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+  ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));\r
 \r
-  Size = (PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
+  Size = (*((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber) & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
 \r
   if (Size == 0) {\r
     //\r
@@ -405,7 +548,7 @@ PeiPcdGet64Ex (
   @param[in]  Guid          The token space for the token number.\r
   @param[in]  ExTokenNumber The PCD token number. \r
 \r
-  @return The pointer to the buffer to be retrived.\r
+  @return The pointer to the buffer to be retrieved.\r
   \r
 **/\r
 VOID *\r
@@ -461,10 +604,6 @@ PeiPcdGetSizeEx (
   IN UINTN                        ExTokenNumber\r
   )\r
 {\r
-  if ((!FeaturePcdGet (PcdPeiPcdDatabaseGetSizeEnabled)) ||  !FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {\r
-    return 0;\r
-  }\r
-\r
   return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber));\r
 }\r
 \r
@@ -834,12 +973,14 @@ PeiRegisterCallBackOnSet (
   IN  PCD_PPI_CALLBACK            CallBackFunction\r
   )\r
 {\r
-  if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled)) {\r
+  if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ASSERT (CallBackFunction != NULL);\r
-  \r
+  if (CallBackFunction == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, TRUE);\r
 }\r
 \r
@@ -863,31 +1004,40 @@ PcdUnRegisterCallBackOnSet (
   IN  PCD_PPI_CALLBACK            CallBackFunction\r
   )\r
 {\r
-  if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled)) {\r
+  if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ASSERT (CallBackFunction != NULL);\r
-  \r
+  if (CallBackFunction == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, FALSE);\r
 }\r
 \r
 /**\r
-  Retrieves the next valid PCD token for a given namespace.\r
-\r
-  @param[in]  Guid The 128-bit unique value that designates the namespace from which to extract the value.\r
-  @param[in, out]  TokenNumber A pointer to the PCD token number to use to find the subsequent token number.  \r
-                  If the input token namespace or token number does not exist on the platform, \r
-                  an error is returned and the value of *TokenNumber is undefined. To retrieve the "first" token, \r
-                  have the pointer reference a TokenNumber value of 0. If the input token number is 0 and \r
-                  there is no valid token number for this token namespace,  *TokenNumber will be assigned to \r
-                  0 and the function return EFI_SUCCESS. If the token number is the last valid token number, \r
-                  *TokenNumber will be assigned to 0 and the function return EFI_SUCCESS.\r
-\r
-  @retval EFI_SUCCESS  The PCD service retrieved the next valid token number. Or the input token number \r
-                        is already the last valid token number in the PCD database. \r
-                        In the later case, *TokenNumber is updated with the value of 0.\r
-  @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform.\r
+  Retrieves the next valid token number in a given namespace.  \r
+  \r
+  This is useful since the PCD infrastructure contains a sparse list of token numbers, \r
+  and one cannot a priori know what token numbers are valid in the database. \r
+  \r
+  If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned.  \r
+  If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned.  \r
+  If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned.  \r
+  If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned.  \r
+  The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid.  \r
+  If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned.  \r
+  If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned.  \r
+  If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned.\r
+\r
+\r
+  @param[in]       Guid        The 128-bit unique value that designates the namespace from which to extract the value.  \r
+                               This is an optional parameter that may be NULL.  If this parameter is NULL, then a request \r
+                               is being made to retrieve tokens from the default token space.\r
+  @param[in, out]  TokenNumber A pointer to the PCD token number to use to find the subsequent token number.\r
+                   \r
+  @retval EFI_SUCCESS   The PCD service has retrieved the next valid token number.\r
+  @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -900,55 +1050,56 @@ PeiPcdGetNextToken (
   UINTN               GuidTableIdx;\r
   PEI_PCD_DATABASE    *PeiPcdDb;\r
   EFI_GUID            *MatchGuid;\r
+  EFI_GUID            *GuidTable;\r
   DYNAMICEX_MAPPING   *ExMapTable;\r
   UINTN               Index;\r
   BOOLEAN             Found;\r
   BOOLEAN             PeiExMapTableEmpty;\r
+  UINTN               PeiNexTokenNumber; \r
 \r
-  if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {\r
+  if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;\r
+  PeiPcdDb          = GetPcdDatabase ();\r
+  PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;\r
+  GuidTable         = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);\r
 \r
+  if (PeiPcdDb->ExTokenCount == 0) {\r
+    PeiExMapTableEmpty = TRUE;\r
+  } else {\r
+    PeiExMapTableEmpty = FALSE;\r
+  }\r
   if (Guid == NULL) {\r
-    if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {\r
+    if (*TokenNumber > PeiNexTokenNumber) {\r
       return EFI_NOT_FOUND;\r
     }\r
     (*TokenNumber)++;\r
-    if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {\r
+    if (*TokenNumber > PeiNexTokenNumber) {\r
       *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+      return EFI_NOT_FOUND;\r
     }\r
     return EFI_SUCCESS;\r
   } else {\r
     if (PeiExMapTableEmpty) {\r
-      *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
-      return EFI_SUCCESS;\r
+      return EFI_NOT_FOUND;\r
     }\r
-    \r
-    //\r
-    // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order\r
-    // 1) ExGuid\r
-    // 2) ExTokenNumber\r
-    //\r
-    PeiPcdDb = GetPcdDatabase ();\r
-    \r
-    MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
+\r
+    MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(EFI_GUID), Guid);\r
 \r
     if (MatchGuid == NULL) {\r
-      *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
       return EFI_NOT_FOUND;\r
     }\r
 \r
-    GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;\r
+    GuidTableIdx = MatchGuid - GuidTable;\r
 \r
-    ExMapTable = PeiPcdDb->Init.ExMapTable;\r
+    ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);\r
 \r
     Found = FALSE;\r
     //\r
     // Locate the GUID in ExMapTable first.\r
     //\r
-    for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {\r
+    for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {\r
       if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
         Found = TRUE;\r
         break;\r
@@ -961,26 +1112,28 @@ PeiPcdGetNextToken (
          return EFI_SUCCESS;\r
       }\r
 \r
-      for ( ; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {\r
+      for ( ; Index < PeiPcdDb->ExTokenCount; Index++) {\r
         if (ExMapTable[Index].ExTokenNumber == *TokenNumber) {\r
-          Index++;\r
-          if (Index == PEI_EXMAPPING_TABLE_SIZE) {\r
-            //\r
-            // Exceed the length of ExMap Table\r
-            //\r
-            *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
-            return EFI_SUCCESS;\r
-          }\r
-          if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
-            *TokenNumber = ExMapTable[Index].ExTokenNumber;\r
-            return EFI_SUCCESS;\r
-          } else {\r
-            *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
-            return EFI_SUCCESS;\r
-          }\r
+          break;\r
+        }\r
+      }\r
+\r
+      while (Index < PeiPcdDb->ExTokenCount) {\r
+        Index++;\r
+        if (Index == PeiPcdDb->ExTokenCount) {\r
+          //\r
+          // Exceed the length of ExMap Table\r
+          //\r
+          *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+          return EFI_NOT_FOUND;\r
+        } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
+          //\r
+          // Found the next match\r
+          //\r
+          *TokenNumber = ExMapTable[Index].ExTokenNumber;\r
+          return EFI_SUCCESS;\r
         }\r
       }\r
-      return EFI_NOT_FOUND;\r
     }\r
   }\r
 \r
@@ -990,22 +1143,17 @@ PeiPcdGetNextToken (
 /**\r
   Retrieves the next valid PCD token namespace for a given namespace.\r
 \r
-  @param[in, out]  Guid An indirect pointer to EFI_GUID.  On input it designates \r
-                    a known token namespace from which the search will start. On output, \r
-                    it designates the next valid token namespace on the platform. If the input \r
-                    token namespace does not exist on the platform, an error is returned and \r
-                    the value of *Guid is undefined. If *Guid is NULL, then the GUID of the \r
-                    first token space of the current platform is assigned to *Guid the function \r
-                    return EFI_SUCCESS. If  *Guid is NULL  and there is no namespace exist in \r
-                    the platform other than the default (NULL) tokennamespace, *Guid is unchanged \r
-                    and the function return EFI_SUCCESS. If this input token namespace is the last \r
-                    namespace on the platform, *Guid will be assigned to NULL and the function return \r
-                    EFI_SUCCESS. \r
-\r
-  @retval EFI_SUCCESS  The PCD service retrieved the next valid token space Guid. \r
-                        Or the input token space Guid is already the last valid token space Guid \r
-                        in the PCD database. In the later case, *Guid is updated with the value of NULL.\r
-  @retval EFI_NOT_FOUND If the input token namespace does not exist on the platform.\r
+  Gets the next valid token namespace for a given namespace. This is useful to traverse the valid\r
+  token namespaces on a platform.\r
+\r
+  @param[in, out]   Guid    An indirect pointer to EFI_GUID. On input it designates a known token\r
+                            namespace from which the search will start. On output, it designates the next valid\r
+                            token namespace on the platform. If *Guid is NULL, then the GUID of the first token\r
+                            space of the current platform is returned. If the search cannot locate the next valid\r
+                            token namespace, an error is returned and the value of *Guid is undefined.\r
\r
+  @retval  EFI_SUCCESS      The PCD service retrieved the value requested.\r
+  @retval  EFI_NOT_FOUND    The PCD service could not find the next valid token namespace.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1019,52 +1167,50 @@ PeiPcdGetNextTokenSpace (
   PEI_PCD_DATABASE    *PeiPcdDb;\r
   DYNAMICEX_MAPPING   *ExMapTable;\r
   UINTN               Index;\r
+  UINTN               Index2;\r
   BOOLEAN             Found;\r
   BOOLEAN             PeiExMapTableEmpty;\r
+  EFI_GUID            *GuidTable;\r
 \r
-  if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {\r
+  if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
   ASSERT (Guid != NULL);\r
 \r
-  PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;\r
+  PeiPcdDb = GetPcdDatabase ();\r
 \r
+  if (PeiPcdDb->ExTokenCount == 0) {\r
+    PeiExMapTableEmpty = TRUE;\r
+  } else {\r
+    PeiExMapTableEmpty = FALSE;\r
+  }\r
+  \r
   if (PeiExMapTableEmpty) {\r
-    if (*Guid != NULL) {\r
-      return EFI_NOT_FOUND;\r
-    } else {\r
-      return EFI_SUCCESS;\r
-    }\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
-  //\r
-  // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order\r
-  // 1) ExGuid\r
-  // 2) ExTokenNumber\r
-  //\r
-  PeiPcdDb = GetPcdDatabase ();\r
-\r
-  ExMapTable = PeiPcdDb->Init.ExMapTable;\r
-\r
+  ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);\r
+  GuidTable  = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);\r
+  \r
   if (*Guid == NULL) {\r
     //\r
     // return the first Token Space Guid.\r
     //\r
-    *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[0].ExGuidIndex];\r
+    *Guid = GuidTable + ExMapTable[0].ExGuidIndex;\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), *Guid);\r
+  MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(GuidTable[0]), *Guid);\r
 \r
   if (MatchGuid == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
   \r
-  GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;\r
+  GuidTableIdx = MatchGuid - GuidTable;\r
 \r
   Found = FALSE;\r
-  for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {\r
+  for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {\r
     if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {\r
       Found = TRUE;\r
       break;\r
@@ -1073,14 +1219,25 @@ PeiPcdGetNextTokenSpace (
 \r
   if (Found) {\r
     Index++;\r
-    for ( ; Index < PEI_EXMAPPING_TABLE_SIZE; Index++ ) {\r
-      if (ExMapTable[Index].ExGuidIndex != GuidTableIdx ) {\r
-        *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[Index].ExGuidIndex];\r
-        return EFI_SUCCESS;\r
+    for ( ; Index < PeiPcdDb->ExTokenCount; Index++ ) {\r
+      if (ExMapTable[Index].ExGuidIndex != GuidTableIdx) {\r
+        Found = FALSE;\r
+        for (Index2 = 0 ; Index2 < Index; Index2++) {\r
+          if (ExMapTable[Index2].ExGuidIndex == ExMapTable[Index].ExGuidIndex) {\r
+            //\r
+            // This token namespace should have been found and output at preceding getting.\r
+            //\r
+            Found = TRUE;\r
+            break;\r
+          }\r
+        }\r
+        if (!Found) {\r
+          *Guid = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + ExMapTable[Index].ExGuidIndex;\r
+          return EFI_SUCCESS;\r
+        }\r
       }\r
     }\r
     *Guid = NULL;\r
-    return EFI_SUCCESS;\r
   }\r
 \r
   return EFI_NOT_FOUND;\r
@@ -1090,11 +1247,11 @@ PeiPcdGetNextTokenSpace (
 /**\r
   Get PCD value's size for POINTER type PCD.\r
   \r
-  The POINTER type PCD's value will be stored into a buffer in specificed size.\r
+  The POINTER type PCD's value will be stored into a buffer in specified size.\r
   The max size of this PCD's value is described in PCD's definition in DEC file.\r
 \r
   @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table\r
-  @param MaxSize                  Maxmium size of PCD's value\r
+  @param MaxSize                  Maximum size of PCD's value\r
   @param Database                 Pcd database in PEI phase.\r
 \r
   @return PCD value's size for POINTER type PCD.\r
@@ -1115,11 +1272,11 @@ GetPtrTypeSize (
 \r
   SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
 \r
-  LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
+  LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
 \r
   ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
   \r
-  SizeTable = Database->Init.SizeTable;\r
+  SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset);\r
 \r
   *MaxSize = SizeTable[SizeTableIdx];\r
   //\r
@@ -1128,8 +1285,9 @@ GetPtrTypeSize (
   //\r
   if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {\r
       //\r
-      // We have only one entry for VPD enabled PCD entry:\r
+      // We have only two entry for VPD enabled PCD entry:\r
       // 1) MAX Size.\r
+      // 2) Current Size\r
       // We consider current size is equal to MAX size.\r
       //\r
       return *MaxSize;\r
@@ -1149,7 +1307,7 @@ GetPtrTypeSize (
       //\r
       SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);\r
       for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
-        if (SkuIdTable[1 + Index] == Database->Init.SystemSkuId) {\r
+        if (SkuIdTable[1 + Index] == Database->SystemSkuId) {\r
           return SizeTable[SizeTableIdx + 1 + Index];\r
         }\r
       }\r
@@ -1161,15 +1319,15 @@ GetPtrTypeSize (
 /**\r
   Set PCD value's size for POINTER type PCD.\r
   \r
-  The POINTER type PCD's value will be stored into a buffer in specificed size.\r
+  The POINTER type PCD's value will be stored into a buffer in specified size.\r
   The max size of this PCD's value is described in PCD's definition in DEC file.\r
 \r
   @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table\r
-  @param CurrentSize              Maxmium size of PCD's value\r
+  @param CurrentSize              Maximum size of PCD's value\r
   @param Database                 Pcd database in PEI phase.\r
 \r
-  @retval TRUE  Success to set PCD's value size, which is not exceed maxmium size\r
-  @retval FALSE Fail to set PCD's value size, which maybe exceed maxmium size\r
+  @retval TRUE  Success to set PCD's value size, which is not exceed maximum size\r
+  @retval FALSE Fail to set PCD's value size, which maybe exceed maximum size\r
 \r
 **/\r
 BOOLEAN\r
@@ -1188,11 +1346,11 @@ SetPtrTypeSize (
   \r
   SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
 \r
-  LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
+  LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);\r
 \r
   ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
-  \r
-  SizeTable = Database->Init.SizeTable;\r
+\r
+  SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset);\r
 \r
   MaxSize = SizeTable[SizeTableIdx];\r
   //\r
@@ -1210,7 +1368,7 @@ SetPtrTypeSize (
       (*CurrentSize == MAX_ADDRESS)) {\r
        *CurrentSize = MaxSize;\r
        return FALSE;\r
-    } \r
+    }\r
     \r
     if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
       //\r
@@ -1228,7 +1386,7 @@ SetPtrTypeSize (
       //\r
       SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);\r
       for (Index = 0; Index < SkuIdTable[0]; Index++) {\r
-        if (SkuIdTable[1 + Index] == Database->Init.SystemSkuId) {\r
+        if (SkuIdTable[1 + Index] == Database->SystemSkuId) {\r
           SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;\r
           return TRUE;\r
         }\r