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
21 The function registers the CallBackOnSet fucntion
22 according to TokenNumber and EFI_GUID space.
24 @param[in] TokenNumber The token number.
25 @param[in] Guid The GUID space.
26 @param[in] CallBackFunction The Callback function to be registered.
28 @retval EFI_SUCCESS If the Callback function is registered.
29 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
32 PeiRegisterCallBackWorker (
33 IN UINTN ExTokenNumber
,
34 IN CONST EFI_GUID
*Guid
, OPTIONAL
35 IN PCD_PPI_CALLBACK CallBackFunction
,
39 EFI_HOB_GUID_TYPE
*GuidHob
;
40 PCD_PPI_CALLBACK
*CallbackTable
;
41 PCD_PPI_CALLBACK Compare
;
42 PCD_PPI_CALLBACK Assign
;
43 UINT32 LocalTokenNumber
;
48 TokenNumber
= ExTokenNumber
;
51 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
52 // We have to decrement TokenNumber by 1 to make it usable
53 // as the array index.
56 ASSERT (TokenNumber
< PEI_NEX_TOKEN_NUMBER
);
58 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
61 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
62 // We have to decrement TokenNumber by 1 to make it usable
63 // as the array index.
66 ASSERT (TokenNumber
< PEI_LOCAL_TOKEN_NUMBER
);
70 LocalTokenNumber
= GetPcdDatabase()->Init
.LocalTokenNumberTable
[TokenNumber
];
72 ASSERT ((LocalTokenNumber
& PCD_TYPE_HII
) == 0);
73 ASSERT ((LocalTokenNumber
& PCD_TYPE_VPD
) == 0);
75 GuidHob
= GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid
);
76 ASSERT (GuidHob
!= NULL
);
78 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
79 CallbackTable
= CallbackTable
+ (TokenNumber
* FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
81 Compare
= Register
? NULL
: CallBackFunction
;
82 Assign
= Register
? CallBackFunction
: NULL
;
85 for (Idx
= 0; Idx
< FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
86 if (CallbackTable
[Idx
] == Compare
) {
87 CallbackTable
[Idx
] = Assign
;
92 return Register
? EFI_OUT_OF_RESOURCES
: EFI_NOT_FOUND
;
100 The function builds the PCD database based on the
101 PCD_IMAGE on the flash.
103 @param[in] PcdImageOnFlash The PCD image on flash.
112 PEI_PCD_DATABASE
*Database
;
113 VOID
*CallbackFnTable
;
114 UINTN SizeOfCallbackFnTable
;
116 Database
= BuildGuidHob (&gPcdDataBaseHobGuid
, sizeof (PEI_PCD_DATABASE
));
118 ZeroMem (Database
, sizeof (PEI_PCD_DATABASE
));
121 // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE
124 CopyMem (&Database
->Init
, &gPEIPcdDbInit
, sizeof (gPEIPcdDbInit
));
126 SizeOfCallbackFnTable
= PEI_LOCAL_TOKEN_NUMBER
* sizeof (PCD_PPI_CALLBACK
) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
);
128 CallbackFnTable
= BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid
, SizeOfCallbackFnTable
);
130 ZeroMem (CallbackFnTable
, SizeOfCallbackFnTable
);
138 The function is provided by PCD PEIM and PCD DXE driver to
139 do the work of reading a HII variable from variable service.
141 @param[in] VariableGuid The Variable GUID.
142 @param[in] VariableName The Variable Name.
143 @param[out] VariableData The output data.
144 @param[out] VariableSize The size of the variable.
146 @retval EFI_SUCCESS Operation successful.
147 @retval EFI_SUCCESS Variablel not found.
151 IN CONST EFI_GUID
*VariableGuid
,
152 IN UINT16
*VariableName
,
153 OUT VOID
**VariableData
,
154 OUT UINTN
*VariableSize
160 EFI_PEI_READ_ONLY_VARIABLE_PPI
*VariablePpi
;
162 Status
= PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid
, 0, NULL
, (VOID
**) &VariablePpi
);
163 ASSERT_EFI_ERROR (Status
);
166 Status
= VariablePpi
->PeiGetVariable (
167 GetPeiServicesTablePointer (),
169 (EFI_GUID
*) VariableGuid
,
174 if (Status
== EFI_BUFFER_TOO_SMALL
) {
177 Status
= PeiServicesAllocatePool (Size
, &Buffer
);
178 ASSERT_EFI_ERROR (Status
);
180 Status
= VariablePpi
->PeiGetVariable (
181 GetPeiServicesTablePointer (),
182 (UINT16
*) VariableName
,
183 (EFI_GUID
*) VariableGuid
,
188 ASSERT_EFI_ERROR (Status
);
190 *VariableSize
= Size
;
191 *VariableData
= Buffer
;
195 return EFI_NOT_FOUND
;
202 GetSkuEnabledTokenNumber (
203 UINT32 LocalTokenNumber
,
207 PEI_PCD_DATABASE
*PeiPcdDb
;
213 PeiPcdDb
= GetPcdDatabase ();
215 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0);
217 SkuHead
= (SKU_HEAD
*) ((UINT8
*)PeiPcdDb
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
218 Value
= (UINT8
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuDataStartOffset
));
219 SkuIdTable
= (SKU_ID
*) ((UINT8
*)PeiPcdDb
+ (SkuHead
->SkuIdTableOffset
));
221 for (i
= 0; i
< SkuIdTable
[0]; i
++) {
222 if (PeiPcdDb
->Init
.SystemSkuId
== SkuIdTable
[i
+ 1]) {
227 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
229 Value
+= sizeof(VPD_HEAD
) * i
;
230 return ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_VPD
);
233 Value
+= sizeof(VARIABLE_HEAD
) * i
;
234 return ((Value
- (UINT8
*) PeiPcdDb
) | PCD_TYPE_HII
);
238 return (Value
- (UINT8
*) PeiPcdDb
);
254 InvokeCallbackOnSet (
255 UINT32 ExTokenNumber
,
256 CONST EFI_GUID
*Guid
, OPTIONAL
262 EFI_HOB_GUID_TYPE
*GuidHob
;
263 PCD_PPI_CALLBACK
*CallbackTable
;
267 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
268 // We have to decrement TokenNumber by 1 to make it usable
269 // as the array index.
274 ASSERT (TokenNumber
< PEI_LOCAL_TOKEN_NUMBER
);
276 GuidHob
= GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid
);
277 ASSERT (GuidHob
!= NULL
);
279 CallbackTable
= GET_GUID_HOB_DATA (GuidHob
);
281 CallbackTable
+= (TokenNumber
* FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
));
283 for (Idx
= 0; Idx
< FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry
); Idx
++) {
284 if (CallbackTable
[Idx
] != NULL
) {
285 CallbackTable
[Idx
] (Guid
,
286 (Guid
== NULL
)? TokenNumber
: ExTokenNumber
,
306 UINT32 LocalTokenNumber
;
307 PEI_PCD_DATABASE
*PeiPcdDb
;
308 UINT16 StringTableIdx
;
313 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
314 // We have to decrement TokenNumber by 1 to make it usable
315 // as the array index.
319 ASSERT (TokenNumber
< PEI_LOCAL_TOKEN_NUMBER
);
321 PeiPcdDb
= GetPcdDatabase ();
323 LocalTokenNumber
= PeiPcdDb
->Init
.LocalTokenNumberTable
[TokenNumber
];
326 ASSERT (PeiPcdDb
->Init
.SizeTable
[TokenNumber
] >= Size
);
328 ASSERT (PeiPcdDb
->Init
.SizeTable
[TokenNumber
] == Size
);
332 // We only invoke the callback function for Dynamic Type PCD Entry.
333 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
334 // type PCD entry in ExSetWorker.
336 if (TokenNumber
< PEI_NEX_TOKEN_NUMBER
) {
337 InvokeCallbackOnSet (0, NULL
, TokenNumber
+ 1, Data
, Size
);
340 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
341 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, Size
);
344 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
345 InternalData
= (VOID
*) ((UINT8
*) PeiPcdDb
+ Offset
);
347 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
352 return EFI_INVALID_PARAMETER
;
355 case PCD_TYPE_STRING
:
356 StringTableIdx
= *((UINT16
*)InternalData
);
357 CopyMem (&PeiPcdDb
->Init
.StringTable
[StringTableIdx
], Data
, Size
);
364 CopyMem (InternalData
, Data
, Size
);
370 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
374 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
378 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
382 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
387 return EFI_NOT_FOUND
;
394 return EFI_NOT_FOUND
;
403 IN UINTN ExTokenNumber
,
404 IN CONST EFI_GUID
*Guid
,
412 TokenNumber
= GetExPcdTokenNumber (Guid
, ExTokenNumber
);
414 InvokeCallbackOnSet (ExTokenNumber
, Guid
, TokenNumber
, Data
, Size
);
416 SetWorker (TokenNumber
, Data
, Size
, PtrType
);
427 IN CONST EFI_GUID
*Guid
,
428 IN UINTN ExTokenNumber
,
432 return GetWorker (GetExPcdTokenNumber (Guid
, ExTokenNumber
), GetSize
);
447 VARIABLE_HEAD
*VariableHead
;
452 UINT16 StringTableIdx
;
453 PEI_PCD_DATABASE
*PeiPcdDb
;
454 UINT32 LocalTokenNumber
;
458 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
459 // We have to decrement TokenNumber by 1 to make it usable
460 // as the array index.
464 ASSERT (TokenNumber
< PEI_LOCAL_TOKEN_NUMBER
);
466 Size
= PeiPcdGetSize(TokenNumber
+ 1);
468 ASSERT (GetSize
== Size
|| GetSize
== 0);
470 PeiPcdDb
= GetPcdDatabase ();
472 LocalTokenNumber
= PeiPcdDb
->Init
.LocalTokenNumberTable
[TokenNumber
];
474 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
475 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, Size
);
478 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
479 StringTable
= PeiPcdDb
->Init
.StringTable
;
481 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
485 VpdHead
= (VPD_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
486 return (VOID
*) (FixedPcdGet32(PcdVpdBaseAddress
) + VpdHead
->Offset
);
491 VariableHead
= (VARIABLE_HEAD
*) ((UINT8
*)PeiPcdDb
+ Offset
);
493 Guid
= &(PeiPcdDb
->Init
.GuidTable
[VariableHead
->GuidTableIndex
]);
494 Name
= &StringTable
[VariableHead
->StringIndex
];
496 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
498 if (Status
== EFI_SUCCESS
) {
499 ASSERT (DataSize
>= (UINTN
) (VariableHead
->Offset
+ Size
));
500 return (VOID
*) ((UINT8
*) Data
+ VariableHead
->Offset
);
503 // Return the default value specified by Platform Integrator
505 return (VOID
*) ((UINT8
*) PeiPcdDb
+ VariableHead
->DefaultValueOffset
);
510 return (VOID
*) ((UINT8
*)PeiPcdDb
+ Offset
);
512 case PCD_TYPE_STRING
:
513 StringTableIdx
= (UINT16
) *((UINT8
*) PeiPcdDb
+ Offset
);
514 return (VOID
*) (&StringTable
[StringTableIdx
]);
530 GetExPcdTokenNumber (
531 IN CONST EFI_GUID
*Guid
,
532 IN UINT32 ExTokenNumber
536 DYNAMICEX_MAPPING
*ExMap
;
540 PEI_PCD_DATABASE
*PeiPcdDb
;
542 PeiPcdDb
= GetPcdDatabase();
544 ExMap
= PeiPcdDb
->Init
.ExMapTable
;
545 GuidTable
= PeiPcdDb
->Init
.GuidTable
;
547 MatchGuid
= ScanGuid (GuidTable
, sizeof(PeiPcdDb
->Init
.GuidTable
), Guid
);
548 ASSERT (MatchGuid
!= NULL
);
550 MatchGuidIdx
= MatchGuid
- GuidTable
;
552 for (i
= 0; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
553 if ((ExTokenNumber
== ExMap
[i
].ExTokenNumber
) &&
554 (MatchGuidIdx
== ExMap
[i
].ExGuidIndex
)) {
555 return ExMap
[i
].LocalTokenNumber
;
571 EFI_HOB_GUID_TYPE
*GuidHob
;
573 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
574 ASSERT (GuidHob
!= NULL
);
576 return (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);