2 Pei Core Firmware File System service routines.
4 Copyright (c) 2006 - 2007, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 STATIC EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList
= {
26 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
27 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
28 FirmwareVolmeInfoPpiNotifyCallback
32 #define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
33 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
36 Returns the highest bit set of the State field
39 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
40 in the Attributes field.
41 @param FfsHeader Pointer to FFS File Header.
43 @return Returns the highest bit in the State field
48 IN UINT8 ErasePolarity
,
49 IN EFI_FFS_FILE_HEADER
*FfsHeader
52 EFI_FFS_FILE_STATE FileState
;
53 EFI_FFS_FILE_STATE HighestBit
;
55 FileState
= FfsHeader
->State
;
57 if (ErasePolarity
!= 0) {
58 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
62 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
70 Calculates the checksum of the header of a file.
72 @param FileHeader Pointer to FFS File Header.
74 @return Checksum of the header.
75 The header is zero byte checksum.
76 Zero means the header is good.
77 Non-zero means the header is bad.
80 CalculateHeaderChecksum (
81 IN EFI_FFS_FILE_HEADER
*FileHeader
89 Ptr
= (UINT8
*)FileHeader
;
91 for (Index
= 0; Index
< sizeof(EFI_FFS_FILE_HEADER
) - 3; Index
+= 4) {
92 Sum
= (UINT8
)(Sum
+ Ptr
[Index
]);
93 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+1]);
94 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+2]);
95 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+3]);
98 for (; Index
< sizeof(EFI_FFS_FILE_HEADER
); Index
++) {
99 Sum
= (UINT8
)(Sum
+ Ptr
[Index
]);
103 // State field (since this indicates the different state of file).
105 Sum
= (UINT8
)(Sum
- FileHeader
->State
);
107 // Checksum field of the file is not part of the header checksum.
109 Sum
= (UINT8
)(Sum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
115 Find FV handler according some FileHandle in that FV.
117 @param FileHandle Handle of file image
118 @param VolumeHandle Handle of FV
120 @return EDES_TODO: Add description for return value
125 PeiFileHandleToVolume (
126 IN EFI_PEI_FILE_HANDLE FileHandle
,
127 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
131 PEI_CORE_INSTANCE
*PrivateData
;
132 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
134 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
135 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
136 FwVolHeader
= PrivateData
->Fv
[Index
].FvHeader
;
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
;
147 Given the input file pointer, search for the next matching file in the
148 FFS volume as defined by SearchType. The search starts from FileHeader inside
149 the Firmware Volume defined by FwVolHeader.
152 @param FvHandle Pointer to the FV header of the volume to search
153 @param FileName File name
154 @param SearchType Filter to find only files of this type.
155 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
156 @param FileHandle This parameter must point to a valid FFS volume.
157 @param AprioriFile Pointer to AprioriFile image in this FV if has
159 @return EFI_NOT_FOUND No files matching the search criteria were found
160 @retval EFI_SUCCESS Success to search given file
165 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
166 IN CONST EFI_GUID
*FileName
, OPTIONAL
167 IN EFI_FV_FILETYPE SearchType
,
168 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
,
169 IN OUT EFI_PEI_FV_HANDLE
*AprioriFile OPTIONAL
172 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
173 EFI_FFS_FILE_HEADER
**FileHeader
;
174 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
175 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
177 UINT32 FileOccupiedSize
;
183 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FvHandle
;
184 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
186 FvLength
= FwVolHeader
->FvLength
;
187 if (FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
194 // If FileHeader is not specified (NULL) or FileName is not NULL,
195 // start with the first file in the firmware volume. Otherwise,
196 // start from the FileHeader.
198 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
199 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
200 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
201 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FwVolHeader
) + FwVolHeader
->ExtHeaderOffset
);
202 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(((UINT8
*)FwVolExHeaderInfo
) + FwVolExHeaderInfo
->ExtHeaderSize
);
206 // Length is 24 bits wide so mask upper 8 bits
207 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
209 FileLength
= *(UINT32
*)(*FileHeader
)->Size
& 0x00FFFFFF;
210 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
211 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
214 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
215 ASSERT (FileOffset
<= 0xFFFFFFFF);
217 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
219 // Get FileState which is the highest bit of the State
221 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
224 case EFI_FILE_HEADER_INVALID
:
225 FileOffset
+= sizeof(EFI_FFS_FILE_HEADER
);
226 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
229 case EFI_FILE_DATA_VALID
:
230 case EFI_FILE_MARKED_FOR_UPDATE
:
231 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
234 return EFI_NOT_FOUND
;
237 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
238 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
240 if (FileName
!= NULL
) {
241 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
242 *FileHeader
= FfsFileHeader
;
245 } else if (SearchType
== PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
) {
246 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
247 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
) ||
248 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
)) {
250 *FileHeader
= FfsFileHeader
;
252 } else if (AprioriFile
!= NULL
) {
253 if (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FREEFORM
) {
254 if (CompareGuid (&FfsFileHeader
->Name
, &gPeiAprioriFileNameGuid
)) {
255 *AprioriFile
= FfsFileHeader
;
259 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
260 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
261 *FileHeader
= FfsFileHeader
;
265 FileOffset
+= FileOccupiedSize
;
266 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
269 case EFI_FILE_DELETED
:
270 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
271 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
272 FileOffset
+= FileOccupiedSize
;
273 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
278 return EFI_NOT_FOUND
;
283 return EFI_NOT_FOUND
;
288 Initialize PeiCore Fv List.
291 @param PrivateData - Pointer to PEI_CORE_INSTANCE.
292 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
299 IN PEI_CORE_INSTANCE
*PrivateData
,
300 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
305 // The BFV must be the first entry. The Core FV support is stateless
306 // The AllFV list has a single entry per FV in PEI.
307 // The Fv list only includes FV that PEIMs will be dispatched from and
308 // its File System Format is PI 1.0 definition.
310 PrivateData
->FvCount
= 1;
311 PrivateData
->Fv
[0].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
313 PrivateData
->AllFvCount
= 1;
314 PrivateData
->AllFv
[0] = (EFI_PEI_FV_HANDLE
)PrivateData
->Fv
[0].FvHeader
;
318 // Post a call-back for the FvInfoPPI services to expose
319 // additional Fvs to PeiCore.
321 Status
= PeiServicesNotifyPpi (&mNotifyOnFvInfoList
);
322 ASSERT_EFI_ERROR (Status
);
327 Process Firmware Volum Information once FvInfoPPI install.
330 @param PeiServices - General purpose services available to every PEIM.
331 @param NotifyDescriptor EDES_TODO: Add parameter description
332 @param Ppi EDES_TODO: Add parameter description
334 @retval EFI_SUCCESS if the interface could be successfully installed
339 FirmwareVolmeInfoPpiNotifyCallback (
340 IN EFI_PEI_SERVICES
**PeiServices
,
341 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
346 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
347 PEI_CORE_INSTANCE
*PrivateData
;
348 EFI_PEI_FILE_HANDLE FileHandle
;
350 UINT32 AuthenticationStatus
;
355 Status
= EFI_SUCCESS
;
356 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
358 if (PrivateData
->FvCount
>= FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
362 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*)Ppi
;
364 if (CompareGuid (&Fv
->FvFormat
, &gEfiFirmwareFileSystem2Guid
)) {
365 for (FvCount
= 0; FvCount
< PrivateData
->FvCount
; FvCount
++) {
366 if ((UINTN
)PrivateData
->Fv
[FvCount
].FvHeader
== (UINTN
)Fv
->FvInfo
) {
370 PrivateData
->Fv
[PrivateData
->FvCount
++].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
->FvInfo
;
373 // Only add FileSystem2 Fv to the All list
375 PrivateData
->AllFv
[PrivateData
->AllFvCount
++] = (EFI_PEI_FV_HANDLE
)Fv
->FvInfo
;
377 DEBUG ((EFI_D_INFO
, "The %dth FvImage start address is 0x%10p and size is 0x%08x\n", PrivateData
->AllFvCount
, (VOID
*) Fv
->FvInfo
, Fv
->FvInfoSize
));
379 // Preprocess all FV type files in this new FileSystem2 Fv image
382 Status
= PeiFindFileEx (
383 (EFI_PEI_FV_HANDLE
)Fv
->FvInfo
,
385 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
389 if (!EFI_ERROR (Status
)) {
390 Status
= PeiFfsFindSectionData (
391 (CONST EFI_PEI_SERVICES
**) PeiServices
,
392 EFI_SECTION_PEI_DEPEX
,
396 if (!EFI_ERROR (Status
)) {
397 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
399 // Dependency is not satisfied.
405 // Process FvFile to install FvInfo ppi and build FvHob
407 ProcessFvFile (PeiServices
, FileHandle
, &AuthenticationStatus
);
409 } while (FileHandle
!= NULL
);
417 Go through the file to search SectionType section,
418 when meeting an encapsuled section.
421 @param PeiServices - General purpose services available to every PEIM.
422 SearchType - Filter to find only section of this type.
423 @param SectionType EDES_TODO: Add parameter description
424 @param Section - From where to search.
425 @param SectionSize - The file size to search.
426 @param OutputBuffer - Pointer to the section to search.
432 PeiFfsProcessSection (
433 IN CONST EFI_PEI_SERVICES
**PeiServices
,
434 IN EFI_SECTION_TYPE SectionType
,
435 IN EFI_COMMON_SECTION_HEADER
*Section
,
436 IN UINTN SectionSize
,
437 OUT VOID
**OutputBuffer
441 UINT32 SectionLength
;
443 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
444 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
448 UINT32 Authentication
;
449 PEI_CORE_INSTANCE
*PrivateData
;
451 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
452 *OutputBuffer
= NULL
;
455 Status
= EFI_NOT_FOUND
;
458 while (ParsedLength
< SectionSize
) {
459 if (Section
->Type
== SectionType
) {
460 *OutputBuffer
= (VOID
*)(Section
+ 1);
462 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
464 // Check the encapsulated section is extracted into the cache data.
466 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
467 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
468 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
469 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
471 // Search section directly from the cache data.
473 return PeiFfsProcessSection (
483 Status
= EFI_NOT_FOUND
;
484 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
485 Status
= PeiServicesLocatePpi (
486 &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
,
489 (VOID
**) &GuidSectionPpi
491 if (!EFI_ERROR (Status
)) {
492 Status
= GuidSectionPpi
->ExtractSection (
500 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
501 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**) &DecompressPpi
);
502 if (!EFI_ERROR (Status
)) {
503 Status
= DecompressPpi
->Decompress (
505 (CONST EFI_COMPRESSION_SECTION
*) Section
,
512 if (!EFI_ERROR (Status
)) {
514 // Update cache section data.
516 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
517 PrivateData
->CacheSection
.AllSectionCount
++;
519 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
520 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
521 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
522 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
524 return PeiFfsProcessSection (
535 // Size is 24 bits wide so mask upper 8 bits.
536 // SectionLength is adjusted it is 4 byte aligned.
537 // Go to the next section
539 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
540 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
541 ASSERT (SectionLength
!= 0);
542 ParsedLength
+= SectionLength
;
543 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
546 return EFI_NOT_FOUND
;
551 Given the input file pointer, search for the next matching section in the
555 @param PeiServices Pointer to the PEI Core Services Table.
556 @param SectionType Filter to find only sections of this type.
557 @param FileHandle Pointer to the current file to search.
558 @param SectionData Pointer to the Section matching SectionType in FfsFileHeader.
559 NULL if section not found
561 @retval EFI_NOT_FOUND No files matching the search criteria were found
562 @retval EFI_SUCCESS Success to find section data in given file
567 PeiFfsFindSectionData (
568 IN CONST EFI_PEI_SERVICES
**PeiServices
,
569 IN EFI_SECTION_TYPE SectionType
,
570 IN EFI_PEI_FILE_HANDLE FileHandle
,
571 IN OUT VOID
**SectionData
574 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
576 EFI_COMMON_SECTION_HEADER
*Section
;
578 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
581 // Size is 24 bits wide so mask upper 8 bits.
582 // Does not include FfsFileHeader header size
583 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
585 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
586 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
587 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
589 return PeiFfsProcessSection (
599 Given the input file pointer, search for the next matching file in the
600 FFS volume as defined by SearchType. The search starts from FileHeader inside
601 the Firmware Volume defined by FwVolHeader.
604 @param PeiServices Pointer to the PEI Core Services Table.
605 @param SearchType Filter to find only files of this type.
606 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
607 @param VolumeHandle Pointer to the FV header of the volume to search.
608 @param FileHandle Pointer to the current file from which to begin searching.
609 This pointer will be updated upon return to reflect the file found.
610 @retval EFI_NOT_FOUND No files matching the search criteria were found
611 @retval EFI_SUCCESS Success to find next file in given volume
617 IN CONST EFI_PEI_SERVICES
**PeiServices
,
619 IN EFI_PEI_FV_HANDLE VolumeHandle
,
620 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
623 return PeiFindFileEx (VolumeHandle
, NULL
, SearchType
, FileHandle
, NULL
);
628 search the firmware volumes by index
630 @param PeiServices The PEI core services table.
631 @param Instance Instance of FV to find
632 @param VolumeHandle Pointer to found Volume.
634 @retval EFI_INVALID_PARAMETER FwVolHeader is NULL
635 @retval EFI_SUCCESS Firmware volume instance successfully found.
640 PeiFvFindNextVolume (
641 IN CONST EFI_PEI_SERVICES
**PeiServices
,
643 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
646 PEI_CORE_INSTANCE
*Private
;
648 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
649 if (VolumeHandle
== NULL
) {
650 return EFI_INVALID_PARAMETER
;
653 if (Instance
>= Private
->AllFvCount
) {
655 return EFI_NOT_FOUND
;
658 *VolumeHandle
= Private
->AllFv
[Instance
];
665 Given the input VolumeHandle, search for the next matching name file.
668 @param FileName - File name to search.
669 @param VolumeHandle - The current FV to search.
670 @param FileHandle - Pointer to the file matching name in VolumeHandle.
671 - NULL if file not found
678 PeiFfsFindFileByName (
679 IN CONST EFI_GUID
*FileName
,
680 IN EFI_PEI_FV_HANDLE VolumeHandle
,
681 OUT EFI_PEI_FILE_HANDLE
*FileHandle
685 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
686 return EFI_INVALID_PARAMETER
;
688 Status
= PeiFindFileEx (VolumeHandle
, FileName
, 0, FileHandle
, NULL
);
689 if (Status
== EFI_NOT_FOUND
) {
697 Returns information about a specific file.
700 @param FileHandle - The handle to file.
701 @param FileInfo - Pointer to the file information.
703 @retval EFI_INVALID_PARAMETER Invalid FileHandle or FileInfo.
704 @retval EFI_SUCCESS Success to collect file info.
710 IN EFI_PEI_FILE_HANDLE FileHandle
,
711 OUT EFI_FV_FILE_INFO
*FileInfo
716 EFI_FFS_FILE_HEADER
*FileHeader
;
717 EFI_PEI_FV_HANDLE VolumeHandle
;
719 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
720 return EFI_INVALID_PARAMETER
;
725 // Retrieve the FirmwareVolume which the file resides in.
727 if (!PeiFileHandleToVolume(FileHandle
, &VolumeHandle
)) {
728 return EFI_INVALID_PARAMETER
;
731 if (((EFI_FIRMWARE_VOLUME_HEADER
*)VolumeHandle
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
738 // Get FileState which is the highest bit of the State
740 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
743 case EFI_FILE_DATA_VALID
:
744 case EFI_FILE_MARKED_FOR_UPDATE
:
747 return EFI_INVALID_PARAMETER
;
750 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
751 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
752 FileInfo
->FileType
= FileHeader
->Type
;
753 FileInfo
->FileAttributes
= FileHeader
->Attributes
;
754 FileInfo
->BufferSize
= ((*(UINT32
*)FileHeader
->Size
) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER
);
755 FileInfo
->Buffer
= (FileHeader
+ 1);
762 Collect information of given Fv Volume.
764 @param VolumeHandle - The handle to Fv Volume.
765 @param VolumeInfo - The pointer to volume information.
767 @retval EFI_INVALID_PARAMETER VolumeInfo is NULL
768 @retval EFI_SUCCESS Success to collect fv info.
772 PeiFfsGetVolumeInfo (
773 IN EFI_PEI_FV_HANDLE VolumeHandle
,
774 OUT EFI_FV_INFO
*VolumeInfo
777 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
778 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
780 if (VolumeInfo
== NULL
) {
781 return EFI_INVALID_PARAMETER
;
785 // VolumeHandle may not align at 8 byte,
786 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
787 // So, Copy FvHeader into the local FvHeader structure.
789 CopyMem (&FwVolHeader
, VolumeHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
791 // Check Fv Image Signature
793 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
794 return EFI_INVALID_PARAMETER
;
796 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
797 VolumeInfo
->FvStart
= (VOID
*) VolumeHandle
;
798 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
799 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
801 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
802 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)VolumeHandle
) + FwVolHeader
.ExtHeaderOffset
);
803 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));