4 Copyright (c) 2006 - 2007, 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.
19 // Include common header file for this module.
21 #include "CommonHeader.h"
25 EFI_LOCK mPcdDatabaseLock
= EFI_INITIALIZE_LOCK_VARIABLE(TPL_CALLBACK
);
27 PCD_PROTOCOL mPcdInstance
= {
60 DxeRegisterCallBackOnSet
,
61 DxeUnRegisterCallBackOnSet
,
63 DxePcdGetNextTokenSpace
68 // Static global to reduce the code size
70 static EFI_HANDLE mNewHandle
= NULL
;
75 IN EFI_HANDLE ImageHandle
,
76 IN EFI_SYSTEM_TABLE
*SystemTable
82 // Make sure the Pcd Protocol is not already installed in the system
85 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gPcdProtocolGuid
);
87 BuildPcdDxeDataBase ();
89 Status
= gBS
->InstallProtocolInterface (
96 ASSERT_EFI_ERROR (Status
);
109 mPcdDatabase
->PeiDb
.Init
.SystemSkuId
= (SKU_ID
) SkuId
;
122 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
133 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
144 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
155 return ReadUnaligned64(GetWorker (TokenNumber
, sizeof (UINT64
)));
166 return GetWorker (TokenNumber
, 0);
177 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
189 UINT32
*LocalTokenNumberTable
;
192 UINTN TmpTokenNumber
;
194 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
195 // We have to decrement TokenNumber by 1 to make it usable
196 // as the array index.
201 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
203 TmpTokenNumber
= TokenNumber
;
205 // EBC compiler is very choosy. It may report warning about comparison
206 // between UINTN and 0 . So we add 1 in each size of the
208 ASSERT (TokenNumber
+ 1 < PCD_TOTAL_TOKEN_NUMBER
+ 1);
210 // EBC compiler is very choosy. It may report warning about comparison
211 // between UINTN and 0 . So we add 1 in each size of the
213 IsPeiDb
= (BOOLEAN
) (TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1);
215 TokenNumber
= IsPeiDb
? TokenNumber
:
216 (TokenNumber
- PEI_LOCAL_TOKEN_NUMBER
);
218 LocalTokenNumberTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.LocalTokenNumberTable
219 : mPcdDatabase
->DxeDb
.Init
.LocalTokenNumberTable
;
221 Size
= (LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
225 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
227 return GetPtrTypeSize (TmpTokenNumber
, &MaxSize
);
239 IN CONST EFI_GUID
*Guid
,
240 IN UINTN ExTokenNumber
243 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT8
)));
251 IN CONST EFI_GUID
*Guid
,
252 IN UINTN ExTokenNumber
255 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT16
)));
263 IN CONST EFI_GUID
*Guid
,
264 IN UINTN ExTokenNumber
267 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT32
)));
275 IN CONST EFI_GUID
*Guid
,
276 IN UINTN ExTokenNumber
279 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT64
)));
287 IN CONST EFI_GUID
*Guid
,
288 IN UINTN ExTokenNumber
291 return ExGetWorker (Guid
, ExTokenNumber
, 0);
299 IN CONST EFI_GUID
*Guid
,
300 IN UINTN ExTokenNumber
303 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(BOOLEAN
)));
311 IN CONST EFI_GUID
*Guid
,
312 IN UINTN ExTokenNumber
315 return DxePcdGetSize(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
));
323 IN UINTN TokenNumber
,
327 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
335 IN UINTN TokenNumber
,
339 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
347 IN UINTN TokenNumber
,
351 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
359 IN UINTN TokenNumber
,
363 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
371 IN UINTN TokenNumber
,
372 IN OUT UINTN
*SizeOfBuffer
,
376 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
384 IN UINTN TokenNumber
,
388 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
396 IN CONST EFI_GUID
*Guid
,
397 IN UINTN ExTokenNumber
,
401 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
409 IN CONST EFI_GUID
*Guid
,
410 IN UINTN ExTokenNumber
,
414 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
422 IN CONST EFI_GUID
*Guid
,
423 IN UINTN ExTokenNumber
,
427 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
435 IN CONST EFI_GUID
*Guid
,
436 IN UINTN ExTokenNumber
,
440 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
448 IN CONST EFI_GUID
*Guid
,
449 IN UINTN ExTokenNumber
,
450 IN OUT UINTN
*SizeOfBuffer
,
454 return ExSetWorker(ExTokenNumber
, Guid
, Buffer
, SizeOfBuffer
, TRUE
);
462 IN CONST EFI_GUID
*Guid
,
463 IN UINTN ExTokenNumber
,
467 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
475 DxeRegisterCallBackOnSet (
476 IN CONST EFI_GUID
*Guid
, OPTIONAL
477 IN UINTN TokenNumber
,
478 IN PCD_PROTOCOL_CALLBACK CallBackFunction
483 ASSERT (CallBackFunction
!= NULL
);
486 // Aquire lock to prevent reentrance from TPL_CALLBACK level
488 EfiAcquireLock (&mPcdDatabaseLock
);
490 Status
= DxeRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
492 EfiReleaseLock (&mPcdDatabaseLock
);
501 DxeUnRegisterCallBackOnSet (
502 IN CONST EFI_GUID
*Guid
, OPTIONAL
503 IN UINTN TokenNumber
,
504 IN PCD_PROTOCOL_CALLBACK CallBackFunction
509 ASSERT (CallBackFunction
!= NULL
);
512 // Aquire lock to prevent reentrance from TPL_CALLBACK level
514 EfiAcquireLock (&mPcdDatabaseLock
);
516 Status
= DxeUnRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
518 EfiReleaseLock (&mPcdDatabaseLock
);
528 IN CONST EFI_GUID
*Guid
, OPTIONAL
529 IN OUT UINTN
*TokenNumber
533 BOOLEAN PeiExMapTableEmpty
;
534 BOOLEAN DxeExMapTableEmpty
;
536 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
537 return EFI_UNSUPPORTED
;
540 Status
= EFI_NOT_FOUND
;
541 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
542 DxeExMapTableEmpty
= DXE_EXMAP_TABLE_EMPTY
;
545 // Scan the local token space
548 // EBC compiler is very choosy. It may report warning about comparison
549 // between UINTN and 0 . So we add 1 in each size of the
551 if (((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) && (*TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1)) ||
552 ((*TokenNumber
+ 1 > (PEI_LOCAL_TOKEN_NUMBER
+ DXE_NEX_TOKEN_NUMBER
+ 1)))) {
553 return EFI_NOT_FOUND
;
557 if ((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) &&
558 (*TokenNumber
<= PEI_LOCAL_TOKEN_NUMBER
)) {
560 // The first Non-Ex type Token Number for DXE PCD
561 // database is PEI_LOCAL_TOKEN_NUMBER
563 *TokenNumber
= PEI_LOCAL_TOKEN_NUMBER
;
564 } else if (*TokenNumber
+ 1 > DXE_NEX_TOKEN_NUMBER
+ PEI_LOCAL_TOKEN_NUMBER
+ 1) {
565 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
570 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
571 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
572 return EFI_NOT_FOUND
;
575 if (!PeiExMapTableEmpty
) {
576 Status
= ExGetNextTokeNumber (
579 mPcdDatabase
->PeiDb
.Init
.GuidTable
,
580 sizeof(mPcdDatabase
->PeiDb
.Init
.GuidTable
),
581 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
582 sizeof(mPcdDatabase
->PeiDb
.Init
.ExMapTable
)
586 if (Status
== EFI_SUCCESS
) {
590 if (!DxeExMapTableEmpty
) {
591 Status
= ExGetNextTokeNumber (
594 mPcdDatabase
->DxeDb
.Init
.GuidTable
,
595 sizeof(mPcdDatabase
->DxeDb
.Init
.GuidTable
),
596 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
597 sizeof(mPcdDatabase
->DxeDb
.Init
.ExMapTable
)
606 GetDistinctTokenSpace (
607 IN OUT UINTN
*ExMapTableSize
,
608 IN DYNAMICEX_MAPPING
*ExMapTable
,
609 IN EFI_GUID
*GuidTable
612 EFI_GUID
**DistinctTokenSpace
;
618 DistinctTokenSpace
= AllocateZeroPool (*ExMapTableSize
* sizeof (EFI_GUID
*));
619 ASSERT (DistinctTokenSpace
!= NULL
);
622 OldGuidIndex
= ExMapTable
[0].ExGuidIndex
;
623 DistinctTokenSpace
[TsIdx
] = &GuidTable
[OldGuidIndex
];
624 for (Idx
= 1; Idx
< *ExMapTableSize
; Idx
++) {
625 if (ExMapTable
[Idx
].ExGuidIndex
!= OldGuidIndex
) {
626 OldGuidIndex
= ExMapTable
[Idx
].ExGuidIndex
;
627 DistinctTokenSpace
[++TsIdx
] = &GuidTable
[OldGuidIndex
];
632 // The total number of Distinct Token Space
633 // is TsIdx + 1 because we use TsIdx as a index
634 // to the DistinctTokenSpace[]
636 *ExMapTableSize
= TsIdx
+ 1;
637 return DistinctTokenSpace
;
642 // Just pre-allocate a memory buffer that is big enough to
643 // host all distinct TokenSpace guid in both
644 // PEI ExMap and DXE ExMap.
646 STATIC EFI_GUID
*TmpTokenSpaceBuffer
[PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
] = { 0 };
650 DxePcdGetNextTokenSpace (
651 IN OUT CONST EFI_GUID
**Guid
657 UINTN PeiTokenSpaceTableSize
;
658 UINTN DxeTokenSpaceTableSize
;
659 EFI_GUID
**PeiTokenSpaceTable
;
660 EFI_GUID
**DxeTokenSpaceTable
;
662 BOOLEAN PeiExMapTableEmpty
;
663 BOOLEAN DxeExMapTableEmpty
;
665 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
666 return EFI_UNSUPPORTED
;
669 ASSERT (Guid
!= NULL
);
671 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
672 DxeExMapTableEmpty
= DXE_EXMAP_TABLE_EMPTY
;
674 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
676 return EFI_NOT_FOUND
;
683 if (TmpTokenSpaceBuffer
[0] == NULL
) {
684 PeiTokenSpaceTableSize
= 0;
686 if (!PeiExMapTableEmpty
) {
687 PeiTokenSpaceTableSize
= PEI_EXMAPPING_TABLE_SIZE
;
688 PeiTokenSpaceTable
= GetDistinctTokenSpace (&PeiTokenSpaceTableSize
,
689 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
690 mPcdDatabase
->PeiDb
.Init
.GuidTable
692 CopyMem (TmpTokenSpaceBuffer
, PeiTokenSpaceTable
, sizeof (EFI_GUID
*) * PeiTokenSpaceTableSize
);
695 if (!DxeExMapTableEmpty
) {
696 DxeTokenSpaceTableSize
= DXE_EXMAPPING_TABLE_SIZE
;
697 DxeTokenSpaceTable
= GetDistinctTokenSpace (&DxeTokenSpaceTableSize
,
698 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
699 mPcdDatabase
->DxeDb
.Init
.GuidTable
703 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
705 for (Idx2
= 0, Idx3
= PeiTokenSpaceTableSize
; Idx2
< DxeTokenSpaceTableSize
; Idx2
++) {
707 for (Idx
= 0; Idx
< PeiTokenSpaceTableSize
; Idx
++) {
708 if (CompareGuid (TmpTokenSpaceBuffer
[Idx
], DxeTokenSpaceTable
[Idx2
])) {
714 TmpTokenSpaceBuffer
[Idx3
++] = DxeTokenSpaceTable
[Idx2
];
721 *Guid
= TmpTokenSpaceBuffer
[0];
725 for (Idx
= 0; Idx
< (PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
); Idx
++) {
726 if(CompareGuid (*Guid
, TmpTokenSpaceBuffer
[Idx
])) {
728 *Guid
= TmpTokenSpaceBuffer
[Idx
];
733 return EFI_NOT_FOUND
;