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 @retval TRUE Success to find FV and return FV handle that contains file by given
113 @retval FALSE Can not find the FV that contains file by given file name.
118 PeiFileHandleToVolume (
119 IN EFI_PEI_FILE_HANDLE FileHandle
,
120 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
124 PEI_CORE_INSTANCE
*PrivateData
;
125 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
127 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
128 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
129 FwVolHeader
= PrivateData
->Fv
[Index
].FvHeader
;
130 if (((UINT64
) (UINTN
) FileHandle
> (UINT64
) (UINTN
) FwVolHeader
) && \
131 ((UINT64
) (UINTN
) FileHandle
<= ((UINT64
) (UINTN
) FwVolHeader
+ FwVolHeader
->FvLength
- 1))) {
132 *VolumeHandle
= (EFI_PEI_FV_HANDLE
)FwVolHeader
;
140 Given the input file pointer, search for the next matching file in the
141 FFS volume as defined by SearchType. The search starts from FileHeader inside
142 the Firmware Volume defined by FwVolHeader.
145 @param FvHandle Pointer to the FV header of the volume to search
146 @param FileName File name
147 @param SearchType Filter to find only files of this type.
148 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
149 Type PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE is an FFS type
150 extension used for PeiFindFileEx. It indicates current
151 Ffs searching is for all PEIMs can be dispatched by PeiCore.
152 @param FileHandle This parameter must point to a valid FFS volume.
153 @param AprioriFile Pointer to AprioriFile image in this FV if has
155 @return EFI_NOT_FOUND No files matching the search criteria were found
156 @retval EFI_SUCCESS Success to search given file
161 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
162 IN CONST EFI_GUID
*FileName
, OPTIONAL
163 IN EFI_FV_FILETYPE SearchType
,
164 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
,
165 IN OUT EFI_PEI_FV_HANDLE
*AprioriFile OPTIONAL
168 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
169 EFI_FFS_FILE_HEADER
**FileHeader
;
170 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
171 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
173 UINT32 FileOccupiedSize
;
179 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FvHandle
;
180 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
182 FvLength
= FwVolHeader
->FvLength
;
183 if (FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
190 // If FileHeader is not specified (NULL) or FileName is not NULL,
191 // start with the first file in the firmware volume. Otherwise,
192 // start from the FileHeader.
194 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
195 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
196 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
197 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FwVolHeader
) + FwVolHeader
->ExtHeaderOffset
);
198 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(((UINT8
*)FwVolExHeaderInfo
) + FwVolExHeaderInfo
->ExtHeaderSize
);
202 // Length is 24 bits wide so mask upper 8 bits
203 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
205 FileLength
= *(UINT32
*)(*FileHeader
)->Size
& 0x00FFFFFF;
206 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
207 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
210 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
211 ASSERT (FileOffset
<= 0xFFFFFFFF);
213 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
215 // Get FileState which is the highest bit of the State
217 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
220 case EFI_FILE_HEADER_INVALID
:
221 FileOffset
+= sizeof(EFI_FFS_FILE_HEADER
);
222 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
225 case EFI_FILE_DATA_VALID
:
226 case EFI_FILE_MARKED_FOR_UPDATE
:
227 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
230 return EFI_NOT_FOUND
;
233 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
234 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
236 if (FileName
!= NULL
) {
237 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
238 *FileHeader
= FfsFileHeader
;
241 } else if (SearchType
== PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
) {
242 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
243 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
) ||
244 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
)) {
246 *FileHeader
= FfsFileHeader
;
248 } else if (AprioriFile
!= NULL
) {
249 if (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FREEFORM
) {
250 if (CompareGuid (&FfsFileHeader
->Name
, &gPeiAprioriFileNameGuid
)) {
251 *AprioriFile
= FfsFileHeader
;
255 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
256 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
257 *FileHeader
= FfsFileHeader
;
261 FileOffset
+= FileOccupiedSize
;
262 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
265 case EFI_FILE_DELETED
:
266 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
267 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
268 FileOffset
+= FileOccupiedSize
;
269 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
274 return EFI_NOT_FOUND
;
279 return EFI_NOT_FOUND
;
283 Initialize PeiCore Fv List.
285 @param PrivateData - Pointer to PEI_CORE_INSTANCE.
286 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
290 IN PEI_CORE_INSTANCE
*PrivateData
,
291 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
296 // The BFV must be the first entry. The Core FV support is stateless
297 // The AllFV list has a single entry per FV in PEI.
298 // The Fv list only includes FV that PEIMs will be dispatched from and
299 // its File System Format is PI 1.0 definition.
301 PrivateData
->FvCount
= 1;
302 PrivateData
->Fv
[0].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
304 PrivateData
->AllFvCount
= 1;
305 PrivateData
->AllFv
[0] = (EFI_PEI_FV_HANDLE
)PrivateData
->Fv
[0].FvHeader
;
309 // Post a call-back for the FvInfoPPI services to expose
310 // additional Fvs to PeiCore.
312 Status
= PeiServicesNotifyPpi (&mNotifyOnFvInfoList
);
313 ASSERT_EFI_ERROR (Status
);
318 Process Firmware Volum Information once FvInfoPPI install.
320 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
321 @param NotifyDescriptor Address of the notification descriptor data structure.
322 @param Ppi Address of the PPI that was installed.
324 @retval EFI_SUCCESS if the interface could be successfully installed
329 FirmwareVolmeInfoPpiNotifyCallback (
330 IN EFI_PEI_SERVICES
**PeiServices
,
331 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
336 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
337 PEI_CORE_INSTANCE
*PrivateData
;
338 EFI_PEI_FILE_HANDLE FileHandle
;
340 UINT32 AuthenticationStatus
;
345 Status
= EFI_SUCCESS
;
346 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
348 if (PrivateData
->FvCount
>= FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
352 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*)Ppi
;
354 if (CompareGuid (&Fv
->FvFormat
, &gEfiFirmwareFileSystem2Guid
)) {
355 for (FvCount
= 0; FvCount
< PrivateData
->FvCount
; FvCount
++) {
356 if ((UINTN
)PrivateData
->Fv
[FvCount
].FvHeader
== (UINTN
)Fv
->FvInfo
) {
360 PrivateData
->Fv
[PrivateData
->FvCount
++].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)Fv
->FvInfo
;
363 // Only add FileSystem2 Fv to the All list
365 PrivateData
->AllFv
[PrivateData
->AllFvCount
++] = (EFI_PEI_FV_HANDLE
)Fv
->FvInfo
;
367 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
));
369 // Preprocess all FV type files in this new FileSystem2 Fv image
372 Status
= PeiFindFileEx (
373 (EFI_PEI_FV_HANDLE
)Fv
->FvInfo
,
375 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
379 if (!EFI_ERROR (Status
)) {
380 Status
= PeiFfsFindSectionData (
381 (CONST EFI_PEI_SERVICES
**) PeiServices
,
382 EFI_SECTION_PEI_DEPEX
,
386 if (!EFI_ERROR (Status
)) {
387 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
389 // Dependency is not satisfied.
395 // Process FvFile to install FvInfo ppi and build FvHob
397 ProcessFvFile (PeiServices
, FileHandle
, &AuthenticationStatus
);
399 } while (FileHandle
!= NULL
);
407 Go through the file to search SectionType section,
408 when meeting an encapsuled section.
411 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
412 @param SectionType Filter to find only section of this type.
413 @param Section From where to search.
414 @param SectionSize The file size to search.
415 @param OutputBuffer Pointer to the section to search.
417 @retval EFI_NOT_FOUND Can not find the section by given section type.
418 @retval EFI_SUCCESS Success to find the section and process section correctly.
422 PeiFfsProcessSection (
423 IN CONST EFI_PEI_SERVICES
**PeiServices
,
424 IN EFI_SECTION_TYPE SectionType
,
425 IN EFI_COMMON_SECTION_HEADER
*Section
,
426 IN UINTN SectionSize
,
427 OUT VOID
**OutputBuffer
431 UINT32 SectionLength
;
433 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
434 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
438 UINT32 Authentication
;
439 PEI_CORE_INSTANCE
*PrivateData
;
441 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
442 *OutputBuffer
= NULL
;
445 Status
= EFI_NOT_FOUND
;
448 while (ParsedLength
< SectionSize
) {
449 if (Section
->Type
== SectionType
) {
450 *OutputBuffer
= (VOID
*)(Section
+ 1);
452 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
454 // Check the encapsulated section is extracted into the cache data.
456 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
457 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
458 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
459 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
461 // Search section directly from the cache data.
463 return PeiFfsProcessSection (
473 Status
= EFI_NOT_FOUND
;
474 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
475 Status
= PeiServicesLocatePpi (
476 &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
,
479 (VOID
**) &GuidSectionPpi
481 if (!EFI_ERROR (Status
)) {
482 Status
= GuidSectionPpi
->ExtractSection (
490 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
491 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**) &DecompressPpi
);
492 if (!EFI_ERROR (Status
)) {
493 Status
= DecompressPpi
->Decompress (
495 (CONST EFI_COMPRESSION_SECTION
*) Section
,
502 if (!EFI_ERROR (Status
)) {
504 // Update cache section data.
506 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
507 PrivateData
->CacheSection
.AllSectionCount
++;
509 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
510 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
511 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
512 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
514 return PeiFfsProcessSection (
525 // Size is 24 bits wide so mask upper 8 bits.
526 // SectionLength is adjusted it is 4 byte aligned.
527 // Go to the next section
529 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
530 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
531 ASSERT (SectionLength
!= 0);
532 ParsedLength
+= SectionLength
;
533 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
536 return EFI_NOT_FOUND
;
541 Given the input file pointer, search for the next matching section in the
545 @param PeiServices Pointer to the PEI Core Services Table.
546 @param SectionType Filter to find only sections of this type.
547 @param FileHandle Pointer to the current file to search.
548 @param SectionData Pointer to the Section matching SectionType in FfsFileHeader.
549 NULL if section not found
551 @retval EFI_NOT_FOUND No files matching the search criteria were found
552 @retval EFI_SUCCESS Success to find section data in given file
557 PeiFfsFindSectionData (
558 IN CONST EFI_PEI_SERVICES
**PeiServices
,
559 IN EFI_SECTION_TYPE SectionType
,
560 IN EFI_PEI_FILE_HANDLE FileHandle
,
561 IN OUT VOID
**SectionData
564 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
566 EFI_COMMON_SECTION_HEADER
*Section
;
568 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
571 // Size is 24 bits wide so mask upper 8 bits.
572 // Does not include FfsFileHeader header size
573 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
575 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
576 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
577 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
579 return PeiFfsProcessSection (
589 Given the input file pointer, search for the next matching file in the
590 FFS volume as defined by SearchType. The search starts from FileHeader inside
591 the Firmware Volume defined by FwVolHeader.
594 @param PeiServices Pointer to the PEI Core Services Table.
595 @param SearchType Filter to find only files of this type.
596 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
597 @param VolumeHandle Pointer to the FV header of the volume to search.
598 @param FileHandle Pointer to the current file from which to begin searching.
599 This pointer will be updated upon return to reflect the file found.
600 @retval EFI_NOT_FOUND No files matching the search criteria were found
601 @retval EFI_SUCCESS Success to find next file in given volume
607 IN CONST EFI_PEI_SERVICES
**PeiServices
,
609 IN EFI_PEI_FV_HANDLE VolumeHandle
,
610 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
613 return PeiFindFileEx (VolumeHandle
, NULL
, SearchType
, FileHandle
, NULL
);
618 search the firmware volumes by index
620 @param PeiServices The PEI core services table.
621 @param Instance Instance of FV to find
622 @param VolumeHandle Pointer to found Volume.
624 @retval EFI_INVALID_PARAMETER FwVolHeader is NULL
625 @retval EFI_SUCCESS Firmware volume instance successfully found.
630 PeiFvFindNextVolume (
631 IN CONST EFI_PEI_SERVICES
**PeiServices
,
633 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
636 PEI_CORE_INSTANCE
*Private
;
638 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
639 if (VolumeHandle
== NULL
) {
640 return EFI_INVALID_PARAMETER
;
643 if (Instance
>= Private
->AllFvCount
) {
645 return EFI_NOT_FOUND
;
648 *VolumeHandle
= Private
->AllFv
[Instance
];
655 Given the input VolumeHandle, search for the next matching name file.
658 @param FileName File name to search.
659 @param VolumeHandle The current FV to search.
660 @param FileHandle Pointer to the file matching name in VolumeHandle.
661 NULL if file not found
663 @retval EFI_NOT_FOUND No files matching the search criteria were found
664 @retval EFI_SUCCESS Success to search given file
668 PeiFfsFindFileByName (
669 IN CONST EFI_GUID
*FileName
,
670 IN EFI_PEI_FV_HANDLE VolumeHandle
,
671 OUT EFI_PEI_FILE_HANDLE
*FileHandle
675 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
676 return EFI_INVALID_PARAMETER
;
678 Status
= PeiFindFileEx (VolumeHandle
, FileName
, 0, FileHandle
, NULL
);
679 if (Status
== EFI_NOT_FOUND
) {
687 Returns information about a specific file.
690 @param FileHandle - The handle to file.
691 @param FileInfo - Pointer to the file information.
693 @retval EFI_INVALID_PARAMETER Invalid FileHandle or FileInfo.
694 @retval EFI_SUCCESS Success to collect file info.
700 IN EFI_PEI_FILE_HANDLE FileHandle
,
701 OUT EFI_FV_FILE_INFO
*FileInfo
706 EFI_FFS_FILE_HEADER
*FileHeader
;
707 EFI_PEI_FV_HANDLE VolumeHandle
;
709 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
710 return EFI_INVALID_PARAMETER
;
715 // Retrieve the FirmwareVolume which the file resides in.
717 if (!PeiFileHandleToVolume(FileHandle
, &VolumeHandle
)) {
718 return EFI_INVALID_PARAMETER
;
721 if (((EFI_FIRMWARE_VOLUME_HEADER
*)VolumeHandle
)->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
728 // Get FileState which is the highest bit of the State
730 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
733 case EFI_FILE_DATA_VALID
:
734 case EFI_FILE_MARKED_FOR_UPDATE
:
737 return EFI_INVALID_PARAMETER
;
740 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
741 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
742 FileInfo
->FileType
= FileHeader
->Type
;
743 FileInfo
->FileAttributes
= FileHeader
->Attributes
;
744 FileInfo
->BufferSize
= ((*(UINT32
*)FileHeader
->Size
) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER
);
745 FileInfo
->Buffer
= (FileHeader
+ 1);
752 Collect information of given Fv Volume.
754 @param VolumeHandle - The handle to Fv Volume.
755 @param VolumeInfo - The pointer to volume information.
757 @retval EFI_INVALID_PARAMETER VolumeInfo is NULL
758 @retval EFI_SUCCESS Success to collect fv info.
762 PeiFfsGetVolumeInfo (
763 IN EFI_PEI_FV_HANDLE VolumeHandle
,
764 OUT EFI_FV_INFO
*VolumeInfo
767 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
768 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
770 if (VolumeInfo
== NULL
) {
771 return EFI_INVALID_PARAMETER
;
775 // VolumeHandle may not align at 8 byte,
776 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
777 // So, Copy FvHeader into the local FvHeader structure.
779 CopyMem (&FwVolHeader
, VolumeHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
781 // Check Fv Image Signature
783 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
784 return EFI_INVALID_PARAMETER
;
786 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
787 VolumeInfo
->FvStart
= (VOID
*) VolumeHandle
;
788 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
789 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
791 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
792 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)VolumeHandle
) + FwVolHeader
.ExtHeaderOffset
);
793 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));