2 The driver internal functions are implmented here.
3 They build Pei PCD database, and provide access service to PCD database.
5 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
6 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 Get Local Token Number by Token Number.
21 @param[in] Database PCD database.
22 @param[in] TokenNumber The PCD token number.
24 @return Local Token Number.
28 IN PEI_PCD_DATABASE
*Database
,
32 UINT32 LocalTokenNumber
;
35 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
36 // We have to decrement TokenNumber by 1 to make it usable
37 // as the array index.
41 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + TokenNumber
);
43 return LocalTokenNumber
;
47 Get PCD type by Local Token Number.
49 @param[in] LocalTokenNumber The PCD local token number.
55 IN UINT32 LocalTokenNumber
58 switch (LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) {
59 case PCD_DATUM_TYPE_POINTER
:
60 return EFI_PCD_TYPE_PTR
;
61 case PCD_DATUM_TYPE_UINT8
:
62 if ((LocalTokenNumber
& PCD_DATUM_TYPE_UINT8_BOOLEAN
) == PCD_DATUM_TYPE_UINT8_BOOLEAN
) {
63 return EFI_PCD_TYPE_BOOL
;
65 return EFI_PCD_TYPE_8
;
67 case PCD_DATUM_TYPE_UINT16
:
68 return EFI_PCD_TYPE_16
;
69 case PCD_DATUM_TYPE_UINT32
:
70 return EFI_PCD_TYPE_32
;
71 case PCD_DATUM_TYPE_UINT64
:
72 return EFI_PCD_TYPE_64
;
75 return EFI_PCD_TYPE_8
;
82 @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.
83 If FALSE, need to get the full PCD name.
84 @param[in] Database PCD database.
85 @param[in] TokenNumber The PCD token number.
87 @return The TokenSpaceCName or full PCD name.
91 IN BOOLEAN OnlyTokenSpaceName
,
92 IN PEI_PCD_DATABASE
*Database
,
98 PCD_NAME_INDEX
*PcdNameIndex
;
99 CHAR8
*TokenSpaceName
;
104 // Return NULL when PCD name table is absent.
106 if (Database
->PcdNameTableOffset
== 0) {
111 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
112 // We have to decrement TokenNumber by 1 to make it usable
113 // as the array index.
117 StringTable
= (UINT8
*) Database
+ Database
->StringTableOffset
;
120 // Get the PCD name index.
122 PcdNameIndex
= (PCD_NAME_INDEX
*)((UINT8
*) Database
+ Database
->PcdNameTableOffset
) + TokenNumber
;
123 TokenSpaceName
= (CHAR8
*)&StringTable
[PcdNameIndex
->TokenSpaceCNameIndex
];
124 PcdName
= (CHAR8
*)&StringTable
[PcdNameIndex
->PcdCNameIndex
];
126 if (OnlyTokenSpaceName
) {
128 // Only need to get the TokenSpaceCName.
130 Name
= AllocateCopyPool (AsciiStrSize (TokenSpaceName
), TokenSpaceName
);
133 // Need to get the full PCD name.
135 NameSize
= AsciiStrSize (TokenSpaceName
) + AsciiStrSize (PcdName
);
136 Name
= AllocateZeroPool (NameSize
);
137 ASSERT (Name
!= NULL
);
139 // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
141 AsciiStrCatS (Name
, NameSize
, TokenSpaceName
);
142 Name
[AsciiStrSize (TokenSpaceName
) - sizeof (CHAR8
)] = '.';
143 AsciiStrCatS (Name
, NameSize
, PcdName
);
150 Retrieve additional information associated with a PCD token.
152 This includes information such as the type of value the TokenNumber is associated with as well as possible
153 human readable name that is associated with the token.
155 @param[in] Database PCD database.
156 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
157 @param[in] TokenNumber The PCD token number.
158 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
159 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
161 @retval EFI_SUCCESS The PCD information was returned successfully
162 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
166 IN PEI_PCD_DATABASE
*Database
,
167 IN CONST EFI_GUID
*Guid
,
168 IN UINTN TokenNumber
,
169 OUT EFI_PCD_INFO
*PcdInfo
175 DYNAMICEX_MAPPING
*ExMapTable
;
177 UINT32 LocalTokenNumber
;
179 GuidTable
= (EFI_GUID
*)((UINT8
*)Database
+ Database
->GuidTableOffset
);
180 MatchGuid
= ScanGuid (GuidTable
, Database
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
182 if (MatchGuid
== NULL
) {
183 return EFI_NOT_FOUND
;
186 GuidTableIdx
= MatchGuid
- GuidTable
;
188 ExMapTable
= (DYNAMICEX_MAPPING
*)((UINT8
*)Database
+ Database
->ExMapTableOffset
);
191 // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
193 for (Index
= 0; Index
< Database
->ExTokenCount
; Index
++) {
194 if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
195 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
197 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
198 // PcdSize to 0 and PcdName to the null-terminated ASCII string
199 // associated with the token's namespace Guid.
201 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
202 PcdInfo
->PcdSize
= 0;
204 // Here use one representative in the token space to get the TokenSpaceCName.
206 PcdInfo
->PcdName
= GetPcdName (TRUE
, Database
, ExMapTable
[Index
].TokenNumber
);
208 } else if (ExMapTable
[Index
].ExTokenNumber
== TokenNumber
) {
209 PcdInfo
->PcdSize
= PeiPcdGetSize (ExMapTable
[Index
].TokenNumber
);
210 LocalTokenNumber
= GetLocalTokenNumber (Database
, ExMapTable
[Index
].TokenNumber
);
211 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
212 PcdInfo
->PcdName
= GetPcdName (FALSE
, Database
, ExMapTable
[Index
].TokenNumber
);
218 return EFI_NOT_FOUND
;
222 Retrieve additional information associated with a PCD token.
224 This includes information such as the type of value the TokenNumber is associated with as well as possible
225 human readable name that is associated with the token.
227 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
228 @param[in] TokenNumber The PCD token number.
229 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
230 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
232 @retval EFI_SUCCESS The PCD information was returned successfully.
233 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
237 IN CONST EFI_GUID
*Guid
,
238 IN UINTN TokenNumber
,
239 OUT EFI_PCD_INFO
*PcdInfo
242 PEI_PCD_DATABASE
*PeiPcdDb
;
243 BOOLEAN PeiExMapTableEmpty
;
244 UINTN PeiNexTokenNumber
;
245 UINT32 LocalTokenNumber
;
247 ASSERT (PcdInfo
!= NULL
);
249 PeiPcdDb
= GetPcdDatabase ();
250 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
252 if (PeiPcdDb
->ExTokenCount
== 0) {
253 PeiExMapTableEmpty
= TRUE
;
255 PeiExMapTableEmpty
= FALSE
;
259 if (TokenNumber
> PeiNexTokenNumber
) {
260 return EFI_NOT_FOUND
;
261 } else if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
263 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
264 // PcdSize to 0 and PcdName to NULL for default Token Space.
266 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
267 PcdInfo
->PcdSize
= 0;
268 PcdInfo
->PcdName
= NULL
;
270 PcdInfo
->PcdSize
= PeiPcdGetSize (TokenNumber
);
271 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
);
272 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
273 PcdInfo
->PcdName
= GetPcdName (FALSE
, PeiPcdDb
, TokenNumber
);
277 if (PeiExMapTableEmpty
) {
278 return EFI_NOT_FOUND
;
280 return ExGetPcdInfo (
290 The function registers the CallBackOnSet fucntion
291 according to TokenNumber and EFI_GUID space.
293 @param ExTokenNumber The token number.
294 @param Guid The GUID space.
295 @param CallBackFunction The Callback function to be registered.
296 @param Register To register or unregister the callback function.
298 @retval EFI_SUCCESS If the Callback function is registered.
299 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
300 @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free
301 slot left in the CallbackFnTable.
302 @retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found.
305 PeiRegisterCallBackWorker (
306 IN UINTN ExTokenNumber
,
307 IN CONST EFI_GUID
*Guid
, OPTIONAL
308 IN PCD_PPI_CALLBACK CallBackFunction
,
312 EFI_HOB_GUID_TYPE
*GuidHob
;
313 PCD_PPI_CALLBACK
*CallbackTable
;
314 PCD_PPI_CALLBACK Compare
;
315 PCD_PPI_CALLBACK Assign
;
316 UINT32 LocalTokenNumber
;
317 UINT32 LocalTokenCount
;
318 UINTN PeiNexTokenNumber
;
321 PEI_PCD_DATABASE
*PeiPcdDb
;
323 PeiPcdDb
= GetPcdDatabase();
324 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
325 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
328 TokenNumber
= ExTokenNumber
;
330 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
331 // We have to decrement TokenNumber by 1 to make it usable
332 // as the array index.
335 ASSERT (TokenNumber
+ 1 < (PeiNexTokenNumber
+ 1));
337 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
338 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
339 return EFI_NOT_FOUND
;
342 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
343 // We have to decrement TokenNumber by 1 to make it usable
344 // as the array index.
347 // EBC compiler is very choosy. It may report warning about comparison
348 // between UINTN and 0 . So we add 1 in each size of the
350 ASSERT ((TokenNumber
+ 1) < (LocalTokenCount
+ 1));
354 LocalTokenNumber
= *((UINT32
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->LocalTokenNumberTableOffset
) + TokenNumber
);
357 // We don't support SET for HII and VPD type PCD entry in PEI phase.
358 // So we will assert if any register callback for such PCD entry.
360 ASSERT ((LocalTokenNumber
& PCD_TYPE_HII
) == 0);
361 ASSERT ((LocalTokenNumber
& PCD_TYPE_VPD
) == 0);
363 GuidHob
= GetFirstGuidHob (&gEfiCallerIdGuid
);
364 ASSERT (GuidHob
!= NULL
);
366 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
367 CallbackTable
= CallbackTable
+ (TokenNumber
* PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
369 Compare
= Register
? NULL
: CallBackFunction
;
370 Assign
= Register
? CallBackFunction
: NULL
;
373 for (Idx
= 0; Idx
< PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
374 if (CallbackTable
[Idx
] == Compare
) {
375 CallbackTable
[Idx
] = Assign
;
380 return Register
? EFI_OUT_OF_RESOURCES
: EFI_INVALID_PARAMETER
;
386 Find the Pcd database.
388 @param FileHandle Handle of the file the external PCD database binary located.
390 @retval The base address of external PCD database binary.
391 @retval NULL Return NULL if not find.
395 IN EFI_PEI_FILE_HANDLE FileHandle
403 ASSERT (FileHandle
!= NULL
);
405 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_RAW
, FileHandle
, &PcdDb
);
406 ASSERT_EFI_ERROR (Status
);
409 // Check the first bytes (Header Signature Guid) and build version.
411 if (!CompareGuid (PcdDb
, &gPcdDataBaseSignatureGuid
) ||
412 (((PEI_PCD_DATABASE
*) PcdDb
)->BuildVersion
!= PCD_SERVICE_PEIM_VERSION
)) {
420 The function builds the PCD database.
422 @param FileHandle Handle of the file the external PCD database binary located.
424 @return Pointer to PCD database.
428 IN EFI_PEI_FILE_HANDLE FileHandle
431 PEI_PCD_DATABASE
*Database
;
432 PEI_PCD_DATABASE
*PeiPcdDbBinary
;
433 VOID
*CallbackFnTable
;
434 UINTN SizeOfCallbackFnTable
;
437 // Locate the external PCD database binary for one section of current FFS
439 PeiPcdDbBinary
= LocateExPcdBinary (FileHandle
);
441 ASSERT(PeiPcdDbBinary
!= NULL
);
443 Database
= BuildGuidHob (&gPcdDataBaseHobGuid
, PeiPcdDbBinary
->Length
+ PeiPcdDbBinary
->UninitDataBaseSize
);
445 ZeroMem (Database
, PeiPcdDbBinary
->Length
+ PeiPcdDbBinary
->UninitDataBaseSize
);
448 // PeiPcdDbBinary is smaller than Database
450 CopyMem (Database
, PeiPcdDbBinary
, PeiPcdDbBinary
->Length
);
452 SizeOfCallbackFnTable
= Database
->LocalTokenCount
* sizeof (PCD_PPI_CALLBACK
) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
);
454 CallbackFnTable
= BuildGuidHob (&gEfiCallerIdGuid
, SizeOfCallbackFnTable
);
456 ZeroMem (CallbackFnTable
, SizeOfCallbackFnTable
);
462 The function is provided by PCD PEIM and PCD DXE driver to
463 do the work of reading a HII variable from variable service.
465 @param VariableGuid The Variable GUID.
466 @param VariableName The Variable Name.
467 @param VariableData The output data.
468 @param VariableSize The size of the variable.
470 @retval EFI_SUCCESS Operation successful.
471 @retval EFI_NOT_FOUND Variablel not found.
475 IN CONST EFI_GUID
*VariableGuid
,
476 IN UINT16
*VariableName
,
477 OUT VOID
**VariableData
,
478 OUT UINTN
*VariableSize
484 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*VariablePpi
;
486 Status
= PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid
, 0, NULL
, (VOID
**) &VariablePpi
);
487 ASSERT_EFI_ERROR (Status
);
490 Status
= VariablePpi
->GetVariable (
493 (EFI_GUID
*) VariableGuid
,
499 if (Status
== EFI_BUFFER_TOO_SMALL
) {
500 Status
= PeiServicesAllocatePool (Size
, &Buffer
);
501 ASSERT_EFI_ERROR (Status
);
503 Status
= VariablePpi
->GetVariable (
505 (UINT16
*) VariableName
,
506 (EFI_GUID
*) VariableGuid
,
511 ASSERT_EFI_ERROR (Status
);
513 *VariableSize
= Size
;
514 *VariableData
= Buffer
;
519 return EFI_NOT_FOUND
;
523 Invoke the callback function when dynamic PCD entry was set, if this PCD entry
524 has registered callback function.
526 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx
528 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type
530 @param TokenNumber PCD token number generated by build tools.
531 @param Data Value want to be set for this PCD entry
532 @param Size The size of value
536 InvokeCallbackOnSet (
538 CONST EFI_GUID
*Guid
, OPTIONAL
544 EFI_HOB_GUID_TYPE
*GuidHob
;
545 PCD_PPI_CALLBACK
*CallbackTable
;
547 PEI_PCD_DATABASE
*PeiPcdDb
;
548 UINT32 LocalTokenCount
;
551 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
552 // We have to decrement TokenNumber by 1 to make it usable
553 // as the array index.
557 PeiPcdDb
= GetPcdDatabase ();
558 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
561 // EBC compiler is very choosy. It may report warning about comparison
562 // between UINTN and 0 . So we add 1 in each size of the
564 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
567 GuidHob
= GetFirstGuidHob (&gEfiCallerIdGuid
);
568 ASSERT (GuidHob
!= NULL
);
570 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
572 CallbackTable
+= (TokenNumber
* PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
574 for (Idx
= 0; Idx
< PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
575 if (CallbackTable
[Idx
] != NULL
) {
576 CallbackTable
[Idx
] (Guid
,
577 (Guid
== NULL
) ? (TokenNumber
+ 1) : ExTokenNumber
,
586 Wrapper function for setting non-pointer type value for a PCD entry.
588 @param TokenNumber Pcd token number autogenerated by build tools.
589 @param Data Value want to be set for PCD entry
590 @param Size Size of value.
592 @return status of SetWorker.
597 IN UINTN TokenNumber
,
602 return SetWorker (TokenNumber
, Data
, &Size
, FALSE
);
606 Set value for an PCD entry
608 @param TokenNumber Pcd token number autogenerated by build tools.
609 @param Data Value want to be set for PCD entry
610 @param Size Size of value.
611 @param PtrType If TRUE, the type of PCD entry's value is Pointer.
612 If False, the type of PCD entry's value is not Pointer.
614 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
615 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.
616 @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.
617 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
618 range of UINT8, UINT16, UINT32, UINT64
619 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.
623 IN UINTN TokenNumber
,
629 UINT32 LocalTokenNumber
;
630 UINTN PeiNexTokenNumber
;
631 PEI_PCD_DATABASE
*PeiPcdDb
;
632 STRING_HEAD StringTableIdx
;
636 UINT32 LocalTokenCount
;
638 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable
)) {
639 return EFI_UNSUPPORTED
;
643 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
644 // We have to decrement TokenNumber by 1 to make it usable
645 // as the array index.
648 PeiPcdDb
= GetPcdDatabase ();
649 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
651 // EBC compiler is very choosy. It may report warning about comparison
652 // between UINTN and 0 . So we add 1 in each size of the
654 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
658 // Get MaxSize first, then check new size with max buffer size.
660 GetPtrTypeSize (TokenNumber
, &MaxSize
, PeiPcdDb
);
661 if (*Size
> MaxSize
) {
663 return EFI_INVALID_PARAMETER
;
666 if (*Size
!= PeiPcdGetSize (TokenNumber
+ 1)) {
667 return EFI_INVALID_PARAMETER
;
672 // We only invoke the callback function for Dynamic Type PCD Entry.
673 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
674 // type PCD entry in ExSetWorker.
676 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
677 if (TokenNumber
+ 1 < PeiNexTokenNumber
+ 1) {
678 InvokeCallbackOnSet (0, NULL
, TokenNumber
+ 1, Data
, *Size
);
681 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
+ 1);
683 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
684 InternalData
= (VOID
*) ((UINT8
*) PeiPcdDb
+ Offset
);
686 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
689 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
692 return EFI_INVALID_PARAMETER
;
695 case PCD_TYPE_STRING
:
696 if (SetPtrTypeSize (TokenNumber
, Size
, PeiPcdDb
)) {
697 StringTableIdx
= *((STRING_HEAD
*)InternalData
);
698 CopyMem ((UINT8
*)PeiPcdDb
+ PeiPcdDb
->StringTableOffset
+ StringTableIdx
, Data
, *Size
);
701 return EFI_INVALID_PARAMETER
;
707 if (SetPtrTypeSize (TokenNumber
, Size
, PeiPcdDb
)) {
708 CopyMem (InternalData
, Data
, *Size
);
711 return EFI_INVALID_PARAMETER
;
717 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
721 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
725 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
729 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
734 return EFI_NOT_FOUND
;
741 return EFI_NOT_FOUND
;
746 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.
748 @param ExTokenNumber Token number for dynamic-ex PCD.
749 @param Guid Token space guid for dynamic-ex PCD.
750 @param Data Value want to be set.
751 @param SetSize The size of value.
753 @return status of ExSetWorker().
758 IN UINTN ExTokenNumber
,
759 IN CONST EFI_GUID
*Guid
,
764 return ExSetWorker (ExTokenNumber
, Guid
, Data
, &Size
, FALSE
);
768 Set value for a dynamic-ex PCD entry.
770 This routine find the local token number according to dynamic-ex PCD's token
771 space guid and token number firstly, and invoke callback function if this PCD
772 entry registered callback function. Finally, invoken general SetWorker to set
775 @param ExTokenNumber Dynamic-ex PCD token number.
776 @param Guid Token space guid for dynamic-ex PCD.
777 @param Data PCD value want to be set
778 @param SetSize Size of value.
779 @param PtrType If TRUE, this PCD entry is pointer type.
780 If FALSE, this PCD entry is not pointer type.
782 @return status of SetWorker().
787 IN UINTN ExTokenNumber
,
788 IN CONST EFI_GUID
*Guid
,
796 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable
)) {
797 return EFI_UNSUPPORTED
;
800 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
801 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
802 return EFI_NOT_FOUND
;
805 InvokeCallbackOnSet (ExTokenNumber
, Guid
, TokenNumber
, Data
, *Size
);
807 return SetWorker (TokenNumber
, Data
, Size
, PtrType
);
812 Wrapper function for get PCD value for dynamic-ex PCD.
814 @param Guid Token space guid for dynamic-ex PCD.
815 @param ExTokenNumber Token number for dyanmic-ex PCD.
816 @param GetSize The size of dynamic-ex PCD value.
818 @return PCD entry in PCD database.
823 IN CONST EFI_GUID
*Guid
,
824 IN UINTN ExTokenNumber
,
828 return GetWorker (GetExPcdTokenNumber (Guid
, ExTokenNumber
), GetSize
);
832 Get the PCD entry pointer in PCD database.
834 This routine will visit PCD database to find the PCD entry according to given
835 token number. The given token number is autogened by build tools and it will be
836 translated to local token number. Local token number contains PCD's type and
837 offset of PCD entry in PCD database.
839 @param TokenNumber Token's number, it is autogened by build tools
840 @param GetSize The size of token's value
842 @return PCD entry pointer in PCD database
847 IN UINTN TokenNumber
,
854 VARIABLE_HEAD
*VariableHead
;
859 STRING_HEAD StringTableIdx
;
860 PEI_PCD_DATABASE
*PeiPcdDb
;
861 UINT32 LocalTokenNumber
;
862 UINT32 LocalTokenCount
;
863 UINT8
*VaraiableDefaultBuffer
;
866 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
867 // We have to decrement TokenNumber by 1 to make it usable
868 // as the array index.
872 PeiPcdDb
= GetPcdDatabase ();
873 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
875 // EBC compiler is very choosy. It may report warning about comparison
876 // between UINTN and 0 . So we add 1 in each size of the
878 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
880 ASSERT ((GetSize
== PeiPcdGetSize(TokenNumber
+ 1)) || (GetSize
== 0));
882 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
+ 1);
884 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
885 StringTable
= (UINT8
*)PeiPcdDb
+ PeiPcdDb
->StringTableOffset
;
887 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
891 VpdHead
= (VPD_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
892 return (VOID
*) ((UINTN
) PcdGet32 (PcdVpdBaseAddress
) + VpdHead
->Offset
);
895 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
898 VariableHead
= (VARIABLE_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
900 Guid
= (EFI_GUID
*) ((UINT8
*)PeiPcdDb
+ PeiPcdDb
->GuidTableOffset
) + VariableHead
->GuidTableIndex
;
901 Name
= (UINT16
*)&StringTable
[VariableHead
->StringIndex
];
903 if ((LocalTokenNumber
& PCD_TYPE_ALL_SET
) == (PCD_TYPE_HII
|PCD_TYPE_STRING
)) {
905 // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
906 // string array in string table.
908 VaraiableDefaultBuffer
= (UINT8
*) &StringTable
[*(STRING_HEAD
*)((UINT8
*) PeiPcdDb
+ VariableHead
->DefaultValueOffset
)];
910 VaraiableDefaultBuffer
= (UINT8
*) PeiPcdDb
+ VariableHead
->DefaultValueOffset
;
912 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
913 if ((Status
== EFI_SUCCESS
) && (DataSize
>= (VariableHead
->Offset
+ GetSize
))) {
916 // It is a pointer type. So get the MaxSize reserved for
919 GetPtrTypeSize (TokenNumber
, &GetSize
, PeiPcdDb
);
920 if (GetSize
> (DataSize
- VariableHead
->Offset
)) {
922 // Use actual valid size.
924 GetSize
= DataSize
- VariableHead
->Offset
;
928 // If the operation is successful, we copy the data
929 // to the default value buffer in the PCD Database.
931 CopyMem (VaraiableDefaultBuffer
, (UINT8
*) Data
+ VariableHead
->Offset
, GetSize
);
933 return (VOID
*) VaraiableDefaultBuffer
;
937 return (VOID
*) ((UINT8
*)PeiPcdDb
+ Offset
);
939 case PCD_TYPE_STRING
:
940 StringTableIdx
= * (STRING_HEAD
*) ((UINT8
*) PeiPcdDb
+ Offset
);
941 return (VOID
*) (&StringTable
[StringTableIdx
]);
956 Get Token Number according to dynamic-ex PCD's {token space guid:token number}
958 A dynamic-ex type PCD, developer must provide pair of token space guid: token number
959 in DEC file. PCD database maintain a mapping table that translate pair of {token
960 space guid: token number} to Token Number.
962 @param Guid Token space guid for dynamic-ex PCD entry.
963 @param ExTokenNumber Dynamic-ex PCD token number.
965 @return Token Number for dynamic-ex PCD.
969 GetExPcdTokenNumber (
970 IN CONST EFI_GUID
*Guid
,
971 IN UINTN ExTokenNumber
975 DYNAMICEX_MAPPING
*ExMap
;
979 PEI_PCD_DATABASE
*PeiPcdDb
;
981 PeiPcdDb
= GetPcdDatabase();
983 ExMap
= (DYNAMICEX_MAPPING
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->ExMapTableOffset
);
984 GuidTable
= (EFI_GUID
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->GuidTableOffset
);
986 MatchGuid
= ScanGuid (GuidTable
, PeiPcdDb
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
988 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
989 // error in the BUILD system.
991 ASSERT (MatchGuid
!= NULL
);
993 MatchGuidIdx
= MatchGuid
- GuidTable
;
995 for (Index
= 0; Index
< PeiPcdDb
->ExTokenCount
; Index
++) {
996 if ((ExTokenNumber
== ExMap
[Index
].ExTokenNumber
) &&
997 (MatchGuidIdx
== ExMap
[Index
].ExGuidIndex
)) {
998 return ExMap
[Index
].TokenNumber
;
1002 return PCD_INVALID_TOKEN_NUMBER
;
1006 Get PCD database from GUID HOB in PEI phase.
1008 @return Pointer to PCD database.
1016 EFI_HOB_GUID_TYPE
*GuidHob
;
1018 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
1019 ASSERT (GuidHob
!= NULL
);
1021 return (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);
1025 Get index of PCD entry in size table.
1027 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1028 @param Database Pointer to PCD database in PEI phase.
1030 @return index of PCD entry in size table.
1035 IN UINTN LocalTokenNumberTableIdx
,
1036 IN PEI_PCD_DATABASE
*Database
1041 UINTN LocalTokenNumber
;
1045 for (Index
= 0; Index
< LocalTokenNumberTableIdx
; Index
++) {
1046 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + Index
);
1048 if ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
) {
1050 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1053 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1055 // We have only two entry for VPD enabled PCD entry:
1058 // Current size is equal to MAX size.
1063 // We have only two entry for Non-Sku enabled PCD entry:
1073 return SizeTableIdx
;