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 - 2017, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 /// PCD database lock.
22 EFI_LOCK mPcdDatabaseLock
= EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY
);
25 /// PCD_PROTOCOL the EDKII native implementation which support dynamic
26 /// type and dynamicEx type PCDs.
28 PCD_PROTOCOL mPcdInstance
= {
61 DxeRegisterCallBackOnSet
,
62 DxeUnRegisterCallBackOnSet
,
64 DxePcdGetNextTokenSpace
68 /// EFI_PCD_PROTOCOL is defined in PI 1.2 Vol 3 which only support dynamicEx type
71 EFI_PCD_PROTOCOL mEfiPcdInstance
= {
86 (EFI_PCD_PROTOCOL_CALLBACK_ON_SET
) DxeRegisterCallBackOnSet
,
87 (EFI_PCD_PROTOCOL_CANCEL_CALLBACK
) DxeUnRegisterCallBackOnSet
,
89 DxePcdGetNextTokenSpace
93 /// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementation.
94 /// This protocol instance support dynamic and dynamicEx type PCDs.
96 GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance
= {
98 DxeGetPcdInfoGetInfoEx
,
103 /// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol 3.
104 /// This PPI instance only support dyanmicEx type PCD.
106 EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance
= {
107 DxeGetPcdInfoGetInfoEx
,
111 EFI_HANDLE mPcdHandle
= NULL
;
114 Main entry for PCD DXE driver.
116 This routine initialize the PCD database and install PCD_PROTOCOL.
118 @param ImageHandle Image handle for PCD DXE driver.
119 @param SystemTable Pointer to SystemTable.
121 @return Status of gBS->InstallProtocolInterface()
127 IN EFI_HANDLE ImageHandle
,
128 IN EFI_SYSTEM_TABLE
*SystemTable
135 // Make sure the Pcd Protocol is not already installed in the system
138 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gPcdProtocolGuid
);
140 BuildPcdDxeDataBase ();
143 // Install PCD_PROTOCOL to handle dynamic type PCD
144 // Install EFI_PCD_PROTOCOL to handle dynamicEx type PCD
146 Status
= gBS
->InstallMultipleProtocolInterfaces (
148 &gPcdProtocolGuid
, &mPcdInstance
,
149 &gEfiPcdProtocolGuid
, &mEfiPcdInstance
,
152 ASSERT_EFI_ERROR (Status
);
155 // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD
156 // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD
158 Status
= gBS
->InstallMultipleProtocolInterfaces (
160 &gGetPcdInfoProtocolGuid
, &mGetPcdInfoInstance
,
161 &gEfiGetPcdInfoProtocolGuid
, &mEfiGetPcdInfoInstance
,
164 ASSERT_EFI_ERROR (Status
);
167 // Register callback function upon VariableLockProtocol
168 // to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.
170 EfiCreateProtocolNotifyEvent (
171 &gEdkiiVariableLockProtocolGuid
,
173 VariableLockCallBack
,
182 Retrieve additional information associated with a PCD token in the default token space.
184 This includes information such as the type of value the TokenNumber is associated with as well as possible
185 human readable name that is associated with the token.
187 @param[in] TokenNumber The PCD token number.
188 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
189 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
191 @retval EFI_SUCCESS The PCD information was returned successfully.
192 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
196 DxeGetPcdInfoGetInfo (
197 IN UINTN TokenNumber
,
198 OUT EFI_PCD_INFO
*PcdInfo
201 return DxeGetPcdInfo (NULL
, TokenNumber
, PcdInfo
);
205 Retrieve additional information associated with a PCD token.
207 This includes information such as the type of value the TokenNumber is associated with as well as possible
208 human readable name that is associated with the token.
210 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
211 @param[in] TokenNumber The PCD token number.
212 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
213 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
215 @retval EFI_SUCCESS The PCD information was returned successfully.
216 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
220 DxeGetPcdInfoGetInfoEx (
221 IN CONST EFI_GUID
*Guid
,
222 IN UINTN TokenNumber
,
223 OUT EFI_PCD_INFO
*PcdInfo
226 return DxeGetPcdInfo (Guid
, TokenNumber
, PcdInfo
);
230 Retrieve the currently set SKU Id.
232 @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
233 default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
238 DxeGetPcdInfoGetSku (
242 return (UINTN
) mPcdDatabase
.DxeDb
->SystemSkuId
;
246 Sets the SKU value for subsequent calls to set or get PCD token values.
248 SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values.
249 SetSku() is normally called only once by the system.
251 For each item (token), the database can hold a single value that applies to all SKUs,
252 or multiple values, where each value is associated with a specific SKU Id. Items with multiple,
253 SKU-specific values are called SKU enabled.
255 The SKU Id of zero is reserved as a default.
256 For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the
257 single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the
258 last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token,
259 the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been
260 set for that Id, the results are unpredictable.
262 @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and
263 set values associated with a PCD token.
276 if (SkuId
== mPcdDatabase
.DxeDb
->SystemSkuId
) {
278 // The input SKU Id is equal to current SKU Id, return directly.
283 if (mPcdDatabase
.DxeDb
->SystemSkuId
!= (SKU_ID
) 0) {
284 DEBUG ((DEBUG_ERROR
, "PcdDxe - The SKU Id could be changed only once."));
287 "PcdDxe - The SKU Id was set to 0x%lx already, it could not be set to 0x%lx any more.",
288 mPcdDatabase
.DxeDb
->SystemSkuId
,
295 SkuIdTable
= (SKU_ID
*) ((UINT8
*) mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->SkuIdTableOffset
);
296 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
297 if (SkuId
== SkuIdTable
[Index
+ 1]) {
298 Status
= UpdatePcdDatabase (SkuId
, TRUE
);
299 if (!EFI_ERROR (Status
)) {
300 mPcdDatabase
.DxeDb
->SystemSkuId
= (SKU_ID
) SkuId
;
301 DEBUG ((DEBUG_INFO
, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SKU_ID
) SkuId
));
308 // Invalid input SkuId, the default SKU Id will be still used for the system.
310 DEBUG ((DEBUG_INFO
, "PcdDxe - Invalid input SkuId, the default SKU Id will be still used.\n"));
315 Retrieves an 8-bit value for a given PCD token.
317 Retrieves the current byte-sized value for a PCD token number.
318 If the TokenNumber is invalid, the results are unpredictable.
320 @param[in] TokenNumber The PCD token number.
322 @return The UINT8 value.
331 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
335 Retrieves an 16-bit value for a given PCD token.
337 Retrieves the current 16-bits value for a PCD token number.
338 If the TokenNumber is invalid, the results are unpredictable.
340 @param[in] TokenNumber The PCD token number.
342 @return The UINT16 value.
351 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
355 Retrieves an 32-bit value for a given PCD token.
357 Retrieves the current 32-bits value for a PCD token number.
358 If the TokenNumber is invalid, the results are unpredictable.
360 @param[in] TokenNumber The PCD token number.
362 @return The UINT32 value.
371 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
375 Retrieves an 64-bit value for a given PCD token.
377 Retrieves the current 64-bits value for a PCD token number.
378 If the TokenNumber is invalid, the results are unpredictable.
380 @param[in] TokenNumber The PCD token number.
382 @return The UINT64 value.
391 return ReadUnaligned64(GetWorker (TokenNumber
, sizeof (UINT64
)));
395 Retrieves a pointer to a value for a given PCD token.
397 Retrieves the current pointer to the buffer for a PCD token number.
398 Do not make any assumptions about the alignment of the pointer that
399 is returned by this function call. If the TokenNumber is invalid,
400 the results are unpredictable.
402 @param[in] TokenNumber The PCD token number.
404 @return The pointer to the buffer to be retrived.
413 return GetWorker (TokenNumber
, 0);
417 Retrieves a Boolean value for a given PCD token.
419 Retrieves the current boolean value for a PCD token number.
420 Do not make any assumptions about the alignment of the pointer that
421 is returned by this function call. If the TokenNumber is invalid,
422 the results are unpredictable.
424 @param[in] TokenNumber The PCD token number.
426 @return The Boolean value.
435 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
439 Retrieves the size of the value for a given PCD token.
441 Retrieves the current size of a particular PCD token.
442 If the TokenNumber is invalid, the results are unpredictable.
444 @param[in] TokenNumber The PCD token number.
446 @return The size of the value for the PCD token.
456 UINT32
*LocalTokenNumberTable
;
459 UINTN TmpTokenNumber
;
461 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
462 // We have to decrement TokenNumber by 1 to make it usable
463 // as the array index.
468 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
470 TmpTokenNumber
= TokenNumber
;
472 // EBC compiler is very choosy. It may report warning about comparison
473 // between UINTN and 0 . So we add 1 in each size of the
475 ASSERT (TokenNumber
+ 1 < mPcdTotalTokenCount
+ 1);
477 // EBC compiler is very choosy. It may report warning about comparison
478 // between UINTN and 0 . So we add 1 in each size of the
480 IsPeiDb
= (BOOLEAN
) (TokenNumber
+ 1 < mPeiLocalTokenCount
+ 1);
482 TokenNumber
= IsPeiDb
? TokenNumber
:
483 (TokenNumber
- mPeiLocalTokenCount
);
485 LocalTokenNumberTable
= IsPeiDb
? (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
)
486 : (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
488 Size
= (LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
492 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
494 return GetPtrTypeSize (TmpTokenNumber
, &MaxSize
);
502 Retrieves an 8-bit value for a given PCD token.
504 Retrieves the 8-bit value of a particular PCD token.
505 If the TokenNumber is invalid or the token space
506 specified by Guid does not exist, the results are
509 @param[in] Guid The token space for the token number.
510 @param[in] ExTokenNumber The PCD token number.
512 @return The size 8-bit value for the PCD token.
518 IN CONST EFI_GUID
*Guid
,
519 IN UINTN ExTokenNumber
522 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT8
)));
526 Retrieves an 16-bit value for a given PCD token.
528 Retrieves the 16-bit value of a particular PCD token.
529 If the TokenNumber is invalid or the token space
530 specified by Guid does not exist, the results are
533 @param[in] Guid The token space for the token number.
534 @param[in] ExTokenNumber The PCD token number.
536 @return The size 16-bit value for the PCD token.
542 IN CONST EFI_GUID
*Guid
,
543 IN UINTN ExTokenNumber
546 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT16
)));
550 Retrieves an 32-bit value for a given PCD token.
552 Retrieves the 32-bit value of a particular PCD token.
553 If the TokenNumber is invalid or the token space
554 specified by Guid does not exist, the results are
557 @param[in] Guid The token space for the token number.
558 @param[in] ExTokenNumber The PCD token number.
560 @return The size 32-bit value for the PCD token.
566 IN CONST EFI_GUID
*Guid
,
567 IN UINTN ExTokenNumber
570 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT32
)));
574 Retrieves an 64-bit value for a given PCD token.
576 Retrieves the 64-bit value of a particular PCD token.
577 If the TokenNumber is invalid or the token space
578 specified by Guid does not exist, the results are
581 @param[in] Guid The token space for the token number.
582 @param[in] ExTokenNumber The PCD token number.
584 @return The size 64-bit value for the PCD token.
590 IN CONST EFI_GUID
*Guid
,
591 IN UINTN ExTokenNumber
594 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT64
)));
598 Retrieves a pointer to a value for a given PCD token.
600 Retrieves the current pointer to the buffer for a PCD token number.
601 Do not make any assumptions about the alignment of the pointer that
602 is returned by this function call. If the TokenNumber is invalid,
603 the results are unpredictable.
605 @param[in] Guid The token space for the token number.
606 @param[in] ExTokenNumber The PCD token number.
608 @return The pointer to the buffer to be retrived.
614 IN CONST EFI_GUID
*Guid
,
615 IN UINTN ExTokenNumber
618 return ExGetWorker (Guid
, ExTokenNumber
, 0);
622 Retrieves an Boolean value for a given PCD token.
624 Retrieves the Boolean value of a particular PCD token.
625 If the TokenNumber is invalid or the token space
626 specified by Guid does not exist, the results are
629 @param[in] Guid The token space for the token number.
630 @param[in] ExTokenNumber The PCD token number.
632 @return The size Boolean value for the PCD token.
638 IN CONST EFI_GUID
*Guid
,
639 IN UINTN ExTokenNumber
642 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(BOOLEAN
)));
646 Retrieves the size of the value for a given PCD token.
648 Retrieves the current size of a particular PCD token.
649 If the TokenNumber is invalid, the results are unpredictable.
651 @param[in] Guid The token space for the token number.
652 @param[in] ExTokenNumber The PCD token number.
654 @return The size of the value for the PCD token.
660 IN CONST EFI_GUID
*Guid
,
661 IN UINTN ExTokenNumber
664 return DxePcdGetSize(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
));
668 Sets an 8-bit value for a given PCD token.
670 When the PCD service sets a value, it will check to ensure that the
671 size of the value being set is compatible with the Token's existing definition.
672 If it is not, an error will be returned.
674 @param[in] TokenNumber The PCD token number.
675 @param[in] Value The value to set for the PCD token.
677 @retval EFI_SUCCESS Procedure returned successfully.
678 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
679 being set was incompatible with a call to this function.
680 Use GetSize() to retrieve the size of the target data.
681 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
687 IN UINTN TokenNumber
,
691 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
695 Sets an 16-bit value for a given PCD token.
697 When the PCD service sets a value, it will check to ensure that the
698 size of the value being set is compatible with the Token's existing definition.
699 If it is not, an error will be returned.
701 @param[in] TokenNumber The PCD token number.
702 @param[in] Value The value to set for the PCD token.
704 @retval EFI_SUCCESS Procedure returned successfully.
705 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
706 being set was incompatible with a call to this function.
707 Use GetSize() to retrieve the size of the target data.
708 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
714 IN UINTN TokenNumber
,
718 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
722 Sets an 32-bit value for a given PCD token.
724 When the PCD service sets a value, it will check to ensure that the
725 size of the value being set is compatible with the Token's existing definition.
726 If it is not, an error will be returned.
728 @param[in] TokenNumber The PCD token number.
729 @param[in] Value The value to set for the PCD token.
731 @retval EFI_SUCCESS Procedure returned successfully.
732 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
733 being set was incompatible with a call to this function.
734 Use GetSize() to retrieve the size of the target data.
735 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
741 IN UINTN TokenNumber
,
745 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
749 Sets an 64-bit value for a given PCD token.
751 When the PCD service sets a value, it will check to ensure that the
752 size of the value being set is compatible with the Token's existing definition.
753 If it is not, an error will be returned.
755 @param[in] TokenNumber The PCD token number.
756 @param[in] Value The value to set for the PCD token.
758 @retval EFI_SUCCESS Procedure returned successfully.
759 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
760 being set was incompatible with a call to this function.
761 Use GetSize() to retrieve the size of the target data.
762 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
768 IN UINTN TokenNumber
,
772 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
776 Sets a value of a specified size for a given PCD token.
778 When the PCD service sets a value, it will check to ensure that the
779 size of the value being set is compatible with the Token's existing definition.
780 If it is not, an error will be returned.
782 @param[in] TokenNumber The PCD token number.
783 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.
784 On input, if the SizeOfValue is greater than the maximum size supported
785 for this TokenNumber then the output value of SizeOfValue will reflect
786 the maximum size supported for this TokenNumber.
787 @param[in] Buffer The buffer to set for the PCD token.
789 @retval EFI_SUCCESS Procedure returned successfully.
790 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
791 being set was incompatible with a call to this function.
792 Use GetSize() to retrieve the size of the target data.
793 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
799 IN UINTN TokenNumber
,
800 IN OUT UINTN
*SizeOfBuffer
,
804 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
808 Sets an Boolean value for a given PCD token.
810 When the PCD service sets a value, it will check to ensure that the
811 size of the value being set is compatible with the Token's existing definition.
812 If it is not, an error will be returned.
814 @param[in] TokenNumber The PCD token number.
815 @param[in] Value The value to set for the PCD token.
817 @retval EFI_SUCCESS Procedure returned successfully.
818 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
819 being set was incompatible with a call to this function.
820 Use GetSize() to retrieve the size of the target data.
821 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
827 IN UINTN TokenNumber
,
831 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
835 Sets an 8-bit value for a given PCD token.
837 When the PCD service sets a value, it will check to ensure that the
838 size of the value being set is compatible with the Token's existing definition.
839 If it is not, an error will be returned.
841 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
842 @param[in] ExTokenNumber The PCD token number.
843 @param[in] Value The value to set for the PCD token.
845 @retval EFI_SUCCESS Procedure returned successfully.
846 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
847 being set was incompatible with a call to this function.
848 Use GetSize() to retrieve the size of the target data.
849 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
855 IN CONST EFI_GUID
*Guid
,
856 IN UINTN ExTokenNumber
,
860 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
864 Sets an 16-bit value for a given PCD token.
866 When the PCD service sets a value, it will check to ensure that the
867 size of the value being set is compatible with the Token's existing definition.
868 If it is not, an error will be returned.
870 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
871 @param[in] ExTokenNumber The PCD token number.
872 @param[in] Value The value to set for the PCD token.
874 @retval EFI_SUCCESS Procedure returned successfully.
875 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
876 being set was incompatible with a call to this function.
877 Use GetSize() to retrieve the size of the target data.
878 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
884 IN CONST EFI_GUID
*Guid
,
885 IN UINTN ExTokenNumber
,
889 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
893 Sets an 32-bit value for a given PCD token.
895 When the PCD service sets a value, it will check to ensure that the
896 size of the value being set is compatible with the Token's existing definition.
897 If it is not, an error will be returned.
899 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
900 @param[in] ExTokenNumber The PCD token number.
901 @param[in] Value The value to set for the PCD token.
903 @retval EFI_SUCCESS Procedure returned successfully.
904 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
905 being set was incompatible with a call to this function.
906 Use GetSize() to retrieve the size of the target data.
907 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
913 IN CONST EFI_GUID
*Guid
,
914 IN UINTN ExTokenNumber
,
918 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
922 Sets an 64-bit value for a given PCD token.
924 When the PCD service sets a value, it will check to ensure that the
925 size of the value being set is compatible with the Token's existing definition.
926 If it is not, an error will be returned.
928 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
929 @param[in] ExTokenNumber The PCD token number.
930 @param[in] Value The value to set for the PCD token.
932 @retval EFI_SUCCESS Procedure returned successfully.
933 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
934 being set was incompatible with a call to this function.
935 Use GetSize() to retrieve the size of the target data.
936 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
942 IN CONST EFI_GUID
*Guid
,
943 IN UINTN ExTokenNumber
,
947 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
951 Sets a value of a specified size for a given PCD token.
953 When the PCD service sets a value, it will check to ensure that the
954 size of the value being set is compatible with the Token's existing definition.
955 If it is not, an error will be returned.
957 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
958 @param[in] ExTokenNumber The PCD token number.
959 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.
960 On input, if the SizeOfValue is greater than the maximum size supported
961 for this TokenNumber then the output value of SizeOfValue will reflect
962 the maximum size supported for this TokenNumber.
963 @param[in] Buffer The buffer to set for the PCD token.
965 @retval EFI_SUCCESS Procedure returned successfully.
966 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
967 being set was incompatible with a call to this function.
968 Use GetSize() to retrieve the size of the target data.
969 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
975 IN CONST EFI_GUID
*Guid
,
976 IN UINTN ExTokenNumber
,
977 IN OUT UINTN
*SizeOfBuffer
,
981 return ExSetWorker(ExTokenNumber
, Guid
, Buffer
, SizeOfBuffer
, TRUE
);
985 Sets an Boolean value for a given PCD token.
987 When the PCD service sets a value, it will check to ensure that the
988 size of the value being set is compatible with the Token's existing definition.
989 If it is not, an error will be returned.
991 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
992 @param[in] ExTokenNumber The PCD token number.
993 @param[in] Value The value to set for the PCD token.
995 @retval EFI_SUCCESS Procedure returned successfully.
996 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
997 being set was incompatible with a call to this function.
998 Use GetSize() to retrieve the size of the target data.
999 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
1005 IN CONST EFI_GUID
*Guid
,
1006 IN UINTN ExTokenNumber
,
1010 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
1014 Specifies a function to be called anytime the value of a designated token is changed.
1016 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
1017 @param[in] TokenNumber The PCD token number.
1018 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.
1020 @retval EFI_SUCCESS The PCD service has successfully established a call event
1021 for the CallBackToken requested.
1022 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.
1027 DxeRegisterCallBackOnSet (
1028 IN CONST EFI_GUID
*Guid
, OPTIONAL
1029 IN UINTN TokenNumber
,
1030 IN PCD_PROTOCOL_CALLBACK CallBackFunction
1035 if (CallBackFunction
== NULL
) {
1036 return EFI_INVALID_PARAMETER
;
1039 // Aquire lock to prevent reentrance from TPL_CALLBACK level
1041 EfiAcquireLock (&mPcdDatabaseLock
);
1043 Status
= DxeRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
1045 EfiReleaseLock (&mPcdDatabaseLock
);
1051 Cancels a previously set callback function for a particular PCD token number.
1053 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
1054 @param[in] TokenNumber The PCD token number.
1055 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.
1057 @retval EFI_SUCCESS The PCD service has successfully established a call event
1058 for the CallBackToken requested.
1059 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.
1064 DxeUnRegisterCallBackOnSet (
1065 IN CONST EFI_GUID
*Guid
, OPTIONAL
1066 IN UINTN TokenNumber
,
1067 IN PCD_PROTOCOL_CALLBACK CallBackFunction
1072 if (CallBackFunction
== NULL
) {
1073 return EFI_INVALID_PARAMETER
;
1077 // Aquire lock to prevent reentrance from TPL_CALLBACK level
1079 EfiAcquireLock (&mPcdDatabaseLock
);
1081 Status
= DxeUnRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
1083 EfiReleaseLock (&mPcdDatabaseLock
);
1089 Retrieves the next valid token number in a given namespace.
1091 This is useful since the PCD infrastructure contains a sparse list of token numbers,
1092 and one cannot a priori know what token numbers are valid in the database.
1094 If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned.
1095 If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned.
1096 If TokenNumber is 0 and Guid is NULL, then the first token in the default token space is returned.
1097 If TokenNumber is not 0 and Guid is NULL, then the next token in the default token space is returned.
1098 The token numbers in the default token space may not be related to token numbers in token spaces that are named by Guid.
1099 If the next token number can be retrieved, then it is returned in TokenNumber, and EFI_SUCCESS is returned.
1100 If TokenNumber represents the last token number in the token space specified by Guid, then EFI_NOT_FOUND is returned.
1101 If TokenNumber is not present in the token space specified by Guid, then EFI_NOT_FOUND is returned.
1104 @param[in] Guid The 128-bit unique value that designates the namespace from which to retrieve the next token.
1105 This is an optional parameter that may be NULL. If this parameter is NULL, then a request is
1106 being made to retrieve tokens from the default token space.
1107 @param[in, out] TokenNumber
1108 A pointer to the PCD token number to use to find the subsequent token number.
1110 @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
1111 @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
1116 DxePcdGetNextToken (
1117 IN CONST EFI_GUID
*Guid
, OPTIONAL
1118 IN OUT UINTN
*TokenNumber
1122 BOOLEAN PeiExMapTableEmpty
;
1123 BOOLEAN DxeExMapTableEmpty
;
1125 Status
= EFI_NOT_FOUND
;
1126 PeiExMapTableEmpty
= mPeiExMapTableEmpty
;
1127 DxeExMapTableEmpty
= mDxeExMapTableEmpty
;
1130 // Scan the local token space
1133 // EBC compiler is very choosy. It may report warning about comparison
1134 // between UINTN and 0 . So we add 1 in each size of the
1136 if (((*TokenNumber
+ 1 > mPeiNexTokenCount
+ 1) && (*TokenNumber
+ 1 <= mPeiLocalTokenCount
+ 1)) ||
1137 ((*TokenNumber
+ 1 > (mPeiLocalTokenCount
+ mDxeNexTokenCount
+ 1)))) {
1138 return EFI_NOT_FOUND
;
1142 if ((*TokenNumber
+ 1 > mPeiNexTokenCount
+ 1) &&
1143 (*TokenNumber
+ 1 <= mPeiLocalTokenCount
+ 1)) {
1145 // The first Non-Ex type Token Number for DXE PCD
1146 // database is mPeiLocalTokenCount + 1
1148 if (mDxeNexTokenCount
> 0) {
1149 *TokenNumber
= mPeiLocalTokenCount
+ 1;
1151 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
1152 return EFI_NOT_FOUND
;
1154 } else if (*TokenNumber
+ 1 > mDxeNexTokenCount
+ mPeiLocalTokenCount
+ 1) {
1155 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
1156 return EFI_NOT_FOUND
;
1161 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
1162 return EFI_NOT_FOUND
;
1165 if (!PeiExMapTableEmpty
) {
1166 Status
= ExGetNextTokeNumber (
1169 (EFI_GUID
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
),
1171 (DYNAMICEX_MAPPING
*)((UINT8
*) mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->ExMapTableOffset
),
1172 mPeiExMapppingTableSize
1176 if (Status
== EFI_SUCCESS
) {
1180 if (!DxeExMapTableEmpty
) {
1181 Status
= ExGetNextTokeNumber (
1184 (EFI_GUID
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
),
1186 (DYNAMICEX_MAPPING
*)((UINT8
*) mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->ExMapTableOffset
),
1187 mDxeExMapppingTableSize
1195 Get all token space guid table which is different with given token space guid.
1197 @param ExMapTableSize The size of ExMapTable in item
1198 @param ExMapTable Token space guid table that want to be scaned.
1199 @param GuidTable Guid table
1201 @return all token space guid table which is different with given token space guid.
1205 GetDistinctTokenSpace (
1206 IN OUT UINTN
*ExMapTableSize
,
1207 IN DYNAMICEX_MAPPING
*ExMapTable
,
1208 IN EFI_GUID
*GuidTable
1211 EFI_GUID
**DistinctTokenSpace
;
1218 DistinctTokenSpace
= AllocateZeroPool (*ExMapTableSize
* sizeof (EFI_GUID
*));
1219 ASSERT (DistinctTokenSpace
!= NULL
);
1222 OldGuidIndex
= ExMapTable
[0].ExGuidIndex
;
1223 DistinctTokenSpace
[TsIdx
] = &GuidTable
[OldGuidIndex
];
1224 for (Idx
= 1; Idx
< *ExMapTableSize
; Idx
++) {
1226 OldGuidIndex
= ExMapTable
[Idx
].ExGuidIndex
;
1227 for (TempTsIdx
= 0; TempTsIdx
<= TsIdx
; TempTsIdx
++) {
1228 if (&GuidTable
[OldGuidIndex
] == DistinctTokenSpace
[TempTsIdx
]) {
1230 // Have recorded this GUID.
1237 DistinctTokenSpace
[++TsIdx
] = &GuidTable
[OldGuidIndex
];
1242 // The total number of Distinct Token Space
1243 // is TsIdx + 1 because we use TsIdx as a index
1244 // to the DistinctTokenSpace[]
1246 *ExMapTableSize
= TsIdx
+ 1;
1247 return DistinctTokenSpace
;
1252 Retrieves the next valid PCD token namespace for a given namespace.
1254 Gets the next valid token namespace for a given namespace. This is useful to traverse the valid
1255 token namespaces on a platform.
1257 @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token
1258 namespace from which the search will start. On output, it designates the next valid
1259 token namespace on the platform. If *Guid is NULL, then the GUID of the first token
1260 space of the current platform is returned. If the search cannot locate the next valid
1261 token namespace, an error is returned and the value of *Guid is undefined.
1263 @retval EFI_SUCCESS The PCD service retrieved the value requested.
1264 @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.
1269 DxePcdGetNextTokenSpace (
1270 IN OUT CONST EFI_GUID
**Guid
1276 UINTN PeiTokenSpaceTableSize
;
1277 UINTN DxeTokenSpaceTableSize
;
1278 EFI_GUID
**PeiTokenSpaceTable
;
1279 EFI_GUID
**DxeTokenSpaceTable
;
1281 BOOLEAN PeiExMapTableEmpty
;
1282 BOOLEAN DxeExMapTableEmpty
;
1284 ASSERT (Guid
!= NULL
);
1286 PeiExMapTableEmpty
= mPeiExMapTableEmpty
;
1287 DxeExMapTableEmpty
= mDxeExMapTableEmpty
;
1289 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
1290 return EFI_NOT_FOUND
;
1293 if (TmpTokenSpaceBuffer
[0] == NULL
) {
1294 PeiTokenSpaceTableSize
= 0;
1296 if (!PeiExMapTableEmpty
) {
1297 PeiTokenSpaceTableSize
= mPeiExMapppingTableSize
/ sizeof(DYNAMICEX_MAPPING
);
1298 PeiTokenSpaceTable
= GetDistinctTokenSpace (&PeiTokenSpaceTableSize
,
1299 (DYNAMICEX_MAPPING
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->ExMapTableOffset
),
1300 (EFI_GUID
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
)
1302 CopyMem (TmpTokenSpaceBuffer
, PeiTokenSpaceTable
, sizeof (EFI_GUID
*) * PeiTokenSpaceTableSize
);
1303 TmpTokenSpaceBufferCount
= PeiTokenSpaceTableSize
;
1304 FreePool (PeiTokenSpaceTable
);
1307 if (!DxeExMapTableEmpty
) {
1308 DxeTokenSpaceTableSize
= mDxeExMapppingTableSize
/ sizeof(DYNAMICEX_MAPPING
);
1309 DxeTokenSpaceTable
= GetDistinctTokenSpace (&DxeTokenSpaceTableSize
,
1310 (DYNAMICEX_MAPPING
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->ExMapTableOffset
),
1311 (EFI_GUID
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
)
1315 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
1317 for (Idx2
= 0, Idx3
= PeiTokenSpaceTableSize
; Idx2
< DxeTokenSpaceTableSize
; Idx2
++) {
1319 for (Idx
= 0; Idx
< PeiTokenSpaceTableSize
; Idx
++) {
1320 if (CompareGuid (TmpTokenSpaceBuffer
[Idx
], DxeTokenSpaceTable
[Idx2
])) {
1326 TmpTokenSpaceBuffer
[Idx3
++] = DxeTokenSpaceTable
[Idx2
];
1330 TmpTokenSpaceBufferCount
= Idx3
;
1331 FreePool (DxeTokenSpaceTable
);
1335 if (*Guid
== NULL
) {
1336 *Guid
= TmpTokenSpaceBuffer
[0];
1340 for (Idx
= 0; Idx
< TmpTokenSpaceBufferCount
; Idx
++) {
1341 if (CompareGuid (*Guid
, TmpTokenSpaceBuffer
[Idx
])) {
1342 if (Idx
== TmpTokenSpaceBufferCount
- 1) {
1344 // It has been the last token namespace.
1347 return EFI_NOT_FOUND
;
1350 *Guid
= TmpTokenSpaceBuffer
[Idx
];
1356 return EFI_NOT_FOUND
;