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 - 2015, 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
;
37 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
38 // We have to decrement TokenNumber by 1 to make it usable
39 // as the array index.
43 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + TokenNumber
);
45 Size
= (LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
47 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
49 GetPtrTypeSize (TokenNumber
, &MaxSize
, Database
);
53 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, MaxSize
);
56 return LocalTokenNumber
;
60 Get PCD type by Local Token Number.
62 @param[in] LocalTokenNumber The PCD local token number.
68 IN UINT32 LocalTokenNumber
71 switch (LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) {
72 case PCD_DATUM_TYPE_POINTER
:
73 return EFI_PCD_TYPE_PTR
;
74 case PCD_DATUM_TYPE_UINT8
:
75 if ((LocalTokenNumber
& PCD_DATUM_TYPE_UINT8_BOOLEAN
) == PCD_DATUM_TYPE_UINT8_BOOLEAN
) {
76 return EFI_PCD_TYPE_BOOL
;
78 return EFI_PCD_TYPE_8
;
80 case PCD_DATUM_TYPE_UINT16
:
81 return EFI_PCD_TYPE_16
;
82 case PCD_DATUM_TYPE_UINT32
:
83 return EFI_PCD_TYPE_32
;
84 case PCD_DATUM_TYPE_UINT64
:
85 return EFI_PCD_TYPE_64
;
88 return EFI_PCD_TYPE_8
;
95 @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.
96 If FALSE, need to get the full PCD name.
97 @param[in] Database PCD database.
98 @param[in] TokenNumber The PCD token number.
100 @return The TokenSpaceCName or full PCD name.
104 IN BOOLEAN OnlyTokenSpaceName
,
105 IN PEI_PCD_DATABASE
*Database
,
110 PCD_NAME_INDEX
*PcdNameIndex
;
111 CHAR8
*TokenSpaceName
;
116 // Return NULL when PCD name table is absent.
118 if (Database
->PcdNameTableOffset
== 0) {
123 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
124 // We have to decrement TokenNumber by 1 to make it usable
125 // as the array index.
129 StringTable
= (UINT8
*) Database
+ Database
->StringTableOffset
;
132 // Get the PCD name index.
134 PcdNameIndex
= (PCD_NAME_INDEX
*)((UINT8
*) Database
+ Database
->PcdNameTableOffset
) + TokenNumber
;
135 TokenSpaceName
= (CHAR8
*)&StringTable
[PcdNameIndex
->TokenSpaceCNameIndex
];
136 PcdName
= (CHAR8
*)&StringTable
[PcdNameIndex
->PcdCNameIndex
];
138 if (OnlyTokenSpaceName
) {
140 // Only need to get the TokenSpaceCName.
142 Name
= AllocateCopyPool (AsciiStrSize (TokenSpaceName
), TokenSpaceName
);
145 // Need to get the full PCD name.
147 Name
= AllocateZeroPool (AsciiStrSize (TokenSpaceName
) + AsciiStrSize (PcdName
));
148 ASSERT (Name
!= NULL
);
150 // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
152 AsciiStrCat (Name
, TokenSpaceName
);
153 Name
[AsciiStrSize (TokenSpaceName
) - sizeof (CHAR8
)] = '.';
154 AsciiStrCat (Name
, PcdName
);
161 Retrieve additional information associated with a PCD token.
163 This includes information such as the type of value the TokenNumber is associated with as well as possible
164 human readable name that is associated with the token.
166 @param[in] Database PCD database.
167 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
168 @param[in] TokenNumber The PCD token number.
169 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
170 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
172 @retval EFI_SUCCESS The PCD information was returned successfully
173 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
177 IN PEI_PCD_DATABASE
*Database
,
178 IN CONST EFI_GUID
*Guid
,
179 IN UINTN TokenNumber
,
180 OUT EFI_PCD_INFO
*PcdInfo
186 DYNAMICEX_MAPPING
*ExMapTable
;
188 UINT32 LocalTokenNumber
;
190 GuidTable
= (EFI_GUID
*)((UINT8
*)Database
+ Database
->GuidTableOffset
);
191 MatchGuid
= ScanGuid (GuidTable
, Database
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
193 if (MatchGuid
== NULL
) {
194 return EFI_NOT_FOUND
;
197 GuidTableIdx
= MatchGuid
- GuidTable
;
199 ExMapTable
= (DYNAMICEX_MAPPING
*)((UINT8
*)Database
+ Database
->ExMapTableOffset
);
202 // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
204 for (Index
= 0; Index
< Database
->ExTokenCount
; Index
++) {
205 if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
206 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
208 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
209 // PcdSize to 0 and PcdName to the null-terminated ASCII string
210 // associated with the token's namespace Guid.
212 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
213 PcdInfo
->PcdSize
= 0;
215 // Here use one representative in the token space to get the TokenSpaceCName.
217 PcdInfo
->PcdName
= GetPcdName (TRUE
, Database
, ExMapTable
[Index
].TokenNumber
);
219 } else if (ExMapTable
[Index
].ExTokenNumber
== TokenNumber
) {
220 PcdInfo
->PcdSize
= PeiPcdGetSize (ExMapTable
[Index
].TokenNumber
);
221 LocalTokenNumber
= GetLocalTokenNumber (Database
, ExMapTable
[Index
].TokenNumber
);
222 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
223 PcdInfo
->PcdName
= GetPcdName (FALSE
, Database
, ExMapTable
[Index
].TokenNumber
);
229 return EFI_NOT_FOUND
;
233 Retrieve additional information associated with a PCD token.
235 This includes information such as the type of value the TokenNumber is associated with as well as possible
236 human readable name that is associated with the token.
238 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
239 @param[in] TokenNumber The PCD token number.
240 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
241 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
243 @retval EFI_SUCCESS The PCD information was returned successfully.
244 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
248 IN CONST EFI_GUID
*Guid
,
249 IN UINTN TokenNumber
,
250 OUT EFI_PCD_INFO
*PcdInfo
253 PEI_PCD_DATABASE
*PeiPcdDb
;
254 BOOLEAN PeiExMapTableEmpty
;
255 UINTN PeiNexTokenNumber
;
256 UINT32 LocalTokenNumber
;
258 ASSERT (PcdInfo
!= NULL
);
260 PeiPcdDb
= GetPcdDatabase ();
261 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
263 if (PeiPcdDb
->ExTokenCount
== 0) {
264 PeiExMapTableEmpty
= TRUE
;
266 PeiExMapTableEmpty
= FALSE
;
270 if (TokenNumber
> PeiNexTokenNumber
) {
271 return EFI_NOT_FOUND
;
272 } else if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
274 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
275 // PcdSize to 0 and PcdName to NULL for default Token Space.
277 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
278 PcdInfo
->PcdSize
= 0;
279 PcdInfo
->PcdName
= NULL
;
281 PcdInfo
->PcdSize
= PeiPcdGetSize (TokenNumber
);
282 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
);
283 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
284 PcdInfo
->PcdName
= GetPcdName (FALSE
, PeiPcdDb
, TokenNumber
);
288 if (PeiExMapTableEmpty
) {
289 return EFI_NOT_FOUND
;
291 return ExGetPcdInfo (
301 The function registers the CallBackOnSet fucntion
302 according to TokenNumber and EFI_GUID space.
304 @param ExTokenNumber The token number.
305 @param Guid The GUID space.
306 @param CallBackFunction The Callback function to be registered.
307 @param Register To register or unregister the callback function.
309 @retval EFI_SUCCESS If the Callback function is registered.
310 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
311 @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free
312 slot left in the CallbackFnTable.
313 @retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found.
316 PeiRegisterCallBackWorker (
317 IN UINTN ExTokenNumber
,
318 IN CONST EFI_GUID
*Guid
, OPTIONAL
319 IN PCD_PPI_CALLBACK CallBackFunction
,
323 EFI_HOB_GUID_TYPE
*GuidHob
;
324 PCD_PPI_CALLBACK
*CallbackTable
;
325 PCD_PPI_CALLBACK Compare
;
326 PCD_PPI_CALLBACK Assign
;
327 UINT32 LocalTokenNumber
;
328 UINT32 LocalTokenCount
;
329 UINTN PeiNexTokenNumber
;
332 PEI_PCD_DATABASE
*PeiPcdDb
;
334 PeiPcdDb
= GetPcdDatabase();
335 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
336 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
339 TokenNumber
= ExTokenNumber
;
341 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
342 // We have to decrement TokenNumber by 1 to make it usable
343 // as the array index.
346 ASSERT (TokenNumber
+ 1 < (PeiNexTokenNumber
+ 1));
348 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
349 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
350 return EFI_NOT_FOUND
;
353 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
354 // We have to decrement TokenNumber by 1 to make it usable
355 // as the array index.
358 // EBC compiler is very choosy. It may report warning about comparison
359 // between UINTN and 0 . So we add 1 in each size of the
361 ASSERT ((TokenNumber
+ 1) < (LocalTokenCount
+ 1));
365 LocalTokenNumber
= *((UINT32
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->LocalTokenNumberTableOffset
) + TokenNumber
);
368 // We don't support SET for HII and VPD type PCD entry in PEI phase.
369 // So we will assert if any register callback for such PCD entry.
371 ASSERT ((LocalTokenNumber
& PCD_TYPE_HII
) == 0);
372 ASSERT ((LocalTokenNumber
& PCD_TYPE_VPD
) == 0);
374 GuidHob
= GetFirstGuidHob (&gEfiCallerIdGuid
);
375 ASSERT (GuidHob
!= NULL
);
377 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
378 CallbackTable
= CallbackTable
+ (TokenNumber
* PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
380 Compare
= Register
? NULL
: CallBackFunction
;
381 Assign
= Register
? CallBackFunction
: NULL
;
384 for (Idx
= 0; Idx
< PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
385 if (CallbackTable
[Idx
] == Compare
) {
386 CallbackTable
[Idx
] = Assign
;
391 return Register
? EFI_OUT_OF_RESOURCES
: EFI_INVALID_PARAMETER
;
397 Find the Pcd database.
399 @param FileHandle Handle of the file the external PCD database binary located.
401 @retval The base address of external PCD database binary.
402 @retval NULL Return NULL if not find.
406 IN EFI_PEI_FILE_HANDLE FileHandle
414 ASSERT (FileHandle
!= NULL
);
416 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_RAW
, FileHandle
, &PcdDb
);
417 ASSERT_EFI_ERROR (Status
);
420 // Check the first bytes (Header Signature Guid) and build version.
422 if (!CompareGuid (PcdDb
, &gPcdDataBaseSignatureGuid
) ||
423 (((PEI_PCD_DATABASE
*) PcdDb
)->BuildVersion
!= PCD_SERVICE_PEIM_VERSION
)) {
431 The function builds the PCD database.
433 @param FileHandle Handle of the file the external PCD database binary located.
435 @return Pointer to PCD database.
439 IN EFI_PEI_FILE_HANDLE FileHandle
442 PEI_PCD_DATABASE
*Database
;
443 PEI_PCD_DATABASE
*PeiPcdDbBinary
;
444 VOID
*CallbackFnTable
;
445 UINTN SizeOfCallbackFnTable
;
448 // Locate the external PCD database binary for one section of current FFS
450 PeiPcdDbBinary
= LocateExPcdBinary (FileHandle
);
452 ASSERT(PeiPcdDbBinary
!= NULL
);
454 Database
= BuildGuidHob (&gPcdDataBaseHobGuid
, PeiPcdDbBinary
->Length
+ PeiPcdDbBinary
->UninitDataBaseSize
);
456 ZeroMem (Database
, PeiPcdDbBinary
->Length
+ PeiPcdDbBinary
->UninitDataBaseSize
);
459 // PeiPcdDbBinary is smaller than Database
461 CopyMem (Database
, PeiPcdDbBinary
, PeiPcdDbBinary
->Length
);
463 SizeOfCallbackFnTable
= Database
->LocalTokenCount
* sizeof (PCD_PPI_CALLBACK
) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
);
465 CallbackFnTable
= BuildGuidHob (&gEfiCallerIdGuid
, SizeOfCallbackFnTable
);
467 ZeroMem (CallbackFnTable
, SizeOfCallbackFnTable
);
473 The function is provided by PCD PEIM and PCD DXE driver to
474 do the work of reading a HII variable from variable service.
476 @param VariableGuid The Variable GUID.
477 @param VariableName The Variable Name.
478 @param VariableData The output data.
479 @param VariableSize The size of the variable.
481 @retval EFI_SUCCESS Operation successful.
482 @retval EFI_NOT_FOUND Variablel not found.
486 IN CONST EFI_GUID
*VariableGuid
,
487 IN UINT16
*VariableName
,
488 OUT VOID
**VariableData
,
489 OUT UINTN
*VariableSize
495 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*VariablePpi
;
497 Status
= PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid
, 0, NULL
, (VOID
**) &VariablePpi
);
498 ASSERT_EFI_ERROR (Status
);
501 Status
= VariablePpi
->GetVariable (
504 (EFI_GUID
*) VariableGuid
,
510 if (Status
== EFI_BUFFER_TOO_SMALL
) {
511 Status
= PeiServicesAllocatePool (Size
, &Buffer
);
512 ASSERT_EFI_ERROR (Status
);
514 Status
= VariablePpi
->GetVariable (
516 (UINT16
*) VariableName
,
517 (EFI_GUID
*) VariableGuid
,
522 ASSERT_EFI_ERROR (Status
);
524 *VariableSize
= Size
;
525 *VariableData
= Buffer
;
530 return EFI_NOT_FOUND
;
534 Find the local token number according to system SKU ID.
536 @param LocalTokenNumber PCD token number
537 @param Size The size of PCD entry.
539 @return Token number according to system SKU ID.
543 GetSkuEnabledTokenNumber (
544 UINT32 LocalTokenNumber
,
548 PEI_PCD_DATABASE
*PeiPcdDb
;
555 PeiPcdDb
= GetPcdDatabase ();
557 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0);
559 SkuHead
= (SKU_HEAD
*) ((UINT8
*)PeiPcdDb
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
560 Value
= (UINT8
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuDataStartOffset
));
561 SkuIdTable
= (SKU_ID
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuIdTableOffset
));
564 // Find the current system's SKU ID entry in SKU ID table.
567 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
568 if (PeiPcdDb
->SystemSkuId
== SkuIdTable
[Index
+ 1]) {
575 // Find the default SKU ID entry in SKU ID table.
578 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
579 if (0 == SkuIdTable
[Index
+ 1]) {
584 ASSERT (Index
< SkuIdTable
[0]);
586 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
588 Value
= (UINT8
*) &(((VPD_HEAD
*) Value
)[Index
]);
589 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_VPD
);
592 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
593 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_HII
);
595 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
596 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
597 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_HII
| PCD_TYPE_STRING
);
599 case PCD_TYPE_STRING
:
600 Value
= (UINT8
*) &(((STRING_HEAD
*) Value
)[Index
]);
601 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_STRING
);
604 Value
+= Size
* Index
;
605 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_DATA
);
617 Invoke the callback function when dynamic PCD entry was set, if this PCD entry
618 has registered callback function.
620 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx
622 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type
624 @param TokenNumber PCD token number generated by build tools.
625 @param Data Value want to be set for this PCD entry
626 @param Size The size of value
630 InvokeCallbackOnSet (
632 CONST EFI_GUID
*Guid
, OPTIONAL
638 EFI_HOB_GUID_TYPE
*GuidHob
;
639 PCD_PPI_CALLBACK
*CallbackTable
;
641 PEI_PCD_DATABASE
*PeiPcdDb
;
642 UINT32 LocalTokenCount
;
645 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
646 // We have to decrement TokenNumber by 1 to make it usable
647 // as the array index.
651 PeiPcdDb
= GetPcdDatabase ();
652 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
655 // EBC compiler is very choosy. It may report warning about comparison
656 // between UINTN and 0 . So we add 1 in each size of the
658 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
661 GuidHob
= GetFirstGuidHob (&gEfiCallerIdGuid
);
662 ASSERT (GuidHob
!= NULL
);
664 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
666 CallbackTable
+= (TokenNumber
* PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
668 for (Idx
= 0; Idx
< PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
669 if (CallbackTable
[Idx
] != NULL
) {
670 CallbackTable
[Idx
] (Guid
,
671 (Guid
== NULL
) ? (TokenNumber
+ 1) : ExTokenNumber
,
680 Wrapper function for setting non-pointer type value for a PCD entry.
682 @param TokenNumber Pcd token number autogenerated by build tools.
683 @param Data Value want to be set for PCD entry
684 @param Size Size of value.
686 @return status of SetWorker.
691 IN UINTN TokenNumber
,
696 return SetWorker (TokenNumber
, Data
, &Size
, FALSE
);
700 Set value for an PCD entry
702 @param TokenNumber Pcd token number autogenerated by build tools.
703 @param Data Value want to be set for PCD entry
704 @param Size Size of value.
705 @param PtrType If TRUE, the type of PCD entry's value is Pointer.
706 If False, the type of PCD entry's value is not Pointer.
708 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
709 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.
710 @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.
711 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
712 range of UINT8, UINT16, UINT32, UINT64
713 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.
717 IN UINTN TokenNumber
,
723 UINT32 LocalTokenNumber
;
724 UINTN PeiNexTokenNumber
;
725 PEI_PCD_DATABASE
*PeiPcdDb
;
726 STRING_HEAD StringTableIdx
;
730 UINT32 LocalTokenCount
;
732 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable
)) {
733 return EFI_UNSUPPORTED
;
737 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
738 // We have to decrement TokenNumber by 1 to make it usable
739 // as the array index.
742 PeiPcdDb
= GetPcdDatabase ();
743 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
745 // EBC compiler is very choosy. It may report warning about comparison
746 // between UINTN and 0 . So we add 1 in each size of the
748 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
752 // Get MaxSize first, then check new size with max buffer size.
754 GetPtrTypeSize (TokenNumber
, &MaxSize
, PeiPcdDb
);
755 if (*Size
> MaxSize
) {
757 return EFI_INVALID_PARAMETER
;
760 if (*Size
!= PeiPcdGetSize (TokenNumber
+ 1)) {
761 return EFI_INVALID_PARAMETER
;
766 // We only invoke the callback function for Dynamic Type PCD Entry.
767 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
768 // type PCD entry in ExSetWorker.
770 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
771 if (TokenNumber
+ 1 < PeiNexTokenNumber
+ 1) {
772 InvokeCallbackOnSet (0, NULL
, TokenNumber
+ 1, Data
, *Size
);
775 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
+ 1);
777 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
778 InternalData
= (VOID
*) ((UINT8
*) PeiPcdDb
+ Offset
);
780 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
783 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
786 return EFI_INVALID_PARAMETER
;
789 case PCD_TYPE_STRING
:
790 if (SetPtrTypeSize (TokenNumber
, Size
, PeiPcdDb
)) {
791 StringTableIdx
= *((STRING_HEAD
*)InternalData
);
792 CopyMem ((UINT8
*)PeiPcdDb
+ PeiPcdDb
->StringTableOffset
+ StringTableIdx
, Data
, *Size
);
795 return EFI_INVALID_PARAMETER
;
801 if (SetPtrTypeSize (TokenNumber
, Size
, PeiPcdDb
)) {
802 CopyMem (InternalData
, Data
, *Size
);
805 return EFI_INVALID_PARAMETER
;
811 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
815 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
819 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
823 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
828 return EFI_NOT_FOUND
;
835 return EFI_NOT_FOUND
;
840 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.
842 @param ExTokenNumber Token number for dynamic-ex PCD.
843 @param Guid Token space guid for dynamic-ex PCD.
844 @param Data Value want to be set.
845 @param SetSize The size of value.
847 @return status of ExSetWorker().
852 IN UINTN ExTokenNumber
,
853 IN CONST EFI_GUID
*Guid
,
858 return ExSetWorker (ExTokenNumber
, Guid
, Data
, &Size
, FALSE
);
862 Set value for a dynamic-ex PCD entry.
864 This routine find the local token number according to dynamic-ex PCD's token
865 space guid and token number firstly, and invoke callback function if this PCD
866 entry registered callback function. Finally, invoken general SetWorker to set
869 @param ExTokenNumber Dynamic-ex PCD token number.
870 @param Guid Token space guid for dynamic-ex PCD.
871 @param Data PCD value want to be set
872 @param SetSize Size of value.
873 @param PtrType If TRUE, this PCD entry is pointer type.
874 If FALSE, this PCD entry is not pointer type.
876 @return status of SetWorker().
881 IN UINTN ExTokenNumber
,
882 IN CONST EFI_GUID
*Guid
,
890 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable
)) {
891 return EFI_UNSUPPORTED
;
894 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
895 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
896 return EFI_NOT_FOUND
;
899 InvokeCallbackOnSet (ExTokenNumber
, Guid
, TokenNumber
, Data
, *Size
);
901 return SetWorker (TokenNumber
, Data
, Size
, PtrType
);
906 Wrapper function for get PCD value for dynamic-ex PCD.
908 @param Guid Token space guid for dynamic-ex PCD.
909 @param ExTokenNumber Token number for dyanmic-ex PCD.
910 @param GetSize The size of dynamic-ex PCD value.
912 @return PCD entry in PCD database.
917 IN CONST EFI_GUID
*Guid
,
918 IN UINTN ExTokenNumber
,
922 return GetWorker (GetExPcdTokenNumber (Guid
, ExTokenNumber
), GetSize
);
926 Get the PCD entry pointer in PCD database.
928 This routine will visit PCD database to find the PCD entry according to given
929 token number. The given token number is autogened by build tools and it will be
930 translated to local token number. Local token number contains PCD's type and
931 offset of PCD entry in PCD database.
933 @param TokenNumber Token's number, it is autogened by build tools
934 @param GetSize The size of token's value
936 @return PCD entry pointer in PCD database
941 IN UINTN TokenNumber
,
948 VARIABLE_HEAD
*VariableHead
;
953 STRING_HEAD StringTableIdx
;
954 PEI_PCD_DATABASE
*PeiPcdDb
;
955 UINT32 LocalTokenNumber
;
956 UINT32 LocalTokenCount
;
957 UINT8
*VaraiableDefaultBuffer
;
960 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
961 // We have to decrement TokenNumber by 1 to make it usable
962 // as the array index.
966 PeiPcdDb
= GetPcdDatabase ();
967 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
969 // EBC compiler is very choosy. It may report warning about comparison
970 // between UINTN and 0 . So we add 1 in each size of the
972 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
974 ASSERT ((GetSize
== PeiPcdGetSize(TokenNumber
+ 1)) || (GetSize
== 0));
976 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
+ 1);
978 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
979 StringTable
= (UINT8
*)PeiPcdDb
+ PeiPcdDb
->StringTableOffset
;
981 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
985 VpdHead
= (VPD_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
986 return (VOID
*) (UINTN
) (PcdGet32 (PcdVpdBaseAddress
) + VpdHead
->Offset
);
989 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
992 VariableHead
= (VARIABLE_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
994 Guid
= (EFI_GUID
*) ((UINT8
*)PeiPcdDb
+ PeiPcdDb
->GuidTableOffset
) + VariableHead
->GuidTableIndex
;
995 Name
= (UINT16
*)&StringTable
[VariableHead
->StringIndex
];
997 if ((LocalTokenNumber
& PCD_TYPE_ALL_SET
) == (PCD_TYPE_HII
|PCD_TYPE_STRING
)) {
999 // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
1000 // string array in string table.
1002 VaraiableDefaultBuffer
= (UINT8
*) &StringTable
[*(STRING_HEAD
*)((UINT8
*) PeiPcdDb
+ VariableHead
->DefaultValueOffset
)];
1004 VaraiableDefaultBuffer
= (UINT8
*) PeiPcdDb
+ VariableHead
->DefaultValueOffset
;
1006 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
1007 if ((Status
== EFI_SUCCESS
) && (DataSize
>= (VariableHead
->Offset
+ GetSize
))) {
1010 // It is a pointer type. So get the MaxSize reserved for
1013 GetPtrTypeSize (TokenNumber
, &GetSize
, PeiPcdDb
);
1014 if (GetSize
> (DataSize
- VariableHead
->Offset
)) {
1016 // Use actual valid size.
1018 GetSize
= DataSize
- VariableHead
->Offset
;
1022 // If the operation is successful, we copy the data
1023 // to the default value buffer in the PCD Database.
1025 CopyMem (VaraiableDefaultBuffer
, (UINT8
*) Data
+ VariableHead
->Offset
, GetSize
);
1027 return (VOID
*) VaraiableDefaultBuffer
;
1031 return (VOID
*) ((UINT8
*)PeiPcdDb
+ Offset
);
1033 case PCD_TYPE_STRING
:
1034 StringTableIdx
= * (STRING_HEAD
*) ((UINT8
*) PeiPcdDb
+ Offset
);
1035 return (VOID
*) (&StringTable
[StringTableIdx
]);
1050 Get Token Number according to dynamic-ex PCD's {token space guid:token number}
1052 A dynamic-ex type PCD, developer must provide pair of token space guid: token number
1053 in DEC file. PCD database maintain a mapping table that translate pair of {token
1054 space guid: token number} to Token Number.
1056 @param Guid Token space guid for dynamic-ex PCD entry.
1057 @param ExTokenNumber Dynamic-ex PCD token number.
1059 @return Token Number for dynamic-ex PCD.
1063 GetExPcdTokenNumber (
1064 IN CONST EFI_GUID
*Guid
,
1065 IN UINTN ExTokenNumber
1069 DYNAMICEX_MAPPING
*ExMap
;
1070 EFI_GUID
*GuidTable
;
1071 EFI_GUID
*MatchGuid
;
1073 PEI_PCD_DATABASE
*PeiPcdDb
;
1075 PeiPcdDb
= GetPcdDatabase();
1077 ExMap
= (DYNAMICEX_MAPPING
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->ExMapTableOffset
);
1078 GuidTable
= (EFI_GUID
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->GuidTableOffset
);
1080 MatchGuid
= ScanGuid (GuidTable
, PeiPcdDb
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
1082 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
1083 // error in the BUILD system.
1085 ASSERT (MatchGuid
!= NULL
);
1087 MatchGuidIdx
= MatchGuid
- GuidTable
;
1089 for (Index
= 0; Index
< PeiPcdDb
->ExTokenCount
; Index
++) {
1090 if ((ExTokenNumber
== ExMap
[Index
].ExTokenNumber
) &&
1091 (MatchGuidIdx
== ExMap
[Index
].ExGuidIndex
)) {
1092 return ExMap
[Index
].TokenNumber
;
1096 return PCD_INVALID_TOKEN_NUMBER
;
1100 Get PCD database from GUID HOB in PEI phase.
1102 @return Pointer to PCD database.
1110 EFI_HOB_GUID_TYPE
*GuidHob
;
1112 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
1113 ASSERT (GuidHob
!= NULL
);
1115 return (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);
1119 Get SKU ID table from PCD database.
1121 @param LocalTokenNumberTableIdx Index of local token number in token number table.
1122 @param Database PCD database.
1124 @return Pointer to SKU ID array table
1129 IN UINTN LocalTokenNumberTableIdx
,
1130 IN PEI_PCD_DATABASE
*Database
1134 UINTN LocalTokenNumber
;
1136 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + LocalTokenNumberTableIdx
);
1138 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) != 0);
1140 SkuHead
= (SKU_HEAD
*) ((UINT8
*)Database
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
1142 return (SKU_ID
*) ((UINT8
*)Database
+ SkuHead
->SkuIdTableOffset
);
1147 Get index of PCD entry in size table.
1149 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1150 @param Database Pointer to PCD database in PEI phase.
1152 @return index of PCD entry in size table.
1157 IN UINTN LocalTokenNumberTableIdx
,
1158 IN PEI_PCD_DATABASE
*Database
1163 UINTN LocalTokenNumber
;
1168 for (Index
= 0; Index
< LocalTokenNumberTableIdx
; Index
++) {
1169 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + Index
);
1171 if ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
) {
1173 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1176 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1178 // We have only two entry for VPD enabled PCD entry:
1181 // Current size is equal to MAX size.
1185 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1187 // We have only two entry for Non-Sku enabled PCD entry:
1194 // We have these entry for SKU enabled PCD entry
1196 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1198 SkuIdTable
= GetSkuIdArray (Index
, Database
);
1199 SizeTableIdx
+= (UINTN
)*SkuIdTable
+ 1;
1206 return SizeTableIdx
;