]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Universal/PCD/Pei/Pcd.c
1) If DebugAssertEnabled is TRUE, we still need to provide the GET size
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Pei / Pcd.c
index 3fb49dd54f925617256f56c9168d91b4b15dd128..33bc4e1069edb063fc5745010d4c0fb5078c3654 100644 (file)
@@ -1,5 +1,4 @@
-/** @file\r
-PCD PEIM\r
+/** @file PCD PEIM\r
 \r
 Copyright (c) 2006, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
@@ -15,7 +14,6 @@ Module Name: Pcd.c
 \r
 **/\r
 \r
-#include "../Common/PcdCommon.h"\r
 #include "Service.h"\r
 \r
 \r
@@ -52,9 +50,10 @@ PCD_PPI mPcdPpiInstance = {
   PeiPcdSetPtrEx,         \r
   PeiPcdSetBoolEx,\r
 \r
-  PcdRegisterCallBackOnSet,\r
+  PeiRegisterCallBackOnSet,\r
   PcdUnRegisterCallBackOnSet,\r
-  PeiPcdGetNextToken\r
+  PeiPcdGetNextToken,\r
+  PeiPcdGetNextTokenSpace\r
 };\r
 \r
 \r
@@ -75,38 +74,26 @@ PcdPeimInit (
   )\r
 {\r
   EFI_STATUS Status;\r
-  UINT8      *PcdImage;\r
 \r
-  PcdImage = (UINT8 *) LocatePcdImage ();\r
-\r
-  BuildPcdDatabase (PcdImage);\r
-\r
-  Status = PeiCoreInstallPpi (&mPpiPCD);\r
+  BuildPcdDatabase ();\r
+  \r
+  Status = PeiServicesInstallPpi (&mPpiPCD);\r
 \r
   ASSERT_EFI_ERROR (Status);\r
   \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
-\r
-EFI_STATUS\r
+VOID\r
 EFIAPI\r
 PeiPcdSetSku (\r
   IN  UINTN                  SkuId\r
   )\r
 {\r
-  PCD_DATABASE      *Database;\r
-  EFI_HOB_GUID_TYPE *GuidHob;\r
-\r
-  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
-  ASSERT (GuidHob != NULL);\r
-  \r
-  Database = (PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
 \r
-  Database->Info.SkuId = SkuId;\r
+  GetPcdDatabase()->Init.SystemSkuId = (SKU_ID) SkuId;\r
 \r
-  return SkuId;\r
+  return;\r
 }\r
 \r
 \r
@@ -114,10 +101,10 @@ PeiPcdSetSku (
 UINT8\r
 EFIAPI\r
 PeiPcdGet8 (\r
-  IN UINTN  TokenNumber\r
+  IN UINTN                    TokenNumber\r
   )\r
 {\r
-  return PeiPcdGet8Ex (NULL, TokenNumber);\r
+  return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));\r
 }\r
 \r
 \r
@@ -125,10 +112,10 @@ PeiPcdGet8 (
 UINT16\r
 EFIAPI\r
 PeiPcdGet16 (\r
-  IN UINTN  TokenNumber\r
+  IN UINTN                    TokenNumber\r
   )\r
 {\r
-  return PeiPcdGet16Ex (NULL, TokenNumber);\r
+  return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));\r
 }\r
 \r
 \r
@@ -136,10 +123,10 @@ PeiPcdGet16 (
 UINT32\r
 EFIAPI\r
 PeiPcdGet32 (\r
-  IN UINTN  TokenNumber\r
+  IN UINTN                    TokenNumber\r
   )\r
 {\r
-  return PeiPcdGet32Ex (NULL, TokenNumber);\r
+  return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));\r
 }\r
 \r
 \r
@@ -147,10 +134,10 @@ PeiPcdGet32 (
 UINT64\r
 EFIAPI\r
 PeiPcdGet64 (\r
-  IN UINTN  TokenNumber\r
+  IN UINTN                    TokenNumber\r
   )\r
 {\r
-  return PeiPcdGet64Ex (NULL, TokenNumber);\r
+  return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64)));\r
 }\r
 \r
 \r
@@ -158,10 +145,10 @@ PeiPcdGet64 (
 VOID *\r
 EFIAPI\r
 PeiPcdGetPtr (\r
-  IN UINTN  TokenNumber\r
+  IN UINTN                    TokenNumber\r
   )\r
 {\r
-  return PeiPcdGetPtrEx (NULL, TokenNumber);\r
+  return GetWorker (TokenNumber, 0);\r
 }\r
 \r
 \r
@@ -169,10 +156,10 @@ PeiPcdGetPtr (
 BOOLEAN\r
 EFIAPI\r
 PeiPcdGetBool (\r
-  IN UINTN  TokenNumber\r
+  IN UINTN                    TokenNumber\r
   )\r
 {\r
-  return PeiPcdGetBoolEx (NULL, TokenNumber);\r
+  return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));\r
 }\r
 \r
 \r
@@ -180,10 +167,46 @@ PeiPcdGetBool (
 UINTN\r
 EFIAPI\r
 PeiPcdGetSize (\r
-  IN UINTN  TokenNumber\r
+  IN UINTN                    TokenNumber\r
   )\r
 {\r
-  return PeiPcdGetSizeEx (NULL, TokenNumber);\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
+  UINTN               Size;\r
+  UINTN               MaxSize;\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
+  //\r
+  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+  // We have to decrement TokenNumber by 1 to make it usable\r
+  // as the array index.\r
+  //\r
+  TokenNumber--;\r
+\r
+  // 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
+\r
+  Size = (PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
+\r
+  if (Size == 0) {\r
+    //\r
+    // For pointer type, we need to scan the SIZE_TABLE to get the current size.\r
+    //\r
+    return GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
+  } else {\r
+    return Size;\r
+  }\r
+\r
 }\r
 \r
 \r
@@ -191,15 +214,11 @@ PeiPcdGetSize (
 UINT8\r
 EFIAPI\r
 PeiPcdGet8Ex (\r
-  IN CONST EFI_GUID        *Guid,\r
-  IN UINTN  TokenNumber\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
   )\r
 {\r
-  UINT8 Data;\r
-  \r
-  PeiGetPcdEntryWorker (TokenNumber, Guid, PcdByte8, &Data);\r
-  \r
-  return Data;\r
+  return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8)));\r
 }\r
 \r
 \r
@@ -207,15 +226,11 @@ PeiPcdGet8Ex (
 UINT16\r
 EFIAPI\r
 PeiPcdGet16Ex (\r
-  IN CONST EFI_GUID        *Guid,\r
-  IN UINTN  TokenNumber\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
   )\r
 {\r
-  UINT16 Data;\r
-  \r
-  PeiGetPcdEntryWorker (TokenNumber, Guid, PcdByte16, &Data);\r
-  \r
-  return Data;\r
+  return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16)));\r
 }\r
 \r
 \r
@@ -223,15 +238,11 @@ PeiPcdGet16Ex (
 UINT32\r
 EFIAPI\r
 PeiPcdGet32Ex (\r
-  IN CONST EFI_GUID        *Guid,\r
-  IN UINTN  TokenNumber\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
   )\r
 {\r
-  UINT32 Data;\r
-  \r
-  PeiGetPcdEntryWorker (TokenNumber, Guid, PcdByte32, &Data);\r
-  \r
-  return Data;\r
+  return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32)));\r
 }\r
 \r
 \r
@@ -239,15 +250,11 @@ PeiPcdGet32Ex (
 UINT64\r
 EFIAPI\r
 PeiPcdGet64Ex (\r
-  IN CONST EFI_GUID        *Guid,\r
-  IN UINTN  TokenNumber\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
   )\r
 {\r
-  UINT64 Data;\r
-  \r
-  PeiGetPcdEntryWorker (TokenNumber, Guid, PcdByte64, &Data);\r
-  \r
-  return Data;\r
+  return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64)));\r
 }\r
 \r
 \r
@@ -255,15 +262,11 @@ PeiPcdGet64Ex (
 VOID *\r
 EFIAPI\r
 PeiPcdGetPtrEx (\r
-  IN CONST EFI_GUID        *Guid,\r
-  IN UINTN  TokenNumber\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
   )\r
 {\r
-  VOID *Data;\r
-  \r
-  PeiGetPcdEntryWorker (TokenNumber, Guid, PcdPointer, &Data);\r
-  \r
-  return Data;\r
+  return ExGetWorker (Guid, ExTokenNumber, 0);\r
 }\r
 \r
 \r
@@ -271,15 +274,11 @@ PeiPcdGetPtrEx (
 BOOLEAN\r
 EFIAPI\r
 PeiPcdGetBoolEx (\r
-  IN CONST  EFI_GUID        *Guid,\r
-  IN UINTN                  TokenNumber\r
+  IN CONST  EFI_GUID              *Guid,\r
+  IN UINTN                        ExTokenNumber\r
   )\r
 {\r
-  BOOLEAN Data;\r
-  \r
-  PeiGetPcdEntryWorker (TokenNumber, Guid, PcdBoolean, &Data);\r
-  \r
-  return Data;\r
+  return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN)));\r
 }\r
 \r
 \r
@@ -287,11 +286,15 @@ PeiPcdGetBoolEx (
 UINTN\r
 EFIAPI\r
 PeiPcdGetSizeEx (\r
-  IN CONST  EFI_GUID        *Guid,\r
-  IN UINTN                  TokenNumber\r
+  IN CONST  EFI_GUID              *Guid,\r
+  IN UINTN                        ExTokenNumber\r
   )\r
 {\r
-  return PeiGetPcdEntrySizeWorker (TokenNumber, Guid);\r
+  if ((!FeaturePcdGet (PcdPeiPcdDatabaseGetSizeEnabled)) ||  !FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {\r
+    return 0;\r
+  }\r
+\r
+  return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber));\r
 }\r
 \r
 \r
@@ -299,11 +302,11 @@ PeiPcdGetSizeEx (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSet8 (\r
-  IN UINTN             TokenNumber,\r
-  IN UINT8             Value\r
+  IN UINTN                        TokenNumber,\r
+  IN UINT8                        Value\r
   )\r
 {\r
-  return PeiPcdSet8Ex (NULL, TokenNumber, Value);\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -311,11 +314,11 @@ PeiPcdSet8 (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSet16 (\r
-  IN UINTN              TokenNumber,\r
-  IN UINT16             Value\r
+  IN UINTN                         TokenNumber,\r
+  IN UINT16                        Value\r
   )\r
 {\r
-  return PeiPcdSet16Ex (NULL, TokenNumber, Value);\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -323,11 +326,11 @@ PeiPcdSet16 (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSet32 (\r
-  IN UINTN              TokenNumber,\r
-  IN UINT32             Value\r
+  IN UINTN                         TokenNumber,\r
+  IN UINT32                        Value\r
   )\r
 {\r
-  return PeiPcdSet32Ex (NULL, TokenNumber, Value);\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -335,22 +338,23 @@ PeiPcdSet32 (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSet64 (\r
-  IN UINTN              TokenNumber,\r
-  IN UINT64             Value\r
+  IN UINTN                         TokenNumber,\r
+  IN UINT64                        Value\r
   )\r
 {\r
-  return PeiPcdSet64Ex (NULL, TokenNumber, Value);\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
 }\r
 \r
 \r
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSetPtr (\r
-  IN UINTN              TokenNumber,\r
-  IN CONST VOID         *Value\r
+  IN      UINTN                    TokenNumber,\r
+  IN OUT  UINTN                    *SizeOfBuffer,\r
+  IN      VOID                     *Buffer\r
   )\r
 {\r
-  return PeiPcdSetPtrEx (NULL, TokenNumber, Value);\r
+  return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);\r
 }\r
 \r
 \r
@@ -358,11 +362,11 @@ PeiPcdSetPtr (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSetBool (\r
-  IN UINTN              TokenNumber,\r
-  IN BOOLEAN            Value\r
+  IN UINTN                         TokenNumber,\r
+  IN BOOLEAN                       Value\r
   )\r
 {\r
-  return PeiPcdSetBoolEx (NULL, TokenNumber, Value);\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -370,12 +374,12 @@ PeiPcdSetBool (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSet8Ex (\r
-  IN CONST EFI_GUID         *Guid,\r
-  IN UINTN                  TokenNumber,\r
-  IN UINT8                  Value\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINT8                        Value\r
   )\r
 {\r
-  return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdByte8, &Value);\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -383,12 +387,12 @@ PeiPcdSet8Ex (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSet16Ex (\r
-  IN CONST EFI_GUID         *Guid,\r
-  IN UINTN                  TokenNumber,\r
-  IN UINT16                 Value\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINT16                       Value\r
   )\r
 {\r
-  return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdByte16, &Value);\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -396,12 +400,12 @@ PeiPcdSet16Ex (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSet32Ex (\r
-  IN CONST EFI_GUID         *Guid,\r
-  IN UINTN                  TokenNumber,\r
-  IN UINT32                 Value\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINT32                       Value\r
   )\r
 {\r
-  return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdByte32, &Value);\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -409,12 +413,12 @@ PeiPcdSet32Ex (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSet64Ex (\r
-  IN CONST EFI_GUID         *Guid,\r
-  IN UINTN                  TokenNumber,\r
-  IN UINT64                 Value\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINT64                       Value\r
   )\r
 {\r
-  return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdByte64, &Value);\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -422,12 +426,13 @@ PeiPcdSet64Ex (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSetPtrEx (\r
-  IN CONST EFI_GUID         *Guid,\r
-  IN UINTN                  TokenNumber,\r
-  IN CONST VOID             *Value\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINTN                        *SizeOfBuffer,\r
+  IN VOID                         *Value\r
   )\r
 {\r
-  return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdPointer, (VOID *)Value);\r
+  return ExSetWorker (ExTokenNumber, Guid, Value, SizeOfBuffer, TRUE);\r
 }\r
 \r
 \r
@@ -435,13 +440,12 @@ PeiPcdSetPtrEx (
 EFI_STATUS\r
 EFIAPI\r
 PeiPcdSetBoolEx (\r
-  IN CONST EFI_GUID       *Guid,\r
-  IN UINTN                TokenNumber,\r
-  IN BOOLEAN              Value\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber,\r
+  IN BOOLEAN                    Value\r
   )\r
 {\r
-  return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdBoolean, &Value);\r
-\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
 }\r
 \r
 \r
@@ -449,13 +453,19 @@ PeiPcdSetBoolEx (
 \r
 EFI_STATUS\r
 EFIAPI\r
-PcdRegisterCallBackOnSet (\r
-  IN  UINTN                       TokenNumber,\r
+PeiRegisterCallBackOnSet (\r
   IN  CONST EFI_GUID              *Guid, OPTIONAL\r
+  IN  UINTN                       ExTokenNumber,\r
   IN  PCD_PPI_CALLBACK            CallBackFunction\r
   )\r
 {\r
-  return PeiRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction, TRUE);\r
+  if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ASSERT (CallBackFunction != NULL);\r
+  \r
+  return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, TRUE);\r
 }\r
 \r
 \r
@@ -463,12 +473,18 @@ PcdRegisterCallBackOnSet (
 EFI_STATUS\r
 EFIAPI\r
 PcdUnRegisterCallBackOnSet (\r
-  IN  UINTN                       TokenNumber,\r
   IN  CONST EFI_GUID              *Guid, OPTIONAL\r
+  IN  UINTN                       ExTokenNumber,\r
   IN  PCD_PPI_CALLBACK            CallBackFunction\r
   )\r
 {\r
-  return PeiRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction, FALSE);\r
+  if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ASSERT (CallBackFunction != NULL);\r
+  \r
+  return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, FALSE);\r
 }\r
 \r
 \r
@@ -480,7 +496,168 @@ PeiPcdGetNextToken (
   IN OUT  UINTN                   *TokenNumber\r
   )\r
 {\r
-  return PeiGetNextTokenWorker (TokenNumber, Guid);\r
+  UINTN               GuidTableIdx;\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
+  EFI_GUID            *MatchGuid;\r
+  DYNAMICEX_MAPPING   *ExMapTable;\r
+  UINTN               i;\r
+  BOOLEAN             Found;\r
+    \r
+  if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+    \r
+  if (Guid == NULL) {\r
+    if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+    (*TokenNumber)++;\r
+    if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {\r
+      *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+    }\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    if (PEI_EXMAP_TABLE_EMPTY) {\r
+      *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+      return EFI_SUCCESS;\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
+    if (MatchGuid == NULL) {\r
+      *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;\r
+\r
+    ExMapTable = PeiPcdDb->Init.ExMapTable;\r
+\r
+    Found = FALSE;\r
+    //\r
+    // Locate the GUID in ExMapTable first.\r
+    //\r
+    for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
+      if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {\r
+        Found = TRUE;\r
+        break;\r
+      }\r
+    }\r
+\r
+    if (Found) {\r
+      if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
+        *TokenNumber = ExMapTable[i].ExTokenNumber;\r
+         return EFI_SUCCESS;\r
+      }\r
+\r
+      for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
+        if (ExMapTable[i].ExTokenNumber == *TokenNumber) {\r
+          i++;\r
+          if (i == 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[i].ExGuidIndex == GuidTableIdx) {\r
+            *TokenNumber = ExMapTable[i].ExTokenNumber;\r
+            return EFI_SUCCESS;\r
+          } else {\r
+            *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+            return EFI_SUCCESS;\r
+          }\r
+        }\r
+      }\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 \r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdGetNextTokenSpace (\r
+  IN OUT CONST EFI_GUID          **Guid\r
+  )\r
+{\r
+  UINTN               GuidTableIdx;\r
+  EFI_GUID            *MatchGuid;\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
+  DYNAMICEX_MAPPING   *ExMapTable;\r
+  UINTN               i;\r
+  BOOLEAN             Found;\r
+\r
+  if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ASSERT (Guid != NULL);\r
+\r
+  if (PEI_EXMAP_TABLE_EMPTY) {\r
+    if (*Guid != NULL) {\r
+      return EFI_NOT_FOUND;\r
+    } else {\r
+      return EFI_SUCCESS;\r
+    }\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
+  if (*Guid == NULL) {\r
+    //\r
+    // return the first Token Space Guid.\r
+    //\r
+    *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[0].ExGuidIndex];\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), *Guid);\r
+\r
+  if (MatchGuid == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  \r
+  GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;\r
+\r
+  Found = FALSE;\r
+  for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
+    if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {\r
+      Found = TRUE;\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Found) {\r
+    i++;\r
+    for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++ ) {\r
+      if (ExMapTable[i].ExGuidIndex != GuidTableIdx ) {\r
+        *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[i].ExGuidIndex];\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+    *Guid = NULL;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+\r
+}\r
+\r