2 PCD DXE driver manage all PCD entry initialized in PEI phase and DXE phase, and
3 produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in
6 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
14 /// PCD database lock.
16 EFI_LOCK mPcdDatabaseLock
= EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY
);
19 /// PCD_PROTOCOL the EDKII native implementation which support dynamic
20 /// type and dynamicEx type PCDs.
22 PCD_PROTOCOL mPcdInstance
= {
55 DxeRegisterCallBackOnSet
,
56 DxeUnRegisterCallBackOnSet
,
58 DxePcdGetNextTokenSpace
62 /// EFI_PCD_PROTOCOL is defined in PI 1.2 Vol 3 which only support dynamicEx type
65 EFI_PCD_PROTOCOL mEfiPcdInstance
= {
80 (EFI_PCD_PROTOCOL_CALLBACK_ON_SET
) DxeRegisterCallBackOnSet
,
81 (EFI_PCD_PROTOCOL_CANCEL_CALLBACK
) DxeUnRegisterCallBackOnSet
,
83 DxePcdGetNextTokenSpace
87 /// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementation.
88 /// This protocol instance support dynamic and dynamicEx type PCDs.
90 GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance
= {
92 DxeGetPcdInfoGetInfoEx
,
97 /// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol 3.
98 /// This PPI instance only support dyanmicEx type PCD.
100 EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance
= {
101 DxeGetPcdInfoGetInfoEx
,
105 EFI_HANDLE mPcdHandle
= NULL
;
106 UINTN mVpdBaseAddress
= 0;
109 Main entry for PCD DXE driver.
111 This routine initialize the PCD database and install PCD_PROTOCOL.
113 @param ImageHandle Image handle for PCD DXE driver.
114 @param SystemTable Pointer to SystemTable.
116 @return Status of gBS->InstallProtocolInterface()
122 IN EFI_HANDLE ImageHandle
,
123 IN EFI_SYSTEM_TABLE
*SystemTable
130 // Make sure the Pcd Protocol is not already installed in the system
133 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gPcdProtocolGuid
);
135 BuildPcdDxeDataBase ();
138 // Install PCD_PROTOCOL to handle dynamic type PCD
139 // Install EFI_PCD_PROTOCOL to handle dynamicEx type PCD
141 Status
= gBS
->InstallMultipleProtocolInterfaces (
143 &gPcdProtocolGuid
, &mPcdInstance
,
144 &gEfiPcdProtocolGuid
, &mEfiPcdInstance
,
147 ASSERT_EFI_ERROR (Status
);
150 // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD
151 // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD
153 Status
= gBS
->InstallMultipleProtocolInterfaces (
155 &gGetPcdInfoProtocolGuid
, &mGetPcdInfoInstance
,
156 &gEfiGetPcdInfoProtocolGuid
, &mEfiGetPcdInfoInstance
,
159 ASSERT_EFI_ERROR (Status
);
162 // Register callback function upon VariableLockProtocol
163 // to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.
165 EfiCreateProtocolNotifyEvent (
166 &gEdkiiVariableLockProtocolGuid
,
168 VariableLockCallBack
,
174 // Cache VpdBaseAddress in entry point for the following usage.
178 // PcdVpdBaseAddress64 is DynamicEx PCD only. So, DxePcdGet64Ex() is used to get its value.
180 mVpdBaseAddress
= (UINTN
) DxePcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGuid
, PcdToken (PcdVpdBaseAddress64
));
181 if (mVpdBaseAddress
== 0) {
183 // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress.
185 mVpdBaseAddress
= (UINTN
) PcdGet32 (PcdVpdBaseAddress
);
192 Retrieve additional information associated with a PCD token in the default token space.
194 This includes information such as the type of value the TokenNumber is associated with as well as possible
195 human readable name that is associated with the token.
197 @param[in] TokenNumber The PCD token number.
198 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
199 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
201 @retval EFI_SUCCESS The PCD information was returned successfully.
202 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
206 DxeGetPcdInfoGetInfo (
207 IN UINTN TokenNumber
,
208 OUT EFI_PCD_INFO
*PcdInfo
211 return DxeGetPcdInfo (NULL
, TokenNumber
, PcdInfo
);
215 Retrieve additional information associated with a PCD token.
217 This includes information such as the type of value the TokenNumber is associated with as well as possible
218 human readable name that is associated with the token.
220 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
221 @param[in] TokenNumber The PCD token number.
222 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
223 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
225 @retval EFI_SUCCESS The PCD information was returned successfully.
226 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
230 DxeGetPcdInfoGetInfoEx (
231 IN CONST EFI_GUID
*Guid
,
232 IN UINTN TokenNumber
,
233 OUT EFI_PCD_INFO
*PcdInfo
236 return DxeGetPcdInfo (Guid
, TokenNumber
, PcdInfo
);
240 Retrieve the currently set SKU Id.
242 @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
243 default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
248 DxeGetPcdInfoGetSku (
252 return (UINTN
) mPcdDatabase
.DxeDb
->SystemSkuId
;
256 Sets the SKU value for subsequent calls to set or get PCD token values.
258 SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values.
259 SetSku() is normally called only once by the system.
261 For each item (token), the database can hold a single value that applies to all SKUs,
262 or multiple values, where each value is associated with a specific SKU Id. Items with multiple,
263 SKU-specific values are called SKU enabled.
265 The SKU Id of zero is reserved as a default.
266 For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the
267 single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the
268 last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token,
269 the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been
270 set for that Id, the results are unpredictable.
272 @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and
273 set values associated with a PCD token.
286 DEBUG ((DEBUG_INFO
, "PcdDxe - SkuId 0x%lx is to be set.\n", (SKU_ID
) SkuId
));
288 if (SkuId
== mPcdDatabase
.DxeDb
->SystemSkuId
) {
290 // The input SKU Id is equal to current SKU Id, return directly.
292 DEBUG ((DEBUG_INFO
, "PcdDxe - SkuId is same to current system Sku.\n"));
296 if (mPcdDatabase
.DxeDb
->SystemSkuId
!= (SKU_ID
) 0) {
297 DEBUG ((DEBUG_ERROR
, "PcdDxe - The SKU Id could be changed only once."));
300 "PcdDxe - The SKU Id was set to 0x%lx already, it could not be set to 0x%lx any more.",
301 mPcdDatabase
.DxeDb
->SystemSkuId
,
308 SkuIdTable
= (SKU_ID
*) ((UINT8
*) mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->SkuIdTableOffset
);
309 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
310 if (SkuId
== SkuIdTable
[Index
+ 1]) {
311 DEBUG ((DEBUG_INFO
, "PcdDxe - SkuId is found in SkuId table.\n"));
312 Status
= UpdatePcdDatabase (SkuId
, TRUE
);
313 if (!EFI_ERROR (Status
)) {
314 mPcdDatabase
.DxeDb
->SystemSkuId
= (SKU_ID
) SkuId
;
315 DEBUG ((DEBUG_INFO
, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID
) SkuId
));
322 // Invalid input SkuId, the default SKU Id will be still used for the system.
324 DEBUG ((DEBUG_ERROR
, "PcdDxe - Invalid input SkuId, the default SKU Id will be still used.\n"));
329 Retrieves an 8-bit value for a given PCD token.
331 Retrieves the current byte-sized value for a PCD token number.
332 If the TokenNumber is invalid, the results are unpredictable.
334 @param[in] TokenNumber The PCD token number.
336 @return The UINT8 value.
345 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
349 Retrieves an 16-bit value for a given PCD token.
351 Retrieves the current 16-bits value for a PCD token number.
352 If the TokenNumber is invalid, the results are unpredictable.
354 @param[in] TokenNumber The PCD token number.
356 @return The UINT16 value.
365 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
369 Retrieves an 32-bit value for a given PCD token.
371 Retrieves the current 32-bits value for a PCD token number.
372 If the TokenNumber is invalid, the results are unpredictable.
374 @param[in] TokenNumber The PCD token number.
376 @return The UINT32 value.
385 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
389 Retrieves an 64-bit value for a given PCD token.
391 Retrieves the current 64-bits value for a PCD token number.
392 If the TokenNumber is invalid, the results are unpredictable.
394 @param[in] TokenNumber The PCD token number.
396 @return The UINT64 value.
405 return ReadUnaligned64(GetWorker (TokenNumber
, sizeof (UINT64
)));
409 Retrieves a pointer to a value for a given PCD token.
411 Retrieves the current pointer to the buffer for a PCD token number.
412 Do not make any assumptions about the alignment of the pointer that
413 is returned by this function call. If the TokenNumber is invalid,
414 the results are unpredictable.
416 @param[in] TokenNumber The PCD token number.
418 @return The pointer to the buffer to be retrived.
427 return GetWorker (TokenNumber
, 0);
431 Retrieves a Boolean value for a given PCD token.
433 Retrieves the current boolean value for a PCD token number.
434 Do not make any assumptions about the alignment of the pointer that
435 is returned by this function call. If the TokenNumber is invalid,
436 the results are unpredictable.
438 @param[in] TokenNumber The PCD token number.
440 @return The Boolean value.
449 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
453 Retrieves the size of the value for a given PCD token.
455 Retrieves the current size of a particular PCD token.
456 If the TokenNumber is invalid, the results are unpredictable.
458 @param[in] TokenNumber The PCD token number.
460 @return The size of the value for the PCD token.
470 UINT32
*LocalTokenNumberTable
;
473 UINTN TmpTokenNumber
;
475 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
476 // We have to decrement TokenNumber by 1 to make it usable
477 // as the array index.
482 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
484 TmpTokenNumber
= TokenNumber
;
486 // EBC compiler is very choosy. It may report warning about comparison
487 // between UINTN and 0 . So we add 1 in each size of the
489 ASSERT (TokenNumber
+ 1 < mPcdTotalTokenCount
+ 1);
491 // EBC compiler is very choosy. It may report warning about comparison
492 // between UINTN and 0 . So we add 1 in each size of the
494 IsPeiDb
= (BOOLEAN
) (TokenNumber
+ 1 < mPeiLocalTokenCount
+ 1);
496 TokenNumber
= IsPeiDb
? TokenNumber
:
497 (TokenNumber
- mPeiLocalTokenCount
);
499 LocalTokenNumberTable
= IsPeiDb
? (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
)
500 : (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
502 Size
= (LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
506 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
508 return GetPtrTypeSize (TmpTokenNumber
, &MaxSize
);
516 Retrieves an 8-bit value for a given PCD token.
518 Retrieves the 8-bit value of a particular PCD token.
519 If the TokenNumber is invalid or the token space
520 specified by Guid does not exist, the results are
523 @param[in] Guid The token space for the token number.
524 @param[in] ExTokenNumber The PCD token number.
526 @return The size 8-bit value for the PCD token.
532 IN CONST EFI_GUID
*Guid
,
533 IN UINTN ExTokenNumber
536 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT8
)));
540 Retrieves an 16-bit value for a given PCD token.
542 Retrieves the 16-bit value of a particular PCD token.
543 If the TokenNumber is invalid or the token space
544 specified by Guid does not exist, the results are
547 @param[in] Guid The token space for the token number.
548 @param[in] ExTokenNumber The PCD token number.
550 @return The size 16-bit value for the PCD token.
556 IN CONST EFI_GUID
*Guid
,
557 IN UINTN ExTokenNumber
560 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT16
)));
564 Retrieves an 32-bit value for a given PCD token.
566 Retrieves the 32-bit value of a particular PCD token.
567 If the TokenNumber is invalid or the token space
568 specified by Guid does not exist, the results are
571 @param[in] Guid The token space for the token number.
572 @param[in] ExTokenNumber The PCD token number.
574 @return The size 32-bit value for the PCD token.
580 IN CONST EFI_GUID
*Guid
,
581 IN UINTN ExTokenNumber
584 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT32
)));
588 Retrieves an 64-bit value for a given PCD token.
590 Retrieves the 64-bit value of a particular PCD token.
591 If the TokenNumber is invalid or the token space
592 specified by Guid does not exist, the results are
595 @param[in] Guid The token space for the token number.
596 @param[in] ExTokenNumber The PCD token number.
598 @return The size 64-bit value for the PCD token.
604 IN CONST EFI_GUID
*Guid
,
605 IN UINTN ExTokenNumber
608 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT64
)));
612 Retrieves a pointer to a value for a given PCD token.
614 Retrieves the current pointer to the buffer for a PCD token number.
615 Do not make any assumptions about the alignment of the pointer that
616 is returned by this function call. If the TokenNumber is invalid,
617 the results are unpredictable.
619 @param[in] Guid The token space for the token number.
620 @param[in] ExTokenNumber The PCD token number.
622 @return The pointer to the buffer to be retrived.
628 IN CONST EFI_GUID
*Guid
,
629 IN UINTN ExTokenNumber
632 return ExGetWorker (Guid
, ExTokenNumber
, 0);
636 Retrieves an Boolean value for a given PCD token.
638 Retrieves the Boolean value of a particular PCD token.
639 If the TokenNumber is invalid or the token space
640 specified by Guid does not exist, the results are
643 @param[in] Guid The token space for the token number.
644 @param[in] ExTokenNumber The PCD token number.
646 @return The size Boolean value for the PCD token.
652 IN CONST EFI_GUID
*Guid
,
653 IN UINTN ExTokenNumber
656 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(BOOLEAN
)));
660 Retrieves the size of the value for a given PCD token.
662 Retrieves the current size of a particular PCD token.
663 If the TokenNumber is invalid, the results are unpredictable.
665 @param[in] Guid The token space for the token number.
666 @param[in] ExTokenNumber The PCD token number.
668 @return The size of the value for the PCD token.
674 IN CONST EFI_GUID
*Guid
,
675 IN UINTN ExTokenNumber
678 return DxePcdGetSize(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
));
682 Sets an 8-bit value for a given PCD token.
684 When the PCD service sets a value, it will check to ensure that the
685 size of the value being set is compatible with the Token's existing definition.
686 If it is not, an error will be returned.
688 @param[in] TokenNumber The PCD token number.
689 @param[in] Value The value to set for the PCD token.
691 @retval EFI_SUCCESS Procedure returned successfully.
692 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
693 being set was incompatible with a call to this function.
694 Use GetSize() to retrieve the size of the target data.
695 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
701 IN UINTN TokenNumber
,
705 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
709 Sets an 16-bit value for a given PCD token.
711 When the PCD service sets a value, it will check to ensure that the
712 size of the value being set is compatible with the Token's existing definition.
713 If it is not, an error will be returned.
715 @param[in] TokenNumber The PCD token number.
716 @param[in] Value The value to set for the PCD token.
718 @retval EFI_SUCCESS Procedure returned successfully.
719 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
720 being set was incompatible with a call to this function.
721 Use GetSize() to retrieve the size of the target data.
722 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
728 IN UINTN TokenNumber
,
732 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
736 Sets an 32-bit value for a given PCD token.
738 When the PCD service sets a value, it will check to ensure that the
739 size of the value being set is compatible with the Token's existing definition.
740 If it is not, an error will be returned.
742 @param[in] TokenNumber The PCD token number.
743 @param[in] Value The value to set for the PCD token.
745 @retval EFI_SUCCESS Procedure returned successfully.
746 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
747 being set was incompatible with a call to this function.
748 Use GetSize() to retrieve the size of the target data.
749 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
755 IN UINTN TokenNumber
,
759 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
763 Sets an 64-bit value for a given PCD token.
765 When the PCD service sets a value, it will check to ensure that the
766 size of the value being set is compatible with the Token's existing definition.
767 If it is not, an error will be returned.
769 @param[in] TokenNumber The PCD token number.
770 @param[in] Value The value to set for the PCD token.
772 @retval EFI_SUCCESS Procedure returned successfully.
773 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
774 being set was incompatible with a call to this function.
775 Use GetSize() to retrieve the size of the target data.
776 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
782 IN UINTN TokenNumber
,
786 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
790 Sets a value of a specified size for a given PCD token.
792 When the PCD service sets a value, it will check to ensure that the
793 size of the value being set is compatible with the Token's existing definition.
794 If it is not, an error will be returned.
796 @param[in] TokenNumber The PCD token number.
797 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.
798 On input, if the SizeOfValue is greater than the maximum size supported
799 for this TokenNumber then the output value of SizeOfValue will reflect
800 the maximum size supported for this TokenNumber.
801 @param[in] Buffer The buffer to set for the PCD token.
803 @retval EFI_SUCCESS Procedure returned successfully.
804 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
805 being set was incompatible with a call to this function.
806 Use GetSize() to retrieve the size of the target data.
807 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
813 IN UINTN TokenNumber
,
814 IN OUT UINTN
*SizeOfBuffer
,
818 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
822 Sets an Boolean value for a given PCD token.
824 When the PCD service sets a value, it will check to ensure that the
825 size of the value being set is compatible with the Token's existing definition.
826 If it is not, an error will be returned.
828 @param[in] TokenNumber The PCD token number.
829 @param[in] Value The value to set for the PCD token.
831 @retval EFI_SUCCESS Procedure returned successfully.
832 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
833 being set was incompatible with a call to this function.
834 Use GetSize() to retrieve the size of the target data.
835 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
841 IN UINTN TokenNumber
,
845 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
849 Sets an 8-bit value for a given PCD token.
851 When the PCD service sets a value, it will check to ensure that the
852 size of the value being set is compatible with the Token's existing definition.
853 If it is not, an error will be returned.
855 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
856 @param[in] ExTokenNumber The PCD token number.
857 @param[in] Value The value to set for the PCD token.
859 @retval EFI_SUCCESS Procedure returned successfully.
860 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
861 being set was incompatible with a call to this function.
862 Use GetSize() to retrieve the size of the target data.
863 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
869 IN CONST EFI_GUID
*Guid
,
870 IN UINTN ExTokenNumber
,
874 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
878 Sets an 16-bit value for a given PCD token.
880 When the PCD service sets a value, it will check to ensure that the
881 size of the value being set is compatible with the Token's existing definition.
882 If it is not, an error will be returned.
884 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
885 @param[in] ExTokenNumber The PCD token number.
886 @param[in] Value The value to set for the PCD token.
888 @retval EFI_SUCCESS Procedure returned successfully.
889 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
890 being set was incompatible with a call to this function.
891 Use GetSize() to retrieve the size of the target data.
892 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
898 IN CONST EFI_GUID
*Guid
,
899 IN UINTN ExTokenNumber
,
904 // PcdSetNvStoreDefaultId should be set in PEI phase to take effect.
906 ASSERT (!(CompareGuid (Guid
, &gEfiMdeModulePkgTokenSpaceGuid
) &&
907 (ExTokenNumber
== PcdToken(PcdSetNvStoreDefaultId
))));
908 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
912 Sets an 32-bit value for a given PCD token.
914 When the PCD service sets a value, it will check to ensure that the
915 size of the value being set is compatible with the Token's existing definition.
916 If it is not, an error will be returned.
918 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
919 @param[in] ExTokenNumber The PCD token number.
920 @param[in] Value The value to set for the PCD token.
922 @retval EFI_SUCCESS Procedure returned successfully.
923 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
924 being set was incompatible with a call to this function.
925 Use GetSize() to retrieve the size of the target data.
926 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
932 IN CONST EFI_GUID
*Guid
,
933 IN UINTN ExTokenNumber
,
937 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
941 Sets an 64-bit value for a given PCD token.
943 When the PCD service sets a value, it will check to ensure that the
944 size of the value being set is compatible with the Token's existing definition.
945 If it is not, an error will be returned.
947 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
948 @param[in] ExTokenNumber The PCD token number.
949 @param[in] Value The value to set for the PCD token.
951 @retval EFI_SUCCESS Procedure returned successfully.
952 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
953 being set was incompatible with a call to this function.
954 Use GetSize() to retrieve the size of the target data.
955 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
961 IN CONST EFI_GUID
*Guid
,
962 IN UINTN ExTokenNumber
,
966 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
970 Sets a value of a specified size for a given PCD token.
972 When the PCD service sets a value, it will check to ensure that the
973 size of the value being set is compatible with the Token's existing definition.
974 If it is not, an error will be returned.
976 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
977 @param[in] ExTokenNumber The PCD token number.
978 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.
979 On input, if the SizeOfValue is greater than the maximum size supported
980 for this TokenNumber then the output value of SizeOfValue will reflect
981 the maximum size supported for this TokenNumber.
982 @param[in] Buffer The buffer to set for the PCD token.
984 @retval EFI_SUCCESS Procedure returned successfully.
985 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
986 being set was incompatible with a call to this function.
987 Use GetSize() to retrieve the size of the target data.
988 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
994 IN CONST EFI_GUID
*Guid
,
995 IN UINTN ExTokenNumber
,
996 IN OUT UINTN
*SizeOfBuffer
,
1000 return ExSetWorker(ExTokenNumber
, Guid
, Buffer
, SizeOfBuffer
, TRUE
);
1004 Sets an Boolean value for a given PCD token.
1006 When the PCD service sets a value, it will check to ensure that the
1007 size of the value being set is compatible with the Token's existing definition.
1008 If it is not, an error will be returned.
1010 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
1011 @param[in] ExTokenNumber The PCD token number.
1012 @param[in] Value The value to set for the PCD token.
1014 @retval EFI_SUCCESS Procedure returned successfully.
1015 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
1016 being set was incompatible with a call to this function.
1017 Use GetSize() to retrieve the size of the target data.
1018 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
1024 IN CONST EFI_GUID
*Guid
,
1025 IN UINTN ExTokenNumber
,
1029 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
1033 Specifies a function to be called anytime the value of a designated token is changed.
1035 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
1036 @param[in] TokenNumber The PCD token number.
1037 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.
1039 @retval EFI_SUCCESS The PCD service has successfully established a call event
1040 for the CallBackToken requested.
1041 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.
1046 DxeRegisterCallBackOnSet (
1047 IN CONST EFI_GUID
*Guid
, OPTIONAL
1048 IN UINTN TokenNumber
,
1049 IN PCD_PROTOCOL_CALLBACK CallBackFunction
1054 if (CallBackFunction
== NULL
) {
1055 return EFI_INVALID_PARAMETER
;
1058 // Aquire lock to prevent reentrance from TPL_CALLBACK level
1060 EfiAcquireLock (&mPcdDatabaseLock
);
1062 Status
= DxeRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
1064 EfiReleaseLock (&mPcdDatabaseLock
);
1070 Cancels a previously set callback function for a particular PCD token number.
1072 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
1073 @param[in] TokenNumber The PCD token number.
1074 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.
1076 @retval EFI_SUCCESS The PCD service has successfully established a call event
1077 for the CallBackToken requested.
1078 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.
1083 DxeUnRegisterCallBackOnSet (
1084 IN CONST EFI_GUID
*Guid
, OPTIONAL
1085 IN UINTN TokenNumber
,
1086 IN PCD_PROTOCOL_CALLBACK CallBackFunction
1091 if (CallBackFunction
== NULL
) {
1092 return EFI_INVALID_PARAMETER
;
1096 // Aquire lock to prevent reentrance from TPL_CALLBACK level
1098 EfiAcquireLock (&mPcdDatabaseLock
);
1100 Status
= DxeUnRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
1102 EfiReleaseLock (&mPcdDatabaseLock
);
1108 Retrieves the next valid token number in a given namespace.
1110 This is useful since the PCD infrastructure contains a sparse list of token numbers,
1111 and one cannot a priori know what token numbers are valid in the database.
1113 If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned.
1114 If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned.
1115 If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned.
1116 If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned.
1117 The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid.
1118 If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned.
1119 If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned.
1120 If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned.
1123 @param[in] Guid The 128-bit unique value that designates the namespace from which to retrieve the next token.
1124 This is an optional parameter that may be NULL. If this parameter is NULL, then a request is
1125 being made to retrieve tokens from the default token space.
1126 @param[in, out] TokenNumber
1127 A pointer to the PCD token number to use to find the subsequent token number.
1129 @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
1130 @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
1135 DxePcdGetNextToken (
1136 IN CONST EFI_GUID
*Guid
, OPTIONAL
1137 IN OUT UINTN
*TokenNumber
1141 BOOLEAN PeiExMapTableEmpty
;
1142 BOOLEAN DxeExMapTableEmpty
;
1144 Status
= EFI_NOT_FOUND
;
1145 PeiExMapTableEmpty
= mPeiExMapTableEmpty
;
1146 DxeExMapTableEmpty
= mDxeExMapTableEmpty
;
1149 // Scan the local token space
1152 // EBC compiler is very choosy. It may report warning about comparison
1153 // between UINTN and 0 . So we add 1 in each size of the
1155 if (((*TokenNumber
+ 1 > mPeiNexTokenCount
+ 1) && (*TokenNumber
+ 1 <= mPeiLocalTokenCount
+ 1)) ||
1156 ((*TokenNumber
+ 1 > (mPeiLocalTokenCount
+ mDxeNexTokenCount
+ 1)))) {
1157 return EFI_NOT_FOUND
;
1161 if ((*TokenNumber
+ 1 > mPeiNexTokenCount
+ 1) &&
1162 (*TokenNumber
+ 1 <= mPeiLocalTokenCount
+ 1)) {
1164 // The first Non-Ex type Token Number for DXE PCD
1165 // database is mPeiLocalTokenCount + 1
1167 if (mDxeNexTokenCount
> 0) {
1168 *TokenNumber
= mPeiLocalTokenCount
+ 1;
1170 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
1171 return EFI_NOT_FOUND
;
1173 } else if (*TokenNumber
+ 1 > mDxeNexTokenCount
+ mPeiLocalTokenCount
+ 1) {
1174 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
1175 return EFI_NOT_FOUND
;
1180 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
1181 return EFI_NOT_FOUND
;
1184 if (!PeiExMapTableEmpty
) {
1185 Status
= ExGetNextTokeNumber (
1188 (EFI_GUID
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
),
1190 (DYNAMICEX_MAPPING
*)((UINT8
*) mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->ExMapTableOffset
),
1191 mPeiExMapppingTableSize
1195 if (Status
== EFI_SUCCESS
) {
1199 if (!DxeExMapTableEmpty
) {
1200 Status
= ExGetNextTokeNumber (
1203 (EFI_GUID
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
),
1205 (DYNAMICEX_MAPPING
*)((UINT8
*) mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->ExMapTableOffset
),
1206 mDxeExMapppingTableSize
1214 Get all token space guid table which is different with given token space guid.
1216 @param ExMapTableSize The size of ExMapTable in item
1217 @param ExMapTable Token space guid table that want to be scaned.
1218 @param GuidTable Guid table
1220 @return all token space guid table which is different with given token space guid.
1224 GetDistinctTokenSpace (
1225 IN OUT UINTN
*ExMapTableSize
,
1226 IN DYNAMICEX_MAPPING
*ExMapTable
,
1227 IN EFI_GUID
*GuidTable
1230 EFI_GUID
**DistinctTokenSpace
;
1237 DistinctTokenSpace
= AllocateZeroPool (*ExMapTableSize
* sizeof (EFI_GUID
*));
1238 ASSERT (DistinctTokenSpace
!= NULL
);
1241 OldGuidIndex
= ExMapTable
[0].ExGuidIndex
;
1242 DistinctTokenSpace
[TsIdx
] = &GuidTable
[OldGuidIndex
];
1243 for (Idx
= 1; Idx
< *ExMapTableSize
; Idx
++) {
1245 OldGuidIndex
= ExMapTable
[Idx
].ExGuidIndex
;
1246 for (TempTsIdx
= 0; TempTsIdx
<= TsIdx
; TempTsIdx
++) {
1247 if (&GuidTable
[OldGuidIndex
] == DistinctTokenSpace
[TempTsIdx
]) {
1249 // Have recorded this GUID.
1256 DistinctTokenSpace
[++TsIdx
] = &GuidTable
[OldGuidIndex
];
1261 // The total number of Distinct Token Space
1262 // is TsIdx + 1 because we use TsIdx as a index
1263 // to the DistinctTokenSpace[]
1265 *ExMapTableSize
= TsIdx
+ 1;
1266 return DistinctTokenSpace
;
1271 Retrieves the next valid PCD token namespace for a given namespace.
1273 Gets the next valid token namespace for a given namespace. This is useful to traverse the valid
1274 token namespaces on a platform.
1276 @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token
1277 namespace from which the search will start. On output, it designates the next valid
1278 token namespace on the platform. If *Guid is NULL, then the GUID of the first token
1279 space of the current platform is returned. If the search cannot locate the next valid
1280 token namespace, an error is returned and the value of *Guid is undefined.
1282 @retval EFI_SUCCESS The PCD service retrieved the value requested.
1283 @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.
1288 DxePcdGetNextTokenSpace (
1289 IN OUT CONST EFI_GUID
**Guid
1295 UINTN PeiTokenSpaceTableSize
;
1296 UINTN DxeTokenSpaceTableSize
;
1297 EFI_GUID
**PeiTokenSpaceTable
;
1298 EFI_GUID
**DxeTokenSpaceTable
;
1300 BOOLEAN PeiExMapTableEmpty
;
1301 BOOLEAN DxeExMapTableEmpty
;
1303 ASSERT (Guid
!= NULL
);
1305 PeiExMapTableEmpty
= mPeiExMapTableEmpty
;
1306 DxeExMapTableEmpty
= mDxeExMapTableEmpty
;
1308 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
1309 return EFI_NOT_FOUND
;
1312 if (TmpTokenSpaceBuffer
[0] == NULL
) {
1313 PeiTokenSpaceTableSize
= 0;
1315 if (!PeiExMapTableEmpty
) {
1316 PeiTokenSpaceTableSize
= mPeiExMapppingTableSize
/ sizeof(DYNAMICEX_MAPPING
);
1317 PeiTokenSpaceTable
= GetDistinctTokenSpace (&PeiTokenSpaceTableSize
,
1318 (DYNAMICEX_MAPPING
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->ExMapTableOffset
),
1319 (EFI_GUID
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
)
1321 CopyMem (TmpTokenSpaceBuffer
, PeiTokenSpaceTable
, sizeof (EFI_GUID
*) * PeiTokenSpaceTableSize
);
1322 TmpTokenSpaceBufferCount
= PeiTokenSpaceTableSize
;
1323 FreePool (PeiTokenSpaceTable
);
1326 if (!DxeExMapTableEmpty
) {
1327 DxeTokenSpaceTableSize
= mDxeExMapppingTableSize
/ sizeof(DYNAMICEX_MAPPING
);
1328 DxeTokenSpaceTable
= GetDistinctTokenSpace (&DxeTokenSpaceTableSize
,
1329 (DYNAMICEX_MAPPING
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->ExMapTableOffset
),
1330 (EFI_GUID
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
)
1334 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
1336 for (Idx2
= 0, Idx3
= PeiTokenSpaceTableSize
; Idx2
< DxeTokenSpaceTableSize
; Idx2
++) {
1338 for (Idx
= 0; Idx
< PeiTokenSpaceTableSize
; Idx
++) {
1339 if (CompareGuid (TmpTokenSpaceBuffer
[Idx
], DxeTokenSpaceTable
[Idx2
])) {
1345 TmpTokenSpaceBuffer
[Idx3
++] = DxeTokenSpaceTable
[Idx2
];
1349 TmpTokenSpaceBufferCount
= Idx3
;
1350 FreePool (DxeTokenSpaceTable
);
1354 if (*Guid
== NULL
) {
1355 *Guid
= TmpTokenSpaceBuffer
[0];
1359 for (Idx
= 0; Idx
< TmpTokenSpaceBufferCount
; Idx
++) {
1360 if (CompareGuid (*Guid
, TmpTokenSpaceBuffer
[Idx
])) {
1361 if (Idx
== TmpTokenSpaceBufferCount
- 1) {
1363 // It has been the last token namespace.
1366 return EFI_NOT_FOUND
;
1369 *Guid
= TmpTokenSpaceBuffer
[Idx
];
1375 return EFI_NOT_FOUND
;