2 Pei Core Firmware File System service routines.
4 Copyright (c) 2015 HP Development Company, L.P.
5 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList
[] = {
20 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
21 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
22 FirmwareVolmeInfoPpiNotifyCallback
25 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
26 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
27 FirmwareVolmeInfoPpiNotifyCallback
31 PEI_FW_VOL_INSTANCE mPeiFfs2FwVol
= {
35 PeiFfsFvPpiProcessVolume
,
36 PeiFfsFvPpiFindFileByType
,
37 PeiFfsFvPpiFindFileByName
,
38 PeiFfsFvPpiGetFileInfo
,
39 PeiFfsFvPpiGetVolumeInfo
,
40 PeiFfsFvPpiFindSectionByType
,
41 PeiFfsFvPpiGetFileInfo2
,
42 PeiFfsFvPpiFindSectionByType2
,
43 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
,
44 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
48 PEI_FW_VOL_INSTANCE mPeiFfs3FwVol
= {
52 PeiFfsFvPpiProcessVolume
,
53 PeiFfsFvPpiFindFileByType
,
54 PeiFfsFvPpiFindFileByName
,
55 PeiFfsFvPpiGetFileInfo
,
56 PeiFfsFvPpiGetVolumeInfo
,
57 PeiFfsFvPpiFindSectionByType
,
58 PeiFfsFvPpiGetFileInfo2
,
59 PeiFfsFvPpiFindSectionByType2
,
60 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
,
61 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
65 EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList
= {
66 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
67 &gEfiFirmwareFileSystem2Guid
,
71 EFI_PEI_PPI_DESCRIPTOR mPeiFfs3FvPpiList
= {
72 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
73 &gEfiFirmwareFileSystem3Guid
,
78 Required Alignment Alignment Value in FFS Alignment Value in
79 (bytes) Attributes Field Firmware Volume Interfaces
89 UINT8 mFvAttributes
[] = {0, 4, 7, 9, 10, 12, 15, 16};
92 Convert the FFS File Attributes to FV File Attributes
94 @param FfsAttributes The attributes of UINT8 type.
96 @return The attributes of EFI_FV_FILE_ATTRIBUTES
99 EFI_FV_FILE_ATTRIBUTES
100 FfsAttributes2FvFileAttributes (
101 IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
105 EFI_FV_FILE_ATTRIBUTES FileAttribute
;
107 DataAlignment
= (UINT8
) ((FfsAttributes
& FFS_ATTRIB_DATA_ALIGNMENT
) >> 3);
108 ASSERT (DataAlignment
< 8);
110 FileAttribute
= (EFI_FV_FILE_ATTRIBUTES
) mFvAttributes
[DataAlignment
];
112 if ((FfsAttributes
& FFS_ATTRIB_FIXED
) == FFS_ATTRIB_FIXED
) {
113 FileAttribute
|= EFI_FV_FILE_ATTRIB_FIXED
;
116 return FileAttribute
;
120 Returns the file state set by the highest zero bit in the State field
122 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
123 in the Attributes field.
124 @param FfsHeader Pointer to FFS File Header.
126 @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit
127 in the header State field.
131 IN UINT8 ErasePolarity
,
132 IN EFI_FFS_FILE_HEADER
*FfsHeader
135 EFI_FFS_FILE_STATE FileState
;
136 EFI_FFS_FILE_STATE HighestBit
;
138 FileState
= FfsHeader
->State
;
140 if (ErasePolarity
!= 0) {
141 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
145 // Get file state set by its highest none zero bit.
148 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
156 Calculates the checksum of the header of a file.
158 @param FileHeader Pointer to FFS File Header.
160 @return Checksum of the header.
161 Zero means the header is good.
162 Non-zero means the header is bad.
165 CalculateHeaderChecksum (
166 IN EFI_FFS_FILE_HEADER
*FileHeader
169 EFI_FFS_FILE_HEADER2 TestFileHeader
;
171 if (IS_FFS_FILE2 (FileHeader
)) {
172 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER2
));
174 // Ingore State and File field in FFS header.
176 TestFileHeader
.State
= 0;
177 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
179 return CalculateSum8 ((CONST UINT8
*) &TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER2
));
181 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
183 // Ingore State and File field in FFS header.
185 TestFileHeader
.State
= 0;
186 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
188 return CalculateSum8 ((CONST UINT8
*) &TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
193 Find FV handler according to FileHandle in that FV.
195 @param FileHandle Handle of file image
197 @return Pointer to instance of PEI_CORE_FV_HANDLE.
201 IN EFI_PEI_FILE_HANDLE FileHandle
205 PEI_CORE_INSTANCE
*PrivateData
;
206 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
209 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
210 BestIndex
= PrivateData
->FvCount
;
213 // Find the best matched FV image that includes this FileHandle.
214 // FV may include the child FV, and they are in the same continuous space.
215 // If FileHandle is from the child FV, the updated logic can find its matched FV.
217 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
218 FwVolHeader
= PrivateData
->Fv
[Index
].FvHeader
;
219 if (((UINT64
) (UINTN
) FileHandle
> (UINT64
) (UINTN
) FwVolHeader
) && \
220 ((UINT64
) (UINTN
) FileHandle
<= ((UINT64
) (UINTN
) FwVolHeader
+ FwVolHeader
->FvLength
- 1))) {
221 if (BestIndex
== PrivateData
->FvCount
) {
224 if ((UINT64
) (UINTN
) PrivateData
->Fv
[BestIndex
].FvHeader
< (UINT64
) (UINTN
) FwVolHeader
) {
231 if (BestIndex
< PrivateData
->FvCount
) {
232 return &PrivateData
->Fv
[BestIndex
];
239 Given the input file pointer, search for the first matching file in the
240 FFS volume as defined by SearchType. The search starts from FileHeader inside
241 the Firmware Volume defined by FwVolHeader.
242 If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.
243 If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
244 the first PEIM, or COMBINED PEIM or FV file type FFS file will return.
246 @param FvHandle Pointer to the FV header of the volume to search
247 @param FileName File name
248 @param SearchType Filter to find only files of this type.
249 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
250 @param FileHandle This parameter must point to a valid FFS volume.
251 @param AprioriFile Pointer to AprioriFile image in this FV if has
253 @return EFI_NOT_FOUND No files matching the search criteria were found
254 @retval EFI_SUCCESS Success to search given file
259 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
260 IN CONST EFI_GUID
*FileName
, OPTIONAL
261 IN EFI_FV_FILETYPE SearchType
,
262 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
,
263 IN OUT EFI_PEI_FILE_HANDLE
*AprioriFile OPTIONAL
266 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
267 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExtHeader
;
268 EFI_FFS_FILE_HEADER
**FileHeader
;
269 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
271 UINT32 FileOccupiedSize
;
280 // Convert the handle of FV to FV header for memory-mapped firmware volume
282 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvHandle
;
283 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
285 IsFfs3Fv
= CompareGuid (&FwVolHeader
->FileSystemGuid
, &gEfiFirmwareFileSystem3Guid
);
287 FvLength
= FwVolHeader
->FvLength
;
288 if ((FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
295 // If FileHeader is not specified (NULL) or FileName is not NULL,
296 // start with the first file in the firmware volume. Otherwise,
297 // start from the FileHeader.
299 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
300 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
302 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
304 FwVolExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) ((UINT8
*) FwVolHeader
+ FwVolHeader
->ExtHeaderOffset
);
305 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FwVolExtHeader
+ FwVolExtHeader
->ExtHeaderSize
);
306 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ALIGN_POINTER (FfsFileHeader
, 8);
308 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*) FwVolHeader
+ FwVolHeader
->HeaderLength
);
311 if (IS_FFS_FILE2 (*FileHeader
)) {
313 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader
)->Name
));
315 FileLength
= FFS_FILE2_SIZE (*FileHeader
);
316 ASSERT (FileLength
> 0x00FFFFFF);
318 FileLength
= FFS_FILE_SIZE (*FileHeader
);
321 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
323 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
324 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
327 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
328 ASSERT (FileOffset
<= 0xFFFFFFFF);
330 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
332 // Get FileState which is the highest bit of the State
334 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
337 case EFI_FILE_HEADER_CONSTRUCTION
:
338 case EFI_FILE_HEADER_INVALID
:
339 if (IS_FFS_FILE2 (FfsFileHeader
)) {
341 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
343 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER2
);
344 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
346 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER
);
347 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
351 case EFI_FILE_DATA_VALID
:
352 case EFI_FILE_MARKED_FOR_UPDATE
:
353 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
356 return EFI_NOT_FOUND
;
359 if (IS_FFS_FILE2 (FfsFileHeader
)) {
360 FileLength
= FFS_FILE2_SIZE (FfsFileHeader
);
361 ASSERT (FileLength
> 0x00FFFFFF);
362 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
364 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
365 FileOffset
+= FileOccupiedSize
;
366 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ FileOccupiedSize
);
370 FileLength
= FFS_FILE_SIZE (FfsFileHeader
);
371 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
374 DataCheckSum
= FFS_FIXED_CHECKSUM
;
375 if ((FfsFileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) == FFS_ATTRIB_CHECKSUM
) {
376 if (IS_FFS_FILE2 (FfsFileHeader
)) {
377 DataCheckSum
= CalculateCheckSum8 ((CONST UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
), FileLength
- sizeof(EFI_FFS_FILE_HEADER2
));
379 DataCheckSum
= CalculateCheckSum8 ((CONST UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
), FileLength
- sizeof(EFI_FFS_FILE_HEADER
));
382 if (FfsFileHeader
->IntegrityCheck
.Checksum
.File
!= DataCheckSum
) {
385 return EFI_NOT_FOUND
;
388 if (FileName
!= NULL
) {
389 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
390 *FileHeader
= FfsFileHeader
;
393 } else if (SearchType
== PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
) {
394 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
395 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
) ||
396 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
)) {
398 *FileHeader
= FfsFileHeader
;
400 } else if (AprioriFile
!= NULL
) {
401 if (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FREEFORM
) {
402 if (CompareGuid (&FfsFileHeader
->Name
, &gPeiAprioriFileNameGuid
)) {
403 *AprioriFile
= FfsFileHeader
;
407 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
408 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
409 *FileHeader
= FfsFileHeader
;
413 FileOffset
+= FileOccupiedSize
;
414 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
417 case EFI_FILE_DELETED
:
418 if (IS_FFS_FILE2 (FfsFileHeader
)) {
420 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
422 FileLength
= FFS_FILE2_SIZE (FfsFileHeader
);
423 ASSERT (FileLength
> 0x00FFFFFF);
425 FileLength
= FFS_FILE_SIZE (FfsFileHeader
);
427 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
428 FileOffset
+= FileOccupiedSize
;
429 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
434 return EFI_NOT_FOUND
;
439 return EFI_NOT_FOUND
;
443 Initialize PeiCore Fv List.
445 @param PrivateData - Pointer to PEI_CORE_INSTANCE.
446 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
450 IN PEI_CORE_INSTANCE
*PrivateData
,
451 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
455 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
456 EFI_PEI_FV_HANDLE FvHandle
;
457 EFI_FIRMWARE_VOLUME_HEADER
*BfvHeader
;
460 // Install FV_PPI for FFS2 file system.
462 PeiServicesInstallPpi (&mPeiFfs2FvPpiList
);
465 // Install FV_PPI for FFS3 file system.
467 PeiServicesInstallPpi (&mPeiFfs3FvPpiList
);
469 BfvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
472 // The FV_PPI in BFV's format should be installed.
474 Status
= PeiServicesLocatePpi (
475 &BfvHeader
->FileSystemGuid
,
480 ASSERT_EFI_ERROR (Status
);
485 FvPpi
->ProcessVolume (
487 SecCoreData
->BootFirmwareVolumeBase
,
488 (UINTN
)BfvHeader
->FvLength
,
493 // Update internal PEI_CORE_FV array.
495 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= BfvHeader
;
496 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
497 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
498 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= 0;
501 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
502 (UINT32
) PrivateData
->FvCount
,
507 PrivateData
->FvCount
++;
510 // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose
511 // additional Fvs to PeiCore.
513 Status
= PeiServicesNotifyPpi (mNotifyOnFvInfoList
);
514 ASSERT_EFI_ERROR (Status
);
519 Process Firmware Volum Information once FvInfoPPI or FvInfo2PPI install.
520 The FV Info will be registered into PeiCore private data structure.
521 And search the inside FV image, if found, the new FV INFO(2) PPI will be installed.
523 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
524 @param NotifyDescriptor Address of the notification descriptor data structure.
525 @param Ppi Address of the PPI that was installed.
527 @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.
528 @return if not EFI_SUCESS, fail to verify FV.
533 FirmwareVolmeInfoPpiNotifyCallback (
534 IN EFI_PEI_SERVICES
**PeiServices
,
535 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
539 EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI FvInfo2Ppi
;
540 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
541 PEI_CORE_INSTANCE
*PrivateData
;
543 EFI_PEI_FV_HANDLE FvHandle
;
545 EFI_PEI_FILE_HANDLE FileHandle
;
550 Status
= EFI_SUCCESS
;
551 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
553 if (CompareGuid (NotifyDescriptor
->Guid
, &gEfiPeiFirmwareVolumeInfo2PpiGuid
)) {
557 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
));
563 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
));
564 FvInfo2Ppi
.AuthenticationStatus
= 0;
568 if (CompareGuid (&FvInfo2Ppi
.FvFormat
, &gEfiFirmwareFileSystem2Guid
)) {
570 // gEfiFirmwareFileSystem2Guid is specified for FvFormat, then here to check the
571 // FileSystemGuid pointed by FvInfo against gEfiFirmwareFileSystem2Guid to make sure
572 // FvInfo has the firmware file system 2 format.
574 // If the ASSERT really appears, FvFormat needs to be specified correctly, for example,
575 // gEfiFirmwareFileSystem3Guid can be used for firmware file system 3 format, or
576 // ((EFI_FIRMWARE_VOLUME_HEADER *) FvInfo)->FileSystemGuid can be just used for both
577 // firmware file system 2 and 3 format.
579 ASSERT (CompareGuid (&(((EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo2Ppi
.FvInfo
)->FileSystemGuid
), &gEfiFirmwareFileSystem2Guid
));
583 // Locate the corresponding FV_PPI according to founded FV's format guid
585 Status
= PeiServicesLocatePpi (
586 &FvInfo2Ppi
.FvFormat
,
591 if (!EFI_ERROR (Status
)) {
593 // Process new found FV and get FV handle.
595 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo2Ppi
.FvInfo
, FvInfo2Ppi
.FvInfoSize
, &FvHandle
);
596 if (EFI_ERROR (Status
)) {
597 DEBUG ((EFI_D_ERROR
, "Fail to process new found FV, FV may be corrupted!\n"));
602 // Check whether the FV has already been processed.
604 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
605 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
606 if (IsFvInfo2
&& (FvInfo2Ppi
.AuthenticationStatus
!= PrivateData
->Fv
[FvIndex
].AuthenticationStatus
)) {
607 PrivateData
->Fv
[FvIndex
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
608 DEBUG ((EFI_D_INFO
, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex
, FvInfo2Ppi
.AuthenticationStatus
));
610 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfo2Ppi
.FvInfo
));
615 if (PrivateData
->FvCount
>= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
616 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, PcdGet32 (PcdPeiCoreMaxFvSupported
)));
617 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
622 // Update internal PEI_CORE_FV array.
624 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo2Ppi
.FvInfo
;
625 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
626 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
627 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
628 CurFvCount
= PrivateData
->FvCount
;
631 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
633 (VOID
*) FvInfo2Ppi
.FvInfo
,
634 FvInfo2Ppi
.FvInfoSize
,
637 PrivateData
->FvCount
++;
640 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
644 Status
= FvPpi
->FindFileByType (
646 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
650 if (!EFI_ERROR (Status
)) {
651 Status
= FvPpi
->FindSectionByType (
653 EFI_SECTION_PEI_DEPEX
,
657 if (!EFI_ERROR (Status
)) {
658 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
660 // Dependency is not satisfied.
666 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, CurFvCount
, FvHandle
));
667 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[CurFvCount
], FileHandle
);
669 } while (FileHandle
!= NULL
);
671 DEBUG ((EFI_D_ERROR
, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi
.FvInfo
));
673 AddUnknownFormatFvInfo (PrivateData
, &FvInfo2Ppi
);
680 Verify the Guided Section GUID by checking if there is the Guided Section GUID HOB recorded the GUID itself.
682 @param GuidedSectionGuid The Guided Section GUID.
683 @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Ppi
684 for the Guided Section.
686 @return TRUE The GuidedSectionGuid could be identified, and the pointer to
687 the Guided Section Extraction Ppi will be returned to *GuidedSectionExtraction.
688 @return FALSE The GuidedSectionGuid could not be identified, or
689 the Guided Section Extraction Ppi has not been installed yet.
693 VerifyGuidedSectionGuid (
694 IN EFI_GUID
*GuidedSectionGuid
,
695 OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
**GuidedSectionExtraction
698 EFI_PEI_HOB_POINTERS Hob
;
699 EFI_GUID
*GuidRecorded
;
704 // Check if there is the Guided Section GUID HOB recorded the GUID itself.
706 Hob
.Raw
= GetFirstGuidHob (GuidedSectionGuid
);
707 if (Hob
.Raw
!= NULL
) {
708 GuidRecorded
= (EFI_GUID
*) GET_GUID_HOB_DATA (Hob
);
709 if (CompareGuid (GuidRecorded
, GuidedSectionGuid
)) {
711 // Found the recorded GuidedSectionGuid.
713 Status
= PeiServicesLocatePpi (GuidedSectionGuid
, 0, NULL
, (VOID
**) &Interface
);
714 if (!EFI_ERROR (Status
) && Interface
!= NULL
) {
716 // Found the supported Guided Section Extraction Ppi for the Guided Section.
718 *GuidedSectionExtraction
= (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*) Interface
;
729 Go through the file to search SectionType section.
730 Search within encapsulation sections (compression and GUIDed) recursively,
731 until the match section is found.
733 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
734 @param SectionType Filter to find only section of this type.
735 @param SectionInstance Pointer to the filter to find the specific instance of section.
736 @param Section From where to search.
737 @param SectionSize The file size to search.
738 @param OutputBuffer A pointer to the discovered section, if successful.
739 NULL if section not found
740 @param AuthenticationStatus Updated upon return to point to the authentication status for this section.
741 @param IsFfs3Fv Indicates the FV format.
743 @return EFI_NOT_FOUND The match section is not found.
744 @return EFI_SUCCESS The match section is found.
749 IN CONST EFI_PEI_SERVICES
**PeiServices
,
750 IN EFI_SECTION_TYPE SectionType
,
751 IN OUT UINTN
*SectionInstance
,
752 IN EFI_COMMON_SECTION_HEADER
*Section
,
753 IN UINTN SectionSize
,
754 OUT VOID
**OutputBuffer
,
755 OUT UINT32
*AuthenticationStatus
,
760 UINT32 SectionLength
;
762 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
763 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
767 UINT32 Authentication
;
768 PEI_CORE_INSTANCE
*PrivateData
;
769 EFI_GUID
*SectionDefinitionGuid
;
770 BOOLEAN SectionCached
;
771 VOID
*TempOutputBuffer
;
772 UINT32 TempAuthenticationStatus
;
773 UINT16 GuidedSectionAttributes
;
775 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
776 *OutputBuffer
= NULL
;
779 Status
= EFI_NOT_FOUND
;
782 while (ParsedLength
< SectionSize
) {
784 if (IS_SECTION2 (Section
)) {
785 ASSERT (SECTION2_SIZE (Section
) > 0x00FFFFFF);
787 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
788 SectionLength
= SECTION2_SIZE (Section
);
790 // SectionLength is adjusted it is 4 byte aligned.
791 // Go to the next section
793 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
794 ASSERT (SectionLength
!= 0);
795 ParsedLength
+= SectionLength
;
796 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ SectionLength
);
801 if (Section
->Type
== SectionType
) {
803 // The type matches, so check the instance count to see if it's the one we want.
805 (*SectionInstance
)--;
806 if (*SectionInstance
== 0) {
810 if (IS_SECTION2 (Section
)) {
811 *OutputBuffer
= (VOID
*)((UINT8
*) Section
+ sizeof (EFI_COMMON_SECTION_HEADER2
));
813 *OutputBuffer
= (VOID
*)((UINT8
*) Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
817 if (IS_SECTION2 (Section
)) {
818 SectionLength
= SECTION2_SIZE (Section
);
820 SectionLength
= SECTION_SIZE (Section
);
823 // SectionLength is adjusted it is 4 byte aligned.
824 // Go to the next section
826 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
827 ASSERT (SectionLength
!= 0);
828 ParsedLength
+= SectionLength
;
829 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
832 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
834 // Check the encapsulated section is extracted into the cache data.
836 SectionCached
= FALSE
;
837 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
838 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
839 SectionCached
= TRUE
;
840 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
841 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
842 Authentication
= PrivateData
->CacheSection
.AuthenticationStatus
[Index
];
844 // Search section directly from the cache data.
846 TempAuthenticationStatus
= 0;
847 Status
= ProcessSection (
854 &TempAuthenticationStatus
,
857 if (!EFI_ERROR (Status
)) {
858 *OutputBuffer
= TempOutputBuffer
;
859 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
866 // If SectionCached is TRUE, the section data has been cached and scanned.
868 if (!SectionCached
) {
869 Status
= EFI_NOT_FOUND
;
871 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
872 if (IS_SECTION2 (Section
)) {
873 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION2
*)Section
)->SectionDefinitionGuid
;
874 GuidedSectionAttributes
= ((EFI_GUID_DEFINED_SECTION2
*)Section
)->Attributes
;
876 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
;
877 GuidedSectionAttributes
= ((EFI_GUID_DEFINED_SECTION
*)Section
)->Attributes
;
879 if (VerifyGuidedSectionGuid (SectionDefinitionGuid
, &GuidSectionPpi
)) {
880 Status
= GuidSectionPpi
->ExtractSection (
887 } else if ((GuidedSectionAttributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
889 // Figure out the proper authentication status for GUIDED section without processing required
891 Status
= EFI_SUCCESS
;
892 if ((GuidedSectionAttributes
& EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) {
893 Authentication
|= EFI_AUTH_STATUS_IMAGE_SIGNED
| EFI_AUTH_STATUS_NOT_TESTED
;
895 if (IS_SECTION2 (Section
)) {
896 PpiOutputSize
= SECTION2_SIZE (Section
) - ((EFI_GUID_DEFINED_SECTION2
*) Section
)->DataOffset
;
897 PpiOutput
= (UINT8
*) Section
+ ((EFI_GUID_DEFINED_SECTION2
*) Section
)->DataOffset
;
899 PpiOutputSize
= SECTION_SIZE (Section
) - ((EFI_GUID_DEFINED_SECTION
*) Section
)->DataOffset
;
900 PpiOutput
= (UINT8
*) Section
+ ((EFI_GUID_DEFINED_SECTION
*) Section
)->DataOffset
;
903 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
904 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**) &DecompressPpi
);
905 if (!EFI_ERROR (Status
)) {
906 Status
= DecompressPpi
->Decompress (
908 (CONST EFI_COMPRESSION_SECTION
*) Section
,
915 if (!EFI_ERROR (Status
)) {
916 if ((Authentication
& EFI_AUTH_STATUS_NOT_TESTED
) == 0) {
918 // Update cache section data.
920 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
921 PrivateData
->CacheSection
.AllSectionCount
++;
923 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
924 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
925 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
926 PrivateData
->CacheSection
.AuthenticationStatus
[PrivateData
->CacheSection
.SectionIndex
] = Authentication
;
927 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
930 TempAuthenticationStatus
= 0;
931 Status
= ProcessSection (
938 &TempAuthenticationStatus
,
941 if (!EFI_ERROR (Status
)) {
942 *OutputBuffer
= TempOutputBuffer
;
943 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
950 if (IS_SECTION2 (Section
)) {
951 SectionLength
= SECTION2_SIZE (Section
);
953 SectionLength
= SECTION_SIZE (Section
);
956 // SectionLength is adjusted it is 4 byte aligned.
957 // Go to the next section
959 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
960 ASSERT (SectionLength
!= 0);
961 ParsedLength
+= SectionLength
;
962 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
965 return EFI_NOT_FOUND
;
970 Searches for the next matching section within the specified file.
972 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
973 @param SectionType Filter to find only sections of this type.
974 @param FileHandle Pointer to the current file to search.
975 @param SectionData A pointer to the discovered section, if successful.
976 NULL if section not found
978 @retval EFI_NOT_FOUND The section was not found.
979 @retval EFI_SUCCESS The section was found.
984 PeiFfsFindSectionData (
985 IN CONST EFI_PEI_SERVICES
**PeiServices
,
986 IN EFI_SECTION_TYPE SectionType
,
987 IN EFI_PEI_FILE_HANDLE FileHandle
,
988 OUT VOID
**SectionData
991 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
993 CoreFvHandle
= FileHandleToVolume (FileHandle
);
994 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
995 return EFI_NOT_FOUND
;
998 return CoreFvHandle
->FvPpi
->FindSectionByType (CoreFvHandle
->FvPpi
, SectionType
, FileHandle
, SectionData
);
1002 Searches for the next matching section within the specified file.
1004 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
1005 @param SectionType The value of the section type to find.
1006 @param SectionInstance Section instance to find.
1007 @param FileHandle Handle of the firmware file to search.
1008 @param SectionData A pointer to the discovered section, if successful.
1009 @param AuthenticationStatus A pointer to the authentication status for this section.
1011 @retval EFI_SUCCESS The section was found.
1012 @retval EFI_NOT_FOUND The section was not found.
1017 PeiFfsFindSectionData3 (
1018 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1019 IN EFI_SECTION_TYPE SectionType
,
1020 IN UINTN SectionInstance
,
1021 IN EFI_PEI_FILE_HANDLE FileHandle
,
1022 OUT VOID
**SectionData
,
1023 OUT UINT32
*AuthenticationStatus
1026 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1028 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1029 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1030 return EFI_NOT_FOUND
;
1033 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1034 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1035 return CoreFvHandle
->FvPpi
->FindSectionByType2 (CoreFvHandle
->FvPpi
, SectionType
, SectionInstance
, FileHandle
, SectionData
, AuthenticationStatus
);
1038 // The old FvPpi doesn't support to find section by section instance
1039 // and return authentication status, so return EFI_UNSUPPORTED.
1041 return EFI_UNSUPPORTED
;
1045 Searches for the next matching file in the firmware volume.
1047 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
1048 @param SearchType Filter to find only files of this type.
1049 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
1050 @param FvHandle Handle of firmware volume in which to search.
1051 @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
1052 at the beginning of the firmware volume. On exit, points the file handle of the next file
1053 in the volume or NULL if there are no more files.
1055 @retval EFI_NOT_FOUND The file was not found.
1056 @retval EFI_NOT_FOUND The header checksum was not zero.
1057 @retval EFI_SUCCESS The file was found.
1062 PeiFfsFindNextFile (
1063 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1064 IN UINT8 SearchType
,
1065 IN EFI_PEI_FV_HANDLE FvHandle
,
1066 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1069 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1071 CoreFvHandle
= FvHandleToCoreHandle (FvHandle
);
1074 // To make backward compatiblity, if can not find corresponding the handle of FV
1075 // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed
1076 // to the address of first byte of FV.
1078 if ((CoreFvHandle
== NULL
) && FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
1079 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1082 if ((CoreFvHandle
== NULL
) || CoreFvHandle
->FvPpi
== NULL
) {
1083 return EFI_NOT_FOUND
;
1086 return CoreFvHandle
->FvPpi
->FindFileByType (CoreFvHandle
->FvPpi
, SearchType
, FvHandle
, FileHandle
);
1091 Search the firmware volumes by index
1093 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
1094 @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
1096 @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
1098 @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
1099 @retval EFI_NOT_FOUND The volume was not found.
1100 @retval EFI_SUCCESS The volume was found.
1105 PeiFfsFindNextVolume (
1106 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1108 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
1111 PEI_CORE_INSTANCE
*Private
;
1112 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1114 if (VolumeHandle
== NULL
) {
1115 return EFI_INVALID_PARAMETER
;
1118 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
1120 CoreFvHandle
= FindNextCoreFvHandle (Private
, Instance
);
1121 if (CoreFvHandle
== NULL
) {
1122 *VolumeHandle
= NULL
;
1123 return EFI_NOT_FOUND
;
1126 *VolumeHandle
= CoreFvHandle
->FvHandle
;
1133 Find a file within a volume by its name.
1135 @param FileName A pointer to the name of the file to find within the firmware volume.
1136 @param VolumeHandle The firmware volume to search
1137 @param FileHandle Upon exit, points to the found file's handle
1138 or NULL if it could not be found.
1140 @retval EFI_SUCCESS File was found.
1141 @retval EFI_NOT_FOUND File was not found.
1142 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
1147 PeiFfsFindFileByName (
1148 IN CONST EFI_GUID
*FileName
,
1149 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1150 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1153 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1155 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1156 return EFI_INVALID_PARAMETER
;
1159 CoreFvHandle
= FvHandleToCoreHandle (VolumeHandle
);
1160 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1161 return EFI_NOT_FOUND
;
1164 return CoreFvHandle
->FvPpi
->FindFileByName (CoreFvHandle
->FvPpi
, FileName
, &VolumeHandle
, FileHandle
);
1168 Returns information about a specific file.
1170 @param FileHandle Handle of the file.
1171 @param FileInfo Upon exit, points to the file's information.
1173 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1174 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1175 @retval EFI_SUCCESS File information returned.
1181 IN EFI_PEI_FILE_HANDLE FileHandle
,
1182 OUT EFI_FV_FILE_INFO
*FileInfo
1185 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1187 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1188 return EFI_INVALID_PARAMETER
;
1192 // Retrieve the FirmwareVolume which the file resides in.
1194 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1195 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1196 return EFI_INVALID_PARAMETER
;
1199 return CoreFvHandle
->FvPpi
->GetFileInfo (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1203 Returns information about a specific file.
1205 @param FileHandle Handle of the file.
1206 @param FileInfo Upon exit, points to the file's information.
1208 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1209 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1210 @retval EFI_SUCCESS File information returned.
1215 PeiFfsGetFileInfo2 (
1216 IN EFI_PEI_FILE_HANDLE FileHandle
,
1217 OUT EFI_FV_FILE_INFO2
*FileInfo
1220 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1222 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1223 return EFI_INVALID_PARAMETER
;
1227 // Retrieve the FirmwareVolume which the file resides in.
1229 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1230 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1231 return EFI_INVALID_PARAMETER
;
1234 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1235 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1236 return CoreFvHandle
->FvPpi
->GetFileInfo2 (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1239 // The old FvPpi doesn't support to return file info with authentication status,
1240 // so return EFI_UNSUPPORTED.
1242 return EFI_UNSUPPORTED
;
1246 Returns information about the specified volume.
1248 This function returns information about a specific firmware
1249 volume, including its name, type, attributes, starting address
1252 @param VolumeHandle Handle of the volume.
1253 @param VolumeInfo Upon exit, points to the volume's information.
1255 @retval EFI_SUCCESS Volume information returned.
1256 @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
1257 @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
1258 @retval EFI_SUCCESS Information successfully returned.
1259 @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
1264 PeiFfsGetVolumeInfo (
1265 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1266 OUT EFI_FV_INFO
*VolumeInfo
1269 PEI_CORE_FV_HANDLE
*CoreHandle
;
1271 if ((VolumeInfo
== NULL
) || (VolumeHandle
== NULL
)) {
1272 return EFI_INVALID_PARAMETER
;
1275 CoreHandle
= FvHandleToCoreHandle (VolumeHandle
);
1277 if ((CoreHandle
== NULL
) || (CoreHandle
->FvPpi
== NULL
)) {
1278 return EFI_INVALID_PARAMETER
;
1281 return CoreHandle
->FvPpi
->GetVolumeInfo (CoreHandle
->FvPpi
, VolumeHandle
, VolumeInfo
);
1285 Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob.
1287 @param PrivateData PeiCore's private data structure
1288 @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.
1289 @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image.
1291 @retval EFI_NOT_FOUND FV image can't be found.
1292 @retval EFI_SUCCESS Successfully to process it.
1293 @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image
1294 @retval EFI_SECURITY_VIOLATION Image is illegal
1295 @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section
1300 IN PEI_CORE_INSTANCE
*PrivateData
,
1301 IN PEI_CORE_FV_HANDLE
*ParentFvCoreHandle
,
1302 IN EFI_PEI_FILE_HANDLE ParentFvFileHandle
1306 EFI_FV_INFO ParentFvImageInfo
;
1309 EFI_PEI_HOB_POINTERS HobPtr
;
1310 EFI_PEI_FIRMWARE_VOLUME_PPI
*ParentFvPpi
;
1311 EFI_PEI_FV_HANDLE ParentFvHandle
;
1312 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
1313 EFI_FV_FILE_INFO FileInfo
;
1315 UINT32 AuthenticationStatus
;
1318 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1321 HobPtr
.Raw
= GetHobList ();
1322 while ((HobPtr
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobPtr
.Raw
)) != NULL
) {
1323 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)ParentFvFileHandle
)->Name
), &HobPtr
.FirmwareVolume2
->FileName
)) {
1325 // this FILE has been dispatched, it will not be dispatched again.
1327 DEBUG ((EFI_D_INFO
, "FV file %p has been dispatched!\r\n", ParentFvFileHandle
));
1330 HobPtr
.Raw
= GET_NEXT_HOB (HobPtr
);
1333 ParentFvHandle
= ParentFvCoreHandle
->FvHandle
;
1334 ParentFvPpi
= ParentFvCoreHandle
->FvPpi
;
1337 // Find FvImage in FvFile
1339 AuthenticationStatus
= 0;
1340 if ((ParentFvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1341 (ParentFvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1342 Status
= ParentFvPpi
->FindSectionByType2 (
1344 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1348 &AuthenticationStatus
1351 Status
= ParentFvPpi
->FindSectionByType (
1353 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1358 if (EFI_ERROR (Status
)) {
1362 Status
= VerifyPeim (PrivateData
, ParentFvHandle
, ParentFvFileHandle
, AuthenticationStatus
);
1363 if (Status
== EFI_SECURITY_VIOLATION
) {
1368 // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
1369 // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
1370 // its initial linked location and maintain its alignment.
1372 if ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_WEAK_ALIGNMENT
) != EFI_FVB2_WEAK_ALIGNMENT
) {
1374 // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
1376 FvAlignment
= 1 << ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_ALIGNMENT
) >> 16);
1377 if (FvAlignment
< 8) {
1384 if ((UINTN
) FvHeader
% FvAlignment
!= 0) {
1385 FvLength
= ReadUnaligned64 (&FvHeader
->FvLength
);
1386 NewFvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvLength
), FvAlignment
);
1387 if (NewFvBuffer
== NULL
) {
1388 return EFI_OUT_OF_RESOURCES
;
1390 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
) FvLength
);
1391 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) NewFvBuffer
;
1395 Status
= ParentFvPpi
->GetVolumeInfo (ParentFvPpi
, ParentFvHandle
, &ParentFvImageInfo
);
1396 ASSERT_EFI_ERROR (Status
);
1398 Status
= ParentFvPpi
->GetFileInfo (ParentFvPpi
, ParentFvFileHandle
, &FileInfo
);
1399 ASSERT_EFI_ERROR (Status
);
1402 // Install FvInfo(2) Ppi
1403 // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated
1404 // FVs inherit the proper AuthenticationStatus.
1406 PeiServicesInstallFvInfo2Ppi(
1407 &FvHeader
->FileSystemGuid
,
1409 (UINT32
)FvHeader
->FvLength
,
1410 &ParentFvImageInfo
.FvName
,
1412 AuthenticationStatus
1415 PeiServicesInstallFvInfoPpi (
1416 &FvHeader
->FileSystemGuid
,
1418 (UINT32
) FvHeader
->FvLength
,
1419 &ParentFvImageInfo
.FvName
,
1424 // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase
1427 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1432 // Makes the encapsulated volume show up in DXE phase to skip processing of
1433 // encapsulated file again.
1436 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1438 &ParentFvImageInfo
.FvName
,
1446 Process a firmware volume and create a volume handle.
1448 Create a volume handle from the information in the buffer. For
1449 memory-mapped firmware volumes, Buffer and BufferSize refer to
1450 the start of the firmware volume and the firmware volume size.
1451 For non memory-mapped firmware volumes, this points to a
1452 buffer which contains the necessary information for creating
1453 the firmware volume handle. Normally, these values are derived
1454 from the EFI_FIRMWARE_VOLUME_INFO_PPI.
1457 @param This Points to this instance of the
1458 EFI_PEI_FIRMWARE_VOLUME_PPI.
1459 @param Buffer Points to the start of the buffer.
1460 @param BufferSize Size of the buffer.
1461 @param FvHandle Points to the returned firmware volume
1462 handle. The firmware volume handle must
1463 be unique within the system.
1465 @retval EFI_SUCCESS Firmware volume handle created.
1466 @retval EFI_VOLUME_CORRUPTED Volume was corrupt.
1471 PeiFfsFvPpiProcessVolume (
1472 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1474 IN UINTN BufferSize
,
1475 OUT EFI_PEI_FV_HANDLE
*FvHandle
1480 ASSERT (FvHandle
!= NULL
);
1482 if (Buffer
== NULL
) {
1483 return EFI_VOLUME_CORRUPTED
;
1487 // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped
1488 // FV image and the handle is pointed to Fv image's buffer.
1490 *FvHandle
= (EFI_PEI_FV_HANDLE
) Buffer
;
1493 // Do verify for given FV buffer.
1495 Status
= VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER
*) Buffer
);
1496 if (EFI_ERROR(Status
)) {
1497 DEBUG ((EFI_D_ERROR
, "Fail to verify FV which address is 0x%11p", Buffer
));
1498 return EFI_VOLUME_CORRUPTED
;
1505 Finds the next file of the specified type.
1507 This service enables PEI modules to discover additional firmware files.
1508 The FileHandle must be unique within the system.
1510 @param This Points to this instance of the
1511 EFI_PEI_FIRMWARE_VOLUME_PPI.
1512 @param SearchType A filter to find only files of this type. Type
1513 EFI_FV_FILETYPE_ALL causes no filtering to be
1515 @param FvHandle Handle of firmware volume in which to
1517 @param FileHandle Points to the current handle from which to
1518 begin searching or NULL to start at the
1519 beginning of the firmware volume. Updated
1520 upon return to reflect the file found.
1522 @retval EFI_SUCCESS The file was found.
1523 @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.
1528 PeiFfsFvPpiFindFileByType (
1529 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1530 IN EFI_FV_FILETYPE SearchType
,
1531 IN EFI_PEI_FV_HANDLE FvHandle
,
1532 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1535 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1539 Find a file within a volume by its name.
1541 This service searches for files with a specific name, within
1542 either the specified firmware volume or all firmware volumes.
1544 @param This Points to this instance of the
1545 EFI_PEI_FIRMWARE_VOLUME_PPI.
1546 @param FileName A pointer to the name of the file to find
1547 within the firmware volume.
1548 @param FvHandle Upon entry, the pointer to the firmware
1549 volume to search or NULL if all firmware
1550 volumes should be searched. Upon exit, the
1551 actual firmware volume in which the file was
1553 @param FileHandle Upon exit, points to the found file's
1554 handle or NULL if it could not be found.
1556 @retval EFI_SUCCESS File was found.
1557 @retval EFI_NOT_FOUND File was not found.
1558 @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or
1565 PeiFfsFvPpiFindFileByName (
1566 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1567 IN CONST EFI_GUID
*FileName
,
1568 IN EFI_PEI_FV_HANDLE
*FvHandle
,
1569 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1573 PEI_CORE_INSTANCE
*PrivateData
;
1576 if ((FvHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1577 return EFI_INVALID_PARAMETER
;
1580 if (*FvHandle
!= NULL
) {
1581 Status
= FindFileEx (*FvHandle
, FileName
, 0, FileHandle
, NULL
);
1582 if (Status
== EFI_NOT_FOUND
) {
1587 // If *FvHandle = NULL, so search all FV for given filename
1589 Status
= EFI_NOT_FOUND
;
1591 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
1592 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1594 // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
1596 if (PrivateData
->Fv
[Index
].FvPpi
!= NULL
) {
1597 Status
= FindFileEx (PrivateData
->Fv
[Index
].FvHandle
, FileName
, 0, FileHandle
, NULL
);
1598 if (!EFI_ERROR (Status
)) {
1599 *FvHandle
= PrivateData
->Fv
[Index
].FvHandle
;
1610 Returns information about a specific file.
1612 This function returns information about a specific
1613 file, including its file name, type, attributes, starting
1616 @param This Points to this instance of the
1617 EFI_PEI_FIRMWARE_VOLUME_PPI.
1618 @param FileHandle Handle of the file.
1619 @param FileInfo Upon exit, points to the file's
1622 @retval EFI_SUCCESS File information returned.
1623 @retval EFI_INVALID_PARAMETER If FileHandle does not
1624 represent a valid file.
1625 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1630 PeiFfsFvPpiGetFileInfo (
1631 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1632 IN EFI_PEI_FILE_HANDLE FileHandle
,
1633 OUT EFI_FV_FILE_INFO
*FileInfo
1637 UINT8 ErasePolarity
;
1638 EFI_FFS_FILE_HEADER
*FileHeader
;
1639 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1640 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1642 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1643 return EFI_INVALID_PARAMETER
;
1647 // Retrieve the FirmwareVolume which the file resides in.
1649 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1650 if (CoreFvHandle
== NULL
) {
1651 return EFI_INVALID_PARAMETER
;
1654 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1656 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
1663 // Get FileState which is the highest bit of the State
1665 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
1667 switch (FileState
) {
1668 case EFI_FILE_DATA_VALID
:
1669 case EFI_FILE_MARKED_FOR_UPDATE
:
1672 return EFI_INVALID_PARAMETER
;
1675 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
1676 if (IS_FFS_FILE2 (FileHeader
)) {
1677 ASSERT (FFS_FILE2_SIZE (FileHeader
) > 0x00FFFFFF);
1678 if (!FwVolInstance
->IsFfs3Fv
) {
1679 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader
->Name
));
1680 return EFI_INVALID_PARAMETER
;
1682 FileInfo
->BufferSize
= FFS_FILE2_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
1683 FileInfo
->Buffer
= (UINT8
*) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
);
1685 FileInfo
->BufferSize
= FFS_FILE_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
1686 FileInfo
->Buffer
= (UINT8
*) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER
);
1688 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
1689 FileInfo
->FileType
= FileHeader
->Type
;
1690 FileInfo
->FileAttributes
= FfsAttributes2FvFileAttributes (FileHeader
->Attributes
);
1691 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_MEMORY_MAPPED
) == EFI_FVB2_MEMORY_MAPPED
) {
1692 FileInfo
->FileAttributes
|= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED
;
1698 Returns information about a specific file.
1700 This function returns information about a specific
1701 file, including its file name, type, attributes, starting
1702 address, size and authentication status.
1704 @param This Points to this instance of the
1705 EFI_PEI_FIRMWARE_VOLUME_PPI.
1706 @param FileHandle Handle of the file.
1707 @param FileInfo Upon exit, points to the file's
1710 @retval EFI_SUCCESS File information returned.
1711 @retval EFI_INVALID_PARAMETER If FileHandle does not
1712 represent a valid file.
1713 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1718 PeiFfsFvPpiGetFileInfo2 (
1719 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1720 IN EFI_PEI_FILE_HANDLE FileHandle
,
1721 OUT EFI_FV_FILE_INFO2
*FileInfo
1725 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1727 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1728 return EFI_INVALID_PARAMETER
;
1732 // Retrieve the FirmwareVolume which the file resides in.
1734 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1735 if (CoreFvHandle
== NULL
) {
1736 return EFI_INVALID_PARAMETER
;
1739 Status
= PeiFfsFvPpiGetFileInfo (This
, FileHandle
, (EFI_FV_FILE_INFO
*) FileInfo
);
1740 if (!EFI_ERROR (Status
)) {
1741 FileInfo
->AuthenticationStatus
= CoreFvHandle
->AuthenticationStatus
;
1748 This function returns information about the firmware volume.
1750 @param This Points to this instance of the
1751 EFI_PEI_FIRMWARE_VOLUME_PPI.
1752 @param FvHandle Handle to the firmware handle.
1753 @param VolumeInfo Points to the returned firmware volume
1756 @retval EFI_SUCCESS Information returned successfully.
1757 @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid
1758 firmware volume or VolumeInfo is NULL.
1763 PeiFfsFvPpiGetVolumeInfo (
1764 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1765 IN EFI_PEI_FV_HANDLE FvHandle
,
1766 OUT EFI_FV_INFO
*VolumeInfo
1769 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
1770 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
1772 if ((VolumeInfo
== NULL
) || (FvHandle
== NULL
)) {
1773 return EFI_INVALID_PARAMETER
;
1777 // VolumeHandle may not align at 8 byte,
1778 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
1779 // So, Copy FvHeader into the local FvHeader structure.
1781 CopyMem (&FwVolHeader
, FvHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
1784 // Check Fv Image Signature
1786 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
1787 return EFI_INVALID_PARAMETER
;
1790 ZeroMem (VolumeInfo
, sizeof (EFI_FV_INFO
));
1791 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
1792 VolumeInfo
->FvStart
= (VOID
*) FvHandle
;
1793 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
1794 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
1796 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
1797 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FvHandle
) + FwVolHeader
.ExtHeaderOffset
);
1798 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));
1805 Find the next matching section in the firmware file.
1807 This service enables PEI modules to discover sections
1808 of a given type within a valid file.
1810 @param This Points to this instance of the
1811 EFI_PEI_FIRMWARE_VOLUME_PPI.
1812 @param SearchType A filter to find only sections of this
1814 @param FileHandle Handle of firmware file in which to
1816 @param SectionData Updated upon return to point to the
1819 @retval EFI_SUCCESS Section was found.
1820 @retval EFI_NOT_FOUND Section of the specified type was not
1821 found. SectionData contains NULL.
1825 PeiFfsFvPpiFindSectionByType (
1826 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1827 IN EFI_SECTION_TYPE SearchType
,
1828 IN EFI_PEI_FILE_HANDLE FileHandle
,
1829 OUT VOID
**SectionData
1832 UINT32 AuthenticationStatus
;
1833 return PeiFfsFvPpiFindSectionByType2 (This
, SearchType
, 0, FileHandle
, SectionData
, &AuthenticationStatus
);
1837 Find the next matching section in the firmware file.
1839 This service enables PEI modules to discover sections
1840 of a given instance and type within a valid file.
1842 @param This Points to this instance of the
1843 EFI_PEI_FIRMWARE_VOLUME_PPI.
1844 @param SearchType A filter to find only sections of this
1846 @param SearchInstance A filter to find the specific instance
1848 @param FileHandle Handle of firmware file in which to
1850 @param SectionData Updated upon return to point to the
1852 @param AuthenticationStatus Updated upon return to point to the
1853 authentication status for this section.
1855 @retval EFI_SUCCESS Section was found.
1856 @retval EFI_NOT_FOUND Section of the specified type was not
1857 found. SectionData contains NULL.
1861 PeiFfsFvPpiFindSectionByType2 (
1862 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1863 IN EFI_SECTION_TYPE SearchType
,
1864 IN UINTN SearchInstance
,
1865 IN EFI_PEI_FILE_HANDLE FileHandle
,
1866 OUT VOID
**SectionData
,
1867 OUT UINT32
*AuthenticationStatus
1871 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
1873 EFI_COMMON_SECTION_HEADER
*Section
;
1874 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1875 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1877 UINT32 ExtractedAuthenticationStatus
;
1879 if (SectionData
== NULL
) {
1880 return EFI_NOT_FOUND
;
1883 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1886 // Retrieve the FirmwareVolume which the file resides in.
1888 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1889 if (CoreFvHandle
== NULL
) {
1890 return EFI_NOT_FOUND
;
1893 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
1895 if (IS_FFS_FILE2 (FfsFileHeader
)) {
1896 ASSERT (FFS_FILE2_SIZE (FfsFileHeader
) > 0x00FFFFFF);
1897 if (!FwVolInstance
->IsFfs3Fv
) {
1898 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
1899 return EFI_NOT_FOUND
;
1901 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
1902 FileSize
= FFS_FILE2_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
1904 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
1905 FileSize
= FFS_FILE_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
1908 Instance
= SearchInstance
+ 1;
1909 ExtractedAuthenticationStatus
= 0;
1910 Status
= ProcessSection (
1911 GetPeiServicesTablePointer (),
1917 &ExtractedAuthenticationStatus
,
1918 FwVolInstance
->IsFfs3Fv
1920 if (!EFI_ERROR (Status
)) {
1922 // Inherit the authentication status.
1924 *AuthenticationStatus
= ExtractedAuthenticationStatus
| CoreFvHandle
->AuthenticationStatus
;
1930 Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.
1932 @param FvHandle The handle of a FV.
1934 @retval NULL if can not find.
1935 @return Pointer of corresponding PEI_CORE_FV_HANDLE.
1937 PEI_CORE_FV_HANDLE
*
1938 FvHandleToCoreHandle (
1939 IN EFI_PEI_FV_HANDLE FvHandle
1943 PEI_CORE_INSTANCE
*PrivateData
;
1945 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
1946 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1947 if (FvHandle
== PrivateData
->Fv
[Index
].FvHandle
) {
1948 return &PrivateData
->Fv
[Index
];
1956 Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.
1958 This routine also will install FvInfo ppi for FV hob in PI ways.
1960 @param Private Pointer of PEI_CORE_INSTANCE
1961 @param Instance The index of FV want to be searched.
1963 @return Instance of PEI_CORE_FV_HANDLE.
1965 PEI_CORE_FV_HANDLE
*
1966 FindNextCoreFvHandle (
1967 IN PEI_CORE_INSTANCE
*Private
,
1973 EFI_HOB_FIRMWARE_VOLUME
*FvHob
;
1976 // Handle Framework FvHob and Install FvInfo Ppi for it.
1978 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
1980 // Loop to search the wanted FirmwareVolume which supports FFS
1982 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetFirstHob (EFI_HOB_TYPE_FV
);
1983 while (FvHob
!= NULL
) {
1985 // Search whether FvHob has been installed into PeiCore's FV database.
1986 // If found, no need install new FvInfoPpi for it.
1988 for (Index
= 0, Match
= FALSE
; Index
< Private
->FvCount
; Index
++) {
1989 if ((EFI_PEI_FV_HANDLE
)(UINTN
)FvHob
->BaseAddress
== Private
->Fv
[Index
].FvHeader
) {
1996 // Search whether FvHob has been cached into PeiCore's Unknown FV database.
1997 // If found, no need install new FvInfoPpi for it.
2000 for (Index
= 0; Index
< Private
->UnknownFvInfoCount
; Index
++) {
2001 if ((UINTN
)FvHob
->BaseAddress
== (UINTN
)Private
->UnknownFvInfo
[Index
].FvInfo
) {
2009 // If the Fv in FvHob has not been installed into PeiCore's FV database and has
2010 // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi
2011 // for it then PeiCore will dispatch it in callback of FvInfoPpi.
2014 PeiServicesInstallFvInfoPpi (
2015 &(((EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)FvHob
->BaseAddress
)->FileSystemGuid
),
2016 (VOID
*)(UINTN
)FvHob
->BaseAddress
,
2017 (UINT32
)FvHob
->Length
,
2023 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetNextHob (EFI_HOB_TYPE_FV
, (VOID
*)((UINTN
)FvHob
+ FvHob
->Header
.HobLength
));
2027 ASSERT (Private
->FvCount
<= PcdGet32 (PcdPeiCoreMaxFvSupported
));
2028 if (Instance
>= Private
->FvCount
) {
2032 return &Private
->Fv
[Instance
];
2036 After PeiCore image is shadowed into permanent memory, all build-in FvPpi should
2037 be re-installed with the instance in permanent memory and all cached FvPpi pointers in
2038 PrivateData->Fv[] array should be fixed up to be pointed to the one in permanent
2041 @param PrivateData Pointer to PEI_CORE_INSTANCE.
2045 IN PEI_CORE_INSTANCE
*PrivateData
2049 EFI_PEI_PPI_DESCRIPTOR
*OldDescriptor
;
2054 // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
2057 Status
= PeiServicesLocatePpi (
2058 &gEfiFirmwareFileSystem2Guid
,
2063 ASSERT_EFI_ERROR (Status
);
2066 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
2067 // which is shadowed from flash to permanent memory within PeiCore image.
2069 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs2FvPpiList
);
2070 ASSERT_EFI_ERROR (Status
);
2073 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2075 for (Index
= 0; Index
< PcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
2076 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2077 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs2FwVol
.Fv
;
2082 // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which
2085 Status
= PeiServicesLocatePpi (
2086 &gEfiFirmwareFileSystem3Guid
,
2091 ASSERT_EFI_ERROR (Status
);
2094 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3
2095 // which is shadowed from flash to permanent memory within PeiCore image.
2097 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs3FvPpiList
);
2098 ASSERT_EFI_ERROR (Status
);
2101 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2103 for (Index
= 0; Index
< PcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
2104 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2105 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs3FwVol
.Fv
;
2111 Report the information for a new discoveried FV in unknown third-party format.
2113 If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but
2114 the FV in this format has been discoveried, then this FV's information will be cached into
2115 PEI_CORE_INSTANCE's UnknownFvInfo array.
2116 Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI
2117 is installed later by platform's PEIM, the original unknown third-party FV will be processed by
2118 using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2120 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2121 @param FvInfo2Ppi Point to FvInfo2 PPI.
2123 @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.
2124 @retval EFI_SUCCESS Success to add the information for unknown FV.
2127 AddUnknownFormatFvInfo (
2128 IN PEI_CORE_INSTANCE
*PrivateData
,
2129 IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
*FvInfo2Ppi
2132 PEI_CORE_UNKNOW_FORMAT_FV_INFO
*NewUnknownFv
;
2134 if (PrivateData
->UnknownFvInfoCount
+ 1 >= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
2135 return EFI_OUT_OF_RESOURCES
;
2138 NewUnknownFv
= &PrivateData
->UnknownFvInfo
[PrivateData
->UnknownFvInfoCount
];
2139 PrivateData
->UnknownFvInfoCount
++;
2141 CopyGuid (&NewUnknownFv
->FvFormat
, &FvInfo2Ppi
->FvFormat
);
2142 NewUnknownFv
->FvInfo
= FvInfo2Ppi
->FvInfo
;
2143 NewUnknownFv
->FvInfoSize
= FvInfo2Ppi
->FvInfoSize
;
2144 NewUnknownFv
->AuthenticationStatus
= FvInfo2Ppi
->AuthenticationStatus
;
2145 NewUnknownFv
->NotifyDescriptor
.Flags
= (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
);
2146 NewUnknownFv
->NotifyDescriptor
.Guid
= &NewUnknownFv
->FvFormat
;
2147 NewUnknownFv
->NotifyDescriptor
.Notify
= ThirdPartyFvPpiNotifyCallback
;
2149 PeiServicesNotifyPpi (&NewUnknownFv
->NotifyDescriptor
);
2154 Find the FV information according to third-party FV format guid.
2156 This routine also will remove the FV information found by given FV format guid from
2157 PrivateData->UnknownFvInfo[].
2159 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2160 @param Format Point to given FV format guid
2161 @param FvInfo On return, the pointer of FV information buffer
2162 @param FvInfoSize On return, the size of FV information buffer.
2163 @param AuthenticationStatus On return, the authentication status of FV information buffer.
2165 @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI
2166 @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2169 FindUnknownFormatFvInfo (
2170 IN PEI_CORE_INSTANCE
*PrivateData
,
2171 IN EFI_GUID
*Format
,
2173 OUT UINT32
*FvInfoSize
,
2174 OUT UINT32
*AuthenticationStatus
2181 for (; Index
< PrivateData
->UnknownFvInfoCount
; Index
++) {
2182 if (CompareGuid (Format
, &PrivateData
->UnknownFvInfo
[Index
].FvFormat
)) {
2187 if (Index
== PrivateData
->UnknownFvInfoCount
) {
2188 return EFI_NOT_FOUND
;
2191 *FvInfo
= PrivateData
->UnknownFvInfo
[Index
].FvInfo
;
2192 *FvInfoSize
= PrivateData
->UnknownFvInfo
[Index
].FvInfoSize
;
2193 *AuthenticationStatus
= PrivateData
->UnknownFvInfo
[Index
].AuthenticationStatus
;
2196 // Remove an entry from UnknownFvInfo array.
2199 for (;Index2
< PrivateData
->UnknownFvInfoCount
; Index2
++, Index
++) {
2200 CopyMem (&PrivateData
->UnknownFvInfo
[Index
], &PrivateData
->UnknownFvInfo
[Index2
], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO
));
2202 PrivateData
->UnknownFvInfoCount
--;
2207 Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.
2209 When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this
2210 routine is called to process all discoveried FVs in this format.
2212 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
2213 @param NotifyDescriptor Address of the notification descriptor data structure.
2214 @param Ppi Address of the PPI that was installed.
2216 @retval EFI_SUCCESS The notification callback is processed correctly.
2220 ThirdPartyFvPpiNotifyCallback (
2221 IN EFI_PEI_SERVICES
**PeiServices
,
2222 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
2226 PEI_CORE_INSTANCE
*PrivateData
;
2227 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
2230 UINT32 AuthenticationStatus
;
2232 EFI_PEI_FV_HANDLE FvHandle
;
2233 BOOLEAN IsProcessed
;
2235 EFI_PEI_FILE_HANDLE FileHandle
;
2239 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
2240 FvPpi
= (EFI_PEI_FIRMWARE_VOLUME_PPI
*) Ppi
;
2243 Status
= FindUnknownFormatFvInfo (PrivateData
, NotifyDescriptor
->Guid
, &FvInfo
, &FvInfoSize
, &AuthenticationStatus
);
2244 if (EFI_ERROR (Status
)) {
2249 // Process new found FV and get FV handle.
2251 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo
, FvInfoSize
, &FvHandle
);
2252 if (EFI_ERROR (Status
)) {
2253 DEBUG ((EFI_D_ERROR
, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo
));
2258 // Check whether the FV has already been processed.
2260 IsProcessed
= FALSE
;
2261 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
2262 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
2263 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfo
));
2273 if (PrivateData
->FvCount
>= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
2274 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, PcdGet32 (PcdPeiCoreMaxFvSupported
)));
2275 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
2280 // Update internal PEI_CORE_FV array.
2282 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo
;
2283 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
2284 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
2285 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= AuthenticationStatus
;
2286 CurFvCount
= PrivateData
->FvCount
;
2289 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
2290 (UINT32
) CurFvCount
,
2295 PrivateData
->FvCount
++;
2298 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
2302 Status
= FvPpi
->FindFileByType (
2304 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
2308 if (!EFI_ERROR (Status
)) {
2309 Status
= FvPpi
->FindSectionByType (
2311 EFI_SECTION_PEI_DEPEX
,
2315 if (!EFI_ERROR (Status
)) {
2316 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
2318 // Dependency is not satisfied.
2324 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, CurFvCount
, FvHandle
));
2325 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[CurFvCount
], FileHandle
);
2327 } while (FileHandle
!= NULL
);