From 80408db0ca4e3d40b37c0f3a710ad4828e26f5f4 Mon Sep 17 00:00:00 2001 From: vanjeff Date: Tue, 3 Jul 2007 08:28:05 +0000 Subject: [PATCH] Import PCD dxe and PCD pei modules. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2994 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Universal/PCD/Dxe/CommonHeader.h | 41 + MdeModulePkg/Universal/PCD/Dxe/Pcd.c | 737 +++++++++++ MdeModulePkg/Universal/PCD/Dxe/Pcd.dxs | 26 + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf | 135 ++ MdeModulePkg/Universal/PCD/Dxe/Pcd.msa | 99 ++ MdeModulePkg/Universal/PCD/Dxe/Service.c | 1158 +++++++++++++++++ MdeModulePkg/Universal/PCD/Dxe/Service.h | 485 +++++++ MdeModulePkg/Universal/PCD/Pei/CommonHeader.h | 40 + MdeModulePkg/Universal/PCD/Pei/Pcd.c | 801 ++++++++++++ MdeModulePkg/Universal/PCD/Pei/Pcd.dxs | 25 + MdeModulePkg/Universal/PCD/Pei/Pcd.inf | 140 ++ MdeModulePkg/Universal/PCD/Pei/Pcd.msa | 129 ++ MdeModulePkg/Universal/PCD/Pei/Service.c | 733 +++++++++++ MdeModulePkg/Universal/PCD/Pei/Service.h | 462 +++++++ 14 files changed, 5011 insertions(+) create mode 100644 MdeModulePkg/Universal/PCD/Dxe/CommonHeader.h create mode 100644 MdeModulePkg/Universal/PCD/Dxe/Pcd.c create mode 100644 MdeModulePkg/Universal/PCD/Dxe/Pcd.dxs create mode 100644 MdeModulePkg/Universal/PCD/Dxe/Pcd.inf create mode 100644 MdeModulePkg/Universal/PCD/Dxe/Pcd.msa create mode 100644 MdeModulePkg/Universal/PCD/Dxe/Service.c create mode 100644 MdeModulePkg/Universal/PCD/Dxe/Service.h create mode 100644 MdeModulePkg/Universal/PCD/Pei/CommonHeader.h create mode 100644 MdeModulePkg/Universal/PCD/Pei/Pcd.c create mode 100644 MdeModulePkg/Universal/PCD/Pei/Pcd.dxs create mode 100644 MdeModulePkg/Universal/PCD/Pei/Pcd.inf create mode 100644 MdeModulePkg/Universal/PCD/Pei/Pcd.msa create mode 100644 MdeModulePkg/Universal/PCD/Pei/Service.c create mode 100644 MdeModulePkg/Universal/PCD/Pei/Service.h diff --git a/MdeModulePkg/Universal/PCD/Dxe/CommonHeader.h b/MdeModulePkg/Universal/PCD/Dxe/CommonHeader.h new file mode 100644 index 0000000000..f01b863ce0 --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Dxe/CommonHeader.h @@ -0,0 +1,41 @@ +/**@file + Common header file shared by all source files. + + This file includes package header files, library classes and protocol, PPI & GUID definitions. + + Copyright (c) 2006 - 2007, 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. +**/ + +#ifndef __COMMON_HEADER_H_ +#define __COMMON_HEADER_H_ + + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c new file mode 100644 index 0000000000..861de0fa84 --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c @@ -0,0 +1,737 @@ +/** @file +PCD DXE driver + +Copyright (c) 2006 - 2007, 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 header file for this module. +// +#include "CommonHeader.h" + +#include "Service.h" + +EFI_LOCK mPcdDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_CALLBACK); + +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, + + DxeRegisterCallBackOnSet, + DxeUnRegisterCallBackOnSet, + DxePcdGetNextToken, + DxePcdGetNextTokenSpace +}; + + +// +// Static global to reduce the code size +// +static EFI_HANDLE mNewHandle = NULL; + +EFI_STATUS +EFIAPI +PcdDxeInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Make sure the Pcd Protocol is not already installed in the system + // + + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid); + + BuildPcdDxeDataBase (); + + Status = gBS->InstallProtocolInterface ( + &mNewHandle, + &gPcdProtocolGuid, + EFI_NATIVE_INTERFACE, + &mPcdInstance + ); + + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; + +} + + +VOID +EFIAPI +DxePcdSetSku ( + IN UINTN SkuId + ) +{ + mPcdDatabase->PeiDb.Init.SystemSkuId = (SKU_ID) SkuId; + + return; +} + + + +UINT8 +EFIAPI +DxePcdGet8 ( + IN UINTN TokenNumber + ) +{ + return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8))); +} + + + +UINT16 +EFIAPI +DxePcdGet16 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16))); +} + + + +UINT32 +EFIAPI +DxePcdGet32 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32))); +} + + + +UINT64 +EFIAPI +DxePcdGet64 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned64(GetWorker (TokenNumber, sizeof (UINT64))); +} + + + +VOID * +EFIAPI +DxePcdGetPtr ( + IN UINTN TokenNumber + ) +{ + return GetWorker (TokenNumber, 0); +} + + + +BOOLEAN +EFIAPI +DxePcdGetBool ( + IN UINTN TokenNumber + ) +{ + return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN))); +} + + + +UINTN +EFIAPI +DxePcdGetSize ( + IN UINTN TokenNumber + ) +{ + UINTN Size; + UINT32 *LocalTokenNumberTable; + BOOLEAN IsPeiDb; + UINTN MaxSize; + UINTN TmpTokenNumber; + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + // + // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber + // + TmpTokenNumber = TokenNumber; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1); + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN) (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + TokenNumber = IsPeiDb ? TokenNumber : + (TokenNumber - PEI_LOCAL_TOKEN_NUMBER); + + LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable + : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + + Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT; + + if (Size == 0) { + // + // For pointer type, we need to scan the SIZE_TABLE to get the current size. + // + return GetPtrTypeSize (TmpTokenNumber, &MaxSize); + } else { + return Size; + } + +} + + + +UINT8 +EFIAPI +DxePcdGet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof(UINT8))); +} + + + +UINT16 +EFIAPI +DxePcdGet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT16))); +} + + + +UINT32 +EFIAPI +DxePcdGet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT32))); +} + + + +UINT64 +EFIAPI +DxePcdGet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT64))); +} + + + +VOID * +EFIAPI +DxePcdGetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ExGetWorker (Guid, ExTokenNumber, 0); +} + + + +BOOLEAN +EFIAPI +DxePcdGetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof(BOOLEAN))); +} + + + +UINTN +EFIAPI +DxePcdGetSizeEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return DxePcdGetSize(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSet8 ( + IN UINTN TokenNumber, + IN UINT8 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSet16 ( + IN UINTN TokenNumber, + IN UINT16 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSet32 ( + IN UINTN TokenNumber, + IN UINT32 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSet64 ( + IN UINTN TokenNumber, + IN UINT64 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSetPtr ( + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +{ + return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE); +} + + + +EFI_STATUS +EFIAPI +DxePcdSetBool ( + IN UINTN TokenNumber, + IN BOOLEAN Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT8 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT16 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT32 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT64 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +DxePcdSetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +{ + return ExSetWorker(ExTokenNumber, Guid, Buffer, SizeOfBuffer, TRUE); +} + + + +EFI_STATUS +EFIAPI +DxePcdSetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN BOOLEAN Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + + +EFI_STATUS +EFIAPI +DxeRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +{ + EFI_STATUS Status; + + ASSERT (CallBackFunction != NULL); + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + Status = DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction); + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; +} + + + +EFI_STATUS +EFIAPI +DxeUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +{ + EFI_STATUS Status; + + ASSERT (CallBackFunction != NULL); + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + Status = DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction); + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; +} + + + +EFI_STATUS +EFIAPI +DxePcdGetNextToken ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN OUT UINTN *TokenNumber + ) +{ + EFI_STATUS Status; + BOOLEAN PeiExMapTableEmpty; + BOOLEAN DxeExMapTableEmpty; + + if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled)) { + return EFI_UNSUPPORTED; + } + + Status = EFI_NOT_FOUND; + PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY; + DxeExMapTableEmpty = DXE_EXMAP_TABLE_EMPTY; + + // + // Scan the local token space + // + if (Guid == NULL) { + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + if (((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) && (*TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1)) || + ((*TokenNumber + 1 > (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1)))) { + return EFI_NOT_FOUND; + } + + (*TokenNumber)++; + if ((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) && + (*TokenNumber <= PEI_LOCAL_TOKEN_NUMBER)) { + // + // The first Non-Ex type Token Number for DXE PCD + // database is PEI_LOCAL_TOKEN_NUMBER + // + *TokenNumber = PEI_LOCAL_TOKEN_NUMBER; + } else if (*TokenNumber + 1 > DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER + 1) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + } + return EFI_SUCCESS; + } + + if (PeiExMapTableEmpty && DxeExMapTableEmpty) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } + + if (!PeiExMapTableEmpty) { + Status = ExGetNextTokeNumber ( + Guid, + TokenNumber, + mPcdDatabase->PeiDb.Init.GuidTable, + sizeof(mPcdDatabase->PeiDb.Init.GuidTable), + mPcdDatabase->PeiDb.Init.ExMapTable, + sizeof(mPcdDatabase->PeiDb.Init.ExMapTable) + ); + } + + if (Status == EFI_SUCCESS) { + return Status; + } + + if (!DxeExMapTableEmpty) { + Status = ExGetNextTokeNumber ( + Guid, + TokenNumber, + mPcdDatabase->DxeDb.Init.GuidTable, + sizeof(mPcdDatabase->DxeDb.Init.GuidTable), + mPcdDatabase->DxeDb.Init.ExMapTable, + sizeof(mPcdDatabase->DxeDb.Init.ExMapTable) + ); + } + + return Status; +} + +STATIC +EFI_GUID ** +GetDistinctTokenSpace ( + IN OUT UINTN *ExMapTableSize, + IN DYNAMICEX_MAPPING *ExMapTable, + IN EFI_GUID *GuidTable + ) +{ + EFI_GUID **DistinctTokenSpace; + UINTN OldGuidIndex; + UINTN TsIdx; + UINTN Idx; + + + DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *)); + ASSERT (DistinctTokenSpace != NULL); + + TsIdx = 0; + OldGuidIndex = ExMapTable[0].ExGuidIndex; + DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex]; + for (Idx = 1; Idx < *ExMapTableSize; Idx++) { + if (ExMapTable[Idx].ExGuidIndex != OldGuidIndex) { + OldGuidIndex = ExMapTable[Idx].ExGuidIndex; + DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex]; + } + } + + // + // The total number of Distinct Token Space + // is TsIdx + 1 because we use TsIdx as a index + // to the DistinctTokenSpace[] + // + *ExMapTableSize = TsIdx + 1; + return DistinctTokenSpace; + +} + +// +// Just pre-allocate a memory buffer that is big enough to +// host all distinct TokenSpace guid in both +// PEI ExMap and DXE ExMap. +// +STATIC EFI_GUID *TmpTokenSpaceBuffer[PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE] = { 0 }; + +EFI_STATUS +EFIAPI +DxePcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ) +{ + UINTN Idx; + UINTN Idx2; + UINTN Idx3; + UINTN PeiTokenSpaceTableSize; + UINTN DxeTokenSpaceTableSize; + EFI_GUID **PeiTokenSpaceTable; + EFI_GUID **DxeTokenSpaceTable; + BOOLEAN Match; + BOOLEAN PeiExMapTableEmpty; + BOOLEAN DxeExMapTableEmpty; + + if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled)) { + return EFI_UNSUPPORTED; + } + + ASSERT (Guid != NULL); + + PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY; + DxeExMapTableEmpty = DXE_EXMAP_TABLE_EMPTY; + + if (PeiExMapTableEmpty && DxeExMapTableEmpty) { + if (*Guid != NULL) { + return EFI_NOT_FOUND; + } else { + return EFI_SUCCESS; + } + } + + + if (TmpTokenSpaceBuffer[0] == NULL) { + PeiTokenSpaceTableSize = 0; + + if (!PeiExMapTableEmpty) { + PeiTokenSpaceTableSize = PEI_EXMAPPING_TABLE_SIZE; + PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize, + mPcdDatabase->PeiDb.Init.ExMapTable, + mPcdDatabase->PeiDb.Init.GuidTable + ); + CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize); + } + + if (!DxeExMapTableEmpty) { + DxeTokenSpaceTableSize = DXE_EXMAPPING_TABLE_SIZE; + DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize, + mPcdDatabase->DxeDb.Init.ExMapTable, + mPcdDatabase->DxeDb.Init.GuidTable + ); + + // + // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable + // + for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) { + Match = FALSE; + for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) { + if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) { + Match = TRUE; + break; + } + } + if (!Match) { + TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2]; + } + } + } + } + + if (*Guid == NULL) { + *Guid = TmpTokenSpaceBuffer[0]; + return EFI_SUCCESS; + } + + for (Idx = 0; Idx < (PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE); Idx++) { + if(CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) { + Idx++; + *Guid = TmpTokenSpaceBuffer[Idx]; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; + +} + + diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.dxs b/MdeModulePkg/Universal/PCD/Dxe/Pcd.dxs new file mode 100644 index 0000000000..860153705b --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.dxs @@ -0,0 +1,26 @@ +/*++ + +Copyright (c) 2006 - 2007, 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.dxs + +Abstract: + + Dependency expression source file. + +--*/ + +#include + +DEPENDENCY_START + TRUE +DEPENDENCY_END diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf new file mode 100644 index 0000000000..6b4103566e --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf @@ -0,0 +1,135 @@ +#/** @file +# Component description file for PCD service DXE driver. +# +# This DXE driver implement and produce the PCD protocol. +# Copyright (c) 2006 - 2007, 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PcdDxe + FILE_GUID = 80CF7257-87AB-47f9-A3FE-D50B76D89541 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + PCD_DRIVER = DXE_PCD_DRIVER + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = PcdDxeInit + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + Pcd.c + Service.c + Service.h + CommonHeader.h + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + UefiRuntimeServicesTableLib + BaseMemoryLib + UefiBootServicesTableLib + MemoryAllocationLib + HobLib + PcdLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gPcdDataBaseHobGuid # ALWAYS_CONSUMED Hob: GUID_EXTENSION + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gPcdProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +################################################################################ +# +# Pcd FEATURE_FLAG - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFeatureFlag.common] + PcdDxePcdDatabaseTraverseEnabled|gEfiEdkModulePkgTokenSpaceGuid + + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild.common] + PcdVpdBaseAddress|gEfiEdkModulePkgTokenSpaceGuid + + +################################################################################ +# +# Dependency Expression Section - list of Dependency expressions that are required for +# this module. +# +################################################################################ + +[Depex] + TRUE + diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.msa b/MdeModulePkg/Universal/PCD/Dxe/Pcd.msa new file mode 100644 index 0000000000..d920f68e92 --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.msa @@ -0,0 +1,99 @@ + + + + PcdDxe + DXE_DRIVER + 80CF7257-87AB-47f9-A3FE-D50B76D89541 + 1.0 + Component description file for PCD service DXE driver. + This DXE driver implement and produce the PCD protocol. + Copyright (c) 2006 - 2007, 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + PcdDxe + + + + BaseLib + + + DebugLib + Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg. + + + UefiLib + + + UefiDriverEntryPoint + + + PcdLib + + + HobLib + + + MemoryAllocationLib + + + UefiBootServicesTableLib + + + BaseMemoryLib + + + UefiRuntimeServicesTableLib + + + + Service.h + Service.c + Pcd.c + Pcd.dxs + + + + + + + + gPcdProtocolGuid + + + + + GUID_EXTENSION + + + + DXE_PCD_DRIVER + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + PcdDxeInit + + + + + PcdVpdBaseAddress + gEfiEdkModulePkgTokenSpaceGuid + The base address of the VPD (Vital Product Data) region. It is + normally a region reserved on flash. + + + PcdDxePcdDatabaseTraverseEnabled + gEfiEdkModulePkgTokenSpaceGuid + This feature flag can be used to enable or disable the Pcd DXE database + traverse capability. Disable it can reduce the size of final image generated. + + + \ 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 index 0000000000..96a40291af --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c @@ -0,0 +1,1158 @@ +/** @file +Private functions used by PCD DXE driver. + +Copyright (c) 2006 - 2007, 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 header file for this module. +// +#include "CommonHeader.h" + +#include "Service.h" + + +PCD_DATABASE * mPcdDatabase; + +LIST_ENTRY *mCallbackFnTable; + +VOID * +GetWorker ( + UINTN TokenNumber, + UINTN GetSize + ) +{ + UINT32 *LocalTokenNumberTable; + EFI_GUID *GuidTable; + UINT16 *StringTable; + EFI_GUID *Guid; + UINT16 *Name; + VARIABLE_HEAD *VariableHead; + UINT8 *VaraiableDefaultBuffer; + UINT8 *Data; + VPD_HEAD *VpdHead; + UINT8 *PcdDb; + VOID *RetPtr; + UINTN MaxSize; + UINTN TmpTokenNumber; + UINTN DataSize; + EFI_STATUS Status; + UINT32 LocalTokenNumber; + UINT32 Offset; + UINT16 StringTableIdx; + BOOLEAN IsPeiDb; + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + RetPtr = NULL; + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + TmpTokenNumber = TokenNumber; + + // + // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant. + // It could be zero. EBC compiler is very choosy. It may + // report warning. So we add 1 in each size of the + // comparison. + // + ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1); + + ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0)); + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE); + + LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : + mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + + TokenNumber = IsPeiDb ? TokenNumber : + TokenNumber - PEI_LOCAL_TOKEN_NUMBER; + + LocalTokenNumber = LocalTokenNumberTable[TokenNumber]; + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { + if (GetSize == 0) { + GetPtrTypeSize (TmpTokenNumber, &MaxSize); + } else { + MaxSize = GetSize; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb); + } + + PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb); + StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable : + mPcdDatabase->DxeDb.Init.StringTable; + + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset); + RetPtr = (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset); + break; + + case PCD_TYPE_HII: + GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable : + mPcdDatabase->DxeDb.Init.GuidTable; + + VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset); + + Guid = &(GuidTable[VariableHead->GuidTableIndex]); + Name = &(StringTable[VariableHead->StringIndex]); + VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset; + + Status = GetHiiVariable (Guid, Name, &Data, &DataSize); + if (Status == EFI_SUCCESS) { + if (GetSize == 0) { + // + // It is a pointer type. So get the MaxSize reserved for + // this PCD entry. + // + GetPtrTypeSize (TmpTokenNumber, &GetSize); + } + CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize); + FreePool (Data); + } + // + // If the operation is successful, we copy the data + // to the default value buffer in the PCD Database. + // So that we can free the Data allocated in GetHiiVariable. + // + // + // If the operation is not successful, + // Return 1) either the default value specified by Platform Integrator + // 2) Or the value Set by a PCD set operation. + // + RetPtr = (VOID *) VaraiableDefaultBuffer; + break; + + case PCD_TYPE_STRING: + StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset); + RetPtr = (VOID *) &StringTable[StringTableIdx]; + break; + + case PCD_TYPE_DATA: + RetPtr = (VOID *) ((UINT8 *) PcdDb + Offset); + break; + + default: + ASSERT (FALSE); + break; + + } + + EfiReleaseLock (&mPcdDatabaseLock); + + return RetPtr; + +} + + + +EFI_STATUS +DxeRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST GUID *Guid, OPTIONAL + IN PCD_PROTOCOL_CALLBACK CallBackFunction +) +{ + CALLBACK_FN_ENTRY *FnTableEntry; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; + + if (Guid != NULL) { + TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber); + } + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + ListHead = &mCallbackFnTable[TokenNumber]; + ListNode = GetFirstNode (ListHead); + + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node); + + if (FnTableEntry->CallbackFn == CallBackFunction) { + // + // We only allow a Callback function to be register once + // for a TokenNumber. So just return EFI_SUCCESS + // + return EFI_SUCCESS; + } + ListNode = GetNextNode (ListHead, ListNode); + } + + FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY)); + ASSERT (FnTableEntry != NULL); + + FnTableEntry->CallbackFn = CallBackFunction; + InsertTailList (ListHead, &FnTableEntry->Node); + + return EFI_SUCCESS; +} + + + + +EFI_STATUS +DxeUnRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST GUID *Guid, OPTIONAL + IN PCD_PROTOCOL_CALLBACK CallBackFunction +) +{ + CALLBACK_FN_ENTRY *FnTableEntry; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; + + if (Guid != NULL) { + TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber); + } + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + ListHead = &mCallbackFnTable[TokenNumber]; + ListNode = GetFirstNode (ListHead); + + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node); + + if (FnTableEntry->CallbackFn == CallBackFunction) { + // + // We only allow a Callback function to be register once + // for a TokenNumber. So we can safely remove the Node from + // the Link List and return EFI_SUCCESS. + // + RemoveEntryList (ListNode); + FreePool (FnTableEntry); + + return EFI_SUCCESS; + } + ListNode = GetNextNode (ListHead, ListNode); + } + + return EFI_INVALID_PARAMETER; +} + + + +EFI_STATUS +ExGetNextTokeNumber ( + IN CONST EFI_GUID *Guid, + IN OUT UINTN *TokenNumber, + IN EFI_GUID *GuidTable, + IN UINTN SizeOfGuidTable, + IN DYNAMICEX_MAPPING *ExMapTable, + IN UINTN SizeOfExMapTable + ) +{ + EFI_GUID *MatchGuid; + UINTN Idx; + UINTN GuidTableIdx; + BOOLEAN Found; + + MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid); + if (MatchGuid == NULL) { + return EFI_NOT_FOUND; + } + + Found = FALSE; + GuidTableIdx = MatchGuid - GuidTable; + for (Idx = 0; Idx < SizeOfExMapTable; Idx++) { + if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) { + Found = TRUE; + break; + } + } + + if (Found) { + if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + *TokenNumber = ExMapTable[Idx].ExTokenNumber; + return EFI_SUCCESS; + } + + for ( ; Idx < SizeOfExMapTable; Idx++) { + if (ExMapTable[Idx].ExTokenNumber == *TokenNumber) { + Idx++; + if (Idx == SizeOfExMapTable) { + // + // Exceed the length of ExMap Table + // + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_SUCCESS; + } else if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) { + // + // Found the next match + // + *TokenNumber = ExMapTable[Idx].ExTokenNumber; + return EFI_SUCCESS; + } else { + // + // Guid has been changed. It is the next Token Space Guid. + // We should flag no more TokenNumber. + // + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_SUCCESS; + } + } + } + } + + return EFI_NOT_FOUND; +} + + + + +VOID +BuildPcdDxeDataBase ( + VOID + ) +{ + PEI_PCD_DATABASE *PeiDatabase; + EFI_HOB_GUID_TYPE *GuidHob; + UINTN Idx; + + mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE)); + ASSERT (mPcdDatabase != NULL); + + GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); + if (GuidHob != NULL) { + + // + // We will copy over the PEI phase's PCD Database. + // + // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM + // should not be included at all. So the GuidHob could + // be NULL. If it is NULL, we just copy over the DXE Default + // Value to PCD Database. + // + + PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); + // + // Copy PCD Entries refereneced in PEI phase to PCD DATABASE + // + CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE)); + } + + // + // Copy PCD Entries with default value to PCD DATABASE + // + CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT)); + + + // + // Initialized the Callback Function Table + // + + mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY)); + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + for (Idx = 0; Idx + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Idx++) { + InitializeListHead (&mCallbackFnTable[Idx]); + } + + return; +} + + + +EFI_STATUS +GetHiiVariable ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + OUT UINT8 **VariableData, + OUT UINTN *VariableSize + ) +{ + UINTN Size; + EFI_STATUS Status; + UINT8 *Buffer; + + Size = 0; + Buffer = NULL; + + Status = gRT->GetVariable ( + (UINT16 *)VariableName, + VariableGuid, + NULL, + &Size, + Buffer + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + Buffer = (UINT8 *) AllocatePool (Size); + + ASSERT (Buffer != NULL); + + Status = gRT->GetVariable ( + VariableName, + VariableGuid, + NULL, + &Size, + Buffer + ); + + ASSERT (Status == EFI_SUCCESS); + *VariableData = Buffer; + *VariableSize = Size; + } + + return Status; +} + + +UINT32 +GetSkuEnabledTokenNumber ( + UINT32 LocalTokenNumber, + UINTN Size, + BOOLEAN IsPeiDb + ) +{ + SKU_HEAD *SkuHead; + SKU_ID *SkuIdTable; + INTN i; + UINT8 *Value; + SKU_ID *PhaseSkuIdTable; + UINT8 *PcdDb; + + ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0); + + PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb; + + SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); + Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); + + PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable : + mPcdDatabase->DxeDb.Init.SkuIdTable; + + SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset]; + + for (i = 0; i < SkuIdTable[0]; i++) { + if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) { + break; + } + } + ASSERT (i < SkuIdTable[0]); + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]); + return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD); + + case PCD_TYPE_HII: + Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]); + return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII); + + case PCD_TYPE_STRING: + Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]); + return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING); + + case PCD_TYPE_DATA: + Value += Size * i; + return (UINT32) (Value - PcdDb); + + default: + ASSERT (FALSE); + } + + ASSERT (FALSE); + + return 0; + +} + + + + +STATIC +VOID +InvokeCallbackOnSet ( + UINT32 ExTokenNumber, + CONST EFI_GUID *Guid, OPTIONAL + UINTN TokenNumber, + VOID *Data, + UINTN Size + ) +{ + CALLBACK_FN_ENTRY *FnTableEntry; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + ListHead = &mCallbackFnTable[TokenNumber]; + ListNode = GetFirstNode (ListHead); + + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node); + + FnTableEntry->CallbackFn(Guid, + (Guid == NULL) ? TokenNumber : ExTokenNumber, + Data, + Size); + + ListNode = GetNextNode (ListHead, ListNode); + } + + return; +} + + +EFI_STATUS +SetValueWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN UINTN Size + ) +{ + return SetWorker (TokenNumber, Data, &Size, FALSE); +} + + +EFI_STATUS +SetWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ) +{ + UINT32 *LocalTokenNumberTable; + BOOLEAN IsPeiDb; + UINT32 LocalTokenNumber; + EFI_GUID *GuidTable; + UINT16 *StringTable; + EFI_GUID *Guid; + UINT16 *Name; + UINTN VariableOffset; + VOID *InternalData; + VARIABLE_HEAD *VariableHead; + UINTN Offset; + UINT8 *PcdDb; + EFI_STATUS Status; + UINTN MaxSize; + UINTN TmpTokenNumber; + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + TmpTokenNumber = TokenNumber; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + + ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1); + + if (!PtrType) { + ASSERT (*Size == DxePcdGetSize (TokenNumber + 1)); + } + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE); + + LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : + mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) || + (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) { + InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size); + } + + TokenNumber = IsPeiDb ? TokenNumber + : TokenNumber - PEI_LOCAL_TOKEN_NUMBER; + + LocalTokenNumber = LocalTokenNumberTable[TokenNumber]; + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { + if (PtrType) { + GetPtrTypeSize (TmpTokenNumber, &MaxSize); + } else { + MaxSize = *Size; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb); + } + + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + + PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb); + + StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable : + mPcdDatabase->DxeDb.Init.StringTable; + + InternalData = PcdDb + Offset; + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + ASSERT (FALSE); + Status = EFI_INVALID_PARAMETER; + break; + + case PCD_TYPE_STRING: + if (SetPtrTypeSize (TmpTokenNumber, Size)) { + CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, *Size); + Status = EFI_SUCCESS; + } else { + Status = EFI_INVALID_PARAMETER; + } + break; + + case PCD_TYPE_HII: + if (PtrType) { + if (!SetPtrTypeSize (TmpTokenNumber, Size)) { + Status = EFI_INVALID_PARAMETER; + break; + } + } + + GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable : + mPcdDatabase->DxeDb.Init.GuidTable; + + VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset); + + Guid = &(GuidTable[VariableHead->GuidTableIndex]); + Name = &(StringTable[VariableHead->StringIndex]); + VariableOffset = VariableHead->Offset; + + Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset); + + if (EFI_NOT_FOUND == Status) { + CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size); + Status = EFI_SUCCESS; + } + break; + + case PCD_TYPE_DATA: + if (PtrType) { + if (SetPtrTypeSize (TmpTokenNumber, Size)) { + CopyMem (InternalData, Data, *Size); + Status = EFI_SUCCESS; + } else { + Status = EFI_INVALID_PARAMETER; + } + break; + } + + Status = EFI_SUCCESS; + switch (*Size) { + case sizeof(UINT8): + *((UINT8 *) InternalData) = *((UINT8 *) Data); + break; + + case sizeof(UINT16): + *((UINT16 *) InternalData) = *((UINT16 *) Data); + break; + + case sizeof(UINT32): + *((UINT32 *) InternalData) = *((UINT32 *) Data); + break; + + case sizeof(UINT64): + *((UINT64 *) InternalData) = *((UINT64 *) Data); + break; + + default: + ASSERT (FALSE); + Status = EFI_NOT_FOUND; + break; + } + break; + + default: + ASSERT (FALSE); + Status = EFI_NOT_FOUND; + break; + } + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; +} + + + + + +VOID * +ExGetWorker ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINTN GetSize + ) +{ + return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize); +} + + + + +EFI_STATUS +ExSetValueWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN SetSize + ) +{ + return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, FALSE); +} + + +EFI_STATUS +ExSetWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN OUT UINTN *SetSize, + IN BOOLEAN PtrType + ) +{ + UINTN TokenNumber; + + TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber); + + InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, *SetSize); + + return SetWorker (TokenNumber, Data, SetSize, PtrType); + +} + + + + +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; + UINT32 Attribute; + + Size = 0; + + Status = gRT->GetVariable ( + (UINT16 *)VariableName, + VariableGuid, + NULL, + &Size, + NULL + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + + Buffer = AllocatePool (Size); + + ASSERT (Buffer != NULL); + + Status = gRT->GetVariable ( + VariableName, + VariableGuid, + &Attribute, + &Size, + Buffer + ); + + ASSERT_EFI_ERROR (Status); + + CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize); + + Status = gRT->SetVariable ( + VariableName, + VariableGuid, + Attribute, + Size, + Buffer + ); + + FreePool (Buffer); + return Status; + + } + + // + // If we drop to here, we don't have a Variable entry in + // the variable service yet. So, we will save the data + // in the PCD Database's volatile area. + // + return Status; +} + + + + + +UINTN +GetExPcdTokenNumber ( + IN CONST EFI_GUID *Guid, + IN UINT32 ExTokenNumber + ) +{ + UINT32 i; + DYNAMICEX_MAPPING *ExMap; + EFI_GUID *GuidTable; + EFI_GUID *MatchGuid; + UINTN MatchGuidIdx; + + if (!PEI_DATABASE_EMPTY) { + ExMap = mPcdDatabase->PeiDb.Init.ExMapTable; + GuidTable = mPcdDatabase->PeiDb.Init.GuidTable; + + MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid); + + if (MatchGuid != NULL) { + + MatchGuidIdx = MatchGuid - GuidTable; + + for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) { + if ((ExTokenNumber == ExMap[i].ExTokenNumber) && + (MatchGuidIdx == ExMap[i].ExGuidIndex)) { + return ExMap[i].LocalTokenNumber; + + } + } + } + } + + ExMap = mPcdDatabase->DxeDb.Init.ExMapTable; + GuidTable = mPcdDatabase->DxeDb.Init.GuidTable; + + MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid); + // + // We need to ASSERT here. If GUID can't be found in GuidTable, this is a + // error in the BUILD system. + // + ASSERT (MatchGuid != NULL); + + MatchGuidIdx = MatchGuid - GuidTable; + + for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) { + if ((ExTokenNumber == ExMap[i].ExTokenNumber) && + (MatchGuidIdx == ExMap[i].ExGuidIndex)) { + return ExMap[i].LocalTokenNumber; + } + } + + ASSERT (FALSE); + + return 0; +} + + +STATIC +SKU_ID * +GetSkuIdArray ( + IN UINTN LocalTokenNumberTableIdx, + IN BOOLEAN IsPeiPcd + ) +{ + SKU_HEAD *SkuHead; + UINTN LocalTokenNumber; + UINT8 *Database; + + if (IsPeiPcd) { + LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx]; + Database = (UINT8 *) &mPcdDatabase->PeiDb; + } else { + LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER]; + Database = (UINT8 *) &mPcdDatabase->DxeDb; + } + + ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0); + + SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); + + return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset); + +} + + +STATIC +UINTN +GetSizeTableIndexA ( + IN UINTN LocalTokenNumberTableIdx, + IN UINT32 *LocalTokenNumberTable, + IN BOOLEAN IsPeiDb + ) +{ + UINTN i; + UINTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + + SizeTableIdx = 0; + + for (i=0; iPeiDb.Init.LocalTokenNumberTable; + } else { + LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + } + return GetSizeTableIndexA (LocalTokenNumberTableIdx, + LocalTokenNumberTable, + IsPeiDb); +} + + + +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + SIZE_INFO *SizeTable; + UINTN i; + BOOLEAN IsPeiDb; + UINT32 *LocalTokenNumberTable; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + + if (IsPeiDb) { + LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable; + SizeTable = mPcdDatabase->PeiDb.Init.SizeTable; + } else { + LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER; + LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + SizeTable = mPcdDatabase->DxeDb.Init.SizeTable; + } + + LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb); + + *MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if (LocalTokenNumber & PCD_TYPE_VPD) { + // + // We have only one entry for VPD enabled PCD entry: + // 1) MAX Size. + // We consider current size is equal to MAX size. + // + return *MaxSize; + } else { + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + return SizeTable[SizeTableIdx + 1]; + } else { + // + // We have these entry for SKU enabled PCD entry + // 1) MAX SIZE + // 2) Current Size for each SKU_ID (It is equal to MaxSku). + // + SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb); + for (i = 0; i < SkuIdTable[0]; i++) { + if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) { + return SizeTable[SizeTableIdx + 1 + i]; + } + } + return SizeTable[SizeTableIdx + 1]; + } + } +} + + + +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + SIZE_INFO *SizeTable; + UINTN i; + UINTN MaxSize; + BOOLEAN IsPeiDb; + UINT32 *LocalTokenNumberTable; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + if (IsPeiDb) { + LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable; + SizeTable = mPcdDatabase->PeiDb.Init.SizeTable; + } else { + LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER; + LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable; + SizeTable = mPcdDatabase->DxeDb.Init.SizeTable; + } + + LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb); + + MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if (LocalTokenNumber & PCD_TYPE_VPD) { + // + // We shouldn't come here as we don't support SET for VPD + // + ASSERT (FALSE); + return FALSE; + } else { + if ((*CurrentSize > MaxSize) || + (*CurrentSize == MAX_ADDRESS)) { + *CurrentSize = MaxSize; + return FALSE; + } + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; + } else { + // + // We have these entry for SKU enabled PCD entry + // 1) MAX SIZE + // 2) Current Size for each SKU_ID (It is equal to MaxSku). + // + SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb); + for (i = 0; i < SkuIdTable[0]; i++) { + if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) { + SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize; + return TRUE; + } + } + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; + } + } +} + diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.h b/MdeModulePkg/Universal/PCD/Dxe/Service.h new file mode 100644 index 0000000000..da38053e13 --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Dxe/Service.h @@ -0,0 +1,485 @@ +/** @file +Private functions used by PCD DXE driver. + +Copyright (c) 2006 - 2007, 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 + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +// +// Please make sure the PCD Serivce PEIM Version is consistent with +// the version of PCD Database generation tool +// +#define PCD_SERVICE_DXE_DRIVER_VERSION 2 + +// +// PCD_DXE_DATABASE_GENTOOL_VERSION is defined in Autogen.h +// and generated by PCD Database generation tool. +// +#if (PCD_SERVICE_DXE_DRIVER_VERSION != PCD_DXE_SERVICE_DRIVER_AUTOGEN_VERSION) + #error "Please make sure the version of PCD Service DXE Driver and PCD DXE Database Generation Tool matches" +#endif + +// +// Protocol Interface function declaration. +// +VOID +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 UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +; + + +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 OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +; + + +EFI_STATUS +EFIAPI +DxePcdSetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN BOOLEAN Value + ) +; + + + +EFI_STATUS +EFIAPI +DxeRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +; + + +EFI_STATUS +EFIAPI +DxeUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +; + + +EFI_STATUS +EFIAPI +DxePcdGetNextToken ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN OUT UINTN *TokenNumber + ) +; + + + +EFI_STATUS +EFIAPI +DxePcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ) +; + + +typedef struct { + LIST_ENTRY Node; + PCD_PROTOCOL_CALLBACK CallbackFn; +} CALLBACK_FN_ENTRY; + +#define CR_FNENTRY_FROM_LISTNODE(Record, Type, Field) _CR(Record, Type, Field) + +// +// Internal Functions +// + +EFI_STATUS +SetValueWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN UINTN Size + ) +; + +EFI_STATUS +SetWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ) +; + + +EFI_STATUS +ExSetValueWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN SetSize + ) +; + + + +EFI_STATUS +ExSetWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ) +; + + +VOID * +GetWorker ( + IN UINTN TokenNumber, + IN UINTN GetSize + ) +; + +VOID * +ExGetWorker ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINTN GetSize + ) +; + +UINT32 +GetSkuEnabledTokenNumber ( + UINT32 LocalTokenNumber, + UINTN Size, + BOOLEAN IsPeiDb + ) +; + +EFI_STATUS +GetHiiVariable ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + OUT UINT8 **VariableData, + OUT UINTN *VariableSize + ) +; + +EFI_STATUS +SetHiiVariable ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + IN CONST VOID *Data, + IN UINTN DataSize, + IN UINTN Offset + ) +; + +EFI_STATUS +DxeRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST EFI_GUID *Guid, OPTIONAL + IN PCD_PROTOCOL_CALLBACK CallBackFunction +); + +EFI_STATUS +DxeUnRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST EFI_GUID *Guid, OPTIONAL + IN PCD_PROTOCOL_CALLBACK CallBackFunction +); + +VOID +BuildPcdDxeDataBase ( + VOID +); + + +UINTN +GetExPcdTokenNumber ( + IN CONST EFI_GUID *Guid, + IN UINT32 ExTokenNumber + ) +; + + + +EFI_STATUS +ExGetNextTokeNumber ( + IN CONST EFI_GUID *Guid, + IN OUT UINTN *TokenNumber, + IN EFI_GUID *GuidTable, + IN UINTN SizeOfGuidTable, + IN DYNAMICEX_MAPPING *ExMapTable, + IN UINTN SizeOfExMapTable + ) +; + + +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize + ) +; + + + +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize + ) +; + +extern EFI_GUID gPcdDataBaseHobGuid; + +extern PCD_DATABASE * mPcdDatabase; + +extern DXE_PCD_DATABASE_INIT gDXEPcdDbInit; + +extern EFI_LOCK mPcdDatabaseLock; + +#endif diff --git a/MdeModulePkg/Universal/PCD/Pei/CommonHeader.h b/MdeModulePkg/Universal/PCD/Pei/CommonHeader.h new file mode 100644 index 0000000000..c488c38e9e --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Pei/CommonHeader.h @@ -0,0 +1,40 @@ +/**@file + Common header file shared by all source files. + + This file includes package header files, library classes and protocol, PPI & GUID definitions. + + Copyright (c) 2006 - 2007, 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. +**/ + +#ifndef __COMMON_HEADER_H_ +#define __COMMON_HEADER_H_ + + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.c b/MdeModulePkg/Universal/PCD/Pei/Pcd.c new file mode 100644 index 0000000000..b018e5a95d --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.c @@ -0,0 +1,801 @@ +/** @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 header file for this module. +// +#include "CommonHeader.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, + + PeiRegisterCallBackOnSet, + PcdUnRegisterCallBackOnSet, + PeiPcdGetNextToken, + PeiPcdGetNextTokenSpace +}; + + + +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; + + BuildPcdDatabase (); + + Status = PeiServicesInstallPpi (&mPpiPCD); + + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +PeiPcdSetSku ( + IN UINTN SkuId + ) +{ + + GetPcdDatabase()->Init.SystemSkuId = (SKU_ID) SkuId; + + return; +} + + + +UINT8 +EFIAPI +PeiPcdGet8 ( + IN UINTN TokenNumber + ) +{ + return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8))); +} + + + +UINT16 +EFIAPI +PeiPcdGet16 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16))); +} + + + +UINT32 +EFIAPI +PeiPcdGet32 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32))); +} + + + +UINT64 +EFIAPI +PeiPcdGet64 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64))); +} + + + +VOID * +EFIAPI +PeiPcdGetPtr ( + IN UINTN TokenNumber + ) +{ + return GetWorker (TokenNumber, 0); +} + + + +BOOLEAN +EFIAPI +PeiPcdGetBool ( + IN UINTN TokenNumber + ) +{ + return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN))); +} + + + +UINTN +EFIAPI +PeiPcdGetSize ( + IN UINTN TokenNumber + ) +{ + PEI_PCD_DATABASE *PeiPcdDb; + UINTN Size; + UINTN MaxSize; + + // + // If DebugAssertEnabled is TRUE, we still need to provide the GET size + // function as GetWorker and SetWoker need this function to do ASSERT. + // + if ((!FeaturePcdGet(PcdPeiPcdDatabaseGetSizeEnabled)) && + (!DebugAssertEnabled ())) { + return 0; + } + + PeiPcdDb = GetPcdDatabase (); + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + Size = (PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT; + + if (Size == 0) { + // + // For pointer type, we need to scan the SIZE_TABLE to get the current size. + // + return GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); + } else { + return Size; + } + +} + + + +UINT8 +EFIAPI +PeiPcdGet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8))); +} + + + +UINT16 +EFIAPI +PeiPcdGet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16))); +} + + + +UINT32 +EFIAPI +PeiPcdGet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32))); +} + + + +UINT64 +EFIAPI +PeiPcdGet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64))); +} + + + +VOID * +EFIAPI +PeiPcdGetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ExGetWorker (Guid, ExTokenNumber, 0); +} + + + +BOOLEAN +EFIAPI +PeiPcdGetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN))); +} + + + +UINTN +EFIAPI +PeiPcdGetSizeEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if ((!FeaturePcdGet (PcdPeiPcdDatabaseGetSizeEnabled)) || !FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) { + return 0; + } + + return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSet8 ( + IN UINTN TokenNumber, + IN UINT8 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSet16 ( + IN UINTN TokenNumber, + IN UINT16 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSet32 ( + IN UINTN TokenNumber, + IN UINT32 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSet64 ( + IN UINTN TokenNumber, + IN UINT64 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + +EFI_STATUS +EFIAPI +PeiPcdSetPtr ( + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +{ + return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSetBool ( + IN UINTN TokenNumber, + IN BOOLEAN Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT8 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT16 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT32 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT64 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINTN *SizeOfBuffer, + IN VOID *Value + ) +{ + return ExSetWorker (ExTokenNumber, Guid, Value, SizeOfBuffer, TRUE); +} + + + +EFI_STATUS +EFIAPI +PeiPcdSetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN BOOLEAN Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + + + + +EFI_STATUS +EFIAPI +PeiRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN ExTokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ) +{ + if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled)) { + return EFI_UNSUPPORTED; + } + + ASSERT (CallBackFunction != NULL); + + return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, TRUE); +} + + + +EFI_STATUS +EFIAPI +PcdUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN ExTokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ) +{ + if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled)) { + return EFI_UNSUPPORTED; + } + + ASSERT (CallBackFunction != NULL); + + return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, FALSE); +} + + + +EFI_STATUS +EFIAPI +PeiPcdGetNextToken ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN OUT UINTN *TokenNumber + ) +{ + UINTN GuidTableIdx; + PEI_PCD_DATABASE *PeiPcdDb; + EFI_GUID *MatchGuid; + DYNAMICEX_MAPPING *ExMapTable; + UINTN i; + BOOLEAN Found; + BOOLEAN PeiExMapTableEmpty; + + if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) { + return EFI_UNSUPPORTED; + } + + PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY; + + if (Guid == NULL) { + if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) { + return EFI_NOT_FOUND; + } + (*TokenNumber)++; + if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + } + return EFI_SUCCESS; + } else { + if (PeiExMapTableEmpty) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_SUCCESS; + } + + // + // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order + // 1) ExGuid + // 2) ExTokenNumber + // + PeiPcdDb = GetPcdDatabase (); + + MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid); + + if (MatchGuid == NULL) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } + + GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable; + + ExMapTable = PeiPcdDb->Init.ExMapTable; + + Found = FALSE; + // + // Locate the GUID in ExMapTable first. + // + for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) { + if (ExMapTable[i].ExGuidIndex == GuidTableIdx) { + Found = TRUE; + break; + } + } + + if (Found) { + if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + *TokenNumber = ExMapTable[i].ExTokenNumber; + return EFI_SUCCESS; + } + + for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++) { + if (ExMapTable[i].ExTokenNumber == *TokenNumber) { + i++; + if (i == PEI_EXMAPPING_TABLE_SIZE) { + // + // Exceed the length of ExMap Table + // + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_SUCCESS; + } + if (ExMapTable[i].ExGuidIndex == GuidTableIdx) { + *TokenNumber = ExMapTable[i].ExTokenNumber; + return EFI_SUCCESS; + } else { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_SUCCESS; + } + } + } + return EFI_NOT_FOUND; + } + } + + return EFI_NOT_FOUND; +} + + + +EFI_STATUS +EFIAPI +PeiPcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ) +{ + UINTN GuidTableIdx; + EFI_GUID *MatchGuid; + PEI_PCD_DATABASE *PeiPcdDb; + DYNAMICEX_MAPPING *ExMapTable; + UINTN i; + BOOLEAN Found; + BOOLEAN PeiExMapTableEmpty; + + if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) { + return EFI_UNSUPPORTED; + } + + ASSERT (Guid != NULL); + + PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY; + + if (PeiExMapTableEmpty) { + if (*Guid != NULL) { + return EFI_NOT_FOUND; + } else { + return EFI_SUCCESS; + } + } + + // + // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order + // 1) ExGuid + // 2) ExTokenNumber + // + PeiPcdDb = GetPcdDatabase (); + + ExMapTable = PeiPcdDb->Init.ExMapTable; + + if (*Guid == NULL) { + // + // return the first Token Space Guid. + // + *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[0].ExGuidIndex]; + return EFI_SUCCESS; + } + + MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), *Guid); + + if (MatchGuid == NULL) { + return EFI_NOT_FOUND; + } + + GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable; + + Found = FALSE; + for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) { + if (ExMapTable[i].ExGuidIndex == GuidTableIdx) { + Found = TRUE; + break; + } + } + + if (Found) { + i++; + for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++ ) { + if (ExMapTable[i].ExGuidIndex != GuidTableIdx ) { + *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[i].ExGuidIndex]; + return EFI_SUCCESS; + } + } + *Guid = NULL; + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; + +} + +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize, + IN PEI_PCD_DATABASE *Database + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + SIZE_INFO *SizeTable; + UINTN i; + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database); + + LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTable = Database->Init.SizeTable; + + *MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if (LocalTokenNumber & PCD_TYPE_VPD) { + // + // We have only one entry for VPD enabled PCD entry: + // 1) MAX Size. + // We consider current size is equal to MAX size. + // + return *MaxSize; + } else { + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + return SizeTable[SizeTableIdx + 1]; + } else { + // + // We have these entry for SKU enabled PCD entry + // 1) MAX SIZE + // 2) Current Size for each SKU_ID (It is equal to MaxSku). + // + SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database); + for (i = 0; i < SkuIdTable[0]; i++) { + if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) { + return SizeTable[SizeTableIdx + 1 + i]; + } + } + return SizeTable[SizeTableIdx + 1]; + } + } +} + + + +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize, + IN PEI_PCD_DATABASE *Database + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + SIZE_INFO *SizeTable; + UINTN i; + UINTN MaxSize; + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database); + + LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTable = Database->Init.SizeTable; + + MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if (LocalTokenNumber & PCD_TYPE_VPD) { + // + // We shouldn't come here as we don't support SET for VPD + // + ASSERT (FALSE); + return FALSE; + } else { + if ((*CurrentSize > MaxSize) || + (*CurrentSize == MAX_ADDRESS)) { + *CurrentSize = MaxSize; + return FALSE; + } + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; + } else { + // + // We have these entry for SKU enabled PCD entry + // 1) MAX SIZE + // 2) Current Size for each SKU_ID (It is equal to MaxSku). + // + SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database); + for (i = 0; i < SkuIdTable[0]; i++) { + if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) { + SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize; + return TRUE; + } + } + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; + } + } + +} diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.dxs b/MdeModulePkg/Universal/PCD/Pei/Pcd.dxs new file mode 100644 index 0000000000..3bad561b78 --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.dxs @@ -0,0 +1,25 @@ +/*++ + +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.dxs + +Abstract: + + Dependency expression source file. + +--*/ +#include + +DEPENDENCY_START + TRUE +DEPENDENCY_END diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf new file mode 100644 index 0000000000..506ab026cd --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf @@ -0,0 +1,140 @@ +#/** @file +# Component description file for Pcd Database PEIM module +# +# This PEIM driver implement and produce PCD PPI. +# Copyright (c) 2006 - 2007, 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PcdPeim + FILE_GUID = 9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + PCD_DRIVER = PEI_PCD_DRIVER + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = PcdPeimInit + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + Service.c + Service.h + Pcd.c + CommonHeader.h + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + BaseMemoryLib + PeiServicesTablePointerLib + PcdLib + PeiServicesLib + HobLib + BaseLib + PeimEntryPoint + DebugLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gPcdPeiCallbackFnTableHobGuid # ALWAYS_PRODUCED Hob: GUID_EXTENSION + gPcdDataBaseHobGuid # ALWAYS_PRODUCED Hob: GUID_EXTENSION + + +################################################################################ +# +# PPI C Name Section - list of PPI and PPI Notify C Names that this module +# uses or produces. +# +################################################################################ + +[Ppis] + gEfiPeiReadOnlyVariablePpiGuid # PPI ALWAYS_CONSUMED + gPcdPpiGuid # PPI ALWAYS_PRODUCED + + +################################################################################ +# +# Pcd FEATURE_FLAG - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFeatureFlag.common] + PcdPeiPcdDatabaseSetEnabled|gEfiEdkModulePkgTokenSpaceGuid + PcdPeiPcdDatabaseGetSizeEnabled|gEfiEdkModulePkgTokenSpaceGuid + PcdPeiPcdDatabaseExEnabled|gEfiEdkModulePkgTokenSpaceGuid + PcdPeiPcdDatabaseCallbackOnSetEnabled|gEfiEdkModulePkgTokenSpaceGuid + PcdPeiPcdDatabaseTraverseEnabled|gEfiEdkModulePkgTokenSpaceGuid + + +################################################################################ +# +# Pcd FIXED_AT_BUILD - list of PCDs that this module is coded for. +# +################################################################################ + +[PcdsFixedAtBuild.common] + PcdVpdBaseAddress|gEfiEdkModulePkgTokenSpaceGuid + PcdMaxPeiPcdCallBackNumberPerPcdEntry|gEfiEdkModulePkgTokenSpaceGuid + + +################################################################################ +# +# Dependency Expression Section - list of Dependency expressions that are required for +# this module. +# +################################################################################ + +[Depex] + TRUE + diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.msa b/MdeModulePkg/Universal/PCD/Pei/Pcd.msa new file mode 100644 index 0000000000..155a576443 --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.msa @@ -0,0 +1,129 @@ + + + + PcdPeim + PEIM + 9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50 + 1.0 + Component description file for Pcd Database PEIM module + This PEIM driver implement and produce PCD PPI. + Copyright (c) 2006 - 2007, 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + PcdPeim + + + + DebugLib + Recommended libary Instance is PeiDxeDebugLibReportStatusCode instance in MdePkg. + + + PeimEntryPoint + + + BaseLib + + + HobLib + + + PeiServicesLib + + + PcdLib + + + PeiServicesTablePointerLib + + + BaseMemoryLib + + + + Pcd.dxs + Pcd.c + Service.h + Service.c + + + + + + + + GUID_EXTENSION + + + GUID_EXTENSION + + + + + gPcdPpiGuid + + + gEfiPeiReadOnlyVariablePpiGuid + + + + PEI_PCD_DRIVER + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + PcdPeimInit + + + + + PcdMaxPeiPcdCallBackNumberPerPcdEntry + gEfiEdkModulePkgTokenSpaceGuid + The maximum number of callback function, which will be triggered when + a PCD entry is been set, can be registered for a single PCD entry in PEI phase. + + + PcdVpdBaseAddress + gEfiEdkModulePkgTokenSpaceGuid + The base address of the VPD (Vital Product Data) region. It is + normally a region reserved on flash. + + + PcdPeiPcdDatabaseTraverseEnabled + gEfiEdkModulePkgTokenSpaceGuid + This feature flag can be used to enable or disable the Pcd PEIM database + traverse capability. Disable it can reduce the size of final image generated. + + + PcdPeiPcdDatabaseCallbackOnSetEnabled + gEfiEdkModulePkgTokenSpaceGuid + FALSE + 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. + + + PcdPeiPcdDatabaseExEnabled + gEfiEdkModulePkgTokenSpaceGuid + FALSE + 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. + + + PcdPeiPcdDatabaseGetSizeEnabled + gEfiEdkModulePkgTokenSpaceGuid + FALSE + 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. + + + PcdPeiPcdDatabaseSetEnabled + gEfiEdkModulePkgTokenSpaceGuid + FALSE + 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. + + + \ 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 index 0000000000..cb980daa39 --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Pei/Service.c @@ -0,0 +1,733 @@ +/** @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 header file for this module. +// +#include "CommonHeader.h" + +#include "Service.h" + +/** + The function registers the CallBackOnSet fucntion + according to TokenNumber and EFI_GUID space. + + @param TokenNumber The token number. + @param Guid The GUID space. + @param CallBackFunction The Callback function to be registered. + @param Register To register or unregister the callback function. + + @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. + @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free + slot left in the CallbackFnTable. +--*/ +EFI_STATUS +PeiRegisterCallBackWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, OPTIONAL + IN PCD_PPI_CALLBACK CallBackFunction, + IN BOOLEAN Register +) +{ + EFI_HOB_GUID_TYPE *GuidHob; + PCD_PPI_CALLBACK *CallbackTable; + PCD_PPI_CALLBACK Compare; + PCD_PPI_CALLBACK Assign; + UINT32 LocalTokenNumber; + UINTN TokenNumber; + UINTN Idx; + + if (Guid == NULL) { + TokenNumber = ExTokenNumber; + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1); + } else { + TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber); + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + } + + + LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber]; + + // + // We don't support SET for HII and VPD type PCD entry in PEI phase. + // So we will assert if any register callback for such PCD entry. + // + ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0); + ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0); + + GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid); + ASSERT (GuidHob != NULL); + + CallbackTable = GET_GUID_HOB_DATA (GuidHob); + CallbackTable = CallbackTable + (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry)); + + Compare = Register? NULL: CallBackFunction; + Assign = Register? CallBackFunction: NULL; + + + for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) { + if (CallbackTable[Idx] == Compare) { + CallbackTable[Idx] = Assign; + return EFI_SUCCESS; + } + } + + return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND; + +} + + + + +/** + The function builds the PCD database. + + @param VOID + + @retval VOID +--*/ +VOID +BuildPcdDatabase ( + VOID + ) +{ + PEI_PCD_DATABASE *Database; + VOID *CallbackFnTable; + UINTN SizeOfCallbackFnTable; + + Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE)); + + ZeroMem (Database, sizeof (PEI_PCD_DATABASE)); + + // + // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE + // + + CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit)); + + SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); + + CallbackFnTable = BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid, SizeOfCallbackFnTable); + + ZeroMem (CallbackFnTable, SizeOfCallbackFnTable); + + 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 VariableGuid The Variable GUID. + @param VariableName The Variable Name. + @param VariableData The output data. + @param VariableSize The size of the variable. + + @retval EFI_SUCCESS Operation successful. + @retval EFI_NOT_FOUND Variablel not found. +--*/ +STATIC +EFI_STATUS +GetHiiVariable ( + IN CONST 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 = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, (VOID **) &VariablePpi); + ASSERT_EFI_ERROR (Status); + + Size = 0; + Status = VariablePpi->PeiGetVariable ( + GetPeiServicesTablePointer (), + VariableName, + (EFI_GUID *) VariableGuid, + NULL, + &Size, + NULL + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + + + Status = PeiServicesAllocatePool (Size, &Buffer); + ASSERT_EFI_ERROR (Status); + + Status = VariablePpi->PeiGetVariable ( + GetPeiServicesTablePointer (), + (UINT16 *) VariableName, + (EFI_GUID *) VariableGuid, + NULL, + &Size, + Buffer + ); + ASSERT_EFI_ERROR (Status); + + *VariableSize = Size; + *VariableData = Buffer; + + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } + +} + +STATIC +UINT32 +GetSkuEnabledTokenNumber ( + UINT32 LocalTokenNumber, + UINTN Size + ) +{ + PEI_PCD_DATABASE *PeiPcdDb; + SKU_HEAD *SkuHead; + SKU_ID *SkuIdTable; + INTN i; + UINT8 *Value; + + PeiPcdDb = GetPcdDatabase (); + + ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0); + + SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); + Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset)); + SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset)); + + for (i = 0; i < SkuIdTable[0]; i++) { + if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) { + break; + } + } + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD); + + case PCD_TYPE_HII: + Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII); + + case PCD_TYPE_STRING: + Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING); + + case PCD_TYPE_DATA: + Value += Size * i; + return (UINT32) (Value - (UINT8 *) PeiPcdDb); + + default: + ASSERT (FALSE); + } + + ASSERT (FALSE); + + return 0; + +} + + + +STATIC +VOID +InvokeCallbackOnSet ( + UINTN ExTokenNumber, + CONST EFI_GUID *Guid, OPTIONAL + UINTN TokenNumber, + VOID *Data, + UINTN Size + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + PCD_PPI_CALLBACK *CallbackTable; + UINTN Idx; + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + if (Guid == NULL) { + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + } + + GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid); + ASSERT (GuidHob != NULL); + + CallbackTable = GET_GUID_HOB_DATA (GuidHob); + + CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry)); + + for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) { + if (CallbackTable[Idx] != NULL) { + CallbackTable[Idx] (Guid, + (Guid == NULL)? TokenNumber: ExTokenNumber, + Data, + Size + ); + } + } + +} + + + +EFI_STATUS +SetValueWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN UINTN Size + ) +{ + return SetWorker (TokenNumber, Data, &Size, FALSE); +} + + + +EFI_STATUS +SetWorker ( + IN UINTN TokenNumber, + IN OUT VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ) +{ + UINT32 LocalTokenNumber; + PEI_PCD_DATABASE *PeiPcdDb; + UINT16 StringTableIdx; + UINTN Offset; + VOID *InternalData; + UINTN MaxSize; + + if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) { + return EFI_UNSUPPORTED; + } + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + PeiPcdDb = GetPcdDatabase (); + + LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber]; + + if (!PtrType) { + ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size); + } + + // + // We only invoke the callback function for Dynamic Type PCD Entry. + // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX + // type PCD entry in ExSetWorker. + // + if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) { + InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size); + } + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { + if (PtrType) { + MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); + } else { + MaxSize = *Size; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize); + } + + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset); + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + case PCD_TYPE_HII: + { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + case PCD_TYPE_STRING: + if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) { + StringTableIdx = *((UINT16 *)InternalData); + CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size); + return EFI_SUCCESS; + } else { + return EFI_INVALID_PARAMETER; + } + + case PCD_TYPE_DATA: + { + if (PtrType) { + if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) { + CopyMem (InternalData, Data, *Size); + return EFI_SUCCESS; + } else { + return EFI_INVALID_PARAMETER; + } + } + + switch (*Size) { + case sizeof(UINT8): + *((UINT8 *) InternalData) = *((UINT8 *) Data); + return EFI_SUCCESS; + + case sizeof(UINT16): + *((UINT16 *) InternalData) = *((UINT16 *) Data); + return EFI_SUCCESS; + + case sizeof(UINT32): + *((UINT32 *) InternalData) = *((UINT32 *) Data); + return EFI_SUCCESS; + + case sizeof(UINT64): + *((UINT64 *) InternalData) = *((UINT64 *) Data); + return EFI_SUCCESS; + + default: + ASSERT (FALSE); + return EFI_NOT_FOUND; + } + } + + } + + ASSERT (FALSE); + return EFI_NOT_FOUND; + +} + + + +EFI_STATUS +ExSetValueWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN Size + ) +{ + return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE); +} + + + +EFI_STATUS +ExSetWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ) +{ + UINTN TokenNumber; + + if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) { + return EFI_UNSUPPORTED; + } + + TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber); + + InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size); + + return SetWorker (TokenNumber, Data, Size, PtrType); + +} + + + + +VOID * +ExGetWorker ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINTN GetSize + ) +{ + if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) { + ASSERT (FALSE); + return 0; + } + + return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize); +} + + + + +VOID * +GetWorker ( + UINTN TokenNumber, + UINTN GetSize + ) +{ + UINT32 Offset; + EFI_GUID *Guid; + UINT16 *Name; + VARIABLE_HEAD *VariableHead; + EFI_STATUS Status; + UINTN DataSize; + VOID *Data; + UINT16 *StringTable; + UINT16 StringTableIdx; + PEI_PCD_DATABASE *PeiPcdDb; + UINT32 LocalTokenNumber; + UINTN MaxSize; + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1); + + ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0)); + + PeiPcdDb = GetPcdDatabase (); + + LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber]; + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { + if (GetSize == 0) { + MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); + } else { + MaxSize = GetSize; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize); + } + + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + StringTable = PeiPcdDb->Init.StringTable; + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + { + VPD_HEAD *VpdHead; + VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset); + return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset); + } + + case PCD_TYPE_HII: + { + VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset); + + Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]); + Name = &StringTable[VariableHead->StringIndex]; + + Status = GetHiiVariable (Guid, Name, &Data, &DataSize); + + if (Status == EFI_SUCCESS) { + return (VOID *) ((UINT8 *) Data + VariableHead->Offset); + } else { + // + // Return the default value specified by Platform Integrator + // + return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset); + } + } + + case PCD_TYPE_DATA: + return (VOID *) ((UINT8 *)PeiPcdDb + Offset); + + case PCD_TYPE_STRING: + StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset); + return (VOID *) (&StringTable[StringTableIdx]); + + default: + ASSERT (FALSE); + break; + + } + + ASSERT (FALSE); + + return NULL; + +} + + + +UINTN +GetExPcdTokenNumber ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + UINT32 i; + DYNAMICEX_MAPPING *ExMap; + EFI_GUID *GuidTable; + EFI_GUID *MatchGuid; + UINTN MatchGuidIdx; + PEI_PCD_DATABASE *PeiPcdDb; + + PeiPcdDb = GetPcdDatabase(); + + ExMap = PeiPcdDb->Init.ExMapTable; + GuidTable = PeiPcdDb->Init.GuidTable; + + MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid); + // + // We need to ASSERT here. If GUID can't be found in GuidTable, this is a + // error in the BUILD system. + // + ASSERT (MatchGuid != NULL); + + MatchGuidIdx = MatchGuid - GuidTable; + + for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) { + if ((ExTokenNumber == ExMap[i].ExTokenNumber) && + (MatchGuidIdx == ExMap[i].ExGuidIndex)) { + return ExMap[i].LocalTokenNumber; + } + } + + ASSERT (FALSE); + + return 0; +} + + + +PEI_PCD_DATABASE * +GetPcdDatabase ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); + ASSERT (GuidHob != NULL); + + return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); +} + + + +SKU_ID * +GetSkuIdArray ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ) +{ + SKU_HEAD *SkuHead; + UINTN LocalTokenNumber; + + LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0); + + SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK)); + + return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset); + +} + + + +UINTN +GetSizeTableIndex ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ) +{ + UINTN i; + UINTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + + SizeTableIdx = 0; + + for (i=0; iInit.LocalTokenNumberTable[i]; + + if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) { + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if (LocalTokenNumber & PCD_TYPE_VPD) { + // + // We have only one entry for VPD enabled PCD entry: + // 1) MAX Size. + // We consider current size is equal to MAX size. + // + SizeTableIdx++; + } else { + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTableIdx += 2; + } else { + // + // We have these entry for SKU enabled PCD entry + // 1) MAX SIZE + // 2) Current Size for each SKU_ID (It is equal to MaxSku). + // + SkuIdTable = GetSkuIdArray (i, Database); + SizeTableIdx += (UINTN)*SkuIdTable + 1; + } + } + } + + } + + return SizeTableIdx; +} diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.h b/MdeModulePkg/Universal/PCD/Pei/Service.h new file mode 100644 index 0000000000..9c3c70a0d0 --- /dev/null +++ b/MdeModulePkg/Universal/PCD/Pei/Service.h @@ -0,0 +1,462 @@ +/** @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 + +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +// +// Please make sure the PCD Serivce PEIM Version is consistent with +// the version of PCD Database generation tool +// +#define PCD_SERVICE_PEIM_VERSION 2 + +// +// PCD_PEI_DATABASE_GENTOOL_VERSION is defined in Autogen.h +// and generated by PCD Database generation tool. +// +#if (PCD_SERVICE_PEIM_VERSION != PCD_PEI_SERVICE_DRIVER_AUTOGEN_VERSION ) + #error "Please make sure the version of PCD Service PEIM and PCD PEI Database Generation Tool matches" +#endif + +// +// PPI Interface Implementation Declaration. +// +VOID +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 OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +; + + +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 OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +; + + +EFI_STATUS +EFIAPI +PeiPcdSetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN BOOLEAN Value + ) +; + + + +EFI_STATUS +EFIAPI +PeiRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ) +; + + +EFI_STATUS +EFIAPI +PcdUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ) +; + + +EFI_STATUS +EFIAPI +PeiPcdGetNextToken ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN OUT UINTN *TokenNumber + ) +; + + +EFI_STATUS +EFIAPI +PeiPcdGetNextTokenSpace ( + IN CONST EFI_GUID **Guid + ) +; + + +/* Internal Function definitions */ + +PEI_PCD_DATABASE * +GetPcdDatabase ( + VOID + ) +; + + +EFI_STATUS +SetValueWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN UINTN Size + ) +; + + +EFI_STATUS +SetWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ) +; + + +EFI_STATUS +ExSetValueWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN Size + ) +; + + + +EFI_STATUS +ExSetWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ) +; + + + +VOID * +GetWorker ( + IN UINTN TokenNumber, + IN UINTN GetSize + ) +; + + + +VOID * +ExGetWorker ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINTN GetSize + ) +; + +typedef struct { + UINTN TokenNumber; + UINTN Size; + UINT32 LocalTokenNumberAlias; +} EX_PCD_ENTRY_ATTRIBUTE; + + +UINTN +GetExPcdTokenNumber ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +; + + + + +EFI_STATUS +PeiRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST GUID *Guid, OPTIONAL + IN PCD_PPI_CALLBACK CallBackFunction, + IN BOOLEAN Register +); + + + + +VOID +BuildPcdDatabase ( + VOID + ) +; + +SKU_ID * +GetSkuIdArray ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ) +; + +UINTN +GetSizeTableIndex ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ) +; + +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize, + IN PEI_PCD_DATABASE *Database + ) +; + + + +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize, + IN PEI_PCD_DATABASE *Database + ) +; + + +extern EFI_GUID gPcdDataBaseHobGuid; + +extern EFI_GUID gPcdPeiCallbackFnTableHobGuid; + +extern PEI_PCD_DATABASE_INIT gPEIPcdDbInit; + +#endif