2 Private functions used by PCD PEIM.
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.
14 Module Name: Service.c
20 The function registers the CallBackOnSet fucntion
21 according to TokenNumber and EFI_GUID space.
23 @param[in] TokenNumber The token number.
24 @param[in] Guid The GUID space.
25 @param[in] CallBackFunction The Callback function to be registered.
27 @retval EFI_SUCCESS If the Callback function is registered.
28 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
31 PeiRegisterCallBackWorker (
32 IN UINTN ExTokenNumber
,
33 IN CONST EFI_GUID
*Guid
, OPTIONAL
34 IN PCD_PPI_CALLBACK CallBackFunction
,
38 EFI_HOB_GUID_TYPE
*GuidHob
;
39 PCD_PPI_CALLBACK
*CallbackTable
;
40 PCD_PPI_CALLBACK Compare
;
41 PCD_PPI_CALLBACK Assign
;
42 UINT32 LocalTokenNumber
;
47 TokenNumber
= ExTokenNumber
;
50 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
51 // We have to decrement TokenNumber by 1 to make it usable
52 // as the array index.
55 ASSERT (TokenNumber
< PEI_NEX_TOKEN_NUMBER
);
57 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
60 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
61 // We have to decrement TokenNumber by 1 to make it usable
62 // as the array index.
65 ASSERT (TokenNumber
< PEI_LOCAL_TOKEN_NUMBER
);
69 LocalTokenNumber
= GetPcdDatabase()->Init
.LocalTokenNumberTable
[TokenNumber
];
71 ASSERT ((LocalTokenNumber
& PCD_TYPE_HII
) == 0);
72 ASSERT ((LocalTokenNumber
& PCD_TYPE_VPD
) == 0);
74 GuidHob
= GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid
);
75 ASSERT (GuidHob
!= NULL
);
77 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
78 CallbackTable
= CallbackTable
+ (TokenNumber
* FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
80 Compare
= Register
? NULL
: CallBackFunction
;
81 Assign
= Register
? CallBackFunction
: NULL
;
84 for (Idx
= 0; Idx
< FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
85 if (CallbackTable
[Idx
] == Compare
) {
86 CallbackTable
[Idx
] = Assign
;
91 return Register
? EFI_OUT_OF_RESOURCES
: EFI_NOT_FOUND
;
99 The function builds the PCD database based on the
100 PCD_IMAGE on the flash.
102 @param[in] PcdImageOnFlash The PCD image on flash.
111 PEI_PCD_DATABASE
*Database
;
112 VOID
*CallbackFnTable
;
113 UINTN SizeOfCallbackFnTable
;
115 Database
= BuildGuidHob (&gPcdDataBaseHobGuid
, sizeof (PEI_PCD_DATABASE
));
117 ZeroMem (Database
, sizeof (PEI_PCD_DATABASE
));
120 // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE
123 CopyMem (&Database
->Init
, &gPEIPcdDbInit
, sizeof (gPEIPcdDbInit
));
125 SizeOfCallbackFnTable
= PEI_LOCAL_TOKEN_NUMBER
* sizeof (PCD_PPI_CALLBACK
) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
);
127 CallbackFnTable
= BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid
, SizeOfCallbackFnTable
);
129 ZeroMem (CallbackFnTable
, SizeOfCallbackFnTable
);
137 The function is provided by PCD PEIM and PCD DXE driver to
138 do the work of reading a HII variable from variable service.
140 @param[in] VariableGuid The Variable GUID.
141 @param[in] VariableName The Variable Name.
142 @param[out] VariableData The output data.
143 @param[out] VariableSize The size of the variable.
145 @retval EFI_SUCCESS Operation successful.
146 @retval EFI_SUCCESS Variablel not found.
150 IN CONST EFI_GUID
*VariableGuid
,
151 IN UINT16
*VariableName
,
152 OUT VOID
**VariableData
,
153 OUT UINTN
*VariableSize
159 EFI_PEI_READ_ONLY_VARIABLE_PPI
*VariablePpi
;
161 Status
= PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid
, 0, NULL
, (VOID
**) &VariablePpi
);
162 ASSERT_EFI_ERROR (Status
);
165 Status
= VariablePpi
->PeiGetVariable (
166 GetPeiServicesTablePointer (),
168 (EFI_GUID
*) VariableGuid
,
173 if (Status
== EFI_BUFFER_TOO_SMALL
) {
176 Status
= PeiServicesAllocatePool (Size
, &Buffer
);
177 ASSERT_EFI_ERROR (Status
);
179 Status
= VariablePpi
->PeiGetVariable (
180 GetPeiServicesTablePointer (),
181 (UINT16
*) VariableName
,
182 (EFI_GUID
*) VariableGuid
,
187 ASSERT_EFI_ERROR (Status
);
189 *VariableSize
= Size
;
190 *VariableData
= Buffer
;
194 return EFI_NOT_FOUND
;
201 GetSkuEnabledTokenNumber (
202 UINT32 LocalTokenNumber
,
206 PEI_PCD_DATABASE
*PeiPcdDb
;
212 PeiPcdDb
= GetPcdDatabase ();
214 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0);
216 SkuHead
= (SKU_HEAD
*) ((UINT8
*)PeiPcdDb
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
217 Value
= (UINT8
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuDataStartOffset
));
218 SkuIdTable
= (SKU_ID
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuIdTableOffset
));
220 for (i
= 0; i
< SkuIdTable
[0]; i
++) {
221 if (PeiPcdDb
->Init
.SystemSkuId
== SkuIdTable
[i
+ 1]) {
226 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
228 Value
+= sizeof(VPD_HEAD
) * i
;
229 return ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_VPD
);
232 Value
+= sizeof(VARIABLE_HEAD
) * i
;
233 return ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_HII
);
237 return (Value
- (UINT8
*) PeiPcdDb
);
253 InvokeCallbackOnSet (
254 UINT32 ExTokenNumber
,
255 CONST EFI_GUID
*Guid
, OPTIONAL
261 EFI_HOB_GUID_TYPE
*GuidHob
;
262 PCD_PPI_CALLBACK
*CallbackTable
;
266 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
267 // We have to decrement TokenNumber by 1 to make it usable
268 // as the array index.
273 ASSERT (TokenNumber
< PEI_LOCAL_TOKEN_NUMBER
);
275 GuidHob
= GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid
);
276 ASSERT (GuidHob
!= NULL
);
278 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
280 CallbackTable
+= (TokenNumber
* FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
282 for (Idx
= 0; Idx
< FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
283 if (CallbackTable
[Idx
] != NULL
) {
284 CallbackTable
[Idx
] (Guid
,
285 (Guid
== NULL
)? TokenNumber
: ExTokenNumber
,
305 UINT32 LocalTokenNumber
;
306 PEI_PCD_DATABASE
*PeiPcdDb
;
307 UINT16 StringTableIdx
;
312 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
313 // We have to decrement TokenNumber by 1 to make it usable
314 // as the array index.
318 ASSERT (TokenNumber
< PEI_LOCAL_TOKEN_NUMBER
);
320 PeiPcdDb
= GetPcdDatabase ();
322 LocalTokenNumber
= PeiPcdDb
->Init
.LocalTokenNumberTable
[TokenNumber
];
325 ASSERT (PeiPcdDb
->Init
.SizeTable
[TokenNumber
] >= Size
);
327 ASSERT (PeiPcdDb
->Init
.SizeTable
[TokenNumber
] == Size
);
331 // We only invoke the callback function for Dynamic Type PCD Entry.
332 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
333 // type PCD entry in ExSetWorker.
335 if (TokenNumber
< PEI_NEX_TOKEN_NUMBER
) {
336 InvokeCallbackOnSet (0, NULL
, TokenNumber
+ 1, Data
, Size
);
339 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
340 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, Size
);
343 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
344 InternalData
= (VOID
*) ((UINT8
*) PeiPcdDb
+ Offset
);
346 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
351 return EFI_INVALID_PARAMETER
;
354 case PCD_TYPE_STRING
:
355 StringTableIdx
= *((UINT16
*)InternalData
);
356 CopyMem (&PeiPcdDb
->Init
.StringTable
[StringTableIdx
], Data
, Size
);
363 CopyMem (InternalData
, Data
, Size
);
369 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
373 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
377 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
381 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
386 return EFI_NOT_FOUND
;
393 return EFI_NOT_FOUND
;
402 IN UINTN ExTokenNumber
,
403 IN CONST EFI_GUID
*Guid
,
411 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
413 InvokeCallbackOnSet (ExTokenNumber
, Guid
, TokenNumber
, Data
, Size
);
415 SetWorker (TokenNumber
, Data
, Size
, PtrType
);
426 IN CONST EFI_GUID
*Guid
,
427 IN UINTN ExTokenNumber
,
431 return GetWorker (GetExPcdTokenNumber (Guid
, ExTokenNumber
), GetSize
);
446 VARIABLE_HEAD
*VariableHead
;
451 UINT16 StringTableIdx
;
452 PEI_PCD_DATABASE
*PeiPcdDb
;
453 UINT32 LocalTokenNumber
;
457 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
458 // We have to decrement TokenNumber by 1 to make it usable
459 // as the array index.
463 ASSERT (TokenNumber
< PEI_LOCAL_TOKEN_NUMBER
);
465 Size
= PeiPcdGetSize(TokenNumber
+ 1);
467 ASSERT (GetSize
== Size
|| GetSize
== 0);
469 PeiPcdDb
= GetPcdDatabase ();
471 LocalTokenNumber
= PeiPcdDb
->Init
.LocalTokenNumberTable
[TokenNumber
];
473 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
474 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, Size
);
477 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
478 StringTable
= PeiPcdDb
->Init
.StringTable
;
480 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
484 VpdHead
= (VPD_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
485 return (VOID
*) (FixedPcdGet32(PcdVpdBaseAddress
) + VpdHead
->Offset
);
490 VariableHead
= (VARIABLE_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
492 Guid
= &(PeiPcdDb
->Init
.GuidTable
[VariableHead
->GuidTableIndex
]);
493 Name
= &StringTable
[VariableHead
->StringIndex
];
495 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
497 if (Status
== EFI_SUCCESS
) {
498 return (VOID
*) ((UINT8
*) Data
+ VariableHead
->Offset
);
501 // Return the default value specified by Platform Integrator
503 return (VOID
*) ((UINT8
*) PeiPcdDb
+ VariableHead
->DefaultValueOffset
);
508 return (VOID
*) ((UINT8
*)PeiPcdDb
+ Offset
);
510 case PCD_TYPE_STRING
:
511 StringTableIdx
= (UINT16
) *((UINT8
*) PeiPcdDb
+ Offset
);
512 return (VOID
*) (&StringTable
[StringTableIdx
]);
528 GetExPcdTokenNumber (
529 IN CONST EFI_GUID
*Guid
,
530 IN UINT32 ExTokenNumber
534 DYNAMICEX_MAPPING
*ExMap
;
538 PEI_PCD_DATABASE
*PeiPcdDb
;
540 PeiPcdDb
= GetPcdDatabase();
542 ExMap
= PeiPcdDb
->Init
.ExMapTable
;
543 GuidTable
= PeiPcdDb
->Init
.GuidTable
;
545 MatchGuid
= ScanGuid (GuidTable
, sizeof(PeiPcdDb
->Init
.GuidTable
), Guid
);
547 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
548 // error in the BUILD system.
550 ASSERT (MatchGuid
!= NULL
);
552 MatchGuidIdx
= MatchGuid
- GuidTable
;
554 for (i
= 0; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
555 if ((ExTokenNumber
== ExMap
[i
].ExTokenNumber
) &&
556 (MatchGuidIdx
== ExMap
[i
].ExGuidIndex
)) {
557 return ExMap
[i
].LocalTokenNumber
;
573 EFI_HOB_GUID_TYPE
*GuidHob
;
575 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
576 ASSERT (GuidHob
!= NULL
);
578 return (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);