2 Pei Core Firmware File System service routines.
4 Copyright (c) 2015 HP Development Company, L.P.
5 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList
[] = {
14 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
15 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
16 FirmwareVolumeInfoPpiNotifyCallback
19 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
20 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
21 FirmwareVolumeInfoPpiNotifyCallback
25 PEI_FW_VOL_INSTANCE mPeiFfs2FwVol
= {
29 PeiFfsFvPpiProcessVolume
,
30 PeiFfsFvPpiFindFileByType
,
31 PeiFfsFvPpiFindFileByName
,
32 PeiFfsFvPpiGetFileInfo
,
33 PeiFfsFvPpiGetVolumeInfo
,
34 PeiFfsFvPpiFindSectionByType
,
35 PeiFfsFvPpiGetFileInfo2
,
36 PeiFfsFvPpiFindSectionByType2
,
37 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
,
38 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
42 PEI_FW_VOL_INSTANCE mPeiFfs3FwVol
= {
46 PeiFfsFvPpiProcessVolume
,
47 PeiFfsFvPpiFindFileByType
,
48 PeiFfsFvPpiFindFileByName
,
49 PeiFfsFvPpiGetFileInfo
,
50 PeiFfsFvPpiGetVolumeInfo
,
51 PeiFfsFvPpiFindSectionByType
,
52 PeiFfsFvPpiGetFileInfo2
,
53 PeiFfsFvPpiFindSectionByType2
,
54 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
,
55 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
59 EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList
= {
60 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
61 &gEfiFirmwareFileSystem2Guid
,
65 EFI_PEI_PPI_DESCRIPTOR mPeiFfs3FvPpiList
= {
66 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
67 &gEfiFirmwareFileSystem3Guid
,
72 Required Alignment Alignment Value in FFS FFS_ATTRIB_DATA_ALIGNMENT2 Alignment Value in
73 (bytes) Attributes Field in FFS Attributes Field Firmware Volume Interfaces
91 UINT8 mFvAttributes
[] = { 0, 4, 7, 9, 10, 12, 15, 16 };
92 UINT8 mFvAttributes2
[] = { 17, 18, 19, 20, 21, 22, 23, 24 };
95 Convert the FFS File Attributes to FV File Attributes
97 @param FfsAttributes The attributes of UINT8 type.
99 @return The attributes of EFI_FV_FILE_ATTRIBUTES
102 EFI_FV_FILE_ATTRIBUTES
103 FfsAttributes2FvFileAttributes (
104 IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
108 EFI_FV_FILE_ATTRIBUTES FileAttribute
;
110 DataAlignment
= (UINT8
)((FfsAttributes
& FFS_ATTRIB_DATA_ALIGNMENT
) >> 3);
111 ASSERT (DataAlignment
< 8);
113 if ((FfsAttributes
& FFS_ATTRIB_DATA_ALIGNMENT_2
) != 0) {
114 FileAttribute
= (EFI_FV_FILE_ATTRIBUTES
)mFvAttributes2
[DataAlignment
];
116 FileAttribute
= (EFI_FV_FILE_ATTRIBUTES
)mFvAttributes
[DataAlignment
];
119 if ((FfsAttributes
& FFS_ATTRIB_FIXED
) == FFS_ATTRIB_FIXED
) {
120 FileAttribute
|= EFI_FV_FILE_ATTRIB_FIXED
;
123 return FileAttribute
;
127 Returns the file state set by the highest zero bit in the State field
129 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
130 in the Attributes field.
131 @param FfsHeader Pointer to FFS File Header.
133 @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit
134 in the header State field.
138 IN UINT8 ErasePolarity
,
139 IN EFI_FFS_FILE_HEADER
*FfsHeader
142 EFI_FFS_FILE_STATE FileState
;
143 EFI_FFS_FILE_STATE HighestBit
;
145 FileState
= FfsHeader
->State
;
147 if (ErasePolarity
!= 0) {
148 FileState
= (EFI_FFS_FILE_STATE
) ~FileState
;
152 // Get file state set by its highest none zero bit.
155 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
163 Calculates the checksum of the header of a file.
165 @param FileHeader Pointer to FFS File Header.
167 @return Checksum of the header.
168 Zero means the header is good.
169 Non-zero means the header is bad.
172 CalculateHeaderChecksum (
173 IN EFI_FFS_FILE_HEADER
*FileHeader
176 EFI_FFS_FILE_HEADER2 TestFileHeader
;
178 if (IS_FFS_FILE2 (FileHeader
)) {
179 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER2
));
181 // Ignore State and File field in FFS header.
183 TestFileHeader
.State
= 0;
184 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
186 return CalculateSum8 ((CONST UINT8
*)&TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER2
));
188 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
190 // Ignore State and File field in FFS header.
192 TestFileHeader
.State
= 0;
193 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
195 return CalculateSum8 ((CONST UINT8
*)&TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
200 Find FV handler according to FileHandle in that FV.
202 @param FileHandle Handle of file image
204 @return Pointer to instance of PEI_CORE_FV_HANDLE.
208 IN EFI_PEI_FILE_HANDLE FileHandle
212 PEI_CORE_INSTANCE
*PrivateData
;
213 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
216 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
217 BestIndex
= PrivateData
->FvCount
;
220 // Find the best matched FV image that includes this FileHandle.
221 // FV may include the child FV, and they are in the same continuous space.
222 // If FileHandle is from the child FV, the updated logic can find its matched FV.
224 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
225 FwVolHeader
= PrivateData
->Fv
[Index
].FvHeader
;
226 if (((UINT64
)(UINTN
)FileHandle
> (UINT64
)(UINTN
)FwVolHeader
) && \
227 ((UINT64
)(UINTN
)FileHandle
<= ((UINT64
)(UINTN
)FwVolHeader
+ FwVolHeader
->FvLength
- 1)))
229 if (BestIndex
== PrivateData
->FvCount
) {
232 if ((UINT64
)(UINTN
)PrivateData
->Fv
[BestIndex
].FvHeader
< (UINT64
)(UINTN
)FwVolHeader
) {
239 if (BestIndex
< PrivateData
->FvCount
) {
240 return &PrivateData
->Fv
[BestIndex
];
247 Given the input file pointer, search for the first matching file in the
248 FFS volume as defined by SearchType. The search starts from FileHeader inside
249 the Firmware Volume defined by FwVolHeader.
250 If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.
251 If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
252 the first PEIM, or COMBINED PEIM or FV file type FFS file will return.
254 @param FvHandle Pointer to the FV header of the volume to search
255 @param FileName File name
256 @param SearchType Filter to find only files of this type.
257 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
258 @param FileHandle This parameter must point to a valid FFS volume.
259 @param AprioriFile Pointer to AprioriFile image in this FV if has
261 @return EFI_NOT_FOUND No files matching the search criteria were found
262 @retval EFI_SUCCESS Success to search given file
267 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
268 IN CONST EFI_GUID
*FileName OPTIONAL
,
269 IN EFI_FV_FILETYPE SearchType
,
270 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
,
271 IN OUT EFI_PEI_FILE_HANDLE
*AprioriFile OPTIONAL
274 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
275 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExtHeader
;
276 EFI_FFS_FILE_HEADER
**FileHeader
;
277 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
279 UINT32 FileOccupiedSize
;
288 // Convert the handle of FV to FV header for memory-mapped firmware volume
290 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FvHandle
;
291 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
293 IsFfs3Fv
= CompareGuid (&FwVolHeader
->FileSystemGuid
, &gEfiFirmwareFileSystem3Guid
);
295 FvLength
= FwVolHeader
->FvLength
;
296 if ((FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
303 // If FileHeader is not specified (NULL) or FileName is not NULL,
304 // start with the first file in the firmware volume. Otherwise,
305 // start from the FileHeader.
307 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
308 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
310 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
312 FwVolExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->ExtHeaderOffset
);
313 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolExtHeader
+ FwVolExtHeader
->ExtHeaderSize
);
315 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
318 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)ALIGN_POINTER (FfsFileHeader
, 8);
320 if (IS_FFS_FILE2 (*FileHeader
)) {
322 DEBUG ((DEBUG_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader
)->Name
));
325 FileLength
= FFS_FILE2_SIZE (*FileHeader
);
326 ASSERT (FileLength
> 0x00FFFFFF);
328 FileLength
= FFS_FILE_SIZE (*FileHeader
);
332 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
334 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
335 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
338 FileOffset
= (UINT32
)((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
339 ASSERT (FileOffset
<= 0xFFFFFFFF);
341 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
343 // Get FileState which is the highest bit of the State
345 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
347 case EFI_FILE_HEADER_CONSTRUCTION
:
348 case EFI_FILE_HEADER_INVALID
:
349 if (IS_FFS_FILE2 (FfsFileHeader
)) {
351 DEBUG ((DEBUG_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
354 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER2
);
355 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
357 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER
);
358 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
363 case EFI_FILE_DATA_VALID
:
364 case EFI_FILE_MARKED_FOR_UPDATE
:
365 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
368 return EFI_NOT_FOUND
;
371 if (IS_FFS_FILE2 (FfsFileHeader
)) {
372 FileLength
= FFS_FILE2_SIZE (FfsFileHeader
);
373 ASSERT (FileLength
> 0x00FFFFFF);
374 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
376 DEBUG ((DEBUG_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
377 FileOffset
+= FileOccupiedSize
;
378 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
382 FileLength
= FFS_FILE_SIZE (FfsFileHeader
);
383 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
386 DataCheckSum
= FFS_FIXED_CHECKSUM
;
387 if ((FfsFileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) == FFS_ATTRIB_CHECKSUM
) {
388 if (IS_FFS_FILE2 (FfsFileHeader
)) {
389 DataCheckSum
= CalculateCheckSum8 ((CONST UINT8
*)FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
), FileLength
- sizeof (EFI_FFS_FILE_HEADER2
));
391 DataCheckSum
= CalculateCheckSum8 ((CONST UINT8
*)FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
), FileLength
- sizeof (EFI_FFS_FILE_HEADER
));
395 if (FfsFileHeader
->IntegrityCheck
.Checksum
.File
!= DataCheckSum
) {
398 return EFI_NOT_FOUND
;
401 if (FileName
!= NULL
) {
402 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
403 *FileHeader
= FfsFileHeader
;
406 } else if (SearchType
== PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
) {
407 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
408 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
) ||
409 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
))
411 *FileHeader
= FfsFileHeader
;
413 } else if (AprioriFile
!= NULL
) {
414 if (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FREEFORM
) {
415 if (CompareGuid (&FfsFileHeader
->Name
, &gPeiAprioriFileNameGuid
)) {
416 *AprioriFile
= (EFI_PEI_FILE_HANDLE
)FfsFileHeader
;
420 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
421 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
))
423 *FileHeader
= FfsFileHeader
;
427 FileOffset
+= FileOccupiedSize
;
428 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
431 case EFI_FILE_DELETED
:
432 if (IS_FFS_FILE2 (FfsFileHeader
)) {
434 DEBUG ((DEBUG_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
437 FileLength
= FFS_FILE2_SIZE (FfsFileHeader
);
438 ASSERT (FileLength
> 0x00FFFFFF);
440 FileLength
= FFS_FILE_SIZE (FfsFileHeader
);
443 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
444 FileOffset
+= FileOccupiedSize
;
445 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
450 return EFI_NOT_FOUND
;
455 return EFI_NOT_FOUND
;
459 Initialize PeiCore FV List.
461 @param PrivateData - Pointer to PEI_CORE_INSTANCE.
462 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
466 IN PEI_CORE_INSTANCE
*PrivateData
,
467 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
471 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
472 EFI_PEI_FV_HANDLE FvHandle
;
473 EFI_FIRMWARE_VOLUME_HEADER
*BfvHeader
;
476 // Install FV_PPI for FFS2 file system.
478 PeiServicesInstallPpi (&mPeiFfs2FvPpiList
);
481 // Install FV_PPI for FFS3 file system.
483 PeiServicesInstallPpi (&mPeiFfs3FvPpiList
);
485 BfvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
488 // The FV_PPI in BFV's format should be installed.
490 Status
= PeiServicesLocatePpi (
491 &BfvHeader
->FileSystemGuid
,
496 ASSERT_EFI_ERROR (Status
);
501 Status
= FvPpi
->ProcessVolume (
503 SecCoreData
->BootFirmwareVolumeBase
,
504 (UINTN
)BfvHeader
->FvLength
,
507 ASSERT_EFI_ERROR (Status
);
509 PrivateData
->Fv
= AllocateZeroPool (sizeof (PEI_CORE_FV_HANDLE
) * FV_GROWTH_STEP
);
510 ASSERT (PrivateData
->Fv
!= NULL
);
511 PrivateData
->MaxFvCount
= FV_GROWTH_STEP
;
514 // Update internal PEI_CORE_FV array.
516 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= BfvHeader
;
517 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
518 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
519 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= 0;
522 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
523 (UINT32
)PrivateData
->FvCount
,
525 (UINT32
)BfvHeader
->FvLength
,
528 PrivateData
->FvCount
++;
531 // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose
532 // additional FVs to PeiCore.
534 Status
= PeiServicesNotifyPpi (mNotifyOnFvInfoList
);
535 ASSERT_EFI_ERROR (Status
);
539 Process Firmware Volume Information once FvInfoPPI or FvInfo2PPI install.
540 The FV Info will be registered into PeiCore private data structure.
541 And search the inside FV image, if found, the new FV INFO(2) PPI will be installed.
543 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
544 @param NotifyDescriptor Address of the notification descriptor data structure.
545 @param Ppi Address of the PPI that was installed.
547 @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.
548 @return if not EFI_SUCCESS, fail to verify FV.
553 FirmwareVolumeInfoPpiNotifyCallback (
554 IN EFI_PEI_SERVICES
**PeiServices
,
555 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
559 EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI FvInfo2Ppi
;
560 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
561 PEI_CORE_INSTANCE
*PrivateData
;
563 EFI_PEI_FV_HANDLE FvHandle
;
565 EFI_PEI_FILE_HANDLE FileHandle
;
571 Status
= EFI_SUCCESS
;
572 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
574 if (CompareGuid (NotifyDescriptor
->Guid
, &gEfiPeiFirmwareVolumeInfo2PpiGuid
)) {
578 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
));
584 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
));
585 FvInfo2Ppi
.AuthenticationStatus
= 0;
589 if (CompareGuid (&FvInfo2Ppi
.FvFormat
, &gEfiFirmwareFileSystem2Guid
)) {
591 // gEfiFirmwareFileSystem2Guid is specified for FvFormat, then here to check the
592 // FileSystemGuid pointed by FvInfo against gEfiFirmwareFileSystem2Guid to make sure
593 // FvInfo has the firmware file system 2 format.
595 // If the ASSERT really appears, FvFormat needs to be specified correctly, for example,
596 // gEfiFirmwareFileSystem3Guid can be used for firmware file system 3 format, or
597 // ((EFI_FIRMWARE_VOLUME_HEADER *) FvInfo)->FileSystemGuid can be just used for both
598 // firmware file system 2 and 3 format.
600 ASSERT (CompareGuid (&(((EFI_FIRMWARE_VOLUME_HEADER
*)FvInfo2Ppi
.FvInfo
)->FileSystemGuid
), &gEfiFirmwareFileSystem2Guid
));
604 // Locate the corresponding FV_PPI according to the format GUID of the FV found
606 Status
= PeiServicesLocatePpi (
607 &FvInfo2Ppi
.FvFormat
,
612 if (!EFI_ERROR (Status
)) {
614 // Process new found FV and get FV handle.
616 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo2Ppi
.FvInfo
, FvInfo2Ppi
.FvInfoSize
, &FvHandle
);
617 if (EFI_ERROR (Status
)) {
618 DEBUG ((DEBUG_ERROR
, "Fail to process new found FV, FV may be corrupted!\n"));
623 // Check whether the FV has already been processed.
625 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
626 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
627 if (IsFvInfo2
&& (FvInfo2Ppi
.AuthenticationStatus
!= PrivateData
->Fv
[FvIndex
].AuthenticationStatus
)) {
628 PrivateData
->Fv
[FvIndex
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
629 DEBUG ((DEBUG_INFO
, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex
, FvInfo2Ppi
.AuthenticationStatus
));
632 DEBUG ((DEBUG_INFO
, "The FV %p has already been processed!\n", FvInfo2Ppi
.FvInfo
));
637 if (PrivateData
->FvCount
>= PrivateData
->MaxFvCount
) {
639 // Run out of room, grow the buffer.
641 TempPtr
= AllocateZeroPool (
642 sizeof (PEI_CORE_FV_HANDLE
) * (PrivateData
->MaxFvCount
+ FV_GROWTH_STEP
)
644 ASSERT (TempPtr
!= NULL
);
648 sizeof (PEI_CORE_FV_HANDLE
) * PrivateData
->MaxFvCount
650 PrivateData
->Fv
= TempPtr
;
651 PrivateData
->MaxFvCount
= PrivateData
->MaxFvCount
+ FV_GROWTH_STEP
;
655 // Update internal PEI_CORE_FV array.
657 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FvInfo2Ppi
.FvInfo
;
658 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
659 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
660 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
661 CurFvCount
= PrivateData
->FvCount
;
664 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
666 (VOID
*)FvInfo2Ppi
.FvInfo
,
667 FvInfo2Ppi
.FvInfoSize
,
670 PrivateData
->FvCount
++;
673 // Scan and process the new discovered FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
677 Status
= FvPpi
->FindFileByType (
679 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
683 if (!EFI_ERROR (Status
)) {
684 Status
= FvPpi
->FindSectionByType (
686 EFI_SECTION_PEI_DEPEX
,
690 if (!EFI_ERROR (Status
)) {
691 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
693 // Dependency is not satisfied.
699 DEBUG ((DEBUG_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, CurFvCount
, FvHandle
));
700 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[CurFvCount
], FileHandle
);
702 } while (FileHandle
!= NULL
);
704 DEBUG ((DEBUG_ERROR
, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi
.FvInfo
));
706 AddUnknownFormatFvInfo (PrivateData
, &FvInfo2Ppi
);
713 Verify the Guided Section GUID by checking if there is the Guided Section GUID HOB recorded the GUID itself.
715 @param GuidedSectionGuid The Guided Section GUID.
716 @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Ppi
717 for the Guided Section.
719 @return TRUE The GuidedSectionGuid could be identified, and the pointer to
720 the Guided Section Extraction Ppi will be returned to *GuidedSectionExtraction.
721 @return FALSE The GuidedSectionGuid could not be identified, or
722 the Guided Section Extraction Ppi has not been installed yet.
726 VerifyGuidedSectionGuid (
727 IN EFI_GUID
*GuidedSectionGuid
,
728 OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
**GuidedSectionExtraction
731 EFI_PEI_HOB_POINTERS Hob
;
732 EFI_GUID
*GuidRecorded
;
737 // Check if there is the Guided Section GUID HOB recorded the GUID itself.
739 Hob
.Raw
= GetFirstGuidHob (GuidedSectionGuid
);
740 if (Hob
.Raw
!= NULL
) {
741 GuidRecorded
= (EFI_GUID
*)GET_GUID_HOB_DATA (Hob
);
742 if (CompareGuid (GuidRecorded
, GuidedSectionGuid
)) {
744 // Found the recorded GuidedSectionGuid.
746 Status
= PeiServicesLocatePpi (GuidedSectionGuid
, 0, NULL
, (VOID
**)&Interface
);
747 if (!EFI_ERROR (Status
) && (Interface
!= NULL
)) {
749 // Found the supported Guided Section Extraction Ppi for the Guided Section.
751 *GuidedSectionExtraction
= (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*)Interface
;
763 Go through the file to search SectionType section.
764 Search within encapsulation sections (compression and GUIDed) recursively,
765 until the match section is found.
767 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
768 @param SectionType Filter to find only section of this type.
769 @param SectionInstance Pointer to the filter to find the specific instance of section.
770 @param Section From where to search.
771 @param SectionSize The file size to search.
772 @param OutputBuffer A pointer to the discovered section, if successful.
773 NULL if section not found
774 @param AuthenticationStatus Updated upon return to point to the authentication status for this section.
775 @param IsFfs3Fv Indicates the FV format.
777 @return EFI_NOT_FOUND The match section is not found.
778 @return EFI_SUCCESS The match section is found.
783 IN CONST EFI_PEI_SERVICES
**PeiServices
,
784 IN EFI_SECTION_TYPE SectionType
,
785 IN OUT UINTN
*SectionInstance
,
786 IN EFI_COMMON_SECTION_HEADER
*Section
,
787 IN UINTN SectionSize
,
788 OUT VOID
**OutputBuffer
,
789 OUT UINT32
*AuthenticationStatus
,
794 UINT32 SectionLength
;
796 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
797 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
801 UINT32 Authentication
;
802 PEI_CORE_INSTANCE
*PrivateData
;
803 EFI_GUID
*SectionDefinitionGuid
;
804 BOOLEAN SectionCached
;
805 VOID
*TempOutputBuffer
;
806 UINT32 TempAuthenticationStatus
;
807 UINT16 GuidedSectionAttributes
;
809 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
810 *OutputBuffer
= NULL
;
813 Status
= EFI_NOT_FOUND
;
816 while (ParsedLength
< SectionSize
) {
817 if (IS_SECTION2 (Section
)) {
818 ASSERT (SECTION2_SIZE (Section
) > 0x00FFFFFF);
820 DEBUG ((DEBUG_ERROR
, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
821 SectionLength
= SECTION2_SIZE (Section
);
823 // SectionLength is adjusted it is 4 byte aligned.
824 // Go to the next section
826 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
827 ASSERT (SectionLength
!= 0);
828 ParsedLength
+= SectionLength
;
829 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
834 if (Section
->Type
== SectionType
) {
836 // The type matches, so check the instance count to see if it's the one we want.
838 (*SectionInstance
)--;
839 if (*SectionInstance
== 0) {
843 if (IS_SECTION2 (Section
)) {
844 *OutputBuffer
= (VOID
*)((UINT8
*)Section
+ sizeof (EFI_COMMON_SECTION_HEADER2
));
846 *OutputBuffer
= (VOID
*)((UINT8
*)Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
851 if (IS_SECTION2 (Section
)) {
852 SectionLength
= SECTION2_SIZE (Section
);
854 SectionLength
= SECTION_SIZE (Section
);
858 // SectionLength is adjusted it is 4 byte aligned.
859 // Go to the next section
861 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
862 ASSERT (SectionLength
!= 0);
863 ParsedLength
+= SectionLength
;
864 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
867 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
869 // Check the encapsulated section is extracted into the cache data.
871 SectionCached
= FALSE
;
872 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
873 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
874 SectionCached
= TRUE
;
875 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
876 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
877 Authentication
= PrivateData
->CacheSection
.AuthenticationStatus
[Index
];
879 // Search section directly from the cache data.
881 TempAuthenticationStatus
= 0;
882 Status
= ProcessSection (
889 &TempAuthenticationStatus
,
892 if (!EFI_ERROR (Status
)) {
893 *OutputBuffer
= TempOutputBuffer
;
894 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
901 // If SectionCached is TRUE, the section data has been cached and scanned.
903 if (!SectionCached
) {
904 Status
= EFI_NOT_FOUND
;
906 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
907 if (IS_SECTION2 (Section
)) {
908 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION2
*)Section
)->SectionDefinitionGuid
;
909 GuidedSectionAttributes
= ((EFI_GUID_DEFINED_SECTION2
*)Section
)->Attributes
;
911 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
;
912 GuidedSectionAttributes
= ((EFI_GUID_DEFINED_SECTION
*)Section
)->Attributes
;
915 if (VerifyGuidedSectionGuid (SectionDefinitionGuid
, &GuidSectionPpi
)) {
916 Status
= GuidSectionPpi
->ExtractSection (
923 } else if ((GuidedSectionAttributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
925 // Figure out the proper authentication status for GUIDED section without processing required
927 Status
= EFI_SUCCESS
;
928 if ((GuidedSectionAttributes
& EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) {
929 Authentication
|= EFI_AUTH_STATUS_IMAGE_SIGNED
| EFI_AUTH_STATUS_NOT_TESTED
;
932 if (IS_SECTION2 (Section
)) {
933 PpiOutputSize
= SECTION2_SIZE (Section
) - ((EFI_GUID_DEFINED_SECTION2
*)Section
)->DataOffset
;
934 PpiOutput
= (UINT8
*)Section
+ ((EFI_GUID_DEFINED_SECTION2
*)Section
)->DataOffset
;
936 PpiOutputSize
= SECTION_SIZE (Section
) - ((EFI_GUID_DEFINED_SECTION
*)Section
)->DataOffset
;
937 PpiOutput
= (UINT8
*)Section
+ ((EFI_GUID_DEFINED_SECTION
*)Section
)->DataOffset
;
940 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
941 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**)&DecompressPpi
);
942 if (!EFI_ERROR (Status
)) {
943 Status
= DecompressPpi
->Decompress (
945 (CONST EFI_COMPRESSION_SECTION
*)Section
,
952 if (!EFI_ERROR (Status
)) {
953 if ((Authentication
& EFI_AUTH_STATUS_NOT_TESTED
) == 0) {
955 // Update cache section data.
957 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
958 PrivateData
->CacheSection
.AllSectionCount
++;
961 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
962 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
963 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
964 PrivateData
->CacheSection
.AuthenticationStatus
[PrivateData
->CacheSection
.SectionIndex
] = Authentication
;
965 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
968 TempAuthenticationStatus
= 0;
969 Status
= ProcessSection (
976 &TempAuthenticationStatus
,
979 if (!EFI_ERROR (Status
)) {
980 *OutputBuffer
= TempOutputBuffer
;
981 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
988 if (IS_SECTION2 (Section
)) {
989 SectionLength
= SECTION2_SIZE (Section
);
991 SectionLength
= SECTION_SIZE (Section
);
995 // SectionLength is adjusted it is 4 byte aligned.
996 // Go to the next section
998 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
999 ASSERT (SectionLength
!= 0);
1000 ParsedLength
+= SectionLength
;
1001 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
1004 return EFI_NOT_FOUND
;
1008 Searches for the next matching section within the specified file.
1010 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
1011 @param SectionType Filter to find only sections of this type.
1012 @param FileHandle Pointer to the current file to search.
1013 @param SectionData A pointer to the discovered section, if successful.
1014 NULL if section not found
1016 @retval EFI_NOT_FOUND The section was not found.
1017 @retval EFI_SUCCESS The section was found.
1022 PeiFfsFindSectionData (
1023 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1024 IN EFI_SECTION_TYPE SectionType
,
1025 IN EFI_PEI_FILE_HANDLE FileHandle
,
1026 OUT VOID
**SectionData
1029 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1031 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1032 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1033 return EFI_NOT_FOUND
;
1036 return CoreFvHandle
->FvPpi
->FindSectionByType (CoreFvHandle
->FvPpi
, SectionType
, FileHandle
, SectionData
);
1040 Searches for the next matching section within the specified file.
1042 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
1043 @param SectionType The value of the section type to find.
1044 @param SectionInstance Section instance to find.
1045 @param FileHandle Handle of the firmware file to search.
1046 @param SectionData A pointer to the discovered section, if successful.
1047 @param AuthenticationStatus A pointer to the authentication status for this section.
1049 @retval EFI_SUCCESS The section was found.
1050 @retval EFI_NOT_FOUND The section was not found.
1055 PeiFfsFindSectionData3 (
1056 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1057 IN EFI_SECTION_TYPE SectionType
,
1058 IN UINTN SectionInstance
,
1059 IN EFI_PEI_FILE_HANDLE FileHandle
,
1060 OUT VOID
**SectionData
,
1061 OUT UINT32
*AuthenticationStatus
1064 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1066 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1067 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1068 return EFI_NOT_FOUND
;
1071 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1072 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
))
1074 return CoreFvHandle
->FvPpi
->FindSectionByType2 (CoreFvHandle
->FvPpi
, SectionType
, SectionInstance
, FileHandle
, SectionData
, AuthenticationStatus
);
1078 // The old FvPpi doesn't support to find section by section instance
1079 // and return authentication status, so return EFI_UNSUPPORTED.
1081 return EFI_UNSUPPORTED
;
1085 Searches for the next matching file in the firmware volume.
1087 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
1088 @param SearchType Filter to find only files of this type.
1089 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
1090 @param FvHandle Handle of firmware volume in which to search.
1091 @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
1092 at the beginning of the firmware volume. On exit, points the file handle of the next file
1093 in the volume or NULL if there are no more files.
1095 @retval EFI_NOT_FOUND The file was not found.
1096 @retval EFI_NOT_FOUND The header checksum was not zero.
1097 @retval EFI_SUCCESS The file was found.
1102 PeiFfsFindNextFile (
1103 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1104 IN UINT8 SearchType
,
1105 IN EFI_PEI_FV_HANDLE FvHandle
,
1106 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1109 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1111 CoreFvHandle
= FvHandleToCoreHandle (FvHandle
);
1113 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1114 return EFI_NOT_FOUND
;
1117 return CoreFvHandle
->FvPpi
->FindFileByType (CoreFvHandle
->FvPpi
, SearchType
, FvHandle
, FileHandle
);
1121 Search the firmware volumes by index
1123 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
1124 @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
1126 @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
1128 @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
1129 @retval EFI_NOT_FOUND The volume was not found.
1130 @retval EFI_SUCCESS The volume was found.
1135 PeiFfsFindNextVolume (
1136 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1138 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
1141 PEI_CORE_INSTANCE
*Private
;
1142 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1144 if (VolumeHandle
== NULL
) {
1145 return EFI_INVALID_PARAMETER
;
1148 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
1150 CoreFvHandle
= FindNextCoreFvHandle (Private
, Instance
);
1151 if (CoreFvHandle
== NULL
) {
1152 *VolumeHandle
= NULL
;
1153 return EFI_NOT_FOUND
;
1156 *VolumeHandle
= CoreFvHandle
->FvHandle
;
1162 Find a file within a volume by its name.
1164 @param FileName A pointer to the name of the file to find within the firmware volume.
1165 @param VolumeHandle The firmware volume to search
1166 @param FileHandle Upon exit, points to the found file's handle
1167 or NULL if it could not be found.
1169 @retval EFI_SUCCESS File was found.
1170 @retval EFI_NOT_FOUND File was not found.
1171 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
1176 PeiFfsFindFileByName (
1177 IN CONST EFI_GUID
*FileName
,
1178 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1179 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1182 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1184 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1185 return EFI_INVALID_PARAMETER
;
1188 CoreFvHandle
= FvHandleToCoreHandle (VolumeHandle
);
1189 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1190 return EFI_NOT_FOUND
;
1193 return CoreFvHandle
->FvPpi
->FindFileByName (CoreFvHandle
->FvPpi
, FileName
, &VolumeHandle
, FileHandle
);
1197 Returns information about a specific file.
1199 @param FileHandle Handle of the file.
1200 @param FileInfo Upon exit, points to the file's information.
1202 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1203 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1204 @retval EFI_SUCCESS File information returned.
1210 IN EFI_PEI_FILE_HANDLE FileHandle
,
1211 OUT EFI_FV_FILE_INFO
*FileInfo
1214 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1216 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1217 return EFI_INVALID_PARAMETER
;
1221 // Retrieve the FirmwareVolume which the file resides in.
1223 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1224 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1225 return EFI_INVALID_PARAMETER
;
1228 return CoreFvHandle
->FvPpi
->GetFileInfo (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1232 Returns information about a specific file.
1234 @param FileHandle Handle of the file.
1235 @param FileInfo Upon exit, points to the file's information.
1237 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1238 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1239 @retval EFI_SUCCESS File information returned.
1244 PeiFfsGetFileInfo2 (
1245 IN EFI_PEI_FILE_HANDLE FileHandle
,
1246 OUT EFI_FV_FILE_INFO2
*FileInfo
1249 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1251 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1252 return EFI_INVALID_PARAMETER
;
1256 // Retrieve the FirmwareVolume which the file resides in.
1258 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1259 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1260 return EFI_INVALID_PARAMETER
;
1263 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1264 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
))
1266 return CoreFvHandle
->FvPpi
->GetFileInfo2 (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1270 // The old FvPpi doesn't support to return file info with authentication status,
1271 // so return EFI_UNSUPPORTED.
1273 return EFI_UNSUPPORTED
;
1277 Returns information about the specified volume.
1279 This function returns information about a specific firmware
1280 volume, including its name, type, attributes, starting address
1283 @param VolumeHandle Handle of the volume.
1284 @param VolumeInfo Upon exit, points to the volume's information.
1286 @retval EFI_SUCCESS Volume information returned.
1287 @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
1288 @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
1289 @retval EFI_SUCCESS Information successfully returned.
1290 @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
1295 PeiFfsGetVolumeInfo (
1296 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1297 OUT EFI_FV_INFO
*VolumeInfo
1300 PEI_CORE_FV_HANDLE
*CoreHandle
;
1302 if ((VolumeInfo
== NULL
) || (VolumeHandle
== NULL
)) {
1303 return EFI_INVALID_PARAMETER
;
1306 CoreHandle
= FvHandleToCoreHandle (VolumeHandle
);
1308 if ((CoreHandle
== NULL
) || (CoreHandle
->FvPpi
== NULL
)) {
1309 return EFI_INVALID_PARAMETER
;
1312 return CoreHandle
->FvPpi
->GetVolumeInfo (CoreHandle
->FvPpi
, VolumeHandle
, VolumeInfo
);
1316 Find USED_SIZE FV_EXT_TYPE entry in FV extension header and get the FV used size.
1318 @param[in] FvHeader Pointer to FV header.
1319 @param[out] FvUsedSize Pointer to FV used size returned,
1320 only valid if USED_SIZE FV_EXT_TYPE entry is found.
1321 @param[out] EraseByte Pointer to erase byte returned,
1322 only valid if USED_SIZE FV_EXT_TYPE entry is found.
1324 @retval TRUE USED_SIZE FV_EXT_TYPE entry is found,
1325 FV used size and erase byte are returned.
1326 @retval FALSE No USED_SIZE FV_EXT_TYPE entry found.
1331 IN EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
,
1332 OUT UINT32
*FvUsedSize
,
1333 OUT UINT8
*EraseByte
1336 UINT16 ExtHeaderOffset
;
1337 EFI_FIRMWARE_VOLUME_EXT_HEADER
*ExtHeader
;
1338 EFI_FIRMWARE_VOLUME_EXT_ENTRY
*ExtEntryList
;
1339 EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE
*ExtEntryUsedSize
;
1341 ExtHeaderOffset
= ReadUnaligned16 (&FvHeader
->ExtHeaderOffset
);
1342 if (ExtHeaderOffset
!= 0) {
1343 ExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)((UINT8
*)FvHeader
+ ExtHeaderOffset
);
1344 ExtEntryList
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY
*)(ExtHeader
+ 1);
1345 while ((UINTN
)ExtEntryList
< ((UINTN
)ExtHeader
+ ReadUnaligned32 (&ExtHeader
->ExtHeaderSize
))) {
1346 if (ReadUnaligned16 (&ExtEntryList
->ExtEntryType
) == EFI_FV_EXT_TYPE_USED_SIZE_TYPE
) {
1348 // USED_SIZE FV_EXT_TYPE entry is found.
1350 ExtEntryUsedSize
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE
*)ExtEntryList
;
1351 *FvUsedSize
= ReadUnaligned32 (&ExtEntryUsedSize
->UsedSize
);
1352 if ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_ERASE_POLARITY
) != 0) {
1360 "FV at 0x%x has 0x%x used size, and erase byte is 0x%02x\n",
1368 ExtEntryList
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY
*)
1369 ((UINT8
*)ExtEntryList
+ ReadUnaligned16 (&ExtEntryList
->ExtEntrySize
));
1374 // No USED_SIZE FV_EXT_TYPE entry found.
1380 Get FV image(s) from the FV type file, then install FV INFO(2) PPI, Build FV(2, 3) HOB.
1382 @param PrivateData PeiCore's private data structure
1383 @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent FV image that contain this FV image.
1384 @param ParentFvFileHandle File handle of a FV type file that contain this FV image.
1386 @retval EFI_NOT_FOUND FV image can't be found.
1387 @retval EFI_SUCCESS Successfully to process it.
1388 @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image
1389 @retval EFI_SECURITY_VIOLATION Image is illegal
1390 @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section
1395 IN PEI_CORE_INSTANCE
*PrivateData
,
1396 IN PEI_CORE_FV_HANDLE
*ParentFvCoreHandle
,
1397 IN EFI_PEI_FILE_HANDLE ParentFvFileHandle
1401 EFI_FV_INFO ParentFvImageInfo
;
1404 EFI_PEI_HOB_POINTERS HobPtr
;
1405 EFI_PEI_FIRMWARE_VOLUME_PPI
*ParentFvPpi
;
1406 EFI_PEI_FV_HANDLE ParentFvHandle
;
1407 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
1408 EFI_FV_FILE_INFO FileInfo
;
1410 UINT32 AuthenticationStatus
;
1416 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1419 HobPtr
.Raw
= GetHobList ();
1420 while ((HobPtr
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobPtr
.Raw
)) != NULL
) {
1421 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)ParentFvFileHandle
)->Name
), &HobPtr
.FirmwareVolume2
->FileName
)) {
1423 // this FILE has been dispatched, it will not be dispatched again.
1425 DEBUG ((DEBUG_INFO
, "FV file %p has been dispatched!\r\n", ParentFvFileHandle
));
1429 HobPtr
.Raw
= GET_NEXT_HOB (HobPtr
);
1432 ParentFvHandle
= ParentFvCoreHandle
->FvHandle
;
1433 ParentFvPpi
= ParentFvCoreHandle
->FvPpi
;
1435 Status
= EFI_SUCCESS
;
1438 // Find FvImage(s) in FvFile
1442 AuthenticationStatus
= 0;
1443 if ((ParentFvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1444 (ParentFvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
))
1446 Status
= ParentFvPpi
->FindSectionByType2 (
1448 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1452 &AuthenticationStatus
1456 // Old FvPpi has no parameter to input SearchInstance,
1457 // only one instance is supported.
1463 Status
= ParentFvPpi
->FindSectionByType (
1465 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1471 if (EFI_ERROR (Status
)) {
1475 Status
= VerifyPeim (PrivateData
, ParentFvHandle
, ParentFvFileHandle
, AuthenticationStatus
);
1476 if (Status
== EFI_SECURITY_VIOLATION
) {
1481 // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
1482 // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
1483 // its initial linked location and maintain its alignment.
1485 if ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_WEAK_ALIGNMENT
) != EFI_FVB2_WEAK_ALIGNMENT
) {
1487 // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
1489 FvAlignment
= 1 << ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_ALIGNMENT
) >> 16);
1490 if (FvAlignment
< 8) {
1496 "%a() FV at 0x%x, FvAlignment required is 0x%x\n",
1503 // Check FvImage alignment.
1505 if ((UINTN
)FvHeader
% FvAlignment
!= 0) {
1506 FvLength
= ReadUnaligned64 (&FvHeader
->FvLength
);
1507 NewFvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
)FvLength
), FvAlignment
);
1508 if (NewFvBuffer
== NULL
) {
1509 Status
= EFI_OUT_OF_RESOURCES
;
1513 if (GetFvUsedSize (FvHeader
, &FvUsedSize
, &EraseByte
)) {
1515 // Copy the used bytes and fill the rest with the erase value.
1517 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
)FvUsedSize
);
1519 (UINT8
*)NewFvBuffer
+ FvUsedSize
,
1520 (UINTN
)(FvLength
- FvUsedSize
),
1524 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
)FvLength
);
1527 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)NewFvBuffer
;
1531 Status
= ParentFvPpi
->GetVolumeInfo (ParentFvPpi
, ParentFvHandle
, &ParentFvImageInfo
);
1532 ASSERT_EFI_ERROR (Status
);
1534 Status
= ParentFvPpi
->GetFileInfo (ParentFvPpi
, ParentFvFileHandle
, &FileInfo
);
1535 ASSERT_EFI_ERROR (Status
);
1538 // Install FvInfo(2) Ppi
1539 // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated
1540 // FVs inherit the proper AuthenticationStatus.
1542 PeiServicesInstallFvInfo2Ppi (
1543 &FvHeader
->FileSystemGuid
,
1545 (UINT32
)FvHeader
->FvLength
,
1546 &ParentFvImageInfo
.FvName
,
1548 AuthenticationStatus
1551 PeiServicesInstallFvInfoPpi (
1552 &FvHeader
->FileSystemGuid
,
1554 (UINT32
)FvHeader
->FvLength
,
1555 &ParentFvImageInfo
.FvName
,
1560 // Expose the extracted FvImage to the FV HOB consumer phase, i.e. DXE phase
1563 (EFI_PHYSICAL_ADDRESS
)(UINTN
)FvHeader
,
1568 // Makes the encapsulated volume show up in DXE phase to skip processing of
1569 // encapsulated file again.
1572 (EFI_PHYSICAL_ADDRESS
)(UINTN
)FvHeader
,
1574 &ParentFvImageInfo
.FvName
,
1579 // Build FV3 HOB with authentication status to be propagated to DXE.
1582 (EFI_PHYSICAL_ADDRESS
)(UINTN
)FvHeader
,
1584 AuthenticationStatus
,
1586 &ParentFvImageInfo
.FvName
,
1595 // At least one FvImage has been processed successfully.
1604 Process a firmware volume and create a volume handle.
1606 Create a volume handle from the information in the buffer. For
1607 memory-mapped firmware volumes, Buffer and BufferSize refer to
1608 the start of the firmware volume and the firmware volume size.
1609 For non memory-mapped firmware volumes, this points to a
1610 buffer which contains the necessary information for creating
1611 the firmware volume handle. Normally, these values are derived
1612 from the EFI_FIRMWARE_VOLUME_INFO_PPI.
1615 @param This Points to this instance of the
1616 EFI_PEI_FIRMWARE_VOLUME_PPI.
1617 @param Buffer Points to the start of the buffer.
1618 @param BufferSize Size of the buffer.
1619 @param FvHandle Points to the returned firmware volume
1620 handle. The firmware volume handle must
1621 be unique within the system.
1623 @retval EFI_SUCCESS Firmware volume handle created.
1624 @retval EFI_VOLUME_CORRUPTED Volume was corrupt.
1629 PeiFfsFvPpiProcessVolume (
1630 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1632 IN UINTN BufferSize
,
1633 OUT EFI_PEI_FV_HANDLE
*FvHandle
1638 ASSERT (FvHandle
!= NULL
);
1640 if (Buffer
== NULL
) {
1641 return EFI_VOLUME_CORRUPTED
;
1645 // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped
1646 // FV image and the handle is pointed to FV image's buffer.
1648 *FvHandle
= (EFI_PEI_FV_HANDLE
)Buffer
;
1651 // Do verify for given FV buffer.
1653 Status
= VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER
*)Buffer
);
1654 if (EFI_ERROR (Status
)) {
1655 DEBUG ((DEBUG_ERROR
, "Fail to verify FV which address is 0x%11p", Buffer
));
1656 return EFI_VOLUME_CORRUPTED
;
1663 Finds the next file of the specified type.
1665 This service enables PEI modules to discover additional firmware files.
1666 The FileHandle must be unique within the system.
1668 @param This Points to this instance of the
1669 EFI_PEI_FIRMWARE_VOLUME_PPI.
1670 @param SearchType A filter to find only files of this type. Type
1671 EFI_FV_FILETYPE_ALL causes no filtering to be
1673 @param FvHandle Handle of firmware volume in which to
1675 @param FileHandle Points to the current handle from which to
1676 begin searching or NULL to start at the
1677 beginning of the firmware volume. Updated
1678 upon return to reflect the file found.
1680 @retval EFI_SUCCESS The file was found.
1681 @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.
1686 PeiFfsFvPpiFindFileByType (
1687 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1688 IN EFI_FV_FILETYPE SearchType
,
1689 IN EFI_PEI_FV_HANDLE FvHandle
,
1690 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1693 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1697 Find a file within a volume by its name.
1699 This service searches for files with a specific name, within
1700 either the specified firmware volume or all firmware volumes.
1702 @param This Points to this instance of the
1703 EFI_PEI_FIRMWARE_VOLUME_PPI.
1704 @param FileName A pointer to the name of the file to find
1705 within the firmware volume.
1706 @param FvHandle Upon entry, the pointer to the firmware
1707 volume to search or NULL if all firmware
1708 volumes should be searched. Upon exit, the
1709 actual firmware volume in which the file was
1711 @param FileHandle Upon exit, points to the found file's
1712 handle or NULL if it could not be found.
1714 @retval EFI_SUCCESS File was found.
1715 @retval EFI_NOT_FOUND File was not found.
1716 @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or
1723 PeiFfsFvPpiFindFileByName (
1724 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1725 IN CONST EFI_GUID
*FileName
,
1726 IN EFI_PEI_FV_HANDLE
*FvHandle
,
1727 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1731 PEI_CORE_INSTANCE
*PrivateData
;
1734 if ((FvHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1735 return EFI_INVALID_PARAMETER
;
1738 if (*FvHandle
!= NULL
) {
1739 Status
= FindFileEx (*FvHandle
, FileName
, 0, FileHandle
, NULL
);
1740 if (Status
== EFI_NOT_FOUND
) {
1745 // If *FvHandle = NULL, so search all FV for given filename
1747 Status
= EFI_NOT_FOUND
;
1749 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
1750 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1752 // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
1754 if (PrivateData
->Fv
[Index
].FvPpi
!= NULL
) {
1755 Status
= FindFileEx (PrivateData
->Fv
[Index
].FvHandle
, FileName
, 0, FileHandle
, NULL
);
1756 if (!EFI_ERROR (Status
)) {
1757 *FvHandle
= PrivateData
->Fv
[Index
].FvHandle
;
1768 Returns information about a specific file.
1770 This function returns information about a specific
1771 file, including its file name, type, attributes, starting
1774 @param This Points to this instance of the
1775 EFI_PEI_FIRMWARE_VOLUME_PPI.
1776 @param FileHandle Handle of the file.
1777 @param FileInfo Upon exit, points to the file's
1780 @retval EFI_SUCCESS File information returned.
1781 @retval EFI_INVALID_PARAMETER If FileHandle does not
1782 represent a valid file.
1783 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1788 PeiFfsFvPpiGetFileInfo (
1789 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1790 IN EFI_PEI_FILE_HANDLE FileHandle
,
1791 OUT EFI_FV_FILE_INFO
*FileInfo
1795 UINT8 ErasePolarity
;
1796 EFI_FFS_FILE_HEADER
*FileHeader
;
1797 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1798 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1800 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1801 return EFI_INVALID_PARAMETER
;
1805 // Retrieve the FirmwareVolume which the file resides in.
1807 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1808 if (CoreFvHandle
== NULL
) {
1809 return EFI_INVALID_PARAMETER
;
1812 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1814 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
1821 // Get FileState which is the highest bit of the State
1823 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
1825 switch (FileState
) {
1826 case EFI_FILE_DATA_VALID
:
1827 case EFI_FILE_MARKED_FOR_UPDATE
:
1830 return EFI_INVALID_PARAMETER
;
1833 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
1834 if (IS_FFS_FILE2 (FileHeader
)) {
1835 ASSERT (FFS_FILE2_SIZE (FileHeader
) > 0x00FFFFFF);
1836 if (!FwVolInstance
->IsFfs3Fv
) {
1837 DEBUG ((DEBUG_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader
->Name
));
1838 return EFI_INVALID_PARAMETER
;
1841 FileInfo
->BufferSize
= FFS_FILE2_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
1842 FileInfo
->Buffer
= (UINT8
*)FileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
);
1844 FileInfo
->BufferSize
= FFS_FILE_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
1845 FileInfo
->Buffer
= (UINT8
*)FileHeader
+ sizeof (EFI_FFS_FILE_HEADER
);
1848 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof (EFI_GUID
));
1849 FileInfo
->FileType
= FileHeader
->Type
;
1850 FileInfo
->FileAttributes
= FfsAttributes2FvFileAttributes (FileHeader
->Attributes
);
1851 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_MEMORY_MAPPED
) == EFI_FVB2_MEMORY_MAPPED
) {
1852 FileInfo
->FileAttributes
|= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED
;
1859 Returns information about a specific file.
1861 This function returns information about a specific
1862 file, including its file name, type, attributes, starting
1863 address, size and authentication status.
1865 @param This Points to this instance of the
1866 EFI_PEI_FIRMWARE_VOLUME_PPI.
1867 @param FileHandle Handle of the file.
1868 @param FileInfo Upon exit, points to the file's
1871 @retval EFI_SUCCESS File information returned.
1872 @retval EFI_INVALID_PARAMETER If FileHandle does not
1873 represent a valid file.
1874 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1879 PeiFfsFvPpiGetFileInfo2 (
1880 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1881 IN EFI_PEI_FILE_HANDLE FileHandle
,
1882 OUT EFI_FV_FILE_INFO2
*FileInfo
1886 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1888 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1889 return EFI_INVALID_PARAMETER
;
1893 // Retrieve the FirmwareVolume which the file resides in.
1895 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1896 if (CoreFvHandle
== NULL
) {
1897 return EFI_INVALID_PARAMETER
;
1900 Status
= PeiFfsFvPpiGetFileInfo (This
, FileHandle
, (EFI_FV_FILE_INFO
*)FileInfo
);
1901 if (!EFI_ERROR (Status
)) {
1902 FileInfo
->AuthenticationStatus
= CoreFvHandle
->AuthenticationStatus
;
1909 This function returns information about the firmware volume.
1911 @param This Points to this instance of the
1912 EFI_PEI_FIRMWARE_VOLUME_PPI.
1913 @param FvHandle Handle to the firmware handle.
1914 @param VolumeInfo Points to the returned firmware volume
1917 @retval EFI_SUCCESS Information returned successfully.
1918 @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid
1919 firmware volume or VolumeInfo is NULL.
1924 PeiFfsFvPpiGetVolumeInfo (
1925 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1926 IN EFI_PEI_FV_HANDLE FvHandle
,
1927 OUT EFI_FV_INFO
*VolumeInfo
1930 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
1931 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
1933 if ((VolumeInfo
== NULL
) || (FvHandle
== NULL
)) {
1934 return EFI_INVALID_PARAMETER
;
1938 // VolumeHandle may not align at 8 byte,
1939 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
1940 // So, Copy FvHeader into the local FvHeader structure.
1942 CopyMem (&FwVolHeader
, FvHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
1945 // Check FV Image Signature
1947 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
1948 return EFI_INVALID_PARAMETER
;
1951 ZeroMem (VolumeInfo
, sizeof (EFI_FV_INFO
));
1952 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
1953 VolumeInfo
->FvStart
= (VOID
*)FvHandle
;
1954 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
1955 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof (EFI_GUID
));
1957 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
1958 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FvHandle
) + FwVolHeader
.ExtHeaderOffset
);
1959 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof (EFI_GUID
));
1966 Find the next matching section in the firmware file.
1968 This service enables PEI modules to discover sections
1969 of a given type within a valid file.
1971 @param This Points to this instance of the
1972 EFI_PEI_FIRMWARE_VOLUME_PPI.
1973 @param SearchType A filter to find only sections of this
1975 @param FileHandle Handle of firmware file in which to
1977 @param SectionData Updated upon return to point to the
1980 @retval EFI_SUCCESS Section was found.
1981 @retval EFI_NOT_FOUND Section of the specified type was not
1982 found. SectionData contains NULL.
1986 PeiFfsFvPpiFindSectionByType (
1987 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1988 IN EFI_SECTION_TYPE SearchType
,
1989 IN EFI_PEI_FILE_HANDLE FileHandle
,
1990 OUT VOID
**SectionData
1993 UINT32 AuthenticationStatus
;
1995 return PeiFfsFvPpiFindSectionByType2 (This
, SearchType
, 0, FileHandle
, SectionData
, &AuthenticationStatus
);
1999 Find the next matching section in the firmware file.
2001 This service enables PEI modules to discover sections
2002 of a given instance and type within a valid file.
2004 @param This Points to this instance of the
2005 EFI_PEI_FIRMWARE_VOLUME_PPI.
2006 @param SearchType A filter to find only sections of this
2008 @param SearchInstance A filter to find the specific instance
2010 @param FileHandle Handle of firmware file in which to
2012 @param SectionData Updated upon return to point to the
2014 @param AuthenticationStatus Updated upon return to point to the
2015 authentication status for this section.
2017 @retval EFI_SUCCESS Section was found.
2018 @retval EFI_NOT_FOUND Section of the specified type was not
2019 found. SectionData contains NULL.
2023 PeiFfsFvPpiFindSectionByType2 (
2024 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
2025 IN EFI_SECTION_TYPE SearchType
,
2026 IN UINTN SearchInstance
,
2027 IN EFI_PEI_FILE_HANDLE FileHandle
,
2028 OUT VOID
**SectionData
,
2029 OUT UINT32
*AuthenticationStatus
2033 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
2035 EFI_COMMON_SECTION_HEADER
*Section
;
2036 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
2037 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
2039 UINT32 ExtractedAuthenticationStatus
;
2041 if (SectionData
== NULL
) {
2042 return EFI_NOT_FOUND
;
2045 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
2048 // Retrieve the FirmwareVolume which the file resides in.
2050 CoreFvHandle
= FileHandleToVolume (FileHandle
);
2051 if (CoreFvHandle
== NULL
) {
2052 return EFI_NOT_FOUND
;
2055 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
2057 if (IS_FFS_FILE2 (FfsFileHeader
)) {
2058 ASSERT (FFS_FILE2_SIZE (FfsFileHeader
) > 0x00FFFFFF);
2059 if (!FwVolInstance
->IsFfs3Fv
) {
2060 DEBUG ((DEBUG_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
2061 return EFI_NOT_FOUND
;
2064 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
2065 FileSize
= FFS_FILE2_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
2067 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
2068 FileSize
= FFS_FILE_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
2071 Instance
= SearchInstance
+ 1;
2072 ExtractedAuthenticationStatus
= 0;
2073 Status
= ProcessSection (
2074 GetPeiServicesTablePointer (),
2080 &ExtractedAuthenticationStatus
,
2081 FwVolInstance
->IsFfs3Fv
2083 if (!EFI_ERROR (Status
)) {
2085 // Inherit the authentication status.
2087 *AuthenticationStatus
= ExtractedAuthenticationStatus
| CoreFvHandle
->AuthenticationStatus
;
2094 Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.
2096 @param FvHandle The handle of a FV.
2098 @retval NULL if can not find.
2099 @return Pointer of corresponding PEI_CORE_FV_HANDLE.
2101 PEI_CORE_FV_HANDLE
*
2102 FvHandleToCoreHandle (
2103 IN EFI_PEI_FV_HANDLE FvHandle
2107 PEI_CORE_INSTANCE
*PrivateData
;
2109 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
2110 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
2111 if (FvHandle
== PrivateData
->Fv
[Index
].FvHandle
) {
2112 return &PrivateData
->Fv
[Index
];
2120 Gets a PEI_CORE_FV_HANDLE instance for the next volume according to the given index.
2122 This routine also will install an instance of the FvInfo PPI for the FV HOB
2123 as defined in the PI specification.
2125 @param Private Pointer of PEI_CORE_INSTANCE
2126 @param Instance Index of the FV to search
2128 @return Instance of PEI_CORE_FV_HANDLE.
2130 PEI_CORE_FV_HANDLE
*
2131 FindNextCoreFvHandle (
2132 IN PEI_CORE_INSTANCE
*Private
,
2136 if (Instance
>= Private
->FvCount
) {
2140 return &Private
->Fv
[Instance
];
2144 After PeiCore image is shadowed into permanent memory, all build-in FvPpi should
2145 be re-installed with the instance in permanent memory and all cached FvPpi pointers in
2146 PrivateData->Fv[] array should be fixed up to be pointed to the one in permanent
2149 @param PrivateData Pointer to PEI_CORE_INSTANCE.
2153 IN PEI_CORE_INSTANCE
*PrivateData
2157 EFI_PEI_PPI_DESCRIPTOR
*OldDescriptor
;
2162 // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
2165 Status
= PeiServicesLocatePpi (
2166 &gEfiFirmwareFileSystem2Guid
,
2171 ASSERT_EFI_ERROR (Status
);
2174 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
2175 // which is shadowed from flash to permanent memory within PeiCore image.
2177 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs2FvPpiList
);
2178 ASSERT_EFI_ERROR (Status
);
2181 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2183 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
2184 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2185 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs2FwVol
.Fv
;
2190 // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which
2193 Status
= PeiServicesLocatePpi (
2194 &gEfiFirmwareFileSystem3Guid
,
2199 ASSERT_EFI_ERROR (Status
);
2202 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3
2203 // which is shadowed from flash to permanent memory within PeiCore image.
2205 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs3FvPpiList
);
2206 ASSERT_EFI_ERROR (Status
);
2209 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2211 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
2212 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2213 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs3FwVol
.Fv
;
2219 Report the information for a newly discovered FV in an unknown format.
2221 If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for a third-party FV format, but
2222 the FV has been discovered, then the information of this FV will be cached into PEI_CORE_INSTANCE's
2223 UnknownFvInfo array.
2225 Also a notification would be installed for unknown FV format GUID, if EFI_PEI_FIRMWARE_VOLUME_PPI
2226 is installed later by platform's PEIM, the original unknown FV will be processed by
2227 using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2229 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2230 @param FvInfo2Ppi Point to FvInfo2 PPI.
2232 @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.
2233 @retval EFI_SUCCESS Success to add the information for unknown FV.
2236 AddUnknownFormatFvInfo (
2237 IN PEI_CORE_INSTANCE
*PrivateData
,
2238 IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
*FvInfo2Ppi
2241 PEI_CORE_UNKNOW_FORMAT_FV_INFO
*NewUnknownFv
;
2244 if (PrivateData
->UnknownFvInfoCount
>= PrivateData
->MaxUnknownFvInfoCount
) {
2246 // Run out of room, grow the buffer.
2248 TempPtr
= AllocateZeroPool (
2249 sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO
) * (PrivateData
->MaxUnknownFvInfoCount
+ FV_GROWTH_STEP
)
2251 ASSERT (TempPtr
!= NULL
);
2254 PrivateData
->UnknownFvInfo
,
2255 sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO
) * PrivateData
->MaxUnknownFvInfoCount
2257 PrivateData
->UnknownFvInfo
= TempPtr
;
2258 PrivateData
->MaxUnknownFvInfoCount
= PrivateData
->MaxUnknownFvInfoCount
+ FV_GROWTH_STEP
;
2261 NewUnknownFv
= &PrivateData
->UnknownFvInfo
[PrivateData
->UnknownFvInfoCount
];
2262 PrivateData
->UnknownFvInfoCount
++;
2264 CopyGuid (&NewUnknownFv
->FvFormat
, &FvInfo2Ppi
->FvFormat
);
2265 NewUnknownFv
->FvInfo
= FvInfo2Ppi
->FvInfo
;
2266 NewUnknownFv
->FvInfoSize
= FvInfo2Ppi
->FvInfoSize
;
2267 NewUnknownFv
->AuthenticationStatus
= FvInfo2Ppi
->AuthenticationStatus
;
2268 NewUnknownFv
->NotifyDescriptor
.Flags
= (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
);
2269 NewUnknownFv
->NotifyDescriptor
.Guid
= &NewUnknownFv
->FvFormat
;
2270 NewUnknownFv
->NotifyDescriptor
.Notify
= ThirdPartyFvPpiNotifyCallback
;
2272 PeiServicesNotifyPpi (&NewUnknownFv
->NotifyDescriptor
);
2277 Find the FV information according to third-party FV format GUID.
2279 This routine also will remove the FV information found by given FV format GUID from
2280 PrivateData->UnknownFvInfo[].
2282 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2283 @param Format Point to given FV format GUID
2284 @param FvInfo On return, the pointer of FV information buffer
2285 @param FvInfoSize On return, the size of FV information buffer.
2286 @param AuthenticationStatus On return, the authentication status of FV information buffer.
2288 @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI
2289 @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2292 FindUnknownFormatFvInfo (
2293 IN PEI_CORE_INSTANCE
*PrivateData
,
2294 IN EFI_GUID
*Format
,
2296 OUT UINT32
*FvInfoSize
,
2297 OUT UINT32
*AuthenticationStatus
2304 for ( ; Index
< PrivateData
->UnknownFvInfoCount
; Index
++) {
2305 if (CompareGuid (Format
, &PrivateData
->UnknownFvInfo
[Index
].FvFormat
)) {
2310 if (Index
== PrivateData
->UnknownFvInfoCount
) {
2311 return EFI_NOT_FOUND
;
2314 *FvInfo
= PrivateData
->UnknownFvInfo
[Index
].FvInfo
;
2315 *FvInfoSize
= PrivateData
->UnknownFvInfo
[Index
].FvInfoSize
;
2316 *AuthenticationStatus
= PrivateData
->UnknownFvInfo
[Index
].AuthenticationStatus
;
2319 // Remove an entry from UnknownFvInfo array.
2322 for ( ; Index2
< PrivateData
->UnknownFvInfoCount
; Index2
++, Index
++) {
2323 CopyMem (&PrivateData
->UnknownFvInfo
[Index
], &PrivateData
->UnknownFvInfo
[Index2
], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO
));
2326 PrivateData
->UnknownFvInfoCount
--;
2331 Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.
2333 When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this
2334 routine is called to process all discovered FVs in this format.
2336 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
2337 @param NotifyDescriptor Address of the notification descriptor data structure.
2338 @param Ppi Address of the PPI that was installed.
2340 @retval EFI_SUCCESS The notification callback is processed correctly.
2344 ThirdPartyFvPpiNotifyCallback (
2345 IN EFI_PEI_SERVICES
**PeiServices
,
2346 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
2350 PEI_CORE_INSTANCE
*PrivateData
;
2351 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
2354 UINT32 AuthenticationStatus
;
2356 EFI_PEI_FV_HANDLE FvHandle
;
2357 BOOLEAN IsProcessed
;
2359 EFI_PEI_FILE_HANDLE FileHandle
;
2364 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
2365 FvPpi
= (EFI_PEI_FIRMWARE_VOLUME_PPI
*)Ppi
;
2368 Status
= FindUnknownFormatFvInfo (PrivateData
, NotifyDescriptor
->Guid
, &FvInfo
, &FvInfoSize
, &AuthenticationStatus
);
2369 if (EFI_ERROR (Status
)) {
2374 // Process new found FV and get FV handle.
2376 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo
, FvInfoSize
, &FvHandle
);
2377 if (EFI_ERROR (Status
)) {
2378 DEBUG ((DEBUG_ERROR
, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo
));
2383 // Check whether the FV has already been processed.
2385 IsProcessed
= FALSE
;
2386 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
2387 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
2388 DEBUG ((DEBUG_INFO
, "The FV %p has already been processed!\n", FvInfo
));
2398 if (PrivateData
->FvCount
>= PrivateData
->MaxFvCount
) {
2400 // Run out of room, grow the buffer.
2402 TempPtr
= AllocateZeroPool (
2403 sizeof (PEI_CORE_FV_HANDLE
) * (PrivateData
->MaxFvCount
+ FV_GROWTH_STEP
)
2405 ASSERT (TempPtr
!= NULL
);
2409 sizeof (PEI_CORE_FV_HANDLE
) * PrivateData
->MaxFvCount
2411 PrivateData
->Fv
= TempPtr
;
2412 PrivateData
->MaxFvCount
= PrivateData
->MaxFvCount
+ FV_GROWTH_STEP
;
2416 // Update internal PEI_CORE_FV array.
2418 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)FvInfo
;
2419 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
2420 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
2421 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= AuthenticationStatus
;
2422 CurFvCount
= PrivateData
->FvCount
;
2425 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
2431 PrivateData
->FvCount
++;
2434 // Scan and process the new discovered FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
2438 Status
= FvPpi
->FindFileByType (
2440 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
2444 if (!EFI_ERROR (Status
)) {
2445 Status
= FvPpi
->FindSectionByType (
2447 EFI_SECTION_PEI_DEPEX
,
2451 if (!EFI_ERROR (Status
)) {
2452 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
2454 // Dependency is not satisfied.
2460 DEBUG ((DEBUG_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, CurFvCount
, FvHandle
));
2461 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[CurFvCount
], FileHandle
);
2463 } while (FileHandle
!= NULL
);