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 ASSERT (PcdInfo
!= NULL
);
252 PeiPcdDb
= GetPcdDatabase ();
253 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
255 if (PeiPcdDb
->ExTokenCount
== 0) {
256 PeiExMapTableEmpty
= TRUE
;
258 PeiExMapTableEmpty
= FALSE
;
262 if (TokenNumber
> PeiNexTokenNumber
) {
263 return EFI_NOT_FOUND
;
264 } else if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
266 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
267 // PcdSize to 0 and PcdName to NULL for default Token Space.
269 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
270 PcdInfo
->PcdSize
= 0;
271 PcdInfo
->PcdName
= NULL
;
273 PcdInfo
->PcdSize
= PeiPcdGetSize (TokenNumber
);
274 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
);
275 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
276 PcdInfo
->PcdName
= GetPcdName (FALSE
, PeiPcdDb
, TokenNumber
);
280 if (PeiExMapTableEmpty
) {
281 return EFI_NOT_FOUND
;
283 return ExGetPcdInfo (
293 The function registers the CallBackOnSet fucntion
294 according to TokenNumber and EFI_GUID space.
296 @param ExTokenNumber The token number.
297 @param Guid The GUID space.
298 @param CallBackFunction The Callback function to be registered.
299 @param Register To register or unregister the callback function.
301 @retval EFI_SUCCESS If the Callback function is registered.
302 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
303 @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free
304 slot left in the CallbackFnTable.
305 @retval EFI_INVALID_PARAMETER If the callback function want to be de-registered can not be found.
308 PeiRegisterCallBackWorker (
309 IN UINTN ExTokenNumber
,
310 IN CONST EFI_GUID
*Guid
, OPTIONAL
311 IN PCD_PPI_CALLBACK CallBackFunction
,
315 EFI_HOB_GUID_TYPE
*GuidHob
;
316 PCD_PPI_CALLBACK
*CallbackTable
;
317 PCD_PPI_CALLBACK Compare
;
318 PCD_PPI_CALLBACK Assign
;
319 UINT32 LocalTokenNumber
;
320 UINT32 LocalTokenCount
;
321 UINTN PeiNexTokenNumber
;
324 PEI_PCD_DATABASE
*PeiPcdDb
;
326 PeiPcdDb
= GetPcdDatabase();
327 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
328 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
331 TokenNumber
= ExTokenNumber
;
333 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
334 // We have to decrement TokenNumber by 1 to make it usable
335 // as the array index.
338 ASSERT (TokenNumber
+ 1 < (PeiNexTokenNumber
+ 1));
340 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
341 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
342 return EFI_NOT_FOUND
;
345 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
346 // We have to decrement TokenNumber by 1 to make it usable
347 // as the array index.
350 // EBC compiler is very choosy. It may report warning about comparison
351 // between UINTN and 0 . So we add 1 in each size of the
353 ASSERT ((TokenNumber
+ 1) < (LocalTokenCount
+ 1));
357 LocalTokenNumber
= *((UINT32
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->LocalTokenNumberTableOffset
) + TokenNumber
);
360 // We don't support SET for HII and VPD type PCD entry in PEI phase.
361 // So we will assert if any register callback for such PCD entry.
363 ASSERT ((LocalTokenNumber
& PCD_TYPE_HII
) == 0);
364 ASSERT ((LocalTokenNumber
& PCD_TYPE_VPD
) == 0);
366 GuidHob
= GetFirstGuidHob (&gEfiCallerIdGuid
);
367 ASSERT (GuidHob
!= NULL
);
369 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
370 CallbackTable
= CallbackTable
+ (TokenNumber
* PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
372 Compare
= Register
? NULL
: CallBackFunction
;
373 Assign
= Register
? CallBackFunction
: NULL
;
376 for (Idx
= 0; Idx
< PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
377 if (CallbackTable
[Idx
] == Compare
) {
378 CallbackTable
[Idx
] = Assign
;
383 return Register
? EFI_OUT_OF_RESOURCES
: EFI_INVALID_PARAMETER
;
389 Find the Pcd database.
391 @param FileHandle Handle of the file the external PCD database binary located.
393 @retval The base address of external PCD database binary.
394 @retval NULL Return NULL if not find.
398 IN EFI_PEI_FILE_HANDLE FileHandle
406 ASSERT (FileHandle
!= NULL
);
408 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_RAW
, FileHandle
, &PcdDb
);
409 ASSERT_EFI_ERROR (Status
);
412 // Check the first bytes (Header Signature Guid) and build version.
414 if (!CompareGuid (PcdDb
, &gPcdDataBaseSignatureGuid
) ||
415 (((PEI_PCD_DATABASE
*) PcdDb
)->BuildVersion
!= PCD_SERVICE_PEIM_VERSION
)) {
423 The function builds the PCD database.
425 @param FileHandle Handle of the file the external PCD database binary located.
427 @return Pointer to PCD database.
431 IN EFI_PEI_FILE_HANDLE FileHandle
434 PEI_PCD_DATABASE
*Database
;
435 PEI_PCD_DATABASE
*PeiPcdDbBinary
;
436 VOID
*CallbackFnTable
;
437 UINTN SizeOfCallbackFnTable
;
440 // Locate the external PCD database binary for one section of current FFS
442 PeiPcdDbBinary
= LocateExPcdBinary (FileHandle
);
444 ASSERT(PeiPcdDbBinary
!= NULL
);
446 Database
= BuildGuidHob (&gPcdDataBaseHobGuid
, PeiPcdDbBinary
->Length
+ PeiPcdDbBinary
->UninitDataBaseSize
);
448 ZeroMem (Database
, PeiPcdDbBinary
->Length
+ PeiPcdDbBinary
->UninitDataBaseSize
);
451 // PeiPcdDbBinary is smaller than Database
453 CopyMem (Database
, PeiPcdDbBinary
, PeiPcdDbBinary
->Length
);
455 SizeOfCallbackFnTable
= Database
->LocalTokenCount
* sizeof (PCD_PPI_CALLBACK
) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
);
457 CallbackFnTable
= BuildGuidHob (&gEfiCallerIdGuid
, SizeOfCallbackFnTable
);
459 ZeroMem (CallbackFnTable
, SizeOfCallbackFnTable
);
465 The function is provided by PCD PEIM and PCD DXE driver to
466 do the work of reading a HII variable from variable service.
468 @param VariableGuid The Variable GUID.
469 @param VariableName The Variable Name.
470 @param VariableData The output data.
471 @param VariableSize The size of the variable.
473 @retval EFI_SUCCESS Operation successful.
474 @retval EFI_NOT_FOUND Variablel not found.
478 IN CONST EFI_GUID
*VariableGuid
,
479 IN UINT16
*VariableName
,
480 OUT VOID
**VariableData
,
481 OUT UINTN
*VariableSize
487 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*VariablePpi
;
489 Status
= PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid
, 0, NULL
, (VOID
**) &VariablePpi
);
490 ASSERT_EFI_ERROR (Status
);
493 Status
= VariablePpi
->GetVariable (
496 (EFI_GUID
*) VariableGuid
,
502 if (Status
== EFI_BUFFER_TOO_SMALL
) {
503 Status
= PeiServicesAllocatePool (Size
, &Buffer
);
504 ASSERT_EFI_ERROR (Status
);
506 Status
= VariablePpi
->GetVariable (
508 (UINT16
*) VariableName
,
509 (EFI_GUID
*) VariableGuid
,
514 ASSERT_EFI_ERROR (Status
);
516 *VariableSize
= Size
;
517 *VariableData
= Buffer
;
522 return EFI_NOT_FOUND
;
526 Find the local token number according to system SKU ID.
528 @param LocalTokenNumber PCD token number
529 @param Size The size of PCD entry.
531 @return Token number according to system SKU ID.
535 GetSkuEnabledTokenNumber (
536 UINT32 LocalTokenNumber
,
540 PEI_PCD_DATABASE
*PeiPcdDb
;
547 PeiPcdDb
= GetPcdDatabase ();
549 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0);
551 SkuHead
= (SKU_HEAD
*) ((UINT8
*)PeiPcdDb
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
552 Value
= (UINT8
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuDataStartOffset
));
553 SkuIdTable
= (SKU_ID
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuIdTableOffset
));
556 // Find the current system's SKU ID entry in SKU ID table.
559 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
560 if (PeiPcdDb
->SystemSkuId
== SkuIdTable
[Index
+ 1]) {
567 // Find the default SKU ID entry in SKU ID table.
570 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
571 if (0 == SkuIdTable
[Index
+ 1]) {
576 ASSERT (Index
< SkuIdTable
[0]);
578 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
580 Value
= (UINT8
*) &(((VPD_HEAD
*) Value
)[Index
]);
581 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_VPD
);
584 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
585 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_HII
);
587 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
588 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
589 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_HII
| PCD_TYPE_STRING
);
591 case PCD_TYPE_STRING
:
592 Value
= (UINT8
*) &(((STRING_HEAD
*) Value
)[Index
]);
593 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_STRING
);
596 Value
+= Size
* Index
;
597 return (UINT32
) ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_DATA
);
609 Invoke the callback function when dynamic PCD entry was set, if this PCD entry
610 has registered callback function.
612 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx
614 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type
616 @param TokenNumber PCD token number generated by build tools.
617 @param Data Value want to be set for this PCD entry
618 @param Size The size of value
622 InvokeCallbackOnSet (
624 CONST EFI_GUID
*Guid
, OPTIONAL
630 EFI_HOB_GUID_TYPE
*GuidHob
;
631 PCD_PPI_CALLBACK
*CallbackTable
;
633 PEI_PCD_DATABASE
*PeiPcdDb
;
634 UINT32 LocalTokenCount
;
637 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
638 // We have to decrement TokenNumber by 1 to make it usable
639 // as the array index.
643 PeiPcdDb
= GetPcdDatabase ();
644 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
647 // EBC compiler is very choosy. It may report warning about comparison
648 // between UINTN and 0 . So we add 1 in each size of the
650 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
653 GuidHob
= GetFirstGuidHob (&gEfiCallerIdGuid
);
654 ASSERT (GuidHob
!= NULL
);
656 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
658 CallbackTable
+= (TokenNumber
* PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
660 for (Idx
= 0; Idx
< PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
661 if (CallbackTable
[Idx
] != NULL
) {
662 CallbackTable
[Idx
] (Guid
,
663 (Guid
== NULL
) ? (TokenNumber
+ 1) : ExTokenNumber
,
672 Wrapper function for setting non-pointer type value for a PCD entry.
674 @param TokenNumber Pcd token number autogenerated by build tools.
675 @param Data Value want to be set for PCD entry
676 @param Size Size of value.
678 @return status of SetWorker.
683 IN UINTN TokenNumber
,
688 return SetWorker (TokenNumber
, Data
, &Size
, FALSE
);
692 Set value for an PCD entry
694 @param TokenNumber Pcd token number autogenerated by build tools.
695 @param Data Value want to be set for PCD entry
696 @param Size Size of value.
697 @param PtrType If TRUE, the type of PCD entry's value is Pointer.
698 If False, the type of PCD entry's value is not Pointer.
700 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
701 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.
702 @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.
703 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
704 range of UINT8, UINT16, UINT32, UINT64
705 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.
709 IN UINTN TokenNumber
,
715 UINT32 LocalTokenNumber
;
716 UINTN PeiNexTokenNumber
;
717 PEI_PCD_DATABASE
*PeiPcdDb
;
718 STRING_HEAD StringTableIdx
;
722 UINT32 LocalTokenCount
;
724 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable
)) {
725 return EFI_UNSUPPORTED
;
729 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
730 // We have to decrement TokenNumber by 1 to make it usable
731 // as the array index.
734 PeiPcdDb
= GetPcdDatabase ();
735 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
737 // EBC compiler is very choosy. It may report warning about comparison
738 // between UINTN and 0 . So we add 1 in each size of the
740 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
744 // Get MaxSize first, then check new size with max buffer size.
746 GetPtrTypeSize (TokenNumber
, &MaxSize
, PeiPcdDb
);
747 if (*Size
> MaxSize
) {
749 return EFI_INVALID_PARAMETER
;
752 if (*Size
!= PeiPcdGetSize (TokenNumber
+ 1)) {
753 return EFI_INVALID_PARAMETER
;
758 // We only invoke the callback function for Dynamic Type PCD Entry.
759 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
760 // type PCD entry in ExSetWorker.
762 PeiNexTokenNumber
= PeiPcdDb
->LocalTokenCount
- PeiPcdDb
->ExTokenCount
;
763 if (TokenNumber
+ 1 < PeiNexTokenNumber
+ 1) {
764 InvokeCallbackOnSet (0, NULL
, TokenNumber
+ 1, Data
, *Size
);
767 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
+ 1);
769 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
770 InternalData
= (VOID
*) ((UINT8
*) PeiPcdDb
+ Offset
);
772 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
775 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
778 return EFI_INVALID_PARAMETER
;
781 case PCD_TYPE_STRING
:
782 if (SetPtrTypeSize (TokenNumber
, Size
, PeiPcdDb
)) {
783 StringTableIdx
= *((STRING_HEAD
*)InternalData
);
784 CopyMem ((UINT8
*)PeiPcdDb
+ PeiPcdDb
->StringTableOffset
+ StringTableIdx
, Data
, *Size
);
787 return EFI_INVALID_PARAMETER
;
793 if (SetPtrTypeSize (TokenNumber
, Size
, PeiPcdDb
)) {
794 CopyMem (InternalData
, Data
, *Size
);
797 return EFI_INVALID_PARAMETER
;
803 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
807 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
811 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
815 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
820 return EFI_NOT_FOUND
;
827 return EFI_NOT_FOUND
;
832 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.
834 @param ExTokenNumber Token number for dynamic-ex PCD.
835 @param Guid Token space guid for dynamic-ex PCD.
836 @param Data Value want to be set.
837 @param SetSize The size of value.
839 @return status of ExSetWorker().
844 IN UINTN ExTokenNumber
,
845 IN CONST EFI_GUID
*Guid
,
850 return ExSetWorker (ExTokenNumber
, Guid
, Data
, &Size
, FALSE
);
854 Set value for a dynamic-ex PCD entry.
856 This routine find the local token number according to dynamic-ex PCD's token
857 space guid and token number firstly, and invoke callback function if this PCD
858 entry registered callback function. Finally, invoken general SetWorker to set
861 @param ExTokenNumber Dynamic-ex PCD token number.
862 @param Guid Token space guid for dynamic-ex PCD.
863 @param Data PCD value want to be set
864 @param SetSize Size of value.
865 @param PtrType If TRUE, this PCD entry is pointer type.
866 If FALSE, this PCD entry is not pointer type.
868 @return status of SetWorker().
873 IN UINTN ExTokenNumber
,
874 IN CONST EFI_GUID
*Guid
,
882 if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable
)) {
883 return EFI_UNSUPPORTED
;
886 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
887 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
888 return EFI_NOT_FOUND
;
891 InvokeCallbackOnSet (ExTokenNumber
, Guid
, TokenNumber
, Data
, *Size
);
893 return SetWorker (TokenNumber
, Data
, Size
, PtrType
);
898 Wrapper function for get PCD value for dynamic-ex PCD.
900 @param Guid Token space guid for dynamic-ex PCD.
901 @param ExTokenNumber Token number for dyanmic-ex PCD.
902 @param GetSize The size of dynamic-ex PCD value.
904 @return PCD entry in PCD database.
909 IN CONST EFI_GUID
*Guid
,
910 IN UINTN ExTokenNumber
,
914 return GetWorker (GetExPcdTokenNumber (Guid
, ExTokenNumber
), GetSize
);
918 Get the PCD entry pointer in PCD database.
920 This routine will visit PCD database to find the PCD entry according to given
921 token number. The given token number is autogened by build tools and it will be
922 translated to local token number. Local token number contains PCD's type and
923 offset of PCD entry in PCD database.
925 @param TokenNumber Token's number, it is autogened by build tools
926 @param GetSize The size of token's value
928 @return PCD entry pointer in PCD database
933 IN UINTN TokenNumber
,
940 VARIABLE_HEAD
*VariableHead
;
945 STRING_HEAD StringTableIdx
;
946 PEI_PCD_DATABASE
*PeiPcdDb
;
947 UINT32 LocalTokenNumber
;
948 UINT32 LocalTokenCount
;
951 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
952 // We have to decrement TokenNumber by 1 to make it usable
953 // as the array index.
957 PeiPcdDb
= GetPcdDatabase ();
958 LocalTokenCount
= PeiPcdDb
->LocalTokenCount
;
960 // EBC compiler is very choosy. It may report warning about comparison
961 // between UINTN and 0 . So we add 1 in each size of the
963 ASSERT (TokenNumber
+ 1 < (LocalTokenCount
+ 1));
965 ASSERT ((GetSize
== PeiPcdGetSize(TokenNumber
+ 1)) || (GetSize
== 0));
967 LocalTokenNumber
= GetLocalTokenNumber (PeiPcdDb
, TokenNumber
+ 1);
969 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
970 StringTable
= (UINT8
*)PeiPcdDb
+ PeiPcdDb
->StringTableOffset
;
972 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
976 VpdHead
= (VPD_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
977 return (VOID
*) (UINTN
) (PcdGet32 (PcdVpdBaseAddress
) + VpdHead
->Offset
);
980 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
983 VariableHead
= (VARIABLE_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
985 Guid
= (EFI_GUID
*) ((UINT8
*)PeiPcdDb
+ PeiPcdDb
->GuidTableOffset
) + VariableHead
->GuidTableIndex
;
986 Name
= (UINT16
*)&StringTable
[VariableHead
->StringIndex
];
988 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
990 if (Status
== EFI_SUCCESS
) {
991 return (VOID
*) ((UINT8
*) Data
+ VariableHead
->Offset
);
994 // Return the default value specified by Platform Integrator
996 if ((LocalTokenNumber
& PCD_TYPE_ALL_SET
) == (PCD_TYPE_HII
|PCD_TYPE_STRING
)) {
997 return (VOID
*)&StringTable
[*(STRING_HEAD
*)((UINT8
*)PeiPcdDb
+ VariableHead
->DefaultValueOffset
)];
999 return (VOID
*) ((UINT8
*) PeiPcdDb
+ VariableHead
->DefaultValueOffset
);
1005 return (VOID
*) ((UINT8
*)PeiPcdDb
+ Offset
);
1007 case PCD_TYPE_STRING
:
1008 StringTableIdx
= * (STRING_HEAD
*) ((UINT8
*) PeiPcdDb
+ Offset
);
1009 return (VOID
*) (&StringTable
[StringTableIdx
]);
1024 Get Token Number according to dynamic-ex PCD's {token space guid:token number}
1026 A dynamic-ex type PCD, developer must provide pair of token space guid: token number
1027 in DEC file. PCD database maintain a mapping table that translate pair of {token
1028 space guid: token number} to Token Number.
1030 @param Guid Token space guid for dynamic-ex PCD entry.
1031 @param ExTokenNumber Dynamic-ex PCD token number.
1033 @return Token Number for dynamic-ex PCD.
1037 GetExPcdTokenNumber (
1038 IN CONST EFI_GUID
*Guid
,
1039 IN UINTN ExTokenNumber
1043 DYNAMICEX_MAPPING
*ExMap
;
1044 EFI_GUID
*GuidTable
;
1045 EFI_GUID
*MatchGuid
;
1047 PEI_PCD_DATABASE
*PeiPcdDb
;
1049 PeiPcdDb
= GetPcdDatabase();
1051 ExMap
= (DYNAMICEX_MAPPING
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->ExMapTableOffset
);
1052 GuidTable
= (EFI_GUID
*)((UINT8
*)PeiPcdDb
+ PeiPcdDb
->GuidTableOffset
);
1054 MatchGuid
= ScanGuid (GuidTable
, PeiPcdDb
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
1056 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
1057 // error in the BUILD system.
1059 ASSERT (MatchGuid
!= NULL
);
1061 MatchGuidIdx
= MatchGuid
- GuidTable
;
1063 for (Index
= 0; Index
< PeiPcdDb
->ExTokenCount
; Index
++) {
1064 if ((ExTokenNumber
== ExMap
[Index
].ExTokenNumber
) &&
1065 (MatchGuidIdx
== ExMap
[Index
].ExGuidIndex
)) {
1066 return ExMap
[Index
].TokenNumber
;
1070 return PCD_INVALID_TOKEN_NUMBER
;
1074 Get PCD database from GUID HOB in PEI phase.
1076 @return Pointer to PCD database.
1084 EFI_HOB_GUID_TYPE
*GuidHob
;
1086 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
1087 ASSERT (GuidHob
!= NULL
);
1089 return (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);
1093 Get SKU ID table from PCD database.
1095 @param LocalTokenNumberTableIdx Index of local token number in token number table.
1096 @param Database PCD database.
1098 @return Pointer to SKU ID array table
1103 IN UINTN LocalTokenNumberTableIdx
,
1104 IN PEI_PCD_DATABASE
*Database
1108 UINTN LocalTokenNumber
;
1110 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + LocalTokenNumberTableIdx
);
1112 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) != 0);
1114 SkuHead
= (SKU_HEAD
*) ((UINT8
*)Database
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
1116 return (SKU_ID
*) ((UINT8
*)Database
+ SkuHead
->SkuIdTableOffset
);
1121 Get index of PCD entry in size table.
1123 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1124 @param Database Pointer to PCD database in PEI phase.
1126 @return index of PCD entry in size table.
1131 IN UINTN LocalTokenNumberTableIdx
,
1132 IN PEI_PCD_DATABASE
*Database
1137 UINTN LocalTokenNumber
;
1142 for (Index
= 0; Index
< LocalTokenNumberTableIdx
; Index
++) {
1143 LocalTokenNumber
= *((UINT32
*)((UINT8
*)Database
+ Database
->LocalTokenNumberTableOffset
) + Index
);
1145 if ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
) {
1147 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1150 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1152 // We have only two entry for VPD enabled PCD entry:
1155 // Current size is equal to MAX size.
1159 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1161 // We have only two entry for Non-Sku enabled PCD entry:
1168 // We have these entry for SKU enabled PCD entry
1170 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1172 SkuIdTable
= GetSkuIdArray (Index
, Database
);
1173 SizeTableIdx
+= (UINTN
)*SkuIdTable
+ 1;
1180 return SizeTableIdx
;