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 ();
83 Status
= gBS
->InstallProtocolInterface (
90 ASSERT_EFI_ERROR (Status
);
103 mPcdDatabase
->PeiDb
.Init
.SystemSkuId
= (SKU_ID
) SkuId
;
116 return *((UINT8
*) GetWorker (TokenNumber
, sizeof (UINT8
)));
127 return ReadUnaligned16 (GetWorker (TokenNumber
, sizeof (UINT16
)));
138 return ReadUnaligned32 (GetWorker (TokenNumber
, sizeof (UINT32
)));
149 return ReadUnaligned64(GetWorker (TokenNumber
, sizeof (UINT64
)));
160 return GetWorker (TokenNumber
, 0);
171 return *((BOOLEAN
*) GetWorker (TokenNumber
, sizeof (BOOLEAN
)));
183 UINT32
*LocalTokenNumberTable
;
186 UINTN TmpTokenNumber
;
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.
195 // Backup the TokenNumber passed in as GetPtrTypeSize need the original TokenNumber
197 TmpTokenNumber
= TokenNumber
;
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 < PCD_TOTAL_TOKEN_NUMBER
+ 1);
204 // EBC compiler is very choosy. It may report warning about comparison
205 // between UINTN and 0 . So we add 1 in each size of the
207 IsPeiDb
= (BOOLEAN
) (TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1);
209 TokenNumber
= IsPeiDb
? TokenNumber
:
210 (TokenNumber
- PEI_LOCAL_TOKEN_NUMBER
);
212 LocalTokenNumberTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.LocalTokenNumberTable
213 : mPcdDatabase
->DxeDb
.Init
.LocalTokenNumberTable
;
215 Size
= (LocalTokenNumberTable
[TokenNumber
] & PCD_DATUM_TYPE_ALL_SET
) >> PCD_DATUM_TYPE_SHIFT
;
219 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
221 return GetPtrTypeSize (TmpTokenNumber
, &MaxSize
);
233 IN CONST EFI_GUID
*Guid
,
234 IN UINTN ExTokenNumber
237 return *((UINT8
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT8
)));
245 IN CONST EFI_GUID
*Guid
,
246 IN UINTN ExTokenNumber
249 return ReadUnaligned16 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT16
)));
257 IN CONST EFI_GUID
*Guid
,
258 IN UINTN ExTokenNumber
261 return ReadUnaligned32 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT32
)));
269 IN CONST EFI_GUID
*Guid
,
270 IN UINTN ExTokenNumber
273 return ReadUnaligned64 (ExGetWorker (Guid
, ExTokenNumber
, sizeof(UINT64
)));
281 IN CONST EFI_GUID
*Guid
,
282 IN UINTN ExTokenNumber
285 return ExGetWorker (Guid
, ExTokenNumber
, 0);
293 IN CONST EFI_GUID
*Guid
,
294 IN UINTN ExTokenNumber
297 return *((BOOLEAN
*) ExGetWorker (Guid
, ExTokenNumber
, sizeof(BOOLEAN
)));
305 IN CONST EFI_GUID
*Guid
,
306 IN UINTN ExTokenNumber
309 return DxePcdGetSize(GetExPcdTokenNumber (Guid
, (UINT32
) ExTokenNumber
));
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
));
353 IN UINTN TokenNumber
,
357 return SetValueWorker (TokenNumber
, &Value
, sizeof (Value
));
365 IN UINTN TokenNumber
,
366 IN OUT UINTN
*SizeOfBuffer
,
370 return SetWorker (TokenNumber
, Buffer
, SizeOfBuffer
, TRUE
);
378 IN UINTN TokenNumber
,
382 return SetValueWorker (TokenNumber
, &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
,
434 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
442 IN CONST EFI_GUID
*Guid
,
443 IN UINTN ExTokenNumber
,
444 IN OUT UINTN
*SizeOfBuffer
,
448 return ExSetWorker(ExTokenNumber
, Guid
, Buffer
, SizeOfBuffer
, TRUE
);
456 IN CONST EFI_GUID
*Guid
,
457 IN UINTN ExTokenNumber
,
461 return ExSetValueWorker (ExTokenNumber
, Guid
, &Value
, sizeof (Value
));
469 DxeRegisterCallBackOnSet (
470 IN CONST EFI_GUID
*Guid
, OPTIONAL
471 IN UINTN TokenNumber
,
472 IN PCD_PROTOCOL_CALLBACK CallBackFunction
475 ASSERT (CallBackFunction
!= NULL
);
477 return DxeRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
484 DxeUnRegisterCallBackOnSet (
485 IN CONST EFI_GUID
*Guid
, OPTIONAL
486 IN UINTN TokenNumber
,
487 IN PCD_PROTOCOL_CALLBACK CallBackFunction
490 ASSERT (CallBackFunction
!= NULL
);
492 return DxeUnRegisterCallBackWorker (TokenNumber
, Guid
, CallBackFunction
);
500 IN CONST EFI_GUID
*Guid
, OPTIONAL
501 IN OUT UINTN
*TokenNumber
506 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
507 return EFI_UNSUPPORTED
;
510 Status
= EFI_NOT_FOUND
;
512 // Scan the local token space
515 // EBC compiler is very choosy. It may report warning about comparison
516 // between UINTN and 0 . So we add 1 in each size of the
518 if (((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) && (*TokenNumber
+ 1 < PEI_LOCAL_TOKEN_NUMBER
+ 1)) ||
519 ((*TokenNumber
+ 1 > (PEI_LOCAL_TOKEN_NUMBER
+ DXE_NEX_TOKEN_NUMBER
+ 1)))) {
520 return EFI_NOT_FOUND
;
524 if ((*TokenNumber
+ 1 > PEI_NEX_TOKEN_NUMBER
+ 1) &&
525 (*TokenNumber
<= PEI_LOCAL_TOKEN_NUMBER
)) {
527 // The first Non-Ex type Token Number for DXE PCD
528 // database is PEI_LOCAL_TOKEN_NUMBER
530 *TokenNumber
= PEI_LOCAL_TOKEN_NUMBER
;
531 } else if (*TokenNumber
+ 1 > DXE_NEX_TOKEN_NUMBER
+ PEI_LOCAL_TOKEN_NUMBER
+ 1) {
532 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
537 if (PEI_EXMAP_TABLE_EMPTY
&& DXE_EXMAP_TABLE_EMPTY
) {
538 *TokenNumber
= PCD_INVALID_TOKEN_NUMBER
;
539 return EFI_NOT_FOUND
;
542 if (!PEI_EXMAP_TABLE_EMPTY
) {
543 Status
= ExGetNextTokeNumber (
546 mPcdDatabase
->PeiDb
.Init
.GuidTable
,
547 sizeof(mPcdDatabase
->PeiDb
.Init
.GuidTable
),
548 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
549 sizeof(mPcdDatabase
->PeiDb
.Init
.ExMapTable
)
553 if (Status
== EFI_SUCCESS
) {
557 if (!DXE_EXMAP_TABLE_EMPTY
) {
558 Status
= ExGetNextTokeNumber (
561 mPcdDatabase
->DxeDb
.Init
.GuidTable
,
562 sizeof(mPcdDatabase
->DxeDb
.Init
.GuidTable
),
563 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
564 sizeof(mPcdDatabase
->DxeDb
.Init
.ExMapTable
)
573 GetDistinctTokenSpace (
574 IN OUT UINTN
*ExMapTableSize
,
575 IN DYNAMICEX_MAPPING
*ExMapTable
,
576 IN EFI_GUID
*GuidTable
579 EFI_GUID
**DistinctTokenSpace
;
585 DistinctTokenSpace
= AllocateZeroPool (*ExMapTableSize
* sizeof (EFI_GUID
*));
586 ASSERT (DistinctTokenSpace
!= NULL
);
589 OldGuidIndex
= ExMapTable
[0].ExGuidIndex
;
590 DistinctTokenSpace
[TsIdx
] = &GuidTable
[OldGuidIndex
];
591 for (Idx
= 1; Idx
< *ExMapTableSize
; Idx
++) {
592 if (ExMapTable
[Idx
].ExGuidIndex
!= OldGuidIndex
) {
593 OldGuidIndex
= ExMapTable
[Idx
].ExGuidIndex
;
594 DistinctTokenSpace
[++TsIdx
] = &GuidTable
[OldGuidIndex
];
599 // The total number of Distinct Token Space
600 // is TsIdx + 1 because we use TsIdx as a index
601 // to the DistinctTokenSpace[]
603 *ExMapTableSize
= TsIdx
+ 1;
604 return DistinctTokenSpace
;
609 // Just pre-allocate a memory buffer that is big enough to
610 // host all distinct TokenSpace guid in both
611 // PEI ExMap and DXE ExMap.
613 STATIC EFI_GUID
*TmpTokenSpaceBuffer
[PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
] = { 0 };
617 DxePcdGetNextTokenSpace (
618 IN OUT CONST EFI_GUID
**Guid
624 UINTN PeiTokenSpaceTableSize
;
625 UINTN DxeTokenSpaceTableSize
;
626 EFI_GUID
**PeiTokenSpaceTable
;
627 EFI_GUID
**DxeTokenSpaceTable
;
630 if (!FeaturePcdGet (PcdDxePcdDatabaseTraverseEnabled
)) {
631 return EFI_UNSUPPORTED
;
634 ASSERT (Guid
!= NULL
);
636 if (PEI_EXMAP_TABLE_EMPTY
&& DXE_EXMAP_TABLE_EMPTY
) {
638 return EFI_NOT_FOUND
;
645 if (TmpTokenSpaceBuffer
[0] == NULL
) {
646 PeiTokenSpaceTableSize
= 0;
648 if (!PEI_EXMAP_TABLE_EMPTY
) {
649 PeiTokenSpaceTableSize
= PEI_EXMAPPING_TABLE_SIZE
;
650 PeiTokenSpaceTable
= GetDistinctTokenSpace (&PeiTokenSpaceTableSize
,
651 mPcdDatabase
->PeiDb
.Init
.ExMapTable
,
652 mPcdDatabase
->PeiDb
.Init
.GuidTable
654 CopyMem (TmpTokenSpaceBuffer
, PeiTokenSpaceTable
, sizeof (EFI_GUID
*) * PeiTokenSpaceTableSize
);
657 if (!DXE_EXMAP_TABLE_EMPTY
) {
658 DxeTokenSpaceTableSize
= DXE_EXMAPPING_TABLE_SIZE
;
659 DxeTokenSpaceTable
= GetDistinctTokenSpace (&DxeTokenSpaceTableSize
,
660 mPcdDatabase
->DxeDb
.Init
.ExMapTable
,
661 mPcdDatabase
->DxeDb
.Init
.GuidTable
665 // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTokenSpaceTable
667 for (Idx2
= 0, Idx3
= PeiTokenSpaceTableSize
; Idx2
< DxeTokenSpaceTableSize
; Idx2
++) {
669 for (Idx
= 0; Idx
< PeiTokenSpaceTableSize
; Idx
++) {
670 if (CompareGuid (TmpTokenSpaceBuffer
[Idx
], DxeTokenSpaceTable
[Idx2
])) {
676 TmpTokenSpaceBuffer
[Idx3
++] = DxeTokenSpaceTable
[Idx2
];
683 *Guid
= TmpTokenSpaceBuffer
[0];
687 for (Idx
= 0; Idx
< (PEI_EXMAPPING_TABLE_SIZE
+ DXE_EXMAPPING_TABLE_SIZE
); Idx
++) {
688 if(CompareGuid (*Guid
, TmpTokenSpaceBuffer
[Idx
])) {
690 *Guid
= TmpTokenSpaceBuffer
[Idx
];
695 return EFI_NOT_FOUND
;