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.
18 // Include common header file for this module.
20 #include "CommonHeader.h"
25 PCD_PPI mPcdPpiInstance
= {
58 PeiRegisterCallBackOnSet
,
59 PcdUnRegisterCallBackOnSet
,
61 PeiPcdGetNextTokenSpace
66 STATIC EFI_PEI_PPI_DESCRIPTOR mPpiPCD
= {
67 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
77 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
78 IN EFI_PEI_SERVICES
**PeiServices
85 Status
= PeiServicesInstallPpi (&mPpiPCD
);
87 ASSERT_EFI_ERROR (Status
);
99 GetPcdDatabase()->Init
.SystemSkuId
= (SKU_ID
) SkuId
;
112 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
123 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
134 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
145 return ReadUnaligned64 (GetWorker (TokenNumber
, sizeof (UINT64
)));
156 return GetWorker (TokenNumber
, 0);
167 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
178 PEI_PCD_DATABASE
*PeiPcdDb
;
183 // If DebugAssertEnabled is TRUE, we still need to provide the GET size
184 // function as GetWorker and SetWoker need this function to do ASSERT.
186 if ((!FeaturePcdGet(PcdPeiPcdDatabaseGetSizeEnabled
)) &&
187 (!DebugAssertEnabled ())) {
191 PeiPcdDb
= GetPcdDatabase ();
193 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
194 // We have to decrement TokenNumber by 1 to make it usable
195 // as the array index.
199 // EBC compiler is very choosy. It may report warning about comparison
200 // between UINTN and 0 . So we add 1 in each size of the
202 ASSERT (TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1);
204 Size
= (PeiPcdDb
->Init
.LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
208 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
210 return GetPtrTypeSize (TokenNumber
, &MaxSize
, PeiPcdDb
);
222 IN CONST EFI_GUID
*Guid
,
223 IN UINTN ExTokenNumber
226 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof (UINT8
)));
234 IN CONST EFI_GUID
*Guid
,
235 IN UINTN ExTokenNumber
238 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof (UINT16
)));
246 IN CONST EFI_GUID
*Guid
,
247 IN UINTN ExTokenNumber
250 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof (UINT32
)));
258 IN CONST EFI_GUID
*Guid
,
259 IN UINTN ExTokenNumber
262 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof (UINT64
)));
270 IN CONST EFI_GUID
*Guid
,
271 IN UINTN ExTokenNumber
274 return ExGetWorker (Guid
, ExTokenNumber
, 0);
282 IN CONST EFI_GUID
*Guid
,
283 IN UINTN ExTokenNumber
286 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof (BOOLEAN
)));
294 IN CONST EFI_GUID
*Guid
,
295 IN UINTN ExTokenNumber
298 if ((!FeaturePcdGet (PcdPeiPcdDatabaseGetSizeEnabled
)) || !FeaturePcdGet (PcdPeiPcdDatabaseExEnabled
)) {
302 return PeiPcdGetSize (GetExPcdTokenNumber (Guid
, ExTokenNumber
));
310 IN UINTN TokenNumber
,
314 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
322 IN UINTN TokenNumber
,
326 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
334 IN UINTN TokenNumber
,
338 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
346 IN UINTN TokenNumber
,
350 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
357 IN UINTN TokenNumber
,
358 IN OUT UINTN
*SizeOfBuffer
,
362 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
370 IN UINTN TokenNumber
,
374 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
382 IN CONST EFI_GUID
*Guid
,
383 IN UINTN ExTokenNumber
,
387 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
395 IN CONST EFI_GUID
*Guid
,
396 IN UINTN ExTokenNumber
,
400 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
408 IN CONST EFI_GUID
*Guid
,
409 IN UINTN ExTokenNumber
,
413 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
421 IN CONST EFI_GUID
*Guid
,
422 IN UINTN ExTokenNumber
,
426 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
434 IN CONST EFI_GUID
*Guid
,
435 IN UINTN ExTokenNumber
,
436 IN UINTN
*SizeOfBuffer
,
440 return ExSetWorker (ExTokenNumber
, Guid
, Value
, SizeOfBuffer
, TRUE
);
448 IN CONST EFI_GUID
*Guid
,
449 IN UINTN ExTokenNumber
,
453 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
461 PeiRegisterCallBackOnSet (
462 IN CONST EFI_GUID
*Guid
, OPTIONAL
463 IN UINTN ExTokenNumber
,
464 IN PCD_PPI_CALLBACK CallBackFunction
467 if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled
)) {
468 return EFI_UNSUPPORTED
;
471 ASSERT (CallBackFunction
!= NULL
);
473 return PeiRegisterCallBackWorker (ExTokenNumber
, Guid
, CallBackFunction
, TRUE
);
480 PcdUnRegisterCallBackOnSet (
481 IN CONST EFI_GUID
*Guid
, OPTIONAL
482 IN UINTN ExTokenNumber
,
483 IN PCD_PPI_CALLBACK CallBackFunction
486 if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled
)) {
487 return EFI_UNSUPPORTED
;
490 ASSERT (CallBackFunction
!= NULL
);
492 return PeiRegisterCallBackWorker (ExTokenNumber
, Guid
, CallBackFunction
, FALSE
);
500 IN CONST EFI_GUID
*Guid
, OPTIONAL
501 IN OUT UINTN
*TokenNumber
505 PEI_PCD_DATABASE
*PeiPcdDb
;
507 DYNAMICEX_MAPPING
*ExMapTable
;
510 BOOLEAN PeiExMapTableEmpty
;
512 if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled
)) {
513 return EFI_UNSUPPORTED
;
516 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
519 if (*TokenNumber
> PEI_NEX_TOKEN_NUMBER
) {
520 return EFI_NOT_FOUND
;
523 if (*TokenNumber
> PEI_NEX_TOKEN_NUMBER
) {
524 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
528 if (PeiExMapTableEmpty
) {
529 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
534 // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
538 PeiPcdDb
= GetPcdDatabase ();
540 MatchGuid
= ScanGuid (PeiPcdDb
->Init
.GuidTable
, sizeof(PeiPcdDb
->Init
.GuidTable
), Guid
);
542 if (MatchGuid
== NULL
) {
543 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
544 return EFI_NOT_FOUND
;
547 GuidTableIdx
= MatchGuid
- PeiPcdDb
->Init
.GuidTable
;
549 ExMapTable
= PeiPcdDb
->Init
.ExMapTable
;
553 // Locate the GUID in ExMapTable first.
555 for (i
= 0; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
556 if (ExMapTable
[i
].ExGuidIndex
== GuidTableIdx
) {
563 if (*TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
564 *TokenNumber
= ExMapTable
[i
].ExTokenNumber
;
568 for ( ; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
569 if (ExMapTable
[i
].ExTokenNumber
== *TokenNumber
) {
571 if (i
== PEI_EXMAPPING_TABLE_SIZE
) {
573 // Exceed the length of ExMap Table
575 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
578 if (ExMapTable
[i
].ExGuidIndex
== GuidTableIdx
) {
579 *TokenNumber
= ExMapTable
[i
].ExTokenNumber
;
582 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
587 return EFI_NOT_FOUND
;
591 return EFI_NOT_FOUND
;
598 PeiPcdGetNextTokenSpace (
599 IN OUT CONST EFI_GUID
**Guid
604 PEI_PCD_DATABASE
*PeiPcdDb
;
605 DYNAMICEX_MAPPING
*ExMapTable
;
608 BOOLEAN PeiExMapTableEmpty
;
610 if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled
)) {
611 return EFI_UNSUPPORTED
;
614 ASSERT (Guid
!= NULL
);
616 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
618 if (PeiExMapTableEmpty
) {
620 return EFI_NOT_FOUND
;
627 // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
631 PeiPcdDb
= GetPcdDatabase ();
633 ExMapTable
= PeiPcdDb
->Init
.ExMapTable
;
637 // return the first Token Space Guid.
639 *Guid
= &PeiPcdDb
->Init
.GuidTable
[ExMapTable
[0].ExGuidIndex
];
643 MatchGuid
= ScanGuid (PeiPcdDb
->Init
.GuidTable
, sizeof(PeiPcdDb
->Init
.GuidTable
), *Guid
);
645 if (MatchGuid
== NULL
) {
646 return EFI_NOT_FOUND
;
649 GuidTableIdx
= MatchGuid
- PeiPcdDb
->Init
.GuidTable
;
652 for (i
= 0; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
653 if (ExMapTable
[i
].ExGuidIndex
== GuidTableIdx
) {
661 for ( ; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++ ) {
662 if (ExMapTable
[i
].ExGuidIndex
!= GuidTableIdx
) {
663 *Guid
= &PeiPcdDb
->Init
.GuidTable
[ExMapTable
[i
].ExGuidIndex
];
671 return EFI_NOT_FOUND
;
677 IN UINTN LocalTokenNumberTableIdx
,
679 IN PEI_PCD_DATABASE
*Database
683 UINTN LocalTokenNumber
;
685 SIZE_INFO
*SizeTable
;
688 SizeTableIdx
= GetSizeTableIndex (LocalTokenNumberTableIdx
, Database
);
690 LocalTokenNumber
= Database
->Init
.LocalTokenNumberTable
[LocalTokenNumberTableIdx
];
692 ASSERT ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
);
694 SizeTable
= Database
->Init
.SizeTable
;
696 *MaxSize
= SizeTable
[SizeTableIdx
];
698 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
701 if (LocalTokenNumber
& PCD_TYPE_VPD
) {
703 // We have only one entry for VPD enabled PCD entry:
705 // We consider current size is equal to MAX size.
709 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
711 // We have only two entry for Non-Sku enabled PCD entry:
715 return SizeTable
[SizeTableIdx
+ 1];
718 // We have these entry for SKU enabled PCD entry
720 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
722 SkuIdTable
= GetSkuIdArray (LocalTokenNumberTableIdx
, Database
);
723 for (i
= 0; i
< SkuIdTable
[0]; i
++) {
724 if (SkuIdTable
[1 + i
] == Database
->Init
.SystemSkuId
) {
725 return SizeTable
[SizeTableIdx
+ 1 + i
];
728 return SizeTable
[SizeTableIdx
+ 1];
737 IN UINTN LocalTokenNumberTableIdx
,
738 IN OUT UINTN
*CurrentSize
,
739 IN PEI_PCD_DATABASE
*Database
743 UINTN LocalTokenNumber
;
745 SIZE_INFO
*SizeTable
;
749 SizeTableIdx
= GetSizeTableIndex (LocalTokenNumberTableIdx
, Database
);
751 LocalTokenNumber
= Database
->Init
.LocalTokenNumberTable
[LocalTokenNumberTableIdx
];
753 ASSERT ((LocalTokenNumber
& PCD_DATUM_TYPE_ALL_SET
) == PCD_DATUM_TYPE_POINTER
);
755 SizeTable
= Database
->Init
.SizeTable
;
757 MaxSize
= SizeTable
[SizeTableIdx
];
759 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
762 if (LocalTokenNumber
& PCD_TYPE_VPD
) {
764 // We shouldn't come here as we don't support SET for VPD
769 if ((*CurrentSize
> MaxSize
) ||
770 (*CurrentSize
== MAX_ADDRESS
)) {
771 *CurrentSize
= MaxSize
;
775 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0) {
777 // We have only two entry for Non-Sku enabled PCD entry:
781 SizeTable
[SizeTableIdx
+ 1] = (SIZE_INFO
) *CurrentSize
;
785 // We have these entry for SKU enabled PCD entry
787 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
789 SkuIdTable
= GetSkuIdArray (LocalTokenNumberTableIdx
, Database
);
790 for (i
= 0; i
< SkuIdTable
[0]; i
++) {
791 if (SkuIdTable
[1 + i
] == Database
->Init
.SystemSkuId
) {
792 SizeTable
[SizeTableIdx
+ 1 + i
] = (SIZE_INFO
) *CurrentSize
;
796 SizeTable
[SizeTableIdx
+ 1] = (SIZE_INFO
) *CurrentSize
;