2 PCD DXE driver manage all PCD entry initialized in PEI phase and DXE phase, and
3 produce the implementation of PCD protocol.
5 Copyright (c) 2006 - 2007, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 // Just pre-allocate a memory buffer that is big enough to
20 // host all distinct TokenSpace guid in both
21 // PEI ExMap and DXE ExMap.
23 EFI_GUID
*TmpTokenSpaceBuffer
[PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
] = { 0 };
26 /// PCD database lock.
28 EFI_LOCK mPcdDatabaseLock
= EFI_INITIALIZE_LOCK_VARIABLE(TPL_CALLBACK
);
30 PCD_PROTOCOL mPcdInstance
= {
63 DxeRegisterCallBackOnSet
,
64 DxeUnRegisterCallBackOnSet
,
66 DxePcdGetNextTokenSpace
71 // Static global to reduce the code size
73 EFI_HANDLE mNewHandle
= NULL
;
76 Main entry for PCD DXE driver.
78 This routine initialize the PCD database and install PCD_PROTOCOL.
80 @param ImageHandle Image handle for PCD DXE driver.
81 @param SystemTable Pointer to SystemTable.
83 @return Status of gBS->InstallProtocolInterface()
89 IN EFI_HANDLE ImageHandle
,
90 IN EFI_SYSTEM_TABLE
*SystemTable
96 // Make sure the Pcd Protocol is not already installed in the system
99 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gPcdProtocolGuid
);
101 BuildPcdDxeDataBase ();
103 Status
= gBS
->InstallProtocolInterface (
106 EFI_NATIVE_INTERFACE
,
110 ASSERT_EFI_ERROR (Status
);
117 Sets the SKU value for subsequent calls to set or get PCD token values.
119 SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values.
120 SetSku() is normally called only once by the system.
122 For each item (token), the database can hold a single value that applies to all SKUs,
123 or multiple values, where each value is associated with a specific SKU Id. Items with multiple,
124 SKU-specific values are called SKU enabled.
126 The SKU Id of zero is reserved as a default. The valid SkuId range is 1 to 255.
127 For tokens that are not SKU enabled, the system ignores any set SKU Id and works with the
128 single value for that token. For SKU-enabled tokens, the system will use the SKU Id set by the
129 last call to SetSku(). If no SKU Id is set or the currently set SKU Id isn't valid for the specified token,
130 the system uses the default SKU Id. If the system attempts to use the default SKU Id and no value has been
131 set for that Id, the results are unpredictable.
133 @param[in] SkuId The SKU value that will be used when the PCD service will retrieve and
134 set values associated with a PCD token.
143 mPcdDatabase
->PeiDb
.Init
.SystemSkuId
= (SKU_ID
) SkuId
;
149 Retrieves an 8-bit value for a given PCD token.
151 Retrieves the current byte-sized value for a PCD token number.
152 If the TokenNumber is invalid, the results are unpredictable.
154 @param[in] TokenNumber The PCD token number.
156 @return The UINT8 value.
165 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
169 Retrieves an 16-bit value for a given PCD token.
171 Retrieves the current 16-bits value for a PCD token number.
172 If the TokenNumber is invalid, the results are unpredictable.
174 @param[in] TokenNumber The PCD token number.
176 @return The UINT16 value.
185 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
189 Retrieves an 32-bit value for a given PCD token.
191 Retrieves the current 32-bits value for a PCD token number.
192 If the TokenNumber is invalid, the results are unpredictable.
194 @param[in] TokenNumber The PCD token number.
196 @return The UINT32 value.
205 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
209 Retrieves an 64-bit value for a given PCD token.
211 Retrieves the current 64-bits value for a PCD token number.
212 If the TokenNumber is invalid, the results are unpredictable.
214 @param[in] TokenNumber The PCD token number.
216 @return The UINT64 value.
225 return ReadUnaligned64(GetWorker (TokenNumber
, sizeof (UINT64
)));
229 Retrieves a pointer to a value for a given PCD token.
231 Retrieves the current pointer to the buffer for a PCD token number.
232 Do not make any assumptions about the alignment of the pointer that
233 is returned by this function call. If the TokenNumber is invalid,
234 the results are unpredictable.
236 @param[in] TokenNumber The PCD token number.
238 @return The pointer to the buffer to be retrived.
247 return GetWorker (TokenNumber
, 0);
251 Retrieves a Boolean value for a given PCD token.
253 Retrieves the current boolean value for a PCD token number.
254 Do not make any assumptions about the alignment of the pointer that
255 is returned by this function call. If the TokenNumber is invalid,
256 the results are unpredictable.
258 @param[in] TokenNumber The PCD token number.
260 @return The Boolean value.
269 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
273 Retrieves the size of the value for a given PCD token.
275 Retrieves the current size of a particular PCD token.
276 If the TokenNumber is invalid, the results are unpredictable.
278 @param[in] TokenNumber The PCD token number.
280 @return The size of the value for the PCD token.
290 UINT32
*LocalTokenNumberTable
;
293 UINTN TmpTokenNumber
;
295 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
296 // We have to decrement TokenNumber by 1 to make it usable
297 // as the array index.
302 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
304 TmpTokenNumber
= TokenNumber
;
306 // EBC compiler is very choosy. It may report warning about comparison
307 // between UINTN and 0 . So we add 1 in each size of the
309 ASSERT (TokenNumber
+ 1 < PCD_TOTAL_TOKEN_NUMBER
+ 1);
311 // EBC compiler is very choosy. It may report warning about comparison
312 // between UINTN and 0 . So we add 1 in each size of the
314 IsPeiDb
= (BOOLEAN
) (TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1);
316 TokenNumber
= IsPeiDb
? TokenNumber
:
317 (TokenNumber
- PEI_LOCAL_TOKEN_NUMBER
);
319 LocalTokenNumberTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.LocalTokenNumberTable
320 : mPcdDatabase
->DxeDb
.Init
.LocalTokenNumberTable
;
322 Size
= (LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
326 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
328 return GetPtrTypeSize (TmpTokenNumber
, &MaxSize
);
336 Retrieves an 8-bit value for a given PCD token.
338 Retrieves the 8-bit value of a particular PCD token.
339 If the TokenNumber is invalid or the token space
340 specified by Guid does not exist, the results are
343 @param[in] Guid The token space for the token number.
344 @param[in] ExTokenNumber The PCD token number.
346 @return The size 8-bit value for the PCD token.
352 IN CONST EFI_GUID
*Guid
,
353 IN UINTN ExTokenNumber
356 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT8
)));
360 Retrieves an 16-bit value for a given PCD token.
362 Retrieves the 16-bit value of a particular PCD token.
363 If the TokenNumber is invalid or the token space
364 specified by Guid does not exist, the results are
367 @param[in] Guid The token space for the token number.
368 @param[in] ExTokenNumber The PCD token number.
370 @return The size 16-bit value for the PCD token.
376 IN CONST EFI_GUID
*Guid
,
377 IN UINTN ExTokenNumber
380 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT16
)));
384 Retrieves an 32-bit value for a given PCD token.
386 Retrieves the 32-bit value of a particular PCD token.
387 If the TokenNumber is invalid or the token space
388 specified by Guid does not exist, the results are
391 @param[in] Guid The token space for the token number.
392 @param[in] ExTokenNumber The PCD token number.
394 @return The size 32-bit value for the PCD token.
400 IN CONST EFI_GUID
*Guid
,
401 IN UINTN ExTokenNumber
404 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT32
)));
408 Retrieves an 64-bit value for a given PCD token.
410 Retrieves the 64-bit value of a particular PCD token.
411 If the TokenNumber is invalid or the token space
412 specified by Guid does not exist, the results are
415 @param[in] Guid The token space for the token number.
416 @param[in] ExTokenNumber The PCD token number.
418 @return The size 64-bit value for the PCD token.
424 IN CONST EFI_GUID
*Guid
,
425 IN UINTN ExTokenNumber
428 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT64
)));
432 Retrieves a pointer to a value for a given PCD token.
434 Retrieves the current pointer to the buffer for a PCD token number.
435 Do not make any assumptions about the alignment of the pointer that
436 is returned by this function call. If the TokenNumber is invalid,
437 the results are unpredictable.
439 @param[in] Guid The token space for the token number.
440 @param[in] ExTokenNumber The PCD token number.
442 @return The pointer to the buffer to be retrived.
448 IN CONST EFI_GUID
*Guid
,
449 IN UINTN ExTokenNumber
452 return ExGetWorker (Guid
, ExTokenNumber
, 0);
456 Retrieves an Boolean value for a given PCD token.
458 Retrieves the Boolean value of a particular PCD token.
459 If the TokenNumber is invalid or the token space
460 specified by Guid does not exist, the results are
463 @param[in] Guid The token space for the token number.
464 @param[in] ExTokenNumber The PCD token number.
466 @return The size Boolean value for the PCD token.
472 IN CONST EFI_GUID
*Guid
,
473 IN UINTN ExTokenNumber
476 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(BOOLEAN
)));
480 Retrieves the size of the value for a given PCD token.
482 Retrieves the current size of a particular PCD token.
483 If the TokenNumber is invalid, the results are unpredictable.
485 @param[in] Guid The token space for the token number.
486 @param[in] ExTokenNumber The PCD token number.
488 @return The size of the value for the PCD token.
494 IN CONST EFI_GUID
*Guid
,
495 IN UINTN ExTokenNumber
498 return DxePcdGetSize(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
));
502 Sets an 8-bit value for a given PCD token.
504 When the PCD service sets a value, it will check to ensure that the
505 size of the value being set is compatible with the Token's existing definition.
506 If it is not, an error will be returned.
508 @param[in] TokenNumber The PCD token number.
509 @param[in] Value The value to set for the PCD token.
511 @retval EFI_SUCCESS Procedure returned successfully.
512 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
513 being set was incompatible with a call to this function.
514 Use GetSize() to retrieve the size of the target data.
515 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
521 IN UINTN TokenNumber
,
525 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
529 Sets an 16-bit value for a given PCD token.
531 When the PCD service sets a value, it will check to ensure that the
532 size of the value being set is compatible with the Token's existing definition.
533 If it is not, an error will be returned.
535 @param[in] TokenNumber The PCD token number.
536 @param[in] Value The value to set for the PCD token.
538 @retval EFI_SUCCESS Procedure returned successfully.
539 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
540 being set was incompatible with a call to this function.
541 Use GetSize() to retrieve the size of the target data.
542 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
548 IN UINTN TokenNumber
,
552 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
556 Sets an 32-bit value for a given PCD token.
558 When the PCD service sets a value, it will check to ensure that the
559 size of the value being set is compatible with the Token's existing definition.
560 If it is not, an error will be returned.
562 @param[in] TokenNumber The PCD token number.
563 @param[in] Value The value to set for the PCD token.
565 @retval EFI_SUCCESS Procedure returned successfully.
566 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
567 being set was incompatible with a call to this function.
568 Use GetSize() to retrieve the size of the target data.
569 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
575 IN UINTN TokenNumber
,
579 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
583 Sets an 64-bit value for a given PCD token.
585 When the PCD service sets a value, it will check to ensure that the
586 size of the value being set is compatible with the Token's existing definition.
587 If it is not, an error will be returned.
589 @param[in] TokenNumber The PCD token number.
590 @param[in] Value The value to set for the PCD token.
592 @retval EFI_SUCCESS Procedure returned successfully.
593 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
594 being set was incompatible with a call to this function.
595 Use GetSize() to retrieve the size of the target data.
596 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
602 IN UINTN TokenNumber
,
606 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
610 Sets a value of a specified size for a given PCD token.
612 When the PCD service sets a value, it will check to ensure that the
613 size of the value being set is compatible with the Token's existing definition.
614 If it is not, an error will be returned.
616 @param[in] TokenNumber The PCD token number.
617 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.
618 On input, if the SizeOfValue is greater than the maximum size supported
619 for this TokenNumber then the output value of SizeOfValue will reflect
620 the maximum size supported for this TokenNumber.
621 @param[in] Buffer The buffer to set for the PCD token.
623 @retval EFI_SUCCESS Procedure returned successfully.
624 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
625 being set was incompatible with a call to this function.
626 Use GetSize() to retrieve the size of the target data.
627 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
633 IN UINTN TokenNumber
,
634 IN OUT UINTN
*SizeOfBuffer
,
638 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
642 Sets an Boolean value for a given PCD token.
644 When the PCD service sets a value, it will check to ensure that the
645 size of the value being set is compatible with the Token's existing definition.
646 If it is not, an error will be returned.
648 @param[in] TokenNumber The PCD token number.
649 @param[in] Value The value to set for the PCD token.
651 @retval EFI_SUCCESS Procedure returned successfully.
652 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
653 being set was incompatible with a call to this function.
654 Use GetSize() to retrieve the size of the target data.
655 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
661 IN UINTN TokenNumber
,
665 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
669 Sets an 8-bit value for a given PCD token.
671 When the PCD service sets a value, it will check to ensure that the
672 size of the value being set is compatible with the Token's existing definition.
673 If it is not, an error will be returned.
675 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
676 @param[in] ExTokenNumber The PCD token number.
677 @param[in] Value The value to set for the PCD token.
679 @retval EFI_SUCCESS Procedure returned successfully.
680 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
681 being set was incompatible with a call to this function.
682 Use GetSize() to retrieve the size of the target data.
683 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
689 IN CONST EFI_GUID
*Guid
,
690 IN UINTN ExTokenNumber
,
694 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
698 Sets an 16-bit value for a given PCD token.
700 When the PCD service sets a value, it will check to ensure that the
701 size of the value being set is compatible with the Token's existing definition.
702 If it is not, an error will be returned.
704 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
705 @param[in] ExTokenNumber The PCD token number.
706 @param[in] Value The value to set for the PCD token.
708 @retval EFI_SUCCESS Procedure returned successfully.
709 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
710 being set was incompatible with a call to this function.
711 Use GetSize() to retrieve the size of the target data.
712 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
718 IN CONST EFI_GUID
*Guid
,
719 IN UINTN ExTokenNumber
,
723 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
727 Sets an 32-bit value for a given PCD token.
729 When the PCD service sets a value, it will check to ensure that the
730 size of the value being set is compatible with the Token's existing definition.
731 If it is not, an error will be returned.
733 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
734 @param[in] ExTokenNumber The PCD token number.
735 @param[in] Value The value to set for the PCD token.
737 @retval EFI_SUCCESS Procedure returned successfully.
738 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
739 being set was incompatible with a call to this function.
740 Use GetSize() to retrieve the size of the target data.
741 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
747 IN CONST EFI_GUID
*Guid
,
748 IN UINTN ExTokenNumber
,
752 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
756 Sets an 64-bit value for a given PCD token.
758 When the PCD service sets a value, it will check to ensure that the
759 size of the value being set is compatible with the Token's existing definition.
760 If it is not, an error will be returned.
762 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
763 @param[in] ExTokenNumber The PCD token number.
764 @param[in] Value The value to set for the PCD token.
766 @retval EFI_SUCCESS Procedure returned successfully.
767 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
768 being set was incompatible with a call to this function.
769 Use GetSize() to retrieve the size of the target data.
770 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
776 IN CONST EFI_GUID
*Guid
,
777 IN UINTN ExTokenNumber
,
781 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
785 Sets a value of a specified size for a given PCD token.
787 When the PCD service sets a value, it will check to ensure that the
788 size of the value being set is compatible with the Token's existing definition.
789 If it is not, an error will be returned.
791 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
792 @param[in] ExTokenNumber The PCD token number.
793 @param[in, out] SizeOfBuffer A pointer to the length of the value being set for the PCD token.
794 On input, if the SizeOfValue is greater than the maximum size supported
795 for this TokenNumber then the output value of SizeOfValue will reflect
796 the maximum size supported for this TokenNumber.
797 @param[in] Buffer The buffer to set for the PCD token.
799 @retval EFI_SUCCESS Procedure returned successfully.
800 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
801 being set was incompatible with a call to this function.
802 Use GetSize() to retrieve the size of the target data.
803 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
809 IN CONST EFI_GUID
*Guid
,
810 IN UINTN ExTokenNumber
,
811 IN OUT UINTN
*SizeOfBuffer
,
815 return ExSetWorker(ExTokenNumber
, Guid
, Buffer
, SizeOfBuffer
, TRUE
);
819 Sets an Boolean value for a given PCD token.
821 When the PCD service sets a value, it will check to ensure that the
822 size of the value being set is compatible with the Token's existing definition.
823 If it is not, an error will be returned.
825 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
826 @param[in] ExTokenNumber The PCD token number.
827 @param[in] Value The value to set for the PCD token.
829 @retval EFI_SUCCESS Procedure returned successfully.
830 @retval EFI_INVALID_PARAMETER The PCD service determined that the size of the data
831 being set was incompatible with a call to this function.
832 Use GetSize() to retrieve the size of the target data.
833 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
839 IN CONST EFI_GUID
*Guid
,
840 IN UINTN ExTokenNumber
,
844 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
848 Specifies a function to be called anytime the value of a designated token is changed.
850 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
851 @param[in] TokenNumber The PCD token number.
852 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.
854 @retval EFI_SUCCESS The PCD service has successfully established a call event
855 for the CallBackToken requested.
856 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.
861 DxeRegisterCallBackOnSet (
862 IN CONST EFI_GUID
*Guid
, OPTIONAL
863 IN UINTN TokenNumber
,
864 IN PCD_PROTOCOL_CALLBACK CallBackFunction
869 if (CallBackFunction
== NULL
) {
870 return EFI_INVALID_PARAMETER
;
873 // Aquire lock to prevent reentrance from TPL_CALLBACK level
875 EfiAcquireLock (&mPcdDatabaseLock
);
877 Status
= DxeRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
879 EfiReleaseLock (&mPcdDatabaseLock
);
885 Cancels a previously set callback function for a particular PCD token number.
887 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
888 @param[in] TokenNumber The PCD token number.
889 @param[in] CallBackFunction The function prototype called when the value associated with the CallBackToken is set.
891 @retval EFI_SUCCESS The PCD service has successfully established a call event
892 for the CallBackToken requested.
893 @retval EFI_NOT_FOUND The PCD service could not find the referenced token number.
898 DxeUnRegisterCallBackOnSet (
899 IN CONST EFI_GUID
*Guid
, OPTIONAL
900 IN UINTN TokenNumber
,
901 IN PCD_PROTOCOL_CALLBACK CallBackFunction
906 if (CallBackFunction
== NULL
) {
907 return EFI_INVALID_PARAMETER
;
911 // Aquire lock to prevent reentrance from TPL_CALLBACK level
913 EfiAcquireLock (&mPcdDatabaseLock
);
915 Status
= DxeUnRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
917 EfiReleaseLock (&mPcdDatabaseLock
);
923 Retrieves the next valid PCD token for a given namespace.
925 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
926 @param[in, out] TokenNumber A pointer to the PCD token number to use to find the subsequent token number.
927 If the input token namespace or token number does not exist on the platform,
928 an error is returned and the value of *TokenNumber is undefined. To retrieve the "first" token,
929 have the pointer reference a TokenNumber value of 0. If the input token number is 0 and
930 there is no valid token number for this token namespace, *TokenNumber will be assigned to
931 0 and the function return EFI_SUCCESS. If the token number is the last valid token number,
932 *TokenNumber will be assigned to 0 and the function return EFI_SUCCESS.
934 @retval EFI_SUCCESS The PCD service retrieved the next valid token number. Or the input token number
935 is already the last valid token number in the PCD database.
936 In the later case, *TokenNumber is updated with the value of 0.
937 @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform.
943 IN CONST EFI_GUID
*Guid
, OPTIONAL
944 IN OUT UINTN
*TokenNumber
948 BOOLEAN PeiExMapTableEmpty
;
949 BOOLEAN DxeExMapTableEmpty
;
951 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
952 return EFI_UNSUPPORTED
;
955 Status
= EFI_NOT_FOUND
;
956 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
957 DxeExMapTableEmpty
= DXE_EXMAP_TABLE_EMPTY
;
960 // Scan the local token space
963 // EBC compiler is very choosy. It may report warning about comparison
964 // between UINTN and 0 . So we add 1 in each size of the
966 if (((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) && (*TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1)) ||
967 ((*TokenNumber
+ 1 > (PEI_LOCAL_TOKEN_NUMBER
+ DXE_NEX_TOKEN_NUMBER
+ 1)))) {
968 return EFI_NOT_FOUND
;
972 if ((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) &&
973 (*TokenNumber
<= PEI_LOCAL_TOKEN_NUMBER
)) {
975 // The first Non-Ex type Token Number for DXE PCD
976 // database is PEI_LOCAL_TOKEN_NUMBER
978 *TokenNumber
= PEI_LOCAL_TOKEN_NUMBER
;
979 } else if (*TokenNumber
+ 1 > DXE_NEX_TOKEN_NUMBER
+ PEI_LOCAL_TOKEN_NUMBER
+ 1) {
980 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
985 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
986 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
987 return EFI_NOT_FOUND
;
990 if (!PeiExMapTableEmpty
) {
991 Status
= ExGetNextTokeNumber (
994 mPcdDatabase
->PeiDb
.Init
.GuidTable
,
995 sizeof(mPcdDatabase
->PeiDb
.Init
.GuidTable
),
996 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
997 sizeof(mPcdDatabase
->PeiDb
.Init
.ExMapTable
)
1001 if (Status
== EFI_SUCCESS
) {
1005 if (!DxeExMapTableEmpty
) {
1006 Status
= ExGetNextTokeNumber (
1009 mPcdDatabase
->DxeDb
.Init
.GuidTable
,
1010 sizeof(mPcdDatabase
->DxeDb
.Init
.GuidTable
),
1011 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
1012 sizeof(mPcdDatabase
->DxeDb
.Init
.ExMapTable
)
1020 Get all token space guid table which is different with given token space guid.
1022 @param ExMapTableSize The size of guid table
1023 @param ExMapTable Token space guid table that want to be scaned.
1024 @param GuidTable Guid table
1026 @return all token space guid table which is different with given token space guid.
1030 GetDistinctTokenSpace (
1031 IN OUT UINTN
*ExMapTableSize
,
1032 IN DYNAMICEX_MAPPING
*ExMapTable
,
1033 IN EFI_GUID
*GuidTable
1036 EFI_GUID
**DistinctTokenSpace
;
1042 DistinctTokenSpace
= AllocateZeroPool (*ExMapTableSize
* sizeof (EFI_GUID
*));
1043 ASSERT (DistinctTokenSpace
!= NULL
);
1046 OldGuidIndex
= ExMapTable
[0].ExGuidIndex
;
1047 DistinctTokenSpace
[TsIdx
] = &GuidTable
[OldGuidIndex
];
1048 for (Idx
= 1; Idx
< *ExMapTableSize
; Idx
++) {
1049 if (ExMapTable
[Idx
].ExGuidIndex
!= OldGuidIndex
) {
1050 OldGuidIndex
= ExMapTable
[Idx
].ExGuidIndex
;
1051 DistinctTokenSpace
[++TsIdx
] = &GuidTable
[OldGuidIndex
];
1056 // The total number of Distinct Token Space
1057 // is TsIdx + 1 because we use TsIdx as a index
1058 // to the DistinctTokenSpace[]
1060 *ExMapTableSize
= TsIdx
+ 1;
1061 return DistinctTokenSpace
;
1066 Get next token space in PCD database according to given token space guid.
1068 This routine is enable only when feature flag PCD PcdDxePcdDatabaseTraverseEnabled
1071 @param Guid Given token space guid. If NULL, then Guid will be set to
1072 the first PCD token space in PCD database, If not NULL, then
1073 Guid will be set to next PCD token space.
1075 @retval EFI_UNSUPPORTED If feature flag PCD PcdDxePcdDatabaseTraverseEnabled is FALSE.
1076 @retval EFI_NOT_FOUND If PCD database has no token space table or can not find given
1077 token space in PCD database.
1078 @retval EFI_SUCCESS Success to get next token space guid.
1082 DxePcdGetNextTokenSpace (
1083 IN OUT CONST EFI_GUID
**Guid
1089 UINTN PeiTokenSpaceTableSize
;
1090 UINTN DxeTokenSpaceTableSize
;
1091 EFI_GUID
**PeiTokenSpaceTable
;
1092 EFI_GUID
**DxeTokenSpaceTable
;
1094 BOOLEAN PeiExMapTableEmpty
;
1095 BOOLEAN DxeExMapTableEmpty
;
1097 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
1098 return EFI_UNSUPPORTED
;
1101 ASSERT (Guid
!= NULL
);
1103 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
1104 DxeExMapTableEmpty
= DXE_EXMAP_TABLE_EMPTY
;
1106 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
1107 if (*Guid
!= NULL
) {
1108 return EFI_NOT_FOUND
;
1115 if (TmpTokenSpaceBuffer
[0] == NULL
) {
1116 PeiTokenSpaceTableSize
= 0;
1118 if (!PeiExMapTableEmpty
) {
1119 PeiTokenSpaceTableSize
= PEI_EXMAPPING_TABLE_SIZE
;
1120 PeiTokenSpaceTable
= GetDistinctTokenSpace (&PeiTokenSpaceTableSize
,
1121 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
1122 mPcdDatabase
->PeiDb
.Init
.GuidTable
1124 CopyMem (TmpTokenSpaceBuffer
, PeiTokenSpaceTable
, sizeof (EFI_GUID
*) * PeiTokenSpaceTableSize
);
1127 if (!DxeExMapTableEmpty
) {
1128 DxeTokenSpaceTableSize
= DXE_EXMAPPING_TABLE_SIZE
;
1129 DxeTokenSpaceTable
= GetDistinctTokenSpace (&DxeTokenSpaceTableSize
,
1130 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
1131 mPcdDatabase
->DxeDb
.Init
.GuidTable
1135 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
1137 for (Idx2
= 0, Idx3
= PeiTokenSpaceTableSize
; Idx2
< DxeTokenSpaceTableSize
; Idx2
++) {
1139 for (Idx
= 0; Idx
< PeiTokenSpaceTableSize
; Idx
++) {
1140 if (CompareGuid (TmpTokenSpaceBuffer
[Idx
], DxeTokenSpaceTable
[Idx2
])) {
1146 TmpTokenSpaceBuffer
[Idx3
++] = DxeTokenSpaceTable
[Idx2
];
1152 if (*Guid
== NULL
) {
1153 *Guid
= TmpTokenSpaceBuffer
[0];
1157 for (Idx
= 0; Idx
< (PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
); Idx
++) {
1158 if(CompareGuid (*Guid
, TmpTokenSpaceBuffer
[Idx
])) {
1160 *Guid
= TmpTokenSpaceBuffer
[Idx
];
1165 return EFI_NOT_FOUND
;