diff options
Diffstat (limited to 'MdeModulePkg/Universal/PCD')
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Dxe/Pcd.c | 2778 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Dxe/Pcd.inf | 698 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Dxe/PcdDxe.uni | 582 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Dxe/PcdDxeExtra.uni | 28 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Dxe/Service.c | 3846 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Dxe/Service.h | 2386 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Pei/Pcd.c | 3508 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Pei/Pcd.inf | 702 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni | 580 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni | 28 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Pei/Service.c | 2162 | ||||
| -rw-r--r-- | MdeModulePkg/Universal/PCD/Pei/Service.h | 2164 |
12 files changed, 9731 insertions, 9731 deletions
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c index 855ba3cceb..1295e024da 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c @@ -1,1389 +1,1389 @@ -/** @file
- PCD DXE driver manage all PCD entry initialized in PEI phase and DXE phase, and
- produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in
- PI 1.4a Vol3.
-
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Service.h"
-
-///
-/// PCD database lock.
-///
-EFI_LOCK mPcdDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
-
-///
-/// PCD_PROTOCOL the EDKII native implementation which support dynamic
-/// type and dynamicEx type PCDs.
-///
-PCD_PROTOCOL mPcdInstance = {
- DxePcdSetSku,
-
- DxePcdGet8,
- DxePcdGet16,
- DxePcdGet32,
- DxePcdGet64,
- DxePcdGetPtr,
- DxePcdGetBool,
- DxePcdGetSize,
-
- DxePcdGet8Ex,
- DxePcdGet16Ex,
- DxePcdGet32Ex,
- DxePcdGet64Ex,
- DxePcdGetPtrEx,
- DxePcdGetBoolEx,
- DxePcdGetSizeEx,
-
- DxePcdSet8,
- DxePcdSet16,
- DxePcdSet32,
- DxePcdSet64,
- DxePcdSetPtr,
- DxePcdSetBool,
-
- DxePcdSet8Ex,
- DxePcdSet16Ex,
- DxePcdSet32Ex,
- DxePcdSet64Ex,
- DxePcdSetPtrEx,
- DxePcdSetBoolEx,
-
- DxeRegisterCallBackOnSet,
- DxeUnRegisterCallBackOnSet,
- DxePcdGetNextToken,
- DxePcdGetNextTokenSpace
-};
-
-///
-/// EFI_PCD_PROTOCOL is defined in PI 1.2 Vol 3 which only support dynamicEx type
-/// PCD.
-///
-EFI_PCD_PROTOCOL mEfiPcdInstance = {
- DxePcdSetSku,
- DxePcdGet8Ex,
- DxePcdGet16Ex,
- DxePcdGet32Ex,
- DxePcdGet64Ex,
- DxePcdGetPtrEx,
- DxePcdGetBoolEx,
- DxePcdGetSizeEx,
- DxePcdSet8Ex,
- DxePcdSet16Ex,
- DxePcdSet32Ex,
- DxePcdSet64Ex,
- DxePcdSetPtrEx,
- DxePcdSetBoolEx,
- (EFI_PCD_PROTOCOL_CALLBACK_ON_SET)DxeRegisterCallBackOnSet,
- (EFI_PCD_PROTOCOL_CANCEL_CALLBACK)DxeUnRegisterCallBackOnSet,
- DxePcdGetNextToken,
- DxePcdGetNextTokenSpace
-};
-
-///
-/// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementation.
-/// This protocol instance support dynamic and dynamicEx type PCDs.
-///
-GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance = {
- DxeGetPcdInfoGetInfo,
- DxeGetPcdInfoGetInfoEx,
- DxeGetPcdInfoGetSku
-};
-
-///
-/// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol 3.
-/// This PPI instance only support dyanmicEx type PCD.
-///
-EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance = {
- DxeGetPcdInfoGetInfoEx,
- DxeGetPcdInfoGetSku
-};
-
-EFI_HANDLE mPcdHandle = NULL;
-UINTN mVpdBaseAddress = 0;
-
-/**
- Main entry for PCD DXE driver.
-
- This routine initialize the PCD database and install PCD_PROTOCOL.
-
- @param ImageHandle Image handle for PCD DXE driver.
- @param SystemTable Pointer to SystemTable.
-
- @return Status of gBS->InstallProtocolInterface()
-
-**/
-EFI_STATUS
-EFIAPI
-PcdDxeInit (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- VOID *Registration;
-
- //
- // Make sure the Pcd Protocol is not already installed in the system
- //
-
- ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid);
-
- BuildPcdDxeDataBase ();
-
- //
- // Install PCD_PROTOCOL to handle dynamic type PCD
- // Install EFI_PCD_PROTOCOL to handle dynamicEx type PCD
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &mPcdHandle,
- &gPcdProtocolGuid,
- &mPcdInstance,
- &gEfiPcdProtocolGuid,
- &mEfiPcdInstance,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD
- // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &mPcdHandle,
- &gGetPcdInfoProtocolGuid,
- &mGetPcdInfoInstance,
- &gEfiGetPcdInfoProtocolGuid,
- &mEfiGetPcdInfoInstance,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Register callback function upon VariableLockProtocol
- // to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.
- //
- EfiCreateProtocolNotifyEvent (
- &gEdkiiVariableLockProtocolGuid,
- TPL_CALLBACK,
- VariableLockCallBack,
- NULL,
- &Registration
- );
-
- //
- // Cache VpdBaseAddress in entry point for the following usage.
- //
-
- //
- // PcdVpdBaseAddress64 is DynamicEx PCD only. So, DxePcdGet64Ex() is used to get its value.
- //
- mVpdBaseAddress = (UINTN)DxePcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdVpdBaseAddress64));
- if (mVpdBaseAddress == 0) {
- //
- // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress.
- //
- mVpdBaseAddress = (UINTN)PcdGet32 (PcdVpdBaseAddress);
- }
-
- 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
-DxeGetPcdInfoGetInfo (
- IN UINTN TokenNumber,
- OUT EFI_PCD_INFO *PcdInfo
- )
-{
- return DxeGetPcdInfo (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
-DxeGetPcdInfoGetInfoEx (
- IN CONST EFI_GUID *Guid,
- IN UINTN TokenNumber,
- OUT EFI_PCD_INFO *PcdInfo
- )
-{
- return DxeGetPcdInfo (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
-DxeGetPcdInfoGetSku (
- VOID
- )
-{
- return (UINTN)mPcdDatabase.DxeDb->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
-DxePcdSetSku (
- IN UINTN SkuId
- )
-{
- SKU_ID *SkuIdTable;
- UINTN Index;
- EFI_STATUS Status;
-
- DEBUG ((DEBUG_INFO, "PcdDxe - SkuId 0x%lx is to be set.\n", (SKU_ID)SkuId));
-
- if (SkuId == mPcdDatabase.DxeDb->SystemSkuId) {
- //
- // The input SKU Id is equal to current SKU Id, return directly.
- //
- DEBUG ((DEBUG_INFO, "PcdDxe - SkuId is same to current system Sku.\n"));
- return;
- }
-
- if (mPcdDatabase.DxeDb->SystemSkuId != (SKU_ID)0) {
- DEBUG ((DEBUG_ERROR, "PcdDxe - The SKU Id could be changed only once."));
- DEBUG ((
- DEBUG_ERROR,
- "PcdDxe - The SKU Id was set to 0x%lx already, it could not be set to 0x%lx any more.",
- mPcdDatabase.DxeDb->SystemSkuId,
- (SKU_ID)SkuId
- ));
- ASSERT (FALSE);
- return;
- }
-
- SkuIdTable = (SKU_ID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SkuIdTableOffset);
- for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuId == SkuIdTable[Index + 1]) {
- DEBUG ((DEBUG_INFO, "PcdDxe - SkuId is found in SkuId table.\n"));
- Status = UpdatePcdDatabase (SkuId, TRUE);
- if (!EFI_ERROR (Status)) {
- mPcdDatabase.DxeDb->SystemSkuId = (SKU_ID)SkuId;
- DEBUG ((DEBUG_INFO, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID)SkuId));
- return;
- }
- }
- }
-
- //
- // Invalid input SkuId, the default SKU Id will be still used for the system.
- //
- DEBUG ((DEBUG_ERROR, "PcdDxe - 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
-DxePcdGet8 (
- 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
-DxePcdGet16 (
- 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
-DxePcdGet32 (
- 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
-DxePcdGet64 (
- 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 retrived.
-
-**/
-VOID *
-EFIAPI
-DxePcdGetPtr (
- 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
-DxePcdGetBool (
- 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
-DxePcdGetSize (
- IN UINTN TokenNumber
- )
-{
- UINTN Size;
- UINT32 *LocalTokenNumberTable;
- BOOLEAN IsPeiDb;
- UINTN MaxSize;
- UINTN TmpTokenNumber;
-
- //
- // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
- // We have to decrement TokenNumber by 1 to make it usable
- // as the array index.
- //
- TokenNumber--;
-
- //
- // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
- //
- TmpTokenNumber = TokenNumber;
-
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
-
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- IsPeiDb = (BOOLEAN)(TokenNumber + 1 < mPeiLocalTokenCount + 1);
-
- TokenNumber = IsPeiDb ? TokenNumber :
- (TokenNumber - mPeiLocalTokenCount);
-
- LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset)
- : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
-
- Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
-
- if (Size == 0) {
- //
- // For pointer type, we need to scan the SIZE_TABLE to get the current size.
- //
- return GetPtrTypeSize (TmpTokenNumber, &MaxSize);
- } else {
- return Size;
- }
-}
-
-/**
- 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
-DxePcdGet8Ex (
- 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
-DxePcdGet16Ex (
- 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
-DxePcdGet32Ex (
- 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
-DxePcdGet64Ex (
- 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 retrived.
-
-**/
-VOID *
-EFIAPI
-DxePcdGetPtrEx (
- 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
-DxePcdGetBoolEx (
- 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
-DxePcdGetSizeEx (
- IN CONST EFI_GUID *Guid,
- IN UINTN ExTokenNumber
- )
-{
- return DxePcdGetSize (GetExPcdTokenNumber (Guid, (UINT32)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
-DxePcdSet8 (
- 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
-DxePcdSet16 (
- 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
-DxePcdSet32 (
- 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
-DxePcdSet64 (
- 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
-DxePcdSetPtr (
- 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
-DxePcdSetBool (
- 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
-DxePcdSet8Ex (
- 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
-DxePcdSet16Ex (
- IN CONST EFI_GUID *Guid,
- IN UINTN ExTokenNumber,
- IN UINT16 Value
- )
-{
- //
- // PcdSetNvStoreDefaultId should be set in PEI phase to take effect.
- //
- ASSERT (
- !(CompareGuid (Guid, &gEfiMdeModulePkgTokenSpaceGuid) &&
- (ExTokenNumber == PcdToken (PcdSetNvStoreDefaultId)))
- );
- 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
-DxePcdSet32Ex (
- 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
-DxePcdSet64Ex (
- 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] 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
-DxePcdSetPtrEx (
- IN CONST EFI_GUID *Guid,
- IN UINTN ExTokenNumber,
- IN OUT UINTN *SizeOfBuffer,
- IN VOID *Buffer
- )
-{
- return ExSetWorker (ExTokenNumber, Guid, 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] 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
-DxePcdSetBoolEx (
- 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] 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
-DxeRegisterCallBackOnSet (
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN UINTN TokenNumber,
- IN PCD_PROTOCOL_CALLBACK CallBackFunction
- )
-{
- EFI_STATUS Status;
-
- if (CallBackFunction == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Aquire lock to prevent reentrance from TPL_CALLBACK level
- //
- EfiAcquireLock (&mPcdDatabaseLock);
-
- Status = DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);
-
- EfiReleaseLock (&mPcdDatabaseLock);
-
- return Status;
-}
-
-/**
- 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
-DxeUnRegisterCallBackOnSet (
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN UINTN TokenNumber,
- IN PCD_PROTOCOL_CALLBACK CallBackFunction
- )
-{
- EFI_STATUS Status;
-
- if (CallBackFunction == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Aquire lock to prevent reentrance from TPL_CALLBACK level
- //
- EfiAcquireLock (&mPcdDatabaseLock);
-
- Status = DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction);
-
- EfiReleaseLock (&mPcdDatabaseLock);
-
- return Status;
-}
-
-/**
- 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 retrieve the next token.
- 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
-DxePcdGetNextToken (
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN OUT UINTN *TokenNumber
- )
-{
- EFI_STATUS Status;
- BOOLEAN PeiExMapTableEmpty;
- BOOLEAN DxeExMapTableEmpty;
-
- Status = EFI_NOT_FOUND;
- PeiExMapTableEmpty = mPeiExMapTableEmpty;
- DxeExMapTableEmpty = mDxeExMapTableEmpty;
-
- //
- // Scan the local token space
- //
- if (Guid == NULL) {
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- if (((*TokenNumber + 1 > mPeiNexTokenCount + 1) && (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||
- ((*TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1))))
- {
- return EFI_NOT_FOUND;
- }
-
- (*TokenNumber)++;
- if ((*TokenNumber + 1 > mPeiNexTokenCount + 1) &&
- (*TokenNumber + 1 <= mPeiLocalTokenCount + 1))
- {
- //
- // The first Non-Ex type Token Number for DXE PCD
- // database is mPeiLocalTokenCount + 1
- //
- if (mDxeNexTokenCount > 0) {
- *TokenNumber = mPeiLocalTokenCount + 1;
- } else {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_NOT_FOUND;
- }
- } else if (*TokenNumber + 1 > mDxeNexTokenCount + mPeiLocalTokenCount + 1) {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_NOT_FOUND;
- }
-
- return EFI_SUCCESS;
- }
-
- if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
- return EFI_NOT_FOUND;
- }
-
- if (!PeiExMapTableEmpty) {
- Status = ExGetNextTokeNumber (
- Guid,
- TokenNumber,
- (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset),
- mPeiGuidTableSize,
- (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),
- mPeiExMapppingTableSize
- );
- }
-
- if (Status == EFI_SUCCESS) {
- return Status;
- }
-
- if (!DxeExMapTableEmpty) {
- Status = ExGetNextTokeNumber (
- Guid,
- TokenNumber,
- (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset),
- mDxeGuidTableSize,
- (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),
- mDxeExMapppingTableSize
- );
- }
-
- return Status;
-}
-
-/**
- Get all token space guid table which is different with given token space guid.
-
- @param ExMapTableSize The size of ExMapTable in item
- @param ExMapTable Token space guid table that want to be scaned.
- @param GuidTable Guid table
-
- @return all token space guid table which is different with given token space guid.
-
-**/
-EFI_GUID **
-GetDistinctTokenSpace (
- IN OUT UINTN *ExMapTableSize,
- IN DYNAMICEX_MAPPING *ExMapTable,
- IN EFI_GUID *GuidTable
- )
-{
- EFI_GUID **DistinctTokenSpace;
- UINTN OldGuidIndex;
- UINTN TsIdx;
- UINTN TempTsIdx;
- UINTN Idx;
- BOOLEAN Match;
-
- DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *));
- ASSERT (DistinctTokenSpace != NULL);
-
- TsIdx = 0;
- OldGuidIndex = ExMapTable[0].ExGuidIndex;
- DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex];
- for (Idx = 1; Idx < *ExMapTableSize; Idx++) {
- Match = FALSE;
- OldGuidIndex = ExMapTable[Idx].ExGuidIndex;
- for (TempTsIdx = 0; TempTsIdx <= TsIdx; TempTsIdx++) {
- if (&GuidTable[OldGuidIndex] == DistinctTokenSpace[TempTsIdx]) {
- //
- // Have recorded this GUID.
- //
- Match = TRUE;
- break;
- }
- }
-
- if (!Match) {
- DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex];
- }
- }
-
- //
- // The total number of Distinct Token Space
- // is TsIdx + 1 because we use TsIdx as a index
- // to the DistinctTokenSpace[]
- //
- *ExMapTableSize = TsIdx + 1;
- return DistinctTokenSpace;
-}
-
-/**
- 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
-DxePcdGetNextTokenSpace (
- IN OUT CONST EFI_GUID **Guid
- )
-{
- UINTN Idx;
- UINTN Idx2;
- UINTN Idx3;
- UINTN PeiTokenSpaceTableSize;
- UINTN DxeTokenSpaceTableSize;
- EFI_GUID **PeiTokenSpaceTable;
- EFI_GUID **DxeTokenSpaceTable;
- BOOLEAN Match;
- BOOLEAN PeiExMapTableEmpty;
- BOOLEAN DxeExMapTableEmpty;
-
- ASSERT (Guid != NULL);
-
- PeiExMapTableEmpty = mPeiExMapTableEmpty;
- DxeExMapTableEmpty = mDxeExMapTableEmpty;
-
- if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
- return EFI_NOT_FOUND;
- }
-
- if (TmpTokenSpaceBuffer[0] == NULL) {
- PeiTokenSpaceTableSize = 0;
-
- if (!PeiExMapTableEmpty) {
- PeiTokenSpaceTableSize = mPeiExMapppingTableSize / sizeof (DYNAMICEX_MAPPING);
- PeiTokenSpaceTable = GetDistinctTokenSpace (
- &PeiTokenSpaceTableSize,
- (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),
- (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset)
- );
- CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID *) * PeiTokenSpaceTableSize);
- TmpTokenSpaceBufferCount = PeiTokenSpaceTableSize;
- FreePool (PeiTokenSpaceTable);
- }
-
- if (!DxeExMapTableEmpty) {
- DxeTokenSpaceTableSize = mDxeExMapppingTableSize / sizeof (DYNAMICEX_MAPPING);
- DxeTokenSpaceTable = GetDistinctTokenSpace (
- &DxeTokenSpaceTableSize,
- (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),
- (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset)
- );
-
- //
- // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
- //
- for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) {
- Match = FALSE;
- for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) {
- if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) {
- Match = TRUE;
- break;
- }
- }
-
- if (!Match) {
- TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2];
- }
- }
-
- TmpTokenSpaceBufferCount = Idx3;
- FreePool (DxeTokenSpaceTable);
- }
- }
-
- if (*Guid == NULL) {
- *Guid = TmpTokenSpaceBuffer[0];
- return EFI_SUCCESS;
- }
-
- for (Idx = 0; Idx < TmpTokenSpaceBufferCount; Idx++) {
- if (CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {
- if (Idx == TmpTokenSpaceBufferCount - 1) {
- //
- // It has been the last token namespace.
- //
- *Guid = NULL;
- return EFI_NOT_FOUND;
- } else {
- Idx++;
- *Guid = TmpTokenSpaceBuffer[Idx];
- return EFI_SUCCESS;
- }
- }
- }
-
- return EFI_NOT_FOUND;
-}
+/** @file + PCD DXE driver manage all PCD entry initialized in PEI phase and DXE phase, and + produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in + PI 1.4a Vol3. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Service.h" + +/// +/// PCD database lock. +/// +EFI_LOCK mPcdDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); + +/// +/// PCD_PROTOCOL the EDKII native implementation which support dynamic +/// type and dynamicEx type PCDs. +/// +PCD_PROTOCOL mPcdInstance = { + DxePcdSetSku, + + DxePcdGet8, + DxePcdGet16, + DxePcdGet32, + DxePcdGet64, + DxePcdGetPtr, + DxePcdGetBool, + DxePcdGetSize, + + DxePcdGet8Ex, + DxePcdGet16Ex, + DxePcdGet32Ex, + DxePcdGet64Ex, + DxePcdGetPtrEx, + DxePcdGetBoolEx, + DxePcdGetSizeEx, + + DxePcdSet8, + DxePcdSet16, + DxePcdSet32, + DxePcdSet64, + DxePcdSetPtr, + DxePcdSetBool, + + DxePcdSet8Ex, + DxePcdSet16Ex, + DxePcdSet32Ex, + DxePcdSet64Ex, + DxePcdSetPtrEx, + DxePcdSetBoolEx, + + DxeRegisterCallBackOnSet, + DxeUnRegisterCallBackOnSet, + DxePcdGetNextToken, + DxePcdGetNextTokenSpace +}; + +/// +/// EFI_PCD_PROTOCOL is defined in PI 1.2 Vol 3 which only support dynamicEx type +/// PCD. +/// +EFI_PCD_PROTOCOL mEfiPcdInstance = { + DxePcdSetSku, + DxePcdGet8Ex, + DxePcdGet16Ex, + DxePcdGet32Ex, + DxePcdGet64Ex, + DxePcdGetPtrEx, + DxePcdGetBoolEx, + DxePcdGetSizeEx, + DxePcdSet8Ex, + DxePcdSet16Ex, + DxePcdSet32Ex, + DxePcdSet64Ex, + DxePcdSetPtrEx, + DxePcdSetBoolEx, + (EFI_PCD_PROTOCOL_CALLBACK_ON_SET)DxeRegisterCallBackOnSet, + (EFI_PCD_PROTOCOL_CANCEL_CALLBACK)DxeUnRegisterCallBackOnSet, + DxePcdGetNextToken, + DxePcdGetNextTokenSpace +}; + +/// +/// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementation. +/// This protocol instance support dynamic and dynamicEx type PCDs. +/// +GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance = { + DxeGetPcdInfoGetInfo, + DxeGetPcdInfoGetInfoEx, + DxeGetPcdInfoGetSku +}; + +/// +/// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol 3. +/// This PPI instance only support dyanmicEx type PCD. +/// +EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance = { + DxeGetPcdInfoGetInfoEx, + DxeGetPcdInfoGetSku +}; + +EFI_HANDLE mPcdHandle = NULL; +UINTN mVpdBaseAddress = 0; + +/** + Main entry for PCD DXE driver. + + This routine initialize the PCD database and install PCD_PROTOCOL. + + @param ImageHandle Image handle for PCD DXE driver. + @param SystemTable Pointer to SystemTable. + + @return Status of gBS->InstallProtocolInterface() + +**/ +EFI_STATUS +EFIAPI +PcdDxeInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + VOID *Registration; + + // + // Make sure the Pcd Protocol is not already installed in the system + // + + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid); + + BuildPcdDxeDataBase (); + + // + // Install PCD_PROTOCOL to handle dynamic type PCD + // Install EFI_PCD_PROTOCOL to handle dynamicEx type PCD + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mPcdHandle, + &gPcdProtocolGuid, + &mPcdInstance, + &gEfiPcdProtocolGuid, + &mEfiPcdInstance, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD + // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mPcdHandle, + &gGetPcdInfoProtocolGuid, + &mGetPcdInfoInstance, + &gEfiGetPcdInfoProtocolGuid, + &mEfiGetPcdInfoInstance, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Register callback function upon VariableLockProtocol + // to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc. + // + EfiCreateProtocolNotifyEvent ( + &gEdkiiVariableLockProtocolGuid, + TPL_CALLBACK, + VariableLockCallBack, + NULL, + &Registration + ); + + // + // Cache VpdBaseAddress in entry point for the following usage. + // + + // + // PcdVpdBaseAddress64 is DynamicEx PCD only. So, DxePcdGet64Ex() is used to get its value. + // + mVpdBaseAddress = (UINTN)DxePcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdVpdBaseAddress64)); + if (mVpdBaseAddress == 0) { + // + // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress. + // + mVpdBaseAddress = (UINTN)PcdGet32 (PcdVpdBaseAddress); + } + + 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 +DxeGetPcdInfoGetInfo ( + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + return DxeGetPcdInfo (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 +DxeGetPcdInfoGetInfoEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + return DxeGetPcdInfo (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 +DxeGetPcdInfoGetSku ( + VOID + ) +{ + return (UINTN)mPcdDatabase.DxeDb->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 +DxePcdSetSku ( + IN UINTN SkuId + ) +{ + SKU_ID *SkuIdTable; + UINTN Index; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "PcdDxe - SkuId 0x%lx is to be set.\n", (SKU_ID)SkuId)); + + if (SkuId == mPcdDatabase.DxeDb->SystemSkuId) { + // + // The input SKU Id is equal to current SKU Id, return directly. + // + DEBUG ((DEBUG_INFO, "PcdDxe - SkuId is same to current system Sku.\n")); + return; + } + + if (mPcdDatabase.DxeDb->SystemSkuId != (SKU_ID)0) { + DEBUG ((DEBUG_ERROR, "PcdDxe - The SKU Id could be changed only once.")); + DEBUG (( + DEBUG_ERROR, + "PcdDxe - The SKU Id was set to 0x%lx already, it could not be set to 0x%lx any more.", + mPcdDatabase.DxeDb->SystemSkuId, + (SKU_ID)SkuId + )); + ASSERT (FALSE); + return; + } + + SkuIdTable = (SKU_ID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SkuIdTableOffset); + for (Index = 0; Index < SkuIdTable[0]; Index++) { + if (SkuId == SkuIdTable[Index + 1]) { + DEBUG ((DEBUG_INFO, "PcdDxe - SkuId is found in SkuId table.\n")); + Status = UpdatePcdDatabase (SkuId, TRUE); + if (!EFI_ERROR (Status)) { + mPcdDatabase.DxeDb->SystemSkuId = (SKU_ID)SkuId; + DEBUG ((DEBUG_INFO, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID)SkuId)); + return; + } + } + } + + // + // Invalid input SkuId, the default SKU Id will be still used for the system. + // + DEBUG ((DEBUG_ERROR, "PcdDxe - 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 +DxePcdGet8 ( + 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 +DxePcdGet16 ( + 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 +DxePcdGet32 ( + 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 +DxePcdGet64 ( + 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 retrived. + +**/ +VOID * +EFIAPI +DxePcdGetPtr ( + 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 +DxePcdGetBool ( + 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 +DxePcdGetSize ( + IN UINTN TokenNumber + ) +{ + UINTN Size; + UINT32 *LocalTokenNumberTable; + BOOLEAN IsPeiDb; + UINTN MaxSize; + UINTN TmpTokenNumber; + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + // + // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber + // + TmpTokenNumber = TokenNumber; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1); + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN)(TokenNumber + 1 < mPeiLocalTokenCount + 1); + + TokenNumber = IsPeiDb ? TokenNumber : + (TokenNumber - mPeiLocalTokenCount); + + LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) + : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset); + + Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT; + + if (Size == 0) { + // + // For pointer type, we need to scan the SIZE_TABLE to get the current size. + // + return GetPtrTypeSize (TmpTokenNumber, &MaxSize); + } else { + return Size; + } +} + +/** + 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 +DxePcdGet8Ex ( + 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 +DxePcdGet16Ex ( + 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 +DxePcdGet32Ex ( + 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 +DxePcdGet64Ex ( + 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 retrived. + +**/ +VOID * +EFIAPI +DxePcdGetPtrEx ( + 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 +DxePcdGetBoolEx ( + 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 +DxePcdGetSizeEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + return DxePcdGetSize (GetExPcdTokenNumber (Guid, (UINT32)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 +DxePcdSet8 ( + 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 +DxePcdSet16 ( + 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 +DxePcdSet32 ( + 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 +DxePcdSet64 ( + 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 +DxePcdSetPtr ( + 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 +DxePcdSetBool ( + 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 +DxePcdSet8Ex ( + 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 +DxePcdSet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT16 Value + ) +{ + // + // PcdSetNvStoreDefaultId should be set in PEI phase to take effect. + // + ASSERT ( + !(CompareGuid (Guid, &gEfiMdeModulePkgTokenSpaceGuid) && + (ExTokenNumber == PcdToken (PcdSetNvStoreDefaultId))) + ); + 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 +DxePcdSet32Ex ( + 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 +DxePcdSet64Ex ( + 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] 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 +DxePcdSetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +{ + return ExSetWorker (ExTokenNumber, Guid, 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] 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 +DxePcdSetBoolEx ( + 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] 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 +DxeRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +{ + EFI_STATUS Status; + + if (CallBackFunction == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + Status = DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction); + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; +} + +/** + 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 +DxeUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +{ + EFI_STATUS Status; + + if (CallBackFunction == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + Status = DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunction); + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; +} + +/** + 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 retrieve the next token. + 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 +DxePcdGetNextToken ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN OUT UINTN *TokenNumber + ) +{ + EFI_STATUS Status; + BOOLEAN PeiExMapTableEmpty; + BOOLEAN DxeExMapTableEmpty; + + Status = EFI_NOT_FOUND; + PeiExMapTableEmpty = mPeiExMapTableEmpty; + DxeExMapTableEmpty = mDxeExMapTableEmpty; + + // + // Scan the local token space + // + if (Guid == NULL) { + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + if (((*TokenNumber + 1 > mPeiNexTokenCount + 1) && (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) || + ((*TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) + { + return EFI_NOT_FOUND; + } + + (*TokenNumber)++; + if ((*TokenNumber + 1 > mPeiNexTokenCount + 1) && + (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) + { + // + // The first Non-Ex type Token Number for DXE PCD + // database is mPeiLocalTokenCount + 1 + // + if (mDxeNexTokenCount > 0) { + *TokenNumber = mPeiLocalTokenCount + 1; + } else { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } + } else if (*TokenNumber + 1 > mDxeNexTokenCount + mPeiLocalTokenCount + 1) { + *TokenNumber = PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; + } + + if (PeiExMapTableEmpty && DxeExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + if (!PeiExMapTableEmpty) { + Status = ExGetNextTokeNumber ( + Guid, + TokenNumber, + (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset), + mPeiGuidTableSize, + (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset), + mPeiExMapppingTableSize + ); + } + + if (Status == EFI_SUCCESS) { + return Status; + } + + if (!DxeExMapTableEmpty) { + Status = ExGetNextTokeNumber ( + Guid, + TokenNumber, + (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset), + mDxeGuidTableSize, + (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset), + mDxeExMapppingTableSize + ); + } + + return Status; +} + +/** + Get all token space guid table which is different with given token space guid. + + @param ExMapTableSize The size of ExMapTable in item + @param ExMapTable Token space guid table that want to be scaned. + @param GuidTable Guid table + + @return all token space guid table which is different with given token space guid. + +**/ +EFI_GUID ** +GetDistinctTokenSpace ( + IN OUT UINTN *ExMapTableSize, + IN DYNAMICEX_MAPPING *ExMapTable, + IN EFI_GUID *GuidTable + ) +{ + EFI_GUID **DistinctTokenSpace; + UINTN OldGuidIndex; + UINTN TsIdx; + UINTN TempTsIdx; + UINTN Idx; + BOOLEAN Match; + + DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *)); + ASSERT (DistinctTokenSpace != NULL); + + TsIdx = 0; + OldGuidIndex = ExMapTable[0].ExGuidIndex; + DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex]; + for (Idx = 1; Idx < *ExMapTableSize; Idx++) { + Match = FALSE; + OldGuidIndex = ExMapTable[Idx].ExGuidIndex; + for (TempTsIdx = 0; TempTsIdx <= TsIdx; TempTsIdx++) { + if (&GuidTable[OldGuidIndex] == DistinctTokenSpace[TempTsIdx]) { + // + // Have recorded this GUID. + // + Match = TRUE; + break; + } + } + + if (!Match) { + DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex]; + } + } + + // + // The total number of Distinct Token Space + // is TsIdx + 1 because we use TsIdx as a index + // to the DistinctTokenSpace[] + // + *ExMapTableSize = TsIdx + 1; + return DistinctTokenSpace; +} + +/** + 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 +DxePcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ) +{ + UINTN Idx; + UINTN Idx2; + UINTN Idx3; + UINTN PeiTokenSpaceTableSize; + UINTN DxeTokenSpaceTableSize; + EFI_GUID **PeiTokenSpaceTable; + EFI_GUID **DxeTokenSpaceTable; + BOOLEAN Match; + BOOLEAN PeiExMapTableEmpty; + BOOLEAN DxeExMapTableEmpty; + + ASSERT (Guid != NULL); + + PeiExMapTableEmpty = mPeiExMapTableEmpty; + DxeExMapTableEmpty = mDxeExMapTableEmpty; + + if (PeiExMapTableEmpty && DxeExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + if (TmpTokenSpaceBuffer[0] == NULL) { + PeiTokenSpaceTableSize = 0; + + if (!PeiExMapTableEmpty) { + PeiTokenSpaceTableSize = mPeiExMapppingTableSize / sizeof (DYNAMICEX_MAPPING); + PeiTokenSpaceTable = GetDistinctTokenSpace ( + &PeiTokenSpaceTableSize, + (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset), + (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset) + ); + CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID *) * PeiTokenSpaceTableSize); + TmpTokenSpaceBufferCount = PeiTokenSpaceTableSize; + FreePool (PeiTokenSpaceTable); + } + + if (!DxeExMapTableEmpty) { + DxeTokenSpaceTableSize = mDxeExMapppingTableSize / sizeof (DYNAMICEX_MAPPING); + DxeTokenSpaceTable = GetDistinctTokenSpace ( + &DxeTokenSpaceTableSize, + (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset), + (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset) + ); + + // + // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable + // + for (Idx2 = 0, Idx3 = PeiTokenSpaceTableSize; Idx2 < DxeTokenSpaceTableSize; Idx2++) { + Match = FALSE; + for (Idx = 0; Idx < PeiTokenSpaceTableSize; Idx++) { + if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Idx2])) { + Match = TRUE; + break; + } + } + + if (!Match) { + TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2]; + } + } + + TmpTokenSpaceBufferCount = Idx3; + FreePool (DxeTokenSpaceTable); + } + } + + if (*Guid == NULL) { + *Guid = TmpTokenSpaceBuffer[0]; + return EFI_SUCCESS; + } + + for (Idx = 0; Idx < TmpTokenSpaceBufferCount; Idx++) { + if (CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) { + if (Idx == TmpTokenSpaceBufferCount - 1) { + // + // It has been the last token namespace. + // + *Guid = NULL; + return EFI_NOT_FOUND; + } else { + Idx++; + *Guid = TmpTokenSpaceBuffer[Idx]; + return EFI_SUCCESS; + } + } + } + + return EFI_NOT_FOUND; +} diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf index eb9f757f14..c4112296e1 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf +++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf @@ -1,349 +1,349 @@ -## @file
-# PCD DXE driver manage database contains all dynamic PCD entries and produce the implementation of PCD protocol.
-#
-# This version PCD DXE depends on the external PCD database binary file, not built in PCD data base.
-# There are two PCD Protocols as follows:
-# 1) PCD_PROTOCOL
-# It is EDKII implementation which support Dynamic/DynamicEx type Pcds.
-# 2) EFI_PCD_PROTOCOL
-# 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_PROTOCOL and EFI_PCD_PROTOCOL.
-# PCD DXE driver will produce above two protocols 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 PCD setting - PcdVpdBaseAddress64 or 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_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 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = PcdDxe
- MODULE_UNI_FILE = PcdDxe.uni
- FILE_GUID = 80CF7257-87AB-47f9-A3FE-D50B76D89541
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 4.0
- PCD_IS_DRIVER = DXE_PCD_DRIVER
- ENTRY_POINT = PcdDxeInit
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64 EBC
-#
-
-[Sources]
- Pcd.c
- Service.c
- Service.h
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- UefiRuntimeServicesTableLib
- BaseMemoryLib
- UefiBootServicesTableLib
- MemoryAllocationLib
- HobLib
- UefiDriverEntryPoint
- UefiLib
- DebugLib
- BaseLib
- PcdLib
- DxeServicesLib
-
-[Guids]
- gPcdDataBaseHobGuid ## SOMETIMES_CONSUMES ## HOB
- gPcdDataBaseSignatureGuid ## CONSUMES ## GUID # PCD database signature GUID.
- gEfiMdeModulePkgTokenSpaceGuid ## SOMETIMES_CONSUMES ## GUID
-
-[Protocols]
- gPcdProtocolGuid ## PRODUCES
- gEfiPcdProtocolGuid ## PRODUCES
- gGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES
- gEfiGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES
- ## NOTIFY
- ## SOMETIMES_CONSUMES
- gEdkiiVariableLockProtocolGuid
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress64 ## SOMETIMES_CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdSetNvStoreDefaultId ## SOMETIMES_CONSUMES
-
-[Depex]
- TRUE
-
-[UserExtensions.TianoCore."ExtraFiles"]
- PcdDxeExtra.uni
+## @file +# PCD DXE driver manage database contains all dynamic PCD entries and produce the implementation of PCD protocol. +# +# This version PCD DXE depends on the external PCD database binary file, not built in PCD data base. +# There are two PCD Protocols as follows: +# 1) PCD_PROTOCOL +# It is EDKII implementation which support Dynamic/DynamicEx type Pcds. +# 2) EFI_PCD_PROTOCOL +# 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_PROTOCOL and EFI_PCD_PROTOCOL. +# PCD DXE driver will produce above two protocols 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 PCD setting - PcdVpdBaseAddress64 or 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_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 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PcdDxe + MODULE_UNI_FILE = PcdDxe.uni + FILE_GUID = 80CF7257-87AB-47f9-A3FE-D50B76D89541 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 4.0 + PCD_IS_DRIVER = DXE_PCD_DRIVER + ENTRY_POINT = PcdDxeInit + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + Pcd.c + Service.c + Service.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiRuntimeServicesTableLib + BaseMemoryLib + UefiBootServicesTableLib + MemoryAllocationLib + HobLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + PcdLib + DxeServicesLib + +[Guids] + gPcdDataBaseHobGuid ## SOMETIMES_CONSUMES ## HOB + gPcdDataBaseSignatureGuid ## CONSUMES ## GUID # PCD database signature GUID. + gEfiMdeModulePkgTokenSpaceGuid ## SOMETIMES_CONSUMES ## GUID + +[Protocols] + gPcdProtocolGuid ## PRODUCES + gEfiPcdProtocolGuid ## PRODUCES + gGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES + gEfiGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES + ## NOTIFY + ## SOMETIMES_CONSUMES + gEdkiiVariableLockProtocolGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress64 ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNvStoreDefaultId ## SOMETIMES_CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + PcdDxeExtra.uni diff --git a/MdeModulePkg/Universal/PCD/Dxe/PcdDxe.uni b/MdeModulePkg/Universal/PCD/Dxe/PcdDxe.uni index 6a3b3db4c6..9a47712d06 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/PcdDxe.uni +++ b/MdeModulePkg/Universal/PCD/Dxe/PcdDxe.uni @@ -1,291 +1,291 @@ -// /** @file
-// PCD DXE driver manage database contains all dynamic PCD entries and produce the implementation of PCD protocol.
-//
-// This version PCD DXE depends on the external PCD database binary file, not built in PCD data base.
-// There are two PCD Protocols as follows:
-// 1) PCD_PROTOCOL
-// It is EDKII implementation which support Dynamic/DynamicEx type Pcds.
-// 2) EFI_PCD_PROTOCOL
-// 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_PROTOCOL and EFI_PCD_PROTOCOL.
-// PCD DXE driver will produce above two protocols 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_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 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "PCD DXE driver manages the database that contains all dynamic PCD entries and produce the implementation of PCD protocol"
-
-#string STR_MODULE_DESCRIPTION #language en-US "PCD DXE driver manages the database that contains all dynamic PCD entries and produces the implementation of PCD protocol."
-
+// /** @file +// PCD DXE driver manage database contains all dynamic PCD entries and produce the implementation of PCD protocol. +// +// This version PCD DXE depends on the external PCD database binary file, not built in PCD data base. +// There are two PCD Protocols as follows: +// 1) PCD_PROTOCOL +// It is EDKII implementation which support Dynamic/DynamicEx type Pcds. +// 2) EFI_PCD_PROTOCOL +// 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_PROTOCOL and EFI_PCD_PROTOCOL. +// PCD DXE driver will produce above two protocols 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_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 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "PCD DXE driver manages the database that contains all dynamic PCD entries and produce the implementation of PCD protocol" + +#string STR_MODULE_DESCRIPTION #language en-US "PCD DXE driver manages the database that contains all dynamic PCD entries and produces the implementation of PCD protocol." + diff --git a/MdeModulePkg/Universal/PCD/Dxe/PcdDxeExtra.uni b/MdeModulePkg/Universal/PCD/Dxe/PcdDxeExtra.uni index b9d12be63e..01c7705280 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/PcdDxeExtra.uni +++ b/MdeModulePkg/Universal/PCD/Dxe/PcdDxeExtra.uni @@ -1,14 +1,14 @@ -// /** @file
-// PcdDxe Localized Strings and Content
-//
-// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_PROPERTIES_MODULE_NAME
-#language en-US
-"Platform Configuration Database DXE Driver"
-
-
+// /** @file +// PcdDxe Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Platform Configuration Database DXE Driver" + + diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c index 1ae06a639c..7b391dcd52 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Service.c +++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c @@ -1,1923 +1,1923 @@ -/** @file
- Help functions used by PCD DXE driver.
-
-Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-(C) Copyright 2016-2021 Hewlett Packard Enterprise Development LP<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Service.h"
-#include <Library/DxeServicesLib.h>
-
-PCD_DATABASE mPcdDatabase;
-
-UINT32 mPcdTotalTokenCount;
-UINT32 mPeiLocalTokenCount;
-UINT32 mDxeLocalTokenCount;
-UINT32 mPeiNexTokenCount;
-UINT32 mDxeNexTokenCount;
-UINT32 mPeiExMapppingTableSize;
-UINT32 mDxeExMapppingTableSize;
-UINT32 mPeiGuidTableSize;
-UINT32 mDxeGuidTableSize;
-
-BOOLEAN mPeiExMapTableEmpty;
-BOOLEAN mDxeExMapTableEmpty;
-BOOLEAN mPeiDatabaseEmpty;
-
-LIST_ENTRY *mCallbackFnTable;
-EFI_GUID **TmpTokenSpaceBuffer;
-UINTN TmpTokenSpaceBufferCount;
-
-UINTN mPeiPcdDbSize = 0;
-PEI_PCD_DATABASE *mPeiPcdDbBinary = NULL;
-UINTN mDxePcdDbSize = 0;
-DXE_PCD_DATABASE *mDxePcdDbBinary = NULL;
-
-/**
- Get Local Token Number by Token Number.
-
- @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
- If FALSE, the pcd entry is initialized in DXE phase.
- @param[in] TokenNumber The PCD token number.
-
- @return Local Token Number.
-**/
-UINT32
-GetLocalTokenNumber (
- IN BOOLEAN IsPeiDb,
- IN UINTN TokenNumber
- )
-{
- UINT32 *LocalTokenNumberTable;
-
- //
- // 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--;
-
- LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) :
- (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
- TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;
-
- return LocalTokenNumberTable[TokenNumber];
-}
-
-/**
- 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] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
- If FALSE, the pcd entry is initialized in DXE phase.
- @param[in] TokenNumber The PCD token number.
-
- @return The TokenSpaceCName or full PCD name.
-**/
-CHAR8 *
-GetPcdName (
- IN BOOLEAN OnlyTokenSpaceName,
- IN BOOLEAN IsPeiDb,
- IN UINTN TokenNumber
- )
-{
- PCD_DATABASE_INIT *Database;
- UINT8 *StringTable;
- UINTN NameSize;
- PCD_NAME_INDEX *PcdNameIndex;
- CHAR8 *TokenSpaceName;
- CHAR8 *PcdName;
- CHAR8 *Name;
-
- //
- // Return NULL when PCD name table is absent.
- //
- if (IsPeiDb) {
- if (mPcdDatabase.PeiDb->PcdNameTableOffset == 0) {
- return NULL;
- }
- } else {
- if (mPcdDatabase.DxeDb->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--;
-
- Database = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb;
- TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;
-
- 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] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
- If FALSE, the pcd entry is initialized in DXE phase.
- @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 BOOLEAN IsPeiDb,
- IN CONST EFI_GUID *Guid,
- IN UINTN TokenNumber,
- OUT EFI_PCD_INFO *PcdInfo
- )
-{
- PCD_DATABASE_INIT *Database;
- UINTN GuidTableIdx;
- EFI_GUID *MatchGuid;
- EFI_GUID *GuidTable;
- DYNAMICEX_MAPPING *ExMapTable;
- UINTN Index;
- UINT32 LocalTokenNumber;
-
- Database = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb;
-
- 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, IsPeiDb, ExMapTable[Index].TokenNumber);
- return EFI_SUCCESS;
- } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {
- PcdInfo->PcdSize = DxePcdGetSize (ExMapTable[Index].TokenNumber);
- LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, ExMapTable[Index].TokenNumber);
- PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
- PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, 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
-DxeGetPcdInfo (
- IN CONST EFI_GUID *Guid,
- IN UINTN TokenNumber,
- OUT EFI_PCD_INFO *PcdInfo
- )
-{
- EFI_STATUS Status;
- BOOLEAN PeiExMapTableEmpty;
- BOOLEAN DxeExMapTableEmpty;
- UINT32 LocalTokenNumber;
- BOOLEAN IsPeiDb;
-
- ASSERT (PcdInfo != NULL);
-
- Status = EFI_NOT_FOUND;
- PeiExMapTableEmpty = mPeiExMapTableEmpty;
- DxeExMapTableEmpty = mDxeExMapTableEmpty;
-
- if (Guid == NULL) {
- if (((TokenNumber + 1 > mPeiNexTokenCount + 1) && (TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||
- ((TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1))))
- {
- 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 = DxePcdGetSize (TokenNumber);
- IsPeiDb = FALSE;
- if ((TokenNumber + 1 <= mPeiNexTokenCount + 1)) {
- IsPeiDb = TRUE;
- }
-
- LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);
- PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
- PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, TokenNumber);
- }
-
- return EFI_SUCCESS;
- }
-
- if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
- return EFI_NOT_FOUND;
- }
-
- if (!PeiExMapTableEmpty) {
- Status = ExGetPcdInfo (
- TRUE,
- Guid,
- TokenNumber,
- PcdInfo
- );
- }
-
- if (Status == EFI_SUCCESS) {
- return Status;
- }
-
- if (!DxeExMapTableEmpty) {
- Status = ExGetPcdInfo (
- FALSE,
- Guid,
- TokenNumber,
- PcdInfo
- );
- }
-
- return Status;
-}
-
-/**
- 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
- )
-{
- EFI_GUID *GuidTable;
- UINT8 *StringTable;
- EFI_GUID *Guid;
- UINT16 *Name;
- VARIABLE_HEAD *VariableHead;
- UINT8 *VaraiableDefaultBuffer;
- UINT8 *Data;
- VPD_HEAD *VpdHead;
- UINT8 *PcdDb;
- VOID *RetPtr;
- UINTN TmpTokenNumber;
- UINTN DataSize;
- EFI_STATUS Status;
- UINT32 LocalTokenNumber;
- UINT32 Offset;
- STRING_HEAD StringTableIdx;
- BOOLEAN IsPeiDb;
-
- //
- // Aquire lock to prevent reentrance from TPL_CALLBACK level
- //
- EfiAcquireLock (&mPcdDatabaseLock);
-
- RetPtr = NULL;
-
- ASSERT (TokenNumber > 0);
- //
- // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
- // We have to decrement TokenNumber by 1 to make it usable
- // as the array index.
- //
- TokenNumber--;
-
- TmpTokenNumber = TokenNumber;
-
- //
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- //
- ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
-
- ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));
-
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- IsPeiDb = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
-
- LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);
-
- PcdDb = IsPeiDb ? ((UINT8 *)mPcdDatabase.PeiDb) : ((UINT8 *)mPcdDatabase.DxeDb);
-
- if (IsPeiDb) {
- StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);
- } else {
- StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);
- }
-
- Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
-
- switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
- case PCD_TYPE_VPD:
- VpdHead = (VPD_HEAD *)((UINT8 *)PcdDb + Offset);
- ASSERT (mVpdBaseAddress != 0);
- RetPtr = (VOID *)(mVpdBaseAddress + VpdHead->Offset);
-
- break;
-
- case PCD_TYPE_HII|PCD_TYPE_STRING:
- case PCD_TYPE_HII:
- if (IsPeiDb) {
- GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
- } else {
- GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
- }
-
- VariableHead = (VARIABLE_HEAD *)(PcdDb + Offset);
- Guid = GuidTable + 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.
- //
- StringTableIdx = *(STRING_HEAD *)((UINT8 *)PcdDb + VariableHead->DefaultValueOffset);
- VaraiableDefaultBuffer = (UINT8 *)(StringTable + StringTableIdx);
- } else {
- VaraiableDefaultBuffer = (UINT8 *)PcdDb + VariableHead->DefaultValueOffset;
- }
-
- Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
- if (Status == EFI_SUCCESS) {
- if (DataSize >= (VariableHead->Offset + GetSize)) {
- if (GetSize == 0) {
- //
- // It is a pointer type. So get the MaxSize reserved for
- // this PCD entry.
- //
- GetPtrTypeSize (TmpTokenNumber, &GetSize);
- 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.
- // So that we can free the Data allocated in GetHiiVariable.
- //
- CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
- }
-
- FreePool (Data);
- }
-
- RetPtr = (VOID *)VaraiableDefaultBuffer;
- break;
-
- case PCD_TYPE_STRING:
- StringTableIdx = *(STRING_HEAD *)((UINT8 *)PcdDb + Offset);
- RetPtr = (VOID *)(StringTable + StringTableIdx);
- break;
-
- case PCD_TYPE_DATA:
- RetPtr = (VOID *)((UINT8 *)PcdDb + Offset);
- break;
-
- default:
- ASSERT (FALSE);
- break;
- }
-
- EfiReleaseLock (&mPcdDatabaseLock);
-
- return RetPtr;
-}
-
-/**
- Register the callback function for a PCD entry.
-
- This routine will register a callback function to a PCD entry by given token number
- and token space guid.
-
- @param TokenNumber PCD token's number, it is autogened by build tools.
- @param Guid PCD token space's guid,
- if not NULL, this PCD is dynamicEx type PCD.
- @param CallBackFunction Callback function pointer
-
- @return EFI_SUCCESS Always success for registering callback function.
-
-**/
-EFI_STATUS
-DxeRegisterCallBackWorker (
- IN UINTN TokenNumber,
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN PCD_PROTOCOL_CALLBACK CallBackFunction
- )
-{
- CALLBACK_FN_ENTRY *FnTableEntry;
- LIST_ENTRY *ListHead;
- LIST_ENTRY *ListNode;
-
- if (Guid != NULL) {
- TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)TokenNumber);
- }
-
- //
- // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
- // We have to decrement TokenNumber by 1 to make it usable
- // as the array index of mCallbackFnTable[].
- //
- ListHead = &mCallbackFnTable[TokenNumber - 1];
- ListNode = GetFirstNode (ListHead);
-
- while (ListNode != ListHead) {
- FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node);
-
- if (FnTableEntry->CallbackFn == CallBackFunction) {
- //
- // We only allow a Callback function to be register once
- // for a TokenNumber. So just return EFI_SUCCESS
- //
- return EFI_SUCCESS;
- }
-
- ListNode = GetNextNode (ListHead, ListNode);
- }
-
- FnTableEntry = AllocatePool (sizeof (CALLBACK_FN_ENTRY));
- ASSERT (FnTableEntry != NULL);
-
- FnTableEntry->CallbackFn = CallBackFunction;
- InsertTailList (ListHead, &FnTableEntry->Node);
-
- return EFI_SUCCESS;
-}
-
-/**
- UnRegister the callback function for a PCD entry.
-
- This routine will unregister a callback function to a PCD entry by given token number
- and token space guid.
-
- @param TokenNumber PCD token's number, it is autogened by build tools.
- @param Guid PCD token space's guid.
- if not NULL, this PCD is dynamicEx type PCD.
- @param CallBackFunction Callback function pointer
-
- @retval EFI_SUCCESS Callback function is success to be unregister.
- @retval EFI_INVALID_PARAMETER Can not find the PCD entry by given token number.
-**/
-EFI_STATUS
-DxeUnRegisterCallBackWorker (
- IN UINTN TokenNumber,
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN PCD_PROTOCOL_CALLBACK CallBackFunction
- )
-{
- CALLBACK_FN_ENTRY *FnTableEntry;
- LIST_ENTRY *ListHead;
- LIST_ENTRY *ListNode;
-
- if (Guid != NULL) {
- TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)TokenNumber);
- }
-
- //
- // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
- // We have to decrement TokenNumber by 1 to make it usable
- // as the array index of mCallbackFnTable[].
- //
- ListHead = &mCallbackFnTable[TokenNumber - 1];
- ListNode = GetFirstNode (ListHead);
-
- while (ListNode != ListHead) {
- FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node);
-
- if (FnTableEntry->CallbackFn == CallBackFunction) {
- //
- // We only allow a Callback function to be register once
- // for a TokenNumber. So we can safely remove the Node from
- // the Link List and return EFI_SUCCESS.
- //
- RemoveEntryList (ListNode);
- FreePool (FnTableEntry);
-
- return EFI_SUCCESS;
- }
-
- ListNode = GetNextNode (ListHead, ListNode);
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-/**
- Get next token number in given token space.
-
- This routine is used for dynamicEx type PCD. It will firstly scan token space
- table to get token space according to given token space guid. Then scan given
- token number in found token space, if found, then return next token number in
- this token space.
-
- @param Guid Token space guid. Next token number will be scaned in
- this token space.
- @param TokenNumber Token number.
- If PCD_INVALID_TOKEN_NUMBER, return first token number in
- token space table.
- If not PCD_INVALID_TOKEN_NUMBER, return next token number
- in token space table.
- @param GuidTable Token space guid table. It will be used for scan token space
- by given token space guid.
- @param SizeOfGuidTable The size of guid table.
- @param ExMapTable DynamicEx token number mapping table.
- @param SizeOfExMapTable The size of dynamicEx token number mapping table.
-
- @retval EFI_NOT_FOUND Can not given token space or token number.
- @retval EFI_SUCCESS Success to get next token number.
-
-**/
-EFI_STATUS
-ExGetNextTokeNumber (
- IN CONST EFI_GUID *Guid,
- IN OUT UINTN *TokenNumber,
- IN EFI_GUID *GuidTable,
- IN UINTN SizeOfGuidTable,
- IN DYNAMICEX_MAPPING *ExMapTable,
- IN UINTN SizeOfExMapTable
- )
-{
- EFI_GUID *MatchGuid;
- UINTN Index;
- UINTN GuidTableIdx;
- BOOLEAN Found;
- UINTN ExMapTableCount;
-
- //
- // Scan token space guid
- //
- MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);
- if (MatchGuid == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Find the token space table in dynamicEx mapping table.
- //
- Found = FALSE;
- GuidTableIdx = MatchGuid - GuidTable;
- ExMapTableCount = SizeOfExMapTable / sizeof (ExMapTable[0]);
- for (Index = 0; Index < ExMapTableCount; 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 < ExMapTableCount; Index++) {
- if ((ExMapTable[Index].ExTokenNumber == *TokenNumber) && (ExMapTable[Index].ExGuidIndex == GuidTableIdx)) {
- break;
- }
- }
-
- while (Index < ExMapTableCount) {
- Index++;
- if (Index == ExMapTableCount) {
- //
- // 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;
-}
-
-/**
- Find the PCD database.
-
- @retval The base address of external PCD database binary.
- @retval NULL Return NULL if not find.
-**/
-DXE_PCD_DATABASE *
-LocateExPcdBinary (
- VOID
- )
-{
- EFI_STATUS Status;
-
- //
- // Search the External Pcd database from one section of current FFS,
- // and read it to memory
- //
- Status = GetSectionFromFfs (
- EFI_SECTION_RAW,
- 0,
- (VOID **)&mDxePcdDbBinary,
- &mDxePcdDbSize
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Check the first bytes (Header Signature Guid) and build version.
- //
- if (!CompareGuid ((VOID *)mDxePcdDbBinary, &gPcdDataBaseSignatureGuid) ||
- (mDxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION))
- {
- ASSERT (FALSE);
- }
-
- return mDxePcdDbBinary;
-}
-
-/**
- Update PCD database base on current SkuId
-
- @param SkuId Current SkuId
- @param IsPeiDb Whether to update PEI PCD database.
-
- @retval EFI_SUCCESS Update PCD database successfully.
- @retval EFI_NOT_FOUND Not found PCD database for current SkuId.
-**/
-EFI_STATUS
-UpdatePcdDatabase (
- IN SKU_ID SkuId,
- IN BOOLEAN IsPeiDb
- )
-{
- UINTN Index;
- PCD_DATABASE_SKU_DELTA *SkuDelta;
- PCD_DATA_DELTA *SkuDeltaData;
-
- if (IsPeiDb && (mPeiPcdDbBinary != NULL)) {
- //
- // Find the delta data for PEI DB
- //
- Index = (mPcdDatabase.PeiDb->Length + 7) & (~7);
- SkuDelta = NULL;
- while (Index < mPeiPcdDbSize) {
- SkuDelta = (PCD_DATABASE_SKU_DELTA *)((UINT8 *)mPeiPcdDbBinary + Index);
- if ((SkuDelta->SkuId == SkuId) && (SkuDelta->SkuIdCompared == 0)) {
- break;
- }
-
- Index = (Index + SkuDelta->Length + 7) & (~7);
- }
-
- //
- // Patch the delta data into current PCD database
- //
- if ((Index < mPeiPcdDbSize) && (SkuDelta != NULL)) {
- SkuDeltaData = (PCD_DATA_DELTA *)(SkuDelta + 1);
- while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length) {
- *((UINT8 *)mPcdDatabase.PeiDb + SkuDeltaData->Offset) = (UINT8)SkuDeltaData->Value;
- SkuDeltaData++;
- }
- } else {
- return EFI_NOT_FOUND;
- }
- }
-
- //
- // Find the delta data for DXE DB
- //
- Index = (mPcdDatabase.DxeDb->Length + 7) & (~7);
- SkuDelta = NULL;
-
- if (Index == mDxePcdDbSize) {
- return EFI_SUCCESS;
- }
-
- while (Index < mDxePcdDbSize) {
- SkuDelta = (PCD_DATABASE_SKU_DELTA *)((UINT8 *)mDxePcdDbBinary + Index);
- if ((SkuDelta->SkuId == SkuId) && (SkuDelta->SkuIdCompared == 0)) {
- break;
- }
-
- Index = (Index + SkuDelta->Length + 7) & (~7);
- }
-
- //
- // Patch the delta data into current PCD database
- //
- if ((Index < mDxePcdDbSize) && (SkuDelta != NULL)) {
- SkuDeltaData = (PCD_DATA_DELTA *)(SkuDelta + 1);
- while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length) {
- *((UINT8 *)mPcdDatabase.DxeDb + SkuDeltaData->Offset) = (UINT8)SkuDeltaData->Value;
- SkuDeltaData++;
- }
-
- return EFI_SUCCESS;
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Initialize the PCD database in DXE phase.
-
- PCD database in DXE phase also contains PCD database in PEI phase which is copied
- from GUID Hob.
-
-**/
-VOID
-BuildPcdDxeDataBase (
- VOID
- )
-{
- PEI_PCD_DATABASE *PeiDatabase;
- EFI_HOB_GUID_TYPE *GuidHob;
- UINTN Index;
- UINT32 PcdDxeDbLen;
- VOID *PcdDxeDb;
- EFI_STATUS Status;
-
- //
- // Assign PCD Entries with default value to PCD DATABASE
- //
- mPcdDatabase.DxeDb = LocateExPcdBinary ();
- ASSERT (mPcdDatabase.DxeDb != NULL);
- PcdDxeDbLen = mPcdDatabase.DxeDb->Length + mPcdDatabase.DxeDb->UninitDataBaseSize;
- PcdDxeDb = AllocateZeroPool (PcdDxeDbLen);
- ASSERT (PcdDxeDb != NULL);
- CopyMem (PcdDxeDb, mPcdDatabase.DxeDb, mPcdDatabase.DxeDb->Length);
- mPcdDatabase.DxeDb = PcdDxeDb;
-
- GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
- if (GuidHob != NULL) {
- //
- // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM
- // should not be included at all. So the GuidHob could
- // be NULL. If it is NULL, we just copy over the DXE Default
- // Value to PCD Database.
- //
- PeiDatabase = (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob);
-
- //
- // Get next one that stores full PEI data
- //
- GuidHob = GetNextGuidHob (&gPcdDataBaseHobGuid, GET_NEXT_HOB (GuidHob));
- if (GuidHob != NULL) {
- mPeiPcdDbBinary = (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob);
- mPeiPcdDbSize = (UINTN)GET_GUID_HOB_DATA_SIZE (GuidHob);
- }
-
- //
- // Assign PCD Entries refereneced in PEI phase to PCD DATABASE
- //
- mPcdDatabase.PeiDb = PeiDatabase;
- //
- // Inherit the SystemSkuId from PEI phase.
- //
- if (mPcdDatabase.PeiDb->SystemSkuId != 0) {
- Status = UpdatePcdDatabase (mPcdDatabase.PeiDb->SystemSkuId, FALSE);
- ASSERT_EFI_ERROR (Status);
- }
-
- mPcdDatabase.DxeDb->SystemSkuId = mPcdDatabase.PeiDb->SystemSkuId;
- } else {
- mPcdDatabase.PeiDb = AllocateZeroPool (sizeof (PEI_PCD_DATABASE));
- ASSERT (mPcdDatabase.PeiDb != NULL);
- }
-
- //
- // Initialized the external PCD database local variables
- //
- mPeiLocalTokenCount = mPcdDatabase.PeiDb->LocalTokenCount;
- mDxeLocalTokenCount = mPcdDatabase.DxeDb->LocalTokenCount;
-
- mPeiExMapppingTableSize = mPcdDatabase.PeiDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);
- mDxeExMapppingTableSize = mPcdDatabase.DxeDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);
- mPeiGuidTableSize = mPcdDatabase.PeiDb->GuidTableCount * sizeof (GUID);
- mDxeGuidTableSize = mPcdDatabase.DxeDb->GuidTableCount * sizeof (GUID);
-
- mPcdTotalTokenCount = mPeiLocalTokenCount + mDxeLocalTokenCount;
- mPeiNexTokenCount = mPeiLocalTokenCount - mPcdDatabase.PeiDb->ExTokenCount;
- mDxeNexTokenCount = mDxeLocalTokenCount - mPcdDatabase.DxeDb->ExTokenCount;
-
- mPeiExMapTableEmpty = (mPcdDatabase.PeiDb->ExTokenCount == 0) ? TRUE : FALSE;
- mDxeExMapTableEmpty = (mPcdDatabase.DxeDb->ExTokenCount == 0) ? TRUE : FALSE;
- mPeiDatabaseEmpty = (mPeiLocalTokenCount == 0) ? TRUE : FALSE;
-
- TmpTokenSpaceBufferCount = mPcdDatabase.PeiDb->ExTokenCount + mPcdDatabase.DxeDb->ExTokenCount;
- TmpTokenSpaceBuffer = (EFI_GUID **)AllocateZeroPool (TmpTokenSpaceBufferCount * sizeof (EFI_GUID *));
-
- //
- // Initialized the Callback Function Table
- //
- mCallbackFnTable = AllocateZeroPool (mPcdTotalTokenCount * sizeof (LIST_ENTRY));
- ASSERT (mCallbackFnTable != 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.
- //
- for (Index = 0; Index + 1 < mPcdTotalTokenCount + 1; Index++) {
- InitializeListHead (&mCallbackFnTable[Index]);
- }
-}
-
-/**
- Get Variable which contains HII type PCD entry.
-
- @param VariableGuid Variable's guid
- @param VariableName Variable's unicode name string
- @param VariableData Variable's data pointer,
- @param VariableSize Variable's size.
-
- @return the status of gRT->GetVariable
-**/
-EFI_STATUS
-GetHiiVariable (
- IN EFI_GUID *VariableGuid,
- IN UINT16 *VariableName,
- OUT UINT8 **VariableData,
- OUT UINTN *VariableSize
- )
-{
- UINTN Size;
- EFI_STATUS Status;
- UINT8 *Buffer;
-
- Size = 0;
- Buffer = NULL;
-
- //
- // Firstly get the real size of HII variable
- //
- Status = gRT->GetVariable (
- (UINT16 *)VariableName,
- VariableGuid,
- NULL,
- &Size,
- Buffer
- );
-
- //
- // Allocate buffer to hold whole variable data according to variable size.
- //
- if (Status == EFI_BUFFER_TOO_SMALL) {
- Buffer = (UINT8 *)AllocatePool (Size);
-
- ASSERT (Buffer != NULL);
-
- Status = gRT->GetVariable (
- VariableName,
- VariableGuid,
- NULL,
- &Size,
- Buffer
- );
-
- ASSERT (Status == EFI_SUCCESS);
- *VariableData = Buffer;
- *VariableSize = Size;
- } else {
- //
- // Use Default Data only when variable is not found.
- // For other error status, correct data can't be got, and trig ASSERT().
- //
- ASSERT (Status == EFI_NOT_FOUND);
- }
-
- return Status;
-}
-
-/**
- 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 (
- UINT32 ExTokenNumber,
- CONST EFI_GUID *Guid OPTIONAL,
- UINTN TokenNumber,
- VOID *Data,
- UINTN Size
- )
-{
- CALLBACK_FN_ENTRY *FnTableEntry;
- LIST_ENTRY *ListHead;
- LIST_ENTRY *ListNode;
-
- //
- // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
- // We have to decrement TokenNumber by 1 to make it usable
- // as the array index of mCallbackFnTable[].
- //
- ListHead = &mCallbackFnTable[TokenNumber - 1];
- ListNode = GetFirstNode (ListHead);
-
- while (ListNode != ListHead) {
- FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node);
-
- FnTableEntry->CallbackFn (
- Guid,
- (Guid == NULL) ? TokenNumber : ExTokenNumber,
- Data,
- Size
- );
-
- ListNode = GetNextNode (ListHead, ListNode);
- }
-
- return;
-}
-
-/**
- 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
- )
-{
- BOOLEAN IsPeiDb;
- UINT32 LocalTokenNumber;
- EFI_GUID *GuidTable;
- UINT8 *StringTable;
- EFI_GUID *Guid;
- UINT16 *Name;
- UINTN VariableOffset;
- UINT32 Attributes;
- VOID *InternalData;
- VARIABLE_HEAD *VariableHead;
- UINTN Offset;
- UINT8 *PcdDb;
- EFI_STATUS Status;
- UINTN MaxSize;
- UINTN TmpTokenNumber;
-
- //
- // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
- // We have to decrement TokenNumber by 1 to make it usable
- // as the array index.
- //
- TokenNumber--;
-
- TmpTokenNumber = TokenNumber;
-
- //
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- //
- ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
-
- if (PtrType) {
- //
- // Get MaxSize first, then check new size with max buffer size.
- //
- GetPtrTypeSize (TokenNumber, &MaxSize);
- if (*Size > MaxSize) {
- *Size = MaxSize;
- return EFI_INVALID_PARAMETER;
- }
- } else {
- if (*Size != DxePcdGetSize (TokenNumber + 1)) {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- //
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- //
- if ((TokenNumber + 1 < mPeiNexTokenCount + 1) ||
- ((TokenNumber + 1 >= mPeiLocalTokenCount + 1) && (TokenNumber + 1 < (mPeiLocalTokenCount + mDxeNexTokenCount + 1))))
- {
- InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
- }
-
- //
- // Aquire lock to prevent reentrance from TPL_CALLBACK level
- //
- EfiAcquireLock (&mPcdDatabaseLock);
-
- //
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- //
- IsPeiDb = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
-
- LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);
-
- Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
-
- PcdDb = IsPeiDb ? ((UINT8 *)mPcdDatabase.PeiDb) : ((UINT8 *)mPcdDatabase.DxeDb);
-
- if (IsPeiDb) {
- StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);
- } else {
- StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);
- }
-
- InternalData = PcdDb + Offset;
-
- switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
- case PCD_TYPE_VPD:
- ASSERT (FALSE);
- Status = EFI_INVALID_PARAMETER;
- break;
-
- case PCD_TYPE_STRING:
- if (SetPtrTypeSize (TmpTokenNumber, Size)) {
- CopyMem (StringTable + *((STRING_HEAD *)InternalData), Data, *Size);
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_INVALID_PARAMETER;
- }
-
- break;
-
- case PCD_TYPE_HII|PCD_TYPE_STRING:
- case PCD_TYPE_HII:
- if (PtrType) {
- if (!SetPtrTypeSize (TmpTokenNumber, Size)) {
- Status = EFI_INVALID_PARAMETER;
- break;
- }
- }
-
- if (IsPeiDb) {
- GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
- } else {
- GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
- }
-
- VariableHead = (VARIABLE_HEAD *)(PcdDb + Offset);
-
- Guid = GuidTable + VariableHead->GuidTableIndex;
- Name = (UINT16 *)(StringTable + VariableHead->StringIndex);
- VariableOffset = VariableHead->Offset;
- Attributes = VariableHead->Attributes;
- Status = SetHiiVariable (Guid, Name, Attributes, Data, *Size, VariableOffset);
- break;
-
- case PCD_TYPE_DATA:
- if (PtrType) {
- if (SetPtrTypeSize (TmpTokenNumber, Size)) {
- CopyMem (InternalData, Data, *Size);
- Status = EFI_SUCCESS;
- } else {
- Status = EFI_INVALID_PARAMETER;
- }
-
- break;
- }
-
- Status = EFI_SUCCESS;
- switch (*Size) {
- case sizeof (UINT8):
- *((UINT8 *)InternalData) = *((UINT8 *)Data);
- break;
-
- case sizeof (UINT16):
- *((UINT16 *)InternalData) = *((UINT16 *)Data);
- break;
-
- case sizeof (UINT32):
- *((UINT32 *)InternalData) = *((UINT32 *)Data);
- break;
-
- case sizeof (UINT64):
- *((UINT64 *)InternalData) = *((UINT64 *)Data);
- break;
-
- default:
- ASSERT (FALSE);
- Status = EFI_NOT_FOUND;
- break;
- }
-
- break;
-
- default:
- ASSERT (FALSE);
- Status = EFI_NOT_FOUND;
- break;
- }
-
- EfiReleaseLock (&mPcdDatabaseLock);
-
- return Status;
-}
-
-/**
- Wrapper function for get PCD value for dynamic-ex PCD.
-
- @param Guid Token space guid for dynamic-ex PCD.
- @param ExTokenNumber Token number for dynamic-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, (UINT32)ExTokenNumber), GetSize);
-}
-
-/**
- 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 SetSize
- )
-{
- return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, 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 *SetSize,
- IN BOOLEAN PtrType
- )
-{
- UINTN TokenNumber;
-
- TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)ExTokenNumber);
-
- InvokeCallbackOnSet ((UINT32)ExTokenNumber, Guid, TokenNumber, Data, *SetSize);
-
- return SetWorker (TokenNumber, Data, SetSize, PtrType);
-}
-
-/**
- Get variable size and data from HII-type PCDs.
-
- @param[in] VariableGuid Guid of variable which stored value of a HII-type PCD.
- @param[in] VariableName Unicode name of variable which stored value of a HII-type PCD.
- @param[out] VariableSize Pointer to variable size got from HII-type PCDs.
- @param[out] VariableData Pointer to variable data got from HII-type PCDs.
-
-**/
-VOID
-GetVariableSizeAndDataFromHiiPcd (
- IN EFI_GUID *VariableGuid,
- IN UINT16 *VariableName,
- OUT UINTN *VariableSize,
- OUT VOID *VariableData OPTIONAL
- )
-{
- BOOLEAN IsPeiDb;
- PCD_DATABASE_INIT *Database;
- UINTN TokenNumber;
- UINT32 LocalTokenNumber;
- UINTN Offset;
- EFI_GUID *GuidTable;
- UINT8 *StringTable;
- VARIABLE_HEAD *VariableHead;
- EFI_GUID *Guid;
- UINT16 *Name;
- UINTN PcdDataSize;
- UINTN Size;
- UINT8 *VaraiableDefaultBuffer;
- STRING_HEAD StringTableIdx;
-
- *VariableSize = 0;
-
- //
- // Go through PCD database to find out DynamicHii PCDs.
- //
- for (TokenNumber = 1; TokenNumber <= mPcdTotalTokenCount; TokenNumber++) {
- IsPeiDb = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
- Database = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb;
- LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);
- if ((LocalTokenNumber & PCD_TYPE_HII) != 0) {
- //
- // Get the Variable Guid and Name pointer.
- //
- Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
- VariableHead = (VARIABLE_HEAD *)((UINT8 *)Database + Offset);
- StringTable = (UINT8 *)((UINT8 *)Database + Database->StringTableOffset);
- GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);
- Guid = GuidTable + VariableHead->GuidTableIndex;
- Name = (UINT16 *)(StringTable + VariableHead->StringIndex);
- if (CompareGuid (VariableGuid, Guid) && (StrCmp (VariableName, Name) == 0)) {
- //
- // It is the matched DynamicHii PCD.
- //
- PcdDataSize = DxePcdGetSize (TokenNumber);
- Size = VariableHead->Offset + PcdDataSize;
- if (Size > *VariableSize) {
- *VariableSize = Size;
- }
-
- if (VariableData != NULL) {
- 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.
- //
- StringTableIdx = *(STRING_HEAD *)((UINT8 *)Database + VariableHead->DefaultValueOffset);
- VaraiableDefaultBuffer = (UINT8 *)(StringTable + StringTableIdx);
- } else {
- VaraiableDefaultBuffer = (UINT8 *)Database + VariableHead->DefaultValueOffset;
- }
-
- CopyMem ((UINT8 *)VariableData + VariableHead->Offset, VaraiableDefaultBuffer, PcdDataSize);
- }
- }
- }
- }
-}
-
-/**
- Set value for HII-type PCD.
-
- A HII-type PCD's value is stored in a variable. Setting/Getting the value of
- HII-type PCD is to visit this variable.
-
- @param VariableGuid Guid of variable which stored value of a HII-type PCD.
- @param VariableName Unicode name of variable which stored value of a HII-type PCD.
- @param SetAttributes Attributes bitmask to set for the variable.
- @param Data Value want to be set.
- @param DataSize Size of value
- @param Offset Value offset of HII-type PCD in variable.
-
- @return status of GetVariable()/SetVariable().
-
-**/
-EFI_STATUS
-SetHiiVariable (
- IN EFI_GUID *VariableGuid,
- IN UINT16 *VariableName,
- IN UINT32 SetAttributes,
- IN CONST VOID *Data,
- IN UINTN DataSize,
- IN UINTN Offset
- )
-{
- UINTN Size;
- VOID *Buffer;
- EFI_STATUS Status;
- UINT32 Attribute;
- UINTN SetSize;
-
- Size = 0;
- SetSize = 0;
-
- //
- // Try to get original variable size information.
- //
- Status = gRT->GetVariable (
- (UINT16 *)VariableName,
- VariableGuid,
- NULL,
- &Size,
- NULL
- );
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- //
- // Patch new PCD's value to offset in given HII variable.
- //
- if (Size >= (DataSize + Offset)) {
- SetSize = Size;
- } else {
- SetSize = DataSize + Offset;
- }
-
- Buffer = AllocatePool (SetSize);
- ASSERT (Buffer != NULL);
-
- Status = gRT->GetVariable (
- VariableName,
- VariableGuid,
- &Attribute,
- &Size,
- Buffer
- );
-
- ASSERT_EFI_ERROR (Status);
-
- CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
-
- if (SetAttributes == 0) {
- SetAttributes = Attribute;
- }
-
- Status = gRT->SetVariable (
- VariableName,
- VariableGuid,
- SetAttributes,
- SetSize,
- Buffer
- );
-
- FreePool (Buffer);
- return Status;
- } else if (Status == EFI_NOT_FOUND) {
- //
- // If variable does not exist, a new variable need to be created.
- //
-
- //
- // Get size, allocate buffer and get data.
- //
- GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, NULL);
- Buffer = AllocateZeroPool (Size);
- ASSERT (Buffer != NULL);
- GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, Buffer);
-
- //
- // Update buffer.
- //
- CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
-
- if (SetAttributes == 0) {
- SetAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
- }
-
- Status = gRT->SetVariable (
- VariableName,
- VariableGuid,
- SetAttributes,
- Size,
- Buffer
- );
-
- FreePool (Buffer);
- return Status;
- }
-
- //
- // If we drop to here, the value is failed to be written in to variable area.
- //
- return Status;
-}
-
-/**
- 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 UINT32 ExTokenNumber
- )
-{
- UINT32 Index;
- DYNAMICEX_MAPPING *ExMap;
- EFI_GUID *GuidTable;
- EFI_GUID *MatchGuid;
- UINTN MatchGuidIdx;
-
- if (!mPeiDatabaseEmpty) {
- ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset);
- GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
-
- MatchGuid = ScanGuid (GuidTable, mPeiGuidTableSize, Guid);
-
- if (MatchGuid != NULL) {
- MatchGuidIdx = MatchGuid - GuidTable;
-
- for (Index = 0; Index < mPcdDatabase.PeiDb->ExTokenCount; Index++) {
- if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
- (MatchGuidIdx == ExMap[Index].ExGuidIndex))
- {
- return ExMap[Index].TokenNumber;
- }
- }
- }
- }
-
- ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset);
- GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
-
- MatchGuid = ScanGuid (GuidTable, mDxeGuidTableSize, 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 < mPcdDatabase.DxeDb->ExTokenCount; Index++) {
- if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
- (MatchGuidIdx == ExMap[Index].ExGuidIndex))
- {
- return ExMap[Index].TokenNumber;
- }
- }
-
- DEBUG ((DEBUG_ERROR, "%a: Failed to find PCD with GUID: %g and token number: %d\n", __func__, Guid, ExTokenNumber));
- ASSERT (FALSE);
-
- return 0;
-}
-
-/**
- Wrapper function of getting index of PCD entry in size table.
-
- @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
- @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
- If FALSE, the pcd entry is initialized in DXE phase.
-
- @return index of PCD entry in size table.
-**/
-UINTN
-GetSizeTableIndex (
- IN UINTN LocalTokenNumberTableIdx,
- IN BOOLEAN IsPeiDb
- )
-{
- UINT32 *LocalTokenNumberTable;
- UINTN LocalTokenNumber;
- UINTN Index;
- UINTN SizeTableIdx;
-
- if (IsPeiDb) {
- LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
- } else {
- LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
- }
-
- SizeTableIdx = 0;
-
- for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {
- LocalTokenNumber = LocalTokenNumberTable[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 {
- //
- // We have only two entry for Non-Sku enabled PCD entry:
- // 1) MAX SIZE
- // 2) Current Size
- //
- SizeTableIdx += 2;
- }
- }
- }
-
- return SizeTableIdx;
-}
-
-/**
- Get size of POINTER type PCD value.
-
- @param LocalTokenNumberTableIdx Index of local token number in local token number table.
- @param MaxSize Maxmium size of POINTER type PCD value.
-
- @return size of POINTER type PCD value.
-
-**/
-UINTN
-GetPtrTypeSize (
- IN UINTN LocalTokenNumberTableIdx,
- OUT UINTN *MaxSize
- )
-{
- INTN SizeTableIdx;
- UINTN LocalTokenNumber;
- SIZE_INFO *SizeTable;
- BOOLEAN IsPeiDb;
- UINT32 *LocalTokenNumberTable;
-
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- IsPeiDb = (BOOLEAN)(LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);
-
- if (IsPeiDb) {
- LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
- SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);
- } else {
- LocalTokenNumberTableIdx -= mPeiLocalTokenCount;
- LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
- SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);
- }
-
- LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
-
- ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
-
- SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);
-
- *MaxSize = SizeTable[SizeTableIdx];
- //
- // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
- // PCD entry.
- //
- if ((LocalTokenNumber & PCD_TYPE_VPD) != 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 {
- //
- // We have only two entry for Non-Sku enabled PCD entry:
- // 1) MAX SIZE
- // 2) Current Size
- //
- return SizeTable[SizeTableIdx + 1];
- }
-}
-
-/**
- Set size of POINTER type PCD value. The size should not exceed the maximum size
- of this PCD value.
-
- @param LocalTokenNumberTableIdx Index of local token number in local token number table.
- @param CurrentSize Size of POINTER type PCD value.
-
- @retval TRUE Success to set size of PCD value.
- @retval FALSE Fail to set size of PCD value.
-**/
-BOOLEAN
-SetPtrTypeSize (
- IN UINTN LocalTokenNumberTableIdx,
- IN OUT UINTN *CurrentSize
- )
-{
- INTN SizeTableIdx;
- UINTN LocalTokenNumber;
- SIZE_INFO *SizeTable;
- UINTN MaxSize;
- BOOLEAN IsPeiDb;
- UINT32 *LocalTokenNumberTable;
-
- //
- // EBC compiler is very choosy. It may report warning about comparison
- // between UINTN and 0 . So we add 1 in each size of the
- // comparison.
- //
- IsPeiDb = (BOOLEAN)(LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);
-
- if (IsPeiDb) {
- LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
- SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);
- } else {
- LocalTokenNumberTableIdx -= mPeiLocalTokenCount;
- LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
- SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);
- }
-
- LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
-
- ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
-
- SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);
-
- MaxSize = SizeTable[SizeTableIdx];
- //
- // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
- // PCD entry.
- //
- if ((LocalTokenNumber & PCD_TYPE_VPD) != 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;
- }
-
- //
- // 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;
- }
-}
-
-/**
- VariableLock DynamicHiiPcd.
-
- @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
- If FALSE, the pcd entry is initialized in DXE phase.
- @param[in] VariableLock Pointer to VariableLockProtocol.
-
-**/
-VOID
-VariableLockDynamicHiiPcd (
- IN BOOLEAN IsPeiDb,
- IN EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock
- )
-{
- EFI_STATUS Status;
- PCD_DATABASE_INIT *Database;
- UINT32 LocalTokenCount;
- UINTN TokenNumber;
- UINT32 LocalTokenNumber;
- UINTN Offset;
- EFI_GUID *GuidTable;
- UINT8 *StringTable;
- VARIABLE_HEAD *VariableHead;
- EFI_GUID *Guid;
- UINT16 *Name;
-
- Database = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb;
- LocalTokenCount = IsPeiDb ? mPeiLocalTokenCount : mDxeLocalTokenCount;
-
- //
- // Go through PCD database to find out DynamicHii PCDs.
- //
- for (TokenNumber = 1; TokenNumber <= LocalTokenCount; TokenNumber++) {
- if (IsPeiDb) {
- LocalTokenNumber = GetLocalTokenNumber (TRUE, TokenNumber);
- } else {
- LocalTokenNumber = GetLocalTokenNumber (FALSE, TokenNumber + mPeiLocalTokenCount);
- }
-
- if ((LocalTokenNumber & PCD_TYPE_HII) != 0) {
- Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
- VariableHead = (VARIABLE_HEAD *)((UINT8 *)Database + Offset);
- //
- // Why not to set property by VarCheckProtocol with Attributes and Property directly here?
- // It is because that set property by VarCheckProtocol will indicate the variable to
- // be a system variable, but the unknown max size of the variable is dangerous to
- // the system variable region.
- //
- if ((VariableHead->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0) {
- //
- // DynamicHii PCD with RO property set in *.dsc.
- //
- StringTable = (UINT8 *)((UINT8 *)Database + Database->StringTableOffset);
- GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);
- Guid = GuidTable + VariableHead->GuidTableIndex;
- Name = (UINT16 *)(StringTable + VariableHead->StringIndex);
- Status = VariableLock->RequestToLock (VariableLock, Name, Guid);
- ASSERT_EFI_ERROR (Status);
- }
- }
- }
-}
-
-/**
- VariableLockProtocol callback
- to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-VariableLockCallBack (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
- EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
-
- Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock);
- if (!EFI_ERROR (Status)) {
- VariableLockDynamicHiiPcd (TRUE, VariableLock);
- VariableLockDynamicHiiPcd (FALSE, VariableLock);
- }
-}
+/** @file + Help functions used by PCD DXE driver. + +Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +(C) Copyright 2016-2021 Hewlett Packard Enterprise Development LP<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Service.h" +#include <Library/DxeServicesLib.h> + +PCD_DATABASE mPcdDatabase; + +UINT32 mPcdTotalTokenCount; +UINT32 mPeiLocalTokenCount; +UINT32 mDxeLocalTokenCount; +UINT32 mPeiNexTokenCount; +UINT32 mDxeNexTokenCount; +UINT32 mPeiExMapppingTableSize; +UINT32 mDxeExMapppingTableSize; +UINT32 mPeiGuidTableSize; +UINT32 mDxeGuidTableSize; + +BOOLEAN mPeiExMapTableEmpty; +BOOLEAN mDxeExMapTableEmpty; +BOOLEAN mPeiDatabaseEmpty; + +LIST_ENTRY *mCallbackFnTable; +EFI_GUID **TmpTokenSpaceBuffer; +UINTN TmpTokenSpaceBufferCount; + +UINTN mPeiPcdDbSize = 0; +PEI_PCD_DATABASE *mPeiPcdDbBinary = NULL; +UINTN mDxePcdDbSize = 0; +DXE_PCD_DATABASE *mDxePcdDbBinary = NULL; + +/** + Get Local Token Number by Token Number. + + @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase, + If FALSE, the pcd entry is initialized in DXE phase. + @param[in] TokenNumber The PCD token number. + + @return Local Token Number. +**/ +UINT32 +GetLocalTokenNumber ( + IN BOOLEAN IsPeiDb, + IN UINTN TokenNumber + ) +{ + UINT32 *LocalTokenNumberTable; + + // + // 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--; + + LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) : + (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset); + TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount; + + return LocalTokenNumberTable[TokenNumber]; +} + +/** + 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] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase, + If FALSE, the pcd entry is initialized in DXE phase. + @param[in] TokenNumber The PCD token number. + + @return The TokenSpaceCName or full PCD name. +**/ +CHAR8 * +GetPcdName ( + IN BOOLEAN OnlyTokenSpaceName, + IN BOOLEAN IsPeiDb, + IN UINTN TokenNumber + ) +{ + PCD_DATABASE_INIT *Database; + UINT8 *StringTable; + UINTN NameSize; + PCD_NAME_INDEX *PcdNameIndex; + CHAR8 *TokenSpaceName; + CHAR8 *PcdName; + CHAR8 *Name; + + // + // Return NULL when PCD name table is absent. + // + if (IsPeiDb) { + if (mPcdDatabase.PeiDb->PcdNameTableOffset == 0) { + return NULL; + } + } else { + if (mPcdDatabase.DxeDb->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--; + + Database = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb; + TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount; + + 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] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase, + If FALSE, the pcd entry is initialized in DXE phase. + @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 BOOLEAN IsPeiDb, + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + PCD_DATABASE_INIT *Database; + UINTN GuidTableIdx; + EFI_GUID *MatchGuid; + EFI_GUID *GuidTable; + DYNAMICEX_MAPPING *ExMapTable; + UINTN Index; + UINT32 LocalTokenNumber; + + Database = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb; + + 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, IsPeiDb, ExMapTable[Index].TokenNumber); + return EFI_SUCCESS; + } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) { + PcdInfo->PcdSize = DxePcdGetSize (ExMapTable[Index].TokenNumber); + LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, ExMapTable[Index].TokenNumber); + PcdInfo->PcdType = GetPcdType (LocalTokenNumber); + PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, 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 +DxeGetPcdInfo ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + EFI_STATUS Status; + BOOLEAN PeiExMapTableEmpty; + BOOLEAN DxeExMapTableEmpty; + UINT32 LocalTokenNumber; + BOOLEAN IsPeiDb; + + ASSERT (PcdInfo != NULL); + + Status = EFI_NOT_FOUND; + PeiExMapTableEmpty = mPeiExMapTableEmpty; + DxeExMapTableEmpty = mDxeExMapTableEmpty; + + if (Guid == NULL) { + if (((TokenNumber + 1 > mPeiNexTokenCount + 1) && (TokenNumber + 1 <= mPeiLocalTokenCount + 1)) || + ((TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) + { + 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 = DxePcdGetSize (TokenNumber); + IsPeiDb = FALSE; + if ((TokenNumber + 1 <= mPeiNexTokenCount + 1)) { + IsPeiDb = TRUE; + } + + LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber); + PcdInfo->PcdType = GetPcdType (LocalTokenNumber); + PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, TokenNumber); + } + + return EFI_SUCCESS; + } + + if (PeiExMapTableEmpty && DxeExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + if (!PeiExMapTableEmpty) { + Status = ExGetPcdInfo ( + TRUE, + Guid, + TokenNumber, + PcdInfo + ); + } + + if (Status == EFI_SUCCESS) { + return Status; + } + + if (!DxeExMapTableEmpty) { + Status = ExGetPcdInfo ( + FALSE, + Guid, + TokenNumber, + PcdInfo + ); + } + + return Status; +} + +/** + 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 + ) +{ + EFI_GUID *GuidTable; + UINT8 *StringTable; + EFI_GUID *Guid; + UINT16 *Name; + VARIABLE_HEAD *VariableHead; + UINT8 *VaraiableDefaultBuffer; + UINT8 *Data; + VPD_HEAD *VpdHead; + UINT8 *PcdDb; + VOID *RetPtr; + UINTN TmpTokenNumber; + UINTN DataSize; + EFI_STATUS Status; + UINT32 LocalTokenNumber; + UINT32 Offset; + STRING_HEAD StringTableIdx; + BOOLEAN IsPeiDb; + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + RetPtr = NULL; + + ASSERT (TokenNumber > 0); + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + TmpTokenNumber = TokenNumber; + + // + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + // + ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1); + + ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0)); + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE); + + LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1); + + PcdDb = IsPeiDb ? ((UINT8 *)mPcdDatabase.PeiDb) : ((UINT8 *)mPcdDatabase.DxeDb); + + if (IsPeiDb) { + StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset); + } else { + StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset); + } + + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + VpdHead = (VPD_HEAD *)((UINT8 *)PcdDb + Offset); + ASSERT (mVpdBaseAddress != 0); + RetPtr = (VOID *)(mVpdBaseAddress + VpdHead->Offset); + + break; + + case PCD_TYPE_HII|PCD_TYPE_STRING: + case PCD_TYPE_HII: + if (IsPeiDb) { + GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset); + } else { + GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset); + } + + VariableHead = (VARIABLE_HEAD *)(PcdDb + Offset); + Guid = GuidTable + 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. + // + StringTableIdx = *(STRING_HEAD *)((UINT8 *)PcdDb + VariableHead->DefaultValueOffset); + VaraiableDefaultBuffer = (UINT8 *)(StringTable + StringTableIdx); + } else { + VaraiableDefaultBuffer = (UINT8 *)PcdDb + VariableHead->DefaultValueOffset; + } + + Status = GetHiiVariable (Guid, Name, &Data, &DataSize); + if (Status == EFI_SUCCESS) { + if (DataSize >= (VariableHead->Offset + GetSize)) { + if (GetSize == 0) { + // + // It is a pointer type. So get the MaxSize reserved for + // this PCD entry. + // + GetPtrTypeSize (TmpTokenNumber, &GetSize); + 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. + // So that we can free the Data allocated in GetHiiVariable. + // + CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize); + } + + FreePool (Data); + } + + RetPtr = (VOID *)VaraiableDefaultBuffer; + break; + + case PCD_TYPE_STRING: + StringTableIdx = *(STRING_HEAD *)((UINT8 *)PcdDb + Offset); + RetPtr = (VOID *)(StringTable + StringTableIdx); + break; + + case PCD_TYPE_DATA: + RetPtr = (VOID *)((UINT8 *)PcdDb + Offset); + break; + + default: + ASSERT (FALSE); + break; + } + + EfiReleaseLock (&mPcdDatabaseLock); + + return RetPtr; +} + +/** + Register the callback function for a PCD entry. + + This routine will register a callback function to a PCD entry by given token number + and token space guid. + + @param TokenNumber PCD token's number, it is autogened by build tools. + @param Guid PCD token space's guid, + if not NULL, this PCD is dynamicEx type PCD. + @param CallBackFunction Callback function pointer + + @return EFI_SUCCESS Always success for registering callback function. + +**/ +EFI_STATUS +DxeRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST EFI_GUID *Guid OPTIONAL, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +{ + CALLBACK_FN_ENTRY *FnTableEntry; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; + + if (Guid != NULL) { + TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)TokenNumber); + } + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index of mCallbackFnTable[]. + // + ListHead = &mCallbackFnTable[TokenNumber - 1]; + ListNode = GetFirstNode (ListHead); + + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node); + + if (FnTableEntry->CallbackFn == CallBackFunction) { + // + // We only allow a Callback function to be register once + // for a TokenNumber. So just return EFI_SUCCESS + // + return EFI_SUCCESS; + } + + ListNode = GetNextNode (ListHead, ListNode); + } + + FnTableEntry = AllocatePool (sizeof (CALLBACK_FN_ENTRY)); + ASSERT (FnTableEntry != NULL); + + FnTableEntry->CallbackFn = CallBackFunction; + InsertTailList (ListHead, &FnTableEntry->Node); + + return EFI_SUCCESS; +} + +/** + UnRegister the callback function for a PCD entry. + + This routine will unregister a callback function to a PCD entry by given token number + and token space guid. + + @param TokenNumber PCD token's number, it is autogened by build tools. + @param Guid PCD token space's guid. + if not NULL, this PCD is dynamicEx type PCD. + @param CallBackFunction Callback function pointer + + @retval EFI_SUCCESS Callback function is success to be unregister. + @retval EFI_INVALID_PARAMETER Can not find the PCD entry by given token number. +**/ +EFI_STATUS +DxeUnRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST EFI_GUID *Guid OPTIONAL, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +{ + CALLBACK_FN_ENTRY *FnTableEntry; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; + + if (Guid != NULL) { + TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)TokenNumber); + } + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index of mCallbackFnTable[]. + // + ListHead = &mCallbackFnTable[TokenNumber - 1]; + ListNode = GetFirstNode (ListHead); + + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node); + + if (FnTableEntry->CallbackFn == CallBackFunction) { + // + // We only allow a Callback function to be register once + // for a TokenNumber. So we can safely remove the Node from + // the Link List and return EFI_SUCCESS. + // + RemoveEntryList (ListNode); + FreePool (FnTableEntry); + + return EFI_SUCCESS; + } + + ListNode = GetNextNode (ListHead, ListNode); + } + + return EFI_INVALID_PARAMETER; +} + +/** + Get next token number in given token space. + + This routine is used for dynamicEx type PCD. It will firstly scan token space + table to get token space according to given token space guid. Then scan given + token number in found token space, if found, then return next token number in + this token space. + + @param Guid Token space guid. Next token number will be scaned in + this token space. + @param TokenNumber Token number. + If PCD_INVALID_TOKEN_NUMBER, return first token number in + token space table. + If not PCD_INVALID_TOKEN_NUMBER, return next token number + in token space table. + @param GuidTable Token space guid table. It will be used for scan token space + by given token space guid. + @param SizeOfGuidTable The size of guid table. + @param ExMapTable DynamicEx token number mapping table. + @param SizeOfExMapTable The size of dynamicEx token number mapping table. + + @retval EFI_NOT_FOUND Can not given token space or token number. + @retval EFI_SUCCESS Success to get next token number. + +**/ +EFI_STATUS +ExGetNextTokeNumber ( + IN CONST EFI_GUID *Guid, + IN OUT UINTN *TokenNumber, + IN EFI_GUID *GuidTable, + IN UINTN SizeOfGuidTable, + IN DYNAMICEX_MAPPING *ExMapTable, + IN UINTN SizeOfExMapTable + ) +{ + EFI_GUID *MatchGuid; + UINTN Index; + UINTN GuidTableIdx; + BOOLEAN Found; + UINTN ExMapTableCount; + + // + // Scan token space guid + // + MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid); + if (MatchGuid == NULL) { + return EFI_NOT_FOUND; + } + + // + // Find the token space table in dynamicEx mapping table. + // + Found = FALSE; + GuidTableIdx = MatchGuid - GuidTable; + ExMapTableCount = SizeOfExMapTable / sizeof (ExMapTable[0]); + for (Index = 0; Index < ExMapTableCount; 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 < ExMapTableCount; Index++) { + if ((ExMapTable[Index].ExTokenNumber == *TokenNumber) && (ExMapTable[Index].ExGuidIndex == GuidTableIdx)) { + break; + } + } + + while (Index < ExMapTableCount) { + Index++; + if (Index == ExMapTableCount) { + // + // 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; +} + +/** + Find the PCD database. + + @retval The base address of external PCD database binary. + @retval NULL Return NULL if not find. +**/ +DXE_PCD_DATABASE * +LocateExPcdBinary ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Search the External Pcd database from one section of current FFS, + // and read it to memory + // + Status = GetSectionFromFfs ( + EFI_SECTION_RAW, + 0, + (VOID **)&mDxePcdDbBinary, + &mDxePcdDbSize + ); + ASSERT_EFI_ERROR (Status); + + // + // Check the first bytes (Header Signature Guid) and build version. + // + if (!CompareGuid ((VOID *)mDxePcdDbBinary, &gPcdDataBaseSignatureGuid) || + (mDxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) + { + ASSERT (FALSE); + } + + return mDxePcdDbBinary; +} + +/** + Update PCD database base on current SkuId + + @param SkuId Current SkuId + @param IsPeiDb Whether to update PEI PCD database. + + @retval EFI_SUCCESS Update PCD database successfully. + @retval EFI_NOT_FOUND Not found PCD database for current SkuId. +**/ +EFI_STATUS +UpdatePcdDatabase ( + IN SKU_ID SkuId, + IN BOOLEAN IsPeiDb + ) +{ + UINTN Index; + PCD_DATABASE_SKU_DELTA *SkuDelta; + PCD_DATA_DELTA *SkuDeltaData; + + if (IsPeiDb && (mPeiPcdDbBinary != NULL)) { + // + // Find the delta data for PEI DB + // + Index = (mPcdDatabase.PeiDb->Length + 7) & (~7); + SkuDelta = NULL; + while (Index < mPeiPcdDbSize) { + SkuDelta = (PCD_DATABASE_SKU_DELTA *)((UINT8 *)mPeiPcdDbBinary + Index); + if ((SkuDelta->SkuId == SkuId) && (SkuDelta->SkuIdCompared == 0)) { + break; + } + + Index = (Index + SkuDelta->Length + 7) & (~7); + } + + // + // Patch the delta data into current PCD database + // + if ((Index < mPeiPcdDbSize) && (SkuDelta != NULL)) { + SkuDeltaData = (PCD_DATA_DELTA *)(SkuDelta + 1); + while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length) { + *((UINT8 *)mPcdDatabase.PeiDb + SkuDeltaData->Offset) = (UINT8)SkuDeltaData->Value; + SkuDeltaData++; + } + } else { + return EFI_NOT_FOUND; + } + } + + // + // Find the delta data for DXE DB + // + Index = (mPcdDatabase.DxeDb->Length + 7) & (~7); + SkuDelta = NULL; + + if (Index == mDxePcdDbSize) { + return EFI_SUCCESS; + } + + while (Index < mDxePcdDbSize) { + SkuDelta = (PCD_DATABASE_SKU_DELTA *)((UINT8 *)mDxePcdDbBinary + Index); + if ((SkuDelta->SkuId == SkuId) && (SkuDelta->SkuIdCompared == 0)) { + break; + } + + Index = (Index + SkuDelta->Length + 7) & (~7); + } + + // + // Patch the delta data into current PCD database + // + if ((Index < mDxePcdDbSize) && (SkuDelta != NULL)) { + SkuDeltaData = (PCD_DATA_DELTA *)(SkuDelta + 1); + while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length) { + *((UINT8 *)mPcdDatabase.DxeDb + SkuDeltaData->Offset) = (UINT8)SkuDeltaData->Value; + SkuDeltaData++; + } + + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +/** + Initialize the PCD database in DXE phase. + + PCD database in DXE phase also contains PCD database in PEI phase which is copied + from GUID Hob. + +**/ +VOID +BuildPcdDxeDataBase ( + VOID + ) +{ + PEI_PCD_DATABASE *PeiDatabase; + EFI_HOB_GUID_TYPE *GuidHob; + UINTN Index; + UINT32 PcdDxeDbLen; + VOID *PcdDxeDb; + EFI_STATUS Status; + + // + // Assign PCD Entries with default value to PCD DATABASE + // + mPcdDatabase.DxeDb = LocateExPcdBinary (); + ASSERT (mPcdDatabase.DxeDb != NULL); + PcdDxeDbLen = mPcdDatabase.DxeDb->Length + mPcdDatabase.DxeDb->UninitDataBaseSize; + PcdDxeDb = AllocateZeroPool (PcdDxeDbLen); + ASSERT (PcdDxeDb != NULL); + CopyMem (PcdDxeDb, mPcdDatabase.DxeDb, mPcdDatabase.DxeDb->Length); + mPcdDatabase.DxeDb = PcdDxeDb; + + GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); + if (GuidHob != NULL) { + // + // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM + // should not be included at all. So the GuidHob could + // be NULL. If it is NULL, we just copy over the DXE Default + // Value to PCD Database. + // + PeiDatabase = (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob); + + // + // Get next one that stores full PEI data + // + GuidHob = GetNextGuidHob (&gPcdDataBaseHobGuid, GET_NEXT_HOB (GuidHob)); + if (GuidHob != NULL) { + mPeiPcdDbBinary = (PEI_PCD_DATABASE *)GET_GUID_HOB_DATA (GuidHob); + mPeiPcdDbSize = (UINTN)GET_GUID_HOB_DATA_SIZE (GuidHob); + } + + // + // Assign PCD Entries refereneced in PEI phase to PCD DATABASE + // + mPcdDatabase.PeiDb = PeiDatabase; + // + // Inherit the SystemSkuId from PEI phase. + // + if (mPcdDatabase.PeiDb->SystemSkuId != 0) { + Status = UpdatePcdDatabase (mPcdDatabase.PeiDb->SystemSkuId, FALSE); + ASSERT_EFI_ERROR (Status); + } + + mPcdDatabase.DxeDb->SystemSkuId = mPcdDatabase.PeiDb->SystemSkuId; + } else { + mPcdDatabase.PeiDb = AllocateZeroPool (sizeof (PEI_PCD_DATABASE)); + ASSERT (mPcdDatabase.PeiDb != NULL); + } + + // + // Initialized the external PCD database local variables + // + mPeiLocalTokenCount = mPcdDatabase.PeiDb->LocalTokenCount; + mDxeLocalTokenCount = mPcdDatabase.DxeDb->LocalTokenCount; + + mPeiExMapppingTableSize = mPcdDatabase.PeiDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING); + mDxeExMapppingTableSize = mPcdDatabase.DxeDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING); + mPeiGuidTableSize = mPcdDatabase.PeiDb->GuidTableCount * sizeof (GUID); + mDxeGuidTableSize = mPcdDatabase.DxeDb->GuidTableCount * sizeof (GUID); + + mPcdTotalTokenCount = mPeiLocalTokenCount + mDxeLocalTokenCount; + mPeiNexTokenCount = mPeiLocalTokenCount - mPcdDatabase.PeiDb->ExTokenCount; + mDxeNexTokenCount = mDxeLocalTokenCount - mPcdDatabase.DxeDb->ExTokenCount; + + mPeiExMapTableEmpty = (mPcdDatabase.PeiDb->ExTokenCount == 0) ? TRUE : FALSE; + mDxeExMapTableEmpty = (mPcdDatabase.DxeDb->ExTokenCount == 0) ? TRUE : FALSE; + mPeiDatabaseEmpty = (mPeiLocalTokenCount == 0) ? TRUE : FALSE; + + TmpTokenSpaceBufferCount = mPcdDatabase.PeiDb->ExTokenCount + mPcdDatabase.DxeDb->ExTokenCount; + TmpTokenSpaceBuffer = (EFI_GUID **)AllocateZeroPool (TmpTokenSpaceBufferCount * sizeof (EFI_GUID *)); + + // + // Initialized the Callback Function Table + // + mCallbackFnTable = AllocateZeroPool (mPcdTotalTokenCount * sizeof (LIST_ENTRY)); + ASSERT (mCallbackFnTable != 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. + // + for (Index = 0; Index + 1 < mPcdTotalTokenCount + 1; Index++) { + InitializeListHead (&mCallbackFnTable[Index]); + } +} + +/** + Get Variable which contains HII type PCD entry. + + @param VariableGuid Variable's guid + @param VariableName Variable's unicode name string + @param VariableData Variable's data pointer, + @param VariableSize Variable's size. + + @return the status of gRT->GetVariable +**/ +EFI_STATUS +GetHiiVariable ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + OUT UINT8 **VariableData, + OUT UINTN *VariableSize + ) +{ + UINTN Size; + EFI_STATUS Status; + UINT8 *Buffer; + + Size = 0; + Buffer = NULL; + + // + // Firstly get the real size of HII variable + // + Status = gRT->GetVariable ( + (UINT16 *)VariableName, + VariableGuid, + NULL, + &Size, + Buffer + ); + + // + // Allocate buffer to hold whole variable data according to variable size. + // + if (Status == EFI_BUFFER_TOO_SMALL) { + Buffer = (UINT8 *)AllocatePool (Size); + + ASSERT (Buffer != NULL); + + Status = gRT->GetVariable ( + VariableName, + VariableGuid, + NULL, + &Size, + Buffer + ); + + ASSERT (Status == EFI_SUCCESS); + *VariableData = Buffer; + *VariableSize = Size; + } else { + // + // Use Default Data only when variable is not found. + // For other error status, correct data can't be got, and trig ASSERT(). + // + ASSERT (Status == EFI_NOT_FOUND); + } + + return Status; +} + +/** + 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 ( + UINT32 ExTokenNumber, + CONST EFI_GUID *Guid OPTIONAL, + UINTN TokenNumber, + VOID *Data, + UINTN Size + ) +{ + CALLBACK_FN_ENTRY *FnTableEntry; + LIST_ENTRY *ListHead; + LIST_ENTRY *ListNode; + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index of mCallbackFnTable[]. + // + ListHead = &mCallbackFnTable[TokenNumber - 1]; + ListNode = GetFirstNode (ListHead); + + while (ListNode != ListHead) { + FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node); + + FnTableEntry->CallbackFn ( + Guid, + (Guid == NULL) ? TokenNumber : ExTokenNumber, + Data, + Size + ); + + ListNode = GetNextNode (ListHead, ListNode); + } + + return; +} + +/** + 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 + ) +{ + BOOLEAN IsPeiDb; + UINT32 LocalTokenNumber; + EFI_GUID *GuidTable; + UINT8 *StringTable; + EFI_GUID *Guid; + UINT16 *Name; + UINTN VariableOffset; + UINT32 Attributes; + VOID *InternalData; + VARIABLE_HEAD *VariableHead; + UINTN Offset; + UINT8 *PcdDb; + EFI_STATUS Status; + UINTN MaxSize; + UINTN TmpTokenNumber; + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + TmpTokenNumber = TokenNumber; + + // + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + // + ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1); + + if (PtrType) { + // + // Get MaxSize first, then check new size with max buffer size. + // + GetPtrTypeSize (TokenNumber, &MaxSize); + if (*Size > MaxSize) { + *Size = MaxSize; + return EFI_INVALID_PARAMETER; + } + } else { + if (*Size != DxePcdGetSize (TokenNumber + 1)) { + return EFI_INVALID_PARAMETER; + } + } + + // + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + // + if ((TokenNumber + 1 < mPeiNexTokenCount + 1) || + ((TokenNumber + 1 >= mPeiLocalTokenCount + 1) && (TokenNumber + 1 < (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) + { + InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size); + } + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + // + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + // + IsPeiDb = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE); + + LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1); + + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + + PcdDb = IsPeiDb ? ((UINT8 *)mPcdDatabase.PeiDb) : ((UINT8 *)mPcdDatabase.DxeDb); + + if (IsPeiDb) { + StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset); + } else { + StringTable = (UINT8 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset); + } + + InternalData = PcdDb + Offset; + + switch (LocalTokenNumber & PCD_TYPE_ALL_SET) { + case PCD_TYPE_VPD: + ASSERT (FALSE); + Status = EFI_INVALID_PARAMETER; + break; + + case PCD_TYPE_STRING: + if (SetPtrTypeSize (TmpTokenNumber, Size)) { + CopyMem (StringTable + *((STRING_HEAD *)InternalData), Data, *Size); + Status = EFI_SUCCESS; + } else { + Status = EFI_INVALID_PARAMETER; + } + + break; + + case PCD_TYPE_HII|PCD_TYPE_STRING: + case PCD_TYPE_HII: + if (PtrType) { + if (!SetPtrTypeSize (TmpTokenNumber, Size)) { + Status = EFI_INVALID_PARAMETER; + break; + } + } + + if (IsPeiDb) { + GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset); + } else { + GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset); + } + + VariableHead = (VARIABLE_HEAD *)(PcdDb + Offset); + + Guid = GuidTable + VariableHead->GuidTableIndex; + Name = (UINT16 *)(StringTable + VariableHead->StringIndex); + VariableOffset = VariableHead->Offset; + Attributes = VariableHead->Attributes; + Status = SetHiiVariable (Guid, Name, Attributes, Data, *Size, VariableOffset); + break; + + case PCD_TYPE_DATA: + if (PtrType) { + if (SetPtrTypeSize (TmpTokenNumber, Size)) { + CopyMem (InternalData, Data, *Size); + Status = EFI_SUCCESS; + } else { + Status = EFI_INVALID_PARAMETER; + } + + break; + } + + Status = EFI_SUCCESS; + switch (*Size) { + case sizeof (UINT8): + *((UINT8 *)InternalData) = *((UINT8 *)Data); + break; + + case sizeof (UINT16): + *((UINT16 *)InternalData) = *((UINT16 *)Data); + break; + + case sizeof (UINT32): + *((UINT32 *)InternalData) = *((UINT32 *)Data); + break; + + case sizeof (UINT64): + *((UINT64 *)InternalData) = *((UINT64 *)Data); + break; + + default: + ASSERT (FALSE); + Status = EFI_NOT_FOUND; + break; + } + + break; + + default: + ASSERT (FALSE); + Status = EFI_NOT_FOUND; + break; + } + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; +} + +/** + Wrapper function for get PCD value for dynamic-ex PCD. + + @param Guid Token space guid for dynamic-ex PCD. + @param ExTokenNumber Token number for dynamic-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, (UINT32)ExTokenNumber), GetSize); +} + +/** + 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 SetSize + ) +{ + return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, 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 *SetSize, + IN BOOLEAN PtrType + ) +{ + UINTN TokenNumber; + + TokenNumber = GetExPcdTokenNumber (Guid, (UINT32)ExTokenNumber); + + InvokeCallbackOnSet ((UINT32)ExTokenNumber, Guid, TokenNumber, Data, *SetSize); + + return SetWorker (TokenNumber, Data, SetSize, PtrType); +} + +/** + Get variable size and data from HII-type PCDs. + + @param[in] VariableGuid Guid of variable which stored value of a HII-type PCD. + @param[in] VariableName Unicode name of variable which stored value of a HII-type PCD. + @param[out] VariableSize Pointer to variable size got from HII-type PCDs. + @param[out] VariableData Pointer to variable data got from HII-type PCDs. + +**/ +VOID +GetVariableSizeAndDataFromHiiPcd ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + OUT UINTN *VariableSize, + OUT VOID *VariableData OPTIONAL + ) +{ + BOOLEAN IsPeiDb; + PCD_DATABASE_INIT *Database; + UINTN TokenNumber; + UINT32 LocalTokenNumber; + UINTN Offset; + EFI_GUID *GuidTable; + UINT8 *StringTable; + VARIABLE_HEAD *VariableHead; + EFI_GUID *Guid; + UINT16 *Name; + UINTN PcdDataSize; + UINTN Size; + UINT8 *VaraiableDefaultBuffer; + STRING_HEAD StringTableIdx; + + *VariableSize = 0; + + // + // Go through PCD database to find out DynamicHii PCDs. + // + for (TokenNumber = 1; TokenNumber <= mPcdTotalTokenCount; TokenNumber++) { + IsPeiDb = (BOOLEAN)((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE); + Database = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb; + LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber); + if ((LocalTokenNumber & PCD_TYPE_HII) != 0) { + // + // Get the Variable Guid and Name pointer. + // + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + VariableHead = (VARIABLE_HEAD *)((UINT8 *)Database + Offset); + StringTable = (UINT8 *)((UINT8 *)Database + Database->StringTableOffset); + GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset); + Guid = GuidTable + VariableHead->GuidTableIndex; + Name = (UINT16 *)(StringTable + VariableHead->StringIndex); + if (CompareGuid (VariableGuid, Guid) && (StrCmp (VariableName, Name) == 0)) { + // + // It is the matched DynamicHii PCD. + // + PcdDataSize = DxePcdGetSize (TokenNumber); + Size = VariableHead->Offset + PcdDataSize; + if (Size > *VariableSize) { + *VariableSize = Size; + } + + if (VariableData != NULL) { + 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. + // + StringTableIdx = *(STRING_HEAD *)((UINT8 *)Database + VariableHead->DefaultValueOffset); + VaraiableDefaultBuffer = (UINT8 *)(StringTable + StringTableIdx); + } else { + VaraiableDefaultBuffer = (UINT8 *)Database + VariableHead->DefaultValueOffset; + } + + CopyMem ((UINT8 *)VariableData + VariableHead->Offset, VaraiableDefaultBuffer, PcdDataSize); + } + } + } + } +} + +/** + Set value for HII-type PCD. + + A HII-type PCD's value is stored in a variable. Setting/Getting the value of + HII-type PCD is to visit this variable. + + @param VariableGuid Guid of variable which stored value of a HII-type PCD. + @param VariableName Unicode name of variable which stored value of a HII-type PCD. + @param SetAttributes Attributes bitmask to set for the variable. + @param Data Value want to be set. + @param DataSize Size of value + @param Offset Value offset of HII-type PCD in variable. + + @return status of GetVariable()/SetVariable(). + +**/ +EFI_STATUS +SetHiiVariable ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + IN UINT32 SetAttributes, + IN CONST VOID *Data, + IN UINTN DataSize, + IN UINTN Offset + ) +{ + UINTN Size; + VOID *Buffer; + EFI_STATUS Status; + UINT32 Attribute; + UINTN SetSize; + + Size = 0; + SetSize = 0; + + // + // Try to get original variable size information. + // + Status = gRT->GetVariable ( + (UINT16 *)VariableName, + VariableGuid, + NULL, + &Size, + NULL + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // Patch new PCD's value to offset in given HII variable. + // + if (Size >= (DataSize + Offset)) { + SetSize = Size; + } else { + SetSize = DataSize + Offset; + } + + Buffer = AllocatePool (SetSize); + ASSERT (Buffer != NULL); + + Status = gRT->GetVariable ( + VariableName, + VariableGuid, + &Attribute, + &Size, + Buffer + ); + + ASSERT_EFI_ERROR (Status); + + CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize); + + if (SetAttributes == 0) { + SetAttributes = Attribute; + } + + Status = gRT->SetVariable ( + VariableName, + VariableGuid, + SetAttributes, + SetSize, + Buffer + ); + + FreePool (Buffer); + return Status; + } else if (Status == EFI_NOT_FOUND) { + // + // If variable does not exist, a new variable need to be created. + // + + // + // Get size, allocate buffer and get data. + // + GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, NULL); + Buffer = AllocateZeroPool (Size); + ASSERT (Buffer != NULL); + GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, Buffer); + + // + // Update buffer. + // + CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize); + + if (SetAttributes == 0) { + SetAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE; + } + + Status = gRT->SetVariable ( + VariableName, + VariableGuid, + SetAttributes, + Size, + Buffer + ); + + FreePool (Buffer); + return Status; + } + + // + // If we drop to here, the value is failed to be written in to variable area. + // + return Status; +} + +/** + 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 UINT32 ExTokenNumber + ) +{ + UINT32 Index; + DYNAMICEX_MAPPING *ExMap; + EFI_GUID *GuidTable; + EFI_GUID *MatchGuid; + UINTN MatchGuidIdx; + + if (!mPeiDatabaseEmpty) { + ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset); + GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset); + + MatchGuid = ScanGuid (GuidTable, mPeiGuidTableSize, Guid); + + if (MatchGuid != NULL) { + MatchGuidIdx = MatchGuid - GuidTable; + + for (Index = 0; Index < mPcdDatabase.PeiDb->ExTokenCount; Index++) { + if ((ExTokenNumber == ExMap[Index].ExTokenNumber) && + (MatchGuidIdx == ExMap[Index].ExGuidIndex)) + { + return ExMap[Index].TokenNumber; + } + } + } + } + + ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset); + GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset); + + MatchGuid = ScanGuid (GuidTable, mDxeGuidTableSize, 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 < mPcdDatabase.DxeDb->ExTokenCount; Index++) { + if ((ExTokenNumber == ExMap[Index].ExTokenNumber) && + (MatchGuidIdx == ExMap[Index].ExGuidIndex)) + { + return ExMap[Index].TokenNumber; + } + } + + DEBUG ((DEBUG_ERROR, "%a: Failed to find PCD with GUID: %g and token number: %d\n", __func__, Guid, ExTokenNumber)); + ASSERT (FALSE); + + return 0; +} + +/** + Wrapper function of getting index of PCD entry in size table. + + @param LocalTokenNumberTableIdx Index of this PCD in local token number table. + @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase, + If FALSE, the pcd entry is initialized in DXE phase. + + @return index of PCD entry in size table. +**/ +UINTN +GetSizeTableIndex ( + IN UINTN LocalTokenNumberTableIdx, + IN BOOLEAN IsPeiDb + ) +{ + UINT32 *LocalTokenNumberTable; + UINTN LocalTokenNumber; + UINTN Index; + UINTN SizeTableIdx; + + if (IsPeiDb) { + LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset); + } else { + LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset); + } + + SizeTableIdx = 0; + + for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) { + LocalTokenNumber = LocalTokenNumberTable[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 { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTableIdx += 2; + } + } + } + + return SizeTableIdx; +} + +/** + Get size of POINTER type PCD value. + + @param LocalTokenNumberTableIdx Index of local token number in local token number table. + @param MaxSize Maxmium size of POINTER type PCD value. + + @return size of POINTER type PCD value. + +**/ +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SIZE_INFO *SizeTable; + BOOLEAN IsPeiDb; + UINT32 *LocalTokenNumberTable; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb = (BOOLEAN)(LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1); + + if (IsPeiDb) { + LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset); + SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset); + } else { + LocalTokenNumberTableIdx -= mPeiLocalTokenCount; + LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset); + SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset); + } + + LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb); + + *MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if ((LocalTokenNumber & PCD_TYPE_VPD) != 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 { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + return SizeTable[SizeTableIdx + 1]; + } +} + +/** + Set size of POINTER type PCD value. The size should not exceed the maximum size + of this PCD value. + + @param LocalTokenNumberTableIdx Index of local token number in local token number table. + @param CurrentSize Size of POINTER type PCD value. + + @retval TRUE Success to set size of PCD value. + @retval FALSE Fail to set size of PCD value. +**/ +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SIZE_INFO *SizeTable; + UINTN MaxSize; + BOOLEAN IsPeiDb; + UINT32 *LocalTokenNumberTable; + + // + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + // + IsPeiDb = (BOOLEAN)(LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1); + + if (IsPeiDb) { + LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset); + SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset); + } else { + LocalTokenNumberTableIdx -= mPeiLocalTokenCount; + LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset); + SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset); + } + + LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx]; + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER); + + SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb); + + MaxSize = SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if ((LocalTokenNumber & PCD_TYPE_VPD) != 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; + } + + // + // 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; + } +} + +/** + VariableLock DynamicHiiPcd. + + @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase, + If FALSE, the pcd entry is initialized in DXE phase. + @param[in] VariableLock Pointer to VariableLockProtocol. + +**/ +VOID +VariableLockDynamicHiiPcd ( + IN BOOLEAN IsPeiDb, + IN EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock + ) +{ + EFI_STATUS Status; + PCD_DATABASE_INIT *Database; + UINT32 LocalTokenCount; + UINTN TokenNumber; + UINT32 LocalTokenNumber; + UINTN Offset; + EFI_GUID *GuidTable; + UINT8 *StringTable; + VARIABLE_HEAD *VariableHead; + EFI_GUID *Guid; + UINT16 *Name; + + Database = IsPeiDb ? mPcdDatabase.PeiDb : mPcdDatabase.DxeDb; + LocalTokenCount = IsPeiDb ? mPeiLocalTokenCount : mDxeLocalTokenCount; + + // + // Go through PCD database to find out DynamicHii PCDs. + // + for (TokenNumber = 1; TokenNumber <= LocalTokenCount; TokenNumber++) { + if (IsPeiDb) { + LocalTokenNumber = GetLocalTokenNumber (TRUE, TokenNumber); + } else { + LocalTokenNumber = GetLocalTokenNumber (FALSE, TokenNumber + mPeiLocalTokenCount); + } + + if ((LocalTokenNumber & PCD_TYPE_HII) != 0) { + Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK; + VariableHead = (VARIABLE_HEAD *)((UINT8 *)Database + Offset); + // + // Why not to set property by VarCheckProtocol with Attributes and Property directly here? + // It is because that set property by VarCheckProtocol will indicate the variable to + // be a system variable, but the unknown max size of the variable is dangerous to + // the system variable region. + // + if ((VariableHead->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0) { + // + // DynamicHii PCD with RO property set in *.dsc. + // + StringTable = (UINT8 *)((UINT8 *)Database + Database->StringTableOffset); + GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset); + Guid = GuidTable + VariableHead->GuidTableIndex; + Name = (UINT16 *)(StringTable + VariableHead->StringIndex); + Status = VariableLock->RequestToLock (VariableLock, Name, Guid); + ASSERT_EFI_ERROR (Status); + } + } + } +} + +/** + VariableLockProtocol callback + to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +VariableLockCallBack ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; + + Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock); + if (!EFI_ERROR (Status)) { + VariableLockDynamicHiiPcd (TRUE, VariableLock); + VariableLockDynamicHiiPcd (FALSE, VariableLock); + } +} diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.h b/MdeModulePkg/Universal/PCD/Dxe/Service.h index 6f4a6c72ff..33baba8a1d 100644 --- a/MdeModulePkg/Universal/PCD/Dxe/Service.h +++ b/MdeModulePkg/Universal/PCD/Dxe/Service.h @@ -1,1193 +1,1193 @@ -/** @file
-Private functions used by PCD DXE driver.
-
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _PCD_DXE_SERVICE_H_
-#define _PCD_DXE_SERVICE_H_
-
-#include <PiDxe.h>
-#include <Guid/PcdDataBaseHobGuid.h>
-#include <Guid/PcdDataBaseSignatureGuid.h>
-#include <Protocol/Pcd.h>
-#include <Protocol/PiPcd.h>
-#include <Protocol/PcdInfo.h>
-#include <Protocol/PiPcdInfo.h>
-#include <Protocol/VarCheck.h>
-#include <Protocol/VariableLock.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/PcdLib.h>
-#include <Library/HobLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-
-//
-// Please make sure the PCD Serivce DXE Version is consistent with
-// the version of the generated DXE PCD Database by build tool.
-//
-#define PCD_SERVICE_DXE_VERSION 7
-
-//
-// PCD_DXE_SERVICE_DRIVER_VERSION is defined in Autogen.h.
-//
-#if (PCD_SERVICE_DXE_VERSION != PCD_DXE_SERVICE_DRIVER_VERSION)
- #error "Please make sure the version of PCD DXE Service and the generated PCD DXE Database match."
-#endif
-
-extern UINTN mVpdBaseAddress;
-
-/**
- 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
-DxeGetPcdInfoGetInfo (
- 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
-DxeGetPcdInfoGetInfoEx (
- 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
-DxeGetPcdInfoGetSku (
- VOID
- );
-
-//
-// Protocol Interface function 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
-DxePcdSetSku (
- 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
-DxePcdGet8 (
- 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
-DxePcdGet16 (
- 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
-DxePcdGet32 (
- 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
-DxePcdGet64 (
- 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 retrieved.
-
-**/
-VOID *
-EFIAPI
-DxePcdGetPtr (
- 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
-DxePcdGetBool (
- 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
-DxePcdGetSize (
- 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
-DxePcdGet8Ex (
- 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
-DxePcdGet16Ex (
- 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
-DxePcdGet32Ex (
- 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
-DxePcdGet64Ex (
- 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 retrieved.
-
-**/
-VOID *
-EFIAPI
-DxePcdGetPtrEx (
- 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
-DxePcdGetBoolEx (
- 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
-DxePcdGetSizeEx (
- 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
-DxePcdSet8 (
- 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
-DxePcdSet16 (
- 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
-DxePcdSet32 (
- 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
-DxePcdSet64 (
- 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
-DxePcdSetPtr (
- 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
-DxePcdSetBool (
- 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
-DxePcdSet8Ex (
- 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
-DxePcdSet16Ex (
- 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
-DxePcdSet32Ex (
- 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
-DxePcdSet64Ex (
- 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
-DxePcdSetPtrEx (
- 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
-DxePcdSetBoolEx (
- 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
-DxeRegisterCallBackOnSet (
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN UINTN TokenNumber,
- IN PCD_PROTOCOL_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
-DxeUnRegisterCallBackOnSet (
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN UINTN TokenNumber,
- IN PCD_PROTOCOL_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 retrieve the next token.
- 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 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
-DxePcdGetNextToken (
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN OUT UINTN *TokenNumber
- );
-
-/**
- Get next token space in PCD database according to given token space guid.
-
- @param Guid Given token space guid. If NULL, then Guid will be set to
- the first PCD token space in PCD database, If not NULL, then
- Guid will be set to next PCD token space.
-
- @retval EFI_NOT_FOUND If PCD database has no token space table or can not find given
- token space in PCD database.
- @retval EFI_SUCCESS Success to get next token space guid.
-**/
-EFI_STATUS
-EFIAPI
-DxePcdGetNextTokenSpace (
- IN OUT CONST EFI_GUID **Guid
- );
-
-typedef struct {
- LIST_ENTRY Node;
- PCD_PROTOCOL_CALLBACK CallbackFn;
-} CALLBACK_FN_ENTRY;
-
-#define CR_FNENTRY_FROM_LISTNODE(Record, Type, Field) BASE_CR(Record, Type, Field)
-
-//
-// Internal Functions
-//
-
-/**
- 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
-DxeGetPcdInfo (
- IN CONST EFI_GUID *Guid,
- IN UINTN TokenNumber,
- OUT EFI_PCD_INFO *PcdInfo
- );
-
-/**
- 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 SetSize
- );
-
-/**
- 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 dynamic-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
- );
-
-/**
- Get Variable which contains HII type PCD entry.
-
- @param VariableGuid Variable's guid
- @param VariableName Variable's unicode name string
- @param VariableData Variable's data pointer,
- @param VariableSize Variable's size.
-
- @return the status of gRT->GetVariable
-**/
-EFI_STATUS
-GetHiiVariable (
- IN EFI_GUID *VariableGuid,
- IN UINT16 *VariableName,
- OUT UINT8 **VariableData,
- OUT UINTN *VariableSize
- );
-
-/**
- Set value for HII-type PCD.
-
- A HII-type PCD's value is stored in a variable. Setting/Getting the value of
- HII-type PCD is to visit this variable.
-
- @param VariableGuid Guid of variable which stored value of a HII-type PCD.
- @param VariableName Unicode name of variable which stored value of a HII-type PCD.
- @param SetAttributes Attributes bitmask to set for the variable.
- @param Data Value want to be set.
- @param DataSize Size of value
- @param Offset Value offset of HII-type PCD in variable.
-
- @return status of GetVariable()/SetVariable().
-
-**/
-EFI_STATUS
-SetHiiVariable (
- IN EFI_GUID *VariableGuid,
- IN UINT16 *VariableName,
- IN UINT32 SetAttributes,
- IN CONST VOID *Data,
- IN UINTN DataSize,
- IN UINTN Offset
- );
-
-/**
- Register the callback function for a PCD entry.
-
- This routine will register a callback function to a PCD entry by given token number
- and token space guid.
-
- @param TokenNumber PCD token's number, it is autogened by build tools.
- @param Guid PCD token space's guid,
- if not NULL, this PCD is dynamicEx type PCD.
- @param CallBackFunction Callback function pointer
-
- @return EFI_SUCCESS Always success for registering callback function.
-
-**/
-EFI_STATUS
-DxeRegisterCallBackWorker (
- IN UINTN TokenNumber,
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN PCD_PROTOCOL_CALLBACK CallBackFunction
- );
-
-/**
- UnRegister the callback function for a PCD entry.
-
- This routine will unregister a callback function to a PCD entry by given token number
- and token space guid.
-
- @param TokenNumber PCD token's number, it is autogened by build tools.
- @param Guid PCD token space's guid.
- if not NULL, this PCD is dynamicEx type PCD.
- @param CallBackFunction Callback function pointer
-
- @retval EFI_SUCCESS Callback function is success to be unregister.
- @retval EFI_INVALID_PARAMETER Can not find the PCD entry by given token number.
-**/
-EFI_STATUS
-DxeUnRegisterCallBackWorker (
- IN UINTN TokenNumber,
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN PCD_PROTOCOL_CALLBACK CallBackFunction
- );
-
-/**
- Initialize the PCD database in DXE phase.
-
- PCD database in DXE phase also contains PCD database in PEI phase which is copied
- from GUID Hob.
-
-**/
-VOID
-BuildPcdDxeDataBase (
- VOID
- );
-
-/**
- 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 UINT32 ExTokenNumber
- );
-
-/**
- Get next token number in given token space.
-
- This routine is used for dynamicEx type PCD. It will firstly scan token space
- table to get token space according to given token space guid. Then scan given
- token number in found token space, if found, then return next token number in
- this token space.
-
- @param Guid Token space guid. Next token number will be scaned in
- this token space.
- @param TokenNumber Token number.
- If PCD_INVALID_TOKEN_NUMBER, return first token number in
- token space table.
- If not PCD_INVALID_TOKEN_NUMBER, return next token number
- in token space table.
- @param GuidTable Token space guid table. It will be used for scan token space
- by given token space guid.
- @param SizeOfGuidTable The size of guid table.
- @param ExMapTable DynamicEx token number mapping table.
- @param SizeOfExMapTable The size of dynamicEx token number mapping table.
-
- @retval EFI_NOT_FOUND Can not given token space or token number.
- @retval EFI_SUCCESS Success to get next token number.
-
-**/
-EFI_STATUS
-ExGetNextTokeNumber (
- IN CONST EFI_GUID *Guid,
- IN OUT UINTN *TokenNumber,
- IN EFI_GUID *GuidTable,
- IN UINTN SizeOfGuidTable,
- IN DYNAMICEX_MAPPING *ExMapTable,
- IN UINTN SizeOfExMapTable
- );
-
-/**
- Get size of POINTER type PCD value.
-
- @param LocalTokenNumberTableIdx Index of local token number in local token number table.
- @param MaxSize Maximum size of POINTER type PCD value.
-
- @return size of POINTER type PCD value.
-
-**/
-UINTN
-GetPtrTypeSize (
- IN UINTN LocalTokenNumberTableIdx,
- OUT UINTN *MaxSize
- );
-
-/**
- Set size of POINTER type PCD value. The size should not exceed the maximum size
- of this PCD value.
-
- @param LocalTokenNumberTableIdx Index of local token number in local token number table.
- @param CurrentSize Size of POINTER type PCD value.
-
- @retval TRUE Success to set size of PCD value.
- @retval FALSE Fail to set size of PCD value.
-**/
-BOOLEAN
-SetPtrTypeSize (
- IN UINTN LocalTokenNumberTableIdx,
- IN OUT UINTN *CurrentSize
- );
-
-/**
- VariableLockProtocol callback
- to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-VariableLockCallBack (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-/**
- Update PCD database base on current SkuId
-
- @param SkuId Current SkuId
- @param IsPeiDb Whether to update PEI PCD database.
-
- @retval EFI_SUCCESS Update PCD database successfully.
- @retval EFI_NOT_FOUND Not found PCD database for current SkuId.
-**/
-EFI_STATUS
-UpdatePcdDatabase (
- IN SKU_ID SkuId,
- IN BOOLEAN IsPeiDb
- );
-
-extern PCD_DATABASE mPcdDatabase;
-
-extern UINT32 mPcdTotalTokenCount;
-extern UINT32 mPeiLocalTokenCount;
-extern UINT32 mDxeLocalTokenCount;
-extern UINT32 mPeiNexTokenCount;
-extern UINT32 mDxeNexTokenCount;
-extern UINT32 mPeiExMapppingTableSize;
-extern UINT32 mDxeExMapppingTableSize;
-extern UINT32 mPeiGuidTableSize;
-extern UINT32 mDxeGuidTableSize;
-
-extern BOOLEAN mPeiExMapTableEmpty;
-extern BOOLEAN mDxeExMapTableEmpty;
-extern BOOLEAN mPeiDatabaseEmpty;
-
-extern EFI_GUID **TmpTokenSpaceBuffer;
-extern UINTN TmpTokenSpaceBufferCount;
-
-extern EFI_LOCK mPcdDatabaseLock;
-
-#endif
+/** @file +Private functions used by PCD DXE driver. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _PCD_DXE_SERVICE_H_ +#define _PCD_DXE_SERVICE_H_ + +#include <PiDxe.h> +#include <Guid/PcdDataBaseHobGuid.h> +#include <Guid/PcdDataBaseSignatureGuid.h> +#include <Protocol/Pcd.h> +#include <Protocol/PiPcd.h> +#include <Protocol/PcdInfo.h> +#include <Protocol/PiPcdInfo.h> +#include <Protocol/VarCheck.h> +#include <Protocol/VariableLock.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiDriverEntryPoint.h> +#include <Library/PcdLib.h> +#include <Library/HobLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> + +// +// Please make sure the PCD Serivce DXE Version is consistent with +// the version of the generated DXE PCD Database by build tool. +// +#define PCD_SERVICE_DXE_VERSION 7 + +// +// PCD_DXE_SERVICE_DRIVER_VERSION is defined in Autogen.h. +// +#if (PCD_SERVICE_DXE_VERSION != PCD_DXE_SERVICE_DRIVER_VERSION) + #error "Please make sure the version of PCD DXE Service and the generated PCD DXE Database match." +#endif + +extern UINTN mVpdBaseAddress; + +/** + 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 +DxeGetPcdInfoGetInfo ( + 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 +DxeGetPcdInfoGetInfoEx ( + 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 +DxeGetPcdInfoGetSku ( + VOID + ); + +// +// Protocol Interface function 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 +DxePcdSetSku ( + 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 +DxePcdGet8 ( + 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 +DxePcdGet16 ( + 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 +DxePcdGet32 ( + 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 +DxePcdGet64 ( + 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 retrieved. + +**/ +VOID * +EFIAPI +DxePcdGetPtr ( + 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 +DxePcdGetBool ( + 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 +DxePcdGetSize ( + 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 +DxePcdGet8Ex ( + 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 +DxePcdGet16Ex ( + 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 +DxePcdGet32Ex ( + 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 +DxePcdGet64Ex ( + 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 retrieved. + +**/ +VOID * +EFIAPI +DxePcdGetPtrEx ( + 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 +DxePcdGetBoolEx ( + 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 +DxePcdGetSizeEx ( + 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 +DxePcdSet8 ( + 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 +DxePcdSet16 ( + 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 +DxePcdSet32 ( + 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 +DxePcdSet64 ( + 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 +DxePcdSetPtr ( + 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 +DxePcdSetBool ( + 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 +DxePcdSet8Ex ( + 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 +DxePcdSet16Ex ( + 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 +DxePcdSet32Ex ( + 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 +DxePcdSet64Ex ( + 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 +DxePcdSetPtrEx ( + 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 +DxePcdSetBoolEx ( + 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 +DxeRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN TokenNumber, + IN PCD_PROTOCOL_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 +DxeUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN TokenNumber, + IN PCD_PROTOCOL_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 retrieve the next token. + 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 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 +DxePcdGetNextToken ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN OUT UINTN *TokenNumber + ); + +/** + Get next token space in PCD database according to given token space guid. + + @param Guid Given token space guid. If NULL, then Guid will be set to + the first PCD token space in PCD database, If not NULL, then + Guid will be set to next PCD token space. + + @retval EFI_NOT_FOUND If PCD database has no token space table or can not find given + token space in PCD database. + @retval EFI_SUCCESS Success to get next token space guid. +**/ +EFI_STATUS +EFIAPI +DxePcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ); + +typedef struct { + LIST_ENTRY Node; + PCD_PROTOCOL_CALLBACK CallbackFn; +} CALLBACK_FN_ENTRY; + +#define CR_FNENTRY_FROM_LISTNODE(Record, Type, Field) BASE_CR(Record, Type, Field) + +// +// Internal Functions +// + +/** + 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 +DxeGetPcdInfo ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ); + +/** + 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 SetSize + ); + +/** + 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 dynamic-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 + ); + +/** + Get Variable which contains HII type PCD entry. + + @param VariableGuid Variable's guid + @param VariableName Variable's unicode name string + @param VariableData Variable's data pointer, + @param VariableSize Variable's size. + + @return the status of gRT->GetVariable +**/ +EFI_STATUS +GetHiiVariable ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + OUT UINT8 **VariableData, + OUT UINTN *VariableSize + ); + +/** + Set value for HII-type PCD. + + A HII-type PCD's value is stored in a variable. Setting/Getting the value of + HII-type PCD is to visit this variable. + + @param VariableGuid Guid of variable which stored value of a HII-type PCD. + @param VariableName Unicode name of variable which stored value of a HII-type PCD. + @param SetAttributes Attributes bitmask to set for the variable. + @param Data Value want to be set. + @param DataSize Size of value + @param Offset Value offset of HII-type PCD in variable. + + @return status of GetVariable()/SetVariable(). + +**/ +EFI_STATUS +SetHiiVariable ( + IN EFI_GUID *VariableGuid, + IN UINT16 *VariableName, + IN UINT32 SetAttributes, + IN CONST VOID *Data, + IN UINTN DataSize, + IN UINTN Offset + ); + +/** + Register the callback function for a PCD entry. + + This routine will register a callback function to a PCD entry by given token number + and token space guid. + + @param TokenNumber PCD token's number, it is autogened by build tools. + @param Guid PCD token space's guid, + if not NULL, this PCD is dynamicEx type PCD. + @param CallBackFunction Callback function pointer + + @return EFI_SUCCESS Always success for registering callback function. + +**/ +EFI_STATUS +DxeRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST EFI_GUID *Guid OPTIONAL, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ); + +/** + UnRegister the callback function for a PCD entry. + + This routine will unregister a callback function to a PCD entry by given token number + and token space guid. + + @param TokenNumber PCD token's number, it is autogened by build tools. + @param Guid PCD token space's guid. + if not NULL, this PCD is dynamicEx type PCD. + @param CallBackFunction Callback function pointer + + @retval EFI_SUCCESS Callback function is success to be unregister. + @retval EFI_INVALID_PARAMETER Can not find the PCD entry by given token number. +**/ +EFI_STATUS +DxeUnRegisterCallBackWorker ( + IN UINTN TokenNumber, + IN CONST EFI_GUID *Guid OPTIONAL, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ); + +/** + Initialize the PCD database in DXE phase. + + PCD database in DXE phase also contains PCD database in PEI phase which is copied + from GUID Hob. + +**/ +VOID +BuildPcdDxeDataBase ( + VOID + ); + +/** + 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 UINT32 ExTokenNumber + ); + +/** + Get next token number in given token space. + + This routine is used for dynamicEx type PCD. It will firstly scan token space + table to get token space according to given token space guid. Then scan given + token number in found token space, if found, then return next token number in + this token space. + + @param Guid Token space guid. Next token number will be scaned in + this token space. + @param TokenNumber Token number. + If PCD_INVALID_TOKEN_NUMBER, return first token number in + token space table. + If not PCD_INVALID_TOKEN_NUMBER, return next token number + in token space table. + @param GuidTable Token space guid table. It will be used for scan token space + by given token space guid. + @param SizeOfGuidTable The size of guid table. + @param ExMapTable DynamicEx token number mapping table. + @param SizeOfExMapTable The size of dynamicEx token number mapping table. + + @retval EFI_NOT_FOUND Can not given token space or token number. + @retval EFI_SUCCESS Success to get next token number. + +**/ +EFI_STATUS +ExGetNextTokeNumber ( + IN CONST EFI_GUID *Guid, + IN OUT UINTN *TokenNumber, + IN EFI_GUID *GuidTable, + IN UINTN SizeOfGuidTable, + IN DYNAMICEX_MAPPING *ExMapTable, + IN UINTN SizeOfExMapTable + ); + +/** + Get size of POINTER type PCD value. + + @param LocalTokenNumberTableIdx Index of local token number in local token number table. + @param MaxSize Maximum size of POINTER type PCD value. + + @return size of POINTER type PCD value. + +**/ +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize + ); + +/** + Set size of POINTER type PCD value. The size should not exceed the maximum size + of this PCD value. + + @param LocalTokenNumberTableIdx Index of local token number in local token number table. + @param CurrentSize Size of POINTER type PCD value. + + @retval TRUE Success to set size of PCD value. + @retval FALSE Fail to set size of PCD value. +**/ +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize + ); + +/** + VariableLockProtocol callback + to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +VariableLockCallBack ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Update PCD database base on current SkuId + + @param SkuId Current SkuId + @param IsPeiDb Whether to update PEI PCD database. + + @retval EFI_SUCCESS Update PCD database successfully. + @retval EFI_NOT_FOUND Not found PCD database for current SkuId. +**/ +EFI_STATUS +UpdatePcdDatabase ( + IN SKU_ID SkuId, + IN BOOLEAN IsPeiDb + ); + +extern PCD_DATABASE mPcdDatabase; + +extern UINT32 mPcdTotalTokenCount; +extern UINT32 mPeiLocalTokenCount; +extern UINT32 mDxeLocalTokenCount; +extern UINT32 mPeiNexTokenCount; +extern UINT32 mDxeNexTokenCount; +extern UINT32 mPeiExMapppingTableSize; +extern UINT32 mDxeExMapppingTableSize; +extern UINT32 mPeiGuidTableSize; +extern UINT32 mDxeGuidTableSize; + +extern BOOLEAN mPeiExMapTableEmpty; +extern BOOLEAN mDxeExMapTableEmpty; +extern BOOLEAN mPeiDatabaseEmpty; + +extern EFI_GUID **TmpTokenSpaceBuffer; +extern UINTN TmpTokenSpaceBufferCount; + +extern EFI_LOCK mPcdDatabaseLock; + +#endif diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.c b/MdeModulePkg/Universal/PCD/Pei/Pcd.c index c51ac96a32..08cbf5c274 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Pcd.c +++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.c @@ -1,1754 +1,1754 @@ -/** @file
- All Pcd Ppi services are implemented here.
-
-Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
-(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#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
- }
-};
-
-/**
- Callback on SET PcdSetNvStoreDefaultId
-
- Once PcdSetNvStoreDefaultId is set, the default NV storage will be found from
- PcdNvStoreDefaultValueBuffer, and built into VariableHob.
-
- @param[in] CallBackGuid The PCD token GUID being set.
- @param[in] CallBackToken The PCD token number being set.
- @param[in, out] TokenData A pointer to the token data being set.
- @param[in] TokenDataSize The size, in bytes, of the data being set.
-
-**/
-VOID
-EFIAPI
-PcdSetNvStoreDefaultIdCallBack (
- IN CONST EFI_GUID *CallBackGuid OPTIONAL,
- IN UINTN CallBackToken,
- IN OUT VOID *TokenData,
- IN UINTN TokenDataSize
- )
-{
- EFI_STATUS Status;
- UINT16 DefaultId;
- SKU_ID SkuId;
- UINTN FullSize;
- UINTN Index;
- UINT8 *DataBuffer;
- UINT8 *VarStoreHobData;
- UINT8 *BufferEnd;
- BOOLEAN IsFound;
- VARIABLE_STORE_HEADER *NvStoreBuffer;
- PCD_DEFAULT_DATA *DataHeader;
- PCD_DEFAULT_INFO *DefaultInfo;
- PCD_DATA_DELTA *DeltaData;
-
- DefaultId = *(UINT16 *)TokenData;
- SkuId = GetPcdDatabase ()->SystemSkuId;
- IsFound = FALSE;
-
- if (PeiPcdGetSizeEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvStoreDefaultValueBuffer)) > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {
- DataBuffer = (UINT8 *)PeiPcdGetPtrEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvStoreDefaultValueBuffer));
- FullSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Length;
- DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));
- //
- // The first section data includes NV storage default setting.
- //
- NvStoreBuffer = (VARIABLE_STORE_HEADER *)((UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);
- VarStoreHobData = (UINT8 *)BuildGuidHob (&NvStoreBuffer->Signature, NvStoreBuffer->Size);
- ASSERT (VarStoreHobData != NULL);
- CopyMem (VarStoreHobData, NvStoreBuffer, NvStoreBuffer->Size);
- //
- // Find the matched SkuId and DefaultId in the first section
- //
- DefaultInfo = &(DataHeader->DefaultInfo[0]);
- BufferEnd = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;
- while ((UINT8 *)DefaultInfo < BufferEnd) {
- if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == SkuId)) {
- IsFound = TRUE;
- break;
- }
-
- DefaultInfo++;
- }
-
- //
- // Find the matched SkuId and DefaultId in the remaining section
- //
- Index = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));
- DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index);
- while (!IsFound && Index < FullSize && DataHeader->DataSize != 0xFFFFFFFF) {
- DefaultInfo = &(DataHeader->DefaultInfo[0]);
- BufferEnd = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;
- while ((UINT8 *)DefaultInfo < BufferEnd) {
- if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == SkuId)) {
- IsFound = TRUE;
- break;
- }
-
- DefaultInfo++;
- }
-
- if (IsFound) {
- DeltaData = (PCD_DATA_DELTA *)BufferEnd;
- BufferEnd = (UINT8 *)DataHeader + DataHeader->DataSize;
- while ((UINT8 *)DeltaData < BufferEnd) {
- *(VarStoreHobData + DeltaData->Offset) = (UINT8)DeltaData->Value;
- DeltaData++;
- }
-
- break;
- }
-
- Index = (Index + DataHeader->DataSize + 7) & (~7);
- DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index);
- }
- }
-
- Status = PcdUnRegisterCallBackOnSet (
- &gEfiMdeModulePkgTokenSpaceGuid,
- PcdToken (PcdSetNvStoreDefaultId),
- PcdSetNvStoreDefaultIdCallBack
- );
- ASSERT_EFI_ERROR (Status);
-}
-
-/**
- Report Pei PCD database of all SKUs as Guid HOB so that DxePcd can access it.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
- @param NotifyDescriptor Address of the notification descriptor data structure.
- @param Ppi Address of the PPI that was installed.
-
- @retval EFI_SUCCESS Successfully update the Boot records.
-**/
-EFI_STATUS
-EFIAPI
-EndOfPeiSignalPpiNotifyCallback (
- IN EFI_PEI_SERVICES **PeiServices,
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
- IN VOID *Ppi
- )
-{
- PEI_PCD_DATABASE *Database;
- EFI_BOOT_MODE BootMode;
- EFI_STATUS Status;
- UINTN Instance;
- EFI_PEI_FV_HANDLE VolumeHandle;
- EFI_PEI_FILE_HANDLE FileHandle;
- VOID *PcdDb;
- UINT32 Length;
- PEI_PCD_DATABASE *PeiPcdDb;
-
- Status = PeiServicesGetBootMode (&BootMode);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Don't need to report it on S3 boot.
- //
- if (BootMode == BOOT_ON_S3_RESUME) {
- return EFI_SUCCESS;
- }
-
- PeiPcdDb = GetPcdDatabase ();
- if (PeiPcdDb->SystemSkuId != (SKU_ID)0) {
- //
- // SkuId has been set. Don't need to report it to DXE phase.
- //
- return EFI_SUCCESS;
- }
-
- //
- // Get full PCD database from PcdPeim FileHandle
- //
- Instance = 0;
- FileHandle = NULL;
- while (TRUE) {
- //
- // Traverse all firmware volume instances
- //
- Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);
- //
- // Error should not happen
- //
- ASSERT_EFI_ERROR (Status);
-
- //
- // Find PcdDb file from the beginning in this firmware volume.
- //
- FileHandle = NULL;
- Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle);
- if (!EFI_ERROR (Status)) {
- //
- // Find PcdPeim FileHandle in this volume
- //
- break;
- }
-
- //
- // We cannot find PcdPeim in this firmware volume, then search the next volume.
- //
- Instance++;
- }
-
- //
- // Find PEI PcdDb and Build second PcdDB GuidHob
- //
- Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);
- ASSERT_EFI_ERROR (Status);
- Length = PeiPcdDb->LengthForAllSkus;
- Database = BuildGuidHob (&gPcdDataBaseHobGuid, Length);
- CopyMem (Database, PcdDb, Length);
-
- return EFI_SUCCESS;
-}
-
-EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[] = {
- {
- (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
- &gEfiEndOfPeiSignalPpiGuid,
- EndOfPeiSignalPpiNotifyCallback
- }
-};
-
-/**
- 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;
-
- Status = PeiServicesRegisterForShadow (FileHandle);
- if (Status == EFI_ALREADY_STARTED) {
- //
- // This is now starting in memory, the second time starting.
- //
- EFI_PEI_PPI_DESCRIPTOR *OldPpiList;
- EFI_PEI_PPI_DESCRIPTOR *OldPpiList2;
- VOID *Ppi;
- VOID *Ppi2;
-
- OldPpiList = NULL;
- Status = PeiServicesLocatePpi (
- &gPcdPpiGuid,
- 0,
- &OldPpiList,
- &Ppi
- );
- ASSERT_EFI_ERROR (Status);
-
- if (OldPpiList != NULL) {
- Status = PeiServicesReInstallPpi (OldPpiList, &mPpiList[0]);
- ASSERT_EFI_ERROR (Status);
- }
-
- OldPpiList2 = NULL;
- Status = PeiServicesLocatePpi (
- &gGetPcdInfoPpiGuid,
- 0,
- &OldPpiList2,
- &Ppi2
- );
- ASSERT_EFI_ERROR (Status);
-
- if (OldPpiList2 != NULL) {
- Status = PeiServicesReInstallPpi (OldPpiList2, &mPpiList2[0]);
- ASSERT_EFI_ERROR (Status);
- }
-
- OldPpiList = NULL;
- Status = PeiServicesLocatePpi (
- &gEfiPeiPcdPpiGuid,
- 0,
- &OldPpiList,
- &Ppi
- );
- ASSERT_EFI_ERROR (Status);
-
- if (OldPpiList != NULL) {
- Status = PeiServicesReInstallPpi (OldPpiList, &mPpiList[1]);
- ASSERT_EFI_ERROR (Status);
- }
-
- OldPpiList2 = NULL;
- Status = PeiServicesLocatePpi (
- &gEfiGetPcdInfoPpiGuid,
- 0,
- &OldPpiList2,
- &Ppi2
- );
- ASSERT_EFI_ERROR (Status);
-
- if (OldPpiList2 != NULL) {
- Status = PeiServicesReInstallPpi (OldPpiList2, &mPpiList2[1]);
- ASSERT_EFI_ERROR (Status);
- }
-
- return 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);
-
- Status = PeiServicesNotifyPpi (&mEndOfPeiSignalPpiNotifyList[0]);
- ASSERT_EFI_ERROR (Status);
-
- Status = PeiRegisterCallBackOnSet (
- &gEfiMdeModulePkgTokenSpaceGuid,
- PcdToken (PcdSetNvStoreDefaultId),
- PcdSetNvStoreDefaultIdCallBack
- );
- 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;
- EFI_STATUS Status;
- UINTN Instance;
- EFI_PEI_FV_HANDLE VolumeHandle;
- EFI_PEI_FILE_HANDLE FileHandle;
- VOID *PcdDb;
- UINT32 Length;
- PCD_DATABASE_SKU_DELTA *SkuDelta;
- PCD_DATA_DELTA *SkuDeltaData;
-
- DEBUG ((DEBUG_INFO, "PcdPei - SkuId 0x%lx is to be set.\n", (SKU_ID)SkuId));
-
- PeiPcdDb = GetPcdDatabase ();
-
- if (SkuId == PeiPcdDb->SystemSkuId) {
- //
- // The input SKU Id is equal to current SKU Id, return directly.
- //
- DEBUG ((DEBUG_INFO, "PcdPei - SkuId is same to current system Sku.\n"));
- 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 ((DEBUG_INFO, "PcdPei - SkuId is found in SkuId table.\n"));
- break;
- }
- }
-
- if (Index < SkuIdTable[0]) {
- //
- // Get full PCD database from PcdPeim FileHandle
- //
- Instance = 0;
- FileHandle = NULL;
- while (TRUE) {
- //
- // Traverse all firmware volume instances
- //
- Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);
- //
- // Error should not happen
- //
- ASSERT_EFI_ERROR (Status);
-
- //
- // Find PcdDb file from the beginning in this firmware volume.
- //
- FileHandle = NULL;
- Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle);
- if (!EFI_ERROR (Status)) {
- //
- // Find PcdPeim FileHandle in this volume
- //
- break;
- }
-
- //
- // We cannot find PcdPeim in this firmware volume, then search the next volume.
- //
- Instance++;
- }
-
- //
- // Find the delta data between the different Skus
- //
- Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);
- ASSERT_EFI_ERROR (Status);
- Length = PeiPcdDb->LengthForAllSkus;
- Index = (PeiPcdDb->Length + 7) & (~7);
- SkuDelta = NULL;
- while (Index < Length) {
- SkuDelta = (PCD_DATABASE_SKU_DELTA *)((UINT8 *)PcdDb + Index);
- if ((SkuDelta->SkuId == SkuId) && (SkuDelta->SkuIdCompared == 0)) {
- break;
- }
-
- Index = (Index + SkuDelta->Length + 7) & (~7);
- }
-
- //
- // Patch the delta data into current PCD database
- //
- if ((Index < Length) && (SkuDelta != NULL)) {
- SkuDeltaData = (PCD_DATA_DELTA *)(SkuDelta + 1);
- while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length) {
- *((UINT8 *)PeiPcdDb + SkuDeltaData->Offset) = (UINT8)SkuDeltaData->Value;
- SkuDeltaData++;
- }
-
- PeiPcdDb->SystemSkuId = (SKU_ID)SkuId;
- DEBUG ((DEBUG_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_ID)SkuId));
- return;
- }
- }
-
- //
- // Invalid input SkuId, the default SKU Id will be still used for the system.
- //
- DEBUG ((DEBUG_ERROR, "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;
- SIZE_INFO *SizeTable;
-
- 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 {
- //
- // We have only two entry for Non-Sku enabled PCD entry:
- // 1) MAX SIZE
- // 2) Current Size
- //
- 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;
- SIZE_INFO *SizeTable;
- 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;
- }
-
- //
- // 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;
- }
-}
+/** @file + All Pcd Ppi services are implemented here. + +Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#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 + } +}; + +/** + Callback on SET PcdSetNvStoreDefaultId + + Once PcdSetNvStoreDefaultId is set, the default NV storage will be found from + PcdNvStoreDefaultValueBuffer, and built into VariableHob. + + @param[in] CallBackGuid The PCD token GUID being set. + @param[in] CallBackToken The PCD token number being set. + @param[in, out] TokenData A pointer to the token data being set. + @param[in] TokenDataSize The size, in bytes, of the data being set. + +**/ +VOID +EFIAPI +PcdSetNvStoreDefaultIdCallBack ( + IN CONST EFI_GUID *CallBackGuid OPTIONAL, + IN UINTN CallBackToken, + IN OUT VOID *TokenData, + IN UINTN TokenDataSize + ) +{ + EFI_STATUS Status; + UINT16 DefaultId; + SKU_ID SkuId; + UINTN FullSize; + UINTN Index; + UINT8 *DataBuffer; + UINT8 *VarStoreHobData; + UINT8 *BufferEnd; + BOOLEAN IsFound; + VARIABLE_STORE_HEADER *NvStoreBuffer; + PCD_DEFAULT_DATA *DataHeader; + PCD_DEFAULT_INFO *DefaultInfo; + PCD_DATA_DELTA *DeltaData; + + DefaultId = *(UINT16 *)TokenData; + SkuId = GetPcdDatabase ()->SystemSkuId; + IsFound = FALSE; + + if (PeiPcdGetSizeEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvStoreDefaultValueBuffer)) > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) { + DataBuffer = (UINT8 *)PeiPcdGetPtrEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvStoreDefaultValueBuffer)); + FullSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Length; + DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)); + // + // The first section data includes NV storage default setting. + // + NvStoreBuffer = (VARIABLE_STORE_HEADER *)((UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize); + VarStoreHobData = (UINT8 *)BuildGuidHob (&NvStoreBuffer->Signature, NvStoreBuffer->Size); + ASSERT (VarStoreHobData != NULL); + CopyMem (VarStoreHobData, NvStoreBuffer, NvStoreBuffer->Size); + // + // Find the matched SkuId and DefaultId in the first section + // + DefaultInfo = &(DataHeader->DefaultInfo[0]); + BufferEnd = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize; + while ((UINT8 *)DefaultInfo < BufferEnd) { + if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == SkuId)) { + IsFound = TRUE; + break; + } + + DefaultInfo++; + } + + // + // Find the matched SkuId and DefaultId in the remaining section + // + Index = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7)); + DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index); + while (!IsFound && Index < FullSize && DataHeader->DataSize != 0xFFFFFFFF) { + DefaultInfo = &(DataHeader->DefaultInfo[0]); + BufferEnd = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize; + while ((UINT8 *)DefaultInfo < BufferEnd) { + if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == SkuId)) { + IsFound = TRUE; + break; + } + + DefaultInfo++; + } + + if (IsFound) { + DeltaData = (PCD_DATA_DELTA *)BufferEnd; + BufferEnd = (UINT8 *)DataHeader + DataHeader->DataSize; + while ((UINT8 *)DeltaData < BufferEnd) { + *(VarStoreHobData + DeltaData->Offset) = (UINT8)DeltaData->Value; + DeltaData++; + } + + break; + } + + Index = (Index + DataHeader->DataSize + 7) & (~7); + DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index); + } + } + + Status = PcdUnRegisterCallBackOnSet ( + &gEfiMdeModulePkgTokenSpaceGuid, + PcdToken (PcdSetNvStoreDefaultId), + PcdSetNvStoreDefaultIdCallBack + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Report Pei PCD database of all SKUs as Guid HOB so that DxePcd can access it. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS Successfully update the Boot records. +**/ +EFI_STATUS +EFIAPI +EndOfPeiSignalPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + PEI_PCD_DATABASE *Database; + EFI_BOOT_MODE BootMode; + EFI_STATUS Status; + UINTN Instance; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *PcdDb; + UINT32 Length; + PEI_PCD_DATABASE *PeiPcdDb; + + Status = PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + // + // Don't need to report it on S3 boot. + // + if (BootMode == BOOT_ON_S3_RESUME) { + return EFI_SUCCESS; + } + + PeiPcdDb = GetPcdDatabase (); + if (PeiPcdDb->SystemSkuId != (SKU_ID)0) { + // + // SkuId has been set. Don't need to report it to DXE phase. + // + return EFI_SUCCESS; + } + + // + // Get full PCD database from PcdPeim FileHandle + // + Instance = 0; + FileHandle = NULL; + while (TRUE) { + // + // Traverse all firmware volume instances + // + Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); + // + // Error should not happen + // + ASSERT_EFI_ERROR (Status); + + // + // Find PcdDb file from the beginning in this firmware volume. + // + FileHandle = NULL; + Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle); + if (!EFI_ERROR (Status)) { + // + // Find PcdPeim FileHandle in this volume + // + break; + } + + // + // We cannot find PcdPeim in this firmware volume, then search the next volume. + // + Instance++; + } + + // + // Find PEI PcdDb and Build second PcdDB GuidHob + // + Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb); + ASSERT_EFI_ERROR (Status); + Length = PeiPcdDb->LengthForAllSkus; + Database = BuildGuidHob (&gPcdDataBaseHobGuid, Length); + CopyMem (Database, PcdDb, Length); + + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + EndOfPeiSignalPpiNotifyCallback + } +}; + +/** + 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; + + Status = PeiServicesRegisterForShadow (FileHandle); + if (Status == EFI_ALREADY_STARTED) { + // + // This is now starting in memory, the second time starting. + // + EFI_PEI_PPI_DESCRIPTOR *OldPpiList; + EFI_PEI_PPI_DESCRIPTOR *OldPpiList2; + VOID *Ppi; + VOID *Ppi2; + + OldPpiList = NULL; + Status = PeiServicesLocatePpi ( + &gPcdPpiGuid, + 0, + &OldPpiList, + &Ppi + ); + ASSERT_EFI_ERROR (Status); + + if (OldPpiList != NULL) { + Status = PeiServicesReInstallPpi (OldPpiList, &mPpiList[0]); + ASSERT_EFI_ERROR (Status); + } + + OldPpiList2 = NULL; + Status = PeiServicesLocatePpi ( + &gGetPcdInfoPpiGuid, + 0, + &OldPpiList2, + &Ppi2 + ); + ASSERT_EFI_ERROR (Status); + + if (OldPpiList2 != NULL) { + Status = PeiServicesReInstallPpi (OldPpiList2, &mPpiList2[0]); + ASSERT_EFI_ERROR (Status); + } + + OldPpiList = NULL; + Status = PeiServicesLocatePpi ( + &gEfiPeiPcdPpiGuid, + 0, + &OldPpiList, + &Ppi + ); + ASSERT_EFI_ERROR (Status); + + if (OldPpiList != NULL) { + Status = PeiServicesReInstallPpi (OldPpiList, &mPpiList[1]); + ASSERT_EFI_ERROR (Status); + } + + OldPpiList2 = NULL; + Status = PeiServicesLocatePpi ( + &gEfiGetPcdInfoPpiGuid, + 0, + &OldPpiList2, + &Ppi2 + ); + ASSERT_EFI_ERROR (Status); + + if (OldPpiList2 != NULL) { + Status = PeiServicesReInstallPpi (OldPpiList2, &mPpiList2[1]); + ASSERT_EFI_ERROR (Status); + } + + return 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); + + Status = PeiServicesNotifyPpi (&mEndOfPeiSignalPpiNotifyList[0]); + ASSERT_EFI_ERROR (Status); + + Status = PeiRegisterCallBackOnSet ( + &gEfiMdeModulePkgTokenSpaceGuid, + PcdToken (PcdSetNvStoreDefaultId), + PcdSetNvStoreDefaultIdCallBack + ); + 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; + EFI_STATUS Status; + UINTN Instance; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *PcdDb; + UINT32 Length; + PCD_DATABASE_SKU_DELTA *SkuDelta; + PCD_DATA_DELTA *SkuDeltaData; + + DEBUG ((DEBUG_INFO, "PcdPei - SkuId 0x%lx is to be set.\n", (SKU_ID)SkuId)); + + PeiPcdDb = GetPcdDatabase (); + + if (SkuId == PeiPcdDb->SystemSkuId) { + // + // The input SKU Id is equal to current SKU Id, return directly. + // + DEBUG ((DEBUG_INFO, "PcdPei - SkuId is same to current system Sku.\n")); + 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 ((DEBUG_INFO, "PcdPei - SkuId is found in SkuId table.\n")); + break; + } + } + + if (Index < SkuIdTable[0]) { + // + // Get full PCD database from PcdPeim FileHandle + // + Instance = 0; + FileHandle = NULL; + while (TRUE) { + // + // Traverse all firmware volume instances + // + Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); + // + // Error should not happen + // + ASSERT_EFI_ERROR (Status); + + // + // Find PcdDb file from the beginning in this firmware volume. + // + FileHandle = NULL; + Status = PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, VolumeHandle, &FileHandle); + if (!EFI_ERROR (Status)) { + // + // Find PcdPeim FileHandle in this volume + // + break; + } + + // + // We cannot find PcdPeim in this firmware volume, then search the next volume. + // + Instance++; + } + + // + // Find the delta data between the different Skus + // + Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb); + ASSERT_EFI_ERROR (Status); + Length = PeiPcdDb->LengthForAllSkus; + Index = (PeiPcdDb->Length + 7) & (~7); + SkuDelta = NULL; + while (Index < Length) { + SkuDelta = (PCD_DATABASE_SKU_DELTA *)((UINT8 *)PcdDb + Index); + if ((SkuDelta->SkuId == SkuId) && (SkuDelta->SkuIdCompared == 0)) { + break; + } + + Index = (Index + SkuDelta->Length + 7) & (~7); + } + + // + // Patch the delta data into current PCD database + // + if ((Index < Length) && (SkuDelta != NULL)) { + SkuDeltaData = (PCD_DATA_DELTA *)(SkuDelta + 1); + while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length) { + *((UINT8 *)PeiPcdDb + SkuDeltaData->Offset) = (UINT8)SkuDeltaData->Value; + SkuDeltaData++; + } + + PeiPcdDb->SystemSkuId = (SKU_ID)SkuId; + DEBUG ((DEBUG_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_ID)SkuId)); + return; + } + } + + // + // Invalid input SkuId, the default SKU Id will be still used for the system. + // + DEBUG ((DEBUG_ERROR, "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; + SIZE_INFO *SizeTable; + + 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 { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + 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; + SIZE_INFO *SizeTable; + 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; + } + + // + // 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; + } +} diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf index 7152a7d53b..a5e0b1381d 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf +++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf @@ -1,351 +1,351 @@ -## @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 PCD setting - PcdVpdBaseAddress64 or 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_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 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[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 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.
- gEfiMdeModulePkgTokenSpaceGuid ## SOMETIMES_CONSUMES ## GUID
-
-[Ppis]
- gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES
- gPcdPpiGuid ## PRODUCES
- gEfiPeiPcdPpiGuid ## PRODUCES
- gGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES
- gEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES
- gEfiEndOfPeiSignalPpiGuid ## NOTIFY
-
-[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## CONSUMES
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress64 ## SOMETIMES_CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry ## SOMETIMES_CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer ## SOMETIMES_CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdSetNvStoreDefaultId ## CONSUMES
-
-[Depex]
- TRUE
-
-[UserExtensions.TianoCore."ExtraFiles"]
- PcdPeimExtra.uni
+## @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 PCD setting - PcdVpdBaseAddress64 or 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_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 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[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 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. + gEfiMdeModulePkgTokenSpaceGuid ## SOMETIMES_CONSUMES ## GUID + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES + gPcdPpiGuid ## PRODUCES + gEfiPeiPcdPpiGuid ## PRODUCES + gGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES + gEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES + gEfiEndOfPeiSignalPpiGuid ## NOTIFY + +[FeaturePcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## CONSUMES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress64 ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNvStoreDefaultId ## CONSUMES + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + PcdPeimExtra.uni diff --git a/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni b/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni index 0a800889a2..357d3ebdce 100644 --- a/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni +++ b/MdeModulePkg/Universal/PCD/Pei/PcdPeim.uni @@ -1,290 +1,290 @@ -// /** @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_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 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#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."
-
+// /** @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_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 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#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/MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni b/MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni index 1e47f0e794..5b6256e7da 100644 --- a/MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni +++ b/MdeModulePkg/Universal/PCD/Pei/PcdPeimExtra.uni @@ -1,14 +1,14 @@ -// /** @file
-// PcdPeim Localized Strings and Content
-//
-// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_PROPERTIES_MODULE_NAME
-#language en-US
-"Platform Configuration Database PEI Module"
-
-
+// /** @file +// PcdPeim Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Platform Configuration Database PEI Module" + + diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.c b/MdeModulePkg/Universal/PCD/Pei/Service.c index 0a570a4cbe..72fd640238 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Service.c +++ b/MdeModulePkg/Universal/PCD/Pei/Service.c @@ -1,1081 +1,1081 @@ -/** @file
- The driver internal functions are implmented here.
- They build Pei PCD database, and provide access service to PCD database.
-
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#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;
-
- //
- // 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);
-
- 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;
-}
-
-/**
- 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;
- UINTN VpdBaseAddress;
-
- //
- // 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);
-
- //
- // PcdVpdBaseAddress64 is DynamicEx PCD only. So, PeiPcdGet64Ex() is used to get its value.
- //
- VpdBaseAddress = (UINTN)PeiPcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdVpdBaseAddress64));
- if (VpdBaseAddress == 0) {
- //
- // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress.
- //
- VpdBaseAddress = (UINTN)PcdGet32 (PcdVpdBaseAddress);
- }
-
- ASSERT (VpdBaseAddress != 0);
- return (VOID *)(VpdBaseAddress + 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 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;
-
- 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 {
- //
- // We have only two entry for Non-Sku enabled PCD entry:
- // 1) MAX SIZE
- // 2) Current Size
- //
- SizeTableIdx += 2;
- }
- }
- }
-
- return SizeTableIdx;
-}
+/** @file + The driver internal functions are implmented here. + They build Pei PCD database, and provide access service to PCD database. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#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; + + // + // 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); + + 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; +} + +/** + 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; + UINTN VpdBaseAddress; + + // + // 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); + + // + // PcdVpdBaseAddress64 is DynamicEx PCD only. So, PeiPcdGet64Ex() is used to get its value. + // + VpdBaseAddress = (UINTN)PeiPcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdVpdBaseAddress64)); + if (VpdBaseAddress == 0) { + // + // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress. + // + VpdBaseAddress = (UINTN)PcdGet32 (PcdVpdBaseAddress); + } + + ASSERT (VpdBaseAddress != 0); + return (VOID *)(VpdBaseAddress + 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 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; + + 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 { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTableIdx += 2; + } + } + } + + return SizeTableIdx; +} diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.h b/MdeModulePkg/Universal/PCD/Pei/Service.h index 8b94bf308e..901a060bf8 100644 --- a/MdeModulePkg/Universal/PCD/Pei/Service.h +++ b/MdeModulePkg/Universal/PCD/Pei/Service.h @@ -1,1082 +1,1082 @@ -/** @file
- The internal header file declares the private functions used by PeiPcd driver.
-
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _PEI_PCD_SERVICE_H_
-#define _PEI_PCD_SERVICE_H_
-
-#include <PiPei.h>
-#include <Ppi/ReadOnlyVariable2.h>
-#include <Ppi/Pcd.h>
-#include <Ppi/PiPcd.h>
-#include <Ppi/PcdInfo.h>
-#include <Ppi/PiPcdInfo.h>
-#include <Guid/PcdDataBaseHobGuid.h>
-#include <Guid/PcdDataBaseSignatureGuid.h>
-#include <Guid/VariableFormat.h>
-#include <Library/DebugLib.h>
-#include <Library/PeimEntryPoint.h>
-#include <Library/BaseLib.h>
-#include <Library/HobLib.h>
-#include <Library/PeiServicesLib.h>
-#include <Library/PcdLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-
-//
-// 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 7
-
-//
-// 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
- );
-
-/**
- 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 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
+/** @file + The internal header file declares the private functions used by PeiPcd driver. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _PEI_PCD_SERVICE_H_ +#define _PEI_PCD_SERVICE_H_ + +#include <PiPei.h> +#include <Ppi/ReadOnlyVariable2.h> +#include <Ppi/Pcd.h> +#include <Ppi/PiPcd.h> +#include <Ppi/PcdInfo.h> +#include <Ppi/PiPcdInfo.h> +#include <Guid/PcdDataBaseHobGuid.h> +#include <Guid/PcdDataBaseSignatureGuid.h> +#include <Guid/VariableFormat.h> +#include <Library/DebugLib.h> +#include <Library/PeimEntryPoint.h> +#include <Library/BaseLib.h> +#include <Library/HobLib.h> +#include <Library/PeiServicesLib.h> +#include <Library/PcdLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> + +// +// 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 7 + +// +// 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 + ); + +/** + 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 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 |
