4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. 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.
21 PCD_PROTOCOL mPcdInstance
= {
54 DxeRegisterCallBackOnSet
,
55 DxeUnRegisterCallBackOnSet
,
57 DxePcdGetNextTokenSpace
62 // Static global to reduce the code size
64 static EFI_HANDLE NewHandle
= NULL
;
69 IN EFI_HANDLE ImageHandle
,
70 IN EFI_SYSTEM_TABLE
*SystemTable
76 // Make sure the Pcd Protocol is not already installed in the system
79 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gPcdProtocolGuid
);
81 BuildPcdDxeDataBase ();
84 // BugBug Check if PcdDatabase is already installed.
87 Status
= gBS
->InstallProtocolInterface (
94 ASSERT_EFI_ERROR (Status
);
107 mPcdDatabase
->PeiDb
.Init
.SystemSkuId
= (SKU_ID
) SkuId
;
120 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
131 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
142 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
153 return ReadUnaligned64(GetWorker (TokenNumber
, sizeof (UINT64
)));
164 return GetWorker (TokenNumber
, 0);
175 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
187 UINT32
*LocalTokenNumberTable
;
190 UINTN TmpTokenNumber
;
192 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
193 // We have to decrement TokenNumber by 1 to make it usable
194 // as the array index.
199 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
201 TmpTokenNumber
= TokenNumber
;
203 // EBC compiler is very choosy. It may report warning about comparison
204 // between UINTN and 0 . So we add 1 in each size of the
206 ASSERT (TokenNumber
+ 1 < PCD_TOTAL_TOKEN_NUMBER
+ 1);
208 // EBC compiler is very choosy. It may report warning about comparison
209 // between UINTN and 0 . So we add 1 in each size of the
211 IsPeiDb
= (BOOLEAN
) (TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1);
213 TokenNumber
= IsPeiDb
? TokenNumber
:
214 (TokenNumber
- PEI_LOCAL_TOKEN_NUMBER
);
216 LocalTokenNumberTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.LocalTokenNumberTable
217 : mPcdDatabase
->DxeDb
.Init
.LocalTokenNumberTable
;
219 Size
= (LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
223 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
225 return GetPtrTypeSize (TmpTokenNumber
, &MaxSize
);
237 IN CONST EFI_GUID
*Guid
,
238 IN UINTN ExTokenNumber
241 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT8
)));
249 IN CONST EFI_GUID
*Guid
,
250 IN UINTN ExTokenNumber
253 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT16
)));
261 IN CONST EFI_GUID
*Guid
,
262 IN UINTN ExTokenNumber
265 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT32
)));
273 IN CONST EFI_GUID
*Guid
,
274 IN UINTN ExTokenNumber
277 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT64
)));
285 IN CONST EFI_GUID
*Guid
,
286 IN UINTN ExTokenNumber
289 return ExGetWorker (Guid
, ExTokenNumber
, 0);
297 IN CONST EFI_GUID
*Guid
,
298 IN UINTN ExTokenNumber
301 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(BOOLEAN
)));
309 IN CONST EFI_GUID
*Guid
,
310 IN UINTN ExTokenNumber
313 return DxePcdGetSize(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
));
321 IN UINTN TokenNumber
,
325 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
333 IN UINTN TokenNumber
,
337 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
345 IN UINTN TokenNumber
,
349 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
357 IN UINTN TokenNumber
,
361 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
369 IN UINTN TokenNumber
,
370 IN OUT UINTN
*SizeOfBuffer
,
374 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
382 IN UINTN TokenNumber
,
386 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
394 IN CONST EFI_GUID
*Guid
,
395 IN UINTN ExTokenNumber
,
399 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
407 IN CONST EFI_GUID
*Guid
,
408 IN UINTN ExTokenNumber
,
412 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
420 IN CONST EFI_GUID
*Guid
,
421 IN UINTN ExTokenNumber
,
425 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
433 IN CONST EFI_GUID
*Guid
,
434 IN UINTN ExTokenNumber
,
438 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
446 IN CONST EFI_GUID
*Guid
,
447 IN UINTN ExTokenNumber
,
448 IN OUT UINTN
*SizeOfBuffer
,
452 return ExSetWorker(ExTokenNumber
, Guid
, Buffer
, SizeOfBuffer
, TRUE
);
460 IN CONST EFI_GUID
*Guid
,
461 IN UINTN ExTokenNumber
,
465 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
473 DxeRegisterCallBackOnSet (
474 IN UINTN TokenNumber
,
475 IN CONST EFI_GUID
*Guid
, OPTIONAL
476 IN PCD_PROTOCOL_CALLBACK CallBackFunction
479 ASSERT (CallBackFunction
!= NULL
);
481 return DxeRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
488 DxeUnRegisterCallBackOnSet (
489 IN UINTN TokenNumber
,
490 IN CONST EFI_GUID
*Guid
, OPTIONAL
491 IN PCD_PROTOCOL_CALLBACK CallBackFunction
494 ASSERT (CallBackFunction
!= NULL
);
496 return DxeUnRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
504 IN CONST EFI_GUID
*Guid
, OPTIONAL
505 IN OUT UINTN
*TokenNumber
510 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
511 return EFI_UNSUPPORTED
;
514 Status
= EFI_NOT_FOUND
;
516 // Scan the local token space
519 // EBC compiler is very choosy. It may report warning about comparison
520 // between UINTN and 0 . So we add 1 in each size of the
522 if (((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) && (*TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1)) ||
523 ((*TokenNumber
+ 1 > (PEI_LOCAL_TOKEN_NUMBER
+ DXE_NEX_TOKEN_NUMBER
+ 1)))) {
524 return EFI_NOT_FOUND
;
528 if ((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) &&
529 (*TokenNumber
<= PEI_LOCAL_TOKEN_NUMBER
)) {
531 // The first Non-Ex type Token Number for DXE PCD
532 // database is PEI_LOCAL_TOKEN_NUMBER
534 *TokenNumber
= PEI_LOCAL_TOKEN_NUMBER
;
535 } else if (*TokenNumber
+ 1 > DXE_NEX_TOKEN_NUMBER
+ PEI_LOCAL_TOKEN_NUMBER
+ 1) {
536 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
541 if (PEI_EXMAP_TABLE_EMPTY
&& DXE_EXMAP_TABLE_EMPTY
) {
542 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
543 return EFI_NOT_FOUND
;
546 if (!PEI_EXMAP_TABLE_EMPTY
) {
547 Status
= ExGetNextTokeNumber (
550 mPcdDatabase
->PeiDb
.Init
.GuidTable
,
551 sizeof(mPcdDatabase
->PeiDb
.Init
.GuidTable
),
552 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
553 sizeof(mPcdDatabase
->PeiDb
.Init
.ExMapTable
)
557 if (Status
== EFI_SUCCESS
) {
561 if (!DXE_EXMAP_TABLE_EMPTY
) {
562 Status
= ExGetNextTokeNumber (
565 mPcdDatabase
->DxeDb
.Init
.GuidTable
,
566 sizeof(mPcdDatabase
->DxeDb
.Init
.GuidTable
),
567 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
568 sizeof(mPcdDatabase
->DxeDb
.Init
.ExMapTable
)
577 GetDistinctTokenSpace (
578 IN OUT UINTN
*ExMapTableSize
,
579 IN DYNAMICEX_MAPPING
*ExMapTable
,
580 IN EFI_GUID
*GuidTable
583 EFI_GUID
**DistinctTokenSpace
;
589 DistinctTokenSpace
= AllocateZeroPool (*ExMapTableSize
* sizeof (EFI_GUID
*));
590 ASSERT (DistinctTokenSpace
!= NULL
);
593 OldGuidIndex
= ExMapTable
[0].ExGuidIndex
;
594 DistinctTokenSpace
[TsIdx
] = &GuidTable
[OldGuidIndex
];
595 for (Idx
= 1; Idx
< *ExMapTableSize
; Idx
++) {
596 if (ExMapTable
[Idx
].ExGuidIndex
!= OldGuidIndex
) {
597 OldGuidIndex
= ExMapTable
[Idx
].ExGuidIndex
;
598 DistinctTokenSpace
[++TsIdx
] = &GuidTable
[OldGuidIndex
];
603 // The total number of Distinct Token Space
604 // is TsIdx + 1 because we use TsIdx as a index
605 // to the DistinctTokenSpace[]
607 *ExMapTableSize
= TsIdx
+ 1;
608 return DistinctTokenSpace
;
613 // Just pre-allocate a memory buffer that is big enough to
614 // host all distinct TokenSpace guid in both
615 // PEI ExMap and DXE ExMap.
617 STATIC EFI_GUID
*TmpTokenSpaceBuffer
[PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
] = { 0 };
621 DxePcdGetNextTokenSpace (
622 IN OUT CONST EFI_GUID
**Guid
628 UINTN PeiTokenSpaceTableSize
;
629 UINTN DxeTokenSpaceTableSize
;
630 EFI_GUID
**PeiTokenSpaceTable
;
631 EFI_GUID
**DxeTokenSpaceTable
;
634 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
635 return EFI_UNSUPPORTED
;
638 ASSERT (Guid
!= NULL
);
640 if (PEI_EXMAP_TABLE_EMPTY
&& DXE_EXMAP_TABLE_EMPTY
) {
642 return EFI_NOT_FOUND
;
649 if (TmpTokenSpaceBuffer
[0] == NULL
) {
650 PeiTokenSpaceTableSize
= 0;
652 if (!PEI_EXMAP_TABLE_EMPTY
) {
653 PeiTokenSpaceTableSize
= PEI_EXMAPPING_TABLE_SIZE
;
654 PeiTokenSpaceTable
= GetDistinctTokenSpace (&PeiTokenSpaceTableSize
,
655 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
656 mPcdDatabase
->PeiDb
.Init
.GuidTable
658 CopyMem (TmpTokenSpaceBuffer
, PeiTokenSpaceTable
, sizeof (EFI_GUID
*) * PeiTokenSpaceTableSize
);
661 if (!DXE_EXMAP_TABLE_EMPTY
) {
662 DxeTokenSpaceTableSize
= DXE_EXMAPPING_TABLE_SIZE
;
663 DxeTokenSpaceTable
= GetDistinctTokenSpace (&DxeTokenSpaceTableSize
,
664 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
665 mPcdDatabase
->DxeDb
.Init
.GuidTable
669 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
671 for (Idx2
= 0, Idx3
= PeiTokenSpaceTableSize
; Idx2
< DxeTokenSpaceTableSize
; Idx2
++) {
673 for (Idx
= 0; Idx
< PeiTokenSpaceTableSize
; Idx
++) {
674 if (CompareGuid (TmpTokenSpaceBuffer
[Idx
], DxeTokenSpaceTable
[Idx2
])) {
680 TmpTokenSpaceBuffer
[Idx3
++] = DxeTokenSpaceTable
[Idx2
];
687 *Guid
= TmpTokenSpaceBuffer
[0];
691 for (Idx
= 0; Idx
< (PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
); Idx
++) {
692 if(CompareGuid (*Guid
, TmpTokenSpaceBuffer
[Idx
])) {
694 *Guid
= TmpTokenSpaceBuffer
[Idx
];
699 return EFI_NOT_FOUND
;