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.
17 STATIC EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList
= {
18 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
19 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
20 FirmwareVolmeInfoPpiNotifyCallback
24 #define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
25 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
28 Returns the highest bit set of the State field
30 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
31 in the Attributes field.
32 @param FfsHeader Pointer to FFS File Header.
34 @return Returns the highest bit in the State field
39 IN UINT8 ErasePolarity
,
40 IN EFI_FFS_FILE_HEADER
*FfsHeader
43 EFI_FFS_FILE_STATE FileState
;
44 EFI_FFS_FILE_STATE HighestBit
;
46 FileState
= FfsHeader
->State
;
48 if (ErasePolarity
!= 0) {
49 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
53 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
61 Calculates the checksum of the header of a file.
63 @param FileHeader Pointer to FFS File Header.
65 @return Checksum of the header.
66 The header is zero byte checksum.
67 Zero means the header is good.
68 Non-zero means the header is bad.
71 CalculateHeaderChecksum (
72 IN EFI_FFS_FILE_HEADER
*FileHeader
80 Ptr
= (UINT8
*)FileHeader
;
82 for (Index
= 0; Index
< sizeof(EFI_FFS_FILE_HEADER
) - 3; Index
+= 4) {
83 Sum
= (UINT8
)(Sum
+ Ptr
[Index
]);
84 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+1]);
85 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+2]);
86 Sum
= (UINT8
)(Sum
+ Ptr
[Index
+3]);
89 for (; Index
< sizeof(EFI_FFS_FILE_HEADER
); Index
++) {
90 Sum
= (UINT8
)(Sum
+ Ptr
[Index
]);
94 // State field (since this indicates the different state of file).
96 Sum
= (UINT8
)(Sum
- FileHeader
->State
);
98 // Checksum field of the file is not part of the header checksum.
100 Sum
= (UINT8
)(Sum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
106 Find FV handler according some FileHandle in that FV.
108 @param FileHandle Handle of file image
109 @param VolumeHandle Handle of FV
111 @return EDES_TODO: Add description for return value
116 PeiFileHandleToVolume (
117 IN EFI_PEI_FILE_HANDLE FileHandle
,
118 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
122 PEI_CORE_INSTANCE
*PrivateData
;
123 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
125 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
126 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
127 FwVolHeader
= PrivateData
->Fv
[Index
].FvHeader
;
128 if (((UINT64
) (UINTN
) FileHandle
> (UINT64
) (UINTN
) FwVolHeader
) && \
129 ((UINT64
) (UINTN
) FileHandle
<= ((UINT64
) (UINTN
) FwVolHeader
+ FwVolHeader
->FvLength
- 1))) {
130 *VolumeHandle
= (EFI_PEI_FV_HANDLE
)FwVolHeader
;
138 Given the input file pointer, search for the next matching file in the
139 FFS volume as defined by SearchType. The search starts from FileHeader inside
140 the Firmware Volume defined by FwVolHeader.
143 @param FvHandle Pointer to the FV header of the volume to search
144 @param FileName File name
145 @param SearchType Filter to find only files of this type.
146 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
147 Type PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE is an FFS type
148 extension used for PeiFindFileEx. It indicates current
149 Ffs searching is for all PEIMs can be dispatched by PeiCore.
150 @param FileHandle This parameter must point to a valid FFS volume.
151 @param AprioriFile Pointer to AprioriFile image in this FV if has
153 @return EFI_NOT_FOUND No files matching the search criteria were found
154 @retval EFI_SUCCESS Success to search given file
159 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
160 IN CONST EFI_GUID
*FileName
, OPTIONAL
161 IN EFI_FV_FILETYPE SearchType
,
162 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
,
163 IN OUT EFI_PEI_FV_HANDLE
*AprioriFile OPTIONAL
166 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
167 EFI_FFS_FILE_HEADER
**FileHeader
;
168 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
169 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
171 UINT32 FileOccupiedSize
;
177 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FvHandle
;
178 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
180 FvLength
= FwVolHeader
->FvLength
;
181 if (FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
188 // If FileHeader is not specified (NULL) or FileName is not NULL,
189 // start with the first file in the firmware volume. Otherwise,
190 // start from the FileHeader.
192 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
193 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
194 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
195 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FwVolHeader
) + FwVolHeader
->ExtHeaderOffset
);
196 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(((UINT8
*)FwVolExHeaderInfo
) + FwVolExHeaderInfo
->ExtHeaderSize
);
200 // Length is 24 bits wide so mask upper 8 bits
201 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
203 FileLength
= *(UINT32
*)(*FileHeader
)->Size
& 0x00FFFFFF;
204 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
205 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
208 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
209 ASSERT (FileOffset
<= 0xFFFFFFFF);
211 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
213 // Get FileState which is the highest bit of the State
215 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
218 case EFI_FILE_HEADER_INVALID
:
219 FileOffset
+= sizeof(EFI_FFS_FILE_HEADER
);
220 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
223 case EFI_FILE_DATA_VALID
:
224 case EFI_FILE_MARKED_FOR_UPDATE
:
225 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
228 return EFI_NOT_FOUND
;
231 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
232 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
234 if (FileName
!= NULL
) {
235 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
236 *FileHeader
= FfsFileHeader
;
239 } else if (SearchType
== PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
) {
240 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
241 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
) ||
242 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
)) {
244 *FileHeader
= FfsFileHeader
;
246 } else if (AprioriFile
!= NULL
) {
247 if (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FREEFORM
) {
248 if (CompareGuid (&FfsFileHeader
->Name
, &gPeiAprioriFileNameGuid
)) {
249 *AprioriFile
= FfsFileHeader
;
253 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
254 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
255 *FileHeader
= FfsFileHeader
;
259 FileOffset
+= FileOccupiedSize
;
260 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
263 case EFI_FILE_DELETED
:
264 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
265 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
266 FileOffset
+= FileOccupiedSize
;
267 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
272 return EFI_NOT_FOUND
;
277 return EFI_NOT_FOUND
;
281 Initialize PeiCore Fv List.
283 @param PrivateData - Pointer to PEI_CORE_INSTANCE.
284 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
288 IN PEI_CORE_INSTANCE
*PrivateData
,
289 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
294 // The BFV must be the first entry. The Core FV support is stateless
295 // The AllFV list has a single entry per FV in PEI.
296 // The Fv list only includes FV that PEIMs will be dispatched from and
297 // its File System Format is PI 1.0 definition.
299 PrivateData
->FvCount
= 1;
300 PrivateData
->Fv
[0].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
302 PrivateData
->AllFvCount
= 1;
303 PrivateData
->AllFv
[0] = (EFI_PEI_FV_HANDLE
)PrivateData
->Fv
[0].FvHeader
;
307 // Post a call-back for the FvInfoPPI services to expose
308 // additional Fvs to PeiCore.
310 Status
= PeiServicesNotifyPpi (&mNotifyOnFvInfoList
);
311 ASSERT_EFI_ERROR (Status
);
316 Process Firmware Volum Information once FvInfoPPI install.
319 @param PeiServices - General purpose services available to every PEIM.
320 @param NotifyDescriptor EDES_TODO: Add parameter description
321 @param Ppi EDES_TODO: Add parameter description
323 @retval EFI_SUCCESS if the interface could be successfully installed
328 FirmwareVolmeInfoPpiNotifyCallback (
329 IN EFI_PEI_SERVICES
**PeiServices
,
330 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
335 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
336 PEI_CORE_INSTANCE
*PrivateData
;
337 EFI_PEI_FILE_HANDLE FileHandle
;
339 UINT32 AuthenticationStatus
;
344 Status
= EFI_SUCCESS
;
345 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
347 if (PrivateData
->FvCount
>= FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
351 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*)Ppi
;
353 if (CompareGuid (&Fv
->FvFormat
, &gEfiFirmwareFileSystem2Guid
)) {
354 for (FvCount
= 0; FvCount
< PrivateData
->FvCount
; FvCount
++) {
355 if ((UINTN
)PrivateData
->Fv
[FvCount
].FvHeader
== (UINTN
)Fv
->FvInfo
) {
359 PrivateData
->Fv
[PrivateData
->FvCount
++].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
->FvInfo
;
362 // Only add FileSystem2 Fv to the All list
364 PrivateData
->AllFv
[PrivateData
->AllFvCount
++] = (EFI_PEI_FV_HANDLE
)Fv
->FvInfo
;
366 DEBUG ((EFI_D_INFO
, "The %dth FvImage start address is 0x%11p and size is 0x%08x\n", PrivateData
->AllFvCount
, (VOID
*) Fv
->FvInfo
, Fv
->FvInfoSize
));
368 // Preprocess all FV type files in this new FileSystem2 Fv image
371 Status
= PeiFindFileEx (
372 (EFI_PEI_FV_HANDLE
)Fv
->FvInfo
,
374 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
378 if (!EFI_ERROR (Status
)) {
379 Status
= PeiFfsFindSectionData (
380 (CONST EFI_PEI_SERVICES
**) PeiServices
,
381 EFI_SECTION_PEI_DEPEX
,
385 if (!EFI_ERROR (Status
)) {
386 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
388 // Dependency is not satisfied.
394 // Process FvFile to install FvInfo ppi and build FvHob
396 ProcessFvFile (PeiServices
, FileHandle
, &AuthenticationStatus
);
398 } while (FileHandle
!= NULL
);
406 Go through the file to search SectionType section,
407 when meeting an encapsuled section.
410 @param PeiServices - General purpose services available to every PEIM.
411 SearchType - Filter to find only section of this type.
412 @param SectionType EDES_TODO: Add parameter description
413 @param Section - From where to search.
414 @param SectionSize - The file size to search.
415 @param OutputBuffer - Pointer to the section to search.
421 PeiFfsProcessSection (
422 IN CONST EFI_PEI_SERVICES
**PeiServices
,
423 IN EFI_SECTION_TYPE SectionType
,
424 IN EFI_COMMON_SECTION_HEADER
*Section
,
425 IN UINTN SectionSize
,
426 OUT VOID
**OutputBuffer
430 UINT32 SectionLength
;
432 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
433 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
437 UINT32 Authentication
;
438 PEI_CORE_INSTANCE
*PrivateData
;
440 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
441 *OutputBuffer
= NULL
;
444 Status
= EFI_NOT_FOUND
;
447 while (ParsedLength
< SectionSize
) {
448 if (Section
->Type
== SectionType
) {
449 *OutputBuffer
= (VOID
*)(Section
+ 1);
451 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
453 // Check the encapsulated section is extracted into the cache data.
455 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
456 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
457 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
458 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
460 // Search section directly from the cache data.
462 return PeiFfsProcessSection (
472 Status
= EFI_NOT_FOUND
;
473 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
474 Status
= PeiServicesLocatePpi (
475 &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
,
478 (VOID
**) &GuidSectionPpi
480 if (!EFI_ERROR (Status
)) {
481 Status
= GuidSectionPpi
->ExtractSection (
489 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
490 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**) &DecompressPpi
);
491 if (!EFI_ERROR (Status
)) {
492 Status
= DecompressPpi
->Decompress (
494 (CONST EFI_COMPRESSION_SECTION
*) Section
,
501 if (!EFI_ERROR (Status
)) {
503 // Update cache section data.
505 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
506 PrivateData
->CacheSection
.AllSectionCount
++;
508 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
509 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
510 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
511 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
513 return PeiFfsProcessSection (
524 // Size is 24 bits wide so mask upper 8 bits.
525 // SectionLength is adjusted it is 4 byte aligned.
526 // Go to the next section
528 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
529 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
530 ASSERT (SectionLength
!= 0);
531 ParsedLength
+= SectionLength
;
532 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
535 return EFI_NOT_FOUND
;
540 Given the input file pointer, search for the next matching section in the
544 @param PeiServices Pointer to the PEI Core Services Table.
545 @param SectionType Filter to find only sections of this type.
546 @param FileHandle Pointer to the current file to search.
547 @param SectionData Pointer to the Section matching SectionType in FfsFileHeader.
548 NULL if section not found
550 @retval EFI_NOT_FOUND No files matching the search criteria were found
551 @retval EFI_SUCCESS Success to find section data in given file
556 PeiFfsFindSectionData (
557 IN CONST EFI_PEI_SERVICES
**PeiServices
,
558 IN EFI_SECTION_TYPE SectionType
,
559 IN EFI_PEI_FILE_HANDLE FileHandle
,
560 IN OUT VOID
**SectionData
563 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
565 EFI_COMMON_SECTION_HEADER
*Section
;
567 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
570 // Size is 24 bits wide so mask upper 8 bits.
571 // Does not include FfsFileHeader header size
572 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
574 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
575 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
576 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
578 return PeiFfsProcessSection (
588 Given the input file pointer, search for the next matching file in the
589 FFS volume as defined by SearchType. The search starts from FileHeader inside
590 the Firmware Volume defined by FwVolHeader.
593 @param PeiServices Pointer to the PEI Core Services Table.
594 @param SearchType Filter to find only files of this type.
595 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
596 @param VolumeHandle Pointer to the FV header of the volume to search.
597 @param FileHandle Pointer to the current file from which to begin searching.
598 This pointer will be updated upon return to reflect the file found.
599 @retval EFI_NOT_FOUND No files matching the search criteria were found
600 @retval EFI_SUCCESS Success to find next file in given volume
606 IN CONST EFI_PEI_SERVICES
**PeiServices
,
608 IN EFI_PEI_FV_HANDLE VolumeHandle
,
609 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
612 return PeiFindFileEx (VolumeHandle
, NULL
, SearchType
, FileHandle
, NULL
);
617 search the firmware volumes by index
619 @param PeiServices The PEI core services table.
620 @param Instance Instance of FV to find
621 @param VolumeHandle Pointer to found Volume.
623 @retval EFI_INVALID_PARAMETER FwVolHeader is NULL
624 @retval EFI_SUCCESS Firmware volume instance successfully found.
629 PeiFvFindNextVolume (
630 IN CONST EFI_PEI_SERVICES
**PeiServices
,
632 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
635 PEI_CORE_INSTANCE
*Private
;
637 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
638 if (VolumeHandle
== NULL
) {
639 return EFI_INVALID_PARAMETER
;
642 if (Instance
>= Private
->AllFvCount
) {
644 return EFI_NOT_FOUND
;
647 *VolumeHandle
= Private
->AllFv
[Instance
];
654 Given the input VolumeHandle, search for the next matching name file.
657 @param FileName File name to search.
658 @param VolumeHandle The current FV to search.
659 @param FileHandle Pointer to the file matching name in VolumeHandle.
660 NULL if file not found
662 @retval EFI_NOT_FOUND No files matching the search criteria were found
663 @retval EFI_SUCCESS Success to search given file
667 PeiFfsFindFileByName (
668 IN CONST EFI_GUID
*FileName
,
669 IN EFI_PEI_FV_HANDLE VolumeHandle
,
670 OUT EFI_PEI_FILE_HANDLE
*FileHandle
674 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
675 return EFI_INVALID_PARAMETER
;
677 Status
= PeiFindFileEx (VolumeHandle
, FileName
, 0, FileHandle
, NULL
);
678 if (Status
== EFI_NOT_FOUND
) {
686 Returns information about a specific file.
689 @param FileHandle - The handle to file.
690 @param FileInfo - Pointer to the file information.
692 @retval EFI_INVALID_PARAMETER Invalid FileHandle or FileInfo.
693 @retval EFI_SUCCESS Success to collect file info.
699 IN EFI_PEI_FILE_HANDLE FileHandle
,
700 OUT EFI_FV_FILE_INFO
*FileInfo
705 EFI_FFS_FILE_HEADER
*FileHeader
;
706 EFI_PEI_FV_HANDLE VolumeHandle
;
708 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
709 return EFI_INVALID_PARAMETER
;
714 // Retrieve the FirmwareVolume which the file resides in.
716 if (!PeiFileHandleToVolume(FileHandle
, &VolumeHandle
)) {
717 return EFI_INVALID_PARAMETER
;
720 if (((EFI_FIRMWARE_VOLUME_HEADER
*)VolumeHandle
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
727 // Get FileState which is the highest bit of the State
729 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
732 case EFI_FILE_DATA_VALID
:
733 case EFI_FILE_MARKED_FOR_UPDATE
:
736 return EFI_INVALID_PARAMETER
;
739 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
740 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
741 FileInfo
->FileType
= FileHeader
->Type
;
742 FileInfo
->FileAttributes
= FileHeader
->Attributes
;
743 FileInfo
->BufferSize
= ((*(UINT32
*)FileHeader
->Size
) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER
);
744 FileInfo
->Buffer
= (FileHeader
+ 1);
751 Collect information of given Fv Volume.
753 @param VolumeHandle - The handle to Fv Volume.
754 @param VolumeInfo - The pointer to volume information.
756 @retval EFI_INVALID_PARAMETER VolumeInfo is NULL
757 @retval EFI_SUCCESS Success to collect fv info.
761 PeiFfsGetVolumeInfo (
762 IN EFI_PEI_FV_HANDLE VolumeHandle
,
763 OUT EFI_FV_INFO
*VolumeInfo
766 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
767 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
769 if (VolumeInfo
== NULL
) {
770 return EFI_INVALID_PARAMETER
;
774 // VolumeHandle may not align at 8 byte,
775 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
776 // So, Copy FvHeader into the local FvHeader structure.
778 CopyMem (&FwVolHeader
, VolumeHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
780 // Check Fv Image Signature
782 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
783 return EFI_INVALID_PARAMETER
;
785 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
786 VolumeInfo
->FvStart
= (VOID
*) VolumeHandle
;
787 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
788 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
790 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
791 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)VolumeHandle
) + FwVolHeader
.ExtHeaderOffset
);
792 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));