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 - 2013, 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
) {
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 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
117 // We have to decrement TokenNumber by 1 to make it usable
118 // as the array index.
122 StringTable
= (UINT8
*) Database
+ Database
->StringTableOffset
;
125 // Get the PCD name index.
127 PcdNameIndex
= (PCD_NAME_INDEX
*)((UINT8
*) Database
+ Database
->PcdNameTableOffset
) + TokenNumber
;
128 TokenSpaceName
= (CHAR8
*)&StringTable
[PcdNameIndex
->TokenSpaceCNameIndex
];
129 PcdName
= (CHAR8
*)&StringTable
[PcdNameIndex
->PcdCNameIndex
];
131 if (OnlyTokenSpaceName
) {
133 // Only need to get the TokenSpaceCName.
135 Name
= AllocateCopyPool (AsciiStrSize (TokenSpaceName
), TokenSpaceName
);
138 // Need to get the full PCD name.
140 Name
= AllocateZeroPool (AsciiStrSize (TokenSpaceName
) + AsciiStrSize (PcdName
));
142 // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
144 AsciiStrCat (Name
, TokenSpaceName
);
145 Name
[AsciiStrSize (TokenSpaceName
) - sizeof (CHAR8
)] = '.';
146 AsciiStrCat (Name
, PcdName
);
153 Retrieve additional information associated with a PCD token.
155 This includes information such as the type of value the TokenNumber is associated with as well as possible
156 human readable name that is associated with the token.
158 @param[in] Database PCD database.
159 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
160 @param[in] TokenNumber The PCD token number.
161 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
162 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
164 @retval EFI_SUCCESS The PCD information was returned successfully
165 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
169 IN PEI_PCD_DATABASE
*Database
,
170 IN CONST EFI_GUID
*Guid
,
171 IN UINTN TokenNumber
,
172 OUT EFI_PCD_INFO
*PcdInfo
178 DYNAMICEX_MAPPING
*ExMapTable
;
180 UINT32 LocalTokenNumber
;
182 GuidTable
= (EFI_GUID
*)((UINT8
*)Database
+ Database
->GuidTableOffset
);
183 MatchGuid
= ScanGuid (GuidTable
, Database
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
185 if (MatchGuid
== NULL
) {
186 return EFI_NOT_FOUND
;
189 GuidTableIdx
= MatchGuid
- GuidTable
;
191 ExMapTable
= (DYNAMICEX_MAPPING
*)((UINT8
*)Database
+ Database
->ExMapTableOffset
);
194 // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
196 for (Index
= 0; Index
< Database
->ExTokenCount
; Index
++) {
197 if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
198 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
200 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
201 // PcdSize to 0 and PcdName to the null-terminated ASCII string
202 // associated with the token's namespace Guid.
204 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
205 PcdInfo
->PcdSize
= 0;
207 // Here use one representative in the token space to get the TokenSpaceCName.
209 PcdInfo
->PcdName
= GetPcdName (TRUE
, Database
, ExMapTable
[Index
].TokenNumber
);
211 } else if (ExMapTable
[Index
].ExTokenNumber
== TokenNumber
) {
212 PcdInfo
->PcdSize
= PeiPcdGetSize (ExMapTable
[Index
].TokenNumber
);
213 LocalTokenNumber
= GetLocalTokenNumber (Database
, ExMapTable
[Index
].TokenNumber
);
214 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
215 PcdInfo
->PcdName
= GetPcdName (FALSE
, Database
, ExMapTable
[Index
].TokenNumber
);
221 return EFI_NOT_FOUND
;
225 Retrieve additional information associated with a PCD token.
227 This includes information such as the type of value the TokenNumber is associated with as well as possible
228 human readable name that is associated with the token.
230 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
231 @param[in] TokenNumber The PCD token number.
232 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
233 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
235 @retval EFI_SUCCESS The PCD information was returned successfully.
236 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
240 IN CONST EFI_GUID
*Guid
,
241 IN UINTN TokenNumber
,
242 OUT EFI_PCD_INFO
*PcdInfo
245 PEI_PCD_DATABASE
*PeiPcdDb
;
246 BOOLEAN PeiExMapTableEmpty
;
247 UINTN PeiNexTokenNumber
;
248 UINT32 LocalTokenNumber
;
250 if (!FeaturePcdGet (PcdPcdInfoGeneration
)) {
251 return EFI_UNSUPPORTED
;
254 ASSERT (PcdInfo
!= NULL
);
256 PeiPcdDb
= GetPcdDatabase ();
257 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
259 if (PeiPcdDb
->ExTokenCount
== 0) {
260 PeiExMapTableEmpty
= TRUE
;
262 PeiExMapTableEmpty
= FALSE
;
266 if (TokenNumber
> PeiNexTokenNumber
) {
267 return EFI_NOT_FOUND
;
268 } else if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
270 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
271 // PcdSize to 0 and PcdName to NULL for default Token Space.
273 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
274 PcdInfo
->PcdSize
= 0;
275 PcdInfo
->PcdName
= NULL
;
277 PcdInfo
->PcdSize
= PeiPcdGetSize (TokenNumber
);
278 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
);
279 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
280 PcdInfo
->PcdName
= GetPcdName (FALSE
, PeiPcdDb
, TokenNumber
);
284 if (PeiExMapTableEmpty
) {
285 return EFI_NOT_FOUND
;
287 return ExGetPcdInfo (
297 The function registers the CallBackOnSet fucntion
298 according to TokenNumber and EFI_GUID space.
300 @param ExTokenNumber The token number.
301 @param Guid The GUID space.
302 @param CallBackFunction The Callback function to be registered.
303 @param Register To register or unregister the callback function.
305 @retval EFI_SUCCESS If the Callback function is registered.
306 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
307 @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free
308 slot left in the CallbackFnTable.
309 @retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found.
312 PeiRegisterCallBackWorker (
313 IN UINTN ExTokenNumber
,
314 IN CONST EFI_GUID
*Guid
, OPTIONAL
315 IN PCD_PPI_CALLBACK CallBackFunction
,
319 EFI_HOB_GUID_TYPE
*GuidHob
;
320 PCD_PPI_CALLBACK
*CallbackTable
;
321 PCD_PPI_CALLBACK Compare
;
322 PCD_PPI_CALLBACK Assign
;
323 UINT32 LocalTokenNumber
;
324 UINT32 LocalTokenCount
;
325 UINTN PeiNexTokenNumber
;
328 PEI_PCD_DATABASE
*PeiPcdDb
;
330 PeiPcdDb
= GetPcdDatabase();
331 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
332 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
335 TokenNumber
= ExTokenNumber
;
337 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
338 // We have to decrement TokenNumber by 1 to make it usable
339 // as the array index.
342 ASSERT (TokenNumber
+ 1 < (PeiNexTokenNumber
+ 1));
344 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
345 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
346 return EFI_NOT_FOUND
;
349 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
350 // We have to decrement TokenNumber by 1 to make it usable
351 // as the array index.
354 // EBC compiler is very choosy. It may report warning about comparison
355 // between UINTN and 0 . So we add 1 in each size of the
357 ASSERT ((TokenNumber
+ 1) < (LocalTokenCount
+ 1));
361 LocalTokenNumber
= *((UINT32
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->LocalTokenNumberTableOffset
) + TokenNumber
);
364 // We don't support SET for HII and VPD type PCD entry in PEI phase.
365 // So we will assert if any register callback for such PCD entry.
367 ASSERT ((LocalTokenNumber
& PCD_TYPE_HII
) == 0);
368 ASSERT ((LocalTokenNumber
& PCD_TYPE_VPD
) == 0);
370 GuidHob
= GetFirstGuidHob (&gEfiCallerIdGuid
);
371 ASSERT (GuidHob
!= NULL
);
373 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
374 CallbackTable
= CallbackTable
+ (TokenNumber
* PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
376 Compare
= Register
? NULL
: CallBackFunction
;
377 Assign
= Register
? CallBackFunction
: NULL
;
380 for (Idx
= 0; Idx
< PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
381 if (CallbackTable
[Idx
] == Compare
) {
382 CallbackTable
[Idx
] = Assign
;
387 return Register
? EFI_OUT_OF_RESOURCES
: EFI_INVALID_PARAMETER
;
393 Find the Pcd database.
395 @param FileHandle Handle of the file the external PCD database binary located.
397 @retval The base address of external PCD database binary.
398 @retval NULL Return NULL if not find.
402 IN EFI_PEI_FILE_HANDLE FileHandle
410 ASSERT (FileHandle
!= NULL
);
412 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_RAW
, FileHandle
, &PcdDb
);
413 ASSERT_EFI_ERROR (Status
);
416 // Check the first bytes (Header Signature Guid) and build version.
418 if (!CompareGuid (PcdDb
, &gPcdDataBaseSignatureGuid
) ||
419 (((PEI_PCD_DATABASE
*) PcdDb
)->BuildVersion
!= PCD_SERVICE_PEIM_VERSION
)) {
427 The function builds the PCD database.
429 @param FileHandle Handle of the file the external PCD database binary located.
431 @return Pointer to PCD database.
435 IN EFI_PEI_FILE_HANDLE FileHandle
438 PEI_PCD_DATABASE
*Database
;
439 PEI_PCD_DATABASE
*PeiPcdDbBinary
;
440 VOID
*CallbackFnTable
;
441 UINTN SizeOfCallbackFnTable
;
444 // Locate the external PCD database binary for one section of current FFS
446 PeiPcdDbBinary
= LocateExPcdBinary (FileHandle
);
448 ASSERT(PeiPcdDbBinary
!= NULL
);
450 Database
= BuildGuidHob (&gPcdDataBaseHobGuid
, PeiPcdDbBinary
->Length
+ PeiPcdDbBinary
->UninitDataBaseSize
);
452 ZeroMem (Database
, PeiPcdDbBinary
->Length
+ PeiPcdDbBinary
->UninitDataBaseSize
);
455 // PeiPcdDbBinary is smaller than Database
457 CopyMem (Database
, PeiPcdDbBinary
, PeiPcdDbBinary
->Length
);
459 SizeOfCallbackFnTable
= Database
->LocalTokenCount
* sizeof (PCD_PPI_CALLBACK
) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
);
461 CallbackFnTable
= BuildGuidHob (&gEfiCallerIdGuid
, SizeOfCallbackFnTable
);
463 ZeroMem (CallbackFnTable
, SizeOfCallbackFnTable
);
469 The function is provided by PCD PEIM and PCD DXE driver to
470 do the work of reading a HII variable from variable service.
472 @param VariableGuid The Variable GUID.
473 @param VariableName The Variable Name.
474 @param VariableData The output data.
475 @param VariableSize The size of the variable.
477 @retval EFI_SUCCESS Operation successful.
478 @retval EFI_NOT_FOUND Variablel not found.
482 IN CONST EFI_GUID
*VariableGuid
,
483 IN UINT16
*VariableName
,
484 OUT VOID
**VariableData
,
485 OUT UINTN
*VariableSize
491 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*VariablePpi
;
493 Status
= PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid
, 0, NULL
, (VOID
**) &VariablePpi
);
494 ASSERT_EFI_ERROR (Status
);
497 Status
= VariablePpi
->GetVariable (
500 (EFI_GUID
*) VariableGuid
,
506 if (Status
== EFI_BUFFER_TOO_SMALL
) {
507 Status
= PeiServicesAllocatePool (Size
, &Buffer
);
508 ASSERT_EFI_ERROR (Status
);
510 Status
= VariablePpi
->GetVariable (
512 (UINT16
*) VariableName
,
513 (EFI_GUID
*) VariableGuid
,
518 ASSERT_EFI_ERROR (Status
);
520 *VariableSize
= Size
;
521 *VariableData
= Buffer
;
526 return EFI_NOT_FOUND
;
530 Find the local token number according to system SKU ID.
532 @param LocalTokenNumber PCD token number
533 @param Size The size of PCD entry.
535 @return Token number according to system SKU ID.
539 GetSkuEnabledTokenNumber (
540 UINT32 LocalTokenNumber
,
544 PEI_PCD_DATABASE
*PeiPcdDb
;
551 PeiPcdDb
= GetPcdDatabase ();
553 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0);
555 SkuHead
= (SKU_HEAD
*) ((UINT8
*)PeiPcdDb
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
556 Value
= (UINT8
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuDataStartOffset
));
557 SkuIdTable
= (SKU_ID
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuIdTableOffset
));
560 // Find the current system's SKU ID entry in SKU ID table.
563 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
564 if (PeiPcdDb
->SystemSkuId
== SkuIdTable
[Index
+ 1]) {
571 // Find the default SKU ID entry in SKU ID table.
574 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
575 if (0 == SkuIdTable
[Index
+ 1]) {
580 ASSERT (Index
< SkuIdTable
[0]);
582 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
584 Value
= (UINT8
*) &(((VPD_HEAD
*) Value
)[Index
]);
585 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_VPD
);
588 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
589 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_HII
);
591 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
592 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
593 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_HII
| PCD_TYPE_STRING
);
595 case PCD_TYPE_STRING
:
596 Value
= (UINT8
*) &(((STRING_HEAD
*) Value
)[Index
]);
597 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_STRING
);
600 Value
+= Size
* Index
;
601 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_DATA
);
613 Invoke the callback function when dynamic PCD entry was set, if this PCD entry
614 has registered callback function.
616 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx
618 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type
620 @param TokenNumber PCD token number generated by build tools.
621 @param Data Value want to be set for this PCD entry
622 @param Size The size of value
626 InvokeCallbackOnSet (
628 CONST EFI_GUID
*Guid
, OPTIONAL
634 EFI_HOB_GUID_TYPE
*GuidHob
;
635 PCD_PPI_CALLBACK
*CallbackTable
;
637 PEI_PCD_DATABASE
*PeiPcdDb
;
638 UINT32 LocalTokenCount
;
641 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
642 // We have to decrement TokenNumber by 1 to make it usable
643 // as the array index.
647 PeiPcdDb
= GetPcdDatabase ();
648 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));
657 GuidHob
= GetFirstGuidHob (&gEfiCallerIdGuid
);
658 ASSERT (GuidHob
!= NULL
);
660 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
662 CallbackTable
+= (TokenNumber
* PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
664 for (Idx
= 0; Idx
< PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
665 if (CallbackTable
[Idx
] != NULL
) {
666 CallbackTable
[Idx
] (Guid
,
667 (Guid
== NULL
) ? (TokenNumber
+ 1) : ExTokenNumber
,
676 Wrapper function for setting non-pointer type value for a PCD entry.
678 @param TokenNumber Pcd token number autogenerated by build tools.
679 @param Data Value want to be set for PCD entry
680 @param Size Size of value.
682 @return status of SetWorker.
687 IN UINTN TokenNumber
,
692 return SetWorker (TokenNumber
, Data
, &Size
, FALSE
);
696 Set value for an PCD entry
698 @param TokenNumber Pcd token number autogenerated by build tools.
699 @param Data Value want to be set for PCD entry
700 @param Size Size of value.
701 @param PtrType If TRUE, the type of PCD entry's value is Pointer.
702 If False, the type of PCD entry's value is not Pointer.
704 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
705 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.
706 @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.
707 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
708 range of UINT8, UINT16, UINT32, UINT64
709 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.
713 IN UINTN TokenNumber
,
719 UINT32 LocalTokenNumber
;
720 UINTN PeiNexTokenNumber
;
721 PEI_PCD_DATABASE
*PeiPcdDb
;
722 STRING_HEAD StringTableIdx
;
726 UINT32 LocalTokenCount
;
728 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable
)) {
729 return EFI_UNSUPPORTED
;
733 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
734 // We have to decrement TokenNumber by 1 to make it usable
735 // as the array index.
738 PeiPcdDb
= GetPcdDatabase ();
739 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
741 // EBC compiler is very choosy. It may report warning about comparison
742 // between UINTN and 0 . So we add 1 in each size of the
744 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
748 // Get MaxSize first, then check new size with max buffer size.
750 GetPtrTypeSize (TokenNumber
, &MaxSize
, PeiPcdDb
);
751 if (*Size
> MaxSize
) {
753 return EFI_INVALID_PARAMETER
;
756 if (*Size
!= PeiPcdGetSize (TokenNumber
+ 1)) {
757 return EFI_INVALID_PARAMETER
;
762 // We only invoke the callback function for Dynamic Type PCD Entry.
763 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
764 // type PCD entry in ExSetWorker.
766 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
767 if (TokenNumber
+ 1 < PeiNexTokenNumber
+ 1) {
768 InvokeCallbackOnSet (0, NULL
, TokenNumber
+ 1, Data
, *Size
);
771 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
+ 1);
773 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
774 InternalData
= (VOID
*) ((UINT8
*) PeiPcdDb
+ Offset
);
776 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
779 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
782 return EFI_INVALID_PARAMETER
;
785 case PCD_TYPE_STRING
:
786 if (SetPtrTypeSize (TokenNumber
, Size
, PeiPcdDb
)) {
787 StringTableIdx
= *((STRING_HEAD
*)InternalData
);
788 CopyMem ((UINT8
*)PeiPcdDb
+ PeiPcdDb
->StringTableOffset
+ StringTableIdx
, Data
, *Size
);
791 return EFI_INVALID_PARAMETER
;
797 if (SetPtrTypeSize (TokenNumber
, Size
, PeiPcdDb
)) {
798 CopyMem (InternalData
, Data
, *Size
);
801 return EFI_INVALID_PARAMETER
;
807 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
811 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
815 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
819 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
824 return EFI_NOT_FOUND
;
831 return EFI_NOT_FOUND
;
836 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.
838 @param ExTokenNumber Token number for dynamic-ex PCD.
839 @param Guid Token space guid for dynamic-ex PCD.
840 @param Data Value want to be set.
841 @param SetSize The size of value.
843 @return status of ExSetWorker().
848 IN UINTN ExTokenNumber
,
849 IN CONST EFI_GUID
*Guid
,
854 return ExSetWorker (ExTokenNumber
, Guid
, Data
, &Size
, FALSE
);
858 Set value for a dynamic-ex PCD entry.
860 This routine find the local token number according to dynamic-ex PCD's token
861 space guid and token number firstly, and invoke callback function if this PCD
862 entry registered callback function. Finally, invoken general SetWorker to set
865 @param ExTokenNumber Dynamic-ex PCD token number.
866 @param Guid Token space guid for dynamic-ex PCD.
867 @param Data PCD value want to be set
868 @param SetSize Size of value.
869 @param PtrType If TRUE, this PCD entry is pointer type.
870 If FALSE, this PCD entry is not pointer type.
872 @return status of SetWorker().
877 IN UINTN ExTokenNumber
,
878 IN CONST EFI_GUID
*Guid
,
886 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable
)) {
887 return EFI_UNSUPPORTED
;
890 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
891 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
892 return EFI_NOT_FOUND
;
895 InvokeCallbackOnSet (ExTokenNumber
, Guid
, TokenNumber
, Data
, *Size
);
897 return SetWorker (TokenNumber
, Data
, Size
, PtrType
);
902 Wrapper function for get PCD value for dynamic-ex PCD.
904 @param Guid Token space guid for dynamic-ex PCD.
905 @param ExTokenNumber Token number for dyanmic-ex PCD.
906 @param GetSize The size of dynamic-ex PCD value.
908 @return PCD entry in PCD database.
913 IN CONST EFI_GUID
*Guid
,
914 IN UINTN ExTokenNumber
,
918 return GetWorker (GetExPcdTokenNumber (Guid
, ExTokenNumber
), GetSize
);
922 Get the PCD entry pointer in PCD database.
924 This routine will visit PCD database to find the PCD entry according to given
925 token number. The given token number is autogened by build tools and it will be
926 translated to local token number. Local token number contains PCD's type and
927 offset of PCD entry in PCD database.
929 @param TokenNumber Token's number, it is autogened by build tools
930 @param GetSize The size of token's value
932 @return PCD entry pointer in PCD database
937 IN UINTN TokenNumber
,
944 VARIABLE_HEAD
*VariableHead
;
949 STRING_HEAD StringTableIdx
;
950 PEI_PCD_DATABASE
*PeiPcdDb
;
951 UINT32 LocalTokenNumber
;
952 UINT32 LocalTokenCount
;
955 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
956 // We have to decrement TokenNumber by 1 to make it usable
957 // as the array index.
961 PeiPcdDb
= GetPcdDatabase ();
962 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
964 // EBC compiler is very choosy. It may report warning about comparison
965 // between UINTN and 0 . So we add 1 in each size of the
967 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
969 ASSERT ((GetSize
== PeiPcdGetSize(TokenNumber
+ 1)) || (GetSize
== 0));
971 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
+ 1);
973 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
974 StringTable
= (UINT8
*)PeiPcdDb
+ PeiPcdDb
->StringTableOffset
;
976 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
980 VpdHead
= (VPD_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
981 return (VOID
*) (UINTN
) (PcdGet32 (PcdVpdBaseAddress
) + VpdHead
->Offset
);
984 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
987 VariableHead
= (VARIABLE_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
989 Guid
= (EFI_GUID
*) ((UINT8
*)PeiPcdDb
+ PeiPcdDb
->GuidTableOffset
) + VariableHead
->GuidTableIndex
;
990 Name
= (UINT16
*)&StringTable
[VariableHead
->StringIndex
];
992 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
994 if (Status
== EFI_SUCCESS
) {
995 return (VOID
*) ((UINT8
*) Data
+ VariableHead
->Offset
);
998 // Return the default value specified by Platform Integrator
1000 if ((LocalTokenNumber
& PCD_TYPE_ALL_SET
) == (PCD_TYPE_HII
|PCD_TYPE_STRING
)) {
1001 return (VOID
*)&StringTable
[*(STRING_HEAD
*)((UINT8
*)PeiPcdDb
+ VariableHead
->DefaultValueOffset
)];
1003 return (VOID
*) ((UINT8
*) PeiPcdDb
+ VariableHead
->DefaultValueOffset
);
1009 return (VOID
*) ((UINT8
*)PeiPcdDb
+ Offset
);
1011 case PCD_TYPE_STRING
:
1012 StringTableIdx
= * (STRING_HEAD
*) ((UINT8
*) PeiPcdDb
+ Offset
);
1013 return (VOID
*) (&StringTable
[StringTableIdx
]);
1028 Get Token Number according to dynamic-ex PCD's {token space guid:token number}
1030 A dynamic-ex type PCD, developer must provide pair of token space guid: token number
1031 in DEC file. PCD database maintain a mapping table that translate pair of {token
1032 space guid: token number} to Token Number.
1034 @param Guid Token space guid for dynamic-ex PCD entry.
1035 @param ExTokenNumber Dynamic-ex PCD token number.
1037 @return Token Number for dynamic-ex PCD.
1041 GetExPcdTokenNumber (
1042 IN CONST EFI_GUID
*Guid
,
1043 IN UINTN ExTokenNumber
1047 DYNAMICEX_MAPPING
*ExMap
;
1048 EFI_GUID
*GuidTable
;
1049 EFI_GUID
*MatchGuid
;
1051 PEI_PCD_DATABASE
*PeiPcdDb
;
1053 PeiPcdDb
= GetPcdDatabase();
1055 ExMap
= (DYNAMICEX_MAPPING
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->ExMapTableOffset
);
1056 GuidTable
= (EFI_GUID
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->GuidTableOffset
);
1058 MatchGuid
= ScanGuid (GuidTable
, PeiPcdDb
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
1060 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
1061 // error in the BUILD system.
1063 ASSERT (MatchGuid
!= NULL
);
1065 MatchGuidIdx
= MatchGuid
- GuidTable
;
1067 for (Index
= 0; Index
< PeiPcdDb
->ExTokenCount
; Index
++) {
1068 if ((ExTokenNumber
== ExMap
[Index
].ExTokenNumber
) &&
1069 (MatchGuidIdx
== ExMap
[Index
].ExGuidIndex
)) {
1070 return ExMap
[Index
].TokenNumber
;
1074 return PCD_INVALID_TOKEN_NUMBER
;
1078 Get PCD database from GUID HOB in PEI phase.
1080 @return Pointer to PCD database.
1088 EFI_HOB_GUID_TYPE
*GuidHob
;
1090 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
1091 ASSERT (GuidHob
!= NULL
);
1093 return (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);
1097 Get SKU ID table from PCD database.
1099 @param LocalTokenNumberTableIdx Index of local token number in token number table.
1100 @param Database PCD database.
1102 @return Pointer to SKU ID array table
1107 IN UINTN LocalTokenNumberTableIdx
,
1108 IN PEI_PCD_DATABASE
*Database
1112 UINTN LocalTokenNumber
;
1114 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + LocalTokenNumberTableIdx
);
1116 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) != 0);
1118 SkuHead
= (SKU_HEAD
*) ((UINT8
*)Database
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
1120 return (SKU_ID
*) ((UINT8
*)Database
+ SkuHead
->SkuIdTableOffset
);
1125 Get index of PCD entry in size table.
1127 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1128 @param Database Pointer to PCD database in PEI phase.
1130 @return index of PCD entry in size table.
1135 IN UINTN LocalTokenNumberTableIdx
,
1136 IN PEI_PCD_DATABASE
*Database
1141 UINTN LocalTokenNumber
;
1146 for (Index
= 0; Index
< LocalTokenNumberTableIdx
; Index
++) {
1147 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + Index
);
1149 if ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
) {
1151 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1154 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1156 // We have only two entry for VPD enabled PCD entry:
1159 // Current size is equal to MAX size.
1163 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1165 // We have only two entry for Non-Sku enabled PCD entry:
1172 // We have these entry for SKU enabled PCD entry
1174 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1176 SkuIdTable
= GetSkuIdArray (Index
, Database
);
1177 SizeTableIdx
+= (UINTN
)*SkuIdTable
+ 1;
1184 return SizeTableIdx
;