2 Implementation of the 6 PEI Ffs (FV) APIs in library form.
4 This code only knows about a FV if it has a EFI_HOB_TYPE_FV entry in the HOB list
6 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include <Library/ExtractGuidedSectionLib.h>
15 #define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
16 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
19 Returns the highest bit set of the State field
21 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
22 in the Attributes field.
23 @param FfsHeader Pointer to FFS File Header
26 @retval the highest bit in the State field
32 IN UINT8 ErasePolarity
,
33 IN EFI_FFS_FILE_HEADER
*FfsHeader
36 EFI_FFS_FILE_STATE FileState
;
37 EFI_FFS_FILE_STATE HighestBit
;
39 FileState
= FfsHeader
->State
;
41 if (ErasePolarity
!= 0) {
42 FileState
= (EFI_FFS_FILE_STATE
) ~FileState
;
46 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
54 Calculates the checksum of the header of a file.
55 The header is a zero byte checksum, so zero means header is good
57 @param FfsHeader Pointer to FFS File Header
59 @retval Checksum of the header
64 CalculateHeaderChecksum (
65 IN EFI_FFS_FILE_HEADER
*FileHeader
73 Ptr
= (UINT8
*)FileHeader
;
75 for (Index
= 0; Index
< sizeof (EFI_FFS_FILE_HEADER
) - 3; Index
+= 4) {
76 Sum
= (UINT8
)(Sum
+ Ptr
[Index
]);
77 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+1]);
78 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+2]);
79 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+3]);
82 for ( ; Index
< sizeof (EFI_FFS_FILE_HEADER
); Index
++) {
83 Sum
= (UINT8
)(Sum
+ Ptr
[Index
]);
87 // State field (since this indicates the different state of file).
89 Sum
= (UINT8
)(Sum
- FileHeader
->State
);
91 // Checksum field of the file is not part of the header checksum.
93 Sum
= (UINT8
)(Sum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
99 Given a FileHandle return the VolumeHandle
101 @param FileHandle File handle to look up
102 @param VolumeHandle Match for FileHandle
104 @retval TRUE VolumeHandle is valid
111 IN EFI_PEI_FILE_HANDLE FileHandle
,
112 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
115 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
116 EFI_PEI_HOB_POINTERS Hob
;
118 Hob
.Raw
= GetHobList ();
119 if (Hob
.Raw
== NULL
) {
124 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
);
125 if (Hob
.Raw
!= NULL
) {
126 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)(Hob
.FirmwareVolume
->BaseAddress
);
127 if (((UINT64
)(UINTN
)FileHandle
> (UINT64
)(UINTN
)FwVolHeader
) && \
128 ((UINT64
)(UINTN
)FileHandle
<= ((UINT64
)(UINTN
)FwVolHeader
+ FwVolHeader
->FvLength
- 1)))
130 *VolumeHandle
= (EFI_PEI_FV_HANDLE
)FwVolHeader
;
134 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, GET_NEXT_HOB (Hob
));
136 } while (Hob
.Raw
!= NULL
);
142 Given the input file pointer, search for the next matching file in the
143 FFS volume as defined by SearchType. The search starts from FileHeader inside
144 the Firmware Volume defined by FwVolHeader.
146 @param FileHandle File handle to look up
147 @param VolumeHandle Match for FileHandle
153 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
154 IN CONST EFI_GUID
*FileName OPTIONAL
,
155 IN EFI_FV_FILETYPE SearchType
,
156 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
159 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
160 EFI_FFS_FILE_HEADER
**FileHeader
;
161 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
162 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
164 UINT32 FileOccupiedSize
;
170 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FvHandle
;
171 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
173 FvLength
= FwVolHeader
->FvLength
;
174 if (FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
181 // If FileHeader is not specified (NULL) or FileName is not NULL,
182 // start with the first file in the firmware volume. Otherwise,
183 // start from the FileHeader.
185 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
186 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
187 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
188 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FwVolHeader
) + FwVolHeader
->ExtHeaderOffset
);
189 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(((UINT8
*)FwVolExHeaderInfo
) + FwVolExHeaderInfo
->ExtHeaderSize
);
193 // Length is 24 bits wide so mask upper 8 bits
194 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
196 FileLength
= *(UINT32
*)(*FileHeader
)->Size
& 0x00FFFFFF;
197 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
198 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
201 // FFS files begin with a header that is aligned on an 8-byte boundary
202 FfsFileHeader
= ALIGN_POINTER (FfsFileHeader
, 8);
204 FileOffset
= (UINT32
)((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
205 ASSERT (FileOffset
<= 0xFFFFFFFF);
207 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
209 // Get FileState which is the highest bit of the State
211 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
214 case EFI_FILE_HEADER_INVALID
:
215 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER
);
216 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
219 case EFI_FILE_DATA_VALID
:
220 case EFI_FILE_MARKED_FOR_UPDATE
:
221 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
224 return EFI_NOT_FOUND
;
227 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
228 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
230 if (FileName
!= NULL
) {
231 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
232 *FileHeader
= FfsFileHeader
;
235 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
236 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
))
238 *FileHeader
= FfsFileHeader
;
242 FileOffset
+= FileOccupiedSize
;
243 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
246 case EFI_FILE_DELETED
:
247 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
248 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
249 FileOffset
+= FileOccupiedSize
;
250 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
255 return EFI_NOT_FOUND
;
260 return EFI_NOT_FOUND
;
264 Go through the file to search SectionType section,
265 when meeting an encapsuled section.
267 @param SectionType - Filter to find only section of this type.
268 @param SectionCheckHook - A hook which can check if the section is the target one.
269 @param Section - From where to search.
270 @param SectionSize - The file size to search.
271 @param OutputBuffer - Pointer to the section to search.
277 IN EFI_SECTION_TYPE SectionType
,
278 IN FFS_CHECK_SECTION_HOOK SectionCheckHook
,
279 IN EFI_COMMON_SECTION_HEADER
*Section
,
280 IN UINTN SectionSize
,
281 OUT VOID
**OutputBuffer
285 UINT32 SectionLength
;
287 EFI_COMPRESSION_SECTION
*CompressionSection
;
288 EFI_COMPRESSION_SECTION2
*CompressionSection2
;
289 UINT32 DstBufferSize
;
291 UINT32 ScratchBufferSize
;
293 UINT16 SectionAttribute
;
294 UINT32 AuthenticationStatus
;
295 CHAR8
*CompressedData
;
296 UINT32 CompressedDataLength
;
300 *OutputBuffer
= NULL
;
302 Status
= EFI_NOT_FOUND
;
303 while (ParsedLength
< SectionSize
) {
304 if (IS_SECTION2 (Section
)) {
305 ASSERT (SECTION2_SIZE (Section
) > 0x00FFFFFF);
308 if (Section
->Type
== SectionType
) {
309 if (SectionCheckHook
!= NULL
) {
310 Found
= SectionCheckHook (Section
) == EFI_SUCCESS
;
316 if (IS_SECTION2 (Section
)) {
317 *OutputBuffer
= (VOID
*)((UINT8
*)Section
+ sizeof (EFI_COMMON_SECTION_HEADER2
));
319 *OutputBuffer
= (VOID
*)((UINT8
*)Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
324 goto CheckNextSection
;
326 } else if ((Section
->Type
== EFI_SECTION_COMPRESSION
) || (Section
->Type
== EFI_SECTION_GUID_DEFINED
)) {
327 if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
328 if (IS_SECTION2 (Section
)) {
329 CompressionSection2
= (EFI_COMPRESSION_SECTION2
*)Section
;
330 SectionLength
= SECTION2_SIZE (Section
);
332 if (CompressionSection2
->CompressionType
!= EFI_STANDARD_COMPRESSION
) {
333 return EFI_UNSUPPORTED
;
336 CompressedData
= (CHAR8
*)((EFI_COMPRESSION_SECTION2
*)Section
+ 1);
337 CompressedDataLength
= SectionLength
- sizeof (EFI_COMPRESSION_SECTION2
);
339 CompressionSection
= (EFI_COMPRESSION_SECTION
*)Section
;
340 SectionLength
= SECTION_SIZE (Section
);
342 if (CompressionSection
->CompressionType
!= EFI_STANDARD_COMPRESSION
) {
343 return EFI_UNSUPPORTED
;
346 CompressedData
= (CHAR8
*)((EFI_COMPRESSION_SECTION
*)Section
+ 1);
347 CompressedDataLength
= SectionLength
- sizeof (EFI_COMPRESSION_SECTION
);
350 Status
= UefiDecompressGetInfo (
352 CompressedDataLength
,
356 } else if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
357 Status
= ExtractGuidedSectionGetInfo (
365 if (EFI_ERROR (Status
)) {
369 DEBUG ((DEBUG_ERROR
, "Decompress GetInfo Failed - %r\n", Status
));
370 return EFI_NOT_FOUND
;
374 // Allocate scratch buffer
376 ScratchBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
377 if (ScratchBuffer
== NULL
) {
378 return EFI_OUT_OF_RESOURCES
;
382 // Allocate destination buffer, extra one page for adjustment
384 DstBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
) + 1);
385 if (DstBuffer
== NULL
) {
386 return EFI_OUT_OF_RESOURCES
;
390 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
391 // to make section data at page alignment.
393 if (IS_SECTION2 (Section
)) {
394 DstBuffer
= (UINT8
*)DstBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER2
);
396 DstBuffer
= (UINT8
*)DstBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER
);
400 // Call decompress function
402 if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
403 if (IS_SECTION2 (Section
)) {
404 CompressedData
= (CHAR8
*)((EFI_COMPRESSION_SECTION2
*)Section
+ 1);
406 CompressedData
= (CHAR8
*)((EFI_COMPRESSION_SECTION
*)Section
+ 1);
409 Status
= UefiDecompress (
414 } else if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
415 Status
= ExtractGuidedSectionDecode (
419 &AuthenticationStatus
423 if (EFI_ERROR (Status
)) {
427 DEBUG ((DEBUG_ERROR
, "Decompress Failed - %r\n", Status
));
428 return EFI_NOT_FOUND
;
430 return FfsProcessSection (
441 if (IS_SECTION2 (Section
)) {
442 SectionLength
= SECTION2_SIZE (Section
);
444 SectionLength
= SECTION_SIZE (Section
);
448 // SectionLength is adjusted it is 4 byte aligned.
449 // Go to the next section
451 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
452 ASSERT (SectionLength
!= 0);
453 ParsedLength
+= SectionLength
;
454 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
457 return EFI_NOT_FOUND
;
461 This service enables discovery sections of a given type within a valid FFS file.
462 Caller also can provide a SectionCheckHook to do additional checking.
464 @param SectionType The value of the section type to find.
465 @param SectionCheckHook A hook which can check if the section is the target one.
466 @param FileHandle A pointer to the file header that contains the set of sections to
468 @param SectionData A pointer to the discovered section, if successful.
470 @retval EFI_SUCCESS The section was found.
471 @retval EFI_NOT_FOUND The section was not found.
476 FfsFindSectionDataWithHook (
477 IN EFI_SECTION_TYPE SectionType
,
478 IN FFS_CHECK_SECTION_HOOK SectionCheckHook
,
479 IN EFI_PEI_FILE_HANDLE FileHandle
,
480 OUT VOID
**SectionData
483 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
485 EFI_COMMON_SECTION_HEADER
*Section
;
487 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
490 // Size is 24 bits wide so mask upper 8 bits.
491 // Does not include FfsFileHeader header size
492 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
494 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
495 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
496 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
498 return FfsProcessSection (
508 This service enables discovery sections of a given type within a valid FFS file.
510 @param SectionType The value of the section type to find.
511 @param FileHandle A pointer to the file header that contains the set of sections to
513 @param SectionData A pointer to the discovered section, if successful.
515 @retval EFI_SUCCESS The section was found.
516 @retval EFI_NOT_FOUND The section was not found.
522 IN EFI_SECTION_TYPE SectionType
,
523 IN EFI_PEI_FILE_HANDLE FileHandle
,
524 OUT VOID
**SectionData
527 return FfsFindSectionDataWithHook (SectionType
, NULL
, FileHandle
, SectionData
);
531 This service enables discovery of additional firmware files.
533 @param SearchType A filter to find files only of this type.
534 @param FwVolHeader Pointer to the firmware volume header of the volume to search.
535 This parameter must point to a valid FFS volume.
536 @param FileHeader Pointer to the current file from which to begin searching.
538 @retval EFI_SUCCESS The file was found.
539 @retval EFI_NOT_FOUND The file was not found.
540 @retval EFI_NOT_FOUND The header checksum was not zero.
547 IN EFI_PEI_FV_HANDLE VolumeHandle
,
548 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
551 return FindFileEx (VolumeHandle
, NULL
, SearchType
, FileHandle
);
555 This service enables discovery of additional firmware volumes.
557 @param Instance This instance of the firmware volume to find. The value 0 is the
558 Boot Firmware Volume (BFV).
559 @param FwVolHeader Pointer to the firmware volume header of the volume to return.
561 @retval EFI_SUCCESS The volume was found.
562 @retval EFI_NOT_FOUND The volume was not found.
569 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
572 EFI_PEI_HOB_POINTERS Hob
;
574 Hob
.Raw
= GetHobList ();
575 if (Hob
.Raw
== NULL
) {
576 return EFI_NOT_FOUND
;
580 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
);
581 if (Hob
.Raw
!= NULL
) {
582 if (Instance
-- == 0) {
583 *VolumeHandle
= (EFI_PEI_FV_HANDLE
)(UINTN
)(Hob
.FirmwareVolume
->BaseAddress
);
587 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, GET_NEXT_HOB (Hob
));
589 } while (Hob
.Raw
!= NULL
);
591 return EFI_NOT_FOUND
;
595 Find a file in the volume by name
597 @param FileName A pointer to the name of the file to
598 find within the firmware volume.
600 @param VolumeHandle The firmware volume to search FileHandle
601 Upon exit, points to the found file's
602 handle or NULL if it could not be found.
604 @retval EFI_SUCCESS File was found.
606 @retval EFI_NOT_FOUND File was not found.
608 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
615 IN CONST EFI_GUID
*FileName
,
616 IN EFI_PEI_FV_HANDLE VolumeHandle
,
617 OUT EFI_PEI_FILE_HANDLE
*FileHandle
622 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
623 return EFI_INVALID_PARAMETER
;
626 Status
= FindFileEx (VolumeHandle
, FileName
, 0, FileHandle
);
627 if (Status
== EFI_NOT_FOUND
) {
635 Get information about the file by name.
637 @param FileHandle Handle of the file.
639 @param FileInfo Upon exit, points to the file's
642 @retval EFI_SUCCESS File information returned.
644 @retval EFI_INVALID_PARAMETER If FileHandle does not
645 represent a valid file.
647 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
653 IN EFI_PEI_FILE_HANDLE FileHandle
,
654 OUT EFI_FV_FILE_INFO
*FileInfo
659 EFI_FFS_FILE_HEADER
*FileHeader
;
660 EFI_PEI_FV_HANDLE VolumeHandle
;
662 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
663 return EFI_INVALID_PARAMETER
;
668 // Retrieve the FirmwareVolume which the file resides in.
670 if (!FileHandleToVolume (FileHandle
, &VolumeHandle
)) {
671 return EFI_INVALID_PARAMETER
;
674 if (((EFI_FIRMWARE_VOLUME_HEADER
*)VolumeHandle
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
681 // Get FileState which is the highest bit of the State
683 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
686 case EFI_FILE_DATA_VALID
:
687 case EFI_FILE_MARKED_FOR_UPDATE
:
690 return EFI_INVALID_PARAMETER
;
693 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
694 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof (EFI_GUID
));
695 FileInfo
->FileType
= FileHeader
->Type
;
696 FileInfo
->FileAttributes
= FileHeader
->Attributes
;
697 FileInfo
->BufferSize
= ((*(UINT32
*)FileHeader
->Size
) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER
);
698 FileInfo
->Buffer
= (FileHeader
+ 1);
703 Get Information about the volume by name
705 @param VolumeHandle Handle of the volume.
707 @param VolumeInfo Upon exit, points to the volume's
710 @retval EFI_SUCCESS File information returned.
712 @retval EFI_INVALID_PARAMETER If FileHandle does not
713 represent a valid file.
715 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
721 IN EFI_PEI_FV_HANDLE VolumeHandle
,
722 OUT EFI_FV_INFO
*VolumeInfo
725 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
726 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
728 if (VolumeInfo
== NULL
) {
729 return EFI_INVALID_PARAMETER
;
733 // VolumeHandle may not align at 8 byte,
734 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
735 // So, Copy FvHeader into the local FvHeader structure.
737 CopyMem (&FwVolHeader
, VolumeHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
739 // Check Fv Image Signature
741 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
742 return EFI_INVALID_PARAMETER
;
745 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
746 VolumeInfo
->FvStart
= (VOID
*)VolumeHandle
;
747 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
748 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof (EFI_GUID
));
750 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
751 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)VolumeHandle
) + FwVolHeader
.ExtHeaderOffset
);
752 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof (EFI_GUID
));
759 Search through every FV until you find a file of type FileType
761 @param FileType File handle of a Fv type file.
762 @param Volumehandle On success Volume Handle of the match
763 @param FileHandle On success File Handle of the match
765 @retval EFI_NOT_FOUND FV image can't be found.
766 @retval EFI_SUCCESS Successfully found FileType
771 FfsAnyFvFindFirstFile (
772 IN EFI_FV_FILETYPE FileType
,
773 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
,
774 OUT EFI_PEI_FILE_HANDLE
*FileHandle
781 // Search every FV for the DXE Core
787 Status
= FfsFindNextVolume (Instance
++, VolumeHandle
);
788 if (EFI_ERROR (Status
)) {
792 Status
= FfsFindNextFile (FileType
, *VolumeHandle
, FileHandle
);
793 if (!EFI_ERROR (Status
)) {
802 Get Fv image from the FV type file, then add FV & FV2 Hob.
804 @param FileHandle File handle of a Fv type file.
807 @retval EFI_NOT_FOUND FV image can't be found.
808 @retval EFI_SUCCESS Successfully to process it.
814 IN EFI_PEI_FILE_HANDLE FvFileHandle
818 EFI_PEI_FV_HANDLE FvImageHandle
;
819 EFI_FV_INFO FvImageInfo
;
822 EFI_PEI_HOB_POINTERS HobFv2
;
827 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
830 HobFv2
.Raw
= GetHobList ();
831 while ((HobFv2
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobFv2
.Raw
)) != NULL
) {
832 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
), &HobFv2
.FirmwareVolume2
->FileName
)) {
834 // this FILE has been dispatched, it will not be dispatched again.
839 HobFv2
.Raw
= GET_NEXT_HOB (HobFv2
);
843 // Find FvImage in FvFile
845 Status
= FfsFindSectionDataWithHook (EFI_SECTION_FIRMWARE_VOLUME_IMAGE
, NULL
, FvFileHandle
, (VOID
**)&FvImageHandle
);
846 if (EFI_ERROR (Status
)) {
851 // Collect FvImage Info.
853 ZeroMem (&FvImageInfo
, sizeof (FvImageInfo
));
854 Status
= FfsGetVolumeInfo (FvImageHandle
, &FvImageInfo
);
855 ASSERT_EFI_ERROR (Status
);
858 // FvAlignment must be more than 8 bytes required by FvHeader structure.
860 FvAlignment
= 1 << ((FvImageInfo
.FvAttributes
& EFI_FVB2_ALIGNMENT
) >> 16);
861 if (FvAlignment
< 8) {
868 if ((UINTN
)FvImageInfo
.FvStart
% FvAlignment
!= 0) {
869 FvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
)FvImageInfo
.FvSize
), FvAlignment
);
870 if (FvBuffer
== NULL
) {
871 return EFI_OUT_OF_RESOURCES
;
874 CopyMem (FvBuffer
, FvImageInfo
.FvStart
, (UINTN
)FvImageInfo
.FvSize
);
876 // Update FvImageInfo after reload FvImage to new aligned memory
878 FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE
)FvBuffer
, &FvImageInfo
);
882 // Inform HOB consumer phase, i.e. DXE core, the existence of this FV
884 BuildFvHob ((EFI_PHYSICAL_ADDRESS
)(UINTN
)FvImageInfo
.FvStart
, FvImageInfo
.FvSize
);
887 // Makes the encapsulated volume show up in DXE phase to skip processing of
888 // encapsulated file again.
891 (EFI_PHYSICAL_ADDRESS
)(UINTN
)FvImageInfo
.FvStart
,
894 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)