3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 PCD_PPI mPcdPpiInstance
= {
53 PeiRegisterCallBackOnSet
,
54 PcdUnRegisterCallBackOnSet
,
56 PeiPcdGetNextTokenSpace
61 STATIC EFI_PEI_PPI_DESCRIPTOR mPpiPCD
= {
62 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
72 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
73 IN EFI_PEI_SERVICES
**PeiServices
80 Status
= PeiServicesInstallPpi (&mPpiPCD
);
82 ASSERT_EFI_ERROR (Status
);
94 GetPcdDatabase()->Init
.SystemSkuId
= (SKU_ID
) SkuId
;
107 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
118 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
129 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
140 return ReadUnaligned64 (GetWorker (TokenNumber
, sizeof (UINT64
)));
151 return GetWorker (TokenNumber
, 0);
162 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
173 PEI_PCD_DATABASE
*PeiPcdDb
;
178 // If DebugAssertEnabled is TRUE, we still need to provide the GET size
179 // function as GetWorker and SetWoker need this function to do ASSERT.
181 if ((!FeaturePcdGet(PcdPeiPcdDatabaseGetSizeEnabled
)) &&
182 (!DebugAssertEnabled ())) {
186 PeiPcdDb
= GetPcdDatabase ();
188 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
189 // We have to decrement TokenNumber by 1 to make it usable
190 // as the array index.
194 // EBC compiler is very choosy. It may report warning about comparison
195 // between UINTN and 0 . So we add 1 in each size of the
197 ASSERT (TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1);
199 Size
= (PeiPcdDb
->Init
.LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
203 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
205 return GetPtrTypeSize (TokenNumber
, &MaxSize
, PeiPcdDb
);
217 IN CONST EFI_GUID
*Guid
,
218 IN UINTN ExTokenNumber
221 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof (UINT8
)));
229 IN CONST EFI_GUID
*Guid
,
230 IN UINTN ExTokenNumber
233 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof (UINT16
)));
241 IN CONST EFI_GUID
*Guid
,
242 IN UINTN ExTokenNumber
245 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof (UINT32
)));
253 IN CONST EFI_GUID
*Guid
,
254 IN UINTN ExTokenNumber
257 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof (UINT64
)));
265 IN CONST EFI_GUID
*Guid
,
266 IN UINTN ExTokenNumber
269 return ExGetWorker (Guid
, ExTokenNumber
, 0);
277 IN CONST EFI_GUID
*Guid
,
278 IN UINTN ExTokenNumber
281 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof (BOOLEAN
)));
289 IN CONST EFI_GUID
*Guid
,
290 IN UINTN ExTokenNumber
293 if ((!FeaturePcdGet (PcdPeiPcdDatabaseGetSizeEnabled
)) || !FeaturePcdGet (PcdPeiPcdDatabaseExEnabled
)) {
297 return PeiPcdGetSize (GetExPcdTokenNumber (Guid
, ExTokenNumber
));
305 IN UINTN TokenNumber
,
309 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
317 IN UINTN TokenNumber
,
321 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
329 IN UINTN TokenNumber
,
333 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
341 IN UINTN TokenNumber
,
345 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
352 IN UINTN TokenNumber
,
353 IN OUT UINTN
*SizeOfBuffer
,
357 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
365 IN UINTN TokenNumber
,
369 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
377 IN CONST EFI_GUID
*Guid
,
378 IN UINTN ExTokenNumber
,
382 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
390 IN CONST EFI_GUID
*Guid
,
391 IN UINTN ExTokenNumber
,
395 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
403 IN CONST EFI_GUID
*Guid
,
404 IN UINTN ExTokenNumber
,
408 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
416 IN CONST EFI_GUID
*Guid
,
417 IN UINTN ExTokenNumber
,
421 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
429 IN CONST EFI_GUID
*Guid
,
430 IN UINTN ExTokenNumber
,
431 IN UINTN
*SizeOfBuffer
,
435 return ExSetWorker (ExTokenNumber
, Guid
, Value
, SizeOfBuffer
, TRUE
);
443 IN CONST EFI_GUID
*Guid
,
444 IN UINTN ExTokenNumber
,
448 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
456 PeiRegisterCallBackOnSet (
457 IN CONST EFI_GUID
*Guid
, OPTIONAL
458 IN UINTN ExTokenNumber
,
459 IN PCD_PPI_CALLBACK CallBackFunction
462 if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled
)) {
463 return EFI_UNSUPPORTED
;
466 ASSERT (CallBackFunction
!= NULL
);
468 return PeiRegisterCallBackWorker (ExTokenNumber
, Guid
, CallBackFunction
, TRUE
);
475 PcdUnRegisterCallBackOnSet (
476 IN CONST EFI_GUID
*Guid
, OPTIONAL
477 IN UINTN ExTokenNumber
,
478 IN PCD_PPI_CALLBACK CallBackFunction
481 if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled
)) {
482 return EFI_UNSUPPORTED
;
485 ASSERT (CallBackFunction
!= NULL
);
487 return PeiRegisterCallBackWorker (ExTokenNumber
, Guid
, CallBackFunction
, FALSE
);
495 IN CONST EFI_GUID
*Guid
, OPTIONAL
496 IN OUT UINTN
*TokenNumber
500 PEI_PCD_DATABASE
*PeiPcdDb
;
502 DYNAMICEX_MAPPING
*ExMapTable
;
505 BOOLEAN PeiExMapTableEmpty
;
507 if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled
)) {
508 return EFI_UNSUPPORTED
;
511 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
514 if (*TokenNumber
> PEI_NEX_TOKEN_NUMBER
) {
515 return EFI_NOT_FOUND
;
518 if (*TokenNumber
> PEI_NEX_TOKEN_NUMBER
) {
519 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
523 if (PeiExMapTableEmpty
) {
524 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
529 // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
533 PeiPcdDb
= GetPcdDatabase ();
535 MatchGuid
= ScanGuid (PeiPcdDb
->Init
.GuidTable
, sizeof(PeiPcdDb
->Init
.GuidTable
), Guid
);
537 if (MatchGuid
== NULL
) {
538 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
539 return EFI_NOT_FOUND
;
542 GuidTableIdx
= MatchGuid
- PeiPcdDb
->Init
.GuidTable
;
544 ExMapTable
= PeiPcdDb
->Init
.ExMapTable
;
548 // Locate the GUID in ExMapTable first.
550 for (i
= 0; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
551 if (ExMapTable
[i
].ExGuidIndex
== GuidTableIdx
) {
558 if (*TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
559 *TokenNumber
= ExMapTable
[i
].ExTokenNumber
;
563 for ( ; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
564 if (ExMapTable
[i
].ExTokenNumber
== *TokenNumber
) {
566 if (i
== PEI_EXMAPPING_TABLE_SIZE
) {
568 // Exceed the length of ExMap Table
570 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
573 if (ExMapTable
[i
].ExGuidIndex
== GuidTableIdx
) {
574 *TokenNumber
= ExMapTable
[i
].ExTokenNumber
;
577 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
582 return EFI_NOT_FOUND
;
586 return EFI_NOT_FOUND
;
593 PeiPcdGetNextTokenSpace (
594 IN OUT CONST EFI_GUID
**Guid
599 PEI_PCD_DATABASE
*PeiPcdDb
;
600 DYNAMICEX_MAPPING
*ExMapTable
;
603 BOOLEAN PeiExMapTableEmpty
;
605 if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled
)) {
606 return EFI_UNSUPPORTED
;
609 ASSERT (Guid
!= NULL
);
611 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
613 if (PeiExMapTableEmpty
) {
615 return EFI_NOT_FOUND
;
622 // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
626 PeiPcdDb
= GetPcdDatabase ();
628 ExMapTable
= PeiPcdDb
->Init
.ExMapTable
;
632 // return the first Token Space Guid.
634 *Guid
= &PeiPcdDb
->Init
.GuidTable
[ExMapTable
[0].ExGuidIndex
];
638 MatchGuid
= ScanGuid (PeiPcdDb
->Init
.GuidTable
, sizeof(PeiPcdDb
->Init
.GuidTable
), *Guid
);
640 if (MatchGuid
== NULL
) {
641 return EFI_NOT_FOUND
;
644 GuidTableIdx
= MatchGuid
- PeiPcdDb
->Init
.GuidTable
;
647 for (i
= 0; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
648 if (ExMapTable
[i
].ExGuidIndex
== GuidTableIdx
) {
656 for ( ; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++ ) {
657 if (ExMapTable
[i
].ExGuidIndex
!= GuidTableIdx
) {
658 *Guid
= &PeiPcdDb
->Init
.GuidTable
[ExMapTable
[i
].ExGuidIndex
];
666 return EFI_NOT_FOUND
;
672 IN UINTN LocalTokenNumberTableIdx
,
674 IN PEI_PCD_DATABASE
*Database
678 UINTN LocalTokenNumber
;
680 SIZE_INFO
*SizeTable
;
683 SizeTableIdx
= GetSizeTableIndex (LocalTokenNumberTableIdx
, Database
);
685 LocalTokenNumber
= Database
->Init
.LocalTokenNumberTable
[LocalTokenNumberTableIdx
];
687 ASSERT ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
);
689 SizeTable
= Database
->Init
.SizeTable
;
691 *MaxSize
= SizeTable
[SizeTableIdx
];
693 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
696 if (LocalTokenNumber
& PCD_TYPE_VPD
) {
698 // We have only one entry for VPD enabled PCD entry:
700 // We consider current size is equal to MAX size.
704 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
706 // We have only two entry for Non-Sku enabled PCD entry:
710 return SizeTable
[SizeTableIdx
+ 1];
713 // We have these entry for SKU enabled PCD entry
715 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
717 SkuIdTable
= GetSkuIdArray (LocalTokenNumberTableIdx
, Database
);
718 for (i
= 0; i
< SkuIdTable
[0]; i
++) {
719 if (SkuIdTable
[1 + i
] == Database
->Init
.SystemSkuId
) {
720 return SizeTable
[SizeTableIdx
+ 1 + i
];
723 return SizeTable
[SizeTableIdx
+ 1];
732 IN UINTN LocalTokenNumberTableIdx
,
733 IN OUT UINTN
*CurrentSize
,
734 IN PEI_PCD_DATABASE
*Database
738 UINTN LocalTokenNumber
;
740 SIZE_INFO
*SizeTable
;
744 SizeTableIdx
= GetSizeTableIndex (LocalTokenNumberTableIdx
, Database
);
746 LocalTokenNumber
= Database
->Init
.LocalTokenNumberTable
[LocalTokenNumberTableIdx
];
748 ASSERT ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
);
750 SizeTable
= Database
->Init
.SizeTable
;
752 MaxSize
= SizeTable
[SizeTableIdx
];
754 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
757 if (LocalTokenNumber
& PCD_TYPE_VPD
) {
759 // We shouldn't come here as we don't support SET for VPD
764 if ((*CurrentSize
> MaxSize
) ||
765 (*CurrentSize
== MAX_ADDRESS
)) {
766 *CurrentSize
= MaxSize
;
770 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
772 // We have only two entry for Non-Sku enabled PCD entry:
776 SizeTable
[SizeTableIdx
+ 1] = (SIZE_INFO
) *CurrentSize
;
780 // We have these entry for SKU enabled PCD entry
782 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
784 SkuIdTable
= GetSkuIdArray (LocalTokenNumberTableIdx
, Database
);
785 for (i
= 0; i
< SkuIdTable
[0]; i
++) {
786 if (SkuIdTable
[1 + i
] == Database
->Init
.SystemSkuId
) {
787 SizeTable
[SizeTableIdx
+ 1 + i
] = (SIZE_INFO
) *CurrentSize
;
791 SizeTable
[SizeTableIdx
+ 1] = (SIZE_INFO
) *CurrentSize
;