summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/PCD
diff options
context:
space:
mode:
authorbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
committerbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
commit878ddf1fc3540a715f63594ed22b6929e881afb4 (patch)
treec56c44dac138137b510e1fba7c3efe5e4d84bea2 /EdkModulePkg/Universal/PCD
downloadedk2-878ddf1fc3540a715f63594ed22b6929e881afb4.zip
edk2-878ddf1fc3540a715f63594ed22b6929e881afb4.tar.gz
edk2-878ddf1fc3540a715f63594ed22b6929e881afb4.tar.bz2
Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Universal/PCD')
-rw-r--r--EdkModulePkg/Universal/PCD/Common/PcdCommon.c592
-rw-r--r--EdkModulePkg/Universal/PCD/Common/PcdCommon.h386
-rw-r--r--EdkModulePkg/Universal/PCD/Dxe/Pcd.c472
-rw-r--r--EdkModulePkg/Universal/PCD/Dxe/Service.c491
-rw-r--r--EdkModulePkg/Universal/PCD/Dxe/Service.h399
-rw-r--r--EdkModulePkg/Universal/PCD/Pei/Pcd.c486
-rw-r--r--EdkModulePkg/Universal/PCD/Pei/Service.c812
-rw-r--r--EdkModulePkg/Universal/PCD/Pei/Service.h371
-rw-r--r--EdkModulePkg/Universal/PCD/Test/PcdTest.c110
-rw-r--r--EdkModulePkg/Universal/PCD/Test/PcdTest.dxs28
10 files changed, 4147 insertions, 0 deletions
diff --git a/EdkModulePkg/Universal/PCD/Common/PcdCommon.c b/EdkModulePkg/Universal/PCD/Common/PcdCommon.c
new file mode 100644
index 0000000..1af93c1
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Common/PcdCommon.c
@@ -0,0 +1,592 @@
+/** @file
+Common functions used by PCD PEIM and PCD DXE.
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: PcdCommon.c
+
+**/
+#include "PcdCommon.h"
+
+
+
+/**
+ The function retrieves the PCD data value according to
+ the PCD_DATA_TYPE specified.
+
+ @param[in] Type The PCD_DATA_TYPE used to interpret the data.
+ @param[in] InData The input data.
+ @param[in] OutData The output data.
+ @param[in] Len The length of the data; it is mainly used for PcdPointer type.
+
+ @retval VOID
+--*/
+VOID
+GetDataBasedOnType (
+ IN PCD_DATA_TYPE Type,
+ IN VOID *InData,
+ OUT VOID *OutData,
+ IN UINTN Len
+ )
+{
+ if (Type == PcdPointer) {
+ //
+ // When the Type is PcdPointer, we are returning
+ // the address of the internal buffer kpet by
+ // PCD database. Therefore, we treat OutData as
+ // a pointer to a "VOID *". Thus, the ugly type cast
+ // (VOID **) is used.
+ //
+
+ *((VOID **) OutData) = InData;
+ } else {
+ CopyMem (OutData, InData, Len);
+ }
+
+ return;
+
+}
+
+UINTN
+GetExtendedDataOffset (
+ IN CONST PCD_INDEX *PcdIndex,
+ IN UINTN SkuIdx,
+ IN CONST PCD_DATABASE_HEADER *Info
+ )
+{
+ UINT8 *OffsetAddress;
+ UINTN Offset;
+
+ OffsetAddress = GetAbsoluteAddress (PcdIndex->ExtendedDataOffset,
+ Info->ImageIndexOffset,
+ Info
+ );
+
+ OffsetAddress += (SkuIdx * Info->ExtendedOffsetLength);
+
+
+ CopyMem (&Offset, OffsetAddress, Info->ExtendedOffsetLength);
+
+ return Offset;
+}
+
+
+
+VOID
+GetHiiDataProperty (
+ IN CONST PCD_INDEX *PcdIndex,
+ IN UINTN SkuIdx,
+ IN CONST PCD_DATABASE_HEADER *Info,
+ OUT EFI_GUID **VariableGuid,
+ OUT UINT16 **VariableName
+ )
+{
+ UINT16 NameOffset;
+ UINT16 GuidOffset;
+ UINT8 *HiiDataOffset;
+
+ HiiDataOffset = GetAbsoluteAddress (PcdIndex->HiiData, Info->ImageIndexOffset, Info);
+ HiiDataOffset += (SkuIdx * (Info->HiiGuidOffsetLength + Info->HiiVariableOffsetLength));
+
+ CopyMem (&GuidOffset, HiiDataOffset, Info->HiiGuidOffsetLength);
+ CopyMem (&NameOffset, HiiDataOffset + Info->HiiGuidOffsetLength, Info->HiiVariableOffsetLength);
+
+ *VariableGuid = (EFI_GUID *) GetAbsoluteAddress (GuidOffset * sizeof (EFI_GUID), Info->GuidTableOffset, Info);
+ *VariableName = (UINT16 *) GetAbsoluteAddress (NameOffset * sizeof (UINT16) , Info->StringTableOffset, Info);
+
+ return;
+}
+
+
+
+UINTN
+GetSkuIdIdx (
+ IN CONST PCD_INDEX *PcdIndex,
+ IN CONST PCD_DATABASE_HEADER *Info
+ )
+{
+ UINT8 *SkuIdArray;
+ UINTN SkuIdx;
+
+ SkuIdArray = GetAbsoluteAddress (PcdIndex->SkuIdArray, Info->ImageIndexOffset, Info);
+
+ SkuIdx = 0;
+
+ if (PcdIndex->StateByte.SkuEnable) {
+
+ for (; SkuIdx < PcdIndex->SkuCount; SkuIdx++) {
+ if (SkuIdArray[SkuIdx] == Info->SkuId) {
+ break;
+ }
+ }
+
+ if (SkuIdx > PcdIndex->SkuCount) {
+ if (Info->SkuId == 0) {
+ //
+ // If no SKU_ID is set previously
+ // Just retrieve the first value
+ //
+ SkuIdx = 0;
+ } else {
+ //
+ // Just can't find the SKU_ID, ASSERT according to Spec.
+ //
+ ASSERT (FALSE);
+ }
+ }
+
+ }
+
+ return SkuIdx;
+
+}
+
+
+
+/**
+ The function is the worker function to get the data of a PCD entry.
+
+ @param[in] PcdIndex The PCD Index.
+ @param[in] Info The attributes of the PCD database.
+ @param[out] Data The output data.
+
+ @retval VOID
+--*/
+UINT8*
+GetPcdDataPtr (
+ IN CONST PCD_INDEX *PcdIndex,
+ IN CONST PCD_DATABASE_HEADER *Info
+ )
+{
+ UINTN VariableDataSize;
+ VOID *VariableData;
+ UINT16 *VariableName;
+ UINT8 *PcdData;
+ EFI_GUID *VariableGuid;
+ EFI_STATUS Status;
+ UINTN SkuIdx;
+ UINTN ExtendedOffset;
+
+ //
+ // If Sku is not enalbed for this PCD Entry.
+ // SkuIdx 0 will be used to compute PcdData
+ //
+ SkuIdx = GetSkuIdIdx (PcdIndex, Info);
+
+ if (PcdIndex->StateByte.HiiEnable) {
+
+ GetHiiDataProperty (PcdIndex, SkuIdx, Info, &VariableGuid, &VariableName);
+
+ Status = GetHiiVariable (VariableGuid, VariableName, &VariableData, &VariableDataSize);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (VariableDataSize >= (PcdIndex->DatumSize + PcdIndex->ExtendedDataOffset));
+
+ PcdData = (UINT8 *) VariableData + PcdIndex->ExtendedDataOffset;
+
+ return PcdData;
+ }
+
+ //
+ // For VPD and Data type, we need the ExtendedOffset.
+ // So get it here.
+ //
+ ExtendedOffset = GetExtendedDataOffset (PcdIndex, SkuIdx, Info);
+
+ if (PcdIndex->StateByte.VpdEnable) {
+
+ PcdData = (VOID *) (Info->VpdStart + ExtendedOffset);
+
+ return PcdData;
+ }
+
+ //
+ // For data type, we just need the pointer
+ //
+ PcdData = GetAbsoluteAddress (
+ ExtendedOffset,
+ Info->DataBufferOffset,
+ Info
+ );
+
+ return PcdData;
+
+}
+
+
+
+/**
+ The function locates the PCD_INDEX according to TokeNumber and GUID space given.
+
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The GUID token space.
+ @param[out] Info The attributes of the PCD database.
+
+ @retval PCD_INDEX* The PCD_INDEX found.
+--*/
+PCD_INDEX *
+FindPcdIndex (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid,
+ IN CONST PCD_DATABASE_HEADER *Info,
+ OUT UINTN *Index
+ )
+{
+ PCD_INDEX *PcdIndex;
+ UINTN Idx;
+ EFI_GUID *GuidSpace;
+
+ PcdIndex = (PCD_INDEX *) GetAbsoluteAddress (0, Info->PcdIndexOffset, Info);
+
+ for (Idx = 0; Idx < Info->EntryCount; Idx++, PcdIndex++) {
+ if (Index != NULL) {
+ *Index = Idx;
+ }
+
+ if (PcdIndex->TokenNumber == TokenNumber) {
+ if (Guid == NULL) {
+ if (!PcdIndex->StateByte.ExtendedGuidPresent) {
+ return PcdIndex;
+ }
+ } else {
+ if (PcdIndex->StateByte.ExtendedGuidPresent) {
+ GuidSpace = (EFI_GUID *) GetAbsoluteAddress (PcdIndex->DynamicExGuid, Info->GuidTableOffset, Info);
+ if (CompareGuid (GuidSpace, Guid)) {
+ return PcdIndex;
+ }
+ }
+ }
+ }
+
+ }
+
+ if (Index != NULL) {
+ *Index = 0;
+ }
+
+ return NULL;
+
+}
+
+
+
+/**
+ The function set the PCD Entry data value according to the
+ PCD_DATA_TYPE given.
+
+ @param[out] OutData The output data.
+ @param[in] InData The input data.
+ @param[in] Len The length of the data.
+
+
+ @retval EFI_SUCESS If data value is found according to SKU_ID.
+ @retval EFI_NOT_FOUND If not such a value is found.
+
+--*/
+VOID
+SetDataBasedOnType (
+ OUT VOID * OutData,
+ IN CONST VOID * InData,
+ IN UINTN Len
+)
+{
+ CopyMem (OutData, InData, Len);
+
+ return;
+}
+
+
+
+/**
+ The function returns the actual address of item in the PCD
+ database according to its Segment and Offset.
+
+ @param[out] Offset The offset within the segment.
+ @param[in] SegmentStart The starting address of the segment.
+ @param[in] DatabaseStart The base address of the PCD DataBase.
+
+
+ @retval UINT8* The absolute address.
+
+--*/
+UINT8 *
+GetAbsoluteAddress (
+ IN UINTN Offset,
+ IN UINTN SegmentStart,
+ IN CONST PCD_DATABASE_HEADER *DatabaseStart
+ )
+{
+ UINT8 *Address;
+
+ Address = (UINT8 *) DatabaseStart + SegmentStart + Offset;
+
+ return Address;
+}
+
+
+
+/**
+ The function retrieves the PCD data value according to
+ TokenNumber and Guid space given.
+
+ @param[in] Database The PCD Database Instance.
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+ @param[in] Type The storage type.
+ @param[out] Data The output data.
+
+ @retval VOID
+
+--*/
+VOID
+GetPcdEntryWorker (
+ IN CONST PCD_DATABASE_HEADER *Info,
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ OUT VOID *Data
+ )
+{
+ PCD_INDEX *PcdIndex;
+ UINT8 *PcdData;
+
+ ASSERT (Data != NULL);
+
+ //
+ // Find the PCD entry in list in memory first
+ //
+ PcdIndex = FindPcdIndex (TokenNumber, Guid, Info, NULL);
+
+ ASSERT (PcdIndex != NULL);
+
+ ASSERT (PcdIndex->StateByte.DataType == Type);
+
+ PcdData = GetPcdDataPtr (PcdIndex, Info);
+
+ GetDataBasedOnType (PcdIndex->StateByte.DataType, PcdData, Data, PcdIndex->DatumSize);
+
+ return;
+}
+
+
+
+/**
+ The function retrieves the PCD data value according to
+ TokenNumber and Guid space given.
+
+ @param[in] Database The PCD Database Instance.
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+
+ @retval UINTN The size of the PCD Entry.
+
+--*/
+UINTN
+GetPcdEntrySizeWorker (
+ IN CONST PCD_DATABASE_HEADER *Info,
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid OPTIONAL
+ )
+{
+ PCD_INDEX *PcdIndex;
+
+ //
+ // Find the PCD entry in list in memory first
+ //
+ PcdIndex = FindPcdIndex (TokenNumber, Guid, Info, NULL);
+
+ ASSERT (PcdIndex != NULL);
+
+ return PcdIndex->DatumSize;
+
+}
+
+
+
+/**
+ The function checks if given GUID space match the record
+ in the PCD_INDEX.
+
+ @param[in] Guid The GUID space.
+ @param[in] PcdIndex The PCD_INDEX.
+ @param[in] Info The attribute of the PCD DATABASE.
+
+ @retval TRUE The GUID space match the record.
+ @retval FALSE Othewise.
+
+--*/
+BOOLEAN
+PeiImageIndexMatchGuidSpace (
+ IN CONST EFI_GUID *Guid,
+ IN CONST PCD_INDEX *PcdIndex,
+ IN CONST PCD_DATABASE_HEADER *Info
+)
+{
+ EFI_GUID *GuidSpace;
+
+ if (PcdIndex->StateByte.ExtendedGuidPresent) {
+ GuidSpace = (EFI_GUID *) GetAbsoluteAddress (PcdIndex->DynamicExGuid, Info->GuidTableOffset, Info);
+ return CompareGuid (GuidSpace, Guid);
+ }
+
+ return FALSE;
+}
+
+
+/**
+ The function looks for the next PCD ENTRY.
+ If *TokenNumber is 0, the first TokenNumber in
+ the GUID token space is return.
+ If there is no next TokenNumber found,
+ *TokenNumber will be 0.
+
+ @param[in] Database The PCD Database Instance.
+ @param[in,out] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+
+ @retval EFI_NOT_FOUND Can't find the PCD_ENTRY.
+ @retval EFI_SUCCESS Operation succesful.
+
+--*/
+EFI_STATUS
+GetNextTokenWorker (
+ IN CONST PCD_DATABASE_HEADER *Info,
+ IN OUT UINTN *TokenNumber,
+ IN CONST EFI_GUID *Guid OPTIONAL
+ )
+{
+ PCD_INDEX *PcdIndex;
+ UINTN Idx;
+ BOOLEAN Found;
+
+ Idx = 0;
+ Found = FALSE;
+ PcdIndex = (PCD_INDEX *) GetAbsoluteAddress (0, Info->PcdIndexOffset, Info);
+
+ while ((Idx < Info->EntryCount) && !Found) {
+ if (*TokenNumber == 0) {
+ if (Guid == NULL || PeiImageIndexMatchGuidSpace (Guid, PcdIndex, Info)) {
+ *TokenNumber = PcdIndex->TokenNumber;
+ return EFI_SUCCESS;
+ }
+ } else {
+ if (PcdIndex->TokenNumber == *TokenNumber) {
+ if (Guid == NULL || PeiImageIndexMatchGuidSpace (Guid, PcdIndex, Info)) {
+ Found = TRUE;
+ }
+ }
+ }
+
+ PcdIndex++;
+ Idx++;
+ }
+
+ //
+ // No PCD Entry in the database match the GUID space given.
+ //
+ if (*TokenNumber == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Can't find the PCD Entry
+ //
+ if (!Found) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Move to the Next Entry
+ //
+ Idx++;
+ PcdIndex++;
+
+ //
+ // Now look for the Next TokenNumber
+ //
+ while (Idx < Info->EntryCount) {
+ if (Guid == NULL || PeiImageIndexMatchGuidSpace (Guid, PcdIndex, Info)) {
+ *TokenNumber = PcdIndex->TokenNumber;
+ return EFI_SUCCESS;
+ }
+ PcdIndex++;
+ Idx++;
+ }
+
+ //
+ // Reache the last TokeNumber.
+ //
+ *TokenNumber = 0;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ The function is the worker function to set the data of a PCD entry.
+
+ @param[in] PcdIndex The PCD Index.
+ @param[in] Info The attributes of the PCD database.
+ @param[in] Data The input data.
+
+ @retval VOID
+--*/
+EFI_STATUS
+SetPcdData (
+ IN CONST PCD_INDEX *PcdIndex,
+ IN CONST PCD_DATABASE_HEADER *Info,
+ IN CONST VOID *Data
+ )
+{
+ UINT16 *VariableName;
+ UINT8 *PcdData;
+ EFI_GUID *VariableGuid;
+ EFI_STATUS Status;
+ UINTN SkuIdx;
+ UINTN ExtendedOffset;
+
+ if (PcdIndex->StateByte.VpdEnable) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SkuIdx = GetSkuIdIdx (PcdIndex, Info);
+
+ //
+ // For Hii and Data type, we need the ExtendedOffset.
+ // So get it here.
+ //
+ ExtendedOffset = GetExtendedDataOffset (PcdIndex, SkuIdx, Info);
+
+ if (PcdIndex->StateByte.HiiEnable) {
+ GetHiiDataProperty (PcdIndex, SkuIdx, Info, &VariableGuid, &VariableName);
+
+ Status = SetHiiVariable (VariableGuid,
+ VariableName,
+ Data,
+ PcdIndex->DatumSize,
+ ExtendedOffset
+ );
+
+ return Status;
+ }
+
+
+ PcdData = GetAbsoluteAddress (
+ ExtendedOffset,
+ Info->DataBufferOffset,
+ Info
+ );
+
+ CopyMem (PcdData, Data, PcdIndex->DatumSize);
+
+ return EFI_SUCCESS;
+
+}
+
diff --git a/EdkModulePkg/Universal/PCD/Common/PcdCommon.h b/EdkModulePkg/Universal/PCD/Common/PcdCommon.h
new file mode 100644
index 0000000..f61aa5b
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Common/PcdCommon.h
@@ -0,0 +1,386 @@
+/** @file
+Common functions used by PCD PEIM and PCD DXE.
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: PcdCommon.h
+
+**/
+
+#ifndef __PCD_COMMON_H__
+#define __PCD_COMMON_H__
+
+//
+// Enumeration for PCD_DATA_TYPE
+//
+typedef enum {
+ PcdByte8,
+ PcdByte16,
+ PcdByte32,
+ PcdByte64,
+ PcdPointer,
+ PcdBoolean
+} PCD_DATA_TYPE;
+
+
+//
+// The definitions for Global PCD Length Fields
+//
+#define PCD_LENGTH_BIT8 0x01
+#define PCD_LENGTH_BIT16 0x02
+#define PCD_LENGTH_BIT24 0x03
+#define PCD_LENGTH_BIT32 0x04
+
+
+
+/*
+ * This data structure is used in <PCD_IMAGE> transverse
+ */
+typedef struct {
+ UINTN EntryCount;
+ UINTN GlobalOffsetLength;
+ UINTN GlobalTokenLength;
+ UINTN GlobalGuidTabIdxLength;
+ UINTN GlobalDatumLength;
+ UINTN GlobalStrTabIdxLength;
+
+ CONST UINT8 *DataDefaultStart;
+ UINTN DataDefaultLength;
+ UINTN WholeDataDefaultLength;
+ CONST UINT8 *IndexStart;
+ UINTN IndexLength;
+ CONST GUID *GuidTableStart;
+ UINTN GuidTableLength;
+ CONST UINT16 *StringTableStart;
+ UINTN StringTableLength;
+ /* Length of the <PCD_IMAGE> in byte.
+ This info is from Section header
+ in FFS */
+ UINTN ImageLength;
+ CONST UINT8 *ImageStart;
+
+} PCD_IMAGE_RECORD;
+
+
+
+typedef struct {
+ BOOLEAN HiiEnable;
+ BOOLEAN SkuEnable;
+ BOOLEAN VpdEnable;
+ BOOLEAN SkuDataArrayEnable;
+ PCD_DATA_TYPE DataType;
+ BOOLEAN ExtendedGuidPresent;
+} PCD_STATEBYTE;
+
+
+
+typedef struct {
+ //
+ // All Pointer's Offset in byte
+ //
+ UINT32 TokenNumber;
+ PCD_STATEBYTE StateByte;
+ UINT32 HiiData;
+ UINT32 SkuIdArray; //Pointer
+ UINT32 ExtendedDataOffset;
+ UINT32 DatumSize;
+ UINT16 DynamicExGuid; //Pointer
+ UINT8 SkuCount;
+} PCD_INDEX;
+
+
+
+/*
+ * PCD Image Definition according PCD Specification 0.51.
+ *
+ */
+#pragma pack(1)
+typedef struct {
+ UINT8 ImageLength[3];
+ //
+ // The length of PCD_FFS_ENCODING is included
+ // in ImageLength
+ //
+ UINT8 DataBufferLength[3];
+ UINT8 WholeDataBufferLength[3];
+ UINT8 PcdIndexLength[3];
+ UINT8 GuidTableLength[3];
+ //
+ // The StringTable can be computed using:
+ // ImageLength, DataBufferLength, PcdIndexLength, GuidTableLength,
+ // and length of PCD_FFS_ENCODING
+ //
+ UINT8 EntryCount[3];
+ UINT8 GlobalOffsetLength[1];
+ UINT8 GlobalTokenLength[1];
+ UINT8 GuidLength[1];
+ UINT8 GlobalDatumLength[1];
+ UINT8 GlobalStrTabIdxLength[1];
+} PCD_FFS_ENCODING;
+#pragma pack()
+
+
+
+typedef struct {
+ UINTN DatabaseLen;
+ UINTN EntryCount;
+ UINTN InfoLength;
+ UINTN GuidTableOffset;
+ UINTN PcdIndexOffset;
+ UINTN StringTableOffset;
+ UINTN CallbackTableOffset;
+ UINTN ImageIndexOffset;
+ UINTN DataBufferOffset;
+ UINTN MaxCallbackNum;
+ UINTN HiiVariableOffsetLength;
+ UINTN HiiGuidOffsetLength;
+ UINTN ExtendedOffsetLength;
+ UINT8 *VpdStart;
+ UINTN SkuId;
+} PCD_DATABASE_HEADER;
+
+
+
+typedef struct {
+ PCD_DATABASE_HEADER Info;
+ EFI_GUID GuidTable[1];
+} PCD_DATABASE;
+
+extern EFI_GUID gPcdDataBaseHobGuid;
+
+
+/**
+ The function returns the actual address of item in the PCD
+ database according to its Segment and Offset.
+
+ @param[out] Offset The offset within the segment.
+ @param[in] SegmentStart The starting address of the segment.
+ @param[in] DatabaseStart The base address of the PCD DataBase.
+
+
+ @retval EFI_SUCESS If data value is found according to SKU_ID.
+ @retval EFI_NOT_FOUND If not such a value is found.
+
+--*/
+UINT8 *
+GetAbsoluteAddress (
+ IN UINTN Offset,
+ IN UINTN SegmentStart,
+ IN CONST VOID *Base
+ )
+;
+
+
+
+/**
+ The function return the number of Unicode Character in a NULL terminated string.
+ The NULL is NOT counted.
+
+ @param[in] String The unicode string starts from an unaligned address.
+
+ @retval UINTN The number of Unicode characters.
+--*/
+UINTN
+GetUnalignedStrLen (
+ UINT16 *String
+);
+
+
+/**
+ The function retrieves the PCD data value according to
+ TokenNumber and Guid space given.
+
+ @param[in] Info The PCD Database Info.
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+ @param[in] Type The storage type.
+ @param[out] Data The output data.
+
+ @retval VOID
+
+--*/
+VOID
+GetPcdEntryWorker (
+ IN CONST PCD_DATABASE_HEADER *Info,
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ OUT VOID *Data
+ )
+;
+
+
+
+/**
+ The function retrieves the PCD data value according to
+ TokenNumber and Guid space given.
+
+ @param[in] Info The PCD Database info.
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+
+ @retval UINTN The size of the PCD Entry.
+
+--*/
+UINTN
+GetPcdEntrySizeWorker (
+ IN CONST PCD_DATABASE_HEADER *Info,
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid OPTIONAL
+ )
+;
+
+
+
+/**
+ The function looks for the next PCD ENTRY.
+ If *TokenNumber is 0, the first TokenNumber in
+ the GUID token space is return.
+ If there is no next TokenNumber found,
+ *TokenNumber will be 0.
+
+ @param[in] Info The PCD Database info.
+ @param[in,out] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+
+ @retval EFI_NOT_FOUND Can't find the PCD_ENTRY.
+ @retval EFI_SUCCESS Operation succesful.
+
+--*/
+EFI_STATUS
+GetNextTokenWorker (
+ IN CONST PCD_DATABASE_HEADER *Info,
+ IN OUT UINTN *TokenNumber,
+ IN CONST GUID *Guid OPTIONAL
+ )
+;
+
+
+
+/**
+ The function is the worker function to set the data of a PCD entry.
+
+ @param[in] PcdIndex The PCD Index.
+ @param[in] Info The attributes of the PCD database.
+ @param[in] Data The input data.
+
+ @retval VOID
+--*/
+EFI_STATUS
+SetPcdData (
+ IN CONST PCD_INDEX *PcdIndex,
+ IN CONST PCD_DATABASE_HEADER *Info,
+ IN CONST VOID *Data
+ )
+;
+
+
+/**
+ The function is provided by PCD PEIM and PCD DXE driver to
+ do the work of reading a HII variable from variable service.
+
+ @param[in] VariableGuid The Variable GUID.
+ @param[in] VariableName The Variable Name.
+ @param[out] VariableData The output data.
+ @param[out] VariableSize The size of the variable.
+
+ @retval EFI_SUCCESS Operation successful.
+ @retval EFI_SUCCESS Variablel not found.
+--*/
+EFI_STATUS
+GetHiiVariable (
+ IN EFI_GUID *VariableGuid,
+ IN UINT16 *VariableName,
+ OUT VOID **VariableData,
+ OUT UINTN *VariableSize
+ )
+;
+
+
+
+/**
+ The function is provided by PCD PEIM and PCD DXE driver to
+ do the work of reading a HII variable from variable service.
+
+ @param[in] VariableGuid The Variable GUID.
+ @param[in] VariableName The Variable Name.
+ @param[in] Data The input data.
+ @param[out] VariableSize The size of the variable.
+ @param[in] Offset The offset of the variable data that a PCD entry will starts from.
+
+ @retval EFI_SUCCESS Operation successful.
+ @retval EFI_SUCCESS Variablel not found.
+--*/
+EFI_STATUS
+SetHiiVariable (
+ IN EFI_GUID *VariableGuid,
+ IN UINT16 *VariableName,
+ IN CONST VOID *Data,
+ IN UINTN VariableSize,
+ IN UINTN Offset
+ )
+;
+
+/**
+ The function locates the PCD_INDEX according to TokeNumber and GUID space given.
+
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The GUID token space.
+ @param[out] Info The attributes of the PCD database.
+
+ @retval PCD_INDEX* The PCD_INDEX found.
+--*/
+PCD_INDEX *
+FindPcdIndex (
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid,
+ IN CONST PCD_DATABASE_HEADER *Info,
+ OUT UINTN *Index
+ )
+;
+
+/**
+ (WQBUGBUG: You must handle the new SKU_ID encoding.
+ The function is the worker function to get the data of a PCD entry.
+
+ @param[in] PcdIndex The PCD Index.
+ @param[in] Info The attributes of the PCD database.
+ @param[out] Data The output data.
+
+ @retval VOID
+--*/
+UINT8*
+GetPcdDataPtr (
+ IN CONST PCD_INDEX *PcdIndex,
+ IN CONST PCD_DATABASE_HEADER *Info
+ )
+;
+
+/**
+ The function retrieves the PCD data value according to
+ the PCD_DATA_TYPE specified.
+
+ @param[in] Type The PCD_DATA_TYPE used to interpret the data.
+ @param[in] InData The input data.
+ @param[in] OutData The output data.
+ @param[in] Len The length of the data; it is mainly used for PcdPointer type.
+
+ @retval VOID
+--*/
+VOID
+GetDataBasedOnType (
+ IN PCD_DATA_TYPE Type,
+ IN VOID *InData,
+ OUT VOID *OutData,
+ IN UINTN Len
+ )
+;
+#endif
diff --git a/EdkModulePkg/Universal/PCD/Dxe/Pcd.c b/EdkModulePkg/Universal/PCD/Dxe/Pcd.c
new file mode 100644
index 0000000..4ed7eb0
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Dxe/Pcd.c
@@ -0,0 +1,472 @@
+/** @file
+PCD DXE driver
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: Pcd.c
+
+**/
+
+#include "../Common/PcdCommon.h"
+#include "Service.h"
+
+
+PCD_PROTOCOL mPcdInstance = {
+ DxePcdSetSku,
+
+ DxePcdGet8,
+ DxePcdGet16,
+ DxePcdGet32,
+ DxePcdGet64,
+ DxePcdGetPtr,
+ DxePcdGetBool,
+ DxePcdGetSize,
+
+ DxePcdGet8Ex,
+ DxePcdGet16Ex,
+ DxePcdGet32Ex,
+ DxePcdGet64Ex,
+ DxePcdGetPtrEx,
+ DxePcdGetBoolEx,
+ DxePcdGetSizeEx,
+
+ DxePcdSet8,
+ DxePcdSet16,
+ DxePcdSet32,
+ DxePcdSet64,
+ DxePcdSetPtr,
+ DxePcdSetBool,
+
+ DxePcdSet8Ex,
+ DxePcdSet16Ex,
+ DxePcdSet32Ex,
+ DxePcdSet64Ex,
+ DxePcdSetPtrEx,
+ DxePcdSetBoolEx,
+
+ PcdRegisterCallBackOnSet,
+ PcdUnRegisterCallBackOnSet,
+ DxePcdGetNextToken
+};
+
+
+//
+// Static global to reduce the code size
+//
+static EFI_HANDLE NewHandle = NULL;
+
+EFI_STATUS
+EFIAPI
+PcdDxeInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ InitPcdDxeDataBase ();
+
+ Status = gBS->InstallProtocolInterface (
+ &NewHandle,
+ &gPcdProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPcdInstance
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetSku (
+ IN UINTN SkuId
+ )
+{
+ return DxeSetSku(SkuId);
+}
+
+
+
+UINT8
+EFIAPI
+DxePcdGet8 (
+ IN UINTN TokenNumber
+ )
+{
+ return DxePcdGet8Ex (NULL, TokenNumber);
+}
+
+
+
+UINT16
+EFIAPI
+DxePcdGet16 (
+ IN UINTN TokenNumber
+ )
+{
+ return DxePcdGet16Ex (NULL, TokenNumber);
+}
+
+
+
+UINT32
+EFIAPI
+DxePcdGet32 (
+ IN UINTN TokenNumber
+ )
+{
+ return DxePcdGet32Ex (NULL, TokenNumber);
+}
+
+
+
+UINT64
+EFIAPI
+DxePcdGet64 (
+ IN UINTN TokenNumber
+ )
+{
+ return DxePcdGet32Ex (NULL, TokenNumber);
+}
+
+
+
+VOID *
+EFIAPI
+DxePcdGetPtr (
+ IN UINTN TokenNumber
+ )
+{
+ return DxePcdGetPtrEx (NULL, TokenNumber);
+}
+
+
+
+BOOLEAN
+EFIAPI
+DxePcdGetBool (
+ IN UINTN TokenNumber
+ )
+{
+ return DxePcdGetBoolEx (NULL, TokenNumber);
+}
+
+
+
+UINTN
+EFIAPI
+DxePcdGetSize (
+ IN UINTN TokenNumber
+ )
+{
+ return DxePcdGetSizeEx (NULL, TokenNumber);
+}
+
+
+
+UINT8
+EFIAPI
+DxePcdGet8Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ UINT8 Data;
+
+ DxeGetPcdEntryWorker (TokenNumber, Guid, PcdByte8, &Data);
+
+ return Data;
+}
+
+
+
+UINT16
+EFIAPI
+DxePcdGet16Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ UINT16 Data;
+
+ DxeGetPcdEntryWorker (TokenNumber, Guid, PcdByte16, &Data);
+
+ return Data;
+}
+
+
+
+UINT32
+EFIAPI
+DxePcdGet32Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ UINT32 Data;
+
+ DxeGetPcdEntryWorker (TokenNumber, Guid, PcdByte32, &Data);
+
+ return Data;
+}
+
+
+
+UINT64
+EFIAPI
+DxePcdGet64Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ UINT64 Data;
+
+ DxeGetPcdEntryWorker (TokenNumber, Guid, PcdByte64, &Data);
+
+ return Data;
+}
+
+
+
+VOID *
+EFIAPI
+DxePcdGetPtrEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ VOID *Data;
+
+ DxeGetPcdEntryWorker (TokenNumber, Guid, PcdPointer, &Data);
+
+ return Data;
+}
+
+
+
+BOOLEAN
+EFIAPI
+DxePcdGetBoolEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ BOOLEAN Data;
+ DxeGetPcdEntryWorker (TokenNumber, Guid, PcdBoolean, &Data);
+ return Data;
+}
+
+
+
+UINTN
+EFIAPI
+DxePcdGetSizeEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ return DxeGetPcdEntrySizeWorker (TokenNumber, Guid);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet8 (
+ IN UINTN TokenNumber,
+ IN UINT8 Value
+ )
+{
+ return DxePcdSet8Ex (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet16 (
+ IN UINTN TokenNumber,
+ IN UINT16 Value
+ )
+{
+ return DxePcdSet16Ex (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet32 (
+ IN UINTN TokenNumber,
+ IN UINT32 Value
+ )
+{
+ return DxePcdSet32Ex (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet64 (
+ IN UINTN TokenNumber,
+ IN UINT64 Value
+ )
+{
+ return DxePcdSet64Ex (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetPtr (
+ IN UINTN TokenNumber,
+ IN CONST VOID *Value
+ )
+{
+ return DxePcdSetPtrEx (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetBool (
+ IN UINTN TokenNumber,
+ IN BOOLEAN Value
+ )
+{
+ return DxePcdSetBoolEx (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet8Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT8 Value
+ )
+{
+ return DxeSetPcdEntryWorker (TokenNumber, Guid, PcdByte8, &Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet16Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT16 Value
+ )
+{
+ return DxeSetPcdEntryWorker (TokenNumber, Guid, PcdByte16, &Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet32Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT32 Value
+ )
+{
+ return DxeSetPcdEntryWorker (TokenNumber, Guid, PcdByte32, &Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet64Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT64 Value
+ )
+{
+ return DxeSetPcdEntryWorker (TokenNumber, Guid, PcdByte64, &Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetPtrEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN CONST VOID *Value
+ )
+{
+ return DxeSetPcdEntryWorker (TokenNumber, Guid, PcdPointer, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetBoolEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN BOOLEAN Value
+ )
+{
+ return DxeSetPcdEntryWorker (TokenNumber, Guid, PcdBoolean, &Value);
+
+}
+
+
+
+
+EFI_STATUS
+EFIAPI
+PcdRegisterCallBackOnSet (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction
+ )
+{
+ return DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction, TRUE);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PcdUnRegisterCallBackOnSet (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction
+ )
+{
+ return DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction, FALSE);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+DxePcdGetNextToken (
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN OUT UINTN *TokenNumber
+ )
+{
+ return DxeGetNextTokenWorker (TokenNumber, Guid);
+}
+
diff --git a/EdkModulePkg/Universal/PCD/Dxe/Service.c b/EdkModulePkg/Universal/PCD/Dxe/Service.c
new file mode 100644
index 0000000..280a45e
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Dxe/Service.c
@@ -0,0 +1,491 @@
+/** @file
+Private functions used by PCD DXE driver.s
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: Service.c
+
+**/
+#include "../Common/PcdCommon.h"
+#include "Service.h"
+
+static PCD_DATABASE *PrivatePcdDxeDatabase;
+static LIST_ENTRY mPcdDatabaseListHead = INITIALIZE_LIST_HEAD_VARIABLE(mPcdDatabaseListHead);
+
+LIST_ENTRY *
+GetPcdDatabaseListHead (
+ VOID
+ )
+{
+ return &mPcdDatabaseListHead;
+}
+
+PCD_DATABASE *
+GetPcdDxeDataBaseInstance (
+ VOID
+)
+{
+ return PrivatePcdDxeDatabase;
+}
+
+PCD_DATABASE *
+SetPcdDxeDataBaseInstance (
+ PCD_DATABASE *PcdDatabase
+)
+{
+ return PrivatePcdDxeDatabase = PcdDatabase;
+}
+
+
+VOID
+DxeGetPcdEntryWorker (
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ OUT VOID *Data
+ )
+{
+ PCD_DATABASE *Database;
+ Database = GetPcdDxeDataBaseInstance ();
+
+ GetPcdEntryWorker ( &Database->Info,
+ TokenNumber,
+ Guid,
+ Type,
+ Data
+ );
+
+
+ return;
+}
+
+
+
+EFI_STATUS
+DxeSetPcdEntryWorker (
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ IN CONST VOID *Data
+ )
+{
+ PCD_DATABASE *Database;
+ PCD_INDEX *PcdIndex;
+ EFI_STATUS Status;
+
+ Database = GetPcdDxeDataBaseInstance ();
+
+
+ ASSERT (Data != NULL);
+
+ PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, NULL);
+
+ ASSERT (PcdIndex != NULL);
+
+ ASSERT (PcdIndex->StateByte.DataType == Type);
+
+ //
+ // Invoke the callback function.
+ //
+
+ Status = SetPcdData (PcdIndex, &Database->Info, Data);
+
+ return Status;
+
+
+}
+
+
+
+UINTN
+DxeGetPcdEntrySizeWorker (
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid OPTIONAL
+ )
+{
+ PCD_DATABASE *Database;
+ Database = GetPcdDxeDataBaseInstance ();
+
+ return GetPcdEntrySizeWorker (&Database->Info,
+ TokenNumber,
+ Guid
+ );
+}
+
+
+
+LIST_ENTRY *
+InsertToGuidSpaceListI (
+ IN LIST_ENTRY *GuidSpaceListHead,
+ IN CONST EFI_GUID *Guid
+ )
+{
+ PCD_GUID_SPACE *GuidSpaceEntry;
+
+ GuidSpaceEntry = AllocatePool (sizeof (PCD_GUID_SPACE));
+ ASSERT (GuidSpaceEntry != NULL);
+
+ GuidSpaceEntry->GuidSpace= Guid;
+ InitializeListHead (&GuidSpaceEntry->TokenSpaceHead);
+
+ InsertTailList (GuidSpaceListHead, &GuidSpaceEntry->ListNode);
+
+ return &GuidSpaceEntry->TokenSpaceHead;
+}
+
+
+
+LIST_ENTRY *
+InsertToTokenSpaceListI (
+ IN LIST_ENTRY *TokenSpaceListHead,
+ IN UINTN TokenNumber
+ )
+{
+ PCD_TOKEN_SPACE *TokenSpaceEntry;
+
+ TokenSpaceEntry = AllocatePool (sizeof (PCD_TOKEN_SPACE));
+ ASSERT (TokenSpaceEntry != NULL);
+
+ TokenSpaceEntry->TokeNumber = TokenNumber;
+ InitializeListHead (&TokenSpaceEntry->CallbackListHead);
+
+ InsertTailList (TokenSpaceListHead, &TokenSpaceEntry->ListNode);
+
+ return &TokenSpaceEntry->CallbackListHead;
+}
+
+
+
+VOID
+InsertToCallbackListI (
+ IN LIST_ENTRY *CallbackListHead,
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction
+ )
+{
+ PCD_CALLBACK_ENTRY *CallbackEntry;
+
+ CallbackEntry = AllocatePool (sizeof (PCD_CALLBACK_ENTRY));
+ ASSERT (CallbackEntry != NULL);
+ CallbackEntry->CallbackFunction = CallBackFunction;
+ InsertTailList (CallbackListHead, &CallbackEntry->ListNode);
+
+ return;
+}
+
+
+
+
+VOID
+InsertToCallbackList (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid,
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction
+ )
+{
+ LIST_ENTRY *GuidListNode;
+ LIST_ENTRY *GuidListHead;
+ LIST_ENTRY *TokenListNode;
+ LIST_ENTRY *TokenListHead;
+ LIST_ENTRY *CallbackListHead;
+ PCD_GUID_SPACE *GuidSpaceEntry;
+ PCD_TOKEN_SPACE *TokenSpaceEntry;
+
+
+ GuidListHead = GetPcdDatabaseListHead ();
+
+ GuidListNode = GetFirstNode (GuidListHead);
+ while (!IsNull (GuidListNode, GuidListHead)) {
+ GuidSpaceEntry = PCD_GUID_SPACE_FROM_LISTNODE(GuidListNode);
+
+ if (CompareGuid (GuidSpaceEntry->GuidSpace, Guid)) {
+ TokenListHead = &GuidSpaceEntry->TokenSpaceHead;
+ TokenListNode = GetFirstNode (TokenListHead);
+ while (!IsNull (TokenListNode, TokenListHead)) {
+ TokenSpaceEntry = PCD_TOKEN_SPACE_FROM_LISTNODE(TokenListNode);
+ if (TokenSpaceEntry->TokeNumber == TokenNumber) {
+ InsertToCallbackListI (&TokenSpaceEntry->CallbackListHead , CallBackFunction);
+ }
+ }
+
+ //
+ // No TokenNumber match input found in this GuidSpace
+ //
+ CallbackListHead = InsertToTokenSpaceListI (TokenListHead, TokenNumber);
+ InsertToCallbackListI (CallbackListHead , CallBackFunction);
+ }
+
+ GuidListNode = GetNextNode (GuidListHead, GuidListNode);
+ }
+
+ //
+ // No GuidSpace match the input Guid, so build the GuidSpace, TokenNumberSpace and Callback
+ //
+ TokenListHead = InsertToGuidSpaceListI (GuidListHead, Guid);
+ CallbackListHead = InsertToTokenSpaceListI (TokenListHead, TokenNumber);
+ InsertToCallbackListI (CallbackListHead , CallBackFunction);
+
+ return;
+
+}
+
+EFI_STATUS
+RemoveFromCallbackListI (
+ IN LIST_ENTRY *CallbackListHead,
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction
+ )
+{
+ LIST_ENTRY *ListNode;
+ PCD_CALLBACK_ENTRY *CallbackEntry;
+
+ ListNode = GetFirstNode (CallbackListHead);
+
+ while (!IsNull(CallbackListHead, ListNode)) {
+ CallbackEntry = PCD_CALLBACK_ENTRY_FROM_LISTNODE(ListNode);
+
+ if (CallbackEntry->CallbackFunction == CallBackFunction) {
+ RemoveEntryList (ListNode);
+ FreePool (CallbackEntry);
+ return EFI_SUCCESS;
+ }
+ ListNode = GetNextNode (CallbackListHead, ListNode);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+
+EFI_STATUS
+RemoveFromCallbackList (
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid,
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction
+ )
+{
+ LIST_ENTRY *GuidListNode;
+ LIST_ENTRY *GuidListHead;
+ LIST_ENTRY *TokenListNode;
+ LIST_ENTRY *TokenListHead;
+ PCD_GUID_SPACE *GuidSpaceEntry;
+ PCD_TOKEN_SPACE *TokenSpaceEntry;
+
+
+ GuidListHead = GetPcdDatabaseListHead ();
+
+ GuidListNode = GetFirstNode (GuidListHead);
+ while (!IsNull (GuidListNode, GuidListHead)) {
+
+ GuidSpaceEntry = PCD_GUID_SPACE_FROM_LISTNODE(GuidListNode);
+ if (CompareGuid (GuidSpaceEntry->GuidSpace, Guid)) {
+
+ TokenListHead = &GuidSpaceEntry->TokenSpaceHead;
+ TokenListNode = GetFirstNode (TokenListHead);
+ while (!IsNull (TokenListNode, TokenListHead)) {
+
+ TokenSpaceEntry = PCD_TOKEN_SPACE_FROM_LISTNODE(TokenListNode);
+ if (TokenSpaceEntry->TokeNumber == TokenNumber) {
+ return RemoveFromCallbackListI (&TokenSpaceEntry->CallbackListHead , CallBackFunction);
+ }
+ }
+
+ //
+ // No TokenNumber match input found in this GuidSpace
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ GuidListNode = GetNextNode (GuidListHead, GuidListNode);
+ }
+
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+
+EFI_STATUS
+DxeRegisterCallBackWorker (
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid, OPTIONAL
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction,
+ IN BOOLEAN Register
+)
+{
+ PCD_DATABASE *Database;
+ PCD_INDEX *PcdIndex;
+
+ Database = GetPcdDxeDataBaseInstance ();
+
+ PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, NULL);
+
+ if (PcdIndex == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Register) {
+ InsertToCallbackList (TokenNumber, Guid, CallBackFunction);
+ return EFI_SUCCESS;
+ } else {
+ return RemoveFromCallbackList (TokenNumber, Guid, CallBackFunction);
+ }
+
+ }
+
+
+
+EFI_STATUS
+DxeSetSku (
+ UINTN Id
+)
+{
+ PCD_DATABASE * Database;
+
+ Database = GetPcdDxeDataBaseInstance ();
+
+ return Database->Info.SkuId = Id;
+
+}
+
+
+
+EFI_STATUS
+DxeGetNextTokenWorker (
+ IN OUT UINTN *TokenNumber,
+ IN CONST GUID *Guid OPTIONAL
+ )
+{
+ PCD_DATABASE * Database;
+
+ Database = GetPcdDxeDataBaseInstance ();
+
+ return GetNextTokenWorker (&Database->Info,
+ TokenNumber,
+ Guid
+ );
+}
+
+
+
+VOID
+InitPcdDxeDataBase (
+ VOID
+)
+{
+ PCD_DATABASE *PeiDatabase;
+ PCD_DATABASE *DxeDatabase;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
+ ASSERT (GuidHob != NULL);
+
+ PeiDatabase = (PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
+
+ DxeDatabase = AllocateCopyPool (PeiDatabase->Info.DatabaseLen, PeiDatabase);
+
+ ASSERT (DxeDatabase != NULL);
+
+ SetPcdDxeDataBaseInstance (DxeDatabase);
+
+ return;
+}
+
+
+
+EFI_STATUS
+GetHiiVariable (
+ IN EFI_GUID *VariableGuid,
+ IN UINT16 *VariableName,
+ OUT VOID ** VariableData,
+ OUT UINTN *VariableSize
+ )
+{
+ UINTN Size;
+ EFI_STATUS Status;
+ VOID *Buffer;
+
+ Status = EfiGetVariable (
+ (UINT16 *)VariableName,
+ VariableGuid,
+ NULL,
+ &Size,
+ NULL
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ Buffer = AllocatePool (Size);
+
+ ASSERT (Buffer != NULL);
+
+ Status = EfiGetVariable (
+ VariableName,
+ VariableGuid,
+ NULL,
+ &Size,
+ Buffer
+ );
+
+ return Status;
+
+}
+
+
+
+EFI_STATUS
+SetHiiVariable (
+ IN EFI_GUID *VariableGuid,
+ IN UINT16 *VariableName,
+ IN CONST VOID *Data,
+ IN UINTN DataSize,
+ IN UINTN Offset
+ )
+{
+ UINTN Size;
+ VOID *Buffer;
+ EFI_STATUS Status;
+
+ Size = 0;
+
+ Status = EfiGetVariable (
+ (UINT16 *)VariableName,
+ VariableGuid,
+ NULL,
+ &Size,
+ NULL
+ );
+
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ Buffer = AllocatePool (Size);
+
+ ASSERT (Buffer != NULL);
+
+ Status = EfiGetVariable (
+ VariableName,
+ VariableGuid,
+ NULL,
+ &Size,
+ Buffer
+ );
+
+
+ CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
+
+ return EfiSetVariable (
+ VariableName,
+ VariableGuid,
+ 0,
+ Size,
+ Buffer
+ );
+
+}
+
diff --git a/EdkModulePkg/Universal/PCD/Dxe/Service.h b/EdkModulePkg/Universal/PCD/Dxe/Service.h
new file mode 100644
index 0000000..86e3dfd
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Dxe/Service.h
@@ -0,0 +1,399 @@
+/** @file
+Private functions used by PCD DXE driver.
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: Service.h
+
+**/
+
+#ifndef _SERVICE_H
+#define _SERVICE_H
+
+VOID
+DxeGetPcdEntryWorker (
+ IN UINTN Token,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ OUT VOID *Data
+ );
+
+EFI_STATUS
+DxeSetPcdEntryWorker (
+ IN UINTN Token,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ IN CONST VOID *Data
+ );
+
+UINTN
+DxeGetPcdEntrySizeWorker (
+ IN UINTN Token,
+ IN CONST EFI_GUID *Guid OPTIONAL
+ );
+
+EFI_STATUS
+DxeRegisterCallBackWorker (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction,
+ IN BOOLEAN Reigster
+);
+
+EFI_STATUS
+DxeSetSku (
+ UINTN Id
+);
+
+EFI_STATUS
+DxeGetNextTokenWorker (
+ IN OUT UINTN *Token,
+ IN CONST EFI_GUID *Guid OPTIONAL
+ );
+
+VOID
+InitPcdDxeDataBase (
+ VOID
+);
+
+//
+// Protocol Interface function declaration.
+//
+EFI_STATUS
+EFIAPI
+DxePcdSetSku (
+ IN UINTN SkuId
+ )
+;
+
+
+UINT8
+EFIAPI
+DxePcdGet8 (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT16
+EFIAPI
+DxePcdGet16 (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT32
+EFIAPI
+DxePcdGet32 (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT64
+EFIAPI
+DxePcdGet64 (
+ IN UINTN TokenNumber
+ )
+;
+
+
+VOID *
+EFIAPI
+DxePcdGetPtr (
+ IN UINTN TokenNumber
+ )
+;
+
+
+BOOLEAN
+EFIAPI
+DxePcdGetBool (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINTN
+EFIAPI
+DxePcdGetSize (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT8
+EFIAPI
+DxePcdGet8Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT16
+EFIAPI
+DxePcdGet16Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT32
+EFIAPI
+DxePcdGet32Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+
+UINT64
+EFIAPI
+DxePcdGet64Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+
+VOID *
+EFIAPI
+DxePcdGetPtrEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+BOOLEAN
+EFIAPI
+DxePcdGetBoolEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINTN
+EFIAPI
+DxePcdGetSizeEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet8 (
+ IN UINTN TokenNumber,
+ IN UINT8 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet16 (
+ IN UINTN TokenNumber,
+ IN UINT16 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet32 (
+ IN UINTN TokenNumber,
+ IN UINT32 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet64 (
+ IN UINTN TokenNumber,
+ IN UINT64 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetPtr (
+ IN UINTN TokenNumber,
+ IN CONST VOID *Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetBool (
+ IN UINTN TokenNumber,
+ IN BOOLEAN Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet8Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT8 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet16Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT16 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet32Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT32 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSet64Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT64 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetPtrEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN CONST VOID *Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdSetBoolEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN BOOLEAN Value
+ )
+;
+
+
+
+EFI_STATUS
+EFIAPI
+PcdRegisterCallBackOnSet (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PcdUnRegisterCallBackOnSet (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PROTOCOL_CALLBACK CallBackFunction
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+DxePcdGetNextToken (
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN OUT UINTN *TokenNumber
+ )
+;
+
+
+/*
+ This DXE_PCD_DATABASE layout. The difference of DXE_PCD_DATABASE
+ and PEI_PCD_DATABASE is as follows:
+
+ 1) No PCD_CALL_BACK_TABLE; DXE_PCD_DATABASE maintain a LinkList for the
+ callback function registered.
+
+ ---------------------------
+ | LIST_ENTRY GuidSpaceHead|
+ ---------------------------
+ | PCD_DATABASE_HEADER |
+ ---------------------------
+ | GUID_TABLE | Aligned on GUID (128 bits)
+ ---------------------------
+ | PCD_INDEX_TABLE | Aligned on PCD_INDEX (see PCD_INDEX's declaration)
+ ---------------------------
+ | IMAGE_STRING_TABLE | Aligned on 16 Bits
+ ---------------------------
+ | IMAGE_PCD_INDEX | Unaligned
+ ---------------------------
+ | Data Defaults | Unaligned
+ ---------------------------
+ | Data Buffer |
+ | for entries without |
+ | defaults |
+ ---------------------------
+
+*/
+
+
+typedef struct {
+ LIST_ENTRY ListNode;
+ LIST_ENTRY TokenSpaceHead;
+ CONST EFI_GUID *GuidSpace;
+} PCD_GUID_SPACE;
+
+typedef struct {
+ LIST_ENTRY ListNode;
+ LIST_ENTRY CallbackListHead;
+ UINTN TokeNumber;
+} PCD_TOKEN_SPACE;
+
+typedef struct {
+ LIST_ENTRY ListNode;
+ PCD_PROTOCOL_CALLBACK CallbackFunction;
+} PCD_CALLBACK_ENTRY;
+
+#define PCD_GUID_SPACE_FROM_LISTNODE(a) \
+ _CR(a, PCD_GUID_SPACE, ListNode)
+
+#define PCD_TOKEN_SPACE_FROM_LISTNODE(a) \
+ _CR(a, PCD_TOKEN_SPACE, ListNode)
+
+#define PCD_CALLBACK_ENTRY_FROM_LISTNODE(a) \
+ _CR(a, PCD_CALLBACK_ENTRY, ListNode)
+
+#endif
diff --git a/EdkModulePkg/Universal/PCD/Pei/Pcd.c b/EdkModulePkg/Universal/PCD/Pei/Pcd.c
new file mode 100644
index 0000000..3fb49dd
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Pei/Pcd.c
@@ -0,0 +1,486 @@
+/** @file
+PCD PEIM
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: Pcd.c
+
+**/
+
+#include "../Common/PcdCommon.h"
+#include "Service.h"
+
+
+PCD_PPI mPcdPpiInstance = {
+ PeiPcdSetSku,
+
+ PeiPcdGet8,
+ PeiPcdGet16,
+ PeiPcdGet32,
+ PeiPcdGet64,
+ PeiPcdGetPtr,
+ PeiPcdGetBool,
+ PeiPcdGetSize,
+
+ PeiPcdGet8Ex,
+ PeiPcdGet16Ex,
+ PeiPcdGet32Ex,
+ PeiPcdGet64Ex,
+ PeiPcdGetPtrEx,
+ PeiPcdGetBoolEx,
+ PeiPcdGetSizeEx,
+
+ PeiPcdSet8,
+ PeiPcdSet16,
+ PeiPcdSet32,
+ PeiPcdSet64,
+ PeiPcdSetPtr,
+ PeiPcdSetBool,
+
+ PeiPcdSet8Ex,
+ PeiPcdSet16Ex,
+ PeiPcdSet32Ex,
+ PeiPcdSet64Ex,
+ PeiPcdSetPtrEx,
+ PeiPcdSetBoolEx,
+
+ PcdRegisterCallBackOnSet,
+ PcdUnRegisterCallBackOnSet,
+ PeiPcdGetNextToken
+};
+
+
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiPCD = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPcdPpiGuid,
+ &mPcdPpiInstance
+};
+
+
+
+EFI_STATUS
+EFIAPI
+PcdPeimInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *PcdImage;
+
+ PcdImage = (UINT8 *) LocatePcdImage ();
+
+ BuildPcdDatabase (PcdImage);
+
+ Status = PeiCoreInstallPpi (&mPpiPCD);
+
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetSku (
+ IN UINTN SkuId
+ )
+{
+ PCD_DATABASE *Database;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
+ ASSERT (GuidHob != NULL);
+
+ Database = (PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
+
+ Database->Info.SkuId = SkuId;
+
+ return SkuId;
+}
+
+
+
+UINT8
+EFIAPI
+PeiPcdGet8 (
+ IN UINTN TokenNumber
+ )
+{
+ return PeiPcdGet8Ex (NULL, TokenNumber);
+}
+
+
+
+UINT16
+EFIAPI
+PeiPcdGet16 (
+ IN UINTN TokenNumber
+ )
+{
+ return PeiPcdGet16Ex (NULL, TokenNumber);
+}
+
+
+
+UINT32
+EFIAPI
+PeiPcdGet32 (
+ IN UINTN TokenNumber
+ )
+{
+ return PeiPcdGet32Ex (NULL, TokenNumber);
+}
+
+
+
+UINT64
+EFIAPI
+PeiPcdGet64 (
+ IN UINTN TokenNumber
+ )
+{
+ return PeiPcdGet64Ex (NULL, TokenNumber);
+}
+
+
+
+VOID *
+EFIAPI
+PeiPcdGetPtr (
+ IN UINTN TokenNumber
+ )
+{
+ return PeiPcdGetPtrEx (NULL, TokenNumber);
+}
+
+
+
+BOOLEAN
+EFIAPI
+PeiPcdGetBool (
+ IN UINTN TokenNumber
+ )
+{
+ return PeiPcdGetBoolEx (NULL, TokenNumber);
+}
+
+
+
+UINTN
+EFIAPI
+PeiPcdGetSize (
+ IN UINTN TokenNumber
+ )
+{
+ return PeiPcdGetSizeEx (NULL, TokenNumber);
+}
+
+
+
+UINT8
+EFIAPI
+PeiPcdGet8Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ UINT8 Data;
+
+ PeiGetPcdEntryWorker (TokenNumber, Guid, PcdByte8, &Data);
+
+ return Data;
+}
+
+
+
+UINT16
+EFIAPI
+PeiPcdGet16Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ UINT16 Data;
+
+ PeiGetPcdEntryWorker (TokenNumber, Guid, PcdByte16, &Data);
+
+ return Data;
+}
+
+
+
+UINT32
+EFIAPI
+PeiPcdGet32Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ UINT32 Data;
+
+ PeiGetPcdEntryWorker (TokenNumber, Guid, PcdByte32, &Data);
+
+ return Data;
+}
+
+
+
+UINT64
+EFIAPI
+PeiPcdGet64Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ UINT64 Data;
+
+ PeiGetPcdEntryWorker (TokenNumber, Guid, PcdByte64, &Data);
+
+ return Data;
+}
+
+
+
+VOID *
+EFIAPI
+PeiPcdGetPtrEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ VOID *Data;
+
+ PeiGetPcdEntryWorker (TokenNumber, Guid, PcdPointer, &Data);
+
+ return Data;
+}
+
+
+
+BOOLEAN
+EFIAPI
+PeiPcdGetBoolEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ BOOLEAN Data;
+
+ PeiGetPcdEntryWorker (TokenNumber, Guid, PcdBoolean, &Data);
+
+ return Data;
+}
+
+
+
+UINTN
+EFIAPI
+PeiPcdGetSizeEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+{
+ return PeiGetPcdEntrySizeWorker (TokenNumber, Guid);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet8 (
+ IN UINTN TokenNumber,
+ IN UINT8 Value
+ )
+{
+ return PeiPcdSet8Ex (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet16 (
+ IN UINTN TokenNumber,
+ IN UINT16 Value
+ )
+{
+ return PeiPcdSet16Ex (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet32 (
+ IN UINTN TokenNumber,
+ IN UINT32 Value
+ )
+{
+ return PeiPcdSet32Ex (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet64 (
+ IN UINTN TokenNumber,
+ IN UINT64 Value
+ )
+{
+ return PeiPcdSet64Ex (NULL, TokenNumber, Value);
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetPtr (
+ IN UINTN TokenNumber,
+ IN CONST VOID *Value
+ )
+{
+ return PeiPcdSetPtrEx (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetBool (
+ IN UINTN TokenNumber,
+ IN BOOLEAN Value
+ )
+{
+ return PeiPcdSetBoolEx (NULL, TokenNumber, Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet8Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT8 Value
+ )
+{
+ return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdByte8, &Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet16Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT16 Value
+ )
+{
+ return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdByte16, &Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet32Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT32 Value
+ )
+{
+ return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdByte32, &Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet64Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT64 Value
+ )
+{
+ return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdByte64, &Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetPtrEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN CONST VOID *Value
+ )
+{
+ return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdPointer, (VOID *)Value);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetBoolEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN BOOLEAN Value
+ )
+{
+ return PeiSetPcdEntryWorker (TokenNumber, Guid, PcdBoolean, &Value);
+
+}
+
+
+
+
+EFI_STATUS
+EFIAPI
+PcdRegisterCallBackOnSet (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PPI_CALLBACK CallBackFunction
+ )
+{
+ return PeiRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction, TRUE);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PcdUnRegisterCallBackOnSet (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PPI_CALLBACK CallBackFunction
+ )
+{
+ return PeiRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction, FALSE);
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdGetNextToken (
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN OUT UINTN *TokenNumber
+ )
+{
+ return PeiGetNextTokenWorker (TokenNumber, Guid);
+}
+
+
diff --git a/EdkModulePkg/Universal/PCD/Pei/Service.c b/EdkModulePkg/Universal/PCD/Pei/Service.c
new file mode 100644
index 0000000..3829325
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Pei/Service.c
@@ -0,0 +1,812 @@
+/** @file
+Private functions used by PCD PEIM.
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: Service.c
+
+**/
+#include "../Common/PcdCommon.h"
+#include "Service.h"
+
+
+
+
+/**
+ This function expand the StateByte
+
+ @param[out] StateByte The output StateByte information.
+ @param[in] Byte The StateByte.
+
+ @retval VOID
+--*/
+VOID
+PcdImageExpandStateByte (
+ OUT PCD_STATEBYTE *StateByte,
+ IN UINT8 Byte
+)
+{
+ switch (Byte & PCD_STATEBYTE_DATUMTYPE) {
+ case PCD_BYTE8:
+ StateByte->DataType = PcdByte8;
+ break;
+ case PCD_BYTE16:
+ StateByte->DataType = PcdByte16;
+ break;
+ case PCD_BYTE32:
+ StateByte->DataType = PcdByte32;
+ break;
+ case PCD_BYTE64:
+ StateByte->DataType = PcdByte64;
+ break;
+ case PCD_POINTER:
+ StateByte->DataType = PcdPointer;
+ break;
+ case PCD_BOOLEAN:
+ StateByte->DataType = PcdBoolean;
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+
+ StateByte->ExtendedGuidPresent = (BOOLEAN) ((Byte & PCD_STATEBYTE_EXTENDEDGUIDPRESENT) != 0);
+ StateByte->HiiEnable = (BOOLEAN) ((Byte & PCD_STATEBYTE_HIIENABLE) != 0);
+ StateByte->SkuDataArrayEnable = (BOOLEAN) ((Byte & PCD_STATEBYTE_SKUDATAARRAYENABLE) != 0);
+ StateByte->SkuEnable = (BOOLEAN) ((Byte & PCD_STATEBYTE_SKUENABLE) != 0);
+ StateByte->VpdEnable = (BOOLEAN) ((Byte & PCD_STATEBYTE_VPDENABLE) != 0);
+
+}
+
+
+
+/**
+ This function locates the <PCD_IMAGE> on the flash and
+ return a pointer to the Section Data on flash.
+
+ @param[in] VOID
+
+ @retval VOID
+--*/
+UINT8 *
+LocatePcdImage (
+ VOID
+)
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHdr;
+ EFI_FFS_FILE_HEADER *FfsHdr;
+ VOID *SectionData;
+
+ Status = PeiCoreFfsFindNextVolume (0, &FvHdr);
+ ASSERT_EFI_ERROR (Status);
+
+ do {
+ FfsHdr = NULL;
+ Status = PeiCoreFfsFindNextFile (EFI_FV_FILETYPE_FREEFORM, FvHdr, &FfsHdr);
+ if (Status == EFI_SUCCESS) {
+ if (CompareGuid (&gPcdImageFileGuid, &FfsHdr->Name)) {
+
+ Status = PeiCoreFfsFindSectionData (EFI_SECTION_RAW, FfsHdr, &SectionData);
+ ASSERT_EFI_ERROR (Status);
+
+ return (UINT8 *)SectionData;
+ }
+ }
+ } while (Status == EFI_SUCCESS);
+
+ ASSERT (FALSE);
+
+ return NULL;
+}
+
+/**
+ The function retrieves the PCD data value according to
+ TokenNumber and Guid space given.
+
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+ @param[in] Type The storage type.
+ @param[out] Data The output data.
+
+
+ @retval EFI_SUCESS If data value is found according to SKU_ID.
+ @retval EFI_NOT_FOUND If not such a value is found.
+
+--*/
+VOID
+PeiGetPcdEntryWorker (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ OUT VOID *Data
+ )
+{
+ PCD_DATABASE *Database;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ ASSERT (Data != NULL);
+
+ GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
+ ASSERT (GuidHob != NULL);
+
+ Database = GET_GUID_HOB_DATA (GuidHob);
+
+ GetPcdEntryWorker ( &Database->Info,
+ TokenNumber,
+ Guid,
+ Type,
+ Data
+ );
+
+
+ return;
+}
+
+
+/**
+ The function set the PCD data value according to
+ TokenNumber and Guid space given.
+
+ @param[in] Database The PCD Database Instance.
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+ @param[in] Type The storage type.
+ @param[in] Data The output data.
+
+
+ @retval EFI_SUCESS If data value is found according to SKU_ID.
+ @retval EFI_NOT_FOUND If not such a value is found.
+
+--*/
+EFI_STATUS
+SetPcdEntryWorker (
+ IN CONST PCD_DATABASE *Database,
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ IN VOID *Data
+ )
+{
+ PCD_INDEX *PcdIndex;
+ EFI_STATUS Status;
+ PCD_PPI_CALLBACK *CallbackTable;
+ UINTN Idx;
+
+ ASSERT (Data != NULL);
+
+ //
+ // Find the PCD entry in list in memory first
+ //
+ PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, &Idx);
+
+ ASSERT (PcdIndex != NULL);
+
+ ASSERT (PcdIndex->StateByte.DataType == Type);
+
+ //
+ // Invoke the callback function.
+ //
+ CallbackTable = (PCD_PPI_CALLBACK *)
+ GetAbsoluteAddress (Idx * Database->Info.MaxCallbackNum * sizeof(PCD_PPI_CALLBACK),
+ Database->Info.CallbackTableOffset,
+ &Database->Info
+ );
+
+ for (Idx = 0; Idx < Database->Info.MaxCallbackNum; Idx++) {
+ if (CallbackTable[Idx] != NULL) {
+ CallbackTable[Idx] (Guid,
+ PcdIndex->TokenNumber,
+ Data,
+ PcdIndex->DatumSize
+ );
+ }
+ }
+
+ Status = SetPcdData (PcdIndex, &Database->Info, Data);
+
+ return Status;
+}
+
+
+
+/**
+ (reviewed) The function set the PCD data value according to
+ TokenNumber and Guid space given.
+
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The Guid space.
+ @param[in] Type The storage type.
+ @param[in] Data The output data.
+
+
+ @retval EFI_SUCESS If data value is found according to SKU_ID.
+ @retval EFI_NOT_FOUND If not such a value is found.
+
+--*/
+EFI_STATUS
+PeiSetPcdEntryWorker (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ IN VOID *Data
+ )
+{
+ PCD_DATABASE *Database;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ ASSERT (Data != NULL);
+
+ GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
+ ASSERT (GuidHob != NULL);
+
+ Database = GET_GUID_HOB_DATA (GuidHob);
+
+ SetPcdEntryWorker (Database,
+ TokenNumber,
+ Guid,
+ Type,
+ Data
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+
+UINTN
+PeiGetPcdEntrySizeWorker (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid OPTIONAL
+ )
+{
+ PCD_DATABASE *Database;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
+ ASSERT (GuidHob != NULL);
+
+ Database = GET_GUID_HOB_DATA (GuidHob);
+
+ return GetPcdEntrySizeWorker (&Database->Info,
+ TokenNumber,
+ Guid
+ );
+
+}
+
+
+
+/**
+ The function registers the CallBackOnSet fucntion
+ according to TokenNumber and EFI_GUID space.
+
+ @param[in] TokenNumber The token number.
+ @param[in] Guid The GUID space.
+ @param[in] CallBackFunction The Callback function to be registered.
+
+ @retval EFI_SUCCESS If the Callback function is registered.
+ @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
+--*/
+EFI_STATUS
+PeiRegisterCallBackWorker (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PPI_CALLBACK CallBackFunction,
+ IN BOOLEAN Register
+)
+{
+ PCD_DATABASE *Database;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ PCD_INDEX *PcdIndex;
+ UINTN Idx;
+ PCD_PPI_CALLBACK *CallbackTable;
+ PCD_PPI_CALLBACK Compare;
+ PCD_PPI_CALLBACK Assign;
+
+ GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
+ ASSERT (GuidHob != NULL);
+
+ Database = GET_GUID_HOB_DATA (GuidHob);
+
+ PcdIndex = FindPcdIndex (TokenNumber, Guid, &Database->Info, NULL);
+
+ ASSERT (PcdIndex != NULL);
+
+ if (PcdIndex->StateByte.VpdEnable) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Idx = ((UINTN) PcdIndex - Database->Info.CallbackTableOffset) / sizeof(PCD_INDEX);
+
+ CallbackTable = (PCD_PPI_CALLBACK *) GetAbsoluteAddress (
+ sizeof (PCD_PPI_CALLBACK) * Idx * Database->Info.MaxCallbackNum,
+ Database->Info.CallbackTableOffset,
+ &Database->Info
+ );
+
+ Compare = Register? NULL: CallBackFunction;
+ Assign = Register? CallBackFunction: NULL;
+
+ for (Idx = 0; Idx < Database->Info.MaxCallbackNum; Idx++) {
+ if (CallbackTable[Idx] == Compare) {
+ CallbackTable[Idx] = Assign;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;
+
+}
+
+
+
+EFI_STATUS
+PeiGetNextTokenWorker (
+ IN OUT UINTN *TokenNumber,
+ IN CONST EFI_GUID *Guid OPTIONAL
+ )
+{
+ PCD_DATABASE *Database;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
+ ASSERT (GuidHob != NULL);
+
+ Database = GET_GUID_HOB_DATA (GuidHob);
+
+ return GetNextTokenWorker (&Database->Info,
+ TokenNumber,
+ Guid
+ );
+
+}
+
+
+
+VOID
+GetPcdImageInfo (
+ IN CONST UINT8 *PcdImageOnFlash,
+ OUT PCD_IMAGE_RECORD *ImageInfo
+)
+{
+ PCD_FFS_ENCODING *PcdFfsHdr;
+
+ PcdFfsHdr = (PCD_FFS_ENCODING *) PcdImageOnFlash;
+
+ ZeroMem (ImageInfo, sizeof (*ImageInfo));
+
+ ImageInfo->ImageStart = PcdImageOnFlash;
+
+ CopyMem (&ImageInfo->EntryCount, PcdFfsHdr->EntryCount, 3);
+
+ CopyMem (&ImageInfo->GlobalDatumLength, PcdFfsHdr->GlobalDatumLength, 1);
+ ASSERT (ImageInfo->GlobalDatumLength <= 3);
+
+ CopyMem (&ImageInfo->GlobalOffsetLength, PcdFfsHdr->GlobalOffsetLength, 1);
+ ASSERT (ImageInfo->GlobalOffsetLength <= 3);
+
+ CopyMem (&ImageInfo->GlobalTokenLength, PcdFfsHdr->GlobalTokenLength, 1);
+ ASSERT (ImageInfo->GlobalTokenLength <= 4);
+
+ CopyMem (&ImageInfo->GlobalGuidTabIdxLength, PcdFfsHdr->GuidLength, 1);
+ ASSERT (ImageInfo->GlobalGuidTabIdxLength <= 2);
+
+ CopyMem (&ImageInfo->GlobalStrTabIdxLength, PcdFfsHdr->GlobalStrTabIdxLength, 1);
+ ASSERT (ImageInfo->GlobalStrTabIdxLength <= 2);
+
+ CopyMem (&ImageInfo->ImageLength, PcdFfsHdr->ImageLength, 3);
+ CopyMem (&ImageInfo->IndexLength, PcdFfsHdr->PcdIndexLength, 3);
+ CopyMem (&ImageInfo->WholeDataDefaultLength, PcdFfsHdr->WholeDataBufferLength, 3);
+ CopyMem (&ImageInfo->DataDefaultLength, PcdFfsHdr->DataBufferLength, 3);
+ CopyMem (&ImageInfo->GuidTableLength, PcdFfsHdr->GuidTableLength, 3);
+
+ ImageInfo->StringTableLength = ImageInfo->ImageLength
+ - sizeof (PCD_FFS_ENCODING)
+ - ImageInfo->DataDefaultLength
+ - ImageInfo->IndexLength
+ - ImageInfo->GuidTableLength;
+
+ ImageInfo->DataDefaultStart = PcdImageOnFlash + sizeof (PCD_FFS_ENCODING);
+ ImageInfo->IndexStart = ImageInfo->DataDefaultStart + ImageInfo->DataDefaultLength;
+ ImageInfo->GuidTableStart = (CONST EFI_GUID *)(ImageInfo->IndexStart + ImageInfo->IndexLength);
+ ImageInfo->StringTableStart = (CONST UINT16 *) ((UINT8 *) ImageInfo->GuidTableStart + ImageInfo->GuidTableLength);
+
+ return;
+}
+
+
+
+/**
+ The function builds the PCD database based on the
+ PCD_IMAGE on the flash.
+
+ The layout of the PCD_DATABASE is as follows:
+
+ ---------------------------
+ | PCD_DATABASE_HEADER |
+ ---------------------------
+ | GUID_TABLE | Aligned on GUID (128 bits)
+ ---------------------------
+ | PCD_CALL_BACK_TABLE | Aligned on Pointer (32 bits or 64 bits)
+ ---------------------------
+ | PCD_INDEX_TABLE | Aligned on PCD_INDEX (see PCD_INDEX's declaration)
+ ---------------------------
+ | IMAGE_STRING_TABLE | Aligned on 16 Bits
+ ---------------------------
+ | IMAGE_PCD_INDEX | Unaligned
+ ---------------------------
+ | Data Defaults | Unaligned
+ ---------------------------
+ | Data Buffer |
+ | for entries without |
+ | defaults |
+ ---------------------------
+
+ @param[in] PcdImageOnFlash The PCD image on flash.
+
+ @retval VOID
+--*/
+UINTN
+GetPcdDatabaseLen (
+ IN CONST UINT8 *PcdImageOnFlash,
+ OUT PCD_DATABASE_HEADER *Info,
+ OUT PCD_IMAGE_RECORD *ImageInfo
+ )
+{
+ UINTN DatabaseLen;
+ UINTN DatabaseHeaderLength;
+ UINTN PcdIndexLength;
+ UINTN CallbackBufferLength;
+
+
+ GetPcdImageInfo (PcdImageOnFlash, ImageInfo);
+
+ Info->MaxCallbackNum = FixedPcdGet32(PcdMaxPcdCallBackNumber) ;
+
+ DatabaseHeaderLength = sizeof (PCD_DATABASE) - sizeof(UINT8);
+
+ PcdIndexLength = sizeof (PCD_INDEX) * ImageInfo->EntryCount;
+ CallbackBufferLength = sizeof (PCD_PPI_CALLBACK) * Info->MaxCallbackNum * ImageInfo->EntryCount;
+
+ Info->EntryCount = ImageInfo->EntryCount;
+ Info->GuidTableOffset = DatabaseHeaderLength;
+ Info->CallbackTableOffset = Info->GuidTableOffset + ImageInfo->GuidTableLength;
+ Info->PcdIndexOffset = Info->PcdIndexOffset + PcdIndexLength;
+ Info->ImageIndexOffset = Info->CallbackTableOffset + CallbackBufferLength;
+ Info->DataBufferOffset = Info->ImageIndexOffset + ImageInfo->DataDefaultLength;
+
+ Info->HiiGuidOffsetLength = ImageInfo->GlobalGuidTabIdxLength;
+ Info->HiiVariableOffsetLength = ImageInfo->GlobalStrTabIdxLength;
+ Info->ExtendedOffsetLength = ImageInfo->GlobalOffsetLength;
+
+ Info->SkuId = 0;
+
+ DatabaseLen = DatabaseHeaderLength
+ + ImageInfo->GuidTableLength
+ + PcdIndexLength
+ + CallbackBufferLength
+ + ImageInfo->IndexLength
+ + ImageInfo->WholeDataDefaultLength;
+
+ Info->DatabaseLen = DatabaseLen;
+
+ return DatabaseLen;
+}
+
+
+/**
+ The function constructs a single PCD_INDEX according a index in
+ <PCD_IMAGE>.
+
+ @param[in] ImageIndex The starting address of a PCD index defined in PCD spec 0.51.
+ @param[in] Index The output PCD_INDEX.
+ @param[in] ImageInfo The attributes of the PCD_IMAGE as this binary stream is highly
+ optimized for size.
+
+ @retval UINTN The length of the current PCD index.
+**/
+UINTN
+BuildPcdIndex (
+ IN CONST UINT8 *ImageIndex,
+ OUT PCD_INDEX *Index,
+ IN CONST PCD_IMAGE_RECORD *ImageInfo
+)
+{
+ UINTN SkuCount;
+ CONST UINT8 *ImageIndexBackUp;
+
+ ImageIndexBackUp = ImageIndex;
+
+ //
+ // Token Number
+ //
+ CopyMem (&Index->TokenNumber,
+ ImageIndex,
+ ImageInfo->GlobalTokenLength
+ );
+
+ ImageIndex += ImageInfo->GlobalTokenLength;
+
+ //
+ // State Byte
+ //
+ PcdImageExpandStateByte (&Index->StateByte,
+ *ImageIndex
+ );
+
+ ImageIndex += 1;
+
+ //
+ // Dataum Size
+ //
+ CopyMem (&Index->DatumSize,
+ ImageIndex,
+ ImageInfo->GlobalDatumLength
+ );
+
+ ImageIndex += ImageInfo->GlobalDatumLength;
+
+ //
+ // SKU_DATA
+ //
+ if (Index->StateByte.SkuEnable) {
+ Index->SkuCount = *ImageIndex;
+ SkuCount = *ImageIndex;
+ ImageIndex++;
+ Index->SkuIdArray = (UINT32) ImageIndex - (UINT32) ImageInfo->IndexStart;
+ ImageIndex += Index->SkuCount;
+ } else {
+ //
+ // There is always a default SKU_ID of zero even
+ // if SKU is not enabled for this PCD entry.
+ //
+ //
+ SkuCount = 1;
+ }
+
+ //
+ // Extended Offset
+ //
+ CopyMem (&Index->ExtendedDataOffset,
+ ImageIndex,
+ ImageInfo->GlobalOffsetLength
+ );
+
+ ImageIndex += ImageInfo->GlobalOffsetLength * SkuCount;
+
+ //
+ // DynamicEX Guid Offset
+ //
+ if (Index->StateByte.ExtendedGuidPresent) {
+ CopyMem (&Index->DynamicExGuid,
+ ImageIndex,
+ ImageInfo->GlobalGuidTabIdxLength
+ );
+
+ ImageIndex += ImageInfo->GlobalGuidTabIdxLength;
+ }
+
+ //
+ // HII_DATA
+ //
+ if (Index->StateByte.HiiEnable) {
+ Index->HiiData = (UINT32) ImageIndex - (UINT32) ImageInfo->IndexStart;
+ ImageIndex += ((ImageInfo->GlobalStrTabIdxLength + ImageInfo->GlobalGuidTabIdxLength) * SkuCount);
+ }
+
+ return (UINTN) (ImageIndex - ImageIndexBackUp);
+}
+
+
+
+
+/**
+ The function builds the PCD database based on the
+ PCD_IMAGE on the flash.
+
+ @param[in] Database The database instance.
+ @param[in] ImageIndex The starting address of a PCD index defined in PCD spec 0.51.
+ @param[in] ImageInfo The attributes of the PCD_IMAGE as this binary stream is highly
+ optimized for size.
+
+ @retval VOID
+**/
+VOID
+BuildPcdDatabaseIndex (
+ PCD_DATABASE *Database,
+ UINT8 *ImageIndex,
+ PCD_IMAGE_RECORD *ImageInfo
+ )
+{
+ UINTN Idx;
+ UINTN Len;
+ PCD_INDEX *IndexTable;
+
+ IndexTable = (PCD_INDEX *) GetAbsoluteAddress (0, Database->Info.PcdIndexOffset, Database);
+
+ for (Idx = 0; Idx < Database->Info.EntryCount; Idx++) {
+ Len = BuildPcdIndex (ImageIndex, &IndexTable[Idx], ImageInfo);
+ ImageIndex += Len;
+ }
+
+ return;
+}
+
+
+/**
+ The function builds the PCD database based on the
+ PCD_IMAGE on the flash.
+
+ @param[in] PcdImageOnFlash The PCD image on flash.
+
+ @retval VOID
+--*/
+VOID
+BuildPcdDatabase (
+ UINT8 *PcdImageOnFlash
+ )
+{
+ PCD_DATABASE *Database;
+ UINTN Len;
+ PCD_IMAGE_RECORD ImageInfo;
+ UINT8 *ImageIndex;
+ PCD_DATABASE_HEADER DatabaseHeader;
+
+ Len = GetPcdDatabaseLen(PcdImageOnFlash, &DatabaseHeader, &ImageInfo);
+
+ Database = BuildGuidHob (&gPcdDataBaseHobGuid, Len);
+ ASSERT (Database != NULL);
+
+ ZeroMem (Database, Len);
+
+ //
+ // Update Database header
+ //
+ CopyMem (&Database->Info, &DatabaseHeader, sizeof (DatabaseHeader));
+
+ //
+ // I need this to get the GuidTableOffset as we don't
+ // know if Database field of PCD_DATABASE starts from an aligned
+ // address. The compilor may add padding after PCD_DATABASE_HEADER field.
+ //
+ Database->Info.GuidTableOffset = ((UINTN) &Database->GuidTable) - (UINTN)Database;
+
+ //
+ // Copy Guid Table from Flash
+ //
+ CopyMem ((UINT8 *) Database + Database->Info.GuidTableOffset,
+ ImageInfo.GuidTableStart,
+ ImageInfo.GuidTableLength
+ );
+
+ //
+ // Copy ImageIndex from Flash
+ //
+ CopyMem ((UINT8 *) Database + Database->Info.ImageIndexOffset,
+ ImageInfo.IndexStart,
+ ImageInfo.IndexLength
+ );
+
+ //
+ // Copy Default Value
+ //
+ CopyMem ((UINT8 *) Database + Database->Info.DataBufferOffset,
+ ImageInfo.DataDefaultStart,
+ ImageInfo.DataDefaultLength
+ );
+
+ //
+ // Copy String Table
+ //
+ CopyMem ((UINT8 *) Database + Database->Info.StringTableOffset,
+ ImageInfo.StringTableStart,
+ ImageInfo.StringTableLength
+ );
+
+ ImageIndex = GetAbsoluteAddress (0, Database->Info.ImageIndexOffset, Database);
+
+ BuildPcdDatabaseIndex (Database, ImageIndex, &ImageInfo);
+
+ return;
+}
+
+
+
+/**
+ The function is provided by PCD PEIM and PCD DXE driver to
+ do the work of reading a HII variable from variable service.
+
+ @param[in] VariableGuid The Variable GUID.
+ @param[in] VariableName The Variable Name.
+ @param[out] VariableData The output data.
+ @param[out] VariableSize The size of the variable.
+
+ @retval EFI_SUCCESS Operation successful.
+ @retval EFI_SUCCESS Variablel not found.
+--*/
+EFI_STATUS
+GetHiiVariable (
+ IN EFI_GUID *VariableGuid,
+ IN UINT16 *VariableName,
+ OUT VOID **VariableData,
+ OUT UINTN *VariableSize
+ )
+{
+ UINTN Size;
+ EFI_STATUS Status;
+ VOID *Buffer;
+ EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;
+
+ Status = PeiCoreLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, &VariablePpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Size = 0;
+
+ Status = VariablePpi->PeiGetVariable (
+ GetPeiServicesTablePointer (),
+ VariableName,
+ VariableGuid,
+ NULL,
+ &Size,
+ NULL
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ Status = PeiCoreAllocatePool (Size, &Buffer);
+ ASSERT_EFI_ERROR (Status);
+
+ // declare a local for STP.
+ //
+ Status = VariablePpi->PeiGetVariable (
+ GetPeiServicesTablePointer (),
+ (UINT16 *) VariableName,
+ VariableGuid,
+ NULL,
+ &Size,
+ Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ *VariableSize = Size;
+ *VariableData = Buffer;
+
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ The function is provided by PCD PEIM and PCD DXE driver to
+ do the work of reading a HII variable from variable service.
+
+ @param[in] VariableGuid The Variable GUID.
+ @param[in] VariableName The Variable Name.
+ @param[in] Data The input data.
+ @param[out] VariableSize The size of the variable.
+ @param[in] Offset The offset of the variable data that a PCD entry will starts from.
+
+ @retval EFI_SUCCESS Operation successful.
+ @retval EFI_SUCCESS Variablel not found.
+--*/
+EFI_STATUS
+SetHiiVariable (
+ IN EFI_GUID *VariableGuid,
+ IN UINT16 *VariableName,
+ IN CONST VOID *Data,
+ IN UINTN VariableSize,
+ IN UINTN Offset
+ )
+{
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+}
+
+
diff --git a/EdkModulePkg/Universal/PCD/Pei/Service.h b/EdkModulePkg/Universal/PCD/Pei/Service.h
new file mode 100644
index 0000000..d775a12
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Pei/Service.h
@@ -0,0 +1,371 @@
+/** @file
+Private functions used by PCD PEIM.
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: Service.h
+
+**/
+
+#ifndef _SERVICE_H
+#define _SERVICE_H
+
+//
+// Offset of StateByte
+//
+#define PCD_STATEBYTE_HIIENABLE 0x01
+#define PCD_STATEBYTE_SKUENABLE 0x02
+#define PCD_STATEBYTE_VPDENABLE 0x04
+#define PCD_STATEBYTE_SKUDATAARRAYENABLE 0x08
+#define PCD_STATEBYTE_DATUMTYPE 0x70
+#define PCD_STATEBYTE_EXTENDEDGUIDPRESENT 0x80
+
+#define PCD_DATUMTYPE_OFFSET 4
+
+//
+// The definitions for interpreting DatumType
+//
+#define PCD_BYTE8 (0x00 << PCD_DATUMTYPE_OFFSET)
+#define PCD_BYTE16 (0x01 << PCD_DATUMTYPE_OFFSET)
+#define PCD_BYTE32 (0x02 << PCD_DATUMTYPE_OFFSET)
+#define PCD_BYTE64 (0x03 << PCD_DATUMTYPE_OFFSET)
+#define PCD_POINTER (0x04 << PCD_DATUMTYPE_OFFSET)
+#define PCD_BOOLEAN (0x05 << PCD_DATUMTYPE_OFFSET)
+
+extern GUID gEfiPcdImageHobGuid;
+
+/* Internal Function definitions */
+
+VOID
+PeiGetPcdEntryWorker (
+ IN UINTN Token,
+ IN CONST GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ OUT VOID *Data
+ );
+
+EFI_STATUS
+PeiSetPcdEntryWorker (
+ IN UINTN Token,
+ IN CONST GUID *Guid, OPTIONAL
+ IN PCD_DATA_TYPE Type,
+ IN VOID *Data
+ );
+
+UINTN
+PeiGetPcdEntrySizeWorker (
+ IN UINTN Token,
+ IN CONST GUID *Guid OPTIONAL
+ );
+
+EFI_STATUS
+PeiRegisterCallBackWorker (
+ IN UINTN TokenNumber,
+ IN CONST GUID *Guid, OPTIONAL
+ IN PCD_PPI_CALLBACK CallBackFunction,
+ IN BOOLEAN Register
+);
+
+EFI_STATUS
+PeiSetSku (
+ UINTN Id
+);
+
+EFI_STATUS
+PeiGetNextTokenWorker (
+ IN OUT UINTN *Token,
+ IN CONST GUID *Guid OPTIONAL
+ );
+
+UINT8 *
+LocatePcdImage (
+ VOID
+);
+
+VOID
+BuildPcdDatabase (
+ UINT8 *PcdImageOnFlash
+ )
+;
+
+
+extern EFI_GUID gPcdImageFileGuid;
+
+//
+// PPI Interface Implementation Declaration.
+//
+EFI_STATUS
+EFIAPI
+PeiPcdSetSku (
+ IN UINTN SkuId
+ )
+;
+
+
+UINT8
+EFIAPI
+PeiPcdGet8 (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT16
+EFIAPI
+PeiPcdGet16 (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT32
+EFIAPI
+PeiPcdGet32 (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT64
+EFIAPI
+PeiPcdGet64 (
+ IN UINTN TokenNumber
+ )
+;
+
+
+VOID *
+EFIAPI
+PeiPcdGetPtr (
+ IN UINTN TokenNumber
+ )
+;
+
+
+BOOLEAN
+EFIAPI
+PeiPcdGetBool (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINTN
+EFIAPI
+PeiPcdGetSize (
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT8
+EFIAPI
+PeiPcdGet8Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT16
+EFIAPI
+PeiPcdGet16Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+UINT32
+EFIAPI
+PeiPcdGet32Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINT64
+EFIAPI
+PeiPcdGet64Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+VOID *
+EFIAPI
+PeiPcdGetPtrEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+BOOLEAN
+EFIAPI
+PeiPcdGetBoolEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+UINTN
+EFIAPI
+PeiPcdGetSizeEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet8 (
+ IN UINTN TokenNumber,
+ IN UINT8 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet16 (
+ IN UINTN TokenNumber,
+ IN UINT16 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet32 (
+ IN UINTN TokenNumber,
+ IN UINT32 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet64 (
+ IN UINTN TokenNumber,
+ IN UINT64 Value
+ )
+;
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetPtr (
+ IN UINTN TokenNumber,
+ IN CONST VOID *Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetBool (
+ IN UINTN TokenNumber,
+ IN BOOLEAN Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet8Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT8 Value
+ )
+;
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet16Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT16 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet32Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT32 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSet64Ex (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN UINT64 Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetPtrEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN CONST VOID *Value
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdSetBoolEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ IN BOOLEAN Value
+ )
+;
+
+
+
+EFI_STATUS
+EFIAPI
+PcdRegisterCallBackOnSet (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PPI_CALLBACK CallBackFunction
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PcdUnRegisterCallBackOnSet (
+ IN UINTN TokenNumber,
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN PCD_PPI_CALLBACK CallBackFunction
+ )
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiPcdGetNextToken (
+ IN CONST EFI_GUID *Guid, OPTIONAL
+ IN OUT UINTN *TokenNumber
+ )
+;
+#endif
diff --git a/EdkModulePkg/Universal/PCD/Test/PcdTest.c b/EdkModulePkg/Universal/PCD/Test/PcdTest.c
new file mode 100644
index 0000000..77e25ac
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Test/PcdTest.c
@@ -0,0 +1,110 @@
+/** @file
+PCD TEST PEIM
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name: PcdTest.c
+
+**/
+#define GUID1 \
+ {0xF9349C58, 0xB767, 0x42c8, 0xB3, 0x6B, 0x41, 0x25, 0xDE, 0x3A, 0xEF, 0xEB}
+
+CONST GUID Guid1 = GUID1;
+
+
+EFI_STATUS
+EFIAPI
+OnsetCallback1 (
+ IN UINT32 CallBackToken,
+ IN VOID *TokenData,
+ IN UINTN TokenDataSize
+ )
+{
+ DebugPrint (0x80000000, "In CallbackOnSet %x %d\n", * ((UINT32 *)TokenData), TokenDataSize);
+ return EFI_SUCCESS;
+}
+
+
+VOID
+DoTest(
+ VOID
+ )
+{
+ PCD_TOKEN_NUMBER tn;
+ UINTN Size;
+ VOID * Ptr;
+ UINT32 Uint32;
+ UINT32 Uint32a;
+ UINT64 Uint64;
+ UINT64 Uint64a;
+ INTN i;
+
+ tn = 0x00001000;
+
+ Size = LibPcdGetSize (tn);
+ Ptr = LibPcdGetPtr (tn); /* a:RW;2880;512!e:RW;262144;512 */
+
+ tn = 0x00001001;
+ Size = LibPcdGetSize (tn); /* FW;40960;512 */
+
+ tn = 0x00001002;
+ Size = LibPcdGetSize (tn); /* FW;40960;512 */
+ Ptr = LibPcdGetPtr (tn);
+
+ LibPcdSetSku (0x0a);
+ tn = 0x2233;
+ Uint64 = LibPcdGet64 (tn);
+
+ LibPcdSetSku (0x0b);
+ Uint64 = LibPcdGet64 (tn);
+
+ LibPcdSetSku (0x0c);
+ Uint64a = LibPcdGet64 (tn);
+
+ LibPcdSetSku (0);
+ tn = 0x2233;
+ Uint64 = LibPcdGet64 (tn);
+
+
+ tn = 0xfaceface;
+ Size = LibPcdGetExSize (&Guid1, tn);
+ Uint32 = LibPcdGetEx32 (&Guid1, tn);
+
+ LibPcdCallBackOnSet (&Guid1, tn, OnsetCallback1);
+
+ LibPcdCancelCallBackOnSet (&Guid1, tn, OnsetCallback1);
+
+ for (i = 0; i < 2; i++) {
+ Uint32a = LibPcdSetEx32 (&Guid1, tn, Uint32 + i);
+ DebugPrint (0x80000000, "%x\n", Uint32a);
+ }
+
+
+
+ Uint32 = LibPcdGet32 (tn);
+
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+PcdTestPeimInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+
+ DoTest();
+
+ return EFI_SUCCESS;
+}
+
diff --git a/EdkModulePkg/Universal/PCD/Test/PcdTest.dxs b/EdkModulePkg/Universal/PCD/Test/PcdTest.dxs
new file mode 100644
index 0000000..bf74296
--- /dev/null
+++ b/EdkModulePkg/Universal/PCD/Test/PcdTest.dxs
@@ -0,0 +1,28 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Variable.dxs
+
+Abstract:
+
+ Dependency expression file for PcdTest PEIM.
+
+--*/
+#include <AutoGen.h>
+#include <PeimDepex.h>
+
+DEPENDENCY_START
+ PCD_PPI_GUID
+DEPENDENCY_END
+
+