]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Import PCD dxe and PCD pei modules.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 3 Jul 2007 08:28:05 +0000 (08:28 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 3 Jul 2007 08:28:05 +0000 (08:28 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2994 6f19259b-4bc3-4df7-8a09-765794883524

14 files changed:
MdeModulePkg/Universal/PCD/Dxe/CommonHeader.h [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Dxe/Pcd.c [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Dxe/Pcd.dxs [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Dxe/Pcd.inf [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Dxe/Pcd.msa [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Dxe/Service.c [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Dxe/Service.h [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Pei/CommonHeader.h [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Pei/Pcd.c [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Pei/Pcd.dxs [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Pei/Pcd.inf [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Pei/Pcd.msa [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Pei/Service.c [new file with mode: 0644]
MdeModulePkg/Universal/PCD/Pei/Service.h [new file with mode: 0644]

diff --git a/MdeModulePkg/Universal/PCD/Dxe/CommonHeader.h b/MdeModulePkg/Universal/PCD/Dxe/CommonHeader.h
new file mode 100644 (file)
index 0000000..f01b863
--- /dev/null
@@ -0,0 +1,41 @@
+/**@file\r
+  Common header file shared by all source files.\r
+\r
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+   are licensed and made available under the terms and conditions of the BSD License\r
+   which accompanies this distribution. The full text of the license may be found at\r
+   http://opensource.org/licenses/bsd-license.php\r
+   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
+**/\r
+\r
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/Pcd.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
new file mode 100644 (file)
index 0000000..861de0f
--- /dev/null
@@ -0,0 +1,737 @@
+/** @file\r
+PCD DXE driver\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+Module Name: Pcd.c\r
+\r
+**/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Service.h"\r
+\r
+EFI_LOCK mPcdDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_CALLBACK);\r
+\r
+PCD_PROTOCOL mPcdInstance = {\r
+  DxePcdSetSku,\r
+\r
+  DxePcdGet8,\r
+  DxePcdGet16,\r
+  DxePcdGet32,\r
+  DxePcdGet64,\r
+  DxePcdGetPtr,\r
+  DxePcdGetBool,\r
+  DxePcdGetSize,\r
+\r
+  DxePcdGet8Ex,\r
+  DxePcdGet16Ex,\r
+  DxePcdGet32Ex,\r
+  DxePcdGet64Ex,\r
+  DxePcdGetPtrEx,\r
+  DxePcdGetBoolEx,\r
+  DxePcdGetSizeEx,\r
+\r
+  DxePcdSet8,\r
+  DxePcdSet16,\r
+  DxePcdSet32,\r
+  DxePcdSet64,\r
+  DxePcdSetPtr,\r
+  DxePcdSetBool,\r
+\r
+  DxePcdSet8Ex,\r
+  DxePcdSet16Ex,\r
+  DxePcdSet32Ex,\r
+  DxePcdSet64Ex,\r
+  DxePcdSetPtrEx,\r
+  DxePcdSetBoolEx,\r
+\r
+  DxeRegisterCallBackOnSet,\r
+  DxeUnRegisterCallBackOnSet,\r
+  DxePcdGetNextToken,\r
+  DxePcdGetNextTokenSpace\r
+};\r
+\r
+\r
+//\r
+// Static global to reduce the code size\r
+//\r
+static EFI_HANDLE mNewHandle = NULL;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PcdDxeInit (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+\r
+  //\r
+  // Make sure the Pcd Protocol is not already installed in the system\r
+  //\r
+\r
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid);\r
+\r
+  BuildPcdDxeDataBase ();\r
+\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &mNewHandle,\r
+                  &gPcdProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &mPcdInstance\r
+                  );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
+\r
+\r
+VOID\r
+EFIAPI\r
+DxePcdSetSku (\r
+  IN  UINTN         SkuId\r
+  )\r
+{\r
+  mPcdDatabase->PeiDb.Init.SystemSkuId = (SKU_ID) SkuId;\r
+  \r
+  return;\r
+}\r
+\r
+\r
+\r
+UINT8\r
+EFIAPI\r
+DxePcdGet8 (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));\r
+}\r
+\r
+\r
+\r
+UINT16\r
+EFIAPI\r
+DxePcdGet16 (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));\r
+}\r
+\r
+\r
+\r
+UINT32\r
+EFIAPI\r
+DxePcdGet32 (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));\r
+}\r
+\r
+\r
+\r
+UINT64\r
+EFIAPI\r
+DxePcdGet64 (\r
+  IN UINTN                     TokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned64(GetWorker (TokenNumber, sizeof (UINT64)));\r
+}\r
+\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+DxePcdGetPtr (\r
+  IN UINTN                     TokenNumber\r
+  )\r
+{\r
+  return GetWorker (TokenNumber, 0);\r
+}\r
+\r
+\r
+\r
+BOOLEAN\r
+EFIAPI\r
+DxePcdGetBool (\r
+  IN UINTN                     TokenNumber\r
+  )\r
+{\r
+  return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));\r
+}\r
+\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+DxePcdGetSize (\r
+  IN UINTN                     TokenNumber\r
+  )\r
+{\r
+  UINTN   Size;\r
+  UINT32  *LocalTokenNumberTable;\r
+  BOOLEAN IsPeiDb;\r
+  UINTN   MaxSize;\r
+  UINTN   TmpTokenNumber;\r
+  //\r
+  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+  // We have to decrement TokenNumber by 1 to make it usable\r
+  // as the array index.\r
+  //\r
+  TokenNumber--;\r
+\r
+  //\r
+  // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber\r
+  // \r
+  TmpTokenNumber = TokenNumber;\r
+\r
+  // 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 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
+\r
+  // EBC compiler is very choosy. It may report warning about comparison\r
+  // between UINTN and 0 . So we add 1 in each size of the \r
+  // comparison.\r
+  IsPeiDb = (BOOLEAN) (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+  \r
+  TokenNumber = IsPeiDb ? TokenNumber : \r
+                          (TokenNumber - PEI_LOCAL_TOKEN_NUMBER);\r
+\r
+  LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable \r
+                                  : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
+\r
+  Size = (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 (TmpTokenNumber, &MaxSize);\r
+  } else {\r
+    return Size;\r
+  }\r
+\r
+}\r
+\r
+\r
+\r
+UINT8\r
+EFIAPI\r
+DxePcdGet8Ex (\r
+  IN CONST EFI_GUID         *Guid,\r
+  IN UINTN                 ExTokenNumber\r
+  )\r
+{\r
+  return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof(UINT8)));\r
+}\r
+\r
+\r
+\r
+UINT16\r
+EFIAPI\r
+DxePcdGet16Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN                ExTokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT16)));\r
+}\r
+\r
+\r
+\r
+UINT32\r
+EFIAPI\r
+DxePcdGet32Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN                 ExTokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT32)));\r
+}\r
+\r
+\r
+\r
+UINT64\r
+EFIAPI\r
+DxePcdGet64Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN                 ExTokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT64)));\r
+}\r
+\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+DxePcdGetPtrEx (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN                 ExTokenNumber\r
+  )\r
+{\r
+  return  ExGetWorker (Guid, ExTokenNumber, 0);\r
+}\r
+\r
+\r
+\r
+BOOLEAN\r
+EFIAPI\r
+DxePcdGetBoolEx (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN                 ExTokenNumber\r
+  )\r
+{\r
+  return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof(BOOLEAN)));\r
+}\r
+\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+DxePcdGetSizeEx (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN                 ExTokenNumber\r
+  )\r
+{\r
+  return DxePcdGetSize(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet8 (\r
+  IN UINTN              TokenNumber,\r
+  IN UINT8              Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet16 (\r
+  IN UINTN              TokenNumber,\r
+  IN UINT16             Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet32 (\r
+  IN UINTN              TokenNumber,\r
+  IN UINT32             Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet64 (\r
+  IN UINTN              TokenNumber,\r
+  IN UINT64             Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSetPtr (\r
+  IN          UINTN              TokenNumber,\r
+  IN OUT      UINTN              *SizeOfBuffer,\r
+  IN          VOID               *Buffer\r
+  )\r
+{\r
+  return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSetBool (\r
+  IN UINTN              TokenNumber,\r
+  IN BOOLEAN            Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet8Ex (\r
+  IN CONST EFI_GUID         *Guid,\r
+  IN UINTN                  ExTokenNumber,\r
+  IN UINT8                  Value\r
+  )\r
+{\r
+  return  ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet16Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             ExTokenNumber,\r
+  IN UINT16            Value\r
+  )\r
+{\r
+  return  ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet32Ex (\r
+  IN CONST EFI_GUID     *Guid,\r
+  IN UINTN              ExTokenNumber,\r
+  IN UINT32             Value\r
+  )\r
+{\r
+  return  ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet64Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             ExTokenNumber,\r
+  IN UINT64            Value\r
+  )\r
+{\r
+  return  ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSetPtrEx (\r
+  IN            CONST EFI_GUID         *Guid,\r
+  IN            UINTN                  ExTokenNumber,\r
+  IN OUT        UINTN                  *SizeOfBuffer,\r
+  IN            VOID                   *Buffer\r
+  )\r
+{\r
+  return  ExSetWorker(ExTokenNumber, Guid, Buffer, SizeOfBuffer, TRUE);\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSetBoolEx (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             ExTokenNumber,\r
+  IN BOOLEAN           Value\r
+  )\r
+{\r
+  return  ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxeRegisterCallBackOnSet (\r
+  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
+  IN  UINTN                   TokenNumber,\r
+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  \r
+  ASSERT (CallBackFunction != NULL);\r
+  \r
+  //\r
+  // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
+  //\r
+  EfiAcquireLock (&mPcdDatabaseLock);\r
+\r
+  Status = DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);\r
+\r
+  EfiReleaseLock (&mPcdDatabaseLock);\r
+  \r
+  return Status;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxeUnRegisterCallBackOnSet (\r
+  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
+  IN  UINTN                   TokenNumber,\r
+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  \r
+  ASSERT (CallBackFunction != NULL);\r
+\r
+  //\r
+  // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
+  //\r
+  EfiAcquireLock (&mPcdDatabaseLock);\r
+  \r
+  Status = DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);\r
+\r
+  EfiReleaseLock (&mPcdDatabaseLock);\r
+  \r
+  return Status;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdGetNextToken (\r
+  IN CONST EFI_GUID         *Guid, OPTIONAL\r
+  IN OUT   UINTN            *TokenNumber\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  BOOLEAN             PeiExMapTableEmpty;\r
+  BOOLEAN             DxeExMapTableEmpty;\r
+\r
+  if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = EFI_NOT_FOUND;\r
+  PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;\r
+  DxeExMapTableEmpty = DXE_EXMAP_TABLE_EMPTY;\r
+\r
+  //\r
+  // Scan the local token space\r
+  //\r
+  if (Guid == NULL) {\r
+    // EBC compiler is very choosy. It may report warning about comparison\r
+    // between UINTN and 0 . So we add 1 in each size of the \r
+    // comparison.\r
+    if (((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) && (*TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1)) ||\r
+        ((*TokenNumber + 1 > (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1)))) {\r
+        return EFI_NOT_FOUND;\r
+    }\r
+    \r
+    (*TokenNumber)++;\r
+    if ((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) &&\r
+        (*TokenNumber <= PEI_LOCAL_TOKEN_NUMBER)) {\r
+      //\r
+      // The first Non-Ex type Token Number for DXE PCD \r
+      // database is PEI_LOCAL_TOKEN_NUMBER\r
+      //\r
+      *TokenNumber = PEI_LOCAL_TOKEN_NUMBER;\r
+    } else if (*TokenNumber + 1 > DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER + 1) {\r
+      *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
+    *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (!PeiExMapTableEmpty) {\r
+    Status = ExGetNextTokeNumber (\r
+                        Guid,\r
+                        TokenNumber,\r
+                        mPcdDatabase->PeiDb.Init.GuidTable,\r
+                        sizeof(mPcdDatabase->PeiDb.Init.GuidTable),\r
+                        mPcdDatabase->PeiDb.Init.ExMapTable,\r
+                        sizeof(mPcdDatabase->PeiDb.Init.ExMapTable)\r
+                        );\r
+  }\r
+\r
+  if (Status == EFI_SUCCESS) {\r
+    return Status;\r
+  }\r
+\r
+  if (!DxeExMapTableEmpty) {\r
+    Status = ExGetNextTokeNumber (\r
+                        Guid,\r
+                        TokenNumber,\r
+                        mPcdDatabase->DxeDb.Init.GuidTable,\r
+                        sizeof(mPcdDatabase->DxeDb.Init.GuidTable),\r
+                        mPcdDatabase->DxeDb.Init.ExMapTable,\r
+                        sizeof(mPcdDatabase->DxeDb.Init.ExMapTable)\r
+                        );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+EFI_GUID **\r
+GetDistinctTokenSpace (\r
+  IN OUT    UINTN             *ExMapTableSize,\r
+  IN        DYNAMICEX_MAPPING *ExMapTable,\r
+  IN        EFI_GUID          *GuidTable\r
+  )\r
+{\r
+  EFI_GUID  **DistinctTokenSpace;\r
+  UINTN     OldGuidIndex;\r
+  UINTN     TsIdx;\r
+  UINTN     Idx;\r
+\r
+\r
+  DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *));\r
+  ASSERT (DistinctTokenSpace != NULL);\r
+\r
+  TsIdx = 0;\r
+  OldGuidIndex = ExMapTable[0].ExGuidIndex;\r
+  DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex];\r
+  for (Idx = 1; Idx < *ExMapTableSize; Idx++) {\r
+    if (ExMapTable[Idx].ExGuidIndex != OldGuidIndex) {\r
+      OldGuidIndex = ExMapTable[Idx].ExGuidIndex;\r
+      DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex];\r
+    }\r
+  }\r
+\r
+  //\r
+  // The total number of Distinct Token Space\r
+  // is TsIdx + 1 because we use TsIdx as a index\r
+  // to the DistinctTokenSpace[]\r
+  //\r
+  *ExMapTableSize = TsIdx + 1;\r
+  return DistinctTokenSpace;\r
+    \r
+}\r
+  \r
+//\r
+// Just pre-allocate a memory buffer that is big enough to\r
+// host all distinct TokenSpace guid in both\r
+// PEI ExMap and DXE ExMap.\r
+//\r
+STATIC EFI_GUID *TmpTokenSpaceBuffer[PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE] = { 0 };\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdGetNextTokenSpace (\r
+  IN OUT CONST EFI_GUID               **Guid\r
+  )\r
+{\r
+  UINTN               Idx;\r
+  UINTN               Idx2;\r
+  UINTN               Idx3;\r
+  UINTN               PeiTokenSpaceTableSize;\r
+  UINTN               DxeTokenSpaceTableSize;\r
+  EFI_GUID            **PeiTokenSpaceTable;\r
+  EFI_GUID            **DxeTokenSpaceTable;\r
+  BOOLEAN             Match;\r
+  BOOLEAN             PeiExMapTableEmpty;\r
+  BOOLEAN             DxeExMapTableEmpty;\r
+\r
+  if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ASSERT (Guid != NULL);\r
+  \r
+  PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;\r
+  DxeExMapTableEmpty = DXE_EXMAP_TABLE_EMPTY;\r
+\r
+  if (PeiExMapTableEmpty && DxeExMapTableEmpty) {\r
+    if (*Guid != NULL) {\r
+      return EFI_NOT_FOUND;\r
+    } else {\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  \r
+  \r
+  if (TmpTokenSpaceBuffer[0] == NULL) {\r
+    PeiTokenSpaceTableSize = 0;\r
+\r
+    if (!PeiExMapTableEmpty) {\r
+      PeiTokenSpaceTableSize = PEI_EXMAPPING_TABLE_SIZE;\r
+      PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize,\r
+                            mPcdDatabase->PeiDb.Init.ExMapTable,\r
+                            mPcdDatabase->PeiDb.Init.GuidTable\r
+                            );\r
+      CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize);\r
+    }\r
+\r
+    if (!DxeExMapTableEmpty) {\r
+      DxeTokenSpaceTableSize = DXE_EXMAPPING_TABLE_SIZE;\r
+      DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize,\r
+                            mPcdDatabase->DxeDb.Init.ExMapTable,\r
+                            mPcdDatabase->DxeDb.Init.GuidTable\r
+                            );\r
+\r
+      //\r
+      // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable\r
+      //\r
+      for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) {\r
+        Match = FALSE;\r
+        for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) {\r
+          if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) {\r
+            Match = TRUE;\r
+            break;\r
+          }\r
+        }\r
+        if (!Match) {\r
+          TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2];\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  if (*Guid == NULL) {\r
+    *Guid = TmpTokenSpaceBuffer[0];\r
+    return EFI_SUCCESS;\r
+  }\r
+  \r
+  for (Idx = 0; Idx < (PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE); Idx++) {\r
+    if(CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {\r
+      Idx++;\r
+      *Guid = TmpTokenSpaceBuffer[Idx];\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+\r
+}\r
+\r
+\r
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.dxs b/MdeModulePkg/Universal/PCD/Dxe/Pcd.dxs
new file mode 100644 (file)
index 0000000..8601537
--- /dev/null
@@ -0,0 +1,26 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  Pcd.dxs\r
+\r
+Abstract:\r
+\r
+  Dependency expression source file.\r
+  \r
+--*/  \r
+\r
+#include <DxeDepex.h>\r
+\r
+DEPENDENCY_START\r
+  TRUE\r
+DEPENDENCY_END\r
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
new file mode 100644 (file)
index 0000000..6b41035
--- /dev/null
@@ -0,0 +1,135 @@
+#/** @file\r
+# Component description file for PCD service DXE driver.\r
+#\r
+# This DXE driver implement and produce the PCD protocol.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  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
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PcdDxe\r
+  FILE_GUID                      = 80CF7257-87AB-47f9-A3FE-D50B76D89541\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  PCD_DRIVER                     = DXE_PCD_DRIVER\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = PcdDxeInit\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  Pcd.c\r
+  Service.c\r
+  Service.h\r
+  CommonHeader.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  UefiRuntimeServicesTableLib\r
+  BaseMemoryLib\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  HobLib\r
+  PcdLib\r
+  UefiDriverEntryPoint\r
+  UefiLib\r
+  DebugLib\r
+  BaseLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+  gPcdDataBaseHobGuid                           # ALWAYS_CONSUMED  Hob: GUID_EXTENSION\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gPcdProtocolGuid                              # PROTOCOL ALWAYS_PRODUCED\r
+\r
+\r
+################################################################################\r
+#\r
+# Pcd FEATURE_FLAG - list of PCDs that this module is coded for.\r
+#\r
+################################################################################\r
+\r
+[PcdsFeatureFlag.common]\r
+  PcdDxePcdDatabaseTraverseEnabled|gEfiEdkModulePkgTokenSpaceGuid\r
+\r
+\r
+################################################################################\r
+#\r
+# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for.\r
+#\r
+################################################################################\r
+\r
+[PcdsFixedAtBuild.common]\r
+  PcdVpdBaseAddress|gEfiEdkModulePkgTokenSpaceGuid\r
+\r
+\r
+################################################################################\r
+#\r
+# Dependency Expression Section - list of Dependency expressions that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Depex]\r
+  TRUE\r
+\r
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.msa b/MdeModulePkg/Universal/PCD/Dxe/Pcd.msa
new file mode 100644 (file)
index 0000000..d920f68
--- /dev/null
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+  <MsaHeader>\r
+    <ModuleName>PcdDxe</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>80CF7257-87AB-47f9-A3FE-D50B76D89541</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for PCD service DXE driver.</Abstract>\r
+    <Description>This DXE driver implement and produce the PCD protocol.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>PcdDxe</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">\r
+      <Keyword>DebugLib</Keyword>\r
+      <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PcdLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>HobLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>Service.h</Filename>\r
+    <Filename>Service.c</Filename>\r
+    <Filename>Pcd.c</Filename>\r
+    <Filename>Pcd.dxs</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gPcdProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Hobs>\r
+    <HobTypes Usage="ALWAYS_CONSUMED" HobGuidCName="gPcdDataBaseHobGuid">\r
+      <HobType>GUID_EXTENSION</HobType>\r
+    </HobTypes>\r
+  </Hobs>\r
+  <Externs>\r
+    <PcdIsDriver>DXE_PCD_DRIVER</PcdIsDriver>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>PcdDxeInit</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+  <PcdCoded>\r
+    <PcdEntry PcdItemType="FIXED_AT_BUILD">\r
+      <C_Name>PcdVpdBaseAddress</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <HelpText>The base address of the VPD (Vital Product Data) region. It is \r
+        normally a region reserved on flash.</HelpText>\r
+    </PcdEntry>\r
+    <PcdEntry PcdItemType="FEATURE_FLAG">\r
+      <C_Name>PcdDxePcdDatabaseTraverseEnabled</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <HelpText>This feature flag can be used to enable or disable the Pcd DXE database \r
+        traverse capability. Disable it can reduce the size of final image generated.</HelpText>\r
+    </PcdEntry>\r
+  </PcdCoded>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c
new file mode 100644 (file)
index 0000000..96a4029
--- /dev/null
@@ -0,0 +1,1158 @@
+/** @file\r
+Private functions used by PCD DXE driver.\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+Module Name: Service.c\r
+\r
+**/\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Service.h"\r
+\r
+\r
+PCD_DATABASE * mPcdDatabase;\r
+\r
+LIST_ENTRY *mCallbackFnTable;\r
+\r
+VOID *\r
+GetWorker (\r
+  UINTN             TokenNumber,\r
+  UINTN             GetSize\r
+  )\r
+{\r
+  UINT32              *LocalTokenNumberTable;\r
+  EFI_GUID            *GuidTable;\r
+  UINT16              *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               MaxSize;\r
+  UINTN               TmpTokenNumber;\r
+  UINTN               DataSize;\r
+  EFI_STATUS          Status;\r
+  UINT32              LocalTokenNumber;\r
+  UINT32              Offset;\r
+  UINT16              StringTableIdx;      \r
+  BOOLEAN             IsPeiDb;\r
+\r
+  //\r
+  // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
+  //\r
+  EfiAcquireLock (&mPcdDatabaseLock);\r
+\r
+  RetPtr = NULL;\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
+  TmpTokenNumber = TokenNumber;\r
+  \r
+  //\r
+  // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant.\r
+  // It could be zero. EBC compiler is very choosy. It may\r
+  // report warning. So we add 1 in each size of the \r
+  // comparison.\r
+  //\r
+  ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
+\r
+  ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));\r
+\r
+  // EBC compiler is very choosy. It may report warning about comparison\r
+  // between UINTN and 0 . So we add 1 in each size of the \r
+  // comparison.\r
+  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);\r
+\r
+  LocalTokenNumberTable  = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
+                                     mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
+\r
+  TokenNumber            = IsPeiDb ? TokenNumber :\r
+                                     TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
+\r
+  LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
+  \r
+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
+    if (GetSize == 0) {\r
+      GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
+    } else {\r
+      MaxSize = GetSize;\r
+    }\r
+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
+  }\r
+\r
+  PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
+  StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
+                          mPcdDatabase->DxeDb.Init.StringTable;\r
+  \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) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
+      break;\r
+      \r
+    case PCD_TYPE_HII:\r
+      GuidTable   = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
+                              mPcdDatabase->DxeDb.Init.GuidTable;\r
+                              \r
+      VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
+      \r
+      Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
+      Name = &(StringTable[VariableHead->StringIndex]);\r
+      VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;\r
+\r
+      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
+      if (Status == EFI_SUCCESS) {\r
+        if (GetSize == 0) {\r
+          //\r
+          // It is a pointer type. So get the MaxSize reserved for\r
+          // this PCD entry.\r
+          //\r
+          GetPtrTypeSize (TmpTokenNumber, &GetSize);\r
+        }\r
+        CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);\r
+        FreePool (Data);\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
+      //\r
+      // If the operation is not successful, \r
+      // Return 1) either the default value specified by Platform Integrator \r
+      //        2) Or the value Set by a PCD set operation.\r
+      //\r
+      RetPtr = (VOID *) VaraiableDefaultBuffer;\r
+      break;\r
+\r
+    case PCD_TYPE_STRING:\r
+      StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);\r
+      RetPtr = (VOID *) &StringTable[StringTableIdx];\r
+      break;\r
+\r
+    case PCD_TYPE_DATA:\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
+\r
+EFI_STATUS\r
+DxeRegisterCallBackWorker (\r
+  IN  UINTN                   TokenNumber,\r
+  IN  CONST 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
+\r
+  if (Guid != NULL) {\r
+    TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
+  }\r
+\r
+  //\r
+  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+  // We have to decrement TokenNumber by 1 to make it usable\r
+  // as the array index.\r
+  //\r
+  TokenNumber--;\r
+\r
+  ListHead = &mCallbackFnTable[TokenNumber];\r
+  ListNode = GetFirstNode (ListHead);\r
+\r
+  while (ListNode != ListHead) {\r
+    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
+\r
+    if (FnTableEntry->CallbackFn == CallBackFunction) {\r
+      //\r
+      // We only allow a Callback function to be register once\r
+      // for a TokenNumber. So just return EFI_SUCCESS\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+    ListNode = GetNextNode (ListHead, ListNode);\r
+  }\r
+\r
+  FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY));\r
+  ASSERT (FnTableEntry != NULL);\r
+\r
+  FnTableEntry->CallbackFn = CallBackFunction;\r
+  InsertTailList (ListHead, &FnTableEntry->Node);\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+\r
+EFI_STATUS\r
+DxeUnRegisterCallBackWorker (\r
+  IN  UINTN                   TokenNumber,\r
+  IN  CONST 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
+\r
+  if (Guid != NULL) {\r
+    TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
+  }\r
+\r
+  //\r
+  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+  // We have to decrement TokenNumber by 1 to make it usable\r
+  // as the array index.\r
+  //\r
+  TokenNumber--;\r
+\r
+  ListHead = &mCallbackFnTable[TokenNumber];\r
+  ListNode = GetFirstNode (ListHead);\r
+\r
+  while (ListNode != ListHead) {\r
+    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
+\r
+    if (FnTableEntry->CallbackFn == CallBackFunction) {\r
+      //\r
+      // We only allow a Callback function to be register once\r
+      // for a TokenNumber. So we can safely remove the Node from\r
+      // the Link List and return EFI_SUCCESS.\r
+      //\r
+      RemoveEntryList (ListNode);\r
+      FreePool (FnTableEntry);\r
+      \r
+      return EFI_SUCCESS;\r
+    }\r
+    ListNode = GetNextNode (ListHead, ListNode);\r
+  }\r
+\r
+  return EFI_INVALID_PARAMETER;\r
+}\r
+\r
+\r
+\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
+  )\r
+{\r
+  EFI_GUID         *MatchGuid;\r
+  UINTN            Idx;\r
+  UINTN            GuidTableIdx;\r
+  BOOLEAN          Found;\r
+\r
+  MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);\r
+  if (MatchGuid == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Found = FALSE;\r
+  GuidTableIdx = MatchGuid - GuidTable;\r
+  for (Idx = 0; Idx < SizeOfExMapTable; Idx++) {\r
+    if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {\r
+      Found = TRUE;\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Found) {\r
+    if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
+      *TokenNumber = ExMapTable[Idx].ExTokenNumber;\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    for ( ; Idx < SizeOfExMapTable; Idx++) {\r
+      if (ExMapTable[Idx].ExTokenNumber == *TokenNumber) {\r
+        Idx++;\r
+        if (Idx == SizeOfExMapTable) {\r
+          //\r
+          // Exceed the length of ExMap Table\r
+          //\r
+          *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+          return EFI_SUCCESS;\r
+        } else if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {\r
+          //\r
+          // Found the next match\r
+          //\r
+          *TokenNumber = ExMapTable[Idx].ExTokenNumber;\r
+          return EFI_SUCCESS;\r
+        } else {\r
+          //\r
+          // Guid has been changed. It is the next Token Space Guid.\r
+          // We should flag no more TokenNumber.\r
+          //\r
+          *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
+          return EFI_SUCCESS;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  \r
+  return EFI_NOT_FOUND;\r
+}\r
+  \r
+\r
+\r
+\r
+VOID\r
+BuildPcdDxeDataBase (\r
+  VOID\r
+  )\r
+{\r
+  PEI_PCD_DATABASE    *PeiDatabase;\r
+  EFI_HOB_GUID_TYPE   *GuidHob;\r
+  UINTN               Idx;\r
+\r
+  mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));\r
+  ASSERT (mPcdDatabase != NULL);\r
+\r
+  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
+  if (GuidHob != NULL) {\r
+\r
+    //\r
+    // We will copy over the PEI phase's PCD Database.\r
+    // \r
+    // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM\r
+    // should not be included at all. So the GuidHob could\r
+    // 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
+    //\r
+    // Copy PCD Entries refereneced in PEI phase to PCD DATABASE\r
+    //\r
+    CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));\r
+  }\r
+\r
+  //\r
+  // Copy PCD Entries with default value to PCD DATABASE\r
+  //\r
+  CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));\r
+\r
+\r
+  //\r
+  // Initialized the Callback Function Table\r
+  //\r
+\r
+  mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));\r
+  \r
+  // EBC compiler is very choosy. It may report warning about comparison\r
+  // between UINTN and 0 . So we add 1 in each size of the \r
+  // comparison.\r
+  for (Idx = 0; Idx + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Idx++) {\r
+    InitializeListHead (&mCallbackFnTable[Idx]);\r
+  }\r
+    \r
+  return;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+GetHiiVariable (\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
+\r
+  Size = 0;\r
+  Buffer = NULL;\r
+  \r
+  Status = gRT->GetVariable (\r
+    (UINT16 *)VariableName,\r
+    VariableGuid,\r
+    NULL,\r
+    &Size,\r
+    Buffer\r
+    );\r
+  \r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\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
+\r
+    ASSERT (Status == EFI_SUCCESS);\r
+    *VariableData = Buffer;\r
+    *VariableSize = Size;\r
+  }\r
+\r
+  return Status;\r
+}\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                  i;\r
+  UINT8                 *Value;\r
+  SKU_ID                *PhaseSkuIdTable;\r
+  UINT8                 *PcdDb;\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
+  PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :\r
+                              mPcdDatabase->DxeDb.Init.SkuIdTable;\r
+                              \r
+  SkuIdTable  = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];\r
+        \r
+  for (i = 0; i < SkuIdTable[0]; i++) {\r
+    if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) {\r
+      break;\r
+    }\r
+  }\r
+  ASSERT (i < SkuIdTable[0]);\r
+\r
+  switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
+    case PCD_TYPE_VPD:\r
+      Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
+      return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);\r
+\r
+    case PCD_TYPE_HII:\r
+      Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
+      return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);\r
+\r
+    case PCD_TYPE_STRING:\r
+      Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]);\r
+      return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING);\r
+      \r
+    case PCD_TYPE_DATA:\r
+      Value += Size * i;\r
+      return (UINT32) (Value - PcdDb);\r
+\r
+    default:\r
+      ASSERT (FALSE);\r
+  }\r
+\r
+  ASSERT (FALSE);\r
+\r
+  return 0;\r
+  \r
+}\r
+\r
+\r
+\r
+\r
+STATIC\r
+VOID\r
+InvokeCallbackOnSet (\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
+\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
+  ListHead = &mCallbackFnTable[TokenNumber];\r
+  ListNode = GetFirstNode (ListHead);\r
+\r
+  while (ListNode != ListHead) {\r
+    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
+\r
+    FnTableEntry->CallbackFn(Guid, \r
+                    (Guid == NULL) ? TokenNumber : ExTokenNumber,\r
+                    Data,\r
+                    Size);\r
+    \r
+    ListNode = GetNextNode (ListHead, ListNode);\r
+  }\r
+  \r
+  return;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+SetValueWorker (\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
+EFI_STATUS\r
+SetWorker (\r
+  IN          UINTN                   TokenNumber,\r
+  IN          VOID                    *Data,\r
+  IN OUT      UINTN                   *Size,\r
+  IN          BOOLEAN                 PtrType\r
+  )\r
+{\r
+  UINT32              *LocalTokenNumberTable;\r
+  BOOLEAN             IsPeiDb;\r
+  UINT32              LocalTokenNumber;\r
+  EFI_GUID            *GuidTable;\r
+  UINT16              *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
+\r
+  //\r
+  // Aquire lock to prevent reentrance from TPL_CALLBACK level\r
+  //\r
+  EfiAcquireLock (&mPcdDatabaseLock);\r
+\r
+  //\r
+  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+  // We have to decrement TokenNumber by 1 to make it usable\r
+  // as the array index.\r
+  //\r
+  TokenNumber--;\r
+\r
+  TmpTokenNumber = 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
+\r
+  ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
+\r
+  if (!PtrType) {\r
+    ASSERT (*Size == DxePcdGetSize (TokenNumber + 1));\r
+  }\r
+  \r
+  // EBC compiler is very choosy. It may report warning about comparison\r
+  // between UINTN and 0 . So we add 1 in each size of the \r
+  // comparison.\r
+  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);\r
+\r
+  LocalTokenNumberTable  = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
+                                     mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
+\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
+  if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) ||\r
+      (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) {\r
+    InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
+  }\r
+\r
+  TokenNumber = IsPeiDb ? TokenNumber\r
+                        : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
+\r
+  LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
+  \r
+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
+    if (PtrType) {\r
+      GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
+    } else {\r
+      MaxSize = *Size;\r
+    }\r
+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
+  }\r
+\r
+  Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+\r
+  PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
+\r
+  StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
+                          mPcdDatabase->DxeDb.Init.StringTable;\r
+  \r
+  InternalData = PcdDb + Offset;\r
+\r
+  switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
+    case PCD_TYPE_VPD:\r
+      ASSERT (FALSE);\r
+      Status = EFI_INVALID_PARAMETER;\r
+      break;\r
+    \r
+    case PCD_TYPE_STRING:\r
+      if (SetPtrTypeSize (TmpTokenNumber, Size)) {\r
+        CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, *Size);\r
+        Status = EFI_SUCCESS;\r
+      } else {\r
+        Status = EFI_INVALID_PARAMETER;\r
+      }\r
+      break;\r
+\r
+    case PCD_TYPE_HII:\r
+      if (PtrType) {\r
+        if (!SetPtrTypeSize (TmpTokenNumber, Size)) {\r
+          Status = EFI_INVALID_PARAMETER;\r
+          break;\r
+        }\r
+      }\r
+      \r
+      GuidTable   = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
+                              mPcdDatabase->DxeDb.Init.GuidTable;\r
+                              \r
+      VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
+      \r
+      Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
+      Name = &(StringTable[VariableHead->StringIndex]);\r
+      VariableOffset = VariableHead->Offset;\r
+\r
+      Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset);\r
+\r
+      if (EFI_NOT_FOUND == Status) {\r
+        CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size);\r
+        Status = EFI_SUCCESS;\r
+      } \r
+      break;\r
+      \r
+    case PCD_TYPE_DATA:\r
+      if (PtrType) {\r
+        if (SetPtrTypeSize (TmpTokenNumber, Size)) {\r
+          CopyMem (InternalData, Data, *Size);\r
+          Status = EFI_SUCCESS;\r
+        } else {\r
+          Status = EFI_INVALID_PARAMETER;\r
+        }\r
+        break;\r
+      }\r
+\r
+      Status = EFI_SUCCESS;\r
+      switch (*Size) {\r
+        case sizeof(UINT8):\r
+          *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
+          break;\r
+\r
+        case sizeof(UINT16):\r
+          *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
+          break;\r
+\r
+        case sizeof(UINT32):\r
+          *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
+          break;\r
+\r
+        case sizeof(UINT64):\r
+          *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
+          break;\r
+\r
+        default:\r
+          ASSERT (FALSE);\r
+          Status = EFI_NOT_FOUND;\r
+          break;\r
+      }\r
+      break;\r
+\r
+    default:\r
+      ASSERT (FALSE);\r
+      Status = EFI_NOT_FOUND;\r
+      break;\r
+    }\r
+\r
+  EfiReleaseLock (&mPcdDatabaseLock);\r
+  \r
+  return Status;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+VOID *\r
+ExGetWorker (\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
+}\r
+\r
+\r
+\r
+\r
+EFI_STATUS\r
+ExSetValueWorker (\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
+}\r
+\r
+\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
+  )\r
+{\r
+  UINTN                   TokenNumber;\r
+  \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
+\r
+\r
+\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
+  )\r
+{\r
+  UINTN       Size;\r
+  VOID        *Buffer;\r
+  EFI_STATUS  Status;\r
+  UINT32      Attribute;\r
+\r
+  Size = 0;\r
+\r
+  Status = gRT->GetVariable (\r
+    (UINT16 *)VariableName,\r
+    VariableGuid,\r
+    NULL,\r
+    &Size,\r
+    NULL\r
+    );\r
+\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+\r
+    Buffer = AllocatePool (Size);\r
+\r
+    ASSERT (Buffer != NULL);\r
+\r
+    Status = gRT->GetVariable (\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
+    Status = gRT->SetVariable (\r
+              VariableName,\r
+              VariableGuid,\r
+              Attribute,\r
+              Size,\r
+              Buffer\r
+              );\r
+\r
+    FreePool (Buffer);\r
+    return Status;\r
+\r
+  } \r
+  \r
+  //\r
+  // If we drop to here, we don't have a Variable entry in\r
+  // the variable service yet. So, we will save the data\r
+  // in the PCD Database's volatile area.\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+UINTN           \r
+GetExPcdTokenNumber (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINT32                     ExTokenNumber\r
+  )\r
+{\r
+  UINT32              i;\r
+  DYNAMICEX_MAPPING   *ExMap;\r
+  EFI_GUID            *GuidTable;\r
+  EFI_GUID            *MatchGuid;\r
+  UINTN               MatchGuidIdx;\r
+\r
+  if (!PEI_DATABASE_EMPTY) {\r
+    ExMap       = mPcdDatabase->PeiDb.Init.ExMapTable;\r
+    GuidTable   = mPcdDatabase->PeiDb.Init.GuidTable;\r
+    \r
+    MatchGuid   = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);\r
+    \r
+    if (MatchGuid != NULL) {\r
+\r
+      MatchGuidIdx = MatchGuid - GuidTable;\r
+      \r
+      for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
+        if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
+            (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
+            return ExMap[i].LocalTokenNumber;\r
+\r
+        }\r
+      }\r
+    }\r
+  }\r
+  \r
+  ExMap       = mPcdDatabase->DxeDb.Init.ExMapTable;\r
+  GuidTable   = mPcdDatabase->DxeDb.Init.GuidTable;\r
+\r
+  MatchGuid   = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);\r
+  //\r
+  // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
+  // error in the BUILD system.\r
+  //\r
+  ASSERT (MatchGuid != NULL);\r
+\r
+  MatchGuidIdx = MatchGuid - GuidTable;\r
+  \r
+  for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {\r
+    if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
+         (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
+        return ExMap[i].LocalTokenNumber;\r
+    }\r
+  }\r
+\r
+  ASSERT (FALSE);\r
+\r
+  return 0;\r
+}\r
+\r
+\r
+STATIC\r
+SKU_ID *\r
+GetSkuIdArray (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  IN    BOOLEAN           IsPeiPcd\r
+  )\r
+{\r
+  SKU_HEAD  *SkuHead;\r
+  UINTN     LocalTokenNumber;\r
+  UINT8     *Database;\r
+\r
+  if (IsPeiPcd) {\r
+    LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
+    Database         = (UINT8 *) &mPcdDatabase->PeiDb;\r
+  } else {\r
+    LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER];\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
+STATIC\r
+UINTN\r
+GetSizeTableIndexA (\r
+  IN UINTN        LocalTokenNumberTableIdx,\r
+  IN UINT32       *LocalTokenNumberTable,\r
+  IN BOOLEAN      IsPeiDb\r
+  )\r
+{\r
+  UINTN       i;\r
+  UINTN       SizeTableIdx;\r
+  UINTN       LocalTokenNumber;\r
+  SKU_ID      *SkuIdTable;\r
+  \r
+  SizeTableIdx = 0;\r
+\r
+  for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
+    LocalTokenNumber = LocalTokenNumberTable[i];\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
+      // PCD entry.\r
+      //\r
+      if (LocalTokenNumber & PCD_TYPE_VPD) {\r
+          //\r
+          // We have only one entry for VPD enabled PCD entry:\r
+          // 1) MAX Size.\r
+          // We consider current size is equal to MAX size.\r
+          //\r
+          SizeTableIdx++;\r
+      } 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 (i, IsPeiDb);\r
+          SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
+        }\r
+      }\r
+    }\r
+\r
+  }\r
+\r
+  return SizeTableIdx;\r
+}\r
+\r
+\r
+\r
+STATIC\r
+UINTN\r
+GetSizeTableIndex (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  IN    BOOLEAN           IsPeiDb\r
+  )\r
+{\r
+  UINT32 *LocalTokenNumberTable;\r
+  \r
+  if (IsPeiDb) {\r
+    LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
+  } else {\r
+    LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
+  }\r
+  return GetSizeTableIndexA (LocalTokenNumberTableIdx, \r
+                              LocalTokenNumberTable,\r
+                              IsPeiDb);\r
+}\r
+\r
+\r
+\r
+UINTN\r
+GetPtrTypeSize (\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       i;\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
+  // comparison.\r
+  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+\r
+\r
+  if (IsPeiDb) {\r
+    LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
+    SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;\r
+  } else {\r
+    LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;\r
+    LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
+    SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;\r
+  }\r
+\r
+  LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
+\r
+  ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
+  \r
+  SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);\r
+\r
+  *MaxSize = SizeTable[SizeTableIdx];\r
+  //\r
+  // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
+  // PCD entry.\r
+  //\r
+  if (LocalTokenNumber & PCD_TYPE_VPD) {\r
+      //\r
+      // We have only one entry for VPD enabled PCD entry:\r
+      // 1) MAX Size.\r
+      // We consider current size is equal to MAX size.\r
+      //\r
+      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 (i = 0; i < SkuIdTable[0]; i++) {\r
+        if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) {\r
+          return SizeTable[SizeTableIdx + 1 + i];\r
+        }\r
+      }\r
+      return SizeTable[SizeTableIdx + 1];\r
+    }\r
+  }\r
+}\r
+\r
+\r
+\r
+BOOLEAN\r
+SetPtrTypeSize (\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       i;\r
+  UINTN       MaxSize;\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
+  // comparison.\r
+  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+\r
+  if (IsPeiDb) {\r
+    LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
+    SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;\r
+  } else {\r
+    LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;\r
+    LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
+    SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;\r
+  }\r
+\r
+  LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
+\r
+  ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
+  \r
+  SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);\r
+\r
+  MaxSize = SizeTable[SizeTableIdx];\r
+  //\r
+  // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
+  // PCD entry.\r
+  //\r
+  if (LocalTokenNumber & PCD_TYPE_VPD) {\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
+    } 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 (i = 0; i < SkuIdTable[0]; i++) {\r
+        if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) {\r
+          SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize;\r
+          return TRUE;\r
+        }\r
+      }\r
+      SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
+      return TRUE;\r
+    }\r
+  }\r
+}\r
+\r
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.h b/MdeModulePkg/Universal/PCD/Dxe/Service.h
new file mode 100644 (file)
index 0000000..da38053
--- /dev/null
@@ -0,0 +1,485 @@
+/** @file\r
+Private functions used by PCD DXE driver.\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+\r
+Module Name: Service.h\r
+\r
+**/\r
+\r
+#ifndef _SERVICE_H\r
+#define _SERVICE_H\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+//\r
+// Please make sure the PCD Serivce PEIM Version is consistent with\r
+// the version of PCD Database generation tool\r
+//\r
+#define PCD_SERVICE_DXE_DRIVER_VERSION      2\r
+\r
+//\r
+// PCD_DXE_DATABASE_GENTOOL_VERSION is defined in Autogen.h\r
+// and generated by PCD Database generation tool.\r
+//\r
+#if (PCD_SERVICE_DXE_DRIVER_VERSION != PCD_DXE_SERVICE_DRIVER_AUTOGEN_VERSION)\r
+  #error "Please make sure the version of PCD Service DXE Driver and PCD DXE Database Generation Tool matches"\r
+#endif\r
+\r
+//\r
+// Protocol Interface function declaration.\r
+//\r
+VOID\r
+EFIAPI\r
+DxePcdSetSku (\r
+  IN  UINTN                  SkuId\r
+  )\r
+;\r
+\r
+\r
+UINT8\r
+EFIAPI\r
+DxePcdGet8 (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT16\r
+EFIAPI\r
+DxePcdGet16 (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT32\r
+EFIAPI\r
+DxePcdGet32 (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT64\r
+EFIAPI\r
+DxePcdGet64 (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+DxePcdGetPtr (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+BOOLEAN\r
+EFIAPI\r
+DxePcdGetBool (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+DxePcdGetSize (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT8\r
+EFIAPI\r
+DxePcdGet8Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT16\r
+EFIAPI\r
+DxePcdGet16Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT32\r
+EFIAPI\r
+DxePcdGet32Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+\r
+UINT64\r
+EFIAPI\r
+DxePcdGet64Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+DxePcdGetPtrEx (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+BOOLEAN\r
+EFIAPI\r
+DxePcdGetBoolEx (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+DxePcdGetSizeEx (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet8 (\r
+  IN UINTN             TokenNumber,\r
+  IN UINT8             Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet16 (\r
+  IN UINTN             TokenNumber,\r
+  IN UINT16             Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet32 (\r
+  IN UINTN             TokenNumber,\r
+  IN UINT32             Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet64 (\r
+  IN UINTN             TokenNumber,\r
+  IN UINT64            Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSetPtr (\r
+  IN        UINTN             TokenNumber,\r
+  IN        UINTN             *SizeOfBuffer,\r
+  IN        VOID              *Buffer\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSetBool (\r
+  IN UINTN             TokenNumber,\r
+  IN BOOLEAN           Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet8Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN UINT8             Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet16Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN UINT16            Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet32Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN UINT32             Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSet64Ex (\r
+  IN CONST EFI_GUID        *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN UINT64            Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSetPtrEx (\r
+  IN        CONST EFI_GUID    *Guid,\r
+  IN        UINTN             TokenNumber,\r
+  IN OUT    UINTN             *SizeOfBuffer,\r
+  IN        VOID              *Buffer\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdSetBoolEx (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN BOOLEAN           Value\r
+  )\r
+;\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxeRegisterCallBackOnSet (\r
+  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
+  IN  UINTN                   TokenNumber,\r
+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxeUnRegisterCallBackOnSet (\r
+  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
+  IN  UINTN                   TokenNumber,\r
+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdGetNextToken (\r
+  IN CONST EFI_GUID               *Guid, OPTIONAL\r
+  IN OUT   UINTN                  *TokenNumber\r
+  )\r
+;\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DxePcdGetNextTokenSpace (\r
+  IN OUT CONST EFI_GUID               **Guid\r
+  )\r
+;\r
+\r
+\r
+typedef struct {\r
+  LIST_ENTRY              Node;\r
+  PCD_PROTOCOL_CALLBACK   CallbackFn;\r
+} CALLBACK_FN_ENTRY;\r
+\r
+#define CR_FNENTRY_FROM_LISTNODE(Record, Type, Field) _CR(Record, Type, Field)\r
+\r
+//\r
+// Internal Functions\r
+//\r
+\r
+EFI_STATUS\r
+SetValueWorker (\r
+  IN UINTN                   TokenNumber,\r
+  IN VOID                    *Data,\r
+  IN UINTN                   Size\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+SetWorker (\r
+  IN          UINTN                     TokenNumber,\r
+  IN          VOID                      *Data,\r
+  IN OUT      UINTN                     *Size,\r
+  IN          BOOLEAN                   PtrType\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+ExSetValueWorker (\r
+  IN          UINTN                ExTokenNumber,\r
+  IN          CONST EFI_GUID       *Guid,\r
+  IN          VOID                 *Data,\r
+  IN          UINTN                SetSize\r
+  )\r
+;\r
+\r
+\r
+\r
+EFI_STATUS\r
+ExSetWorker (\r
+  IN      UINTN                ExTokenNumber,\r
+  IN      CONST EFI_GUID       *Guid,\r
+  IN      VOID                 *Data,\r
+  IN OUT  UINTN                *Size,\r
+  IN      BOOLEAN              PtrType\r
+  )\r
+;\r
+\r
+\r
+VOID *\r
+GetWorker (\r
+  IN UINTN             TokenNumber,\r
+  IN UINTN             GetSize\r
+  )\r
+;\r
+\r
+VOID *\r
+ExGetWorker (\r
+  IN CONST EFI_GUID         *Guid,\r
+  IN UINTN                  ExTokenNumber,\r
+  IN UINTN                  GetSize\r
+  ) \r
+;\r
+\r
+UINT32\r
+GetSkuEnabledTokenNumber (\r
+  UINT32 LocalTokenNumber,\r
+  UINTN  Size,\r
+  BOOLEAN IsPeiDb\r
+  ) \r
+;\r
+\r
+EFI_STATUS\r
+GetHiiVariable (\r
+  IN  EFI_GUID      *VariableGuid,\r
+  IN  UINT16        *VariableName,\r
+  OUT UINT8          **VariableData,\r
+  OUT UINTN         *VariableSize\r
+  )\r
+;\r
+\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
+  )\r
+;\r
+\r
+EFI_STATUS\r
+DxeRegisterCallBackWorker (\r
+  IN  UINTN                   TokenNumber,\r
+  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction\r
+);\r
+\r
+EFI_STATUS\r
+DxeUnRegisterCallBackWorker (\r
+  IN  UINTN                   TokenNumber,\r
+  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
+  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction\r
+);\r
+\r
+VOID\r
+BuildPcdDxeDataBase (\r
+  VOID\r
+);\r
+\r
+\r
+UINTN           \r
+GetExPcdTokenNumber (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINT32                     ExTokenNumber\r
+  )\r
+;\r
+\r
+\r
+\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
+  )\r
+;\r
+\r
+\r
+UINTN\r
+GetPtrTypeSize (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  OUT   UINTN             *MaxSize\r
+  )\r
+;\r
+\r
+\r
+\r
+BOOLEAN\r
+SetPtrTypeSize (\r
+  IN          UINTN             LocalTokenNumberTableIdx,\r
+  IN    OUT   UINTN             *CurrentSize\r
+  )\r
+;\r
+\r
+extern EFI_GUID gPcdDataBaseHobGuid;\r
+\r
+extern PCD_DATABASE * mPcdDatabase;\r
+\r
+extern DXE_PCD_DATABASE_INIT gDXEPcdDbInit;\r
+\r
+extern EFI_LOCK mPcdDatabaseLock;\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/PCD/Pei/CommonHeader.h b/MdeModulePkg/Universal/PCD/Pei/CommonHeader.h
new file mode 100644 (file)
index 0000000..c488c38
--- /dev/null
@@ -0,0 +1,40 @@
+/**@file\r
+  Common header file shared by all source files.\r
+\r
+  This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+   are licensed and made available under the terms and conditions of the BSD License\r
+   which accompanies this distribution. The full text of the license may be found at\r
+   http://opensource.org/licenses/bsd-license.php\r
+   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
+**/\r
+\r
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiPei.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Ppi/ReadOnlyVariable.h>\r
+#include <Ppi/Pcd.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.c b/MdeModulePkg/Universal/PCD/Pei/Pcd.c
new file mode 100644 (file)
index 0000000..b018e5a
--- /dev/null
@@ -0,0 +1,801 @@
+/** @file PCD PEIM\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+\r
+Module Name: Pcd.c\r
+\r
+**/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Service.h"\r
+\r
+\r
+PCD_PPI mPcdPpiInstance = {\r
+  PeiPcdSetSku,\r
+\r
+  PeiPcdGet8,\r
+  PeiPcdGet16,          \r
+  PeiPcdGet32,          \r
+  PeiPcdGet64,          \r
+  PeiPcdGetPtr,         \r
+  PeiPcdGetBool,     \r
+  PeiPcdGetSize,\r
+\r
+  PeiPcdGet8Ex,\r
+  PeiPcdGet16Ex,          \r
+  PeiPcdGet32Ex,          \r
+  PeiPcdGet64Ex,          \r
+  PeiPcdGetPtrEx,         \r
+  PeiPcdGetBoolEx,     \r
+  PeiPcdGetSizeEx,\r
+  \r
+  PeiPcdSet8,\r
+  PeiPcdSet16,          \r
+  PeiPcdSet32,          \r
+  PeiPcdSet64,          \r
+  PeiPcdSetPtr,         \r
+  PeiPcdSetBool,     \r
+\r
+  PeiPcdSet8Ex,\r
+  PeiPcdSet16Ex,          \r
+  PeiPcdSet32Ex,          \r
+  PeiPcdSet64Ex,          \r
+  PeiPcdSetPtrEx,         \r
+  PeiPcdSetBoolEx,\r
+\r
+  PeiRegisterCallBackOnSet,\r
+  PcdUnRegisterCallBackOnSet,\r
+  PeiPcdGetNextToken,\r
+  PeiPcdGetNextTokenSpace\r
+};\r
+\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
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PcdPeimInit (\r
+  IN EFI_FFS_FILE_HEADER      *FfsHeader,\r
+  IN EFI_PEI_SERVICES         **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  BuildPcdDatabase ();\r
+  \r
+  Status = PeiServicesInstallPpi (&mPpiPCD);\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PeiPcdSetSku (\r
+  IN  UINTN                  SkuId\r
+  )\r
+{\r
+\r
+  GetPcdDatabase()->Init.SystemSkuId = (SKU_ID) SkuId;\r
+\r
+  return;\r
+}\r
+\r
+\r
+\r
+UINT8\r
+EFIAPI\r
+PeiPcdGet8 (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));\r
+}\r
+\r
+\r
+\r
+UINT16\r
+EFIAPI\r
+PeiPcdGet16 (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));\r
+}\r
+\r
+\r
+\r
+UINT32\r
+EFIAPI\r
+PeiPcdGet32 (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));\r
+}\r
+\r
+\r
+\r
+UINT64\r
+EFIAPI\r
+PeiPcdGet64 (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64)));\r
+}\r
+\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+PeiPcdGetPtr (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return GetWorker (TokenNumber, 0);\r
+}\r
+\r
+\r
+\r
+BOOLEAN\r
+EFIAPI\r
+PeiPcdGetBool (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\r
+  return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));\r
+}\r
+\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+PeiPcdGetSize (\r
+  IN UINTN                    TokenNumber\r
+  )\r
+{\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
+\r
+UINT8\r
+EFIAPI\r
+PeiPcdGet8Ex (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
+  )\r
+{\r
+  return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8)));\r
+}\r
+\r
+\r
+\r
+UINT16\r
+EFIAPI\r
+PeiPcdGet16Ex (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16)));\r
+}\r
+\r
+\r
+\r
+UINT32\r
+EFIAPI\r
+PeiPcdGet32Ex (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32)));\r
+}\r
+\r
+\r
+\r
+UINT64\r
+EFIAPI\r
+PeiPcdGet64Ex (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
+  )\r
+{\r
+  return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64)));\r
+}\r
+\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+PeiPcdGetPtrEx (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
+  )\r
+{\r
+  return ExGetWorker (Guid, ExTokenNumber, 0);\r
+}\r
+\r
+\r
+\r
+BOOLEAN\r
+EFIAPI\r
+PeiPcdGetBoolEx (\r
+  IN CONST  EFI_GUID              *Guid,\r
+  IN UINTN                        ExTokenNumber\r
+  )\r
+{\r
+  return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN)));\r
+}\r
+\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+PeiPcdGetSizeEx (\r
+  IN CONST  EFI_GUID              *Guid,\r
+  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
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet8 (\r
+  IN UINTN                        TokenNumber,\r
+  IN UINT8                        Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet16 (\r
+  IN UINTN                         TokenNumber,\r
+  IN UINT16                        Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet32 (\r
+  IN UINTN                         TokenNumber,\r
+  IN UINT32                        Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet64 (\r
+  IN UINTN                         TokenNumber,\r
+  IN UINT64                        Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSetPtr (\r
+  IN      UINTN                    TokenNumber,\r
+  IN OUT  UINTN                    *SizeOfBuffer,\r
+  IN      VOID                     *Buffer\r
+  )\r
+{\r
+  return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSetBool (\r
+  IN UINTN                         TokenNumber,\r
+  IN BOOLEAN                       Value\r
+  )\r
+{\r
+  return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet8Ex (\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINT8                        Value\r
+  )\r
+{\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet16Ex (\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINT16                       Value\r
+  )\r
+{\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet32Ex (\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINT32                       Value\r
+  )\r
+{\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet64Ex (\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINT64                       Value\r
+  )\r
+{\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSetPtrEx (\r
+  IN CONST EFI_GUID               *Guid,\r
+  IN UINTN                        ExTokenNumber,\r
+  IN UINTN                        *SizeOfBuffer,\r
+  IN VOID                         *Value\r
+  )\r
+{\r
+  return ExSetWorker (ExTokenNumber, Guid, Value, SizeOfBuffer, TRUE);\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSetBoolEx (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber,\r
+  IN BOOLEAN                    Value\r
+  )\r
+{\r
+  return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
+}\r
+\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiRegisterCallBackOnSet (\r
+  IN  CONST EFI_GUID              *Guid, OPTIONAL\r
+  IN  UINTN                       ExTokenNumber,\r
+  IN  PCD_PPI_CALLBACK            CallBackFunction\r
+  )\r
+{\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
+\r
+EFI_STATUS\r
+EFIAPI\r
+PcdUnRegisterCallBackOnSet (\r
+  IN  CONST EFI_GUID              *Guid, OPTIONAL\r
+  IN  UINTN                       ExTokenNumber,\r
+  IN  PCD_PPI_CALLBACK            CallBackFunction\r
+  )\r
+{\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
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdGetNextToken (\r
+  IN CONST EFI_GUID               *Guid, OPTIONAL\r
+  IN OUT  UINTN                   *TokenNumber\r
+  )\r
+{\r
+  UINTN               GuidTableIdx;\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
+  EFI_GUID            *MatchGuid;\r
+  DYNAMICEX_MAPPING   *ExMapTable;\r
+  UINTN               i;\r
+  BOOLEAN             Found;\r
+  BOOLEAN             PeiExMapTableEmpty;\r
+\r
+  if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;\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 (PeiExMapTableEmpty) {\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
+  BOOLEAN             PeiExMapTableEmpty;\r
+\r
+  if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  ASSERT (Guid != NULL);\r
+\r
+  PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;\r
+\r
+  if (PeiExMapTableEmpty) {\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
+UINTN\r
+GetPtrTypeSize (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  OUT   UINTN             *MaxSize,\r
+  IN    PEI_PCD_DATABASE  *Database\r
+  )\r
+{\r
+  INTN        SizeTableIdx;\r
+  UINTN       LocalTokenNumber;\r
+  SKU_ID      *SkuIdTable;\r
+  SIZE_INFO   *SizeTable;\r
+  UINTN       i;\r
+\r
+  SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
+\r
+  LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
+\r
+  ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
+  \r
+  SizeTable = Database->Init.SizeTable;\r
+\r
+  *MaxSize = SizeTable[SizeTableIdx];\r
+  //\r
+  // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
+  // PCD entry.\r
+  //\r
+  if (LocalTokenNumber & PCD_TYPE_VPD) {\r
+      //\r
+      // We have only one entry for VPD enabled PCD entry:\r
+      // 1) MAX Size.\r
+      // We consider current size is equal to MAX size.\r
+      //\r
+      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, Database);\r
+      for (i = 0; i < SkuIdTable[0]; i++) {\r
+        if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {\r
+          return SizeTable[SizeTableIdx + 1 + i];\r
+        }\r
+      }\r
+      return SizeTable[SizeTableIdx + 1];\r
+    }\r
+  }\r
+}\r
+\r
+\r
+\r
+BOOLEAN\r
+SetPtrTypeSize (\r
+  IN          UINTN             LocalTokenNumberTableIdx,\r
+  IN    OUT   UINTN             *CurrentSize,\r
+  IN          PEI_PCD_DATABASE  *Database\r
+  )\r
+{\r
+  INTN        SizeTableIdx;\r
+  UINTN       LocalTokenNumber;\r
+  SKU_ID      *SkuIdTable;\r
+  SIZE_INFO   *SizeTable;\r
+  UINTN       i;\r
+  UINTN       MaxSize;\r
+  \r
+  SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
+\r
+  LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
+\r
+  ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
+  \r
+  SizeTable = Database->Init.SizeTable;\r
+\r
+  MaxSize = SizeTable[SizeTableIdx];\r
+  //\r
+  // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
+  // PCD entry.\r
+  //\r
+  if (LocalTokenNumber & PCD_TYPE_VPD) {\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
+    } 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, Database);\r
+      for (i = 0; i < SkuIdTable[0]; i++) {\r
+        if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {\r
+          SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize;\r
+          return TRUE;\r
+        }\r
+      }\r
+      SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+}\r
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.dxs b/MdeModulePkg/Universal/PCD/Pei/Pcd.dxs
new file mode 100644 (file)
index 0000000..3bad561
--- /dev/null
@@ -0,0 +1,25 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  Pcd.dxs\r
+\r
+Abstract:\r
+\r
+  Dependency expression source file.\r
+  \r
+--*/  \r
+#include <DxeDepex.h>\r
+\r
+DEPENDENCY_START\r
+  TRUE\r
+DEPENDENCY_END\r
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
new file mode 100644 (file)
index 0000000..506ab02
--- /dev/null
@@ -0,0 +1,140 @@
+#/** @file\r
+# Component description file for Pcd Database PEIM module\r
+#\r
+# This PEIM driver implement and produce PCD PPI.\r
+# Copyright (c) 2006 - 2007, Intel Corporation\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  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
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PcdPeim\r
+  FILE_GUID                      = 9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  PCD_DRIVER                     = PEI_PCD_DRIVER\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = PcdPeimInit\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  Service.c\r
+  Service.h\r
+  Pcd.c\r
+  CommonHeader.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  PeiServicesTablePointerLib\r
+  PcdLib\r
+  PeiServicesLib\r
+  HobLib\r
+  BaseLib\r
+  PeimEntryPoint\r
+  DebugLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Guid C Name Section - list of Guids that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Guids]\r
+  gPcdPeiCallbackFnTableHobGuid                 # ALWAYS_PRODUCED  Hob: GUID_EXTENSION\r
+  gPcdDataBaseHobGuid                           # ALWAYS_PRODUCED  Hob: GUID_EXTENSION\r
+\r
+\r
+################################################################################\r
+#\r
+# PPI C Name Section - list of PPI and PPI Notify C Names that this module\r
+#                      uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Ppis]\r
+  gEfiPeiReadOnlyVariablePpiGuid                # PPI ALWAYS_CONSUMED\r
+  gPcdPpiGuid                                   # PPI ALWAYS_PRODUCED\r
+\r
+\r
+################################################################################\r
+#\r
+# Pcd FEATURE_FLAG - list of PCDs that this module is coded for.\r
+#\r
+################################################################################\r
+\r
+[PcdsFeatureFlag.common]\r
+  PcdPeiPcdDatabaseSetEnabled|gEfiEdkModulePkgTokenSpaceGuid\r
+  PcdPeiPcdDatabaseGetSizeEnabled|gEfiEdkModulePkgTokenSpaceGuid\r
+  PcdPeiPcdDatabaseExEnabled|gEfiEdkModulePkgTokenSpaceGuid\r
+  PcdPeiPcdDatabaseCallbackOnSetEnabled|gEfiEdkModulePkgTokenSpaceGuid\r
+  PcdPeiPcdDatabaseTraverseEnabled|gEfiEdkModulePkgTokenSpaceGuid\r
+\r
+\r
+################################################################################\r
+#\r
+# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for.\r
+#\r
+################################################################################\r
+\r
+[PcdsFixedAtBuild.common]\r
+  PcdVpdBaseAddress|gEfiEdkModulePkgTokenSpaceGuid\r
+  PcdMaxPeiPcdCallBackNumberPerPcdEntry|gEfiEdkModulePkgTokenSpaceGuid\r
+\r
+\r
+################################################################################\r
+#\r
+# Dependency Expression Section - list of Dependency expressions that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Depex]\r
+  TRUE\r
+\r
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.msa b/MdeModulePkg/Universal/PCD/Pei/Pcd.msa
new file mode 100644 (file)
index 0000000..155a576
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>PcdPeim</ModuleName>\r
+    <ModuleType>PEIM</ModuleType>\r
+    <GuidValue>9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for Pcd Database PEIM module</Abstract>\r
+    <Description>This PEIM driver implement and produce PCD PPI.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>PcdPeim</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED" RecommendedInstanceGuid="bda39d3a-451b-4350-8266-81ab10fa0523">\r
+      <Keyword>DebugLib</Keyword>\r
+      <HelpText>Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg.</HelpText>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PeimEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>HobLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PeiServicesLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PcdLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PeiServicesTablePointerLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>Pcd.dxs</Filename>\r
+    <Filename>Pcd.c</Filename>\r
+    <Filename>Service.h</Filename>\r
+    <Filename>Service.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Hobs>\r
+    <HobTypes Usage="ALWAYS_PRODUCED" HobGuidCName="gPcdDataBaseHobGuid">\r
+      <HobType>GUID_EXTENSION</HobType>\r
+    </HobTypes>\r
+    <HobTypes Usage="ALWAYS_PRODUCED" HobGuidCName="gPcdPeiCallbackFnTableHobGuid">\r
+      <HobType>GUID_EXTENSION</HobType>\r
+    </HobTypes>\r
+  </Hobs>\r
+  <PPIs>\r
+    <Ppi Usage="ALWAYS_PRODUCED">\r
+      <PpiCName>gPcdPpiGuid</PpiCName>\r
+    </Ppi>\r
+    <Ppi Usage="ALWAYS_CONSUMED">\r
+      <PpiCName>gEfiPeiReadOnlyVariablePpiGuid</PpiCName>\r
+    </Ppi>\r
+  </PPIs>\r
+  <Externs>\r
+    <PcdIsDriver>PEI_PCD_DRIVER</PcdIsDriver>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>PcdPeimInit</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+  <PcdCoded>\r
+    <PcdEntry PcdItemType="FIXED_AT_BUILD" Usage="ALWAYS_CONSUMED">\r
+      <C_Name>PcdMaxPeiPcdCallBackNumberPerPcdEntry</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <HelpText>The maximum number of callback function, which will be triggered when \r
+        a PCD entry is been set, can be registered for a single PCD entry in PEI phase.</HelpText>\r
+    </PcdEntry>\r
+    <PcdEntry PcdItemType="FIXED_AT_BUILD" Usage="ALWAYS_CONSUMED">\r
+      <C_Name>PcdVpdBaseAddress</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <HelpText>The base address of the VPD (Vital Product Data) region. It is \r
+        normally a region reserved on flash.</HelpText>\r
+    </PcdEntry>\r
+    <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">\r
+      <C_Name>PcdPeiPcdDatabaseTraverseEnabled</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <HelpText>This feature flag can be used to enable or disable the Pcd PEIM database \r
+        traverse capability. Disable it can reduce the size of final image generated.</HelpText>\r
+    </PcdEntry>\r
+    <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">\r
+      <C_Name>PcdPeiPcdDatabaseCallbackOnSetEnabled</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <DefaultValue>FALSE</DefaultValue>\r
+      <HelpText>This feature flag can be used to enable or disable the Callback On SET capability of PCD service PEIM. If a platform does not register any callback on set  in PEI phase. This flag can be set to DISABLE to save size.</HelpText>\r
+    </PcdEntry>\r
+    <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">\r
+      <C_Name>PcdPeiPcdDatabaseExEnabled</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <DefaultValue>FALSE</DefaultValue>\r
+      <HelpText>This feature flag can be used to enable or disable the PCD service PEIM to handle DynamicEX PCD. If a platform has no module to use DynamicEX  in PEI phase. This flag can be set to DISABLE to save size.</HelpText>\r
+    </PcdEntry>\r
+    <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">\r
+      <C_Name>PcdPeiPcdDatabaseGetSizeEnabled</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <DefaultValue>FALSE</DefaultValue>\r
+      <HelpText>This feature flag can be used to enable or disable the GET size capability of PCD service PEIM. If a platform does not do PCD get size operation in PEI phase. This flag can be set to DISABLE to save size.</HelpText>\r
+    </PcdEntry>\r
+    <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">\r
+      <C_Name>PcdPeiPcdDatabaseSetEnabled</C_Name>\r
+      <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+      <DefaultValue>FALSE</DefaultValue>\r
+      <HelpText>This feature flag can be used to enable or disable the SET capability of PCD service PEIM. If a platform does not do PCD SET operation in PEI phase. This flag can be set to DISABLE to save size.</HelpText>\r
+    </PcdEntry>\r
+  </PcdCoded>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.c b/MdeModulePkg/Universal/PCD/Pei/Service.c
new file mode 100644 (file)
index 0000000..cb980da
--- /dev/null
@@ -0,0 +1,733 @@
+/** @file\r
+Private functions used by PCD PEIM.\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+Module Name: Service.c\r
+\r
+**/\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "Service.h"\r
+\r
+/**\r
+  The function registers the CallBackOnSet fucntion\r
+  according to TokenNumber and EFI_GUID space.\r
+\r
+  @param  TokenNumber       The token number.\r
+  @param  Guid              The GUID space.\r
+  @param  CallBackFunction  The Callback function to be registered.\r
+  @param  Register          To register or unregister the callback function.\r
+\r
+  @retval EFI_SUCCESS If the Callback function is registered.\r
+  @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
+  @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free\r
+                                slot left in the CallbackFnTable.\r
+--*/\r
+EFI_STATUS\r
+PeiRegisterCallBackWorker (\r
+  IN  UINTN                       ExTokenNumber,\r
+  IN  CONST EFI_GUID              *Guid, OPTIONAL\r
+  IN  PCD_PPI_CALLBACK            CallBackFunction,\r
+  IN  BOOLEAN                     Register\r
+)\r
+{\r
+  EFI_HOB_GUID_TYPE       *GuidHob;\r
+  PCD_PPI_CALLBACK        *CallbackTable;\r
+  PCD_PPI_CALLBACK        Compare;\r
+  PCD_PPI_CALLBACK        Assign;\r
+  UINT32                  LocalTokenNumber;\r
+  UINTN                   TokenNumber;\r
+  UINTN                   Idx;\r
+\r
+  if (Guid == NULL) {\r
+    TokenNumber = ExTokenNumber;\r
+\r
+    //\r
+    // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+    // We have to decrement TokenNumber by 1 to make it usable\r
+    // as the array index.\r
+    //\r
+    TokenNumber--;\r
+    ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1);\r
+  } else {\r
+    TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
+\r
+    //\r
+    // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+    // We have to decrement TokenNumber by 1 to make it usable\r
+    // as the array index.\r
+    //\r
+    TokenNumber--;\r
+    // 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
+\r
+\r
+  LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];\r
+\r
+  //\r
+  // We don't support SET for HII and VPD type PCD entry in PEI phase.\r
+  // So we will assert if any register callback for such PCD entry.\r
+  //\r
+  ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);\r
+  ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);\r
+\r
+  GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
+  ASSERT (GuidHob != NULL);\r
+  \r
+  CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
+  CallbackTable = CallbackTable + (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
+\r
+  Compare = Register? NULL: CallBackFunction;\r
+  Assign  = Register? CallBackFunction: NULL;\r
+\r
+\r
+  for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
+    if (CallbackTable[Idx] == Compare) {\r
+      CallbackTable[Idx] = Assign;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;\r
+\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+  The function builds the PCD database.\r
+\r
+  @param VOID\r
+\r
+  @retval VOID\r
+--*/\r
+VOID\r
+BuildPcdDatabase (\r
+  VOID\r
+  )\r
+{\r
+  PEI_PCD_DATABASE  *Database;\r
+  VOID              *CallbackFnTable;\r
+  UINTN             SizeOfCallbackFnTable;\r
+  \r
+  Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));\r
+\r
+  ZeroMem (Database, sizeof (PEI_PCD_DATABASE));\r
+\r
+  //\r
+  // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE\r
+  //\r
+  \r
+  CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));\r
+\r
+  SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
+\r
+  CallbackFnTable = BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid, SizeOfCallbackFnTable);\r
+  \r
+  ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
+  \r
+  return;\r
+}\r
+\r
+\r
+\r
+/**\r
+  The function is provided by PCD PEIM and PCD DXE driver to\r
+  do the work of reading a HII variable from variable service.\r
+\r
+  @param VariableGuid     The Variable GUID.\r
+  @param VariableName     The Variable Name.\r
+  @param VariableData    The output data.\r
+  @param VariableSize    The size of the variable.\r
+\r
+  @retval EFI_SUCCESS         Operation successful.\r
+  @retval EFI_NOT_FOUND         Variablel not found.\r
+--*/\r
+STATIC\r
+EFI_STATUS\r
+GetHiiVariable (\r
+  IN  CONST EFI_GUID      *VariableGuid,\r
+  IN  UINT16              *VariableName,\r
+  OUT VOID                **VariableData,\r
+  OUT UINTN               *VariableSize\r
+  )\r
+{\r
+  UINTN      Size;\r
+  EFI_STATUS Status;\r
+  VOID       *Buffer;\r
+  EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;\r
+\r
+  Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Size = 0;\r
+  Status = VariablePpi->PeiGetVariable (\r
+                          GetPeiServicesTablePointer (),\r
+                          VariableName,\r
+                          (EFI_GUID *) VariableGuid,\r
+                          NULL,\r
+                          &Size,\r
+                          NULL\r
+                            );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+\r
+\r
+    Status = PeiServicesAllocatePool (Size, &Buffer);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Status = VariablePpi->PeiGetVariable (\r
+                              GetPeiServicesTablePointer (),\r
+                              (UINT16 *) VariableName,\r
+                              (EFI_GUID *) VariableGuid,\r
+                              NULL,\r
+                              &Size,\r
+                              Buffer\r
+                              );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    *VariableSize = Size;\r
+    *VariableData = Buffer;\r
+\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+}\r
+\r
+STATIC\r
+UINT32\r
+GetSkuEnabledTokenNumber (\r
+  UINT32 LocalTokenNumber,\r
+  UINTN  Size\r
+  ) \r
+{\r
+  PEI_PCD_DATABASE      *PeiPcdDb;\r
+  SKU_HEAD              *SkuHead;\r
+  SKU_ID                *SkuIdTable;\r
+  INTN                  i;\r
+  UINT8                 *Value;\r
+\r
+  PeiPcdDb = GetPcdDatabase ();\r
+\r
+  ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
+\r
+  SkuHead     = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
+  Value       = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));\r
+  SkuIdTable  = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));\r
+        \r
+  for (i = 0; i < SkuIdTable[0]; i++) {\r
+    if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
+    case PCD_TYPE_VPD:\r
+      Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
+      return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);\r
+\r
+    case PCD_TYPE_HII:\r
+      Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
+      return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);\r
+      \r
+    case PCD_TYPE_STRING:\r
+      Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]);\r
+      return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);\r
+\r
+    case PCD_TYPE_DATA:\r
+      Value += Size * i;\r
+      return (UINT32) (Value - (UINT8 *) PeiPcdDb);\r
+\r
+    default:\r
+      ASSERT (FALSE);\r
+  }\r
+\r
+  ASSERT (FALSE);\r
+\r
+  return 0;\r
+  \r
+}\r
+\r
+\r
+\r
+STATIC\r
+VOID\r
+InvokeCallbackOnSet (\r
+  UINTN             ExTokenNumber,\r
+  CONST EFI_GUID    *Guid, OPTIONAL\r
+  UINTN             TokenNumber,\r
+  VOID              *Data,\r
+  UINTN             Size\r
+  )\r
+{\r
+  EFI_HOB_GUID_TYPE   *GuidHob;\r
+  PCD_PPI_CALLBACK    *CallbackTable;\r
+  UINTN               Idx;\r
+\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
+  if (Guid == NULL) {\r
+    // EBC compiler is very choosy. It may report warning about comparison\r
+    // between UINTN and 0 . So we add 1 in each size of the \r
+    // comparison.\r
+    ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
+  }\r
+\r
+  GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
+  ASSERT (GuidHob != NULL);\r
+  \r
+  CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
+\r
+  CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
+\r
+  for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
+    if (CallbackTable[Idx] != NULL) {\r
+      CallbackTable[Idx] (Guid,\r
+                          (Guid == NULL)? TokenNumber: ExTokenNumber,\r
+                          Data,\r
+                          Size\r
+                          );\r
+    }\r
+  }\r
+  \r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+SetValueWorker (\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
+EFI_STATUS\r
+SetWorker (\r
+  IN          UINTN               TokenNumber,\r
+  IN OUT      VOID                *Data,\r
+  IN OUT      UINTN               *Size,\r
+  IN          BOOLEAN             PtrType\r
+  )\r
+{\r
+  UINT32              LocalTokenNumber;\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
+  UINT16              StringTableIdx;\r
+  UINTN               Offset;\r
+  VOID                *InternalData;\r
+  UINTN               MaxSize;\r
+\r
+  if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  //\r
+  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
+  // We have to decrement TokenNumber by 1 to make it usable\r
+  // as the array index.\r
+  //\r
+  TokenNumber--;\r
+\r
+  // 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
+  PeiPcdDb = GetPcdDatabase ();\r
+\r
+  LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
+\r
+  if (!PtrType) {\r
+    ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);\r
+  }\r
+\r
+  //\r
+  // We only invoke the callback function for Dynamic Type PCD Entry.\r
+  // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r
+  // type PCD entry in ExSetWorker.\r
+  //\r
+  if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {\r
+    InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
+  }\r
+\r
+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
+    if (PtrType) {\r
+      MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
+    } else {\r
+      MaxSize = *Size;\r
+    }\r
+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
+  }\r
+\r
+  Offset          = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+  InternalData    = (VOID *) ((UINT8 *) PeiPcdDb + Offset);\r
+  \r
+  switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
+    case PCD_TYPE_VPD:\r
+    case PCD_TYPE_HII:\r
+    {\r
+      ASSERT (FALSE);\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    case PCD_TYPE_STRING:\r
+      if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
+        StringTableIdx = *((UINT16 *)InternalData);\r
+        CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+    case PCD_TYPE_DATA:\r
+    {\r
+      if (PtrType) {\r
+        if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
+          CopyMem (InternalData, Data, *Size);\r
+          return EFI_SUCCESS;\r
+        } else {\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+      }\r
+\r
+      switch (*Size) {\r
+        case sizeof(UINT8):\r
+          *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
+          return EFI_SUCCESS;\r
+\r
+        case sizeof(UINT16):\r
+          *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
+          return EFI_SUCCESS;\r
+\r
+        case sizeof(UINT32):\r
+          *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
+          return EFI_SUCCESS;\r
+\r
+        case sizeof(UINT64):\r
+          *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
+          return EFI_SUCCESS;\r
+\r
+        default:\r
+          ASSERT (FALSE);\r
+          return EFI_NOT_FOUND;\r
+      }\r
+    }\r
+      \r
+  }\r
+\r
+  ASSERT (FALSE);\r
+  return EFI_NOT_FOUND;\r
+\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+ExSetValueWorker (\r
+  IN          UINTN                ExTokenNumber,\r
+  IN          CONST EFI_GUID       *Guid,\r
+  IN          VOID                 *Data,\r
+  IN          UINTN                Size\r
+  )\r
+{\r
+  return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+ExSetWorker (\r
+  IN            UINTN                ExTokenNumber,\r
+  IN            CONST EFI_GUID       *Guid,\r
+  IN            VOID                 *Data,\r
+  IN OUT        UINTN                *Size,\r
+  IN            BOOLEAN              PtrType\r
+  )\r
+{\r
+  UINTN                     TokenNumber;\r
+\r
+  if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
+\r
+  InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r
+\r
+  return SetWorker (TokenNumber, Data, Size, PtrType);\r
+\r
+}\r
+\r
+\r
+\r
+\r
+VOID *\r
+ExGetWorker (\r
+  IN CONST  EFI_GUID  *Guid,\r
+  IN UINTN            ExTokenNumber,\r
+  IN UINTN            GetSize\r
+  )\r
+{\r
+  if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {\r
+    ASSERT (FALSE);\r
+    return 0;\r
+  }\r
+  \r
+  return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
+}\r
+\r
+\r
+\r
+\r
+VOID *\r
+GetWorker (\r
+  UINTN               TokenNumber,\r
+  UINTN               GetSize\r
+  )\r
+{\r
+  UINT32              Offset;\r
+  EFI_GUID            *Guid;\r
+  UINT16              *Name;\r
+  VARIABLE_HEAD       *VariableHead;\r
+  EFI_STATUS          Status;\r
+  UINTN               DataSize;\r
+  VOID                *Data;\r
+  UINT16              *StringTable;\r
+  UINT16              StringTableIdx;\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
+  UINT32              LocalTokenNumber;\r
+  UINTN               MaxSize;\r
+\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
+  ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));\r
+\r
+  PeiPcdDb        = GetPcdDatabase ();\r
+\r
+  LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
+\r
+  if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
+    if (GetSize == 0) {\r
+      MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
+    } else {\r
+      MaxSize = GetSize;\r
+    }\r
+    LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
+  }\r
+\r
+  Offset      = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
+  StringTable = PeiPcdDb->Init.StringTable;\r
+  \r
+  switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
+    case PCD_TYPE_VPD:\r
+    {\r
+      VPD_HEAD *VpdHead;\r
+      VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
+      return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
+    }\r
+      \r
+    case PCD_TYPE_HII:\r
+    {\r
+      VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
+      \r
+      Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);\r
+      Name = &StringTable[VariableHead->StringIndex];\r
+\r
+      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
+\r
+      if (Status == EFI_SUCCESS) {\r
+        return (VOID *) ((UINT8 *) Data + VariableHead->Offset);\r
+      } else {\r
+        //\r
+        // Return the default value specified by Platform Integrator \r
+        //\r
+        return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);\r
+      }\r
+    }\r
+\r
+    case PCD_TYPE_DATA:\r
+      return (VOID *) ((UINT8 *)PeiPcdDb + Offset);\r
+\r
+    case PCD_TYPE_STRING:\r
+      StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);\r
+      return (VOID *) (&StringTable[StringTableIdx]);\r
+\r
+    default:\r
+      ASSERT (FALSE);\r
+      break;\r
+      \r
+  }\r
+\r
+  ASSERT (FALSE);\r
+      \r
+  return NULL;\r
+  \r
+}\r
+\r
+\r
+\r
+UINTN           \r
+GetExPcdTokenNumber (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
+  )\r
+{\r
+  UINT32              i;\r
+  DYNAMICEX_MAPPING   *ExMap;\r
+  EFI_GUID            *GuidTable;\r
+  EFI_GUID            *MatchGuid;\r
+  UINTN               MatchGuidIdx;\r
+  PEI_PCD_DATABASE    *PeiPcdDb;\r
+\r
+  PeiPcdDb    = GetPcdDatabase();\r
+  \r
+  ExMap       = PeiPcdDb->Init.ExMapTable;\r
+  GuidTable   = PeiPcdDb->Init.GuidTable;\r
+\r
+  MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
+  //\r
+  // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
+  // error in the BUILD system.\r
+  //\r
+  ASSERT (MatchGuid != NULL);\r
+  \r
+  MatchGuidIdx = MatchGuid - GuidTable;\r
+  \r
+  for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
+    if ((ExTokenNumber == ExMap[i].ExTokenNumber) && \r
+        (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
+      return ExMap[i].LocalTokenNumber;\r
+    }\r
+  }\r
+  \r
+  ASSERT (FALSE);\r
+  \r
+  return 0;\r
+}\r
+\r
+\r
+\r
+PEI_PCD_DATABASE *\r
+GetPcdDatabase (\r
+  VOID\r
+  )\r
+{\r
+  EFI_HOB_GUID_TYPE *GuidHob;\r
+\r
+  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
+  ASSERT (GuidHob != NULL);\r
+  \r
+  return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
+}\r
+\r
+\r
+\r
+SKU_ID *\r
+GetSkuIdArray (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  IN    PEI_PCD_DATABASE  *Database\r
+  )\r
+{\r
+  SKU_HEAD *SkuHead;\r
+  UINTN     LocalTokenNumber;\r
+\r
+  LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
+\r
+  ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
+\r
+  SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
+\r
+  return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);\r
+  \r
+}\r
+\r
+\r
+\r
+UINTN\r
+GetSizeTableIndex (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  IN    PEI_PCD_DATABASE  *Database\r
+  )\r
+{\r
+  UINTN       i;\r
+  UINTN        SizeTableIdx;\r
+  UINTN       LocalTokenNumber;\r
+  SKU_ID      *SkuIdTable;\r
+  \r
+  SizeTableIdx = 0;\r
+\r
+  for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
+    LocalTokenNumber = Database->Init.LocalTokenNumberTable[i];\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
+      // PCD entry.\r
+      //\r
+      if (LocalTokenNumber & PCD_TYPE_VPD) {\r
+          //\r
+          // We have only one entry for VPD enabled PCD entry:\r
+          // 1) MAX Size.\r
+          // We consider current size is equal to MAX size.\r
+          //\r
+          SizeTableIdx++;\r
+      } 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 (i, Database);\r
+          SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
+        }\r
+      }\r
+    }\r
+\r
+  }\r
+\r
+  return SizeTableIdx;\r
+}\r
diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.h b/MdeModulePkg/Universal/PCD/Pei/Service.h
new file mode 100644 (file)
index 0000000..9c3c70a
--- /dev/null
@@ -0,0 +1,462 @@
+/** @file\r
+Private functions used by PCD PEIM.\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+\r
+Module Name: Service.h\r
+\r
+**/\r
+\r
+#ifndef _SERVICE_H\r
+#define _SERVICE_H\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+//\r
+// Please make sure the PCD Serivce PEIM Version is consistent with\r
+// the version of PCD Database generation tool\r
+//\r
+#define PCD_SERVICE_PEIM_VERSION      2\r
+\r
+//\r
+// PCD_PEI_DATABASE_GENTOOL_VERSION is defined in Autogen.h\r
+// and generated by PCD Database generation tool.\r
+//\r
+#if (PCD_SERVICE_PEIM_VERSION != PCD_PEI_SERVICE_DRIVER_AUTOGEN_VERSION )\r
+  #error "Please make sure the version of PCD Service PEIM and PCD PEI Database Generation Tool matches"\r
+#endif\r
+\r
+//\r
+// PPI Interface Implementation Declaration.\r
+//\r
+VOID\r
+EFIAPI\r
+PeiPcdSetSku (\r
+  IN  UINTN                  SkuId\r
+  )\r
+;\r
+\r
+\r
+UINT8\r
+EFIAPI\r
+PeiPcdGet8 (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT16\r
+EFIAPI\r
+PeiPcdGet16 (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT32\r
+EFIAPI\r
+PeiPcdGet32 (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT64\r
+EFIAPI\r
+PeiPcdGet64 (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+PeiPcdGetPtr (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+BOOLEAN\r
+EFIAPI\r
+PeiPcdGetBool (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+PeiPcdGetSize (\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT8\r
+EFIAPI\r
+PeiPcdGet8Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT16\r
+EFIAPI\r
+PeiPcdGet16Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+UINT32\r
+EFIAPI\r
+PeiPcdGet32Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINT64\r
+EFIAPI\r
+PeiPcdGet64Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+VOID *\r
+EFIAPI\r
+PeiPcdGetPtrEx (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+BOOLEAN\r
+EFIAPI\r
+PeiPcdGetBoolEx (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+UINTN\r
+EFIAPI\r
+PeiPcdGetSizeEx (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet8 (\r
+  IN UINTN             TokenNumber,\r
+  IN UINT8             Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet16 (\r
+  IN UINTN             TokenNumber,\r
+  IN UINT16            Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet32 (\r
+  IN UINTN             TokenNumber,\r
+  IN UINT32            Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet64 (\r
+  IN UINTN             TokenNumber,\r
+  IN UINT64            Value\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSetPtr (\r
+  IN        UINTN             TokenNumber,\r
+  IN OUT    UINTN             *SizeOfBuffer,\r
+  IN        VOID              *Buffer\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSetBool (\r
+  IN UINTN             TokenNumber,\r
+  IN BOOLEAN           Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet8Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN UINT8             Value\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet16Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN UINT16            Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet32Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN UINT32            Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSet64Ex (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN UINT64            Value\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSetPtrEx (\r
+  IN        CONST EFI_GUID    *Guid,\r
+  IN        UINTN             TokenNumber,\r
+  IN OUT    UINTN             *SizeOfBuffer,\r
+  IN        VOID              *Buffer\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdSetBoolEx (\r
+  IN CONST EFI_GUID    *Guid,\r
+  IN UINTN             TokenNumber,\r
+  IN BOOLEAN           Value\r
+  )\r
+;\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiRegisterCallBackOnSet (\r
+  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
+  IN  UINTN                   TokenNumber,\r
+  IN  PCD_PPI_CALLBACK        CallBackFunction\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PcdUnRegisterCallBackOnSet (\r
+  IN  CONST EFI_GUID          *Guid, OPTIONAL\r
+  IN  UINTN                   TokenNumber,\r
+  IN  PCD_PPI_CALLBACK        CallBackFunction\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdGetNextToken (\r
+  IN CONST EFI_GUID           *Guid, OPTIONAL\r
+  IN OUT  UINTN               *TokenNumber\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiPcdGetNextTokenSpace (\r
+  IN CONST EFI_GUID           **Guid\r
+  )\r
+;\r
+\r
+\r
+/* Internal Function definitions */\r
+\r
+PEI_PCD_DATABASE *\r
+GetPcdDatabase (\r
+  VOID\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+SetValueWorker (\r
+  IN          UINTN              TokenNumber,\r
+  IN          VOID               *Data,\r
+  IN          UINTN              Size\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+SetWorker (\r
+  IN          UINTN              TokenNumber,\r
+  IN          VOID               *Data,\r
+  IN OUT      UINTN              *Size,\r
+  IN          BOOLEAN            PtrType\r
+  )\r
+;\r
+\r
+\r
+EFI_STATUS\r
+ExSetValueWorker (\r
+  IN          UINTN                ExTokenNumber,\r
+  IN          CONST EFI_GUID       *Guid,\r
+  IN          VOID                 *Data,\r
+  IN          UINTN                Size\r
+  )\r
+;\r
+\r
+\r
+\r
+EFI_STATUS\r
+ExSetWorker (\r
+  IN      UINTN                ExTokenNumber,\r
+  IN      CONST EFI_GUID       *Guid,\r
+  IN      VOID                 *Data,\r
+  IN OUT  UINTN                *Size,\r
+  IN      BOOLEAN              PtrType\r
+  )\r
+;\r
+\r
+\r
+\r
+VOID *\r
+GetWorker (\r
+  IN UINTN                TokenNumber,\r
+  IN UINTN                GetSize\r
+  )\r
+;\r
+\r
+\r
+\r
+VOID *\r
+ExGetWorker (\r
+  IN CONST EFI_GUID   *Guid,\r
+  IN UINTN            ExTokenNumber,\r
+  IN UINTN            GetSize\r
+  )\r
+;\r
+\r
+typedef struct {\r
+  UINTN   TokenNumber;\r
+  UINTN   Size;\r
+  UINT32  LocalTokenNumberAlias;\r
+} EX_PCD_ENTRY_ATTRIBUTE;\r
+\r
+\r
+UINTN           \r
+GetExPcdTokenNumber (\r
+  IN CONST EFI_GUID             *Guid,\r
+  IN UINTN                      ExTokenNumber\r
+  )\r
+;\r
+\r
+\r
+\r
+\r
+EFI_STATUS\r
+PeiRegisterCallBackWorker (\r
+  IN  UINTN              TokenNumber,\r
+  IN  CONST GUID         *Guid, OPTIONAL\r
+  IN  PCD_PPI_CALLBACK   CallBackFunction,\r
+  IN  BOOLEAN            Register\r
+);\r
+\r
+\r
+\r
+\r
+VOID\r
+BuildPcdDatabase (\r
+  VOID\r
+  )\r
+;\r
+\r
+SKU_ID *\r
+GetSkuIdArray (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  IN    PEI_PCD_DATABASE  *Database\r
+  )\r
+;\r
+\r
+UINTN\r
+GetSizeTableIndex (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  IN    PEI_PCD_DATABASE  *Database\r
+  )\r
+;\r
+\r
+UINTN\r
+GetPtrTypeSize (\r
+  IN    UINTN             LocalTokenNumberTableIdx,\r
+  OUT   UINTN             *MaxSize,\r
+  IN    PEI_PCD_DATABASE  *Database\r
+  )\r
+;\r
+\r
+\r
+\r
+BOOLEAN\r
+SetPtrTypeSize (\r
+  IN          UINTN             LocalTokenNumberTableIdx,\r
+  IN    OUT   UINTN             *CurrentSize,\r
+  IN          PEI_PCD_DATABASE  *Database\r
+  )\r
+;\r
+\r
+\r
+extern EFI_GUID gPcdDataBaseHobGuid;\r
+\r
+extern EFI_GUID gPcdPeiCallbackFnTableHobGuid;\r
+\r
+extern PEI_PCD_DATABASE_INIT gPEIPcdDbInit;\r
+\r
+#endif\r