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.
20 EFI_LOCK mPcdDatabaseLock
= EFI_INITIALIZE_LOCK_VARIABLE(TPL_CALLBACK
);
22 PCD_PROTOCOL mPcdInstance
= {
55 DxeRegisterCallBackOnSet
,
56 DxeUnRegisterCallBackOnSet
,
58 DxePcdGetNextTokenSpace
63 // Static global to reduce the code size
65 static EFI_HANDLE mNewHandle
= NULL
;
70 IN EFI_HANDLE ImageHandle
,
71 IN EFI_SYSTEM_TABLE
*SystemTable
77 // Make sure the Pcd Protocol is not already installed in the system
80 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gPcdProtocolGuid
);
82 BuildPcdDxeDataBase ();
84 Status
= gBS
->InstallProtocolInterface (
91 ASSERT_EFI_ERROR (Status
);
104 mPcdDatabase
->PeiDb
.Init
.SystemSkuId
= (SKU_ID
) SkuId
;
117 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
128 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
139 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
150 return ReadUnaligned64(GetWorker (TokenNumber
, sizeof (UINT64
)));
161 return GetWorker (TokenNumber
, 0);
172 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
184 UINT32
*LocalTokenNumberTable
;
187 UINTN TmpTokenNumber
;
189 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
190 // We have to decrement TokenNumber by 1 to make it usable
191 // as the array index.
196 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
198 TmpTokenNumber
= TokenNumber
;
200 // EBC compiler is very choosy. It may report warning about comparison
201 // between UINTN and 0 . So we add 1 in each size of the
203 ASSERT (TokenNumber
+ 1 < PCD_TOTAL_TOKEN_NUMBER
+ 1);
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 IsPeiDb
= (BOOLEAN
) (TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1);
210 TokenNumber
= IsPeiDb
? TokenNumber
:
211 (TokenNumber
- PEI_LOCAL_TOKEN_NUMBER
);
213 LocalTokenNumberTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.LocalTokenNumberTable
214 : mPcdDatabase
->DxeDb
.Init
.LocalTokenNumberTable
;
216 Size
= (LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
220 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
222 return GetPtrTypeSize (TmpTokenNumber
, &MaxSize
);
234 IN CONST EFI_GUID
*Guid
,
235 IN UINTN ExTokenNumber
238 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT8
)));
246 IN CONST EFI_GUID
*Guid
,
247 IN UINTN ExTokenNumber
250 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT16
)));
258 IN CONST EFI_GUID
*Guid
,
259 IN UINTN ExTokenNumber
262 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT32
)));
270 IN CONST EFI_GUID
*Guid
,
271 IN UINTN ExTokenNumber
274 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT64
)));
282 IN CONST EFI_GUID
*Guid
,
283 IN UINTN ExTokenNumber
286 return ExGetWorker (Guid
, ExTokenNumber
, 0);
294 IN CONST EFI_GUID
*Guid
,
295 IN UINTN ExTokenNumber
298 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(BOOLEAN
)));
306 IN CONST EFI_GUID
*Guid
,
307 IN UINTN ExTokenNumber
310 return DxePcdGetSize(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
));
318 IN UINTN TokenNumber
,
322 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
330 IN UINTN TokenNumber
,
334 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
342 IN UINTN TokenNumber
,
346 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
354 IN UINTN TokenNumber
,
358 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
366 IN UINTN TokenNumber
,
367 IN OUT UINTN
*SizeOfBuffer
,
371 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
379 IN UINTN TokenNumber
,
383 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
391 IN CONST EFI_GUID
*Guid
,
392 IN UINTN ExTokenNumber
,
396 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
404 IN CONST EFI_GUID
*Guid
,
405 IN UINTN ExTokenNumber
,
409 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
417 IN CONST EFI_GUID
*Guid
,
418 IN UINTN ExTokenNumber
,
422 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
430 IN CONST EFI_GUID
*Guid
,
431 IN UINTN ExTokenNumber
,
435 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
443 IN CONST EFI_GUID
*Guid
,
444 IN UINTN ExTokenNumber
,
445 IN OUT UINTN
*SizeOfBuffer
,
449 return ExSetWorker(ExTokenNumber
, Guid
, Buffer
, SizeOfBuffer
, TRUE
);
457 IN CONST EFI_GUID
*Guid
,
458 IN UINTN ExTokenNumber
,
462 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
470 DxeRegisterCallBackOnSet (
471 IN CONST EFI_GUID
*Guid
, OPTIONAL
472 IN UINTN TokenNumber
,
473 IN PCD_PROTOCOL_CALLBACK CallBackFunction
478 ASSERT (CallBackFunction
!= NULL
);
481 // Aquire lock to prevent reentrance from TPL_CALLBACK level
483 EfiAcquireLock (&mPcdDatabaseLock
);
485 Status
= DxeRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
487 EfiReleaseLock (&mPcdDatabaseLock
);
496 DxeUnRegisterCallBackOnSet (
497 IN CONST EFI_GUID
*Guid
, OPTIONAL
498 IN UINTN TokenNumber
,
499 IN PCD_PROTOCOL_CALLBACK CallBackFunction
504 ASSERT (CallBackFunction
!= NULL
);
507 // Aquire lock to prevent reentrance from TPL_CALLBACK level
509 EfiAcquireLock (&mPcdDatabaseLock
);
511 Status
= DxeUnRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
513 EfiReleaseLock (&mPcdDatabaseLock
);
523 IN CONST EFI_GUID
*Guid
, OPTIONAL
524 IN OUT UINTN
*TokenNumber
528 BOOLEAN PeiExMapTableEmpty
;
529 BOOLEAN DxeExMapTableEmpty
;
531 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
532 return EFI_UNSUPPORTED
;
535 Status
= EFI_NOT_FOUND
;
536 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
537 DxeExMapTableEmpty
= DXE_EXMAP_TABLE_EMPTY
;
540 // Scan the local token space
543 // EBC compiler is very choosy. It may report warning about comparison
544 // between UINTN and 0 . So we add 1 in each size of the
546 if (((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) && (*TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1)) ||
547 ((*TokenNumber
+ 1 > (PEI_LOCAL_TOKEN_NUMBER
+ DXE_NEX_TOKEN_NUMBER
+ 1)))) {
548 return EFI_NOT_FOUND
;
552 if ((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) &&
553 (*TokenNumber
<= PEI_LOCAL_TOKEN_NUMBER
)) {
555 // The first Non-Ex type Token Number for DXE PCD
556 // database is PEI_LOCAL_TOKEN_NUMBER
558 *TokenNumber
= PEI_LOCAL_TOKEN_NUMBER
;
559 } else if (*TokenNumber
+ 1 > DXE_NEX_TOKEN_NUMBER
+ PEI_LOCAL_TOKEN_NUMBER
+ 1) {
560 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
565 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
566 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
567 return EFI_NOT_FOUND
;
570 if (!PeiExMapTableEmpty
) {
571 Status
= ExGetNextTokeNumber (
574 mPcdDatabase
->PeiDb
.Init
.GuidTable
,
575 sizeof(mPcdDatabase
->PeiDb
.Init
.GuidTable
),
576 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
577 sizeof(mPcdDatabase
->PeiDb
.Init
.ExMapTable
)
581 if (Status
== EFI_SUCCESS
) {
585 if (!DxeExMapTableEmpty
) {
586 Status
= ExGetNextTokeNumber (
589 mPcdDatabase
->DxeDb
.Init
.GuidTable
,
590 sizeof(mPcdDatabase
->DxeDb
.Init
.GuidTable
),
591 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
592 sizeof(mPcdDatabase
->DxeDb
.Init
.ExMapTable
)
601 GetDistinctTokenSpace (
602 IN OUT UINTN
*ExMapTableSize
,
603 IN DYNAMICEX_MAPPING
*ExMapTable
,
604 IN EFI_GUID
*GuidTable
607 EFI_GUID
**DistinctTokenSpace
;
613 DistinctTokenSpace
= AllocateZeroPool (*ExMapTableSize
* sizeof (EFI_GUID
*));
614 ASSERT (DistinctTokenSpace
!= NULL
);
617 OldGuidIndex
= ExMapTable
[0].ExGuidIndex
;
618 DistinctTokenSpace
[TsIdx
] = &GuidTable
[OldGuidIndex
];
619 for (Idx
= 1; Idx
< *ExMapTableSize
; Idx
++) {
620 if (ExMapTable
[Idx
].ExGuidIndex
!= OldGuidIndex
) {
621 OldGuidIndex
= ExMapTable
[Idx
].ExGuidIndex
;
622 DistinctTokenSpace
[++TsIdx
] = &GuidTable
[OldGuidIndex
];
627 // The total number of Distinct Token Space
628 // is TsIdx + 1 because we use TsIdx as a index
629 // to the DistinctTokenSpace[]
631 *ExMapTableSize
= TsIdx
+ 1;
632 return DistinctTokenSpace
;
637 // Just pre-allocate a memory buffer that is big enough to
638 // host all distinct TokenSpace guid in both
639 // PEI ExMap and DXE ExMap.
641 STATIC EFI_GUID
*TmpTokenSpaceBuffer
[PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
] = { 0 };
645 DxePcdGetNextTokenSpace (
646 IN OUT CONST EFI_GUID
**Guid
652 UINTN PeiTokenSpaceTableSize
;
653 UINTN DxeTokenSpaceTableSize
;
654 EFI_GUID
**PeiTokenSpaceTable
;
655 EFI_GUID
**DxeTokenSpaceTable
;
657 BOOLEAN PeiExMapTableEmpty
;
658 BOOLEAN DxeExMapTableEmpty
;
660 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
661 return EFI_UNSUPPORTED
;
664 ASSERT (Guid
!= NULL
);
666 PeiExMapTableEmpty
= PEI_EXMAP_TABLE_EMPTY
;
667 DxeExMapTableEmpty
= DXE_EXMAP_TABLE_EMPTY
;
669 if (PeiExMapTableEmpty
&& DxeExMapTableEmpty
) {
671 return EFI_NOT_FOUND
;
678 if (TmpTokenSpaceBuffer
[0] == NULL
) {
679 PeiTokenSpaceTableSize
= 0;
681 if (!PeiExMapTableEmpty
) {
682 PeiTokenSpaceTableSize
= PEI_EXMAPPING_TABLE_SIZE
;
683 PeiTokenSpaceTable
= GetDistinctTokenSpace (&PeiTokenSpaceTableSize
,
684 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
685 mPcdDatabase
->PeiDb
.Init
.GuidTable
687 CopyMem (TmpTokenSpaceBuffer
, PeiTokenSpaceTable
, sizeof (EFI_GUID
*) * PeiTokenSpaceTableSize
);
690 if (!DxeExMapTableEmpty
) {
691 DxeTokenSpaceTableSize
= DXE_EXMAPPING_TABLE_SIZE
;
692 DxeTokenSpaceTable
= GetDistinctTokenSpace (&DxeTokenSpaceTableSize
,
693 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
694 mPcdDatabase
->DxeDb
.Init
.GuidTable
698 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
700 for (Idx2
= 0, Idx3
= PeiTokenSpaceTableSize
; Idx2
< DxeTokenSpaceTableSize
; Idx2
++) {
702 for (Idx
= 0; Idx
< PeiTokenSpaceTableSize
; Idx
++) {
703 if (CompareGuid (TmpTokenSpaceBuffer
[Idx
], DxeTokenSpaceTable
[Idx2
])) {
709 TmpTokenSpaceBuffer
[Idx3
++] = DxeTokenSpaceTable
[Idx2
];
716 *Guid
= TmpTokenSpaceBuffer
[0];
720 for (Idx
= 0; Idx
< (PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
); Idx
++) {
721 if(CompareGuid (*Guid
, TmpTokenSpaceBuffer
[Idx
])) {
723 *Guid
= TmpTokenSpaceBuffer
[Idx
];
728 return EFI_NOT_FOUND
;