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 Section - From where to search.
269 @param SectionSize - The file size to search.
270 @param OutputBuffer - Pointer to the section to search.
276 IN EFI_SECTION_TYPE SectionType
,
277 IN EFI_COMMON_SECTION_HEADER
*Section
,
278 IN UINTN SectionSize
,
279 OUT VOID
**OutputBuffer
283 UINT32 SectionLength
;
285 EFI_COMPRESSION_SECTION
*CompressionSection
;
286 EFI_COMPRESSION_SECTION2
*CompressionSection2
;
287 UINT32 DstBufferSize
;
289 UINT32 ScratchBufferSize
;
291 UINT16 SectionAttribute
;
292 UINT32 AuthenticationStatus
;
293 CHAR8
*CompressedData
;
294 UINT32 CompressedDataLength
;
296 *OutputBuffer
= NULL
;
298 Status
= EFI_NOT_FOUND
;
299 while (ParsedLength
< SectionSize
) {
300 if (IS_SECTION2 (Section
)) {
301 ASSERT (SECTION2_SIZE (Section
) > 0x00FFFFFF);
304 if (Section
->Type
== SectionType
) {
305 if (IS_SECTION2 (Section
)) {
306 *OutputBuffer
= (VOID
*)((UINT8
*)Section
+ sizeof (EFI_COMMON_SECTION_HEADER2
));
308 *OutputBuffer
= (VOID
*)((UINT8
*)Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
312 } else if ((Section
->Type
== EFI_SECTION_COMPRESSION
) || (Section
->Type
== EFI_SECTION_GUID_DEFINED
)) {
313 if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
314 if (IS_SECTION2 (Section
)) {
315 CompressionSection2
= (EFI_COMPRESSION_SECTION2
*)Section
;
316 SectionLength
= SECTION2_SIZE (Section
);
318 if (CompressionSection2
->CompressionType
!= EFI_STANDARD_COMPRESSION
) {
319 return EFI_UNSUPPORTED
;
322 CompressedData
= (CHAR8
*)((EFI_COMPRESSION_SECTION2
*)Section
+ 1);
323 CompressedDataLength
= SectionLength
- sizeof (EFI_COMPRESSION_SECTION2
);
325 CompressionSection
= (EFI_COMPRESSION_SECTION
*)Section
;
326 SectionLength
= SECTION_SIZE (Section
);
328 if (CompressionSection
->CompressionType
!= EFI_STANDARD_COMPRESSION
) {
329 return EFI_UNSUPPORTED
;
332 CompressedData
= (CHAR8
*)((EFI_COMPRESSION_SECTION
*)Section
+ 1);
333 CompressedDataLength
= SectionLength
- sizeof (EFI_COMPRESSION_SECTION
);
336 Status
= UefiDecompressGetInfo (
338 CompressedDataLength
,
342 } else if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
343 Status
= ExtractGuidedSectionGetInfo (
351 if (EFI_ERROR (Status
)) {
355 DEBUG ((DEBUG_ERROR
, "Decompress GetInfo Failed - %r\n", Status
));
356 return EFI_NOT_FOUND
;
360 // Allocate scratch buffer
362 ScratchBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
363 if (ScratchBuffer
== NULL
) {
364 return EFI_OUT_OF_RESOURCES
;
368 // Allocate destination buffer, extra one page for adjustment
370 DstBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
) + 1);
371 if (DstBuffer
== NULL
) {
372 return EFI_OUT_OF_RESOURCES
;
376 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
377 // to make section data at page alignment.
379 if (IS_SECTION2 (Section
)) {
380 DstBuffer
= (UINT8
*)DstBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER2
);
382 DstBuffer
= (UINT8
*)DstBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER
);
386 // Call decompress function
388 if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
389 if (IS_SECTION2 (Section
)) {
390 CompressedData
= (CHAR8
*)((EFI_COMPRESSION_SECTION2
*)Section
+ 1);
392 CompressedData
= (CHAR8
*)((EFI_COMPRESSION_SECTION
*)Section
+ 1);
395 Status
= UefiDecompress (
400 } else if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
401 Status
= ExtractGuidedSectionDecode (
405 &AuthenticationStatus
409 if (EFI_ERROR (Status
)) {
413 DEBUG ((DEBUG_ERROR
, "Decompress Failed - %r\n", Status
));
414 return EFI_NOT_FOUND
;
416 return FfsProcessSection (
425 if (IS_SECTION2 (Section
)) {
426 SectionLength
= SECTION2_SIZE (Section
);
428 SectionLength
= SECTION_SIZE (Section
);
432 // SectionLength is adjusted it is 4 byte aligned.
433 // Go to the next section
435 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
436 ASSERT (SectionLength
!= 0);
437 ParsedLength
+= SectionLength
;
438 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
441 return EFI_NOT_FOUND
;
445 This service enables discovery sections of a given type within a valid FFS file.
447 @param SearchType The value of the section type to find.
448 @param FfsFileHeader A pointer to the file header that contains the set of sections to
450 @param SectionData A pointer to the discovered section, if successful.
452 @retval EFI_SUCCESS The section was found.
453 @retval EFI_NOT_FOUND The section was not found.
459 IN EFI_SECTION_TYPE SectionType
,
460 IN EFI_PEI_FILE_HANDLE FileHandle
,
461 OUT VOID
**SectionData
464 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
466 EFI_COMMON_SECTION_HEADER
*Section
;
468 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
471 // Size is 24 bits wide so mask upper 8 bits.
472 // Does not include FfsFileHeader header size
473 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
475 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
476 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
477 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
479 return FfsProcessSection (
488 This service enables discovery of additional firmware files.
490 @param SearchType A filter to find files only of this type.
491 @param FwVolHeader Pointer to the firmware volume header of the volume to search.
492 This parameter must point to a valid FFS volume.
493 @param FileHeader Pointer to the current file from which to begin searching.
495 @retval EFI_SUCCESS The file was found.
496 @retval EFI_NOT_FOUND The file was not found.
497 @retval EFI_NOT_FOUND The header checksum was not zero.
504 IN EFI_PEI_FV_HANDLE VolumeHandle
,
505 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
508 return FindFileEx (VolumeHandle
, NULL
, SearchType
, FileHandle
);
512 This service enables discovery of additional firmware volumes.
514 @param Instance This instance of the firmware volume to find. The value 0 is the
515 Boot Firmware Volume (BFV).
516 @param FwVolHeader Pointer to the firmware volume header of the volume to return.
518 @retval EFI_SUCCESS The volume was found.
519 @retval EFI_NOT_FOUND The volume was not found.
526 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
529 EFI_PEI_HOB_POINTERS Hob
;
531 Hob
.Raw
= GetHobList ();
532 if (Hob
.Raw
== NULL
) {
533 return EFI_NOT_FOUND
;
537 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
);
538 if (Hob
.Raw
!= NULL
) {
539 if (Instance
-- == 0) {
540 *VolumeHandle
= (EFI_PEI_FV_HANDLE
)(UINTN
)(Hob
.FirmwareVolume
->BaseAddress
);
544 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, GET_NEXT_HOB (Hob
));
546 } while (Hob
.Raw
!= NULL
);
548 return EFI_NOT_FOUND
;
552 Find a file in the volume by name
554 @param FileName A pointer to the name of the file to
555 find within the firmware volume.
557 @param VolumeHandle The firmware volume to search FileHandle
558 Upon exit, points to the found file's
559 handle or NULL if it could not be found.
561 @retval EFI_SUCCESS File was found.
563 @retval EFI_NOT_FOUND File was not found.
565 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
572 IN CONST EFI_GUID
*FileName
,
573 IN EFI_PEI_FV_HANDLE VolumeHandle
,
574 OUT EFI_PEI_FILE_HANDLE
*FileHandle
579 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
580 return EFI_INVALID_PARAMETER
;
583 Status
= FindFileEx (VolumeHandle
, FileName
, 0, FileHandle
);
584 if (Status
== EFI_NOT_FOUND
) {
592 Get information about the file by name.
594 @param FileHandle Handle of the file.
596 @param FileInfo Upon exit, points to the file's
599 @retval EFI_SUCCESS File information returned.
601 @retval EFI_INVALID_PARAMETER If FileHandle does not
602 represent a valid file.
604 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
610 IN EFI_PEI_FILE_HANDLE FileHandle
,
611 OUT EFI_FV_FILE_INFO
*FileInfo
616 EFI_FFS_FILE_HEADER
*FileHeader
;
617 EFI_PEI_FV_HANDLE VolumeHandle
;
619 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
620 return EFI_INVALID_PARAMETER
;
625 // Retrieve the FirmwareVolume which the file resides in.
627 if (!FileHandleToVolume (FileHandle
, &VolumeHandle
)) {
628 return EFI_INVALID_PARAMETER
;
631 if (((EFI_FIRMWARE_VOLUME_HEADER
*)VolumeHandle
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
638 // Get FileState which is the highest bit of the State
640 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
643 case EFI_FILE_DATA_VALID
:
644 case EFI_FILE_MARKED_FOR_UPDATE
:
647 return EFI_INVALID_PARAMETER
;
650 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
651 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof (EFI_GUID
));
652 FileInfo
->FileType
= FileHeader
->Type
;
653 FileInfo
->FileAttributes
= FileHeader
->Attributes
;
654 FileInfo
->BufferSize
= ((*(UINT32
*)FileHeader
->Size
) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER
);
655 FileInfo
->Buffer
= (FileHeader
+ 1);
660 Get Information about the volume by name
662 @param VolumeHandle Handle of the volume.
664 @param VolumeInfo Upon exit, points to the volume's
667 @retval EFI_SUCCESS File information returned.
669 @retval EFI_INVALID_PARAMETER If FileHandle does not
670 represent a valid file.
672 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
678 IN EFI_PEI_FV_HANDLE VolumeHandle
,
679 OUT EFI_FV_INFO
*VolumeInfo
682 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
683 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
685 if (VolumeInfo
== NULL
) {
686 return EFI_INVALID_PARAMETER
;
690 // VolumeHandle may not align at 8 byte,
691 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
692 // So, Copy FvHeader into the local FvHeader structure.
694 CopyMem (&FwVolHeader
, VolumeHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
696 // Check Fv Image Signature
698 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
699 return EFI_INVALID_PARAMETER
;
702 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
703 VolumeInfo
->FvStart
= (VOID
*)VolumeHandle
;
704 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
705 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof (EFI_GUID
));
707 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
708 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)VolumeHandle
) + FwVolHeader
.ExtHeaderOffset
);
709 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof (EFI_GUID
));
716 Search through every FV until you find a file of type FileType
718 @param FileType File handle of a Fv type file.
719 @param Volumehandle On success Volume Handle of the match
720 @param FileHandle On success File Handle of the match
722 @retval EFI_NOT_FOUND FV image can't be found.
723 @retval EFI_SUCCESS Successfully found FileType
728 FfsAnyFvFindFirstFile (
729 IN EFI_FV_FILETYPE FileType
,
730 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
,
731 OUT EFI_PEI_FILE_HANDLE
*FileHandle
738 // Search every FV for the DXE Core
744 Status
= FfsFindNextVolume (Instance
++, VolumeHandle
);
745 if (EFI_ERROR (Status
)) {
749 Status
= FfsFindNextFile (FileType
, *VolumeHandle
, FileHandle
);
750 if (!EFI_ERROR (Status
)) {
759 Get Fv image from the FV type file, then add FV & FV2 Hob.
761 @param FileHandle File handle of a Fv type file.
764 @retval EFI_NOT_FOUND FV image can't be found.
765 @retval EFI_SUCCESS Successfully to process it.
771 IN EFI_PEI_FILE_HANDLE FvFileHandle
775 EFI_PEI_FV_HANDLE FvImageHandle
;
776 EFI_FV_INFO FvImageInfo
;
779 EFI_PEI_HOB_POINTERS HobFv2
;
784 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
787 HobFv2
.Raw
= GetHobList ();
788 while ((HobFv2
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobFv2
.Raw
)) != NULL
) {
789 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
), &HobFv2
.FirmwareVolume2
->FileName
)) {
791 // this FILE has been dispatched, it will not be dispatched again.
796 HobFv2
.Raw
= GET_NEXT_HOB (HobFv2
);
800 // Find FvImage in FvFile
802 Status
= FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE
, FvFileHandle
, (VOID
**)&FvImageHandle
);
803 if (EFI_ERROR (Status
)) {
808 // Collect FvImage Info.
810 ZeroMem (&FvImageInfo
, sizeof (FvImageInfo
));
811 Status
= FfsGetVolumeInfo (FvImageHandle
, &FvImageInfo
);
812 ASSERT_EFI_ERROR (Status
);
815 // FvAlignment must be more than 8 bytes required by FvHeader structure.
817 FvAlignment
= 1 << ((FvImageInfo
.FvAttributes
& EFI_FVB2_ALIGNMENT
) >> 16);
818 if (FvAlignment
< 8) {
825 if ((UINTN
)FvImageInfo
.FvStart
% FvAlignment
!= 0) {
826 FvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
)FvImageInfo
.FvSize
), FvAlignment
);
827 if (FvBuffer
== NULL
) {
828 return EFI_OUT_OF_RESOURCES
;
831 CopyMem (FvBuffer
, FvImageInfo
.FvStart
, (UINTN
)FvImageInfo
.FvSize
);
833 // Update FvImageInfo after reload FvImage to new aligned memory
835 FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE
)FvBuffer
, &FvImageInfo
);
839 // Inform HOB consumer phase, i.e. DXE core, the existence of this FV
841 BuildFvHob ((EFI_PHYSICAL_ADDRESS
)(UINTN
)FvImageInfo
.FvStart
, FvImageInfo
.FvSize
);
844 // Makes the encapsulated volume show up in DXE phase to skip processing of
845 // encapsulated file again.
848 (EFI_PHYSICAL_ADDRESS
)(UINTN
)FvImageInfo
.FvStart
,
851 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)