WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
\r
\r
-Module Name: DxePcdLib.c\r
-\r
**/\r
\r
-static PCD_PROTOCOL *mPcd;\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/Pcd.h>\r
+\r
+#include <Library/PcdLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#include "DxePcdLibInternal.h"\r
+\r
+STATIC PCD_PROTOCOL *mPcd = NULL;\r
\r
/**\r
- The constructor function caches the PCD_PROTOCOL pointer.\r
+ Retrieves PCD protocol interface.\r
\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
- @param[in] SystemTable A pointer to the EFI System Table.\r
- \r
- @retval EFI_SUCCESS The constructor always return EFI_SUCCESS.\r
+ This function retrieves PCD protocol interface. On the first invocation, it\r
+ retrieves protocol interface via UEFI boot services and cache it to accelarte\r
+ further access. A module invokes this function only when it needs to access a\r
+ dynamic PCD entry.\r
+ If UefiBootServicesTableLib has not been initialized, then ASSERT ().\r
+ If PCD protocol has not been installed, then ASSERT ().\r
+\r
+ @return mPcd The PCD protocol protocol interface.\r
\r
**/\r
-EFI_STATUS\r
-EFIAPI\r
-PcdLibConstructor (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
+PCD_PROTOCOL*\r
+GetPcdProtocol (\r
+ VOID\r
)\r
{\r
EFI_STATUS Status;\r
\r
- Status = gBS->LocateProtocol (&gPcdProtocolGuid, NULL, (VOID **)&mPcd);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (mPcd == NULL) {\r
+ ASSERT (gBS != NULL);\r
+ //\r
+ // PCD protocol has not been installed, but a module needs to access a\r
+ // dynamic PCD entry.\r
+ // \r
+ Status = gBS->LocateProtocol (&gPcdProtocolGuid, NULL, (VOID **)&mPcd);\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (mPcd!= NULL);\r
+ }\r
\r
- return EFI_SUCCESS;\r
+ return mPcd;\r
}\r
\r
\r
IN UINTN SkuId\r
)\r
{\r
- mPcd->SetSku (SkuId);\r
+ ASSERT (SkuId < 0x100);\r
+\r
+ (GetPcdProtocol ())->SetSku (SkuId);\r
\r
return SkuId;\r
}\r
IN UINTN TokenNumber\r
)\r
{\r
- return mPcd->Get8 (TokenNumber);\r
+ return (GetPcdProtocol ())->Get8 (TokenNumber);\r
}\r
\r
\r
IN UINTN TokenNumber\r
)\r
{\r
- return mPcd->Get16 (TokenNumber);\r
+ return (GetPcdProtocol ())->Get16 (TokenNumber);\r
}\r
\r
\r
IN UINTN TokenNumber\r
)\r
{\r
- return mPcd->Get32 (TokenNumber);\r
+ return (GetPcdProtocol ())->Get32 (TokenNumber);\r
}\r
\r
\r
IN UINTN TokenNumber\r
)\r
{\r
- return mPcd->Get64 (TokenNumber);\r
+ return (GetPcdProtocol ())->Get64 (TokenNumber);\r
}\r
\r
\r
IN UINTN TokenNumber\r
)\r
{\r
- return mPcd->GetPtr (TokenNumber);\r
+ return (GetPcdProtocol ())->GetPtr (TokenNumber);\r
}\r
\r
\r
IN UINTN TokenNumber\r
)\r
{\r
- return mPcd->GetBool (TokenNumber);\r
+ return (GetPcdProtocol ())->GetBool (TokenNumber);\r
}\r
\r
\r
IN UINTN TokenNumber\r
)\r
{\r
- return mPcd->GetSize (TokenNumber);\r
+ return (GetPcdProtocol ())->GetSize (TokenNumber);\r
}\r
\r
\r
{\r
ASSERT (Guid != NULL);\r
\r
- return mPcd->Get8Ex (Guid, TokenNumber);\r
+ return (GetPcdProtocol ())->Get8Ex (Guid, TokenNumber);\r
}\r
\r
\r
{\r
ASSERT (Guid != NULL);\r
\r
- return mPcd->Get16Ex (Guid, TokenNumber);\r
+ return (GetPcdProtocol ())->Get16Ex (Guid, TokenNumber);\r
}\r
\r
\r
{\r
ASSERT (Guid != NULL);\r
\r
- return mPcd->Get32Ex (Guid, TokenNumber);\r
+ return (GetPcdProtocol ())->Get32Ex (Guid, TokenNumber);\r
}\r
\r
\r
{\r
ASSERT (Guid != NULL);\r
\r
- return mPcd->Get64Ex (Guid, TokenNumber);\r
+ return (GetPcdProtocol ())->Get64Ex (Guid, TokenNumber);\r
}\r
\r
\r
{\r
ASSERT (Guid != NULL);\r
\r
- return mPcd->GetPtrEx (Guid, TokenNumber);\r
+ return (GetPcdProtocol ())->GetPtrEx (Guid, TokenNumber);\r
}\r
\r
\r
{\r
ASSERT (Guid != NULL);\r
\r
- return mPcd->GetBoolEx (Guid, TokenNumber);\r
+ return (GetPcdProtocol ())->GetBoolEx (Guid, TokenNumber);\r
}\r
\r
\r
{\r
ASSERT (Guid != NULL);\r
\r
- return mPcd->GetSizeEx (Guid, TokenNumber);\r
+ return (GetPcdProtocol ())->GetSizeEx (Guid, TokenNumber);\r
}\r
\r
\r
{\r
EFI_STATUS Status;\r
\r
- Status = mPcd->Set8 (TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->Set8 (TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
{\r
EFI_STATUS Status;\r
\r
- Status = mPcd->Set16 (TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->Set16 (TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
)\r
{\r
EFI_STATUS Status;\r
- Status = mPcd->Set32 (TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->Set32 (TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
{\r
EFI_STATUS Status;\r
\r
- Status = mPcd->Set64 (TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->Set64 (TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN Size;\r
- \r
- ASSERT ((*SizeOfBuffer > 0) && Buffer == NULL);\r
\r
- Size = LibPcdGetSize (TokenNumber);\r
- \r
- if (*SizeOfBuffer > Size) {\r
- *SizeOfBuffer = Size;\r
- return NULL;\r
+ ASSERT (SizeOfBuffer != NULL);\r
+\r
+ if (*SizeOfBuffer > 0) {\r
+ ASSERT (Buffer != NULL);\r
}\r
\r
- Status = mPcd->SetPtr (TokenNumber, *SizeOfBuffer, Buffer);\r
+ Status = (GetPcdProtocol ())->SetPtr (TokenNumber, SizeOfBuffer, Buffer);\r
\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
\r
return Buffer;\r
}\r
{\r
EFI_STATUS Status;\r
\r
- Status = mPcd->SetBool (TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->SetBool (TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
\r
ASSERT (Guid != NULL);\r
\r
- Status = mPcd->Set8Ex (Guid, TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->Set8Ex (Guid, TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
\r
ASSERT (Guid != NULL);\r
\r
- Status = mPcd->Set16Ex (Guid, TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->Set16Ex (Guid, TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
\r
ASSERT (Guid != NULL);\r
\r
- Status = mPcd->Set32Ex (Guid, TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->Set32Ex (Guid, TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
\r
ASSERT (Guid != NULL);\r
\r
- Status = mPcd->Set64Ex (Guid, TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->Set64Ex (Guid, TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN Size;\r
\r
ASSERT (Guid != NULL);\r
- ASSERT (Buffer != NULL);\r
\r
- Size = LibPcdGetExSize (Guid, TokenNumber);\r
- if (*SizeOfBuffer > Size) {\r
- *SizeOfBuffer = Size;\r
- return NULL;\r
+ ASSERT (SizeOfBuffer != NULL);\r
+\r
+ if (*SizeOfBuffer > 0) {\r
+ ASSERT (Buffer != NULL);\r
}\r
\r
- Status = mPcd->SetPtrEx (Guid, TokenNumber, *SizeOfBuffer, Buffer);\r
+ Status = (GetPcdProtocol ())->SetPtrEx (Guid, TokenNumber, SizeOfBuffer, Buffer);\r
\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
\r
return Buffer;\r
}\r
\r
ASSERT (Guid != NULL);\r
\r
- Status = mPcd->SetBoolEx (Guid, TokenNumber, Value);\r
+ Status = (GetPcdProtocol ())->SetBoolEx (Guid, TokenNumber, Value);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
\r
ASSERT (NotificationFunction != NULL);\r
\r
- Status = mPcd->CallbackOnSet (TokenNumber, Guid, NotificationFunction);\r
+ Status = (GetPcdProtocol ())->CallbackOnSet (Guid, TokenNumber, NotificationFunction);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
\r
ASSERT (NotificationFunction != NULL);\r
\r
- Status = mPcd->CancelCallback (TokenNumber, Guid, NotificationFunction);\r
+ Status = (GetPcdProtocol ())->CancelCallback (Guid, TokenNumber, NotificationFunction);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
{\r
EFI_STATUS Status;\r
\r
- Status = mPcd->GetNextToken (Guid, &TokenNumber);\r
+ Status = (GetPcdProtocol ())->GetNextToken (Guid, &TokenNumber);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
@retval CONST GUID * The next valid token namespace.\r
\r
**/\r
-CONST GUID* \r
+GUID * \r
EFIAPI\r
LibPcdGetNextTokenSpace (\r
IN CONST GUID *Guid\r
{\r
EFI_STATUS Status;\r
\r
- Status = mPcd->GetNextTokenSpace (&Guid);\r
+ Status = (GetPcdProtocol ())->GetNextTokenSpace (&Guid);\r
\r
ASSERT_EFI_ERROR (Status);\r
\r
- return Guid;\r
+ return (GUID *) Guid;\r
}\r
\r
+\r
+/**\r
+ Sets the PCD entry specified by PatchVariable to the value specified by Buffer \r
+ and SizeOfValue. Buffer is returned. If SizeOfValue is greater than \r
+ MaximumDatumSize, then set SizeOfValue to MaximumDatumSize and return \r
+ NULL to indicate that the set operation was not actually performed. \r
+ If SizeOfValue is set to MAX_ADDRESS, then SizeOfValue must be set to \r
+ MaximumDatumSize and NULL must be returned.\r
+ \r
+ If PatchVariable is NULL, then ASSERT().\r
+ If SizeOfValue is NULL, then ASSERT().\r
+ If SizeOfValue > 0 and Buffer is NULL, then ASSERT().\r
+\r
+ @param[in] PatchVariable A pointer to the global variable in a module that is \r
+ the target of the set operation.\r
+ @param[in] MaximumDatumSize The maximum size allowed for the PCD entry specified by PatchVariable.\r
+ @param[in, out] SizeOfBuffer A pointer to the size, in bytes, of Buffer.\r
+ @param[in] Buffer A pointer to the buffer to used to set the target variable.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+LibPatchPcdSetPtr (\r
+ IN VOID *PatchVariable,\r
+ IN UINTN MaximumDatumSize,\r
+ IN OUT UINTN *SizeOfBuffer,\r
+ IN CONST VOID *Buffer\r
+ )\r
+{\r
+ ASSERT (PatchVariable != NULL);\r
+ ASSERT (SizeOfBuffer != NULL);\r
+ \r
+ if (*SizeOfBuffer > 0) {\r
+ ASSERT (Buffer != NULL);\r
+ }\r
+\r
+ if ((*SizeOfBuffer > MaximumDatumSize) ||\r
+ (*SizeOfBuffer == MAX_ADDRESS)) {\r
+ *SizeOfBuffer = MaximumDatumSize;\r
+ return NULL;\r
+ }\r
+ \r
+ CopyMem (PatchVariable, Buffer, *SizeOfBuffer);\r
+ \r
+ return (VOID *) Buffer;\r
+}\r
+\r
+\r
+\r