2 Common functions used by PCD PEIM and PCD DXE.
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: PcdCommon.c
17 #include "PcdCommon.h"
22 The function retrieves the PCD data value according to
23 the PCD_DATA_TYPE specified.
25 @param[in] Type The PCD_DATA_TYPE used to interpret the data.
26 @param[in] InData The input data.
27 @param[in] OutData The output data.
28 @param[in] Len The length of the data; it is mainly used for PcdPointer type.
34 IN PCD_DATA_TYPE Type
,
40 if (Type
== PcdPointer
) {
42 // When the Type is PcdPointer, we are returning
43 // the address of the internal buffer kpet by
44 // PCD database. Therefore, we treat OutData as
45 // a pointer to a "VOID *". Thus, the ugly type cast
49 *((VOID
**) OutData
) = InData
;
51 CopyMem (OutData
, InData
, Len
);
59 GetExtendedDataOffset (
60 IN CONST PCD_INDEX
*PcdIndex
,
62 IN CONST PCD_DATABASE_HEADER
*Info
68 OffsetAddress
= GetAbsoluteAddress (PcdIndex
->ExtendedDataOffset
,
69 Info
->ImageIndexOffset
,
73 OffsetAddress
+= (SkuIdx
* Info
->ExtendedOffsetLength
);
76 CopyMem (&Offset
, OffsetAddress
, Info
->ExtendedOffsetLength
);
85 IN CONST PCD_INDEX
*PcdIndex
,
87 IN CONST PCD_DATABASE_HEADER
*Info
,
88 OUT EFI_GUID
**VariableGuid
,
89 OUT UINT16
**VariableName
96 HiiDataOffset
= GetAbsoluteAddress (PcdIndex
->HiiData
, Info
->ImageIndexOffset
, Info
);
97 HiiDataOffset
+= (SkuIdx
* (Info
->HiiGuidOffsetLength
+ Info
->HiiVariableOffsetLength
));
99 CopyMem (&GuidOffset
, HiiDataOffset
, Info
->HiiGuidOffsetLength
);
100 CopyMem (&NameOffset
, HiiDataOffset
+ Info
->HiiGuidOffsetLength
, Info
->HiiVariableOffsetLength
);
102 *VariableGuid
= (EFI_GUID
*) GetAbsoluteAddress (GuidOffset
* sizeof (EFI_GUID
), Info
->GuidTableOffset
, Info
);
103 *VariableName
= (UINT16
*) GetAbsoluteAddress (NameOffset
* sizeof (UINT16
) , Info
->StringTableOffset
, Info
);
112 IN CONST PCD_INDEX
*PcdIndex
,
113 IN CONST PCD_DATABASE_HEADER
*Info
119 SkuIdArray
= GetAbsoluteAddress (PcdIndex
->SkuIdArray
, Info
->ImageIndexOffset
, Info
);
123 if (PcdIndex
->StateByte
.SkuEnable
) {
125 for (; SkuIdx
< PcdIndex
->SkuCount
; SkuIdx
++) {
126 if (SkuIdArray
[SkuIdx
] == Info
->SkuId
) {
131 if (SkuIdx
> PcdIndex
->SkuCount
) {
132 if (Info
->SkuId
== 0) {
134 // If no SKU_ID is set previously
135 // Just retrieve the first value
140 // Just can't find the SKU_ID, ASSERT according to Spec.
155 The function is the worker function to get the data of a PCD entry.
157 @param[in] PcdIndex The PCD Index.
158 @param[in] Info The attributes of the PCD database.
159 @param[out] Data The output data.
165 IN CONST PCD_INDEX
*PcdIndex
,
166 IN CONST PCD_DATABASE_HEADER
*Info
169 UINTN VariableDataSize
;
171 UINT16
*VariableName
;
173 EFI_GUID
*VariableGuid
;
176 UINTN ExtendedOffset
;
179 // If Sku is not enalbed for this PCD Entry.
180 // SkuIdx 0 will be used to compute PcdData
182 SkuIdx
= GetSkuIdIdx (PcdIndex
, Info
);
184 if (PcdIndex
->StateByte
.HiiEnable
) {
186 GetHiiDataProperty (PcdIndex
, SkuIdx
, Info
, &VariableGuid
, &VariableName
);
188 Status
= GetHiiVariable (VariableGuid
, VariableName
, &VariableData
, &VariableDataSize
);
189 ASSERT_EFI_ERROR (Status
);
190 ASSERT (VariableDataSize
>= (PcdIndex
->DatumSize
+ PcdIndex
->ExtendedDataOffset
));
192 PcdData
= (UINT8
*) VariableData
+ PcdIndex
->ExtendedDataOffset
;
198 // For VPD and Data type, we need the ExtendedOffset.
201 ExtendedOffset
= GetExtendedDataOffset (PcdIndex
, SkuIdx
, Info
);
203 if (PcdIndex
->StateByte
.VpdEnable
) {
205 PcdData
= (VOID
*) (Info
->VpdStart
+ ExtendedOffset
);
211 // For data type, we just need the pointer
213 PcdData
= GetAbsoluteAddress (
215 Info
->DataBufferOffset
,
226 The function locates the PCD_INDEX according to TokeNumber and GUID space given.
228 @param[in] TokenNumber The token number.
229 @param[in] Guid The GUID token space.
230 @param[out] Info The attributes of the PCD database.
232 @retval PCD_INDEX* The PCD_INDEX found.
236 IN UINTN TokenNumber
,
237 IN CONST EFI_GUID
*Guid
,
238 IN CONST PCD_DATABASE_HEADER
*Info
,
246 PcdIndex
= (PCD_INDEX
*) GetAbsoluteAddress (0, Info
->PcdIndexOffset
, Info
);
248 for (Idx
= 0; Idx
< Info
->EntryCount
; Idx
++, PcdIndex
++) {
253 if (PcdIndex
->TokenNumber
== TokenNumber
) {
255 if (!PcdIndex
->StateByte
.ExtendedGuidPresent
) {
259 if (PcdIndex
->StateByte
.ExtendedGuidPresent
) {
260 GuidSpace
= (EFI_GUID
*) GetAbsoluteAddress (PcdIndex
->DynamicExGuid
, Info
->GuidTableOffset
, Info
);
261 if (CompareGuid (GuidSpace
, Guid
)) {
281 The function set the PCD Entry data value according to the
284 @param[out] OutData The output data.
285 @param[in] InData The input data.
286 @param[in] Len The length of the data.
289 @retval EFI_SUCESS If data value is found according to SKU_ID.
290 @retval EFI_NOT_FOUND If not such a value is found.
296 IN CONST VOID
* InData
,
300 CopyMem (OutData
, InData
, Len
);
308 The function returns the actual address of item in the PCD
309 database according to its Segment and Offset.
311 @param[out] Offset The offset within the segment.
312 @param[in] SegmentStart The starting address of the segment.
313 @param[in] DatabaseStart The base address of the PCD DataBase.
316 @retval UINT8* The absolute address.
322 IN UINTN SegmentStart
,
323 IN CONST PCD_DATABASE_HEADER
*DatabaseStart
328 Address
= (UINT8
*) DatabaseStart
+ SegmentStart
+ Offset
;
336 The function retrieves the PCD data value according to
337 TokenNumber and Guid space given.
339 @param[in] Database The PCD Database Instance.
340 @param[in] TokenNumber The token number.
341 @param[in] Guid The Guid space.
342 @param[in] Type The storage type.
343 @param[out] Data The output data.
350 IN CONST PCD_DATABASE_HEADER
*Info
,
351 IN UINTN TokenNumber
,
352 IN CONST EFI_GUID
*Guid
, OPTIONAL
353 IN PCD_DATA_TYPE Type
,
360 ASSERT (Data
!= NULL
);
363 // Find the PCD entry in list in memory first
365 PcdIndex
= FindPcdIndex (TokenNumber
, Guid
, Info
, NULL
);
367 ASSERT (PcdIndex
!= NULL
);
369 ASSERT (PcdIndex
->StateByte
.DataType
== Type
);
371 PcdData
= GetPcdDataPtr (PcdIndex
, Info
);
373 GetDataBasedOnType (PcdIndex
->StateByte
.DataType
, PcdData
, Data
, PcdIndex
->DatumSize
);
381 The function retrieves the PCD data value according to
382 TokenNumber and Guid space given.
384 @param[in] Database The PCD Database Instance.
385 @param[in] TokenNumber The token number.
386 @param[in] Guid The Guid space.
388 @retval UINTN The size of the PCD Entry.
392 GetPcdEntrySizeWorker (
393 IN CONST PCD_DATABASE_HEADER
*Info
,
394 IN UINTN TokenNumber
,
395 IN CONST EFI_GUID
*Guid OPTIONAL
401 // Find the PCD entry in list in memory first
403 PcdIndex
= FindPcdIndex (TokenNumber
, Guid
, Info
, NULL
);
405 ASSERT (PcdIndex
!= NULL
);
407 return PcdIndex
->DatumSize
;
414 The function checks if given GUID space match the record
417 @param[in] Guid The GUID space.
418 @param[in] PcdIndex The PCD_INDEX.
419 @param[in] Info The attribute of the PCD DATABASE.
421 @retval TRUE The GUID space match the record.
422 @retval FALSE Othewise.
426 PeiImageIndexMatchGuidSpace (
427 IN CONST EFI_GUID
*Guid
,
428 IN CONST PCD_INDEX
*PcdIndex
,
429 IN CONST PCD_DATABASE_HEADER
*Info
434 if (PcdIndex
->StateByte
.ExtendedGuidPresent
) {
435 GuidSpace
= (EFI_GUID
*) GetAbsoluteAddress (PcdIndex
->DynamicExGuid
, Info
->GuidTableOffset
, Info
);
436 return CompareGuid (GuidSpace
, Guid
);
444 The function looks for the next PCD ENTRY.
445 If *TokenNumber is 0, the first TokenNumber in
446 the GUID token space is return.
447 If there is no next TokenNumber found,
448 *TokenNumber will be 0.
450 @param[in] Database The PCD Database Instance.
451 @param[in,out] TokenNumber The token number.
452 @param[in] Guid The Guid space.
454 @retval EFI_NOT_FOUND Can't find the PCD_ENTRY.
455 @retval EFI_SUCCESS Operation succesful.
460 IN CONST PCD_DATABASE_HEADER
*Info
,
461 IN OUT UINTN
*TokenNumber
,
462 IN CONST EFI_GUID
*Guid OPTIONAL
471 PcdIndex
= (PCD_INDEX
*) GetAbsoluteAddress (0, Info
->PcdIndexOffset
, Info
);
473 while ((Idx
< Info
->EntryCount
) && !Found
) {
474 if (*TokenNumber
== 0) {
475 if (Guid
== NULL
|| PeiImageIndexMatchGuidSpace (Guid
, PcdIndex
, Info
)) {
476 *TokenNumber
= PcdIndex
->TokenNumber
;
480 if (PcdIndex
->TokenNumber
== *TokenNumber
) {
481 if (Guid
== NULL
|| PeiImageIndexMatchGuidSpace (Guid
, PcdIndex
, Info
)) {
492 // No PCD Entry in the database match the GUID space given.
494 if (*TokenNumber
== 0) {
499 // Can't find the PCD Entry
502 return EFI_NOT_FOUND
;
506 // Move to the Next Entry
512 // Now look for the Next TokenNumber
514 while (Idx
< Info
->EntryCount
) {
515 if (Guid
== NULL
|| PeiImageIndexMatchGuidSpace (Guid
, PcdIndex
, Info
)) {
516 *TokenNumber
= PcdIndex
->TokenNumber
;
524 // Reache the last TokeNumber.
532 The function is the worker function to set the data of a PCD entry.
534 @param[in] PcdIndex The PCD Index.
535 @param[in] Info The attributes of the PCD database.
536 @param[in] Data The input data.
542 IN CONST PCD_INDEX
*PcdIndex
,
543 IN CONST PCD_DATABASE_HEADER
*Info
,
547 UINT16
*VariableName
;
549 EFI_GUID
*VariableGuid
;
552 UINTN ExtendedOffset
;
554 if (PcdIndex
->StateByte
.VpdEnable
) {
556 return EFI_INVALID_PARAMETER
;
559 SkuIdx
= GetSkuIdIdx (PcdIndex
, Info
);
562 // For Hii and Data type, we need the ExtendedOffset.
565 ExtendedOffset
= GetExtendedDataOffset (PcdIndex
, SkuIdx
, Info
);
567 if (PcdIndex
->StateByte
.HiiEnable
) {
568 GetHiiDataProperty (PcdIndex
, SkuIdx
, Info
, &VariableGuid
, &VariableName
);
570 Status
= SetHiiVariable (VariableGuid
,
581 PcdData
= GetAbsoluteAddress (
583 Info
->DataBufferOffset
,
587 CopyMem (PcdData
, Data
, PcdIndex
->DatumSize
);