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 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
213 ASSERT (FileOffset
<= 0xFFFFFFFF);
215 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
217 // Get FileState which is the highest bit of the State
219 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
223 case EFI_FILE_HEADER_INVALID
:
224 FileOffset
+= sizeof(EFI_FFS_FILE_HEADER
);
225 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
228 case EFI_FILE_DATA_VALID
:
229 case EFI_FILE_MARKED_FOR_UPDATE
:
230 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
233 return EFI_NOT_FOUND
;
236 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
237 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
239 if (FileName
!= NULL
) {
240 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
241 *FileHeader
= FfsFileHeader
;
244 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
245 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
246 *FileHeader
= FfsFileHeader
;
250 FileOffset
+= FileOccupiedSize
;
251 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
254 case EFI_FILE_DELETED
:
255 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
256 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
257 FileOffset
+= FileOccupiedSize
;
258 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
263 return EFI_NOT_FOUND
;
269 return EFI_NOT_FOUND
;
274 Go through the file to search SectionType section,
275 when meeting an encapsuled section.
277 @param SectionType - Filter to find only section of this type.
278 @param Section - From where to search.
279 @param SectionSize - The file size to search.
280 @param OutputBuffer - Pointer to the section to search.
286 IN EFI_SECTION_TYPE SectionType
,
287 IN EFI_COMMON_SECTION_HEADER
*Section
,
288 IN UINTN SectionSize
,
289 OUT VOID
**OutputBuffer
293 UINT32 SectionLength
;
295 EFI_COMPRESSION_SECTION
*CompressionSection
;
298 UINT32 ScratchBufferSize
;
300 UINT16 SectionAttribute
;
301 UINT32 AuthenticationStatus
;
304 *OutputBuffer
= NULL
;
306 Status
= EFI_NOT_FOUND
;
307 while (ParsedLength
< SectionSize
) {
308 if (Section
->Type
== SectionType
) {
309 *OutputBuffer
= (VOID
*)(Section
+ 1);
312 } else if ((Section
->Type
== EFI_SECTION_COMPRESSION
) || (Section
->Type
== EFI_SECTION_GUID_DEFINED
)) {
314 if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
315 CompressionSection
= (EFI_COMPRESSION_SECTION
*) Section
;
316 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
318 if (CompressionSection
->CompressionType
!= EFI_STANDARD_COMPRESSION
) {
319 return EFI_UNSUPPORTED
;
322 Status
= UefiDecompressGetInfo (
323 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
324 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
325 (UINT32
*) &DstBufferSize
,
328 } else if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
329 Status
= ExtractGuidedSectionGetInfo (
331 (UINT32
*) &DstBufferSize
,
337 if (EFI_ERROR (Status
)) {
341 DEBUG ((EFI_D_ERROR
, "Decompress GetInfo Failed - %r\n", Status
));
342 return EFI_NOT_FOUND
;
345 // Allocate scratch buffer
347 ScratchBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
348 if (ScratchBuffer
== NULL
) {
349 return EFI_OUT_OF_RESOURCES
;
352 // Allocate destination buffer, extra one page for adjustment
354 DstBuffer
= (VOID
*)(UINTN
)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
) + 1);
355 if (DstBuffer
== NULL
) {
356 return EFI_OUT_OF_RESOURCES
;
359 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
360 // to make section data at page alignment.
362 DstBuffer
= (UINT8
*)DstBuffer
+ EFI_PAGE_SIZE
- sizeof (EFI_COMMON_SECTION_HEADER
);
364 // Call decompress function
366 if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
367 Status
= UefiDecompress (
368 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
372 } else if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
373 Status
= ExtractGuidedSectionDecode (
377 &AuthenticationStatus
381 if (EFI_ERROR (Status
)) {
385 DEBUG ((EFI_D_ERROR
, "Decompress Failed - %r\n", Status
));
386 return EFI_NOT_FOUND
;
388 return FfsProcessSection (
398 // Size is 24 bits wide so mask upper 8 bits.
399 // SectionLength is adjusted it is 4 byte aligned.
400 // Go to the next section
402 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
403 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
404 ASSERT (SectionLength
!= 0);
405 ParsedLength
+= SectionLength
;
406 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
409 return EFI_NOT_FOUND
;
415 This service enables discovery sections of a given type within a valid FFS file.
417 @param SearchType The value of the section type to find.
418 @param FfsFileHeader A pointer to the file header that contains the set of sections to
420 @param SectionData A pointer to the discovered section, if successful.
422 @retval EFI_SUCCESS The section was found.
423 @retval EFI_NOT_FOUND The section was not found.
429 IN EFI_SECTION_TYPE SectionType
,
430 IN EFI_PEI_FILE_HANDLE FileHandle
,
431 OUT VOID
**SectionData
434 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
436 EFI_COMMON_SECTION_HEADER
*Section
;
438 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
441 // Size is 24 bits wide so mask upper 8 bits.
442 // Does not include FfsFileHeader header size
443 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
445 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
446 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
447 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
449 return FfsProcessSection (
463 This service enables discovery of additional firmware files.
465 @param SearchType A filter to find files only of this type.
466 @param FwVolHeader Pointer to the firmware volume header of the volume to search.
467 This parameter must point to a valid FFS volume.
468 @param FileHeader Pointer to the current file from which to begin searching.
470 @retval EFI_SUCCESS The file was found.
471 @retval EFI_NOT_FOUND The file was not found.
472 @retval EFI_NOT_FOUND The header checksum was not zero.
479 IN EFI_PEI_FV_HANDLE VolumeHandle
,
480 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
483 return FindFileEx (VolumeHandle
, NULL
, SearchType
, FileHandle
);
488 This service enables discovery of additional firmware volumes.
490 @param Instance This instance of the firmware volume to find. The value 0 is the
491 Boot Firmware Volume (BFV).
492 @param FwVolHeader Pointer to the firmware volume header of the volume to return.
494 @retval EFI_SUCCESS The volume was found.
495 @retval EFI_NOT_FOUND The volume was not found.
502 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
505 EFI_PEI_HOB_POINTERS Hob
;
508 Hob
.Raw
= GetHobList ();
509 if (Hob
.Raw
== NULL
) {
510 return EFI_NOT_FOUND
;
514 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
);
515 if (Hob
.Raw
!= NULL
) {
516 if (Instance
-- == 0) {
517 *VolumeHandle
= (EFI_PEI_FV_HANDLE
)(UINTN
)(Hob
.FirmwareVolume
->BaseAddress
);
521 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, GET_NEXT_HOB (Hob
));
523 } while (Hob
.Raw
!= NULL
);
525 return EFI_NOT_FOUND
;
531 Find a file in the volume by name
533 @param FileName A pointer to the name of the file to
534 find within the firmware volume.
536 @param VolumeHandle The firmware volume to search FileHandle
537 Upon exit, points to the found file's
538 handle or NULL if it could not be found.
540 @retval EFI_SUCCESS File was found.
542 @retval EFI_NOT_FOUND File was not found.
544 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
551 IN CONST EFI_GUID
*FileName
,
552 IN EFI_PEI_FV_HANDLE VolumeHandle
,
553 OUT EFI_PEI_FILE_HANDLE
*FileHandle
557 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
558 return EFI_INVALID_PARAMETER
;
560 Status
= FindFileEx (VolumeHandle
, FileName
, 0, FileHandle
);
561 if (Status
== EFI_NOT_FOUND
) {
571 Get information about the file by name.
573 @param FileHandle Handle of the file.
575 @param FileInfo Upon exit, points to the file's
578 @retval EFI_SUCCESS File information returned.
580 @retval EFI_INVALID_PARAMETER If FileHandle does not
581 represent a valid file.
583 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
589 IN EFI_PEI_FILE_HANDLE FileHandle
,
590 OUT EFI_FV_FILE_INFO
*FileInfo
595 EFI_FFS_FILE_HEADER
*FileHeader
;
596 EFI_PEI_FV_HANDLE VolumeHandle
;
598 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
599 return EFI_INVALID_PARAMETER
;
604 // Retrieve the FirmwareVolume which the file resides in.
606 if (!FileHandleToVolume(FileHandle
, &VolumeHandle
)) {
607 return EFI_INVALID_PARAMETER
;
610 if (((EFI_FIRMWARE_VOLUME_HEADER
*)VolumeHandle
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
617 // Get FileState which is the highest bit of the State
619 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
622 case EFI_FILE_DATA_VALID
:
623 case EFI_FILE_MARKED_FOR_UPDATE
:
626 return EFI_INVALID_PARAMETER
;
629 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
630 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
631 FileInfo
->FileType
= FileHeader
->Type
;
632 FileInfo
->FileAttributes
= FileHeader
->Attributes
;
633 FileInfo
->BufferSize
= ((*(UINT32
*)FileHeader
->Size
) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER
);
634 FileInfo
->Buffer
= (FileHeader
+ 1);
640 Get Information about the volume by name
642 @param VolumeHandle Handle of the volume.
644 @param VolumeInfo Upon exit, points to the volume's
647 @retval EFI_SUCCESS File information returned.
649 @retval EFI_INVALID_PARAMETER If FileHandle does not
650 represent a valid file.
652 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
658 IN EFI_PEI_FV_HANDLE VolumeHandle
,
659 OUT EFI_FV_INFO
*VolumeInfo
662 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
663 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
665 if (VolumeInfo
== NULL
) {
666 return EFI_INVALID_PARAMETER
;
670 // VolumeHandle may not align at 8 byte,
671 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
672 // So, Copy FvHeader into the local FvHeader structure.
674 CopyMem (&FwVolHeader
, VolumeHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
676 // Check Fv Image Signature
678 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
679 return EFI_INVALID_PARAMETER
;
681 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
682 VolumeInfo
->FvStart
= (VOID
*) VolumeHandle
;
683 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
684 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
686 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
687 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)VolumeHandle
) + FwVolHeader
.ExtHeaderOffset
);
688 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));
696 Search through every FV until you find a file of type FileType
698 @param FileType File handle of a Fv type file.
699 @param Volumehandle On succes Volume Handle of the match
700 @param FileHandle On success File Handle of the match
702 @retval EFI_NOT_FOUND FV image can't be found.
703 @retval EFI_SUCCESS Successfully found FileType
708 FfsAnyFvFindFirstFile (
709 IN EFI_FV_FILETYPE FileType
,
710 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
,
711 OUT EFI_PEI_FILE_HANDLE
*FileHandle
718 // Search every FV for the DXE Core
725 Status
= FfsFindNextVolume (Instance
++, VolumeHandle
);
726 if (EFI_ERROR (Status
))
731 Status
= FfsFindNextFile (FileType
, *VolumeHandle
, FileHandle
);
732 if (!EFI_ERROR (Status
))
744 Get Fv image from the FV type file, then add FV & FV2 Hob.
746 @param FileHandle File handle of a Fv type file.
749 @retval EFI_NOT_FOUND FV image can't be found.
750 @retval EFI_SUCCESS Successfully to process it.
756 IN EFI_PEI_FILE_HANDLE FvFileHandle
760 EFI_PEI_FV_HANDLE FvImageHandle
;
761 EFI_FV_INFO FvImageInfo
;
764 EFI_PEI_HOB_POINTERS HobFv2
;
770 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
773 HobFv2
.Raw
= GetHobList ();
774 while ((HobFv2
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobFv2
.Raw
)) != NULL
) {
775 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
), &HobFv2
.FirmwareVolume2
->FileName
)) {
777 // this FILE has been dispatched, it will not be dispatched again.
781 HobFv2
.Raw
= GET_NEXT_HOB (HobFv2
);
785 // Find FvImage in FvFile
787 Status
= FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE
, FvFileHandle
, (VOID
**)&FvImageHandle
);
788 if (EFI_ERROR (Status
)) {
793 // Collect FvImage Info.
795 ZeroMem (&FvImageInfo
, sizeof (FvImageInfo
));
796 Status
= FfsGetVolumeInfo (FvImageHandle
, &FvImageInfo
);
797 ASSERT_EFI_ERROR (Status
);
800 // FvAlignment must be more than 8 bytes required by FvHeader structure.
802 FvAlignment
= 1 << ((FvImageInfo
.FvAttributes
& EFI_FVB2_ALIGNMENT
) >> 16);
803 if (FvAlignment
< 8) {
810 if ((UINTN
) FvImageInfo
.FvStart
% FvAlignment
!= 0) {
811 FvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvImageInfo
.FvSize
), FvAlignment
);
812 if (FvBuffer
== NULL
) {
813 return EFI_OUT_OF_RESOURCES
;
815 CopyMem (FvBuffer
, FvImageInfo
.FvStart
, (UINTN
) FvImageInfo
.FvSize
);
817 // Update FvImageInfo after reload FvImage to new aligned memory
819 FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE
) FvBuffer
, &FvImageInfo
);
824 // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
826 BuildFvHob ((EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
, FvImageInfo
.FvSize
);
829 // Makes the encapsulated volume show up in DXE phase to skip processing of
830 // encapsulated file again.
833 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
836 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)