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
17 #include "../Common/PcdCommon.h"
24 This function expand the StateByte
26 @param[out] StateByte The output StateByte information.
27 @param[in] Byte The StateByte.
32 PcdImageExpandStateByte (
33 OUT PCD_STATEBYTE
*StateByte
,
37 switch (Byte
& PCD_STATEBYTE_DATUMTYPE
) {
39 StateByte
->DataType
= PcdByte8
;
42 StateByte
->DataType
= PcdByte16
;
45 StateByte
->DataType
= PcdByte32
;
48 StateByte
->DataType
= PcdByte64
;
51 StateByte
->DataType
= PcdPointer
;
54 StateByte
->DataType
= PcdBoolean
;
60 StateByte
->ExtendedGuidPresent
= (BOOLEAN
) ((Byte
& PCD_STATEBYTE_EXTENDEDGUIDPRESENT
) != 0);
61 StateByte
->HiiEnable
= (BOOLEAN
) ((Byte
& PCD_STATEBYTE_HIIENABLE
) != 0);
62 StateByte
->SkuDataArrayEnable
= (BOOLEAN
) ((Byte
& PCD_STATEBYTE_SKUDATAARRAYENABLE
) != 0);
63 StateByte
->SkuEnable
= (BOOLEAN
) ((Byte
& PCD_STATEBYTE_SKUENABLE
) != 0);
64 StateByte
->VpdEnable
= (BOOLEAN
) ((Byte
& PCD_STATEBYTE_VPDENABLE
) != 0);
71 This function locates the <PCD_IMAGE> on the flash and
72 return a pointer to the Section Data on flash.
84 EFI_FIRMWARE_VOLUME_HEADER
*FvHdr
;
85 EFI_FFS_FILE_HEADER
*FfsHdr
;
88 Status
= PeiCoreFfsFindNextVolume (0, &FvHdr
);
89 ASSERT_EFI_ERROR (Status
);
93 Status
= PeiCoreFfsFindNextFile (EFI_FV_FILETYPE_FREEFORM
, FvHdr
, &FfsHdr
);
94 if (Status
== EFI_SUCCESS
) {
95 if (CompareGuid (&gPcdImageFileGuid
, &FfsHdr
->Name
)) {
97 Status
= PeiCoreFfsFindSectionData (EFI_SECTION_RAW
, FfsHdr
, &SectionData
);
98 ASSERT_EFI_ERROR (Status
);
100 return (UINT8
*)SectionData
;
103 } while (Status
== EFI_SUCCESS
);
111 The function retrieves the PCD data value according to
112 TokenNumber and Guid space given.
114 @param[in] TokenNumber The token number.
115 @param[in] Guid The Guid space.
116 @param[in] Type The storage type.
117 @param[out] Data The output data.
120 @retval EFI_SUCESS If data value is found according to SKU_ID.
121 @retval EFI_NOT_FOUND If not such a value is found.
125 PeiGetPcdEntryWorker (
126 IN UINTN TokenNumber
,
127 IN CONST EFI_GUID
*Guid
, OPTIONAL
128 IN PCD_DATA_TYPE Type
,
132 PCD_DATABASE
*Database
;
133 EFI_HOB_GUID_TYPE
*GuidHob
;
135 ASSERT (Data
!= NULL
);
137 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
138 ASSERT (GuidHob
!= NULL
);
140 Database
= GET_GUID_HOB_DATA (GuidHob
);
142 GetPcdEntryWorker ( &Database
->Info
,
155 The function set the PCD data value according to
156 TokenNumber and Guid space given.
158 @param[in] Database The PCD Database Instance.
159 @param[in] TokenNumber The token number.
160 @param[in] Guid The Guid space.
161 @param[in] Type The storage type.
162 @param[in] Data The output data.
165 @retval EFI_SUCESS If data value is found according to SKU_ID.
166 @retval EFI_NOT_FOUND If not such a value is found.
171 IN CONST PCD_DATABASE
*Database
,
172 IN UINTN TokenNumber
,
173 IN CONST EFI_GUID
*Guid
, OPTIONAL
174 IN PCD_DATA_TYPE Type
,
180 PCD_PPI_CALLBACK
*CallbackTable
;
183 ASSERT (Data
!= NULL
);
186 // Find the PCD entry in list in memory first
188 PcdIndex
= FindPcdIndex (TokenNumber
, Guid
, &Database
->Info
, &Idx
);
190 ASSERT (PcdIndex
!= NULL
);
192 ASSERT (PcdIndex
->StateByte
.DataType
== Type
);
195 // Invoke the callback function.
197 CallbackTable
= (PCD_PPI_CALLBACK
*)
198 GetAbsoluteAddress (Idx
* Database
->Info
.MaxCallbackNum
* sizeof(PCD_PPI_CALLBACK
),
199 Database
->Info
.CallbackTableOffset
,
203 for (Idx
= 0; Idx
< Database
->Info
.MaxCallbackNum
; Idx
++) {
204 if (CallbackTable
[Idx
] != NULL
) {
205 CallbackTable
[Idx
] (Guid
,
206 PcdIndex
->TokenNumber
,
213 Status
= SetPcdData (PcdIndex
, &Database
->Info
, Data
);
221 (reviewed) The function set the PCD data value according to
222 TokenNumber and Guid space given.
224 @param[in] TokenNumber The token number.
225 @param[in] Guid The Guid space.
226 @param[in] Type The storage type.
227 @param[in] Data The output data.
230 @retval EFI_SUCESS If data value is found according to SKU_ID.
231 @retval EFI_NOT_FOUND If not such a value is found.
235 PeiSetPcdEntryWorker (
236 IN UINTN TokenNumber
,
237 IN CONST EFI_GUID
*Guid
, OPTIONAL
238 IN PCD_DATA_TYPE Type
,
242 PCD_DATABASE
*Database
;
243 EFI_HOB_GUID_TYPE
*GuidHob
;
245 ASSERT (Data
!= NULL
);
247 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
248 ASSERT (GuidHob
!= NULL
);
250 Database
= GET_GUID_HOB_DATA (GuidHob
);
252 SetPcdEntryWorker (Database
,
265 PeiGetPcdEntrySizeWorker (
266 IN UINTN TokenNumber
,
267 IN CONST EFI_GUID
*Guid OPTIONAL
270 PCD_DATABASE
*Database
;
271 EFI_HOB_GUID_TYPE
*GuidHob
;
273 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
274 ASSERT (GuidHob
!= NULL
);
276 Database
= GET_GUID_HOB_DATA (GuidHob
);
278 return GetPcdEntrySizeWorker (&Database
->Info
,
288 The function registers the CallBackOnSet fucntion
289 according to TokenNumber and EFI_GUID space.
291 @param[in] TokenNumber The token number.
292 @param[in] Guid The GUID space.
293 @param[in] CallBackFunction The Callback function to be registered.
295 @retval EFI_SUCCESS If the Callback function is registered.
296 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.
299 PeiRegisterCallBackWorker (
300 IN UINTN TokenNumber
,
301 IN CONST EFI_GUID
*Guid
, OPTIONAL
302 IN PCD_PPI_CALLBACK CallBackFunction
,
306 PCD_DATABASE
*Database
;
307 EFI_HOB_GUID_TYPE
*GuidHob
;
310 PCD_PPI_CALLBACK
*CallbackTable
;
311 PCD_PPI_CALLBACK Compare
;
312 PCD_PPI_CALLBACK Assign
;
314 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
315 ASSERT (GuidHob
!= NULL
);
317 Database
= GET_GUID_HOB_DATA (GuidHob
);
319 PcdIndex
= FindPcdIndex (TokenNumber
, Guid
, &Database
->Info
, NULL
);
321 ASSERT (PcdIndex
!= NULL
);
323 if (PcdIndex
->StateByte
.VpdEnable
) {
324 return EFI_INVALID_PARAMETER
;
327 Idx
= ((UINTN
) PcdIndex
- Database
->Info
.CallbackTableOffset
) / sizeof(PCD_INDEX
);
329 CallbackTable
= (PCD_PPI_CALLBACK
*) GetAbsoluteAddress (
330 sizeof (PCD_PPI_CALLBACK
) * Idx
* Database
->Info
.MaxCallbackNum
,
331 Database
->Info
.CallbackTableOffset
,
335 Compare
= Register
? NULL
: CallBackFunction
;
336 Assign
= Register
? CallBackFunction
: NULL
;
338 for (Idx
= 0; Idx
< Database
->Info
.MaxCallbackNum
; Idx
++) {
339 if (CallbackTable
[Idx
] == Compare
) {
340 CallbackTable
[Idx
] = Assign
;
345 return Register
? EFI_OUT_OF_RESOURCES
: EFI_NOT_FOUND
;
352 PeiGetNextTokenWorker (
353 IN OUT UINTN
*TokenNumber
,
354 IN CONST EFI_GUID
*Guid OPTIONAL
357 PCD_DATABASE
*Database
;
358 EFI_HOB_GUID_TYPE
*GuidHob
;
360 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
361 ASSERT (GuidHob
!= NULL
);
363 Database
= GET_GUID_HOB_DATA (GuidHob
);
365 return GetNextTokenWorker (&Database
->Info
,
376 IN CONST UINT8
*PcdImageOnFlash
,
377 OUT PCD_IMAGE_RECORD
*ImageInfo
380 PCD_FFS_ENCODING
*PcdFfsHdr
;
382 PcdFfsHdr
= (PCD_FFS_ENCODING
*) PcdImageOnFlash
;
384 ZeroMem (ImageInfo
, sizeof (*ImageInfo
));
386 ImageInfo
->ImageStart
= PcdImageOnFlash
;
388 CopyMem (&ImageInfo
->EntryCount
, PcdFfsHdr
->EntryCount
, 3);
390 CopyMem (&ImageInfo
->GlobalDatumLength
, PcdFfsHdr
->GlobalDatumLength
, 1);
391 ASSERT (ImageInfo
->GlobalDatumLength
<= 3);
393 CopyMem (&ImageInfo
->GlobalOffsetLength
, PcdFfsHdr
->GlobalOffsetLength
, 1);
394 ASSERT (ImageInfo
->GlobalOffsetLength
<= 3);
396 CopyMem (&ImageInfo
->GlobalTokenLength
, PcdFfsHdr
->GlobalTokenLength
, 1);
397 ASSERT (ImageInfo
->GlobalTokenLength
<= 4);
399 CopyMem (&ImageInfo
->GlobalGuidTabIdxLength
, PcdFfsHdr
->GuidLength
, 1);
400 ASSERT (ImageInfo
->GlobalGuidTabIdxLength
<= 2);
402 CopyMem (&ImageInfo
->GlobalStrTabIdxLength
, PcdFfsHdr
->GlobalStrTabIdxLength
, 1);
403 ASSERT (ImageInfo
->GlobalStrTabIdxLength
<= 2);
405 CopyMem (&ImageInfo
->ImageLength
, PcdFfsHdr
->ImageLength
, 3);
406 CopyMem (&ImageInfo
->IndexLength
, PcdFfsHdr
->PcdIndexLength
, 3);
407 CopyMem (&ImageInfo
->WholeDataDefaultLength
, PcdFfsHdr
->WholeDataBufferLength
, 3);
408 CopyMem (&ImageInfo
->DataDefaultLength
, PcdFfsHdr
->DataBufferLength
, 3);
409 CopyMem (&ImageInfo
->GuidTableLength
, PcdFfsHdr
->GuidTableLength
, 3);
411 ImageInfo
->StringTableLength
= ImageInfo
->ImageLength
412 - sizeof (PCD_FFS_ENCODING
)
413 - ImageInfo
->DataDefaultLength
414 - ImageInfo
->IndexLength
415 - ImageInfo
->GuidTableLength
;
417 ImageInfo
->DataDefaultStart
= PcdImageOnFlash
+ sizeof (PCD_FFS_ENCODING
);
418 ImageInfo
->IndexStart
= ImageInfo
->DataDefaultStart
+ ImageInfo
->DataDefaultLength
;
419 ImageInfo
->GuidTableStart
= (CONST EFI_GUID
*)(ImageInfo
->IndexStart
+ ImageInfo
->IndexLength
);
420 ImageInfo
->StringTableStart
= (CONST UINT16
*) ((UINT8
*) ImageInfo
->GuidTableStart
+ ImageInfo
->GuidTableLength
);
428 The function builds the PCD database based on the
429 PCD_IMAGE on the flash.
431 The layout of the PCD_DATABASE is as follows:
433 ---------------------------
434 | PCD_DATABASE_HEADER |
435 ---------------------------
436 | GUID_TABLE | Aligned on GUID (128 bits)
437 ---------------------------
438 | PCD_CALL_BACK_TABLE | Aligned on Pointer (32 bits or 64 bits)
439 ---------------------------
440 | PCD_INDEX_TABLE | Aligned on PCD_INDEX (see PCD_INDEX's declaration)
441 ---------------------------
442 | IMAGE_STRING_TABLE | Aligned on 16 Bits
443 ---------------------------
444 | IMAGE_PCD_INDEX | Unaligned
445 ---------------------------
446 | Data Defaults | Unaligned
447 ---------------------------
449 | for entries without |
451 ---------------------------
453 @param[in] PcdImageOnFlash The PCD image on flash.
459 IN CONST UINT8
*PcdImageOnFlash
,
460 OUT PCD_DATABASE_HEADER
*Info
,
461 OUT PCD_IMAGE_RECORD
*ImageInfo
465 UINTN DatabaseHeaderLength
;
466 UINTN PcdIndexLength
;
467 UINTN CallbackBufferLength
;
470 GetPcdImageInfo (PcdImageOnFlash
, ImageInfo
);
472 Info
->MaxCallbackNum
= FixedPcdGet32(PcdMaxPcdCallBackNumber
) ;
474 DatabaseHeaderLength
= sizeof (PCD_DATABASE
) - sizeof(UINT8
);
476 PcdIndexLength
= sizeof (PCD_INDEX
) * ImageInfo
->EntryCount
;
477 CallbackBufferLength
= sizeof (PCD_PPI_CALLBACK
) * Info
->MaxCallbackNum
* ImageInfo
->EntryCount
;
479 Info
->EntryCount
= ImageInfo
->EntryCount
;
480 Info
->GuidTableOffset
= DatabaseHeaderLength
;
481 Info
->CallbackTableOffset
= Info
->GuidTableOffset
+ ImageInfo
->GuidTableLength
;
482 Info
->PcdIndexOffset
= Info
->PcdIndexOffset
+ PcdIndexLength
;
483 Info
->ImageIndexOffset
= Info
->CallbackTableOffset
+ CallbackBufferLength
;
484 Info
->DataBufferOffset
= Info
->ImageIndexOffset
+ ImageInfo
->DataDefaultLength
;
486 Info
->HiiGuidOffsetLength
= ImageInfo
->GlobalGuidTabIdxLength
;
487 Info
->HiiVariableOffsetLength
= ImageInfo
->GlobalStrTabIdxLength
;
488 Info
->ExtendedOffsetLength
= ImageInfo
->GlobalOffsetLength
;
492 DatabaseLen
= DatabaseHeaderLength
493 + ImageInfo
->GuidTableLength
495 + CallbackBufferLength
496 + ImageInfo
->IndexLength
497 + ImageInfo
->WholeDataDefaultLength
;
499 Info
->DatabaseLen
= DatabaseLen
;
506 The function constructs a single PCD_INDEX according a index in
509 @param[in] ImageIndex The starting address of a PCD index defined in PCD spec 0.51.
510 @param[in] Index The output PCD_INDEX.
511 @param[in] ImageInfo The attributes of the PCD_IMAGE as this binary stream is highly
514 @retval UINTN The length of the current PCD index.
518 IN CONST UINT8
*ImageIndex
,
519 OUT PCD_INDEX
*Index
,
520 IN CONST PCD_IMAGE_RECORD
*ImageInfo
524 CONST UINT8
*ImageIndexBackUp
;
526 ImageIndexBackUp
= ImageIndex
;
531 CopyMem (&Index
->TokenNumber
,
533 ImageInfo
->GlobalTokenLength
536 ImageIndex
+= ImageInfo
->GlobalTokenLength
;
541 PcdImageExpandStateByte (&Index
->StateByte
,
550 CopyMem (&Index
->DatumSize
,
552 ImageInfo
->GlobalDatumLength
555 ImageIndex
+= ImageInfo
->GlobalDatumLength
;
560 if (Index
->StateByte
.SkuEnable
) {
561 Index
->SkuCount
= *ImageIndex
;
562 SkuCount
= *ImageIndex
;
564 Index
->SkuIdArray
= (UINT32
) ImageIndex
- (UINT32
) ImageInfo
->IndexStart
;
565 ImageIndex
+= Index
->SkuCount
;
568 // There is always a default SKU_ID of zero even
569 // if SKU is not enabled for this PCD entry.
578 CopyMem (&Index
->ExtendedDataOffset
,
580 ImageInfo
->GlobalOffsetLength
583 ImageIndex
+= ImageInfo
->GlobalOffsetLength
* SkuCount
;
586 // DynamicEX Guid Offset
588 if (Index
->StateByte
.ExtendedGuidPresent
) {
589 CopyMem (&Index
->DynamicExGuid
,
591 ImageInfo
->GlobalGuidTabIdxLength
594 ImageIndex
+= ImageInfo
->GlobalGuidTabIdxLength
;
600 if (Index
->StateByte
.HiiEnable
) {
601 Index
->HiiData
= (UINT32
) ImageIndex
- (UINT32
) ImageInfo
->IndexStart
;
602 ImageIndex
+= ((ImageInfo
->GlobalStrTabIdxLength
+ ImageInfo
->GlobalGuidTabIdxLength
) * SkuCount
);
605 return (UINTN
) (ImageIndex
- ImageIndexBackUp
);
612 The function builds the PCD database based on the
613 PCD_IMAGE on the flash.
615 @param[in] Database The database instance.
616 @param[in] ImageIndex The starting address of a PCD index defined in PCD spec 0.51.
617 @param[in] ImageInfo The attributes of the PCD_IMAGE as this binary stream is highly
623 BuildPcdDatabaseIndex (
624 PCD_DATABASE
*Database
,
626 PCD_IMAGE_RECORD
*ImageInfo
631 PCD_INDEX
*IndexTable
;
633 IndexTable
= (PCD_INDEX
*) GetAbsoluteAddress (0, Database
->Info
.PcdIndexOffset
, Database
);
635 for (Idx
= 0; Idx
< Database
->Info
.EntryCount
; Idx
++) {
636 Len
= BuildPcdIndex (ImageIndex
, &IndexTable
[Idx
], ImageInfo
);
645 The function builds the PCD database based on the
646 PCD_IMAGE on the flash.
648 @param[in] PcdImageOnFlash The PCD image on flash.
654 UINT8
*PcdImageOnFlash
657 PCD_DATABASE
*Database
;
659 PCD_IMAGE_RECORD ImageInfo
;
661 PCD_DATABASE_HEADER DatabaseHeader
;
663 Len
= GetPcdDatabaseLen(PcdImageOnFlash
, &DatabaseHeader
, &ImageInfo
);
665 Database
= BuildGuidHob (&gPcdDataBaseHobGuid
, Len
);
666 ASSERT (Database
!= NULL
);
668 ZeroMem (Database
, Len
);
671 // Update Database header
673 CopyMem (&Database
->Info
, &DatabaseHeader
, sizeof (DatabaseHeader
));
676 // I need this to get the GuidTableOffset as we don't
677 // know if Database field of PCD_DATABASE starts from an aligned
678 // address. The compilor may add padding after PCD_DATABASE_HEADER field.
680 Database
->Info
.GuidTableOffset
= ((UINTN
) &Database
->GuidTable
) - (UINTN
)Database
;
683 // Copy Guid Table from Flash
685 CopyMem ((UINT8
*) Database
+ Database
->Info
.GuidTableOffset
,
686 ImageInfo
.GuidTableStart
,
687 ImageInfo
.GuidTableLength
691 // Copy ImageIndex from Flash
693 CopyMem ((UINT8
*) Database
+ Database
->Info
.ImageIndexOffset
,
694 ImageInfo
.IndexStart
,
695 ImageInfo
.IndexLength
699 // Copy Default Value
701 CopyMem ((UINT8
*) Database
+ Database
->Info
.DataBufferOffset
,
702 ImageInfo
.DataDefaultStart
,
703 ImageInfo
.DataDefaultLength
709 CopyMem ((UINT8
*) Database
+ Database
->Info
.StringTableOffset
,
710 ImageInfo
.StringTableStart
,
711 ImageInfo
.StringTableLength
714 ImageIndex
= GetAbsoluteAddress (0, Database
->Info
.ImageIndexOffset
, Database
);
716 BuildPcdDatabaseIndex (Database
, ImageIndex
, &ImageInfo
);
724 The function is provided by PCD PEIM and PCD DXE driver to
725 do the work of reading a HII variable from variable service.
727 @param[in] VariableGuid The Variable GUID.
728 @param[in] VariableName The Variable Name.
729 @param[out] VariableData The output data.
730 @param[out] VariableSize The size of the variable.
732 @retval EFI_SUCCESS Operation successful.
733 @retval EFI_SUCCESS Variablel not found.
737 IN EFI_GUID
*VariableGuid
,
738 IN UINT16
*VariableName
,
739 OUT VOID
**VariableData
,
740 OUT UINTN
*VariableSize
746 EFI_PEI_READ_ONLY_VARIABLE_PPI
*VariablePpi
;
748 Status
= PeiCoreLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid
, 0, NULL
, &VariablePpi
);
749 ASSERT_EFI_ERROR (Status
);
753 Status
= VariablePpi
->PeiGetVariable (
754 GetPeiServicesTablePointer (),
761 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
763 Status
= PeiCoreAllocatePool (Size
, &Buffer
);
764 ASSERT_EFI_ERROR (Status
);
766 // declare a local for STP.
768 Status
= VariablePpi
->PeiGetVariable (
769 GetPeiServicesTablePointer (),
770 (UINT16
*) VariableName
,
776 ASSERT_EFI_ERROR (Status
);
778 *VariableSize
= Size
;
779 *VariableData
= Buffer
;
787 The function is provided by PCD PEIM and PCD DXE driver to
788 do the work of reading a HII variable from variable service.
790 @param[in] VariableGuid The Variable GUID.
791 @param[in] VariableName The Variable Name.
792 @param[in] Data The input data.
793 @param[out] VariableSize The size of the variable.
794 @param[in] Offset The offset of the variable data that a PCD entry will starts from.
796 @retval EFI_SUCCESS Operation successful.
797 @retval EFI_SUCCESS Variablel not found.
801 IN EFI_GUID
*VariableGuid
,
802 IN UINT16
*VariableName
,
804 IN UINTN VariableSize
,
809 return EFI_INVALID_PARAMETER
;