2 Help functions used by PCD DXE driver.
4 Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2006 - 2014, 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.
17 #include <Library/DxeServicesLib.h>
19 PCD_DATABASE mPcdDatabase
;
21 UINT32 mPcdTotalTokenCount
;
22 UINT32 mPeiLocalTokenCount
;
23 UINT32 mDxeLocalTokenCount
;
24 UINT32 mPeiNexTokenCount
;
25 UINT32 mDxeNexTokenCount
;
26 UINT32 mPeiExMapppingTableSize
;
27 UINT32 mDxeExMapppingTableSize
;
28 UINT32 mPeiGuidTableSize
;
29 UINT32 mDxeGuidTableSize
;
31 BOOLEAN mPeiExMapTableEmpty
;
32 BOOLEAN mDxeExMapTableEmpty
;
33 BOOLEAN mPeiDatabaseEmpty
;
35 LIST_ENTRY
*mCallbackFnTable
;
36 EFI_GUID
**TmpTokenSpaceBuffer
;
37 UINTN TmpTokenSpaceBufferCount
;
40 Get Local Token Number by Token Number.
42 @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
43 If FALSE, the pcd entry is initialized in DXE phase.
44 @param[in] TokenNumber The PCD token number.
46 @return Local Token Number.
55 UINT32
*LocalTokenNumberTable
;
56 UINT32 LocalTokenNumber
;
61 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
62 // We have to decrement TokenNumber by 1 to make it usable
63 // as the array index.
68 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
70 TmpTokenNumber
= TokenNumber
;
72 LocalTokenNumberTable
= IsPeiDb
? (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
) :
73 (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
74 TokenNumber
= IsPeiDb
? TokenNumber
: TokenNumber
- mPeiLocalTokenCount
;
76 LocalTokenNumber
= LocalTokenNumberTable
[TokenNumber
];
78 Size
= (LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
80 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
82 GetPtrTypeSize (TmpTokenNumber
, &MaxSize
);
86 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, MaxSize
, IsPeiDb
);
89 return LocalTokenNumber
;
93 Get PCD type by Local Token Number.
95 @param[in] LocalTokenNumber The PCD local token number.
101 IN UINT32 LocalTokenNumber
104 switch (LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) {
105 case PCD_DATUM_TYPE_POINTER
:
106 return EFI_PCD_TYPE_PTR
;
107 case PCD_DATUM_TYPE_UINT8
:
108 if ((LocalTokenNumber
& PCD_DATUM_TYPE_UINT8_BOOLEAN
) == PCD_DATUM_TYPE_UINT8_BOOLEAN
) {
109 return EFI_PCD_TYPE_BOOL
;
111 return EFI_PCD_TYPE_8
;
113 case PCD_DATUM_TYPE_UINT16
:
114 return EFI_PCD_TYPE_16
;
115 case PCD_DATUM_TYPE_UINT32
:
116 return EFI_PCD_TYPE_32
;
117 case PCD_DATUM_TYPE_UINT64
:
118 return EFI_PCD_TYPE_64
;
121 return EFI_PCD_TYPE_8
;
128 @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.
129 If FALSE, need to get the full PCD name.
130 @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
131 If FALSE, the pcd entry is initialized in DXE phase.
132 @param[in] TokenNumber The PCD token number.
134 @return The TokenSpaceCName or full PCD name.
138 IN BOOLEAN OnlyTokenSpaceName
,
143 PCD_DATABASE_INIT
*Database
;
145 PCD_NAME_INDEX
*PcdNameIndex
;
146 CHAR8
*TokenSpaceName
;
151 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
152 // We have to decrement TokenNumber by 1 to make it usable
153 // as the array index.
157 Database
= IsPeiDb
? mPcdDatabase
.PeiDb
: mPcdDatabase
.DxeDb
;
158 TokenNumber
= IsPeiDb
? TokenNumber
: TokenNumber
- mPeiLocalTokenCount
;
160 StringTable
= (UINT8
*) Database
+ Database
->StringTableOffset
;
163 // Get the PCD name index.
165 PcdNameIndex
= (PCD_NAME_INDEX
*)((UINT8
*) Database
+ Database
->PcdNameTableOffset
) + TokenNumber
;
166 TokenSpaceName
= (CHAR8
*)&StringTable
[PcdNameIndex
->TokenSpaceCNameIndex
];
167 PcdName
= (CHAR8
*)&StringTable
[PcdNameIndex
->PcdCNameIndex
];
169 if (OnlyTokenSpaceName
) {
171 // Only need to get the TokenSpaceCName.
173 Name
= AllocateCopyPool (AsciiStrSize (TokenSpaceName
), TokenSpaceName
);
176 // Need to get the full PCD name.
178 Name
= AllocateZeroPool (AsciiStrSize (TokenSpaceName
) + AsciiStrSize (PcdName
));
179 ASSERT (Name
!= NULL
);
181 // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
183 AsciiStrCat (Name
, TokenSpaceName
);
184 Name
[AsciiStrSize (TokenSpaceName
) - sizeof (CHAR8
)] = '.';
185 AsciiStrCat (Name
, PcdName
);
192 Retrieve additional information associated with a PCD token.
194 This includes information such as the type of value the TokenNumber is associated with as well as possible
195 human readable name that is associated with the token.
197 @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
198 If FALSE, the pcd entry is initialized in DXE phase.
199 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
200 @param[in] TokenNumber The PCD token number.
201 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
202 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
204 @retval EFI_SUCCESS The PCD information was returned successfully
205 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
210 IN CONST EFI_GUID
*Guid
,
211 IN UINTN TokenNumber
,
212 OUT EFI_PCD_INFO
*PcdInfo
215 PCD_DATABASE_INIT
*Database
;
219 DYNAMICEX_MAPPING
*ExMapTable
;
221 UINT32 LocalTokenNumber
;
223 Database
= IsPeiDb
? mPcdDatabase
.PeiDb
: mPcdDatabase
.DxeDb
;
225 GuidTable
= (EFI_GUID
*)((UINT8
*)Database
+ Database
->GuidTableOffset
);
226 MatchGuid
= ScanGuid (GuidTable
, Database
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
228 if (MatchGuid
== NULL
) {
229 return EFI_NOT_FOUND
;
232 GuidTableIdx
= MatchGuid
- GuidTable
;
234 ExMapTable
= (DYNAMICEX_MAPPING
*)((UINT8
*)Database
+ Database
->ExMapTableOffset
);
237 // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
239 for (Index
= 0; Index
< Database
->ExTokenCount
; Index
++) {
240 if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
241 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
243 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
244 // PcdSize to 0 and PcdName to the null-terminated ASCII string
245 // associated with the token's namespace Guid.
247 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
248 PcdInfo
->PcdSize
= 0;
250 // Here use one representative in the token space to get the TokenSpaceCName.
252 PcdInfo
->PcdName
= GetPcdName (TRUE
, IsPeiDb
, ExMapTable
[Index
].TokenNumber
);
254 } else if (ExMapTable
[Index
].ExTokenNumber
== TokenNumber
) {
255 PcdInfo
->PcdSize
= DxePcdGetSize (ExMapTable
[Index
].TokenNumber
);
256 LocalTokenNumber
= GetLocalTokenNumber (IsPeiDb
, ExMapTable
[Index
].TokenNumber
);
257 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
258 PcdInfo
->PcdName
= GetPcdName (FALSE
, IsPeiDb
, ExMapTable
[Index
].TokenNumber
);
264 return EFI_NOT_FOUND
;
268 Retrieve additional information associated with a PCD token.
270 This includes information such as the type of value the TokenNumber is associated with as well as possible
271 human readable name that is associated with the token.
273 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
274 @param[in] TokenNumber The PCD token number.
275 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
276 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
278 @retval EFI_SUCCESS The PCD information was returned successfully.
279 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
283 IN CONST EFI_GUID
*Guid
,
284 IN UINTN TokenNumber
,
285 OUT EFI_PCD_INFO
*PcdInfo
289 BOOLEAN PeiExMapTableEmpty
;
290 BOOLEAN DxeExMapTableEmpty
;
291 UINT32 LocalTokenNumber
;
294 ASSERT (PcdInfo
!= NULL
);
296 Status
= EFI_NOT_FOUND
;
297 PeiExMapTableEmpty
= mPeiExMapTableEmpty
;
298 DxeExMapTableEmpty
= mDxeExMapTableEmpty
;
301 if (((TokenNumber
+ 1 > mPeiNexTokenCount
+ 1) && (TokenNumber
+ 1 <= mPeiLocalTokenCount
+ 1)) ||
302 ((TokenNumber
+ 1 > (mPeiLocalTokenCount
+ mDxeNexTokenCount
+ 1)))) {
303 return EFI_NOT_FOUND
;
304 } else if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
306 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
307 // PcdSize to 0 and PcdName to NULL for default Token Space.
309 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
310 PcdInfo
->PcdSize
= 0;
311 PcdInfo
->PcdName
= NULL
;
313 PcdInfo
->PcdSize
= DxePcdGetSize (TokenNumber
);
315 if ((TokenNumber
+ 1 <= mPeiNexTokenCount
+ 1)) {
318 LocalTokenNumber
= GetLocalTokenNumber (IsPeiDb
, TokenNumber
);
319 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
320 PcdInfo
->PcdName
= GetPcdName (FALSE
, IsPeiDb
, TokenNumber
);
325 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
326 return EFI_NOT_FOUND
;
329 if (!PeiExMapTableEmpty
) {
330 Status
= ExGetPcdInfo (
338 if (Status
== EFI_SUCCESS
) {
342 if (!DxeExMapTableEmpty
) {
343 Status
= ExGetPcdInfo (
355 Get the PCD entry pointer in PCD database.
357 This routine will visit PCD database to find the PCD entry according to given
358 token number. The given token number is autogened by build tools and it will be
359 translated to local token number. Local token number contains PCD's type and
360 offset of PCD entry in PCD database.
362 @param TokenNumber Token's number, it is autogened by build tools
363 @param GetSize The size of token's value
365 @return PCD entry pointer in PCD database
370 IN UINTN TokenNumber
,
378 VARIABLE_HEAD
*VariableHead
;
379 UINT8
*VaraiableDefaultBuffer
;
384 UINTN TmpTokenNumber
;
387 UINT32 LocalTokenNumber
;
389 STRING_HEAD StringTableIdx
;
393 // Aquire lock to prevent reentrance from TPL_CALLBACK level
395 EfiAcquireLock (&mPcdDatabaseLock
);
399 ASSERT (TokenNumber
> 0);
401 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
402 // We have to decrement TokenNumber by 1 to make it usable
403 // as the array index.
407 TmpTokenNumber
= TokenNumber
;
410 // EBC compiler is very choosy. It may report warning about comparison
411 // between UINTN and 0 . So we add 1 in each size of the
414 ASSERT (TokenNumber
+ 1 < mPcdTotalTokenCount
+ 1);
416 ASSERT ((GetSize
== DxePcdGetSize (TokenNumber
+ 1)) || (GetSize
== 0));
418 // EBC compiler is very choosy. It may report warning about comparison
419 // between UINTN and 0 . So we add 1 in each size of the
421 IsPeiDb
= (BOOLEAN
) ((TokenNumber
+ 1 < mPeiLocalTokenCount
+ 1) ? TRUE
: FALSE
);
423 LocalTokenNumber
= GetLocalTokenNumber (IsPeiDb
, TokenNumber
+ 1);
425 PcdDb
= IsPeiDb
? ((UINT8
*) mPcdDatabase
.PeiDb
) : ((UINT8
*) mPcdDatabase
.DxeDb
);
428 StringTable
= (UINT8
*) ((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->StringTableOffset
);
430 StringTable
= (UINT8
*) ((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->StringTableOffset
);
434 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
436 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
438 VpdHead
= (VPD_HEAD
*) ((UINT8
*) PcdDb
+ Offset
);
439 RetPtr
= (VOID
*) (UINTN
) (PcdGet32 (PcdVpdBaseAddress
) + VpdHead
->Offset
);
443 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
446 GuidTable
= (EFI_GUID
*) ((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
);
448 GuidTable
= (EFI_GUID
*) ((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
);
451 VariableHead
= (VARIABLE_HEAD
*) (PcdDb
+ Offset
);
452 Guid
= GuidTable
+ VariableHead
->GuidTableIndex
;
453 Name
= (UINT16
*)(StringTable
+ VariableHead
->StringIndex
);
455 if ((LocalTokenNumber
& PCD_TYPE_ALL_SET
) == (PCD_TYPE_HII
|PCD_TYPE_STRING
)) {
457 // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
458 // string array in string table.
460 StringTableIdx
= *(STRING_HEAD
*)((UINT8
*) PcdDb
+ VariableHead
->DefaultValueOffset
);
461 VaraiableDefaultBuffer
= (UINT8
*) (StringTable
+ StringTableIdx
);
463 VaraiableDefaultBuffer
= (UINT8
*) PcdDb
+ VariableHead
->DefaultValueOffset
;
465 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
466 if (Status
== EFI_SUCCESS
) {
467 if (DataSize
>= (VariableHead
->Offset
+ GetSize
)) {
470 // It is a pointer type. So get the MaxSize reserved for
473 GetPtrTypeSize (TmpTokenNumber
, &GetSize
);
474 if (GetSize
> (DataSize
- VariableHead
->Offset
)) {
476 // Use actual valid size.
478 GetSize
= DataSize
- VariableHead
->Offset
;
482 // If the operation is successful, we copy the data
483 // to the default value buffer in the PCD Database.
484 // So that we can free the Data allocated in GetHiiVariable.
486 CopyMem (VaraiableDefaultBuffer
, Data
+ VariableHead
->Offset
, GetSize
);
490 RetPtr
= (VOID
*) VaraiableDefaultBuffer
;
493 case PCD_TYPE_STRING
:
494 StringTableIdx
= *(STRING_HEAD
*)((UINT8
*) PcdDb
+ Offset
);
495 RetPtr
= (VOID
*) (StringTable
+ StringTableIdx
);
499 RetPtr
= (VOID
*) ((UINT8
*) PcdDb
+ Offset
);
508 EfiReleaseLock (&mPcdDatabaseLock
);
515 Register the callback function for a PCD entry.
517 This routine will register a callback function to a PCD entry by given token number
518 and token space guid.
520 @param TokenNumber PCD token's number, it is autogened by build tools.
521 @param Guid PCD token space's guid,
522 if not NULL, this PCD is dynamicEx type PCD.
523 @param CallBackFunction Callback function pointer
525 @return EFI_SUCCESS Always success for registering callback function.
529 DxeRegisterCallBackWorker (
530 IN UINTN TokenNumber
,
531 IN CONST EFI_GUID
*Guid
, OPTIONAL
532 IN PCD_PROTOCOL_CALLBACK CallBackFunction
535 CALLBACK_FN_ENTRY
*FnTableEntry
;
536 LIST_ENTRY
*ListHead
;
537 LIST_ENTRY
*ListNode
;
540 TokenNumber
= GetExPcdTokenNumber (Guid
, (UINT32
) TokenNumber
);
544 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
545 // We have to decrement TokenNumber by 1 to make it usable
546 // as the array index of mCallbackFnTable[].
548 ListHead
= &mCallbackFnTable
[TokenNumber
- 1];
549 ListNode
= GetFirstNode (ListHead
);
551 while (ListNode
!= ListHead
) {
552 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE(ListNode
, CALLBACK_FN_ENTRY
, Node
);
554 if (FnTableEntry
->CallbackFn
== CallBackFunction
) {
556 // We only allow a Callback function to be register once
557 // for a TokenNumber. So just return EFI_SUCCESS
561 ListNode
= GetNextNode (ListHead
, ListNode
);
564 FnTableEntry
= AllocatePool (sizeof(CALLBACK_FN_ENTRY
));
565 ASSERT (FnTableEntry
!= NULL
);
567 FnTableEntry
->CallbackFn
= CallBackFunction
;
568 InsertTailList (ListHead
, &FnTableEntry
->Node
);
574 UnRegister the callback function for a PCD entry.
576 This routine will unregister a callback function to a PCD entry by given token number
577 and token space guid.
579 @param TokenNumber PCD token's number, it is autogened by build tools.
580 @param Guid PCD token space's guid.
581 if not NULL, this PCD is dynamicEx type PCD.
582 @param CallBackFunction Callback function pointer
584 @retval EFI_SUCCESS Callback function is success to be unregister.
585 @retval EFI_INVALID_PARAMETER Can not find the PCD entry by given token number.
588 DxeUnRegisterCallBackWorker (
589 IN UINTN TokenNumber
,
590 IN CONST EFI_GUID
*Guid
, OPTIONAL
591 IN PCD_PROTOCOL_CALLBACK CallBackFunction
594 CALLBACK_FN_ENTRY
*FnTableEntry
;
595 LIST_ENTRY
*ListHead
;
596 LIST_ENTRY
*ListNode
;
599 TokenNumber
= GetExPcdTokenNumber (Guid
, (UINT32
) TokenNumber
);
603 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
604 // We have to decrement TokenNumber by 1 to make it usable
605 // as the array index of mCallbackFnTable[].
607 ListHead
= &mCallbackFnTable
[TokenNumber
- 1];
608 ListNode
= GetFirstNode (ListHead
);
610 while (ListNode
!= ListHead
) {
611 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE(ListNode
, CALLBACK_FN_ENTRY
, Node
);
613 if (FnTableEntry
->CallbackFn
== CallBackFunction
) {
615 // We only allow a Callback function to be register once
616 // for a TokenNumber. So we can safely remove the Node from
617 // the Link List and return EFI_SUCCESS.
619 RemoveEntryList (ListNode
);
620 FreePool (FnTableEntry
);
624 ListNode
= GetNextNode (ListHead
, ListNode
);
627 return EFI_INVALID_PARAMETER
;
631 Get next token number in given token space.
633 This routine is used for dynamicEx type PCD. It will firstly scan token space
634 table to get token space according to given token space guid. Then scan given
635 token number in found token space, if found, then return next token number in
638 @param Guid Token space guid. Next token number will be scaned in
640 @param TokenNumber Token number.
641 If PCD_INVALID_TOKEN_NUMBER, return first token number in
643 If not PCD_INVALID_TOKEN_NUMBER, return next token number
644 in token space table.
645 @param GuidTable Token space guid table. It will be used for scan token space
646 by given token space guid.
647 @param SizeOfGuidTable The size of guid table.
648 @param ExMapTable DynamicEx token number mapping table.
649 @param SizeOfExMapTable The size of dynamicEx token number mapping table.
651 @retval EFI_NOT_FOUND Can not given token space or token number.
652 @retval EFI_SUCCESS Success to get next token number.
656 ExGetNextTokeNumber (
657 IN CONST EFI_GUID
*Guid
,
658 IN OUT UINTN
*TokenNumber
,
659 IN EFI_GUID
*GuidTable
,
660 IN UINTN SizeOfGuidTable
,
661 IN DYNAMICEX_MAPPING
*ExMapTable
,
662 IN UINTN SizeOfExMapTable
669 UINTN ExMapTableCount
;
672 // Scan token space guid
674 MatchGuid
= ScanGuid (GuidTable
, SizeOfGuidTable
, Guid
);
675 if (MatchGuid
== NULL
) {
676 return EFI_NOT_FOUND
;
680 // Find the token space table in dynamicEx mapping table.
683 GuidTableIdx
= MatchGuid
- GuidTable
;
684 ExMapTableCount
= SizeOfExMapTable
/ sizeof(ExMapTable
[0]);
685 for (Index
= 0; Index
< ExMapTableCount
; Index
++) {
686 if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
694 // If given token number is PCD_INVALID_TOKEN_NUMBER, then return the first
695 // token number in found token space.
697 if (*TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
698 *TokenNumber
= ExMapTable
[Index
].ExTokenNumber
;
702 for ( ; Index
< ExMapTableCount
; Index
++) {
703 if (ExMapTable
[Index
].ExTokenNumber
== *TokenNumber
) {
708 while (Index
< ExMapTableCount
) {
710 if (Index
== ExMapTableCount
) {
712 // Exceed the length of ExMap Table
714 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
715 return EFI_NOT_FOUND
;
716 } else if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
718 // Found the next match
720 *TokenNumber
= ExMapTable
[Index
].ExTokenNumber
;
726 return EFI_NOT_FOUND
;
730 Find the PCD database.
732 @retval The base address of external PCD database binary.
733 @retval NULL Return NULL if not find.
740 DXE_PCD_DATABASE
*DxePcdDbBinary
;
744 DxePcdDbBinary
= NULL
;
746 // Search the External Pcd database from one section of current FFS,
747 // and read it to memory
749 Status
= GetSectionFromFfs (
752 (VOID
**) &DxePcdDbBinary
,
755 ASSERT_EFI_ERROR (Status
);
758 // Check the first bytes (Header Signature Guid) and build version.
760 if (!CompareGuid ((VOID
*)DxePcdDbBinary
, &gPcdDataBaseSignatureGuid
) ||
761 (DxePcdDbBinary
->BuildVersion
!= PCD_SERVICE_DXE_VERSION
)) {
765 return DxePcdDbBinary
;
769 Initialize the PCD database in DXE phase.
771 PCD database in DXE phase also contains PCD database in PEI phase which is copied
776 BuildPcdDxeDataBase (
780 PEI_PCD_DATABASE
*PeiDatabase
;
781 EFI_HOB_GUID_TYPE
*GuidHob
;
787 // Assign PCD Entries with default value to PCD DATABASE
789 mPcdDatabase
.DxeDb
= LocateExPcdBinary ();
790 ASSERT(mPcdDatabase
.DxeDb
!= NULL
);
791 PcdDxeDbLen
= mPcdDatabase
.DxeDb
->Length
+ mPcdDatabase
.DxeDb
->UninitDataBaseSize
;
792 PcdDxeDb
= AllocateZeroPool (PcdDxeDbLen
);
793 ASSERT (PcdDxeDb
!= NULL
);
794 CopyMem (PcdDxeDb
, mPcdDatabase
.DxeDb
, mPcdDatabase
.DxeDb
->Length
);
795 FreePool (mPcdDatabase
.DxeDb
);
796 mPcdDatabase
.DxeDb
= PcdDxeDb
;
798 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
799 if (GuidHob
!= NULL
) {
802 // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM
803 // should not be included at all. So the GuidHob could
804 // be NULL. If it is NULL, we just copy over the DXE Default
805 // Value to PCD Database.
808 PeiDatabase
= (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);
810 // Assign PCD Entries refereneced in PEI phase to PCD DATABASE
812 mPcdDatabase
.PeiDb
= PeiDatabase
;
814 // Inherit the SystemSkuId from PEI phase.
816 mPcdDatabase
.DxeDb
->SystemSkuId
= mPcdDatabase
.PeiDb
->SystemSkuId
;
818 mPcdDatabase
.PeiDb
= AllocateZeroPool (sizeof (PEI_PCD_DATABASE
));
819 ASSERT(mPcdDatabase
.PeiDb
!= NULL
);
823 // Initialized the external PCD database local variables
825 mPeiLocalTokenCount
= mPcdDatabase
.PeiDb
->LocalTokenCount
;
826 mDxeLocalTokenCount
= mPcdDatabase
.DxeDb
->LocalTokenCount
;
828 mPeiExMapppingTableSize
= mPcdDatabase
.PeiDb
->ExTokenCount
* sizeof (DYNAMICEX_MAPPING
);
829 mDxeExMapppingTableSize
= mPcdDatabase
.DxeDb
->ExTokenCount
* sizeof (DYNAMICEX_MAPPING
);
830 mPeiGuidTableSize
= mPcdDatabase
.PeiDb
->GuidTableCount
* sizeof(GUID
);
831 mDxeGuidTableSize
= mPcdDatabase
.DxeDb
->GuidTableCount
* sizeof (GUID
);
833 mPcdTotalTokenCount
= mPeiLocalTokenCount
+ mDxeLocalTokenCount
;
834 mPeiNexTokenCount
= mPeiLocalTokenCount
- mPcdDatabase
.PeiDb
->ExTokenCount
;
835 mDxeNexTokenCount
= mDxeLocalTokenCount
- mPcdDatabase
.DxeDb
->ExTokenCount
;
837 mPeiExMapTableEmpty
= (mPcdDatabase
.PeiDb
->ExTokenCount
== 0) ? TRUE
: FALSE
;
838 mDxeExMapTableEmpty
= (mPcdDatabase
.DxeDb
->ExTokenCount
== 0) ? TRUE
: FALSE
;
839 mPeiDatabaseEmpty
= (mPeiLocalTokenCount
== 0) ? TRUE
: FALSE
;
841 TmpTokenSpaceBufferCount
= mPcdDatabase
.PeiDb
->ExTokenCount
+ mPcdDatabase
.DxeDb
->ExTokenCount
;
842 TmpTokenSpaceBuffer
= (EFI_GUID
**)AllocateZeroPool(TmpTokenSpaceBufferCount
* sizeof (EFI_GUID
*));
845 // Initialized the Callback Function Table
847 mCallbackFnTable
= AllocateZeroPool (mPcdTotalTokenCount
* sizeof (LIST_ENTRY
));
848 ASSERT(mCallbackFnTable
!= NULL
);
851 // EBC compiler is very choosy. It may report warning about comparison
852 // between UINTN and 0 . So we add 1 in each size of the
855 for (Index
= 0; Index
+ 1 < mPcdTotalTokenCount
+ 1; Index
++) {
856 InitializeListHead (&mCallbackFnTable
[Index
]);
861 Get Variable which contains HII type PCD entry.
863 @param VariableGuid Variable's guid
864 @param VariableName Variable's unicode name string
865 @param VariableData Variable's data pointer,
866 @param VariableSize Variable's size.
868 @return the status of gRT->GetVariable
872 IN EFI_GUID
*VariableGuid
,
873 IN UINT16
*VariableName
,
874 OUT UINT8
**VariableData
,
875 OUT UINTN
*VariableSize
886 // Firstly get the real size of HII variable
888 Status
= gRT
->GetVariable (
889 (UINT16
*)VariableName
,
897 // Allocate buffer to hold whole variable data according to variable size.
899 if (Status
== EFI_BUFFER_TOO_SMALL
) {
900 Buffer
= (UINT8
*) AllocatePool (Size
);
902 ASSERT (Buffer
!= NULL
);
904 Status
= gRT
->GetVariable (
912 ASSERT (Status
== EFI_SUCCESS
);
913 *VariableData
= Buffer
;
914 *VariableSize
= Size
;
917 // Use Default Data only when variable is not found.
918 // For other error status, correct data can't be got, and trig ASSERT().
920 ASSERT (Status
== EFI_NOT_FOUND
);
927 Find the local token number according to system SKU ID.
929 @param LocalTokenNumber PCD token number
930 @param Size The size of PCD entry.
931 @param IsPeiDb If TRUE, the PCD entry is initialized in PEI phase.
932 If False, the PCD entry is initialized in DXE phase.
934 @return Token number according to system SKU ID.
938 GetSkuEnabledTokenNumber (
939 UINT32 LocalTokenNumber
,
951 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0);
953 PcdDb
= IsPeiDb
? (UINT8
*) mPcdDatabase
.PeiDb
: (UINT8
*) mPcdDatabase
.DxeDb
;
955 SkuHead
= (SKU_HEAD
*) (PcdDb
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
956 Value
= (UINT8
*) (PcdDb
+ SkuHead
->SkuDataStartOffset
);
958 SkuIdTable
= (SKU_ID
*)(PcdDb
+ SkuHead
->SkuIdTableOffset
);
960 // Find the current system's SKU ID entry in SKU ID table.
963 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
964 if (mPcdDatabase
.DxeDb
->SystemSkuId
== SkuIdTable
[Index
+ 1]) {
971 // Find the default SKU ID entry in SKU ID table.
975 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
976 if (0 == SkuIdTable
[Index
+ 1]) {
981 ASSERT (Index
< SkuIdTable
[0]);
983 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
985 Value
= (UINT8
*) &(((VPD_HEAD
*) Value
)[Index
]);
986 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_VPD
);
989 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
990 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_HII
);
992 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
993 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
994 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_HII
| PCD_TYPE_STRING
);
996 case PCD_TYPE_STRING
:
997 Value
= (UINT8
*) &(((STRING_HEAD
*) Value
)[Index
]);
998 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_STRING
);
1001 Value
+= Size
* Index
;
1002 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_DATA
);
1015 Invoke the callback function when dynamic PCD entry was set, if this PCD entry
1016 has registered callback function.
1018 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx
1020 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type
1022 @param TokenNumber PCD token number generated by build tools.
1023 @param Data Value want to be set for this PCD entry
1024 @param Size The size of value
1028 InvokeCallbackOnSet (
1029 UINT32 ExTokenNumber
,
1030 CONST EFI_GUID
*Guid
, OPTIONAL
1036 CALLBACK_FN_ENTRY
*FnTableEntry
;
1037 LIST_ENTRY
*ListHead
;
1038 LIST_ENTRY
*ListNode
;
1041 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
1042 // We have to decrement TokenNumber by 1 to make it usable
1043 // as the array index of mCallbackFnTable[].
1045 ListHead
= &mCallbackFnTable
[TokenNumber
- 1];
1046 ListNode
= GetFirstNode (ListHead
);
1048 while (ListNode
!= ListHead
) {
1049 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE (ListNode
, CALLBACK_FN_ENTRY
, Node
);
1051 FnTableEntry
->CallbackFn(Guid
,
1052 (Guid
== NULL
) ? TokenNumber
: ExTokenNumber
,
1056 ListNode
= GetNextNode (ListHead
, ListNode
);
1064 Wrapper function for setting non-pointer type value for a PCD entry.
1066 @param TokenNumber Pcd token number autogenerated by build tools.
1067 @param Data Value want to be set for PCD entry
1068 @param Size Size of value.
1070 @return status of SetWorker.
1075 IN UINTN TokenNumber
,
1080 return SetWorker (TokenNumber
, Data
, &Size
, FALSE
);
1085 Set value for an PCD entry
1087 @param TokenNumber Pcd token number autogenerated by build tools.
1088 @param Data Value want to be set for PCD entry
1089 @param Size Size of value.
1090 @param PtrType If TRUE, the type of PCD entry's value is Pointer.
1091 If False, the type of PCD entry's value is not Pointer.
1093 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
1094 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.
1095 @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.
1096 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
1097 range of UINT8, UINT16, UINT32, UINT64
1098 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.
1102 IN UINTN TokenNumber
,
1109 UINT32 LocalTokenNumber
;
1110 EFI_GUID
*GuidTable
;
1114 UINTN VariableOffset
;
1116 VARIABLE_HEAD
*VariableHead
;
1121 UINTN TmpTokenNumber
;
1124 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
1125 // We have to decrement TokenNumber by 1 to make it usable
1126 // as the array index.
1130 TmpTokenNumber
= TokenNumber
;
1133 // EBC compiler is very choosy. It may report warning about comparison
1134 // between UINTN and 0 . So we add 1 in each size of the
1137 ASSERT (TokenNumber
+ 1 < mPcdTotalTokenCount
+ 1);
1141 // Get MaxSize first, then check new size with max buffer size.
1143 GetPtrTypeSize (TokenNumber
, &MaxSize
);
1144 if (*Size
> MaxSize
) {
1146 return EFI_INVALID_PARAMETER
;
1149 if (*Size
!= DxePcdGetSize (TokenNumber
+ 1)) {
1150 return EFI_INVALID_PARAMETER
;
1155 // EBC compiler is very choosy. It may report warning about comparison
1156 // between UINTN and 0 . So we add 1 in each size of the
1159 if ((TokenNumber
+ 1 < mPeiNexTokenCount
+ 1) ||
1160 (TokenNumber
+ 1 >= mPeiLocalTokenCount
+ 1 && TokenNumber
+ 1 < (mPeiLocalTokenCount
+ mDxeNexTokenCount
+ 1))) {
1161 InvokeCallbackOnSet (0, NULL
, TokenNumber
+ 1, Data
, *Size
);
1165 // Aquire lock to prevent reentrance from TPL_CALLBACK level
1167 EfiAcquireLock (&mPcdDatabaseLock
);
1170 // EBC compiler is very choosy. It may report warning about comparison
1171 // between UINTN and 0 . So we add 1 in each size of the
1174 IsPeiDb
= (BOOLEAN
) ((TokenNumber
+ 1 < mPeiLocalTokenCount
+ 1) ? TRUE
: FALSE
);
1176 LocalTokenNumber
= GetLocalTokenNumber (IsPeiDb
, TokenNumber
+ 1);
1178 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
1180 PcdDb
= IsPeiDb
? ((UINT8
*) mPcdDatabase
.PeiDb
) : ((UINT8
*) mPcdDatabase
.DxeDb
);
1183 StringTable
= (UINT8
*) ((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->StringTableOffset
);
1185 StringTable
= (UINT8
*) ((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->StringTableOffset
);
1189 InternalData
= PcdDb
+ Offset
;
1191 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
1194 Status
= EFI_INVALID_PARAMETER
;
1197 case PCD_TYPE_STRING
:
1198 if (SetPtrTypeSize (TmpTokenNumber
, Size
)) {
1199 CopyMem (StringTable
+ *((STRING_HEAD
*)InternalData
), Data
, *Size
);
1200 Status
= EFI_SUCCESS
;
1202 Status
= EFI_INVALID_PARAMETER
;
1206 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
1209 if (!SetPtrTypeSize (TmpTokenNumber
, Size
)) {
1210 Status
= EFI_INVALID_PARAMETER
;
1216 GuidTable
= (EFI_GUID
*) ((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
);
1218 GuidTable
= (EFI_GUID
*) ((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
);
1221 VariableHead
= (VARIABLE_HEAD
*) (PcdDb
+ Offset
);
1223 Guid
= GuidTable
+ VariableHead
->GuidTableIndex
;
1224 Name
= (UINT16
*) (StringTable
+ VariableHead
->StringIndex
);
1225 VariableOffset
= VariableHead
->Offset
;
1226 Status
= SetHiiVariable (Guid
, Name
, Data
, *Size
, VariableOffset
);
1228 if (EFI_NOT_FOUND
== Status
) {
1229 if ((LocalTokenNumber
& PCD_TYPE_ALL_SET
) == (PCD_TYPE_HII
|PCD_TYPE_STRING
)) {
1231 StringTable
+ *(STRING_HEAD
*)(PcdDb
+ VariableHead
->DefaultValueOffset
),
1236 CopyMem (PcdDb
+ VariableHead
->DefaultValueOffset
, Data
, *Size
);
1238 Status
= EFI_SUCCESS
;
1244 if (SetPtrTypeSize (TmpTokenNumber
, Size
)) {
1245 CopyMem (InternalData
, Data
, *Size
);
1246 Status
= EFI_SUCCESS
;
1248 Status
= EFI_INVALID_PARAMETER
;
1253 Status
= EFI_SUCCESS
;
1256 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
1259 case sizeof(UINT16
):
1260 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
1263 case sizeof(UINT32
):
1264 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
1267 case sizeof(UINT64
):
1268 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
1273 Status
= EFI_NOT_FOUND
;
1280 Status
= EFI_NOT_FOUND
;
1284 EfiReleaseLock (&mPcdDatabaseLock
);
1290 Wrapper function for get PCD value for dynamic-ex PCD.
1292 @param Guid Token space guid for dynamic-ex PCD.
1293 @param ExTokenNumber Token number for dynamic-ex PCD.
1294 @param GetSize The size of dynamic-ex PCD value.
1296 @return PCD entry in PCD database.
1301 IN CONST EFI_GUID
*Guid
,
1302 IN UINTN ExTokenNumber
,
1306 return GetWorker(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
), GetSize
);
1310 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.
1312 @param ExTokenNumber Token number for dynamic-ex PCD.
1313 @param Guid Token space guid for dynamic-ex PCD.
1314 @param Data Value want to be set.
1315 @param SetSize The size of value.
1317 @return status of ExSetWorker().
1322 IN UINTN ExTokenNumber
,
1323 IN CONST EFI_GUID
*Guid
,
1328 return ExSetWorker (ExTokenNumber
, Guid
, Data
, &SetSize
, FALSE
);
1332 Set value for a dynamic-ex PCD entry.
1334 This routine find the local token number according to dynamic-ex PCD's token
1335 space guid and token number firstly, and invoke callback function if this PCD
1336 entry registered callback function. Finally, invoken general SetWorker to set
1339 @param ExTokenNumber Dynamic-ex PCD token number.
1340 @param Guid Token space guid for dynamic-ex PCD.
1341 @param Data PCD value want to be set
1342 @param SetSize Size of value.
1343 @param PtrType If TRUE, this PCD entry is pointer type.
1344 If FALSE, this PCD entry is not pointer type.
1346 @return status of SetWorker().
1351 IN UINTN ExTokenNumber
,
1352 IN CONST EFI_GUID
*Guid
,
1354 IN OUT UINTN
*SetSize
,
1360 TokenNumber
= GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
);
1362 InvokeCallbackOnSet ((UINT32
) ExTokenNumber
, Guid
, TokenNumber
, Data
, *SetSize
);
1364 return SetWorker (TokenNumber
, Data
, SetSize
, PtrType
);
1369 Set value for HII-type PCD.
1371 A HII-type PCD's value is stored in a variable. Setting/Getting the value of
1372 HII-type PCD is to visit this variable.
1374 @param VariableGuid Guid of variable which stored value of a HII-type PCD.
1375 @param VariableName Unicode name of variable which stored value of a HII-type PCD.
1376 @param Data Value want to be set.
1377 @param DataSize Size of value
1378 @param Offset Value offset of HII-type PCD in variable.
1380 @return status of GetVariable()/SetVariable().
1385 IN EFI_GUID
*VariableGuid
,
1386 IN UINT16
*VariableName
,
1387 IN CONST VOID
*Data
,
1402 // Try to get original variable size information.
1404 Status
= gRT
->GetVariable (
1405 (UINT16
*)VariableName
,
1412 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1414 // Patch new PCD's value to offset in given HII variable.
1416 if (Size
>= (DataSize
+ Offset
)) {
1419 SetSize
= DataSize
+ Offset
;
1421 Buffer
= AllocatePool (SetSize
);
1422 ASSERT (Buffer
!= NULL
);
1424 Status
= gRT
->GetVariable (
1432 ASSERT_EFI_ERROR (Status
);
1434 CopyMem ((UINT8
*)Buffer
+ Offset
, Data
, DataSize
);
1436 Status
= gRT
->SetVariable (
1446 } else if (Status
== EFI_NOT_FOUND
) {
1448 // If variable does not exist, a new variable need to be created.
1451 Size
= Offset
+ DataSize
;
1453 Buffer
= AllocateZeroPool (Size
);
1454 ASSERT (Buffer
!= NULL
);
1456 CopyMem ((UINT8
*)Buffer
+ Offset
, Data
, DataSize
);
1458 Status
= gRT
->SetVariable (
1461 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1471 // If we drop to here, the value is failed to be written in to variable area
1472 // So, we will save the data in the PCD Database's volatile area.
1478 Get Token Number according to dynamic-ex PCD's {token space guid:token number}
1480 A dynamic-ex type PCD, developer must provide pair of token space guid: token number
1481 in DEC file. PCD database maintain a mapping table that translate pair of {token
1482 space guid: token number} to Token Number.
1484 @param Guid Token space guid for dynamic-ex PCD entry.
1485 @param ExTokenNumber Dynamic-ex PCD token number.
1487 @return Token Number for dynamic-ex PCD.
1491 GetExPcdTokenNumber (
1492 IN CONST EFI_GUID
*Guid
,
1493 IN UINT32 ExTokenNumber
1497 DYNAMICEX_MAPPING
*ExMap
;
1498 EFI_GUID
*GuidTable
;
1499 EFI_GUID
*MatchGuid
;
1502 if (!mPeiDatabaseEmpty
) {
1503 ExMap
= (DYNAMICEX_MAPPING
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->ExMapTableOffset
);
1504 GuidTable
= (EFI_GUID
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
);
1506 MatchGuid
= ScanGuid (GuidTable
, mPeiGuidTableSize
, Guid
);
1508 if (MatchGuid
!= NULL
) {
1510 MatchGuidIdx
= MatchGuid
- GuidTable
;
1512 for (Index
= 0; Index
< mPcdDatabase
.PeiDb
->ExTokenCount
; Index
++) {
1513 if ((ExTokenNumber
== ExMap
[Index
].ExTokenNumber
) &&
1514 (MatchGuidIdx
== ExMap
[Index
].ExGuidIndex
)) {
1515 return ExMap
[Index
].TokenNumber
;
1521 ExMap
= (DYNAMICEX_MAPPING
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->ExMapTableOffset
);
1522 GuidTable
= (EFI_GUID
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
);
1524 MatchGuid
= ScanGuid (GuidTable
, mDxeGuidTableSize
, Guid
);
1526 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
1527 // error in the BUILD system.
1529 ASSERT (MatchGuid
!= NULL
);
1531 MatchGuidIdx
= MatchGuid
- GuidTable
;
1533 for (Index
= 0; Index
< mPcdDatabase
.DxeDb
->ExTokenCount
; Index
++) {
1534 if ((ExTokenNumber
== ExMap
[Index
].ExTokenNumber
) &&
1535 (MatchGuidIdx
== ExMap
[Index
].ExGuidIndex
)) {
1536 return ExMap
[Index
].TokenNumber
;
1546 Get SKU ID table from PCD database.
1548 @param LocalTokenNumberTableIdx Index of local token number in token number table.
1549 @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
1550 If FALSE, the pcd entry is initialized in DXE phase.
1551 @return Pointer to SKU ID array table
1556 IN UINTN LocalTokenNumberTableIdx
,
1561 UINTN LocalTokenNumber
;
1565 LocalTokenNumber
= *((UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
) + LocalTokenNumberTableIdx
);
1566 Database
= (UINT8
*) mPcdDatabase
.PeiDb
;
1568 LocalTokenNumber
= *((UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
) + LocalTokenNumberTableIdx
);
1569 Database
= (UINT8
*) mPcdDatabase
.DxeDb
;
1572 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) != 0);
1574 SkuHead
= (SKU_HEAD
*) ((UINT8
*)Database
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
1576 return (SKU_ID
*) (Database
+ SkuHead
->SkuIdTableOffset
);
1581 Wrapper function of getting index of PCD entry in size table.
1583 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1584 @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
1585 If FALSE, the pcd entry is initialized in DXE phase.
1587 @return index of PCD entry in size table.
1591 IN UINTN LocalTokenNumberTableIdx
,
1595 UINT32
*LocalTokenNumberTable
;
1596 UINTN LocalTokenNumber
;
1602 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
);
1604 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
1609 for (Index
= 0; Index
< LocalTokenNumberTableIdx
; Index
++) {
1610 LocalTokenNumber
= LocalTokenNumberTable
[Index
];
1612 if ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
) {
1614 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1617 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1619 // We have only two entry for VPD enabled PCD entry:
1622 // Current size is equal to MAX size.
1626 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1628 // We have only two entry for Non-Sku enabled PCD entry:
1635 // We have these entry for SKU enabled PCD entry
1637 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1639 SkuIdTable
= GetSkuIdArray (Index
, IsPeiDb
);
1640 SizeTableIdx
+= (UINTN
)*SkuIdTable
+ 1;
1647 return SizeTableIdx
;
1651 Get size of POINTER type PCD value.
1653 @param LocalTokenNumberTableIdx Index of local token number in local token number table.
1654 @param MaxSize Maxmium size of POINTER type PCD value.
1656 @return size of POINTER type PCD value.
1661 IN UINTN LocalTokenNumberTableIdx
,
1666 UINTN LocalTokenNumber
;
1668 SIZE_INFO
*SizeTable
;
1671 UINT32
*LocalTokenNumberTable
;
1673 // EBC compiler is very choosy. It may report warning about comparison
1674 // between UINTN and 0 . So we add 1 in each size of the
1676 IsPeiDb
= (BOOLEAN
) (LocalTokenNumberTableIdx
+ 1 < mPeiLocalTokenCount
+ 1);
1680 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
);
1681 SizeTable
= (SIZE_INFO
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->SizeTableOffset
);
1683 LocalTokenNumberTableIdx
-= mPeiLocalTokenCount
;
1684 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
1685 SizeTable
= (SIZE_INFO
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->SizeTableOffset
);
1688 LocalTokenNumber
= LocalTokenNumberTable
[LocalTokenNumberTableIdx
];
1690 ASSERT ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
);
1692 SizeTableIdx
= GetSizeTableIndex (LocalTokenNumberTableIdx
, IsPeiDb
);
1694 *MaxSize
= SizeTable
[SizeTableIdx
];
1696 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1699 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1701 // We have only two entry for VPD enabled PCD entry:
1704 // We consider current size is equal to MAX size.
1708 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1710 // We have only two entry for Non-Sku enabled PCD entry:
1714 return SizeTable
[SizeTableIdx
+ 1];
1717 // We have these entry for SKU enabled PCD entry
1719 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1721 SkuIdTable
= GetSkuIdArray (LocalTokenNumberTableIdx
, IsPeiDb
);
1722 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
1723 if (SkuIdTable
[1 + Index
] == mPcdDatabase
.DxeDb
->SystemSkuId
) {
1724 return SizeTable
[SizeTableIdx
+ 1 + Index
];
1727 return SizeTable
[SizeTableIdx
+ 1];
1733 Set size of POINTER type PCD value. The size should not exceed the maximum size
1736 @param LocalTokenNumberTableIdx Index of local token number in local token number table.
1737 @param CurrentSize Size of POINTER type PCD value.
1739 @retval TRUE Success to set size of PCD value.
1740 @retval FALSE Fail to set size of PCD value.
1744 IN UINTN LocalTokenNumberTableIdx
,
1745 IN OUT UINTN
*CurrentSize
1749 UINTN LocalTokenNumber
;
1751 SIZE_INFO
*SizeTable
;
1755 UINT32
*LocalTokenNumberTable
;
1758 // EBC compiler is very choosy. It may report warning about comparison
1759 // between UINTN and 0 . So we add 1 in each size of the
1762 IsPeiDb
= (BOOLEAN
) (LocalTokenNumberTableIdx
+ 1 < mPeiLocalTokenCount
+ 1);
1765 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
);
1766 SizeTable
= (SIZE_INFO
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->SizeTableOffset
);
1768 LocalTokenNumberTableIdx
-= mPeiLocalTokenCount
;
1769 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
1770 SizeTable
= (SIZE_INFO
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->SizeTableOffset
);
1773 LocalTokenNumber
= LocalTokenNumberTable
[LocalTokenNumberTableIdx
];
1775 ASSERT ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
);
1777 SizeTableIdx
= GetSizeTableIndex (LocalTokenNumberTableIdx
, IsPeiDb
);
1779 MaxSize
= SizeTable
[SizeTableIdx
];
1781 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1784 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1786 // We shouldn't come here as we don't support SET for VPD
1791 if ((*CurrentSize
> MaxSize
) ||
1792 (*CurrentSize
== MAX_ADDRESS
)) {
1793 *CurrentSize
= MaxSize
;
1797 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1799 // We have only two entry for Non-Sku enabled PCD entry:
1803 SizeTable
[SizeTableIdx
+ 1] = (SIZE_INFO
) *CurrentSize
;
1807 // We have these entry for SKU enabled PCD entry
1809 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1811 SkuIdTable
= GetSkuIdArray (LocalTokenNumberTableIdx
, IsPeiDb
);
1812 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
1813 if (SkuIdTable
[1 + Index
] == mPcdDatabase
.DxeDb
->SystemSkuId
) {
1814 SizeTable
[SizeTableIdx
+ 1 + Index
] = (SIZE_INFO
) *CurrentSize
;
1818 SizeTable
[SizeTableIdx
+ 1] = (SIZE_INFO
) *CurrentSize
;