2 Help functions used by PCD DXE driver.
4 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/DxeServicesLib.h>
18 PCD_DATABASE mPcdDatabase
;
20 UINT32 mPcdTotalTokenCount
;
21 UINT32 mPeiLocalTokenCount
;
22 UINT32 mDxeLocalTokenCount
;
23 UINT32 mPeiNexTokenCount
;
24 UINT32 mDxeNexTokenCount
;
25 UINT32 mPeiExMapppingTableSize
;
26 UINT32 mDxeExMapppingTableSize
;
27 UINT32 mPeiGuidTableSize
;
28 UINT32 mDxeGuidTableSize
;
30 BOOLEAN mPeiExMapTableEmpty
;
31 BOOLEAN mDxeExMapTableEmpty
;
32 BOOLEAN mPeiDatabaseEmpty
;
34 LIST_ENTRY
*mCallbackFnTable
;
35 EFI_GUID
**TmpTokenSpaceBuffer
;
36 UINTN TmpTokenSpaceBufferCount
;
39 Get Local Token Number by Token Number.
41 @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
42 If FALSE, the pcd entry is initialized in DXE phase.
43 @param[in] TokenNumber The PCD token number.
45 @return Local Token Number.
53 UINT32
*LocalTokenNumberTable
;
54 UINT32 LocalTokenNumber
;
59 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
60 // We have to decrement TokenNumber by 1 to make it usable
61 // as the array index.
65 LocalTokenNumberTable
= IsPeiDb
? (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
) :
66 (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
67 TokenNumber
= IsPeiDb
? TokenNumber
: TokenNumber
- mPeiLocalTokenCount
;
69 LocalTokenNumber
= LocalTokenNumberTable
[TokenNumber
];
71 Size
= (LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
73 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
75 GetPtrTypeSize (TokenNumber
, &MaxSize
);
79 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, MaxSize
, IsPeiDb
);
82 return LocalTokenNumber
;
86 Get PCD type by Local Token Number.
88 @param[in] LocalTokenNumber The PCD local token number.
94 IN UINT32 LocalTokenNumber
97 switch (LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) {
98 case PCD_DATUM_TYPE_POINTER
:
99 return EFI_PCD_TYPE_PTR
;
100 case PCD_DATUM_TYPE_UINT8
:
101 if (LocalTokenNumber
& PCD_DATUM_TYPE_UINT8_BOOLEAN
) {
102 return EFI_PCD_TYPE_BOOL
;
104 return EFI_PCD_TYPE_8
;
106 case PCD_DATUM_TYPE_UINT16
:
107 return EFI_PCD_TYPE_16
;
108 case PCD_DATUM_TYPE_UINT32
:
109 return EFI_PCD_TYPE_32
;
110 case PCD_DATUM_TYPE_UINT64
:
111 return EFI_PCD_TYPE_64
;
114 return EFI_PCD_TYPE_8
;
121 @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.
122 If FALSE, need to get the full PCD name.
123 @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
124 If FALSE, the pcd entry is initialized in DXE phase.
125 @param[in] TokenNumber The PCD token number.
127 @return The TokenSpaceCName or full PCD name.
131 IN BOOLEAN OnlyTokenSpaceName
,
136 PCD_DATABASE_INIT
*Database
;
138 PCD_NAME_INDEX
*PcdNameIndex
;
139 CHAR8
*TokenSpaceName
;
144 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
145 // We have to decrement TokenNumber by 1 to make it usable
146 // as the array index.
150 Database
= IsPeiDb
? mPcdDatabase
.PeiDb
: mPcdDatabase
.DxeDb
;
151 TokenNumber
= IsPeiDb
? TokenNumber
: TokenNumber
- mPeiLocalTokenCount
;
153 StringTable
= (UINT8
*) Database
+ Database
->StringTableOffset
;
156 // Get the PCD name index.
158 PcdNameIndex
= (PCD_NAME_INDEX
*)((UINT8
*) Database
+ Database
->PcdNameTableOffset
) + TokenNumber
;
159 TokenSpaceName
= (CHAR8
*)&StringTable
[PcdNameIndex
->TokenSpaceCNameIndex
];
160 PcdName
= (CHAR8
*)&StringTable
[PcdNameIndex
->PcdCNameIndex
];
162 if (OnlyTokenSpaceName
) {
164 // Only need to get the TokenSpaceCName.
166 Name
= AllocateCopyPool (AsciiStrSize (TokenSpaceName
), TokenSpaceName
);
169 // Need to get the full PCD name.
171 Name
= AllocateZeroPool (AsciiStrSize (TokenSpaceName
) + AsciiStrSize (PcdName
));
173 // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
175 AsciiStrCat (Name
, TokenSpaceName
);
176 Name
[AsciiStrSize (TokenSpaceName
) - sizeof (CHAR8
)] = '.';
177 AsciiStrCat (Name
, PcdName
);
184 Retrieve additional information associated with a PCD token.
186 This includes information such as the type of value the TokenNumber is associated with as well as possible
187 human readable name that is associated with the token.
189 @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
190 If FALSE, the pcd entry is initialized in DXE phase.
191 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
192 @param[in] TokenNumber The PCD token number.
193 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
194 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
196 @retval EFI_SUCCESS The PCD information was returned successfully
197 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
202 IN CONST EFI_GUID
*Guid
,
203 IN UINTN TokenNumber
,
204 OUT EFI_PCD_INFO
*PcdInfo
207 PCD_DATABASE_INIT
*Database
;
211 DYNAMICEX_MAPPING
*ExMapTable
;
213 UINT32 LocalTokenNumber
;
215 Database
= IsPeiDb
? mPcdDatabase
.PeiDb
: mPcdDatabase
.DxeDb
;
217 GuidTable
= (EFI_GUID
*)((UINT8
*)Database
+ Database
->GuidTableOffset
);
218 MatchGuid
= ScanGuid (GuidTable
, Database
->GuidTableCount
* sizeof(EFI_GUID
), Guid
);
220 if (MatchGuid
== NULL
) {
221 return EFI_NOT_FOUND
;
224 GuidTableIdx
= MatchGuid
- GuidTable
;
226 ExMapTable
= (DYNAMICEX_MAPPING
*)((UINT8
*)Database
+ Database
->ExMapTableOffset
);
229 // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
231 for (Index
= 0; Index
< Database
->ExTokenCount
; Index
++) {
232 if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
233 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
235 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
236 // PcdSize to 0 and PcdName to the null-terminated ASCII string
237 // associated with the token's namespace Guid.
239 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
240 PcdInfo
->PcdSize
= 0;
242 // Here use one representative in the token space to get the TokenSpaceCName.
244 PcdInfo
->PcdName
= GetPcdName (TRUE
, IsPeiDb
, ExMapTable
[Index
].TokenNumber
);
246 } else if (ExMapTable
[Index
].ExTokenNumber
== TokenNumber
) {
247 PcdInfo
->PcdSize
= DxePcdGetSize (ExMapTable
[Index
].TokenNumber
);
248 LocalTokenNumber
= GetLocalTokenNumber (IsPeiDb
, ExMapTable
[Index
].TokenNumber
);
249 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
250 PcdInfo
->PcdName
= GetPcdName (FALSE
, IsPeiDb
, ExMapTable
[Index
].TokenNumber
);
256 return EFI_NOT_FOUND
;
260 Retrieve additional information associated with a PCD token.
262 This includes information such as the type of value the TokenNumber is associated with as well as possible
263 human readable name that is associated with the token.
265 @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
266 @param[in] TokenNumber The PCD token number.
267 @param[out] PcdInfo The returned information associated with the requested TokenNumber.
268 The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
270 @retval EFI_SUCCESS The PCD information was returned successfully.
271 @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
275 IN CONST EFI_GUID
*Guid
,
276 IN UINTN TokenNumber
,
277 OUT EFI_PCD_INFO
*PcdInfo
281 BOOLEAN PeiExMapTableEmpty
;
282 BOOLEAN DxeExMapTableEmpty
;
283 UINT32 LocalTokenNumber
;
286 if (!FeaturePcdGet (PcdPcdInfoGeneration
)) {
287 return EFI_UNSUPPORTED
;
290 ASSERT (PcdInfo
!= NULL
);
292 Status
= EFI_NOT_FOUND
;
293 PeiExMapTableEmpty
= mPeiExMapTableEmpty
;
294 DxeExMapTableEmpty
= mDxeExMapTableEmpty
;
297 if (((TokenNumber
+ 1 > mPeiNexTokenCount
+ 1) && (TokenNumber
+ 1 <= mPeiLocalTokenCount
+ 1)) ||
298 ((TokenNumber
+ 1 > (mPeiLocalTokenCount
+ mDxeNexTokenCount
+ 1)))) {
299 return EFI_NOT_FOUND
;
300 } else if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
302 // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
303 // PcdSize to 0 and PcdName to NULL for default Token Space.
305 PcdInfo
->PcdType
= EFI_PCD_TYPE_8
;
306 PcdInfo
->PcdSize
= 0;
307 PcdInfo
->PcdName
= NULL
;
309 PcdInfo
->PcdSize
= DxePcdGetSize (TokenNumber
);
311 if ((TokenNumber
+ 1 <= mPeiNexTokenCount
+ 1)) {
314 LocalTokenNumber
= GetLocalTokenNumber (IsPeiDb
, TokenNumber
);
315 PcdInfo
->PcdType
= GetPcdType (LocalTokenNumber
);
316 PcdInfo
->PcdName
= GetPcdName (FALSE
, IsPeiDb
, TokenNumber
);
321 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
322 return EFI_NOT_FOUND
;
325 if (!PeiExMapTableEmpty
) {
326 Status
= ExGetPcdInfo (
334 if (Status
== EFI_SUCCESS
) {
338 if (!DxeExMapTableEmpty
) {
339 Status
= ExGetPcdInfo (
351 Get the PCD entry pointer in PCD database.
353 This routine will visit PCD database to find the PCD entry according to given
354 token number. The given token number is autogened by build tools and it will be
355 translated to local token number. Local token number contains PCD's type and
356 offset of PCD entry in PCD database.
358 @param TokenNumber Token's number, it is autogened by build tools
359 @param GetSize The size of token's value
361 @return PCD entry pointer in PCD database
366 IN UINTN TokenNumber
,
374 VARIABLE_HEAD
*VariableHead
;
375 UINT8
*VaraiableDefaultBuffer
;
380 UINTN TmpTokenNumber
;
383 UINT32 LocalTokenNumber
;
385 STRING_HEAD StringTableIdx
;
389 // Aquire lock to prevent reentrance from TPL_CALLBACK level
391 EfiAcquireLock (&mPcdDatabaseLock
);
395 ASSERT (TokenNumber
> 0);
397 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
398 // We have to decrement TokenNumber by 1 to make it usable
399 // as the array index.
403 TmpTokenNumber
= TokenNumber
;
406 // EBC compiler is very choosy. It may report warning about comparison
407 // between UINTN and 0 . So we add 1 in each size of the
410 ASSERT (TokenNumber
+ 1 < mPcdTotalTokenCount
+ 1);
412 ASSERT ((GetSize
== DxePcdGetSize (TokenNumber
+ 1)) || (GetSize
== 0));
414 // EBC compiler is very choosy. It may report warning about comparison
415 // between UINTN and 0 . So we add 1 in each size of the
417 IsPeiDb
= (BOOLEAN
) ((TokenNumber
+ 1 < mPeiLocalTokenCount
+ 1) ? TRUE
: FALSE
);
419 LocalTokenNumber
= GetLocalTokenNumber (IsPeiDb
, TokenNumber
+ 1);
421 PcdDb
= IsPeiDb
? ((UINT8
*) mPcdDatabase
.PeiDb
) : ((UINT8
*) mPcdDatabase
.DxeDb
);
424 StringTable
= (UINT8
*) ((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->StringTableOffset
);
426 StringTable
= (UINT8
*) ((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->StringTableOffset
);
430 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
432 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
434 VpdHead
= (VPD_HEAD
*) ((UINT8
*) PcdDb
+ Offset
);
435 RetPtr
= (VOID
*) (UINTN
) (PcdGet32 (PcdVpdBaseAddress
) + VpdHead
->Offset
);
439 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
442 GuidTable
= (EFI_GUID
*) ((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
);
444 GuidTable
= (EFI_GUID
*) ((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
);
447 VariableHead
= (VARIABLE_HEAD
*) (PcdDb
+ Offset
);
448 Guid
= GuidTable
+ VariableHead
->GuidTableIndex
;
449 Name
= (UINT16
*)(StringTable
+ VariableHead
->StringIndex
);
451 if ((LocalTokenNumber
& PCD_TYPE_ALL_SET
) == (PCD_TYPE_HII
|PCD_TYPE_STRING
)) {
453 // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
454 // string array in string table.
456 StringTableIdx
= *(STRING_HEAD
*)((UINT8
*) PcdDb
+ VariableHead
->DefaultValueOffset
);
457 VaraiableDefaultBuffer
= (VOID
*) (StringTable
+ StringTableIdx
);
459 VaraiableDefaultBuffer
= (UINT8
*) PcdDb
+ VariableHead
->DefaultValueOffset
;
461 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
462 if (Status
== EFI_SUCCESS
) {
465 // It is a pointer type. So get the MaxSize reserved for
468 GetPtrTypeSize (TmpTokenNumber
, &GetSize
);
471 // If the operation is successful, we copy the data
472 // to the default value buffer in the PCD Database.
473 // So that we can free the Data allocated in GetHiiVariable.
475 CopyMem (VaraiableDefaultBuffer
, Data
+ VariableHead
->Offset
, GetSize
);
478 RetPtr
= (VOID
*) VaraiableDefaultBuffer
;
481 case PCD_TYPE_STRING
:
482 StringTableIdx
= *(STRING_HEAD
*)((UINT8
*) PcdDb
+ Offset
);
483 RetPtr
= (VOID
*) (StringTable
+ StringTableIdx
);
487 RetPtr
= (VOID
*) ((UINT8
*) PcdDb
+ Offset
);
496 EfiReleaseLock (&mPcdDatabaseLock
);
503 Register the callback function for a PCD entry.
505 This routine will register a callback function to a PCD entry by given token number
506 and token space guid.
508 @param TokenNumber PCD token's number, it is autogened by build tools.
509 @param Guid PCD token space's guid,
510 if not NULL, this PCD is dynamicEx type PCD.
511 @param CallBackFunction Callback function pointer
513 @return EFI_SUCCESS Always success for registering callback function.
517 DxeRegisterCallBackWorker (
518 IN UINTN TokenNumber
,
519 IN CONST EFI_GUID
*Guid
, OPTIONAL
520 IN PCD_PROTOCOL_CALLBACK CallBackFunction
523 CALLBACK_FN_ENTRY
*FnTableEntry
;
524 LIST_ENTRY
*ListHead
;
525 LIST_ENTRY
*ListNode
;
528 TokenNumber
= GetExPcdTokenNumber (Guid
, (UINT32
) TokenNumber
);
532 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
533 // We have to decrement TokenNumber by 1 to make it usable
534 // as the array index of mCallbackFnTable[].
536 ListHead
= &mCallbackFnTable
[TokenNumber
- 1];
537 ListNode
= GetFirstNode (ListHead
);
539 while (ListNode
!= ListHead
) {
540 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE(ListNode
, CALLBACK_FN_ENTRY
, Node
);
542 if (FnTableEntry
->CallbackFn
== CallBackFunction
) {
544 // We only allow a Callback function to be register once
545 // for a TokenNumber. So just return EFI_SUCCESS
549 ListNode
= GetNextNode (ListHead
, ListNode
);
552 FnTableEntry
= AllocatePool (sizeof(CALLBACK_FN_ENTRY
));
553 ASSERT (FnTableEntry
!= NULL
);
555 FnTableEntry
->CallbackFn
= CallBackFunction
;
556 InsertTailList (ListHead
, &FnTableEntry
->Node
);
562 UnRegister the callback function for a PCD entry.
564 This routine will unregister a callback function to a PCD entry by given token number
565 and token space guid.
567 @param TokenNumber PCD token's number, it is autogened by build tools.
568 @param Guid PCD token space's guid.
569 if not NULL, this PCD is dynamicEx type PCD.
570 @param CallBackFunction Callback function pointer
572 @retval EFI_SUCCESS Callback function is success to be unregister.
573 @retval EFI_INVALID_PARAMETER Can not find the PCD entry by given token number.
576 DxeUnRegisterCallBackWorker (
577 IN UINTN TokenNumber
,
578 IN CONST EFI_GUID
*Guid
, OPTIONAL
579 IN PCD_PROTOCOL_CALLBACK CallBackFunction
582 CALLBACK_FN_ENTRY
*FnTableEntry
;
583 LIST_ENTRY
*ListHead
;
584 LIST_ENTRY
*ListNode
;
587 TokenNumber
= GetExPcdTokenNumber (Guid
, (UINT32
) TokenNumber
);
591 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
592 // We have to decrement TokenNumber by 1 to make it usable
593 // as the array index of mCallbackFnTable[].
595 ListHead
= &mCallbackFnTable
[TokenNumber
- 1];
596 ListNode
= GetFirstNode (ListHead
);
598 while (ListNode
!= ListHead
) {
599 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE(ListNode
, CALLBACK_FN_ENTRY
, Node
);
601 if (FnTableEntry
->CallbackFn
== CallBackFunction
) {
603 // We only allow a Callback function to be register once
604 // for a TokenNumber. So we can safely remove the Node from
605 // the Link List and return EFI_SUCCESS.
607 RemoveEntryList (ListNode
);
608 FreePool (FnTableEntry
);
612 ListNode
= GetNextNode (ListHead
, ListNode
);
615 return EFI_INVALID_PARAMETER
;
619 Get next token number in given token space.
621 This routine is used for dynamicEx type PCD. It will firstly scan token space
622 table to get token space according to given token space guid. Then scan given
623 token number in found token space, if found, then return next token number in
626 @param Guid Token space guid. Next token number will be scaned in
628 @param TokenNumber Token number.
629 If PCD_INVALID_TOKEN_NUMBER, return first token number in
631 If not PCD_INVALID_TOKEN_NUMBER, return next token number
632 in token space table.
633 @param GuidTable Token space guid table. It will be used for scan token space
634 by given token space guid.
635 @param SizeOfGuidTable The size of guid table.
636 @param ExMapTable DynamicEx token number mapping table.
637 @param SizeOfExMapTable The size of dynamicEx token number mapping table.
639 @retval EFI_NOT_FOUND Can not given token space or token number.
640 @retval EFI_SUCCESS Success to get next token number.
644 ExGetNextTokeNumber (
645 IN CONST EFI_GUID
*Guid
,
646 IN OUT UINTN
*TokenNumber
,
647 IN EFI_GUID
*GuidTable
,
648 IN UINTN SizeOfGuidTable
,
649 IN DYNAMICEX_MAPPING
*ExMapTable
,
650 IN UINTN SizeOfExMapTable
657 UINTN ExMapTableCount
;
660 // Scan token space guid
662 MatchGuid
= ScanGuid (GuidTable
, SizeOfGuidTable
, Guid
);
663 if (MatchGuid
== NULL
) {
664 return EFI_NOT_FOUND
;
668 // Find the token space table in dynamicEx mapping table.
671 GuidTableIdx
= MatchGuid
- GuidTable
;
672 ExMapTableCount
= SizeOfExMapTable
/ sizeof(ExMapTable
[0]);
673 for (Index
= 0; Index
< ExMapTableCount
; Index
++) {
674 if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
682 // If given token number is PCD_INVALID_TOKEN_NUMBER, then return the first
683 // token number in found token space.
685 if (*TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
686 *TokenNumber
= ExMapTable
[Index
].ExTokenNumber
;
690 for ( ; Index
< ExMapTableCount
; Index
++) {
691 if (ExMapTable
[Index
].ExTokenNumber
== *TokenNumber
) {
696 while (Index
< ExMapTableCount
) {
698 if (Index
== ExMapTableCount
) {
700 // Exceed the length of ExMap Table
702 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
703 return EFI_NOT_FOUND
;
704 } else if (ExMapTable
[Index
].ExGuidIndex
== GuidTableIdx
) {
706 // Found the next match
708 *TokenNumber
= ExMapTable
[Index
].ExTokenNumber
;
714 return EFI_NOT_FOUND
;
718 Find the PCD database.
720 @retval The base address of external PCD database binary.
721 @retval NULL Return NULL if not find.
728 DXE_PCD_DATABASE
*DxePcdDbBinary
;
732 DxePcdDbBinary
= NULL
;
734 // Search the External Pcd database from one section of current FFS,
735 // and read it to memory
737 Status
= GetSectionFromFfs (
740 (VOID
**) &DxePcdDbBinary
,
743 ASSERT_EFI_ERROR (Status
);
746 // Check the first bytes (Header Signature Guid) and build version.
748 if (!CompareGuid ((VOID
*)DxePcdDbBinary
, &gPcdDataBaseSignatureGuid
) ||
749 (DxePcdDbBinary
->BuildVersion
!= PCD_SERVICE_DXE_VERSION
)) {
753 return DxePcdDbBinary
;
757 Initialize the PCD database in DXE phase.
759 PCD database in DXE phase also contains PCD database in PEI phase which is copied
764 BuildPcdDxeDataBase (
768 PEI_PCD_DATABASE
*PeiDatabase
;
769 EFI_HOB_GUID_TYPE
*GuidHob
;
774 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
775 if (GuidHob
!= NULL
) {
778 // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM
779 // should not be included at all. So the GuidHob could
780 // be NULL. If it is NULL, we just copy over the DXE Default
781 // Value to PCD Database.
784 PeiDatabase
= (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);
786 // Assign PCD Entries refereneced in PEI phase to PCD DATABASE
788 mPcdDatabase
.PeiDb
= PeiDatabase
;
792 // Assign PCD Entries with default value to PCD DATABASE
794 mPcdDatabase
.DxeDb
= LocateExPcdBinary ();
795 ASSERT(mPcdDatabase
.DxeDb
!= NULL
);
796 PcdDxeDbLen
= mPcdDatabase
.DxeDb
->Length
+ mPcdDatabase
.DxeDb
->UninitDataBaseSize
;
797 PcdDxeDb
= AllocateZeroPool (PcdDxeDbLen
);
798 ASSERT (PcdDxeDb
!= NULL
);
799 CopyMem (PcdDxeDb
, mPcdDatabase
.DxeDb
, mPcdDatabase
.DxeDb
->Length
);
800 FreePool (mPcdDatabase
.DxeDb
);
801 mPcdDatabase
.DxeDb
= PcdDxeDb
;
804 // Initialized the external PCD database local variables
806 mPeiLocalTokenCount
= mPcdDatabase
.PeiDb
->LocalTokenCount
;
807 mDxeLocalTokenCount
= mPcdDatabase
.DxeDb
->LocalTokenCount
;
809 mPeiExMapppingTableSize
= mPcdDatabase
.PeiDb
->ExTokenCount
* sizeof (DYNAMICEX_MAPPING
);
810 mDxeExMapppingTableSize
= mPcdDatabase
.DxeDb
->ExTokenCount
* sizeof (DYNAMICEX_MAPPING
);
811 mPeiGuidTableSize
= mPcdDatabase
.PeiDb
->GuidTableCount
* sizeof(GUID
);
812 mDxeGuidTableSize
= mPcdDatabase
.DxeDb
->GuidTableCount
* sizeof (GUID
);
814 mPcdTotalTokenCount
= mPeiLocalTokenCount
+ mDxeLocalTokenCount
;
815 mPeiNexTokenCount
= mPeiLocalTokenCount
- mPcdDatabase
.PeiDb
->ExTokenCount
;
816 mDxeNexTokenCount
= mDxeLocalTokenCount
- mPcdDatabase
.DxeDb
->ExTokenCount
;
818 mPeiExMapTableEmpty
= (mPcdDatabase
.PeiDb
->ExTokenCount
== 0) ? TRUE
: FALSE
;
819 mDxeExMapTableEmpty
= (mPcdDatabase
.DxeDb
->ExTokenCount
== 0) ? TRUE
: FALSE
;
820 mPeiDatabaseEmpty
= (mPeiLocalTokenCount
== 0) ? TRUE
: FALSE
;
822 TmpTokenSpaceBufferCount
= mPcdDatabase
.PeiDb
->ExTokenCount
+ mPcdDatabase
.DxeDb
->ExTokenCount
;
823 TmpTokenSpaceBuffer
= (EFI_GUID
**)AllocateZeroPool(TmpTokenSpaceBufferCount
* sizeof (EFI_GUID
*));
826 // Initialized the Callback Function Table
828 mCallbackFnTable
= AllocateZeroPool (mPcdTotalTokenCount
* sizeof (LIST_ENTRY
));
829 ASSERT(mCallbackFnTable
!= NULL
);
832 // EBC compiler is very choosy. It may report warning about comparison
833 // between UINTN and 0 . So we add 1 in each size of the
836 for (Index
= 0; Index
+ 1 < mPcdTotalTokenCount
+ 1; Index
++) {
837 InitializeListHead (&mCallbackFnTable
[Index
]);
842 Get Variable which contains HII type PCD entry.
844 @param VariableGuid Variable's guid
845 @param VariableName Variable's unicode name string
846 @param VariableData Variable's data pointer,
847 @param VariableSize Variable's size.
849 @return the status of gRT->GetVariable
853 IN EFI_GUID
*VariableGuid
,
854 IN UINT16
*VariableName
,
855 OUT UINT8
**VariableData
,
856 OUT UINTN
*VariableSize
867 // Firstly get the real size of HII variable
869 Status
= gRT
->GetVariable (
870 (UINT16
*)VariableName
,
878 // Allocate buffer to hold whole variable data according to variable size.
880 if (Status
== EFI_BUFFER_TOO_SMALL
) {
881 Buffer
= (UINT8
*) AllocatePool (Size
);
883 ASSERT (Buffer
!= NULL
);
885 Status
= gRT
->GetVariable (
893 ASSERT (Status
== EFI_SUCCESS
);
894 *VariableData
= Buffer
;
895 *VariableSize
= Size
;
898 // Use Default Data only when variable is not found.
899 // For other error status, correct data can't be got, and trig ASSERT().
901 ASSERT (Status
== EFI_NOT_FOUND
);
908 Find the local token number according to system SKU ID.
910 @param LocalTokenNumber PCD token number
911 @param Size The size of PCD entry.
912 @param IsPeiDb If TRUE, the PCD entry is initialized in PEI phase.
913 If False, the PCD entry is initialized in DXE phase.
915 @return Token number according to system SKU ID.
919 GetSkuEnabledTokenNumber (
920 UINT32 LocalTokenNumber
,
932 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0);
934 PcdDb
= IsPeiDb
? (UINT8
*) mPcdDatabase
.PeiDb
: (UINT8
*) mPcdDatabase
.DxeDb
;
936 SkuHead
= (SKU_HEAD
*) (PcdDb
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
937 Value
= (UINT8
*) (PcdDb
+ SkuHead
->SkuDataStartOffset
);
939 SkuIdTable
= (SKU_ID
*)(PcdDb
+ SkuHead
->SkuIdTableOffset
);
941 // Find the current system's SKU ID entry in SKU ID table.
944 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
945 if (mPcdDatabase
.PeiDb
->SystemSkuId
== SkuIdTable
[Index
+ 1]) {
952 // Find the default SKU ID entry in SKU ID table.
956 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
957 if (0 == SkuIdTable
[Index
+ 1]) {
962 ASSERT (Index
< SkuIdTable
[0]);
964 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
966 Value
= (UINT8
*) &(((VPD_HEAD
*) Value
)[Index
]);
967 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_VPD
);
970 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
971 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_HII
);
973 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
974 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[Index
]);
975 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_HII
| PCD_TYPE_STRING
);
977 case PCD_TYPE_STRING
:
978 Value
= (UINT8
*) &(((STRING_HEAD
*) Value
)[Index
]);
979 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_STRING
);
982 Value
+= Size
* Index
;
983 return (UINT32
) ((Value
- PcdDb
) | PCD_TYPE_DATA
);
996 Invoke the callback function when dynamic PCD entry was set, if this PCD entry
997 has registered callback function.
999 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx
1001 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type
1003 @param TokenNumber PCD token number generated by build tools.
1004 @param Data Value want to be set for this PCD entry
1005 @param Size The size of value
1009 InvokeCallbackOnSet (
1010 UINT32 ExTokenNumber
,
1011 CONST EFI_GUID
*Guid
, OPTIONAL
1017 CALLBACK_FN_ENTRY
*FnTableEntry
;
1018 LIST_ENTRY
*ListHead
;
1019 LIST_ENTRY
*ListNode
;
1022 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
1023 // We have to decrement TokenNumber by 1 to make it usable
1024 // as the array index of mCallbackFnTable[].
1026 ListHead
= &mCallbackFnTable
[TokenNumber
- 1];
1027 ListNode
= GetFirstNode (ListHead
);
1029 while (ListNode
!= ListHead
) {
1030 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE (ListNode
, CALLBACK_FN_ENTRY
, Node
);
1032 FnTableEntry
->CallbackFn(Guid
,
1033 (Guid
== NULL
) ? TokenNumber
: ExTokenNumber
,
1037 ListNode
= GetNextNode (ListHead
, ListNode
);
1045 Wrapper function for setting non-pointer type value for a PCD entry.
1047 @param TokenNumber Pcd token number autogenerated by build tools.
1048 @param Data Value want to be set for PCD entry
1049 @param Size Size of value.
1051 @return status of SetWorker.
1056 IN UINTN TokenNumber
,
1061 return SetWorker (TokenNumber
, Data
, &Size
, FALSE
);
1066 Set value for an PCD entry
1068 @param TokenNumber Pcd token number autogenerated by build tools.
1069 @param Data Value want to be set for PCD entry
1070 @param Size Size of value.
1071 @param PtrType If TRUE, the type of PCD entry's value is Pointer.
1072 If False, the type of PCD entry's value is not Pointer.
1074 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
1075 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.
1076 @retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.
1077 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
1078 range of UINT8, UINT16, UINT32, UINT64
1079 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.
1083 IN UINTN TokenNumber
,
1090 UINT32 LocalTokenNumber
;
1091 EFI_GUID
*GuidTable
;
1095 UINTN VariableOffset
;
1097 VARIABLE_HEAD
*VariableHead
;
1102 UINTN TmpTokenNumber
;
1105 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
1106 // We have to decrement TokenNumber by 1 to make it usable
1107 // as the array index.
1111 TmpTokenNumber
= TokenNumber
;
1114 // EBC compiler is very choosy. It may report warning about comparison
1115 // between UINTN and 0 . So we add 1 in each size of the
1118 ASSERT (TokenNumber
+ 1 < mPcdTotalTokenCount
+ 1);
1122 // Get MaxSize first, then check new size with max buffer size.
1124 GetPtrTypeSize (TokenNumber
, &MaxSize
);
1125 if (*Size
> MaxSize
) {
1127 return EFI_INVALID_PARAMETER
;
1130 if (*Size
!= DxePcdGetSize (TokenNumber
+ 1)) {
1131 return EFI_INVALID_PARAMETER
;
1136 // EBC compiler is very choosy. It may report warning about comparison
1137 // between UINTN and 0 . So we add 1 in each size of the
1140 if ((TokenNumber
+ 1 < mPeiNexTokenCount
+ 1) ||
1141 (TokenNumber
+ 1 >= mPeiLocalTokenCount
+ 1 && TokenNumber
+ 1 < (mPeiLocalTokenCount
+ mDxeNexTokenCount
+ 1))) {
1142 InvokeCallbackOnSet (0, NULL
, TokenNumber
+ 1, Data
, *Size
);
1146 // Aquire lock to prevent reentrance from TPL_CALLBACK level
1148 EfiAcquireLock (&mPcdDatabaseLock
);
1151 // EBC compiler is very choosy. It may report warning about comparison
1152 // between UINTN and 0 . So we add 1 in each size of the
1155 IsPeiDb
= (BOOLEAN
) ((TokenNumber
+ 1 < mPeiLocalTokenCount
+ 1) ? TRUE
: FALSE
);
1157 LocalTokenNumber
= GetLocalTokenNumber (IsPeiDb
, TokenNumber
+ 1);
1159 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
1161 PcdDb
= IsPeiDb
? ((UINT8
*) mPcdDatabase
.PeiDb
) : ((UINT8
*) mPcdDatabase
.DxeDb
);
1164 StringTable
= (UINT8
*) ((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->StringTableOffset
);
1166 StringTable
= (UINT8
*) ((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->StringTableOffset
);
1170 InternalData
= PcdDb
+ Offset
;
1172 switch (LocalTokenNumber
& PCD_TYPE_ALL_SET
) {
1175 Status
= EFI_INVALID_PARAMETER
;
1178 case PCD_TYPE_STRING
:
1179 if (SetPtrTypeSize (TmpTokenNumber
, Size
)) {
1180 CopyMem (StringTable
+ *((STRING_HEAD
*)InternalData
), Data
, *Size
);
1181 Status
= EFI_SUCCESS
;
1183 Status
= EFI_INVALID_PARAMETER
;
1187 case PCD_TYPE_HII
|PCD_TYPE_STRING
:
1190 if (!SetPtrTypeSize (TmpTokenNumber
, Size
)) {
1191 Status
= EFI_INVALID_PARAMETER
;
1197 GuidTable
= (EFI_GUID
*) ((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
);
1199 GuidTable
= (EFI_GUID
*) ((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
);
1202 VariableHead
= (VARIABLE_HEAD
*) (PcdDb
+ Offset
);
1204 Guid
= GuidTable
+ VariableHead
->GuidTableIndex
;
1205 Name
= (UINT16
*) (StringTable
+ VariableHead
->StringIndex
);
1206 VariableOffset
= VariableHead
->Offset
;
1207 Status
= SetHiiVariable (Guid
, Name
, Data
, *Size
, VariableOffset
);
1209 if (EFI_NOT_FOUND
== Status
) {
1210 if ((LocalTokenNumber
& PCD_TYPE_ALL_SET
) == (PCD_TYPE_HII
|PCD_TYPE_STRING
)) {
1212 StringTable
+ *(STRING_HEAD
*)(PcdDb
+ VariableHead
->DefaultValueOffset
),
1217 CopyMem (PcdDb
+ VariableHead
->DefaultValueOffset
, Data
, *Size
);
1219 Status
= EFI_SUCCESS
;
1225 if (SetPtrTypeSize (TmpTokenNumber
, Size
)) {
1226 CopyMem (InternalData
, Data
, *Size
);
1227 Status
= EFI_SUCCESS
;
1229 Status
= EFI_INVALID_PARAMETER
;
1234 Status
= EFI_SUCCESS
;
1237 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
1240 case sizeof(UINT16
):
1241 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
1244 case sizeof(UINT32
):
1245 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
1248 case sizeof(UINT64
):
1249 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
1254 Status
= EFI_NOT_FOUND
;
1261 Status
= EFI_NOT_FOUND
;
1265 EfiReleaseLock (&mPcdDatabaseLock
);
1271 Wrapper function for get PCD value for dynamic-ex PCD.
1273 @param Guid Token space guid for dynamic-ex PCD.
1274 @param ExTokenNumber Token number for dynamic-ex PCD.
1275 @param GetSize The size of dynamic-ex PCD value.
1277 @return PCD entry in PCD database.
1282 IN CONST EFI_GUID
*Guid
,
1283 IN UINTN ExTokenNumber
,
1287 return GetWorker(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
), GetSize
);
1291 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.
1293 @param ExTokenNumber Token number for dynamic-ex PCD.
1294 @param Guid Token space guid for dynamic-ex PCD.
1295 @param Data Value want to be set.
1296 @param SetSize The size of value.
1298 @return status of ExSetWorker().
1303 IN UINTN ExTokenNumber
,
1304 IN CONST EFI_GUID
*Guid
,
1309 return ExSetWorker (ExTokenNumber
, Guid
, Data
, &SetSize
, FALSE
);
1313 Set value for a dynamic-ex PCD entry.
1315 This routine find the local token number according to dynamic-ex PCD's token
1316 space guid and token number firstly, and invoke callback function if this PCD
1317 entry registered callback function. Finally, invoken general SetWorker to set
1320 @param ExTokenNumber Dynamic-ex PCD token number.
1321 @param Guid Token space guid for dynamic-ex PCD.
1322 @param Data PCD value want to be set
1323 @param SetSize Size of value.
1324 @param PtrType If TRUE, this PCD entry is pointer type.
1325 If FALSE, this PCD entry is not pointer type.
1327 @return status of SetWorker().
1332 IN UINTN ExTokenNumber
,
1333 IN CONST EFI_GUID
*Guid
,
1335 IN OUT UINTN
*SetSize
,
1341 TokenNumber
= GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
);
1343 InvokeCallbackOnSet ((UINT32
) ExTokenNumber
, Guid
, TokenNumber
, Data
, *SetSize
);
1345 return SetWorker (TokenNumber
, Data
, SetSize
, PtrType
);
1350 Set value for HII-type PCD.
1352 A HII-type PCD's value is stored in a variable. Setting/Getting the value of
1353 HII-type PCD is to visit this variable.
1355 @param VariableGuid Guid of variable which stored value of a HII-type PCD.
1356 @param VariableName Unicode name of variable which stored value of a HII-type PCD.
1357 @param Data Value want to be set.
1358 @param DataSize Size of value
1359 @param Offset Value offset of HII-type PCD in variable.
1361 @return status of GetVariable()/SetVariable().
1366 IN EFI_GUID
*VariableGuid
,
1367 IN UINT16
*VariableName
,
1368 IN CONST VOID
*Data
,
1383 // Try to get original variable size information.
1385 Status
= gRT
->GetVariable (
1386 (UINT16
*)VariableName
,
1393 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1395 // Patch new PCD's value to offset in given HII variable.
1397 if (Size
>= (DataSize
+ Offset
)) {
1400 SetSize
= DataSize
+ Offset
;
1402 Buffer
= AllocatePool (SetSize
);
1403 ASSERT (Buffer
!= NULL
);
1405 Status
= gRT
->GetVariable (
1413 ASSERT_EFI_ERROR (Status
);
1415 CopyMem ((UINT8
*)Buffer
+ Offset
, Data
, DataSize
);
1417 Status
= gRT
->SetVariable (
1427 } else if (Status
== EFI_NOT_FOUND
) {
1429 // If variable does not exist, a new variable need to be created.
1432 Size
= Offset
+ DataSize
;
1434 Buffer
= AllocateZeroPool (Size
);
1435 ASSERT (Buffer
!= NULL
);
1437 CopyMem ((UINT8
*)Buffer
+ Offset
, Data
, DataSize
);
1439 Status
= gRT
->SetVariable (
1442 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1452 // If we drop to here, the value is failed to be written in to variable area
1453 // So, we will save the data in the PCD Database's volatile area.
1459 Get Token Number according to dynamic-ex PCD's {token space guid:token number}
1461 A dynamic-ex type PCD, developer must provide pair of token space guid: token number
1462 in DEC file. PCD database maintain a mapping table that translate pair of {token
1463 space guid: token number} to Token Number.
1465 @param Guid Token space guid for dynamic-ex PCD entry.
1466 @param ExTokenNumber Dynamic-ex PCD token number.
1468 @return Token Number for dynamic-ex PCD.
1472 GetExPcdTokenNumber (
1473 IN CONST EFI_GUID
*Guid
,
1474 IN UINT32 ExTokenNumber
1478 DYNAMICEX_MAPPING
*ExMap
;
1479 EFI_GUID
*GuidTable
;
1480 EFI_GUID
*MatchGuid
;
1483 if (!mPeiDatabaseEmpty
) {
1484 ExMap
= (DYNAMICEX_MAPPING
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->ExMapTableOffset
);
1485 GuidTable
= (EFI_GUID
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->GuidTableOffset
);
1487 MatchGuid
= ScanGuid (GuidTable
, mPeiGuidTableSize
, Guid
);
1489 if (MatchGuid
!= NULL
) {
1491 MatchGuidIdx
= MatchGuid
- GuidTable
;
1493 for (Index
= 0; Index
< mPeiExMapppingTableSize
; Index
++) {
1494 if ((ExTokenNumber
== ExMap
[Index
].ExTokenNumber
) &&
1495 (MatchGuidIdx
== ExMap
[Index
].ExGuidIndex
)) {
1496 return ExMap
[Index
].TokenNumber
;
1502 ExMap
= (DYNAMICEX_MAPPING
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->ExMapTableOffset
);
1503 GuidTable
= (EFI_GUID
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->GuidTableOffset
);
1505 MatchGuid
= ScanGuid (GuidTable
, mDxeGuidTableSize
, Guid
);
1507 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
1508 // error in the BUILD system.
1510 ASSERT (MatchGuid
!= NULL
);
1512 MatchGuidIdx
= MatchGuid
- GuidTable
;
1514 for (Index
= 0; Index
< mDxeExMapppingTableSize
; Index
++) {
1515 if ((ExTokenNumber
== ExMap
[Index
].ExTokenNumber
) &&
1516 (MatchGuidIdx
== ExMap
[Index
].ExGuidIndex
)) {
1517 return ExMap
[Index
].TokenNumber
;
1527 Get SKU ID table from PCD database.
1529 @param LocalTokenNumberTableIdx Index of local token number in token number table.
1530 @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
1531 If FALSE, the pcd entry is initialized in DXE phase.
1532 @return Pointer to SKU ID array table
1537 IN UINTN LocalTokenNumberTableIdx
,
1542 UINTN LocalTokenNumber
;
1546 LocalTokenNumber
= *((UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
) + LocalTokenNumberTableIdx
);
1547 Database
= (UINT8
*) mPcdDatabase
.PeiDb
;
1549 LocalTokenNumber
= *((UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
) + LocalTokenNumberTableIdx
);
1550 Database
= (UINT8
*) mPcdDatabase
.DxeDb
;
1553 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) != 0);
1555 SkuHead
= (SKU_HEAD
*) ((UINT8
*)Database
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
1557 return (SKU_ID
*) (Database
+ SkuHead
->SkuIdTableOffset
);
1562 Wrapper function of getting index of PCD entry in size table.
1564 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1565 @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
1566 If FALSE, the pcd entry is initialized in DXE phase.
1568 @return index of PCD entry in size table.
1572 IN UINTN LocalTokenNumberTableIdx
,
1576 UINT32
*LocalTokenNumberTable
;
1577 UINTN LocalTokenNumber
;
1583 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
);
1585 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
1590 for (Index
= 0; Index
< LocalTokenNumberTableIdx
; Index
++) {
1591 LocalTokenNumber
= LocalTokenNumberTable
[Index
];
1593 if ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
) {
1595 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1598 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1600 // We have only two entry for VPD enabled PCD entry:
1603 // Current size is equal to MAX size.
1607 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1609 // We have only two entry for Non-Sku enabled PCD entry:
1616 // We have these entry for SKU enabled PCD entry
1618 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1620 SkuIdTable
= GetSkuIdArray (Index
, IsPeiDb
);
1621 SizeTableIdx
+= (UINTN
)*SkuIdTable
+ 1;
1628 return SizeTableIdx
;
1632 Get size of POINTER type PCD value.
1634 @param LocalTokenNumberTableIdx Index of local token number in local token number table.
1635 @param MaxSize Maxmium size of POINTER type PCD value.
1637 @return size of POINTER type PCD value.
1642 IN UINTN LocalTokenNumberTableIdx
,
1647 UINTN LocalTokenNumber
;
1649 SIZE_INFO
*SizeTable
;
1652 UINT32
*LocalTokenNumberTable
;
1654 // EBC compiler is very choosy. It may report warning about comparison
1655 // between UINTN and 0 . So we add 1 in each size of the
1657 IsPeiDb
= (BOOLEAN
) (LocalTokenNumberTableIdx
+ 1 < mPeiLocalTokenCount
+ 1);
1661 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
);
1662 SizeTable
= (SIZE_INFO
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->SizeTableOffset
);
1664 LocalTokenNumberTableIdx
-= mPeiLocalTokenCount
;
1665 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
1666 SizeTable
= (SIZE_INFO
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->SizeTableOffset
);
1669 LocalTokenNumber
= LocalTokenNumberTable
[LocalTokenNumberTableIdx
];
1671 ASSERT ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
);
1673 SizeTableIdx
= GetSizeTableIndex (LocalTokenNumberTableIdx
, IsPeiDb
);
1675 *MaxSize
= SizeTable
[SizeTableIdx
];
1677 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1680 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1682 // We have only two entry for VPD enabled PCD entry:
1685 // We consider current size is equal to MAX size.
1689 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1691 // We have only two entry for Non-Sku enabled PCD entry:
1695 return SizeTable
[SizeTableIdx
+ 1];
1698 // We have these entry for SKU enabled PCD entry
1700 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1702 SkuIdTable
= GetSkuIdArray (LocalTokenNumberTableIdx
, IsPeiDb
);
1703 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
1704 if (SkuIdTable
[1 + Index
] == mPcdDatabase
.PeiDb
->SystemSkuId
) {
1705 return SizeTable
[SizeTableIdx
+ 1 + Index
];
1708 return SizeTable
[SizeTableIdx
+ 1];
1714 Set size of POINTER type PCD value. The size should not exceed the maximum size
1717 @param LocalTokenNumberTableIdx Index of local token number in local token number table.
1718 @param CurrentSize Size of POINTER type PCD value.
1720 @retval TRUE Success to set size of PCD value.
1721 @retval FALSE Fail to set size of PCD value.
1725 IN UINTN LocalTokenNumberTableIdx
,
1726 IN OUT UINTN
*CurrentSize
1730 UINTN LocalTokenNumber
;
1732 SIZE_INFO
*SizeTable
;
1736 UINT32
*LocalTokenNumberTable
;
1739 // EBC compiler is very choosy. It may report warning about comparison
1740 // between UINTN and 0 . So we add 1 in each size of the
1743 IsPeiDb
= (BOOLEAN
) (LocalTokenNumberTableIdx
+ 1 < mPeiLocalTokenCount
+ 1);
1746 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->LocalTokenNumberTableOffset
);
1747 SizeTable
= (SIZE_INFO
*)((UINT8
*)mPcdDatabase
.PeiDb
+ mPcdDatabase
.PeiDb
->SizeTableOffset
);
1749 LocalTokenNumberTableIdx
-= mPeiLocalTokenCount
;
1750 LocalTokenNumberTable
= (UINT32
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->LocalTokenNumberTableOffset
);
1751 SizeTable
= (SIZE_INFO
*)((UINT8
*)mPcdDatabase
.DxeDb
+ mPcdDatabase
.DxeDb
->SizeTableOffset
);
1754 LocalTokenNumber
= LocalTokenNumberTable
[LocalTokenNumberTableIdx
];
1756 ASSERT ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
);
1758 SizeTableIdx
= GetSizeTableIndex (LocalTokenNumberTableIdx
, IsPeiDb
);
1760 MaxSize
= SizeTable
[SizeTableIdx
];
1762 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1765 if ((LocalTokenNumber
& PCD_TYPE_VPD
) != 0) {
1767 // We shouldn't come here as we don't support SET for VPD
1772 if ((*CurrentSize
> MaxSize
) ||
1773 (*CurrentSize
== MAX_ADDRESS
)) {
1774 *CurrentSize
= MaxSize
;
1778 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
1780 // We have only two entry for Non-Sku enabled PCD entry:
1784 SizeTable
[SizeTableIdx
+ 1] = (SIZE_INFO
) *CurrentSize
;
1788 // We have these entry for SKU enabled PCD entry
1790 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1792 SkuIdTable
= GetSkuIdArray (LocalTokenNumberTableIdx
, IsPeiDb
);
1793 for (Index
= 0; Index
< SkuIdTable
[0]; Index
++) {
1794 if (SkuIdTable
[1 + Index
] == mPcdDatabase
.PeiDb
->SystemSkuId
) {
1795 SizeTable
[SizeTableIdx
+ 1 + Index
] = (SIZE_INFO
) *CurrentSize
;
1799 SizeTable
[SizeTableIdx
+ 1] = (SIZE_INFO
) *CurrentSize
;