From c23f114d3cfbb29b8734b87213d1ec0de404197b Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 27 Apr 2017 11:05:07 +0800 Subject: MdeModulePkg: Move to new location Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- Core/MdeModulePkg/Universal/PCD/Pei/Pcd.c | 1433 ++++++++++++++++++++ Core/MdeModulePkg/Universal/PCD/Pei/Pcd.inf | 352 +++++ Core/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni | 296 ++++ .../Universal/PCD/Pei/PcdPeimExtra.uni | 19 + Core/MdeModulePkg/Universal/PCD/Pei/Service.c | 1209 +++++++++++++++++ Core/MdeModulePkg/Universal/PCD/Pei/Service.h | 1117 +++++++++++++++ 6 files changed, 4426 insertions(+) create mode 100644 Core/MdeModulePkg/Universal/PCD/Pei/Pcd.c create mode 100644 Core/MdeModulePkg/Universal/PCD/Pei/Pcd.inf create mode 100644 Core/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni create mode 100644 Core/MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni create mode 100644 Core/MdeModulePkg/Universal/PCD/Pei/Service.c create mode 100644 Core/MdeModulePkg/Universal/PCD/Pei/Service.h (limited to 'Core/MdeModulePkg/Universal/PCD/Pei') diff --git a/Core/MdeModulePkg/Universal/PCD/Pei/Pcd.c b/Core/MdeModulePkg/Universal/PCD/Pei/Pcd.c new file mode 100644 index 0000000000..a3f7337cec --- /dev/null +++ b/Core/MdeModulePkg/Universal/PCD/Pei/Pcd.c @@ -0,0 +1,1433 @@ +/** @file + All Pcd Ppi services are implemented here. + +Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+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. + +**/ + +#include "Service.h" + +/// +/// Instance of PCD_PPI protocol is EDKII native implementation. +/// This protocol instance support dynamic and dynamicEx type PCDs. +/// +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 +}; + +/// +/// Instance of EFI_PEI_PCD_PPI which is defined in PI 1.2 Vol 3. +/// This PPI instance only support dyanmicEx type PCD. +/// +EFI_PEI_PCD_PPI mEfiPcdPpiInstance = { + PeiPcdSetSku, + + PeiPcdGet8Ex, + PeiPcdGet16Ex, + PeiPcdGet32Ex, + PeiPcdGet64Ex, + PeiPcdGetPtrEx, + PeiPcdGetBoolEx, + PeiPcdGetSizeEx, + PeiPcdSet8Ex, + PeiPcdSet16Ex, + PeiPcdSet32Ex, + PeiPcdSet64Ex, + PeiPcdSetPtrEx, + PeiPcdSetBoolEx, + (EFI_PEI_PCD_PPI_CALLBACK_ON_SET) PeiRegisterCallBackOnSet, + (EFI_PEI_PCD_PPI_CANCEL_CALLBACK) PcdUnRegisterCallBackOnSet, + PeiPcdGetNextToken, + PeiPcdGetNextTokenSpace +}; + +/// +/// Instance of GET_PCD_INFO_PPI protocol is EDKII native implementation. +/// This protocol instance support dynamic and dynamicEx type PCDs. +/// +GET_PCD_INFO_PPI mGetPcdInfoInstance = { + PeiGetPcdInfoGetInfo, + PeiGetPcdInfoGetInfoEx, + PeiGetPcdInfoGetSku +}; + +/// +/// Instance of EFI_GET_PCD_INFO_PPI which is defined in PI 1.2.1 Vol 3. +/// This PPI instance only support dyanmicEx type PCD. +/// +EFI_GET_PCD_INFO_PPI mEfiGetPcdInfoInstance = { + PeiGetPcdInfoGetInfoEx, + PeiGetPcdInfoGetSku +}; + +EFI_PEI_PPI_DESCRIPTOR mPpiList[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gPcdPpiGuid, + &mPcdPpiInstance + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiPcdPpiGuid, + &mEfiPcdPpiInstance + } +}; + +EFI_PEI_PPI_DESCRIPTOR mPpiList2[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gGetPcdInfoPpiGuid, + &mGetPcdInfoInstance + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiGetPcdInfoPpiGuid, + &mEfiGetPcdInfoInstance + } +}; + +/** + Main entry for PCD PEIM driver. + + This routine initialize the PCD database for PEI phase and install PCD_PPI/EFI_PEI_PCD_PPI. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @return Status of install PCD_PPI + +**/ +EFI_STATUS +EFIAPI +PcdPeimInit ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + BuildPcdDatabase (FileHandle); + + // + // Install PCD_PPI and EFI_PEI_PCD_PPI. + // + Status = PeiServicesInstallPpi (&mPpiList[0]); + ASSERT_EFI_ERROR (Status); + + // + // Install GET_PCD_INFO_PPI and EFI_GET_PCD_INFO_PPI. + // + Status = PeiServicesInstallPpi (&mPpiList2[0]); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Retrieve additional information associated with a PCD token in the default token space. + + This includes information such as the type of value the TokenNumber is associated with as well as possible + human readable name that is associated with the token. + + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the requested TokenNumber. + The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +EFI_STATUS +EFIAPI +PeiGetPcdInfoGetInfo ( + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + return PeiGetPcdInfo (NULL, TokenNumber, PcdInfo); +} + +/** + Retrieve additional information associated with a PCD token. + + This includes information such as the type of value the TokenNumber is associated with as well as possible + human readable name that is associated with the token. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the requested TokenNumber. + The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +EFI_STATUS +EFIAPI +PeiGetPcdInfoGetInfoEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + return PeiGetPcdInfo (Guid, TokenNumber, PcdInfo); +} + +/** + Retrieve the currently set SKU Id. + + @return The currently set SKU Id. If the platform has not set at a SKU Id, then the + default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU + Id is returned. +**/ +UINTN +EFIAPI +PeiGetPcdInfoGetSku ( + VOID + ) +{ + return (UINTN) GetPcdDatabase()->SystemSkuId; +} + +/** + Sets the SKU value for subsequent calls to set or get PCD token values. + + SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values. + SetSku() is normally called only once by the system. + + For each item (token), the database can hold a single value that applies to all SKUs, + or multiple values, where each value is associated with a specific SKU Id. Items with multiple, + SKU-specific values are called SKU enabled. + + The SKU Id of zero is reserved as a default. + For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the + single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the + last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token, + the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been + set for that Id, the results are unpredictable. + + @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and + set values associated with a PCD token. + +**/ +VOID +EFIAPI +PeiPcdSetSku ( + IN UINTN SkuId + ) +{ + PEI_PCD_DATABASE *PeiPcdDb; + SKU_ID *SkuIdTable; + UINTN Index; + + PeiPcdDb = GetPcdDatabase(); + + if (SkuId == PeiPcdDb->SystemSkuId) { + // + // The input SKU Id is equal to current SKU Id, return directly. + // + return; + } + + if (PeiPcdDb->SystemSkuId != (SKU_ID) 0) { + DEBUG ((DEBUG_ERROR, "PcdPei - The SKU Id could be changed only once.")); + DEBUG (( + DEBUG_ERROR, + "PcdPei - The SKU Id was set to 0x%lx already, it could not be set to 0x%lx any more.", + PeiPcdDb->SystemSkuId, + (SKU_ID) SkuId + )); + ASSERT (FALSE); + return; + } + + SkuIdTable = (SKU_ID *) ((UINT8 *) PeiPcdDb + PeiPcdDb->SkuIdTableOffset); + for (Index = 0; Index < SkuIdTable[0]; Index++) { + if (SkuId == SkuIdTable[Index + 1]) { + DEBUG ((EFI_D_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_ID) SkuId)); + PeiPcdDb->SystemSkuId = (SKU_ID) SkuId; + return; + } + } + + // + // Invalid input SkuId, the default SKU Id will be still used for the system. + // + DEBUG ((EFI_D_INFO, "PcdPei - Invalid input SkuId, the default SKU Id will be still used.\n")); + return; +} + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the current byte-sized value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT8 value. + +**/ +UINT8 +EFIAPI +PeiPcdGet8 ( + IN UINTN TokenNumber + ) +{ + return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8))); +} + +/** + Retrieves an 16-bit value for a given PCD token. + + Retrieves the current 16-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT16 value. + +**/ +UINT16 +EFIAPI +PeiPcdGet16 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16))); +} + +/** + Retrieves an 32-bit value for a given PCD token. + + Retrieves the current 32-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT32 value. + +**/ +UINT32 +EFIAPI +PeiPcdGet32 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32))); +} + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the current 64-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT64 value. + +**/ +UINT64 +EFIAPI +PeiPcdGet64 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64))); +} + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The pointer to the buffer to be retrieved. + +**/ +VOID * +EFIAPI +PeiPcdGetPtr ( + IN UINTN TokenNumber + ) +{ + return GetWorker (TokenNumber, 0); +} + +/** + Retrieves a Boolean value for a given PCD token. + + Retrieves the current boolean value for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The Boolean value. + +**/ +BOOLEAN +EFIAPI +PeiPcdGetBool ( + IN UINTN TokenNumber + ) +{ + return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN))); +} + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +UINTN +EFIAPI +PeiPcdGetSize ( + IN UINTN TokenNumber + ) +{ + PEI_PCD_DATABASE *PeiPcdDb; + UINTN Size; + UINTN MaxSize; + UINT32 LocalTokenCount; + + PeiPcdDb = GetPcdDatabase (); + LocalTokenCount = PeiPcdDb->LocalTokenCount; + // + // 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 < (LocalTokenCount + 1)); + + Size = (*((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + 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; + } + +} + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the 8-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 8-bit value for the PCD token. + +**/ +UINT8 +EFIAPI +PeiPcdGet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8))); +} + +/** + Retrieves an 16-bit value for a given PCD token. + + Retrieves the 16-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 16-bit value for the PCD token. + +**/ +UINT16 +EFIAPI +PeiPcdGet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16))); +} + +/** + Retrieves an 32-bit value for a given PCD token. + + Retrieves the 32-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 32-bit value for the PCD token. + +**/ +UINT32 +EFIAPI +PeiPcdGet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32))); +} + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the 64-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 64-bit value for the PCD token. + +**/ +UINT64 +EFIAPI +PeiPcdGet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64))); +} + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The pointer to the buffer to be retrieved. + +**/ +VOID * +EFIAPI +PeiPcdGetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return ExGetWorker (Guid, ExTokenNumber, 0); +} + +/** + Retrieves an Boolean value for a given PCD token. + + Retrieves the Boolean value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size Boolean value for the PCD token. + +**/ +BOOLEAN +EFIAPI +PeiPcdGetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN))); +} + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +UINTN +EFIAPI +PeiPcdGetSizeEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber)); +} + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet8 ( + IN UINTN TokenNumber, + IN UINT8 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet16 ( + IN UINTN TokenNumber, + IN UINT16 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet32 ( + IN UINTN TokenNumber, + IN UINT32 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet64 ( + IN UINTN TokenNumber, + IN UINT64 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. + On input, if the SizeOfValue is greater than the maximum size supported + for this TokenNumber then the output value of SizeOfValue will reflect + the maximum size supported for this TokenNumber. + @param[in] Buffer The buffer to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetPtr ( + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +{ + return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE); +} + +/** + Sets an Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetBool ( + IN UINTN TokenNumber, + IN BOOLEAN Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT8 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT16 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT32 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT64 Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. + On input, if the SizeOfValue is greater than the maximum size supported + for this TokenNumber then the output value of SizeOfValue will reflect + the maximum size supported for this TokenNumber. + @param[in] Value The buffer to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Value + ) +{ + return ExSetWorker (ExTokenNumber, Guid, Value, SizeOfBuffer, TRUE); +} + +/** + Sets an Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param [in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param [in] ExTokenNumber The PCD token number. + @param [in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN BOOLEAN Value + ) +{ + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Specifies a function to be called anytime the value of a designated token is changed. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. + +**/ +EFI_STATUS +EFIAPI +PeiRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN ExTokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ) +{ + if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + if (CallBackFunction == NULL) { + return EFI_INVALID_PARAMETER; + } + + return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, TRUE); +} + +/** + Cancels a previously set callback function for a particular PCD token number. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. + +**/ +EFI_STATUS +EFIAPI +PcdUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN ExTokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ) +{ + if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + if (CallBackFunction == NULL) { + return EFI_INVALID_PARAMETER; + } + + return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, FALSE); +} + +/** + Retrieves the next valid token number in a given namespace. + + This is useful since the PCD infrastructure contains a sparse list of token numbers, + and one cannot a priori know what token numbers are valid in the database. + + If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned. + If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned. + If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned. + If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned. + The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid. + If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned. + If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned. + If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned. + + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + This is an optional parameter that may be NULL. If this parameter is NULL, then a request + is being made to retrieve tokens from the default token space. + @param[in, out] TokenNumber A pointer to the PCD token number to use to find the subsequent token number. + + @retval EFI_SUCCESS The PCD service has retrieved the next valid token number. + @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdGetNextToken ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN OUT UINTN *TokenNumber + ) +{ + UINTN GuidTableIdx; + PEI_PCD_DATABASE *PeiPcdDb; + EFI_GUID *MatchGuid; + EFI_GUID *GuidTable; + DYNAMICEX_MAPPING *ExMapTable; + UINTN Index; + BOOLEAN Found; + BOOLEAN PeiExMapTableEmpty; + UINTN PeiNexTokenNumber; + + if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + PeiPcdDb = GetPcdDatabase (); + PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount; + GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset); + + if (PeiPcdDb->ExTokenCount == 0) { + PeiExMapTableEmpty = TRUE; + } else { + PeiExMapTableEmpty = FALSE; + } + if (Guid == NULL) { + if (*TokenNumber > PeiNexTokenNumber) { + return EFI_NOT_FOUND; + } + (*TokenNumber)++; + if (*TokenNumber > PeiNexTokenNumber) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } + return EFI_SUCCESS; + } else { + if (PeiExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(EFI_GUID), Guid); + + if (MatchGuid == NULL) { + return EFI_NOT_FOUND; + } + + GuidTableIdx = MatchGuid - GuidTable; + + ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset); + + Found = FALSE; + // + // Locate the GUID in ExMapTable first. + // + for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) { + if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) { + Found = TRUE; + break; + } + } + + if (Found) { + // + // If given token number is PCD_INVALID_TOKEN_NUMBER, then return the first + // token number in found token space. + // + if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + *TokenNumber = ExMapTable[Index].ExTokenNumber; + return EFI_SUCCESS; + } + + for ( ; Index < PeiPcdDb->ExTokenCount; Index++) { + if ((ExMapTable[Index].ExTokenNumber == *TokenNumber) && (ExMapTable[Index].ExGuidIndex == GuidTableIdx)) { + break; + } + } + + while (Index < PeiPcdDb->ExTokenCount) { + Index++; + if (Index == PeiPcdDb->ExTokenCount) { + // + // Exceed the length of ExMap Table + // + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) { + // + // Found the next match + // + *TokenNumber = ExMapTable[Index].ExTokenNumber; + return EFI_SUCCESS; + } + } + } + } + + return EFI_NOT_FOUND; +} + +/** + Retrieves the next valid PCD token namespace for a given namespace. + + Gets the next valid token namespace for a given namespace. This is useful to traverse the valid + token namespaces on a platform. + + @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token + namespace from which the search will start. On output, it designates the next valid + token namespace on the platform. If *Guid is NULL, then the GUID of the first token + space of the current platform is returned. If the search cannot locate the next valid + token namespace, an error is returned and the value of *Guid is undefined. + + @retval EFI_SUCCESS The PCD service retrieved the value requested. + @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace. + +**/ +EFI_STATUS +EFIAPI +PeiPcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ) +{ + UINTN GuidTableIdx; + EFI_GUID *MatchGuid; + PEI_PCD_DATABASE *PeiPcdDb; + DYNAMICEX_MAPPING *ExMapTable; + UINTN Index; + UINTN Index2; + BOOLEAN Found; + BOOLEAN PeiExMapTableEmpty; + EFI_GUID *GuidTable; + + if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + ASSERT (Guid != NULL); + + PeiPcdDb = GetPcdDatabase (); + + if (PeiPcdDb->ExTokenCount == 0) { + PeiExMapTableEmpty = TRUE; + } else { + PeiExMapTableEmpty = FALSE; + } + + if (PeiExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset); + GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset); + + if (*Guid == NULL) { + // + // return the first Token Space Guid. + // + *Guid = GuidTable + ExMapTable[0].ExGuidIndex; + return EFI_SUCCESS; + } + + MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(GuidTable[0]), *Guid); + + if (MatchGuid == NULL) { + return EFI_NOT_FOUND; + } + + GuidTableIdx = MatchGuid - GuidTable; + + Found = FALSE; + for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) { + if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) { + Found = TRUE; + break; + } + } + + if (Found) { + Index++; + for ( ; Index < PeiPcdDb->ExTokenCount; Index++ ) { + if (ExMapTable[Index].ExGuidIndex != GuidTableIdx) { + Found = FALSE; + for (Index2 = 0 ; Index2 < Index; Index2++) { + if (ExMapTable[Index2].ExGuidIndex == ExMapTable[Index].ExGuidIndex) { + // + // This token namespace should have been found and output at preceding getting. + // + Found = TRUE; + break; + } + } + if (!Found) { + *Guid = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + ExMapTable[Index].ExGuidIndex; + return EFI_SUCCESS; + } + } + } + *Guid = NULL; + } + + return EFI_NOT_FOUND; + +} + +/** + Get PCD value's size for POINTER type PCD. + + The POINTER type PCD's value will be stored into a buffer in specified size. + The max size of this PCD's value is described in PCD's definition in DEC file. + + @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table + @param MaxSize Maximum size of PCD's value + @param Database Pcd database in PEI phase. + + @return PCD value's size for POINTER type PCD. + +**/ +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize, + IN PEI_PCD_DATABASE *Database + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + SIZE_INFO *SizeTable; + UINTN Index; + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database); + + LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx); + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset); + + *MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) { + // + // We have only two entry for VPD enabled PCD entry: + // 1) MAX Size. + // 2) Current 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 (Index = 0; Index < SkuIdTable[0]; Index++) { + if (SkuIdTable[1 + Index] == Database->SystemSkuId) { + return SizeTable[SizeTableIdx + 1 + Index]; + } + } + return SizeTable[SizeTableIdx + 1]; + } + } +} + +/** + Set PCD value's size for POINTER type PCD. + + The POINTER type PCD's value will be stored into a buffer in specified size. + The max size of this PCD's value is described in PCD's definition in DEC file. + + @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table + @param CurrentSize Maximum size of PCD's value + @param Database Pcd database in PEI phase. + + @retval TRUE Success to set PCD's value size, which is not exceed maximum size + @retval FALSE Fail to set PCD's value size, which maybe exceed maximum size + +**/ +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 Index; + UINTN MaxSize; + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database); + + LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx); + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset); + + MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) { + // + // 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 (Index = 0; Index < SkuIdTable[0]; Index++) { + if (SkuIdTable[1 + Index] == Database->SystemSkuId) { + SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize; + return TRUE; + } + } + SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize; + return TRUE; + } + } + +} diff --git a/Core/MdeModulePkg/Universal/PCD/Pei/Pcd.inf b/Core/MdeModulePkg/Universal/PCD/Pei/Pcd.inf new file mode 100644 index 0000000000..1d9c9242d9 --- /dev/null +++ b/Core/MdeModulePkg/Universal/PCD/Pei/Pcd.inf @@ -0,0 +1,352 @@ +## @file +# PCD PEIM produces PCD database to manage all dynamic PCD in PEI phase and install Pcd Ppi service. +# +# This version PCD PEIM depends on the external PCD database binary file, not built in PCD data base. +# There are two PCD PPIs as follows: +# 1) PCD_PPI +# It is EDKII implementation which support Dynamic/DynamicEx Pcds. +# 2) EFI_PEI_PCD_PPI +# It is defined by PI specification 1.2, Vol 3 which only support dynamicEx +# type Pcd. +# For dynamicEx type PCD, it is compatible between PCD_PPI and EFI_PEI_PCD_PPI. +# PCD PEIM driver will produce above two PPIs at same time. +# +# PCD database is generated as the separate binary image at build time. The binary image +# will be intergrated into Firmware volume together with PCD driver. +# +# //////////////////////////////////////////////////////////////////////////////// +# // // +# // Introduction of PCD database // +# // // +# //////////////////////////////////////////////////////////////////////////////// +# +# 1, Introduction +# PCD database hold all dynamic type PCD information. The structure of PEI PCD +# database is generated by build tools according to dynamic PCD usage for +# specified platform. +# +# 2, Dynamic Type PCD +# Dynamic type PCD is used for the configuration/setting which value is determined +# dynamic. In contrast, the value of static type PCD (FeatureFlag, FixedPcd, +# PatchablePcd) is fixed in final generated FD image in build time. +# +# 2.1 The "dynamic" determination means one of below cases: +# a) The PCD setting value is produced by someone driver and consumed by +# other driver in execution time. +# b) The PCD setting value is set/get by user from FrontPage. +# c) The PCD setting value is produced by platform OEM vendor in specified area. +# +# 2.2 According to module distribution way, dynamic PCD could be classfied as: +# a) Dynamic: +# If module is released in source code and will be built with platform +# DSC, the dynamic PCD used by this module can be accessed as: +# PcdGetxx(PcdSampleDynamicPcd); +# In building platform, build tools will translate PcdSampleDynamicPcd to +# pair of {Token Space Guid: Token Number} for this PCD. +# b) DynamicEx: +# If module is release as binary and will not pariticpate platform building, +# the dynamic PCD used by this module need be accessed as: +# PcdGetxxEx(gEfiMyTokenspaceGuid, PcdSampleDynamicPcd) +# Developer need explicity gives {Token Space Guid:Token Number} as parameter +# in writting source code. +# +# 2.3 According to PCD value's storage method, dynamic PCD could be classfied as: +# a) Default Storage: +# - The PCD value is stored in PCD database maintained by PCD driver in boot +# time memory. +# - This type is used for communication between PEIM/DXE driver, DXE/DXE +# driver. But all set/get value will be losted after boot-time memory +# is turn off. +# - [PcdsDynamicDefault] is used as section name for this type PCD in +# platform DSC file. [PcdsDynamicExDefault] is used for dynamicEx type PCD. +# +# b) Variable Storage: +# - The PCD value is stored in variable area. +# - As default storage type, this type PCD could be used for PEI/DXE driver +# communication. But beside it, this type PCD could also be used to store +# the value associate with a HII setting via variable interface. +# - In PEI phase, the PCD value could only be got but can not be set due +# to variable area is readonly. +# - [PcdsDynamicHii] is used as section name for this type PCD in platform +# DSC file. [PcdsDynamicExHii] is for dynamicEx type PCD. +# +# c) OEM specificed storage area: +# - The PCD value is stored in OEM specified area which base address is +# specified by a FixedAtBuild PCD setting - PcdVpdBaseAddress. +# - The area is read only for PEI and DXE phase. +# - [PcdsDynamicVpd] is used as section name for this type PCD in platform +# DSC file. [PcdsDynamicExVpd] is for dynamicex type PCD. +# +# 2.4 When and how to use dynamic PCD +# Module developer do not care the used PCD is dynamic or static when writting +# source code/INF. Dynamic PCD and dynamic type is pointed by platform integrator +# in platform DSC file. Please ref section 2.3 to get matching between dynamic +# PCD type and section name in DSC file. +# +# 3, PCD database: +# Although dynamic PCD could be in different storage type as above description, +# but the basic information and default value for all dynamic PCD is hold +# by PCD database maintained by PEI/DXE driver. +# +# As the whole EFI BIOS boot path is divided into PEI/DXE phase, the PCD database +# also is divided into Pei/Dxe database maintaied by PcdPeim/PcdDxe driver separatly. +# To make PcdPeim's driver image smaller, PEI PCD database only hold all dynamic +# PCD information used in PEI phase or use in both PEI/DXE phase. And DXE PCD +# database contains all PCDs used in PEI/DXE phase in memory. +# +# Build tool will generate PCD database into the separate binary file for +# PEI/DXE PCD driver according to dynamic PCD section in platform DSC file. +# +# 3.1 PcdPeim and PcdDxe +# PEI PCD database is maintained by PcdPeim driver run from flash. PcdPeim driver +# build guid hob in temporary memory and copy the binary data base from flash +# to temporary memory for PEI PCD database. +# DXE PCD database is maintained by PcdDxe driver.At entry point of PcdDxe driver, +# a new PCD database is allocated in boot-time memory which including all +# PEI PCD and DXE PCD entry. +# +# Pcd driver should run as early as possible before any other driver access +# dynamic PCD's value. PEI/DXE "Apriori File" mechanism make it possible by +# making PcdPeim/PcdDxe as first dispatching driver in PEI/DXE phase. +# +# 3.2 Token space Guid/Token number, Platform token, Local token number +# Dynamic PCD +# +-----------+ +---------+ +# |TokenSpace | |Platform | +# | Guid | build tool | Token | +# | + +-------------->| Number | +# | Token | +---------+`._ +# | Number | `. +# +-----------+ `. +------+ +# `-|Local | +# |Token | +# DynamicEx PCD ,-|Number| +# +-----------+ ,-' +------+ +# |TokenSpace | ,-' +# | Guid | _,-' +# | + +.' +# | Token | +# | Number | +# +-----------+ +# +# +# 3.2.1 Pair of Token space guid + Token number +# Any type PCD is identified by pair of "TokenSpaceGuid + TokeNumber". But it +# is not easy maintained by PCD driver, and hashed token number will make +# searching slowly. +# +# 3.2.2 Platform Token Number +# "Platform token number" concept is introduced for mapping to a pair of +# "TokenSpaceGuid + TokenNumber". The platform token number is generated by +# build tool in autogen.h and all of them are continual in a platform scope +# started from 1.(0 meaning invalid internal token number) +# With auto-generated "platform token number", PcdGet(PcdSampleDynamicPcd) +# in source code is translated to LibPcdGet(_PCD_TOKEN_PcdSampleDynamicPcd) +# in autogen.h. +# Notes: The mapping between pair of "tokenspace guid + token number" and +# "internal token number" need build tool establish, so "platform token number" +# mechanism is not suitable for binary module which use DynamicEx type PCD. +# To access a dynamicEx type PCD, pair of "token space guid/token number" all need +# to be specificed for PcdSet/PcdGet accessing macro. +# +# Platform Token Number is started from 1, and inceased continuous. From whole +# platform scope, there are two zones: PEI Zone and DXE Zone +# | Platform Token Number +# ----------|---------------------------------------------------------------- +# PEI Zone: | 1 ~ PEI_LOCAL_TOKEN_NUMBER +# DXE Zone: | (PEI_LOCAL_TOKEN_NUMBER + 1) ~ (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER) +# +# 3.2.3 Local Token Number +# To fast searching a PCD entry in PCD database, PCD driver translate +# platform token number to local token number via a mapping table. +# For binary DynamicEx type PCD, there is a another mapping table to translate +# "token space guid + token number" to local token number directly. +# Local token number is identifier for all internal interface in PCD PEI/DXE +# driver. +# +# A local token number is a 32-bit value in following meaning: +# 32 ------------- 28 ---------- 24 -------- 0 +# | PCD type mask | Datum Type | Offset | +# +-----------------------------------------+ +# where: +# PCd type mask: indicate Pcd type from following macro: +# PCD_TYPE_DATA +# PCD_TYPE_HII +# PCD_TYPE_VPD +# PCD_TYPE_SKU_ENABLED +# PCD_TYPE_STRING +# Datum Type : indicate PCD vaue type from following macro: +# PCD_DATUM_TYPE_POINTER +# PCD_DATUM_TYPE_UINT8 +# PCD_DATUM_TYPE_UINT16 +# PCD_DATUM_TYPE_UINT32 +# PCD_DATUM_TYPE_UINT64 +# Offset : indicate the related offset of PCD value in PCD database array. +# Based on local token number, PCD driver could fast determine PCD type, value +# type and get PCD entry from PCD database. +# +# 3.3 PCD Database binary file +# PCD Database binary file will be created at build time as the standalone binary image. +# To understand the binary image layout, PCD Database C structure is still generated +# as comments by build tools in PCD driver's autogen.h/ +# autogen.c file. In generated C structure, following information is stored: +# - ExMapTable: This table is used translate a binary dynamicex type PCD's +# "tokenguid + token" to local token number. +# - LocalTokenNumberTable: +# This table stores all local token number in array, use "Internal +# token number" as array index to get PCD entry's offset fastly. +# - SizeTable: This table stores the size information for all PCD entry. +# - GuidTable: This table stores guid value for DynamicEx's token space, +# HII type PCD's variable GUID. +# - SkuIdTable: TBD +# - SystemSkuId: TBD +# - PCD value structure: +# Every PCD has a value record in PCD database. For different +# datum type PCD has different record structure which will be +# introduced in 3.3.1 +# +# In a PCD database structure, there are two major area: Init and UnInit. +# Init area is use stored above PCD internal structure such as ExMapTable, +# LocalTokenNumberTable etc and the (default) value of PCD which has default +# value specified in platform DSC file. +# Unint area is used stored the value of PCD which has no default value in +# platform DSC file, the value of NULL, 0 specified in platform DSC file can +# be seemed as "no default value". +# +# 3.3.1 Simple Sample PCD Database C Structure +# A general sample of PCD database structue is as follows: +# typedef struct _PCD_DATABASE { +# typedef struct _PCD_DATABASE_INIT { +# //===== Following is PCD database internal maintain structures +# DYNAMICEX_MAPPING ExMapTable[PEI_EXMAPPING_TABLE_SIZE]; +# UINT32 LocalTokenNumberTable[PEI_LOCAL_TOKEN_NUMBER_TABLE_SIZE]; +# GUID GuidTable[PEI_GUID_TABLE_SIZE]; +# SIZE_INFO SizeTable[PEI_SIZE_TABLE_SIZE]; +# UINT8 SkuIdTable[PEI_SKUID_TABLE_SIZE]; +# SKU_ID SystemSkuId; +# +# //===== Following is value structure for PCD with default value +# .... +# .... +# .... +# } Init; +# typedef struct _PCD_DATABSE_UNINIT { +# //==== Following is value structure for PCD without default value +# .... +# .... +# } UnInit; +# } +# +# 3.3.2 PCD value structure in PCD database C structure +# The value's structure is generated by build tool in PCD database C structure. +# The PCDs in different datum type has different value structure. +# +# 3.3.2.1 UINT8/UINT16/UINT32/UINT64 datum type PCD +# The C structure for these datum type PCD is just a UINT8/UINT16/UINT32/UINT64 +# data member in PCD database, For example: +# UINT16 PcdHardwareErrorRecordLevel_d3705011_bc19_4af7_be16_f68030378c15_VariableDefault_0; +# Above structure is generated by build tool, the member name is "PcdCName_Guidvalue" +# Member type is UINT16 according to PcdHardwareErrorRecordLevel declaration +# in DEC file. +# +# 3.3.2.2 VOID* datum type PCD +# The value of VOID* datum type PCD is a UINT8/UINT16 array in PCD database. +# +# 3.3.2.2.1 VOID* - string type +# If the default value for VOID* datum type PCD like L"xxx", the PCD is +# used for unicode string, and C structure of this datum type PCD is +# UINT16 string array in PCD database, for example: +# UINT16 StringTable[29]; +# The number of 29 in above sample is max size of a unicode string. +# +# If the default value for VOID* datum type PCD like "xxx", the PCD is +# used for ascii string, and C structure of this datum type PCD is +# UINT8 string array in PCD database, for example: +# UINT8 StringTable[20]; +# The number of 20 in above sample is max size of a ascii string. +# +# 3.3.2.2.2 VOID* - byte array +# If the default value of VOID* datum type PCD like {'0x29', '0x01', '0xf2'} +# the PCD is used for byte array. The generated structrue is same as +# above ascii string table, +# UINT8 StringTable[13]; +# The number of 13 in above sample is max size of byte array. +# +# 3.3.3 Some utility structures in PCD Database +# 3.3.3.1 GuidTable +# GuidTable array is used to store all related GUID value in PCD database: +# - Variable GUID for HII type PCD +# - Token space GUID for dynamicex type PCD +# +# Copyright (c) 2006 - 2017, 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] + INF_VERSION = 0x00010005 + BASE_NAME = PcdPeim + MODULE_UNI_FILE = PcdPeim.uni + FILE_GUID = 9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50 + MODULE_TYPE = PEIM + VERSION_STRING = 4.0 + PCD_IS_DRIVER = PEI_PCD_DRIVER + ENTRY_POINT = PcdPeimInit + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only) +# + +[Sources] + Service.c + Service.h + Pcd.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + PcdLib + PeiServicesLib + HobLib + BaseLib + PeimEntryPoint + DebugLib + MemoryAllocationLib + +[Guids] + ## PRODUCES ## HOB + ## SOMETIMES_CONSUMES ## HOB + gPcdDataBaseHobGuid + gPcdDataBaseSignatureGuid ## CONSUMES ## GUID # PCD database signature GUID. + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES + gPcdPpiGuid ## PRODUCES + gEfiPeiPcdPpiGuid ## PRODUCES + gGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES + gEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES + +[FeaturePcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## CONSUMES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry ## SOMETIMES_CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + PcdPeimExtra.uni diff --git a/Core/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni b/Core/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni new file mode 100644 index 0000000000..b0d3f1f79a --- /dev/null +++ b/Core/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni @@ -0,0 +1,296 @@ +// /** @file +// PCD PEIM produces PCD database to manage all dynamic PCD in PEI phase and install Pcd Ppi service. +// +// This version PCD PEIM depends on the external PCD database binary file, not built in PCD data base. +// There are two PCD PPIs as follows: +// 1) PCD_PPI +// It is EDKII implementation which support Dynamic/DynamicEx Pcds. +// 2) EFI_PEI_PCD_PPI +// It is defined by PI specification 1.2, Vol 3 which only support dynamicEx +// type Pcd. +// For dynamicEx type PCD, it is compatible between PCD_PPI and EFI_PEI_PCD_PPI. +// PCD PEIM driver will produce above two PPIs at same time. +// +// PCD database is generated as the separate binary image at build time. The binary image +// will be intergrated into Firmware volume together with PCD driver. +// +// //////////////////////////////////////////////////////////////////////////////// +// // // +// // Introduction of PCD database // +// // // +// //////////////////////////////////////////////////////////////////////////////// +// +// 1, Introduction +// PCD database hold all dynamic type PCD information. The structure of PEI PCD +// database is generated by build tools according to dynamic PCD usage for +// specified platform. +// +// 2, Dynamic Type PCD +// Dynamic type PCD is used for the configuration/setting which value is determined +// dynamic. In contrast, the value of static type PCD (FeatureFlag, FixedPcd, +// PatchablePcd) is fixed in final generated FD image in build time. +// +// 2.1 The "dynamic" determination means one of below cases: +// a) The PCD setting value is produced by someone driver and consumed by +// other driver in execution time. +// b) The PCD setting value is set/get by user from FrontPage. +// c) The PCD setting value is produced by platform OEM vendor in specified area. +// +// 2.2 According to module distribution way, dynamic PCD could be classfied as: +// a) Dynamic: +// If module is released in source code and will be built with platform +// DSC, the dynamic PCD used by this module can be accessed as: +// PcdGetxx(PcdSampleDynamicPcd); +// In building platform, build tools will translate PcdSampleDynamicPcd to +// pair of {Token Space Guid: Token Number} for this PCD. +// b) DynamicEx: +// If module is release as binary and will not pariticpate platform building, +// the dynamic PCD used by this module need be accessed as: +// PcdGetxxEx(gEfiMyTokenspaceGuid, PcdSampleDynamicPcd) +// Developer need explicity gives {Token Space Guid:Token Number} as parameter +// in writting source code. +// +// 2.3 According to PCD value's storage method, dynamic PCD could be classfied as: +// a) Default Storage: +// - The PCD value is stored in PCD database maintained by PCD driver in boot +// time memory. +// - This type is used for communication between PEIM/DXE driver, DXE/DXE +// driver. But all set/get value will be losted after boot-time memory +// is turn off. +// - [PcdsDynamicDefault] is used as section name for this type PCD in +// platform DSC file. [PcdsDynamicExDefault] is used for dynamicEx type PCD. +// +// b) Variable Storage: +// - The PCD value is stored in variable area. +// - As default storage type, this type PCD could be used for PEI/DXE driver +// communication. But beside it, this type PCD could also be used to store +// the value associate with a HII setting via variable interface. +// - In PEI phase, the PCD value could only be got but can not be set due +// to variable area is readonly. +// - [PcdsDynamicHii] is used as section name for this type PCD in platform +// DSC file. [PcdsDynamicExHii] is for dynamicEx type PCD. +// +// c) OEM specificed storage area: +// - The PCD value is stored in OEM specified area which base address is +// specified by a FixedAtBuild PCD setting - PcdVpdBaseAddress. +// - The area is read only for PEI and DXE phase. +// - [PcdsDynamicVpd] is used as section name for this type PCD in platform +// DSC file. [PcdsDynamicExVpd] is for dynamicex type PCD. +// +// 2.4 When and how to use dynamic PCD +// Module developer do not care the used PCD is dynamic or static when writting +// source code/INF. Dynamic PCD and dynamic type is pointed by platform integrator +// in platform DSC file. Please ref section 2.3 to get matching between dynamic +// PCD type and section name in DSC file. +// +// 3, PCD database: +// Although dynamic PCD could be in different storage type as above description, +// but the basic information and default value for all dynamic PCD is hold +// by PCD database maintained by PEI/DXE driver. +// +// As the whole EFI BIOS boot path is divided into PEI/DXE phase, the PCD database +// also is divided into Pei/Dxe database maintaied by PcdPeim/PcdDxe driver separatly. +// To make PcdPeim's driver image smaller, PEI PCD database only hold all dynamic +// PCD information used in PEI phase or use in both PEI/DXE phase. And DXE PCD +// database contains all PCDs used in PEI/DXE phase in memory. +// +// Build tool will generate PCD database into the separate binary file for +// PEI/DXE PCD driver according to dynamic PCD section in platform DSC file. +// +// 3.1 PcdPeim and PcdDxe +// PEI PCD database is maintained by PcdPeim driver run from flash. PcdPeim driver +// build guid hob in temporary memory and copy the binary data base from flash +// to temporary memory for PEI PCD database. +// DXE PCD database is maintained by PcdDxe driver.At entry point of PcdDxe driver, +// a new PCD database is allocated in boot-time memory which including all +// PEI PCD and DXE PCD entry. +// +// Pcd driver should run as early as possible before any other driver access +// dynamic PCD's value. PEI/DXE "Apriori File" mechanism make it possible by +// making PcdPeim/PcdDxe as first dispatching driver in PEI/DXE phase. +// +// 3.2 Token space Guid/Token number, Platform token, Local token number +// Dynamic PCD +// +-----------+ +---------+ +// |TokenSpace | |Platform | +// | Guid | build tool | Token | +// | + +-------------->| Number | +// | Token | +---------+`._ +// | Number | `. +// +-----------+ `. +------+ +// `-|Local | +// |Token | +// DynamicEx PCD ,-|Number| +// +-----------+ ,-' +------+ +// |TokenSpace | ,-' +// | Guid | _,-' +// | + +.' +// | Token | +// | Number | +// +-----------+ +// +// +// 3.2.1 Pair of Token space guid + Token number +// Any type PCD is identified by pair of "TokenSpaceGuid + TokeNumber". But it +// is not easy maintained by PCD driver, and hashed token number will make +// searching slowly. +// +// 3.2.2 Platform Token Number +// "Platform token number" concept is introduced for mapping to a pair of +// "TokenSpaceGuid + TokenNumber". The platform token number is generated by +// build tool in autogen.h and all of them are continual in a platform scope +// started from 1.(0 meaning invalid internal token number) +// With auto-generated "platform token number", PcdGet(PcdSampleDynamicPcd) +// in source code is translated to LibPcdGet(_PCD_TOKEN_PcdSampleDynamicPcd) +// in autogen.h. +// Notes: The mapping between pair of "tokenspace guid + token number" and +// "internal token number" need build tool establish, so "platform token number" +// mechanism is not suitable for binary module which use DynamicEx type PCD. +// To access a dynamicEx type PCD, pair of "token space guid/token number" all need +// to be specificed for PcdSet/PcdGet accessing macro. +// +// Platform Token Number is started from 1, and inceased continuous. From whole +// platform scope, there are two zones: PEI Zone and DXE Zone +// | Platform Token Number +// ----------|---------------------------------------------------------------- +// PEI Zone: | 1 ~ PEI_LOCAL_TOKEN_NUMBER +// DXE Zone: | (PEI_LOCAL_TOKEN_NUMBER + 1) ~ (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER) +// +// 3.2.3 Local Token Number +// To fast searching a PCD entry in PCD database, PCD driver translate +// platform token number to local token number via a mapping table. +// For binary DynamicEx type PCD, there is a another mapping table to translate +// "token space guid + token number" to local token number directly. +// Local token number is identifier for all internal interface in PCD PEI/DXE +// driver. +// +// A local token number is a 32-bit value in following meaning: +// 32 ------------- 28 ---------- 24 -------- 0 +// | PCD type mask | Datum Type | Offset | +// +-----------------------------------------+ +// where: +// PCd type mask: indicate Pcd type from following macro: +// PCD_TYPE_DATA +// PCD_TYPE_HII +// PCD_TYPE_VPD +// PCD_TYPE_SKU_ENABLED +// PCD_TYPE_STRING +// Datum Type : indicate PCD vaue type from following macro: +// PCD_DATUM_TYPE_POINTER +// PCD_DATUM_TYPE_UINT8 +// PCD_DATUM_TYPE_UINT16 +// PCD_DATUM_TYPE_UINT32 +// PCD_DATUM_TYPE_UINT64 +// Offset : indicate the related offset of PCD value in PCD database array. +// Based on local token number, PCD driver could fast determine PCD type, value +// type and get PCD entry from PCD database. +// +// 3.3 PCD Database binary file +// PCD Database binary file will be created at build time as the standalone binary image. +// To understand the binary image layout, PCD Database C structure is still generated +// as comments by build tools in PCD driver's autogen.h/ +// autogen.c file. In generated C structure, following information is stored: +// - ExMapTable: This table is used translate a binary dynamicex type PCD's +// "tokenguid + token" to local token number. +// - LocalTokenNumberTable: +// This table stores all local token number in array, use "Internal +// token number" as array index to get PCD entry's offset fastly. +// - SizeTable: This table stores the size information for all PCD entry. +// - GuidTable: This table stores guid value for DynamicEx's token space, +// HII type PCD's variable GUID. +// - SkuIdTable: TBD +// - SystemSkuId: TBD +// - PCD value structure: +// Every PCD has a value record in PCD database. For different +// datum type PCD has different record structure which will be +// introduced in 3.3.1 +// +// In a PCD database structure, there are two major area: Init and UnInit. +// Init area is use stored above PCD internal structure such as ExMapTable, +// LocalTokenNumberTable etc and the (default) value of PCD which has default +// value specified in platform DSC file. +// Unint area is used stored the value of PCD which has no default value in +// platform DSC file, the value of NULL, 0 specified in platform DSC file can +// be seemed as "no default value". +// +// 3.3.1 Simple Sample PCD Database C Structure +// A general sample of PCD database structue is as follows: +// typedef struct _PCD_DATABASE { +// typedef struct _PCD_DATABASE_INIT { +// //===== Following is PCD database internal maintain structures +// DYNAMICEX_MAPPING ExMapTable[PEI_EXMAPPING_TABLE_SIZE]; +// UINT32 LocalTokenNumberTable[PEI_LOCAL_TOKEN_NUMBER_TABLE_SIZE]; +// GUID GuidTable[PEI_GUID_TABLE_SIZE]; +// SIZE_INFO SizeTable[PEI_SIZE_TABLE_SIZE]; +// UINT8 SkuIdTable[PEI_SKUID_TABLE_SIZE]; +// SKU_ID SystemSkuId; +// +// //===== Following is value structure for PCD with default value +// .... +// .... +// .... +// } Init; +// typedef struct _PCD_DATABSE_UNINIT { +// //==== Following is value structure for PCD without default value +// .... +// .... +// } UnInit; +// } +// +// 3.3.2 PCD value structure in PCD database C structure +// The value's structure is generated by build tool in PCD database C structure. +// The PCDs in different datum type has different value structure. +// +// 3.3.2.1 UINT8/UINT16/UINT32/UINT64 datum type PCD +// The C structure for these datum type PCD is just a UINT8/UINT16/UINT32/UINT64 +// data member in PCD database, For example: +// UINT16 PcdHardwareErrorRecordLevel_d3705011_bc19_4af7_be16_f68030378c15_VariableDefault_0; +// Above structure is generated by build tool, the member name is "PcdCName_Guidvalue" +// Member type is UINT16 according to PcdHardwareErrorRecordLevel declaration +// in DEC file. +// +// 3.3.2.2 VOID* datum type PCD +// The value of VOID* datum type PCD is a UINT8/UINT16 array in PCD database. +// +// 3.3.2.2.1 VOID* - string type +// If the default value for VOID* datum type PCD like L"xxx", the PCD is +// used for unicode string, and C structure of this datum type PCD is +// UINT16 string array in PCD database, for example: +// UINT16 StringTable[29]; +// The number of 29 in above sample is max size of a unicode string. +// +// If the default value for VOID* datum type PCD like "xxx", the PCD is +// used for ascii string, and C structure of this datum type PCD is +// UINT8 string array in PCD database, for example: +// UINT8 StringTable[20]; +// The number of 20 in above sample is max size of a ascii string. +// +// 3.3.2.2.2 VOID* - byte array +// If the default value of VOID* datum type PCD like {'0x29', '0x01', '0xf2'} +// the PCD is used for byte array. The generated structrue is same as +// above ascii string table, +// UINT8 StringTable[13]; +// The number of 13 in above sample is max size of byte array. +// +// 3.3.3 Some utility structures in PCD Database +// 3.3.3.1 GuidTable +// GuidTable array is used to store all related GUID value in PCD database: +// - Variable GUID for HII type PCD +// - Token space GUID for dynamicex type PCD +// +// Copyright (c) 2006 - 2014, 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. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "PCD PEIM produces PCD database to manage all dynamic PCD in PEI phase and install Pcd Ppi service." + +#string STR_MODULE_DESCRIPTION #language en-US "PCD PEIM produces PCD database to manage all dynamic PCD in PEI phase and install Pcd Ppi service." + diff --git a/Core/MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni b/Core/MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni new file mode 100644 index 0000000000..a618943612 --- /dev/null +++ b/Core/MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni @@ -0,0 +1,19 @@ +// /** @file +// PcdPeim Localized Strings and Content +// +// Copyright (c) 2013 - 2014, 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. +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Platform Configuration Database PEI Module" + + diff --git a/Core/MdeModulePkg/Universal/PCD/Pei/Service.c b/Core/MdeModulePkg/Universal/PCD/Pei/Service.c new file mode 100644 index 0000000000..5e1cb72ba5 --- /dev/null +++ b/Core/MdeModulePkg/Universal/PCD/Pei/Service.c @@ -0,0 +1,1209 @@ +/** @file + The driver internal functions are implmented here. + They build Pei PCD database, and provide access service to PCD database. + +Copyright (c) 2006 - 2017, 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. + +**/ + +#include "Service.h" + +/** + Get Local Token Number by Token Number. + + @param[in] Database PCD database. + @param[in] TokenNumber The PCD token number. + + @return Local Token Number. +**/ +UINT32 +GetLocalTokenNumber ( + IN PEI_PCD_DATABASE *Database, + IN UINTN TokenNumber + ) +{ + UINT32 LocalTokenNumber; + UINTN Size; + 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--; + + LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber); + + Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT; + + if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) { + if (Size == 0) { + GetPtrTypeSize (TokenNumber, &MaxSize, Database); + } else { + MaxSize = Size; + } + LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize); + } + + return LocalTokenNumber; +} + +/** + Get PCD type by Local Token Number. + + @param[in] LocalTokenNumber The PCD local token number. + + @return PCD type. +**/ +EFI_PCD_TYPE +GetPcdType ( + IN UINT32 LocalTokenNumber + ) +{ + switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) { + case PCD_DATUM_TYPE_POINTER: + return EFI_PCD_TYPE_PTR; + case PCD_DATUM_TYPE_UINT8: + if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) { + return EFI_PCD_TYPE_BOOL; + } else { + return EFI_PCD_TYPE_8; + } + case PCD_DATUM_TYPE_UINT16: + return EFI_PCD_TYPE_16; + case PCD_DATUM_TYPE_UINT32: + return EFI_PCD_TYPE_32; + case PCD_DATUM_TYPE_UINT64: + return EFI_PCD_TYPE_64; + default: + ASSERT (FALSE); + return EFI_PCD_TYPE_8; + } +} + +/** + Get PCD name. + + @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName. + If FALSE, need to get the full PCD name. + @param[in] Database PCD database. + @param[in] TokenNumber The PCD token number. + + @return The TokenSpaceCName or full PCD name. +**/ +CHAR8 * +GetPcdName ( + IN BOOLEAN OnlyTokenSpaceName, + IN PEI_PCD_DATABASE *Database, + IN UINTN TokenNumber + ) +{ + UINT8 *StringTable; + UINTN NameSize; + PCD_NAME_INDEX *PcdNameIndex; + CHAR8 *TokenSpaceName; + CHAR8 *PcdName; + CHAR8 *Name; + + // + // Return NULL when PCD name table is absent. + // + if (Database->PcdNameTableOffset == 0) { + return 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--; + + StringTable = (UINT8 *) Database + Database->StringTableOffset; + + // + // Get the PCD name index. + // + PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber; + TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex]; + PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex]; + + if (OnlyTokenSpaceName) { + // + // Only need to get the TokenSpaceCName. + // + Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName); + } else { + // + // Need to get the full PCD name. + // + NameSize = AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName); + Name = AllocateZeroPool (NameSize); + ASSERT (Name != NULL); + // + // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name. + // + AsciiStrCatS (Name, NameSize, TokenSpaceName); + Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.'; + AsciiStrCatS (Name, NameSize, PcdName); + } + + return Name; +} + +/** + Retrieve additional information associated with a PCD token. + + This includes information such as the type of value the TokenNumber is associated with as well as possible + human readable name that is associated with the token. + + @param[in] Database PCD database. + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the requested TokenNumber. + The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +EFI_STATUS +ExGetPcdInfo ( + IN PEI_PCD_DATABASE *Database, + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + UINTN GuidTableIdx; + EFI_GUID *MatchGuid; + EFI_GUID *GuidTable; + DYNAMICEX_MAPPING *ExMapTable; + UINTN Index; + UINT32 LocalTokenNumber; + + GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset); + MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof(EFI_GUID), Guid); + + if (MatchGuid == NULL) { + return EFI_NOT_FOUND; + } + + GuidTableIdx = MatchGuid - GuidTable; + + ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset); + + // + // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable. + // + for (Index = 0; Index < Database->ExTokenCount; Index++) { + if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) { + if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + // + // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8, + // PcdSize to 0 and PcdName to the null-terminated ASCII string + // associated with the token's namespace Guid. + // + PcdInfo->PcdType = EFI_PCD_TYPE_8; + PcdInfo->PcdSize = 0; + // + // Here use one representative in the token space to get the TokenSpaceCName. + // + PcdInfo->PcdName = GetPcdName (TRUE, Database, ExMapTable[Index].TokenNumber); + return EFI_SUCCESS; + } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) { + PcdInfo->PcdSize = PeiPcdGetSize (ExMapTable[Index].TokenNumber); + LocalTokenNumber = GetLocalTokenNumber (Database, ExMapTable[Index].TokenNumber); + PcdInfo->PcdType = GetPcdType (LocalTokenNumber); + PcdInfo->PcdName = GetPcdName (FALSE, Database, ExMapTable[Index].TokenNumber); + return EFI_SUCCESS; + } + } + } + + return EFI_NOT_FOUND; +} + +/** + Retrieve additional information associated with a PCD token. + + This includes information such as the type of value the TokenNumber is associated with as well as possible + human readable name that is associated with the token. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the requested TokenNumber. + The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +EFI_STATUS +PeiGetPcdInfo ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + PEI_PCD_DATABASE *PeiPcdDb; + BOOLEAN PeiExMapTableEmpty; + UINTN PeiNexTokenNumber; + UINT32 LocalTokenNumber; + + ASSERT (PcdInfo != NULL); + + PeiPcdDb = GetPcdDatabase (); + PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount; + + if (PeiPcdDb->ExTokenCount == 0) { + PeiExMapTableEmpty = TRUE; + } else { + PeiExMapTableEmpty = FALSE; + } + + if (Guid == NULL) { + if (TokenNumber > PeiNexTokenNumber) { + return EFI_NOT_FOUND; + } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + // + // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8, + // PcdSize to 0 and PcdName to NULL for default Token Space. + // + PcdInfo->PcdType = EFI_PCD_TYPE_8; + PcdInfo->PcdSize = 0; + PcdInfo->PcdName = NULL; + } else { + PcdInfo->PcdSize = PeiPcdGetSize (TokenNumber); + LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber); + PcdInfo->PcdType = GetPcdType (LocalTokenNumber); + PcdInfo->PcdName = GetPcdName (FALSE, PeiPcdDb, TokenNumber); + } + return EFI_SUCCESS; + } else { + if (PeiExMapTableEmpty) { + return EFI_NOT_FOUND; + } + return ExGetPcdInfo ( + PeiPcdDb, + Guid, + TokenNumber, + PcdInfo + ); + } +} + +/** + The function registers the CallBackOnSet fucntion + according to TokenNumber and EFI_GUID space. + + @param ExTokenNumber 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. + @retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found. +**/ +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; + UINT32 LocalTokenCount; + UINTN PeiNexTokenNumber; + UINTN TokenNumber; + UINTN Idx; + PEI_PCD_DATABASE *PeiPcdDb; + + PeiPcdDb = GetPcdDatabase(); + LocalTokenCount = PeiPcdDb->LocalTokenCount; + PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount; + + 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 < (PeiNexTokenNumber + 1)); + } else { + TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber); + if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + return EFI_NOT_FOUND; + } + // + // 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) < (LocalTokenCount + 1)); + } + + + LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + 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 (&gEfiCallerIdGuid); + ASSERT (GuidHob != NULL); + + CallbackTable = GET_GUID_HOB_DATA (GuidHob); + CallbackTable = CallbackTable + (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry)); + + Compare = Register? NULL: CallBackFunction; + Assign = Register? CallBackFunction: NULL; + + + for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) { + if (CallbackTable[Idx] == Compare) { + CallbackTable[Idx] = Assign; + return EFI_SUCCESS; + } + } + + return Register? EFI_OUT_OF_RESOURCES : EFI_INVALID_PARAMETER; + +} + + +/** + Find the Pcd database. + + @param FileHandle Handle of the file the external PCD database binary located. + + @retval The base address of external PCD database binary. + @retval NULL Return NULL if not find. +**/ +VOID * +LocateExPcdBinary ( + IN EFI_PEI_FILE_HANDLE FileHandle + ) +{ + EFI_STATUS Status; + VOID *PcdDb; + + PcdDb = NULL; + + ASSERT (FileHandle != NULL); + + Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb); + ASSERT_EFI_ERROR (Status); + + // + // Check the first bytes (Header Signature Guid) and build version. + // + if (!CompareGuid (PcdDb, &gPcdDataBaseSignatureGuid) || + (((PEI_PCD_DATABASE *) PcdDb)->BuildVersion != PCD_SERVICE_PEIM_VERSION)) { + ASSERT (FALSE); + } + return PcdDb; +} + + +/** + The function builds the PCD database. + + @param FileHandle Handle of the file the external PCD database binary located. + + @return Pointer to PCD database. +**/ +PEI_PCD_DATABASE * +BuildPcdDatabase ( + IN EFI_PEI_FILE_HANDLE FileHandle + ) +{ + PEI_PCD_DATABASE *Database; + PEI_PCD_DATABASE *PeiPcdDbBinary; + VOID *CallbackFnTable; + UINTN SizeOfCallbackFnTable; + + // + // Locate the external PCD database binary for one section of current FFS + // + PeiPcdDbBinary = LocateExPcdBinary (FileHandle); + + ASSERT(PeiPcdDbBinary != NULL); + + Database = BuildGuidHob (&gPcdDataBaseHobGuid, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize); + + ZeroMem (Database, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize); + + // + // PeiPcdDbBinary is smaller than Database + // + CopyMem (Database, PeiPcdDbBinary, PeiPcdDbBinary->Length); + + SizeOfCallbackFnTable = Database->LocalTokenCount * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); + + CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable); + + ZeroMem (CallbackFnTable, SizeOfCallbackFnTable); + + return Database; +} + +/** + 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. +**/ +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_VARIABLE2_PPI *VariablePpi; + + Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); + ASSERT_EFI_ERROR (Status); + + Size = 0; + Status = VariablePpi->GetVariable ( + VariablePpi, + VariableName, + (EFI_GUID *) VariableGuid, + NULL, + &Size, + NULL + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + Status = PeiServicesAllocatePool (Size, &Buffer); + ASSERT_EFI_ERROR (Status); + + Status = VariablePpi->GetVariable ( + VariablePpi, + (UINT16 *) VariableName, + (EFI_GUID *) VariableGuid, + NULL, + &Size, + Buffer + ); + ASSERT_EFI_ERROR (Status); + + *VariableSize = Size; + *VariableData = Buffer; + + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +/** + Find the local token number according to system SKU ID. + + @param LocalTokenNumber PCD token number + @param Size The size of PCD entry. + + @return Token number according to system SKU ID. + +**/ +UINT32 +GetSkuEnabledTokenNumber ( + UINT32 LocalTokenNumber, + UINTN Size + ) +{ + PEI_PCD_DATABASE *PeiPcdDb; + SKU_HEAD *SkuHead; + SKU_ID *SkuIdTable; + UINTN Index; + UINT8 *Value; + BOOLEAN FoundSku; + + 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)); + + // + // Find the current system's SKU ID entry in SKU ID table. + // + FoundSku = FALSE; + for (Index = 0; Index < SkuIdTable[0]; Index++) { + if (PeiPcdDb->SystemSkuId == SkuIdTable[Index + 1]) { + FoundSku = TRUE; + break; + } + } + + // + // Find the default SKU ID entry in SKU ID table. + // + if(!FoundSku) { + for (Index = 0; Index < SkuIdTable[0]; Index++) { + if (0 == SkuIdTable[Index + 1]) { + break; + } + } + } + ASSERT (Index < SkuIdTable[0]); + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD); + + case PCD_TYPE_HII: + Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII); + + case PCD_TYPE_HII|PCD_TYPE_STRING: + Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING); + + case PCD_TYPE_STRING: + Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]); + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING); + + case PCD_TYPE_DATA: + Value += Size * Index; + return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_DATA); + + default: + ASSERT (FALSE); + } + + ASSERT (FALSE); + + return 0; +} + +/** + Invoke the callback function when dynamic PCD entry was set, if this PCD entry + has registered callback function. + + @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx + type PCD. + @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type + PCD. + @param TokenNumber PCD token number generated by build tools. + @param Data Value want to be set for this PCD entry + @param Size The size of value + +**/ +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; + PEI_PCD_DATABASE *PeiPcdDb; + UINT32 LocalTokenCount; + + // + // 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--; + + PeiPcdDb = GetPcdDatabase (); + LocalTokenCount = PeiPcdDb->LocalTokenCount; + + 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 < (LocalTokenCount + 1)); + } + + GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); + ASSERT (GuidHob != NULL); + + CallbackTable = GET_GUID_HOB_DATA (GuidHob); + + CallbackTable += (TokenNumber * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry)); + + for (Idx = 0; Idx < PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) { + if (CallbackTable[Idx] != NULL) { + CallbackTable[Idx] (Guid, + (Guid == NULL) ? (TokenNumber + 1) : ExTokenNumber, + Data, + Size + ); + } + } +} + +/** + Wrapper function for setting non-pointer type value for a PCD entry. + + @param TokenNumber Pcd token number autogenerated by build tools. + @param Data Value want to be set for PCD entry + @param Size Size of value. + + @return status of SetWorker. + +**/ +EFI_STATUS +SetValueWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN UINTN Size + ) +{ + return SetWorker (TokenNumber, Data, &Size, FALSE); +} + +/** + Set value for an PCD entry + + @param TokenNumber Pcd token number autogenerated by build tools. + @param Data Value want to be set for PCD entry + @param Size Size of value. + @param PtrType If TRUE, the type of PCD entry's value is Pointer. + If False, the type of PCD entry's value is not Pointer. + + @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set. + @retval EFI_INVALID_PARAMETER If Size can not be set to size table. + @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database. + @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in + range of UINT8, UINT16, UINT32, UINT64 + @retval EFI_NOT_FOUND Can not find the PCD type according to token number. +**/ +EFI_STATUS +SetWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ) +{ + UINT32 LocalTokenNumber; + UINTN PeiNexTokenNumber; + PEI_PCD_DATABASE *PeiPcdDb; + STRING_HEAD StringTableIdx; + UINTN Offset; + VOID *InternalData; + UINTN MaxSize; + UINT32 LocalTokenCount; + + if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) { + 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--; + PeiPcdDb = GetPcdDatabase (); + LocalTokenCount = PeiPcdDb->LocalTokenCount; + + // 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 < (LocalTokenCount + 1)); + + if (PtrType) { + // + // Get MaxSize first, then check new size with max buffer size. + // + GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); + if (*Size > MaxSize) { + *Size = MaxSize; + return EFI_INVALID_PARAMETER; + } + } else { + if (*Size != PeiPcdGetSize (TokenNumber + 1)) { + return EFI_INVALID_PARAMETER; + } + } + + // + // 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. + // + PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount; + if (TokenNumber + 1 < PeiNexTokenNumber + 1) { + InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size); + } + + LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1); + + 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: + case PCD_TYPE_HII|PCD_TYPE_STRING: + { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + case PCD_TYPE_STRING: + if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) { + StringTableIdx = *((STRING_HEAD *)InternalData); + CopyMem ((UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset + 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; + +} + +/** + Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD. + + @param ExTokenNumber Token number for dynamic-ex PCD. + @param Guid Token space guid for dynamic-ex PCD. + @param Data Value want to be set. + @param SetSize The size of value. + + @return status of ExSetWorker(). + +**/ +EFI_STATUS +ExSetValueWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN Size + ) +{ + return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE); +} + +/** + Set value for a dynamic-ex PCD entry. + + This routine find the local token number according to dynamic-ex PCD's token + space guid and token number firstly, and invoke callback function if this PCD + entry registered callback function. Finally, invoken general SetWorker to set + PCD value. + + @param ExTokenNumber Dynamic-ex PCD token number. + @param Guid Token space guid for dynamic-ex PCD. + @param Data PCD value want to be set + @param SetSize Size of value. + @param PtrType If TRUE, this PCD entry is pointer type. + If FALSE, this PCD entry is not pointer type. + + @return status of SetWorker(). + +**/ +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(PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber); + if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) { + return EFI_NOT_FOUND; + } + + InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size); + + return SetWorker (TokenNumber, Data, Size, PtrType); + +} + +/** + Wrapper function for get PCD value for dynamic-ex PCD. + + @param Guid Token space guid for dynamic-ex PCD. + @param ExTokenNumber Token number for dyanmic-ex PCD. + @param GetSize The size of dynamic-ex PCD value. + + @return PCD entry in PCD database. + +**/ +VOID * +ExGetWorker ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINTN GetSize + ) +{ + return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize); +} + +/** + Get the PCD entry pointer in PCD database. + + This routine will visit PCD database to find the PCD entry according to given + token number. The given token number is autogened by build tools and it will be + translated to local token number. Local token number contains PCD's type and + offset of PCD entry in PCD database. + + @param TokenNumber Token's number, it is autogened by build tools + @param GetSize The size of token's value + + @return PCD entry pointer in PCD database + +**/ +VOID * +GetWorker ( + IN UINTN TokenNumber, + IN UINTN GetSize + ) +{ + UINT32 Offset; + EFI_GUID *Guid; + UINT16 *Name; + VARIABLE_HEAD *VariableHead; + EFI_STATUS Status; + UINTN DataSize; + VOID *Data; + UINT8 *StringTable; + STRING_HEAD StringTableIdx; + PEI_PCD_DATABASE *PeiPcdDb; + UINT32 LocalTokenNumber; + UINT32 LocalTokenCount; + UINT8 *VaraiableDefaultBuffer; + + // + // 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--; + + PeiPcdDb = GetPcdDatabase (); + LocalTokenCount = PeiPcdDb->LocalTokenCount; + + // 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 < (LocalTokenCount + 1)); + + ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0)); + + LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1); + + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset; + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + { + VPD_HEAD *VpdHead; + VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset); + return (VOID *) ((UINTN) PcdGet32 (PcdVpdBaseAddress) + VpdHead->Offset); + } + + case PCD_TYPE_HII|PCD_TYPE_STRING: + case PCD_TYPE_HII: + { + VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset); + + Guid = (EFI_GUID *) ((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex; + Name = (UINT16*)&StringTable[VariableHead->StringIndex]; + + if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) { + // + // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of + // string array in string table. + // + VaraiableDefaultBuffer = (UINT8 *) &StringTable[*(STRING_HEAD*)((UINT8*) PeiPcdDb + VariableHead->DefaultValueOffset)]; + } else { + VaraiableDefaultBuffer = (UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset; + } + Status = GetHiiVariable (Guid, Name, &Data, &DataSize); + if ((Status == EFI_SUCCESS) && (DataSize >= (VariableHead->Offset + GetSize))) { + if (GetSize == 0) { + // + // It is a pointer type. So get the MaxSize reserved for + // this PCD entry. + // + GetPtrTypeSize (TokenNumber, &GetSize, PeiPcdDb); + if (GetSize > (DataSize - VariableHead->Offset)) { + // + // Use actual valid size. + // + GetSize = DataSize - VariableHead->Offset; + } + } + // + // If the operation is successful, we copy the data + // to the default value buffer in the PCD Database. + // + CopyMem (VaraiableDefaultBuffer, (UINT8 *) Data + VariableHead->Offset, GetSize); + } + return (VOID *) VaraiableDefaultBuffer; + } + + case PCD_TYPE_DATA: + return (VOID *) ((UINT8 *)PeiPcdDb + Offset); + + case PCD_TYPE_STRING: + StringTableIdx = * (STRING_HEAD*) ((UINT8 *) PeiPcdDb + Offset); + return (VOID *) (&StringTable[StringTableIdx]); + + default: + ASSERT (FALSE); + break; + + } + + ASSERT (FALSE); + + return NULL; + +} + +/** + Get Token Number according to dynamic-ex PCD's {token space guid:token number} + + A dynamic-ex type PCD, developer must provide pair of token space guid: token number + in DEC file. PCD database maintain a mapping table that translate pair of {token + space guid: token number} to Token Number. + + @param Guid Token space guid for dynamic-ex PCD entry. + @param ExTokenNumber Dynamic-ex PCD token number. + + @return Token Number for dynamic-ex PCD. + +**/ +UINTN +GetExPcdTokenNumber ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + UINT32 Index; + DYNAMICEX_MAPPING *ExMap; + EFI_GUID *GuidTable; + EFI_GUID *MatchGuid; + UINTN MatchGuidIdx; + PEI_PCD_DATABASE *PeiPcdDb; + + PeiPcdDb = GetPcdDatabase(); + + ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset); + GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset); + + MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(EFI_GUID), 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 (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) { + if ((ExTokenNumber == ExMap[Index].ExTokenNumber) && + (MatchGuidIdx == ExMap[Index].ExGuidIndex)) { + return ExMap[Index].TokenNumber; + } + } + + return PCD_INVALID_TOKEN_NUMBER; +} + +/** + Get PCD database from GUID HOB in PEI phase. + + @return Pointer to PCD database. + +**/ +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); +} + +/** + Get SKU ID table from PCD database. + + @param LocalTokenNumberTableIdx Index of local token number in token number table. + @param Database PCD database. + + @return Pointer to SKU ID array table + +**/ +SKU_ID * +GetSkuIdArray ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ) +{ + SKU_HEAD *SkuHead; + UINTN LocalTokenNumber; + + LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + 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); + +} + +/** + Get index of PCD entry in size table. + + @param LocalTokenNumberTableIdx Index of this PCD in local token number table. + @param Database Pointer to PCD database in PEI phase. + + @return index of PCD entry in size table. + +**/ +UINTN +GetSizeTableIndex ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ) +{ + UINTN Index; + UINTN SizeTableIdx; + UINTN LocalTokenNumber; + SKU_ID *SkuIdTable; + + SizeTableIdx = 0; + + for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) { + LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + Index); + + 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) != 0) { + // + // We have only two entry for VPD enabled PCD entry: + // 1) MAX Size. + // 2) Current Size + // Current size is equal to MAX size. + // + SizeTableIdx += 2; + } 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 (Index, Database); + SizeTableIdx += (UINTN)*SkuIdTable + 1; + } + } + } + + } + + return SizeTableIdx; +} diff --git a/Core/MdeModulePkg/Universal/PCD/Pei/Service.h b/Core/MdeModulePkg/Universal/PCD/Pei/Service.h new file mode 100644 index 0000000000..fa14abeaa3 --- /dev/null +++ b/Core/MdeModulePkg/Universal/PCD/Pei/Service.h @@ -0,0 +1,1117 @@ +/** @file + The internal header file declares the private functions used by PeiPcd driver. + +Copyright (c) 2006 - 2016, 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 _PEI_PCD_SERVICE_H_ +#define _PEI_PCD_SERVICE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Please make sure the PCD Serivce PEIM Version is consistent with +// the version of the generated PEIM PCD Database by build tool. +// +#define PCD_SERVICE_PEIM_VERSION 6 + +// +// PCD_PEI_SERVICE_DRIVER_VERSION is defined in Autogen.h. +// +#if (PCD_SERVICE_PEIM_VERSION != PCD_PEI_SERVICE_DRIVER_VERSION) + #error "Please make sure the version of PCD PEIM Service and the generated PCD PEI Database match." +#endif + +/** + Retrieve additional information associated with a PCD token in the default token space. + + This includes information such as the type of value the TokenNumber is associated with as well as possible + human readable name that is associated with the token. + + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the requested TokenNumber. + The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +EFI_STATUS +EFIAPI +PeiGetPcdInfoGetInfo ( + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ); + +/** + Retrieve additional information associated with a PCD token. + + This includes information such as the type of value the TokenNumber is associated with as well as possible + human readable name that is associated with the token. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the requested TokenNumber. + The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +EFI_STATUS +EFIAPI +PeiGetPcdInfoGetInfoEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ); + +/** + Retrieve the currently set SKU Id. + + @return The currently set SKU Id. If the platform has not set at a SKU Id, then the + default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU + Id is returned. +**/ +UINTN +EFIAPI +PeiGetPcdInfoGetSku ( + VOID + ); + +// +// PPI Interface Implementation Declaration. +// + +/** + Sets the SKU value for subsequent calls to set or get PCD token values. + + SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values. + SetSku() is normally called only once by the system. + + For each item (token), the database can hold a single value that applies to all SKUs, + or multiple values, where each value is associated with a specific SKU Id. Items with multiple, + SKU-specific values are called SKU enabled. + + The SKU Id of zero is reserved as a default. The valid SkuId range is 1 to 255. + For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the + single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the + last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token, + the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been + set for that Id, the results are unpredictable. + + @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and + set values associated with a PCD token. + +**/ +VOID +EFIAPI +PeiPcdSetSku ( + IN UINTN SkuId + ); + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the current byte-sized value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT8 value. + +**/ +UINT8 +EFIAPI +PeiPcdGet8 ( + IN UINTN TokenNumber + ); + +/** + Retrieves an 16-bit value for a given PCD token. + + Retrieves the current 16-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT16 value. + +**/ +UINT16 +EFIAPI +PeiPcdGet16 ( + IN UINTN TokenNumber + ); + +/** + Retrieves an 32-bit value for a given PCD token. + + Retrieves the current 32-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT32 value. + +**/ +UINT32 +EFIAPI +PeiPcdGet32 ( + IN UINTN TokenNumber + ); + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the current 64-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT64 value. + +**/ +UINT64 +EFIAPI +PeiPcdGet64 ( + IN UINTN TokenNumber + ); + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The pointer to the buffer to be retrived. + +**/ +VOID * +EFIAPI +PeiPcdGetPtr ( + IN UINTN TokenNumber + ); + +/** + Retrieves a Boolean value for a given PCD token. + + Retrieves the current boolean value for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The Boolean value. + +**/ +BOOLEAN +EFIAPI +PeiPcdGetBool ( + IN UINTN TokenNumber + ); + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +UINTN +EFIAPI +PeiPcdGetSize ( + IN UINTN TokenNumber + ); + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the 8-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size 8-bit value for the PCD token. + +**/ +UINT8 +EFIAPI +PeiPcdGet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves an 16-bit value for a given PCD token. + + Retrieves the 16-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size 16-bit value for the PCD token. + +**/ +UINT16 +EFIAPI +PeiPcdGet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves an 32-bit value for a given PCD token. + + Retrieves the 32-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size 32-bit value for the PCD token. + +**/ +UINT32 +EFIAPI +PeiPcdGet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the 64-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size 64-bit value for the PCD token. + +**/ +UINT64 +EFIAPI +PeiPcdGet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The pointer to the buffer to be retrived. + +**/ +VOID * +EFIAPI +PeiPcdGetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves an Boolean value for a given PCD token. + + Retrieves the Boolean value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size Boolean value for the PCD token. + +**/ +BOOLEAN +EFIAPI +PeiPcdGetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] TokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +UINTN +EFIAPI +PeiPcdGetSizeEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber + ); + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet8 ( + IN UINTN TokenNumber, + IN UINT8 Value + ); + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet16 ( + IN UINTN TokenNumber, + IN UINT16 Value + ); + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet32 ( + IN UINTN TokenNumber, + IN UINT32 Value + ); + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet64 ( + IN UINTN TokenNumber, + IN UINT64 Value + ); + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. + On input, if the SizeOfValue is greater than the maximum size supported + for this TokenNumber then the output value of SizeOfValue will reflect + the maximum size supported for this TokenNumber. + @param[in] Buffer The buffer to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetPtr ( + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ); + +/** + Sets an Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetBool ( + IN UINTN TokenNumber, + IN BOOLEAN Value + ); + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT8 Value + ); + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT16 Value + ); + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT32 Value + ); + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN UINT64 Value + ); + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token. + On input, if the SizeOfValue is greater than the maximum size supported + for this TokenNumber then the output value of SizeOfValue will reflect + the maximum size supported for this TokenNumber. + @param[in] Buffer The buffer to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ); + +/** + Sets an Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing definition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data + being set was incompatible with a call to this function. + Use GetSize() to retrieve the size of the target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + IN BOOLEAN Value + ); + +/** + Specifies a function to be called anytime the value of a designated token is changed. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. + +**/ +EFI_STATUS +EFIAPI +PeiRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ); + +/** + Cancels a previously set callback function for a particular PCD token number. + + @param [in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param [in] TokenNumber The PCD token number. + @param [in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced token number. + +**/ +EFI_STATUS +EFIAPI +PcdUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN UINTN TokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ); + +/** + Retrieves the next valid token number in a given namespace. + + This is useful since the PCD infrastructure contains a sparse list of token numbers, + and one cannot a priori know what token numbers are valid in the database. + + If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned. + If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned. + If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned. + If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned. + The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid. + If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned. + If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned. + If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned. + + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + This is an optional parameter that may be NULL. If this parameter is NULL, then a request + is being made to retrieve tokens from the default token space. + @param[in, out] TokenNumber A pointer to the PCD token number to use to find the subsequent token number. + + @retval EFI_SUCCESS The PCD service has retrieved the next valid token number. + Or the input token number is already the last valid token number in the PCD database. + In the later case, *TokenNumber is updated with the value of 0. + @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform. + +**/ +EFI_STATUS +EFIAPI +PeiPcdGetNextToken ( + IN CONST EFI_GUID *Guid, OPTIONAL + IN OUT UINTN *TokenNumber + ); + +/** + Retrieves the next valid PCD token namespace for a given namespace. + + @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates + a known token namespace from which the search will start. On output, + it designates the next valid token namespace on the platform. If the input + token namespace does not exist on the platform, an error is returned and + the value of *Guid is undefined. If *Guid is NULL, then the GUID of the + first token space of the current platform is assigned to *Guid the function + return EFI_SUCCESS. If *Guid is NULL and there is no namespace exist in + the platform other than the default (NULL) tokennamespace, *Guid is unchanged + and the function return EFI_SUCCESS. If this input token namespace is the last + namespace on the platform, *Guid will be assigned to NULL and the function return + EFI_SUCCESS. + + @retval EFI_SUCCESS The PCD service retrieved the next valid token space Guid. + Or the input token space Guid is already the last valid token space Guid + in the PCD database. In the later case, *Guid is updated with the value of NULL. + @retval EFI_NOT_FOUND If the input token namespace does not exist on the platform. + +**/ +EFI_STATUS +EFIAPI +PeiPcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ); + +/** + Retrieve additional information associated with a PCD token. + + This includes information such as the type of value the TokenNumber is associated with as well as possible + human readable name that is associated with the token. + + @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the requested TokenNumber. + The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully + @retval EFI_NOT_FOUND The PCD service could not find the requested token number. +**/ +EFI_STATUS +PeiGetPcdInfo ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ); + +/* Internal Function definitions */ +/** + Get PCD database from GUID HOB in PEI phase. + + @return Pointer to PCD database. + +**/ +PEI_PCD_DATABASE * +GetPcdDatabase ( + VOID + ); + +/** + Wrapper function for setting non-pointer type value for a PCD entry. + + @param TokenNumber Pcd token number autogenerated by build tools. + @param Data Value want to be set for PCD entry + @param Size Size of value. + + @return status of SetWorker. + +**/ +EFI_STATUS +SetValueWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN UINTN Size + ); + +/** + Set value for an PCD entry + + @param TokenNumber Pcd token number autogenerated by build tools. + @param Data Value want to be set for PCD entry + @param Size Size of value. + @param PtrType If TRUE, the type of PCD entry's value is Pointer. + If False, the type of PCD entry's value is not Pointer. + + @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set. + @retval EFI_INVALID_PARAMETER If Size can not be set to size table. + @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database. + @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in + range of UINT8, UINT16, UINT32, UINT64 + @retval EFI_NOT_FOUND Can not find the PCD type according to token number. +**/ +EFI_STATUS +SetWorker ( + IN UINTN TokenNumber, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ); + +/** + Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD. + + @param ExTokenNumber Token number for dynamic-ex PCD. + @param Guid Token space guid for dynamic-ex PCD. + @param Data Value want to be set. + @param SetSize The size of value. + + @return status of ExSetWorker(). + +**/ +EFI_STATUS +ExSetValueWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN UINTN Size + ); + +/** + Set value for a dynamic PCD entry. + + This routine find the local token number according to dynamic-ex PCD's token + space guid and token number firstly, and invoke callback function if this PCD + entry registered callback function. Finally, invoken general SetWorker to set + PCD value. + + @param ExTokenNumber Dynamic-ex PCD token number. + @param Guid Token space guid for dynamic-ex PCD. + @param Data PCD value want to be set + @param SetSize Size of value. + @param PtrType If TRUE, this PCD entry is pointer type. + If FALSE, this PCD entry is not pointer type. + + @return status of SetWorker(). + +**/ +EFI_STATUS +ExSetWorker ( + IN UINTN ExTokenNumber, + IN CONST EFI_GUID *Guid, + IN VOID *Data, + IN OUT UINTN *Size, + IN BOOLEAN PtrType + ); + +/** + Get the PCD entry pointer in PCD database. + + This routine will visit PCD database to find the PCD entry according to given + token number. The given token number is autogened by build tools and it will be + translated to local token number. Local token number contains PCD's type and + offset of PCD entry in PCD database. + + @param TokenNumber Token's number, it is autogened by build tools + @param GetSize The size of token's value + + @return PCD entry pointer in PCD database + +**/ +VOID * +GetWorker ( + IN UINTN TokenNumber, + IN UINTN GetSize + ); + +/** + Wrapper function for get PCD value for dynamic-ex PCD. + + @param Guid Token space guid for dynamic-ex PCD. + @param ExTokenNumber Token number for dyanmic-ex PCD. + @param GetSize The size of dynamic-ex PCD value. + + @return PCD entry in PCD database. + +**/ +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; + +/** + Get Token Number according to dynamic-ex PCD's {token space guid:token number} + + A dynamic-ex type PCD, developer must provide pair of token space guid: token number + in DEC file. PCD database maintain a mapping table that translate pair of {token + space guid: token number} to Token Number. + + @param Guid Token space guid for dynamic-ex PCD entry. + @param ExTokenNumber Token number for dynamic-ex PCD. + + @return Token Number for dynamic-ex PCD. + +**/ +UINTN +GetExPcdTokenNumber ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ); + +/** + Find the local token number according to system SKU ID. + + @param LocalTokenNumber PCD token number + @param Size The size of PCD entry. + + @return Token number according to system SKU ID. + +**/ +UINT32 +GetSkuEnabledTokenNumber ( + UINT32 LocalTokenNumber, + UINTN Size + ); + +/** + 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 TokenNumber, + IN CONST EFI_GUID *Guid, OPTIONAL + IN PCD_PPI_CALLBACK CallBackFunction, + IN BOOLEAN Register + ); + +/** + The function builds the PCD database. + + @param FileHandle Handle of the file the external PCD database binary located. + + @return Pointer to PCD database. + +**/ +PEI_PCD_DATABASE * +BuildPcdDatabase ( + IN EFI_PEI_FILE_HANDLE FileHandle + ); + +/** + Get SKU ID tabble from PCD database. + + @param LocalTokenNumberTableIdx Index of local token number in token number table. + @param Database PCD Database in PEI phase + + @return Pointer to SKU ID array table + +**/ +SKU_ID * +GetSkuIdArray ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ); + +/** + Get index of PCD entry in size table. + + @param LocalTokenNumberTableIdx Index of this PCD in local token number table. + @param Database Pointer to PCD database. + + @return index of PCD entry in size table. + +**/ +UINTN +GetSizeTableIndex ( + IN UINTN LocalTokenNumberTableIdx, + IN PEI_PCD_DATABASE *Database + ); + +/** + Get PCD value's size for POINTER type PCD. + + The POINTER type PCD's value will be stored into a buffer in specificed size. + The max size of this PCD's value is described in PCD's definition in DEC file. + + @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table + @param MaxSize Maxmium size of PCD's value + @param Database Pcd database in PEI phase. + + @return PCD value's size for POINTER type PCD. + +**/ +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize, + IN PEI_PCD_DATABASE *Database + ); + +/** + Set PCD value's size for POINTER type PCD. + + The POINTER type PCD's value will be stored into a buffer in specificed size. + The max size of this PCD's value is described in PCD's definition in DEC file. + + @param LocalTokenNumberTableIdx Index of PCD token number in PCD token table + @param CurrentSize Maxmium size of PCD's value + @param Database Pcd database in PEI phase. + + @retval TRUE Success to set PCD's value size, which is not exceed maxmium size + @retval FALSE Fail to set PCD's value size, which maybe exceed maxmium size + +**/ +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize, + IN PEI_PCD_DATABASE *Database + ); + +#endif + -- cgit v1.2.3