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 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Library/ExtractGuidedSectionLib.h>
22 #define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
23 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
27 Returns the highest bit set of the State field
29 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
30 in the Attributes field.
31 @param FfsHeader Pointer to FFS File Header
34 @retval the highest bit in the State field
40 IN UINT8 ErasePolarity
,
41 IN EFI_FFS_FILE_HEADER
*FfsHeader
44 EFI_FFS_FILE_STATE FileState
;
45 EFI_FFS_FILE_STATE HighestBit
;
47 FileState
= FfsHeader
->State
;
49 if (ErasePolarity
!= 0) {
50 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
54 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
63 Calculates the checksum of the header of a file.
64 The header is a zero byte checksum, so zero means header is good
66 @param FfsHeader Pointer to FFS File Header
68 @retval Checksum of the header
73 CalculateHeaderChecksum (
74 IN EFI_FFS_FILE_HEADER
*FileHeader
82 Ptr
= (UINT8
*)FileHeader
;
84 for (Index
= 0; Index
< sizeof(EFI_FFS_FILE_HEADER
) - 3; Index
+= 4) {
85 Sum
= (UINT8
)(Sum
+ Ptr
[Index
]);
86 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+1]);
87 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+2]);
88 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+3]);
91 for (; Index
< sizeof(EFI_FFS_FILE_HEADER
); Index
++) {
92 Sum
= (UINT8
)(Sum
+ Ptr
[Index
]);
96 // State field (since this indicates the different state of file).
98 Sum
= (UINT8
)(Sum
- FileHeader
->State
);
100 // Checksum field of the file is not part of the header checksum.
102 Sum
= (UINT8
)(Sum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
109 Given a FileHandle return the VolumeHandle
111 @param FileHandle File handle to look up
112 @param VolumeHandle Match for FileHandle
114 @retval TRUE VolumeHandle is valid
121 IN EFI_PEI_FILE_HANDLE FileHandle
,
122 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
125 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
126 EFI_PEI_HOB_POINTERS Hob
;
128 Hob
.Raw
= GetHobList ();
129 if (Hob
.Raw
== NULL
) {
134 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
);
135 if (Hob
.Raw
!= NULL
) {
136 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)(Hob
.FirmwareVolume
->BaseAddress
);
137 if (((UINT64
) (UINTN
) FileHandle
> (UINT64
) (UINTN
) FwVolHeader
) && \
138 ((UINT64
) (UINTN
) FileHandle
<= ((UINT64
) (UINTN
) FwVolHeader
+ FwVolHeader
->FvLength
- 1))) {
139 *VolumeHandle
= (EFI_PEI_FV_HANDLE
)FwVolHeader
;
143 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, GET_NEXT_HOB (Hob
));
145 } while (Hob
.Raw
!= NULL
);
153 Given the input file pointer, search for the next matching file in the
154 FFS volume as defined by SearchType. The search starts from FileHeader inside
155 the Firmware Volume defined by FwVolHeader.
157 @param FileHandle File handle to look up
158 @param VolumeHandle Match for FileHandle
164 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
165 IN CONST EFI_GUID
*FileName
, OPTIONAL
166 IN EFI_FV_FILETYPE SearchType
,
167 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
170 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
171 EFI_FFS_FILE_HEADER
**FileHeader
;
172 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
173 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
175 UINT32 FileOccupiedSize
;
181 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FvHandle
;
182 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
184 FvLength
= FwVolHeader
->FvLength
;
185 if (FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
192 // If FileHeader is not specified (NULL) or FileName is not NULL,
193 // start with the first file in the firmware volume. Otherwise,
194 // start from the FileHeader.
196 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
197 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
198 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
199 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FwVolHeader
) + FwVolHeader
->ExtHeaderOffset
);
200 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(((UINT8
*)FwVolExHeaderInfo
) + FwVolExHeaderInfo
->ExtHeaderSize
);
204 // Length is 24 bits wide so mask upper 8 bits
205 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
207 FileLength
= *(UINT32
*)(*FileHeader
)->Size
& 0x00FFFFFF;
208 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
209 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
212 // FFS files begin with a header that is aligned on an 8-byte boundary
213 FfsFileHeader
= ALIGN_POINTER (FfsFileHeader
, 8);
215 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
216 ASSERT (FileOffset
<= 0xFFFFFFFF);
218 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
220 // Get FileState which is the highest bit of the State
222 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
226 case EFI_FILE_HEADER_INVALID
:
227 FileOffset
+= sizeof(EFI_FFS_FILE_HEADER
);
228 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
231 case EFI_FILE_DATA_VALID
:
232 case EFI_FILE_MARKED_FOR_UPDATE
:
233 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
236 return EFI_NOT_FOUND
;
239 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
240 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
242 if (FileName
!= NULL
) {
243 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
244 *FileHeader
= FfsFileHeader
;
247 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
248 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
249 *FileHeader
= FfsFileHeader
;
253 FileOffset
+= FileOccupiedSize
;
254 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
257 case EFI_FILE_DELETED
:
258 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
259 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
260 FileOffset
+= FileOccupiedSize
;
261 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
266 return EFI_NOT_FOUND
;
272 return EFI_NOT_FOUND
;
277 Go through the file to search SectionType section,
278 when meeting an encapsuled section.
280 @param SectionType - Filter to find only section of this type.
281 @param Section - From where to search.
282 @param SectionSize - The file size to search.
283 @param OutputBuffer - Pointer to the section to search.
289 IN EFI_SECTION_TYPE SectionType
,
290 IN EFI_COMMON_SECTION_HEADER
*Section
,
291 IN UINTN SectionSize
,
292 OUT VOID
**OutputBuffer
296 UINT32 SectionLength
;
298 EFI_COMPRESSION_SECTION
*CompressionSection
;
299 UINT32 DstBufferSize
;
301 UINT32 ScratchBufferSize
;
303 UINT16 SectionAttribute
;
304 UINT32 AuthenticationStatus
;
307 *OutputBuffer
= NULL
;
309 Status
= EFI_NOT_FOUND
;
310 while (ParsedLength
< SectionSize
) {
311 if (Section
->Type
== SectionType
) {
312 *OutputBuffer
= (VOID
*)(Section
+ 1);
315 } else if ((Section
->Type
== EFI_SECTION_COMPRESSION
) || (Section
->Type
== EFI_SECTION_GUID_DEFINED
)) {
317 if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
318 CompressionSection
= (EFI_COMPRESSION_SECTION
*) Section
;
319 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
321 if (CompressionSection
->CompressionType
!= EFI_STANDARD_COMPRESSION
) {
322 return EFI_UNSUPPORTED
;
325 Status
= UefiDecompressGetInfo (
326 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
327 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
331 } else if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
332 Status
= ExtractGuidedSectionGetInfo (
340 if (EFI_ERROR (Status
)) {
344 DEBUG ((EFI_D_ERROR
, "Decompress GetInfo Failed - %r\n", Status
));
345 return EFI_NOT_FOUND
;
348 // Allocate scratch buffer
350 ScratchBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
351 if (ScratchBuffer
== NULL
) {
352 return EFI_OUT_OF_RESOURCES
;
355 // Allocate destination buffer, extra one page for adjustment
357 DstBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
) + 1);
358 if (DstBuffer
== NULL
) {
359 return EFI_OUT_OF_RESOURCES
;
362 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
363 // to make section data at page alignment.
365 DstBuffer
= (UINT8
*)DstBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER
);
367 // Call decompress function
369 if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
370 Status
= UefiDecompress (
371 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
375 } else if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
376 Status
= ExtractGuidedSectionDecode (
380 &AuthenticationStatus
384 if (EFI_ERROR (Status
)) {
388 DEBUG ((EFI_D_ERROR
, "Decompress Failed - %r\n", Status
));
389 return EFI_NOT_FOUND
;
391 return FfsProcessSection (
401 // Size is 24 bits wide so mask upper 8 bits.
402 // SectionLength is adjusted it is 4 byte aligned.
403 // Go to the next section
405 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
406 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
407 ASSERT (SectionLength
!= 0);
408 ParsedLength
+= SectionLength
;
409 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
412 return EFI_NOT_FOUND
;
418 This service enables discovery sections of a given type within a valid FFS file.
420 @param SearchType The value of the section type to find.
421 @param FfsFileHeader A pointer to the file header that contains the set of sections to
423 @param SectionData A pointer to the discovered section, if successful.
425 @retval EFI_SUCCESS The section was found.
426 @retval EFI_NOT_FOUND The section was not found.
432 IN EFI_SECTION_TYPE SectionType
,
433 IN EFI_PEI_FILE_HANDLE FileHandle
,
434 OUT VOID
**SectionData
437 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
439 EFI_COMMON_SECTION_HEADER
*Section
;
441 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
444 // Size is 24 bits wide so mask upper 8 bits.
445 // Does not include FfsFileHeader header size
446 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
448 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
449 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
450 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
452 return FfsProcessSection (
466 This service enables discovery of additional firmware files.
468 @param SearchType A filter to find files only of this type.
469 @param FwVolHeader Pointer to the firmware volume header of the volume to search.
470 This parameter must point to a valid FFS volume.
471 @param FileHeader Pointer to the current file from which to begin searching.
473 @retval EFI_SUCCESS The file was found.
474 @retval EFI_NOT_FOUND The file was not found.
475 @retval EFI_NOT_FOUND The header checksum was not zero.
482 IN EFI_PEI_FV_HANDLE VolumeHandle
,
483 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
486 return FindFileEx (VolumeHandle
, NULL
, SearchType
, FileHandle
);
491 This service enables discovery of additional firmware volumes.
493 @param Instance This instance of the firmware volume to find. The value 0 is the
494 Boot Firmware Volume (BFV).
495 @param FwVolHeader Pointer to the firmware volume header of the volume to return.
497 @retval EFI_SUCCESS The volume was found.
498 @retval EFI_NOT_FOUND The volume was not found.
505 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
508 EFI_PEI_HOB_POINTERS Hob
;
511 Hob
.Raw
= GetHobList ();
512 if (Hob
.Raw
== NULL
) {
513 return EFI_NOT_FOUND
;
517 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
);
518 if (Hob
.Raw
!= NULL
) {
519 if (Instance
-- == 0) {
520 *VolumeHandle
= (EFI_PEI_FV_HANDLE
)(UINTN
)(Hob
.FirmwareVolume
->BaseAddress
);
524 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, GET_NEXT_HOB (Hob
));
526 } while (Hob
.Raw
!= NULL
);
528 return EFI_NOT_FOUND
;
534 Find a file in the volume by name
536 @param FileName A pointer to the name of the file to
537 find within the firmware volume.
539 @param VolumeHandle The firmware volume to search FileHandle
540 Upon exit, points to the found file's
541 handle or NULL if it could not be found.
543 @retval EFI_SUCCESS File was found.
545 @retval EFI_NOT_FOUND File was not found.
547 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
554 IN CONST EFI_GUID
*FileName
,
555 IN EFI_PEI_FV_HANDLE VolumeHandle
,
556 OUT EFI_PEI_FILE_HANDLE
*FileHandle
560 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
561 return EFI_INVALID_PARAMETER
;
563 Status
= FindFileEx (VolumeHandle
, FileName
, 0, FileHandle
);
564 if (Status
== EFI_NOT_FOUND
) {
574 Get information about the file by name.
576 @param FileHandle Handle of the file.
578 @param FileInfo Upon exit, points to the file's
581 @retval EFI_SUCCESS File information returned.
583 @retval EFI_INVALID_PARAMETER If FileHandle does not
584 represent a valid file.
586 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
592 IN EFI_PEI_FILE_HANDLE FileHandle
,
593 OUT EFI_FV_FILE_INFO
*FileInfo
598 EFI_FFS_FILE_HEADER
*FileHeader
;
599 EFI_PEI_FV_HANDLE VolumeHandle
;
601 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
602 return EFI_INVALID_PARAMETER
;
607 // Retrieve the FirmwareVolume which the file resides in.
609 if (!FileHandleToVolume(FileHandle
, &VolumeHandle
)) {
610 return EFI_INVALID_PARAMETER
;
613 if (((EFI_FIRMWARE_VOLUME_HEADER
*)VolumeHandle
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
620 // Get FileState which is the highest bit of the State
622 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
625 case EFI_FILE_DATA_VALID
:
626 case EFI_FILE_MARKED_FOR_UPDATE
:
629 return EFI_INVALID_PARAMETER
;
632 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
633 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
634 FileInfo
->FileType
= FileHeader
->Type
;
635 FileInfo
->FileAttributes
= FileHeader
->Attributes
;
636 FileInfo
->BufferSize
= ((*(UINT32
*)FileHeader
->Size
) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER
);
637 FileInfo
->Buffer
= (FileHeader
+ 1);
643 Get Information about the volume by name
645 @param VolumeHandle Handle of the volume.
647 @param VolumeInfo Upon exit, points to the volume's
650 @retval EFI_SUCCESS File information returned.
652 @retval EFI_INVALID_PARAMETER If FileHandle does not
653 represent a valid file.
655 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
661 IN EFI_PEI_FV_HANDLE VolumeHandle
,
662 OUT EFI_FV_INFO
*VolumeInfo
665 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
666 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
668 if (VolumeInfo
== NULL
) {
669 return EFI_INVALID_PARAMETER
;
673 // VolumeHandle may not align at 8 byte,
674 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
675 // So, Copy FvHeader into the local FvHeader structure.
677 CopyMem (&FwVolHeader
, VolumeHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
679 // Check Fv Image Signature
681 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
682 return EFI_INVALID_PARAMETER
;
684 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
685 VolumeInfo
->FvStart
= (VOID
*) VolumeHandle
;
686 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
687 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
689 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
690 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)VolumeHandle
) + FwVolHeader
.ExtHeaderOffset
);
691 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));
699 Search through every FV until you find a file of type FileType
701 @param FileType File handle of a Fv type file.
702 @param Volumehandle On succes Volume Handle of the match
703 @param FileHandle On success File Handle of the match
705 @retval EFI_NOT_FOUND FV image can't be found.
706 @retval EFI_SUCCESS Successfully found FileType
711 FfsAnyFvFindFirstFile (
712 IN EFI_FV_FILETYPE FileType
,
713 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
,
714 OUT EFI_PEI_FILE_HANDLE
*FileHandle
721 // Search every FV for the DXE Core
728 Status
= FfsFindNextVolume (Instance
++, VolumeHandle
);
729 if (EFI_ERROR (Status
))
734 Status
= FfsFindNextFile (FileType
, *VolumeHandle
, FileHandle
);
735 if (!EFI_ERROR (Status
))
747 Get Fv image from the FV type file, then add FV & FV2 Hob.
749 @param FileHandle File handle of a Fv type file.
752 @retval EFI_NOT_FOUND FV image can't be found.
753 @retval EFI_SUCCESS Successfully to process it.
759 IN EFI_PEI_FILE_HANDLE FvFileHandle
763 EFI_PEI_FV_HANDLE FvImageHandle
;
764 EFI_FV_INFO FvImageInfo
;
767 EFI_PEI_HOB_POINTERS HobFv2
;
773 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
776 HobFv2
.Raw
= GetHobList ();
777 while ((HobFv2
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobFv2
.Raw
)) != NULL
) {
778 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
), &HobFv2
.FirmwareVolume2
->FileName
)) {
780 // this FILE has been dispatched, it will not be dispatched again.
784 HobFv2
.Raw
= GET_NEXT_HOB (HobFv2
);
788 // Find FvImage in FvFile
790 Status
= FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE
, FvFileHandle
, (VOID
**)&FvImageHandle
);
791 if (EFI_ERROR (Status
)) {
796 // Collect FvImage Info.
798 ZeroMem (&FvImageInfo
, sizeof (FvImageInfo
));
799 Status
= FfsGetVolumeInfo (FvImageHandle
, &FvImageInfo
);
800 ASSERT_EFI_ERROR (Status
);
803 // FvAlignment must be more than 8 bytes required by FvHeader structure.
805 FvAlignment
= 1 << ((FvImageInfo
.FvAttributes
& EFI_FVB2_ALIGNMENT
) >> 16);
806 if (FvAlignment
< 8) {
813 if ((UINTN
) FvImageInfo
.FvStart
% FvAlignment
!= 0) {
814 FvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvImageInfo
.FvSize
), FvAlignment
);
815 if (FvBuffer
== NULL
) {
816 return EFI_OUT_OF_RESOURCES
;
818 CopyMem (FvBuffer
, FvImageInfo
.FvStart
, (UINTN
) FvImageInfo
.FvSize
);
820 // Update FvImageInfo after reload FvImage to new aligned memory
822 FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE
) FvBuffer
, &FvImageInfo
);
827 // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
829 BuildFvHob ((EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
, FvImageInfo
.FvSize
);
832 // Makes the encapsulated volume show up in DXE phase to skip processing of
833 // encapsulated file again.
836 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
839 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)