2 Pei Core Firmware File System service routines.
4 Copyright (c) 2015 HP Development Company, L.P.
5 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList
[] = {
20 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
21 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
22 FirmwareVolmeInfoPpiNotifyCallback
25 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
26 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
27 FirmwareVolmeInfoPpiNotifyCallback
31 PEI_FW_VOL_INSTANCE mPeiFfs2FwVol
= {
35 PeiFfsFvPpiProcessVolume
,
36 PeiFfsFvPpiFindFileByType
,
37 PeiFfsFvPpiFindFileByName
,
38 PeiFfsFvPpiGetFileInfo
,
39 PeiFfsFvPpiGetVolumeInfo
,
40 PeiFfsFvPpiFindSectionByType
,
41 PeiFfsFvPpiGetFileInfo2
,
42 PeiFfsFvPpiFindSectionByType2
,
43 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
,
44 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
48 PEI_FW_VOL_INSTANCE mPeiFfs3FwVol
= {
52 PeiFfsFvPpiProcessVolume
,
53 PeiFfsFvPpiFindFileByType
,
54 PeiFfsFvPpiFindFileByName
,
55 PeiFfsFvPpiGetFileInfo
,
56 PeiFfsFvPpiGetVolumeInfo
,
57 PeiFfsFvPpiFindSectionByType
,
58 PeiFfsFvPpiGetFileInfo2
,
59 PeiFfsFvPpiFindSectionByType2
,
60 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
,
61 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
65 EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList
= {
66 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
67 &gEfiFirmwareFileSystem2Guid
,
71 EFI_PEI_PPI_DESCRIPTOR mPeiFfs3FvPpiList
= {
72 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
73 &gEfiFirmwareFileSystem3Guid
,
78 Required Alignment Alignment Value in FFS FFS_ATTRIB_DATA_ALIGNMENT2 Alignment Value in
79 (bytes) Attributes Field in FFS Attributes Field Firmware Volume Interfaces
97 UINT8 mFvAttributes
[] = {0, 4, 7, 9, 10, 12, 15, 16};
98 UINT8 mFvAttributes2
[] = {17, 18, 19, 20, 21, 22, 23, 24};
101 Convert the FFS File Attributes to FV File Attributes
103 @param FfsAttributes The attributes of UINT8 type.
105 @return The attributes of EFI_FV_FILE_ATTRIBUTES
108 EFI_FV_FILE_ATTRIBUTES
109 FfsAttributes2FvFileAttributes (
110 IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
114 EFI_FV_FILE_ATTRIBUTES FileAttribute
;
116 DataAlignment
= (UINT8
) ((FfsAttributes
& FFS_ATTRIB_DATA_ALIGNMENT
) >> 3);
117 ASSERT (DataAlignment
< 8);
119 if ((FfsAttributes
& FFS_ATTRIB_DATA_ALIGNMENT_2
) != 0) {
120 FileAttribute
= (EFI_FV_FILE_ATTRIBUTES
) mFvAttributes2
[DataAlignment
];
122 FileAttribute
= (EFI_FV_FILE_ATTRIBUTES
) mFvAttributes
[DataAlignment
];
125 if ((FfsAttributes
& FFS_ATTRIB_FIXED
) == FFS_ATTRIB_FIXED
) {
126 FileAttribute
|= EFI_FV_FILE_ATTRIB_FIXED
;
129 return FileAttribute
;
133 Returns the file state set by the highest zero bit in the State field
135 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
136 in the Attributes field.
137 @param FfsHeader Pointer to FFS File Header.
139 @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit
140 in the header State field.
144 IN UINT8 ErasePolarity
,
145 IN EFI_FFS_FILE_HEADER
*FfsHeader
148 EFI_FFS_FILE_STATE FileState
;
149 EFI_FFS_FILE_STATE HighestBit
;
151 FileState
= FfsHeader
->State
;
153 if (ErasePolarity
!= 0) {
154 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
158 // Get file state set by its highest none zero bit.
161 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
169 Calculates the checksum of the header of a file.
171 @param FileHeader Pointer to FFS File Header.
173 @return Checksum of the header.
174 Zero means the header is good.
175 Non-zero means the header is bad.
178 CalculateHeaderChecksum (
179 IN EFI_FFS_FILE_HEADER
*FileHeader
182 EFI_FFS_FILE_HEADER2 TestFileHeader
;
184 if (IS_FFS_FILE2 (FileHeader
)) {
185 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER2
));
187 // Ingore State and File field in FFS header.
189 TestFileHeader
.State
= 0;
190 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
192 return CalculateSum8 ((CONST UINT8
*) &TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER2
));
194 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
196 // Ingore State and File field in FFS header.
198 TestFileHeader
.State
= 0;
199 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
201 return CalculateSum8 ((CONST UINT8
*) &TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
206 Find FV handler according to FileHandle in that FV.
208 @param FileHandle Handle of file image
210 @return Pointer to instance of PEI_CORE_FV_HANDLE.
214 IN EFI_PEI_FILE_HANDLE FileHandle
218 PEI_CORE_INSTANCE
*PrivateData
;
219 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
222 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
223 BestIndex
= PrivateData
->FvCount
;
226 // Find the best matched FV image that includes this FileHandle.
227 // FV may include the child FV, and they are in the same continuous space.
228 // If FileHandle is from the child FV, the updated logic can find its matched FV.
230 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
231 FwVolHeader
= PrivateData
->Fv
[Index
].FvHeader
;
232 if (((UINT64
) (UINTN
) FileHandle
> (UINT64
) (UINTN
) FwVolHeader
) && \
233 ((UINT64
) (UINTN
) FileHandle
<= ((UINT64
) (UINTN
) FwVolHeader
+ FwVolHeader
->FvLength
- 1))) {
234 if (BestIndex
== PrivateData
->FvCount
) {
237 if ((UINT64
) (UINTN
) PrivateData
->Fv
[BestIndex
].FvHeader
< (UINT64
) (UINTN
) FwVolHeader
) {
244 if (BestIndex
< PrivateData
->FvCount
) {
245 return &PrivateData
->Fv
[BestIndex
];
252 Given the input file pointer, search for the first matching file in the
253 FFS volume as defined by SearchType. The search starts from FileHeader inside
254 the Firmware Volume defined by FwVolHeader.
255 If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.
256 If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
257 the first PEIM, or COMBINED PEIM or FV file type FFS file will return.
259 @param FvHandle Pointer to the FV header of the volume to search
260 @param FileName File name
261 @param SearchType Filter to find only files of this type.
262 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
263 @param FileHandle This parameter must point to a valid FFS volume.
264 @param AprioriFile Pointer to AprioriFile image in this FV if has
266 @return EFI_NOT_FOUND No files matching the search criteria were found
267 @retval EFI_SUCCESS Success to search given file
272 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
273 IN CONST EFI_GUID
*FileName
, OPTIONAL
274 IN EFI_FV_FILETYPE SearchType
,
275 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
,
276 IN OUT EFI_PEI_FILE_HANDLE
*AprioriFile OPTIONAL
279 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
280 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExtHeader
;
281 EFI_FFS_FILE_HEADER
**FileHeader
;
282 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
284 UINT32 FileOccupiedSize
;
293 // Convert the handle of FV to FV header for memory-mapped firmware volume
295 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvHandle
;
296 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
298 IsFfs3Fv
= CompareGuid (&FwVolHeader
->FileSystemGuid
, &gEfiFirmwareFileSystem3Guid
);
300 FvLength
= FwVolHeader
->FvLength
;
301 if ((FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
308 // If FileHeader is not specified (NULL) or FileName is not NULL,
309 // start with the first file in the firmware volume. Otherwise,
310 // start from the FileHeader.
312 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
313 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
315 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
317 FwVolExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) ((UINT8
*) FwVolHeader
+ FwVolHeader
->ExtHeaderOffset
);
318 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FwVolExtHeader
+ FwVolExtHeader
->ExtHeaderSize
);
319 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ALIGN_POINTER (FfsFileHeader
, 8);
321 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*) FwVolHeader
+ FwVolHeader
->HeaderLength
);
324 if (IS_FFS_FILE2 (*FileHeader
)) {
326 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader
)->Name
));
328 FileLength
= FFS_FILE2_SIZE (*FileHeader
);
329 ASSERT (FileLength
> 0x00FFFFFF);
331 FileLength
= FFS_FILE_SIZE (*FileHeader
);
334 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
336 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
337 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
340 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
341 ASSERT (FileOffset
<= 0xFFFFFFFF);
343 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
345 // Get FileState which is the highest bit of the State
347 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
350 case EFI_FILE_HEADER_CONSTRUCTION
:
351 case EFI_FILE_HEADER_INVALID
:
352 if (IS_FFS_FILE2 (FfsFileHeader
)) {
354 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
356 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER2
);
357 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
359 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER
);
360 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
364 case EFI_FILE_DATA_VALID
:
365 case EFI_FILE_MARKED_FOR_UPDATE
:
366 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
369 return EFI_NOT_FOUND
;
372 if (IS_FFS_FILE2 (FfsFileHeader
)) {
373 FileLength
= FFS_FILE2_SIZE (FfsFileHeader
);
374 ASSERT (FileLength
> 0x00FFFFFF);
375 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
377 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
378 FileOffset
+= FileOccupiedSize
;
379 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ FileOccupiedSize
);
383 FileLength
= FFS_FILE_SIZE (FfsFileHeader
);
384 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
387 DataCheckSum
= FFS_FIXED_CHECKSUM
;
388 if ((FfsFileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) == FFS_ATTRIB_CHECKSUM
) {
389 if (IS_FFS_FILE2 (FfsFileHeader
)) {
390 DataCheckSum
= CalculateCheckSum8 ((CONST UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
), FileLength
- sizeof(EFI_FFS_FILE_HEADER2
));
392 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
= FfsFileHeader
;
420 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
421 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
422 *FileHeader
= FfsFileHeader
;
426 FileOffset
+= FileOccupiedSize
;
427 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
430 case EFI_FILE_DELETED
:
431 if (IS_FFS_FILE2 (FfsFileHeader
)) {
433 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
435 FileLength
= FFS_FILE2_SIZE (FfsFileHeader
);
436 ASSERT (FileLength
> 0x00FFFFFF);
438 FileLength
= FFS_FILE_SIZE (FfsFileHeader
);
440 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
441 FileOffset
+= FileOccupiedSize
;
442 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
447 return EFI_NOT_FOUND
;
452 return EFI_NOT_FOUND
;
456 Initialize PeiCore Fv List.
458 @param PrivateData - Pointer to PEI_CORE_INSTANCE.
459 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
463 IN PEI_CORE_INSTANCE
*PrivateData
,
464 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
468 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
469 EFI_PEI_FV_HANDLE FvHandle
;
470 EFI_FIRMWARE_VOLUME_HEADER
*BfvHeader
;
473 // Install FV_PPI for FFS2 file system.
475 PeiServicesInstallPpi (&mPeiFfs2FvPpiList
);
478 // Install FV_PPI for FFS3 file system.
480 PeiServicesInstallPpi (&mPeiFfs3FvPpiList
);
482 BfvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
485 // The FV_PPI in BFV's format should be installed.
487 Status
= PeiServicesLocatePpi (
488 &BfvHeader
->FileSystemGuid
,
493 ASSERT_EFI_ERROR (Status
);
498 FvPpi
->ProcessVolume (
500 SecCoreData
->BootFirmwareVolumeBase
,
501 (UINTN
)BfvHeader
->FvLength
,
506 // Update internal PEI_CORE_FV array.
508 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= BfvHeader
;
509 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
510 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
511 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= 0;
514 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
515 (UINT32
) PrivateData
->FvCount
,
520 PrivateData
->FvCount
++;
523 // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose
524 // additional Fvs to PeiCore.
526 Status
= PeiServicesNotifyPpi (mNotifyOnFvInfoList
);
527 ASSERT_EFI_ERROR (Status
);
532 Process Firmware Volum Information once FvInfoPPI or FvInfo2PPI install.
533 The FV Info will be registered into PeiCore private data structure.
534 And search the inside FV image, if found, the new FV INFO(2) PPI will be installed.
536 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
537 @param NotifyDescriptor Address of the notification descriptor data structure.
538 @param Ppi Address of the PPI that was installed.
540 @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.
541 @return if not EFI_SUCESS, fail to verify FV.
546 FirmwareVolmeInfoPpiNotifyCallback (
547 IN EFI_PEI_SERVICES
**PeiServices
,
548 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
552 EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI FvInfo2Ppi
;
553 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
554 PEI_CORE_INSTANCE
*PrivateData
;
556 EFI_PEI_FV_HANDLE FvHandle
;
558 EFI_PEI_FILE_HANDLE FileHandle
;
563 Status
= EFI_SUCCESS
;
564 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
566 if (CompareGuid (NotifyDescriptor
->Guid
, &gEfiPeiFirmwareVolumeInfo2PpiGuid
)) {
570 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
));
576 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
));
577 FvInfo2Ppi
.AuthenticationStatus
= 0;
581 if (CompareGuid (&FvInfo2Ppi
.FvFormat
, &gEfiFirmwareFileSystem2Guid
)) {
583 // gEfiFirmwareFileSystem2Guid is specified for FvFormat, then here to check the
584 // FileSystemGuid pointed by FvInfo against gEfiFirmwareFileSystem2Guid to make sure
585 // FvInfo has the firmware file system 2 format.
587 // If the ASSERT really appears, FvFormat needs to be specified correctly, for example,
588 // gEfiFirmwareFileSystem3Guid can be used for firmware file system 3 format, or
589 // ((EFI_FIRMWARE_VOLUME_HEADER *) FvInfo)->FileSystemGuid can be just used for both
590 // firmware file system 2 and 3 format.
592 ASSERT (CompareGuid (&(((EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo2Ppi
.FvInfo
)->FileSystemGuid
), &gEfiFirmwareFileSystem2Guid
));
596 // Locate the corresponding FV_PPI according to founded FV's format guid
598 Status
= PeiServicesLocatePpi (
599 &FvInfo2Ppi
.FvFormat
,
604 if (!EFI_ERROR (Status
)) {
606 // Process new found FV and get FV handle.
608 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo2Ppi
.FvInfo
, FvInfo2Ppi
.FvInfoSize
, &FvHandle
);
609 if (EFI_ERROR (Status
)) {
610 DEBUG ((EFI_D_ERROR
, "Fail to process new found FV, FV may be corrupted!\n"));
615 // Check whether the FV has already been processed.
617 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
618 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
619 if (IsFvInfo2
&& (FvInfo2Ppi
.AuthenticationStatus
!= PrivateData
->Fv
[FvIndex
].AuthenticationStatus
)) {
620 PrivateData
->Fv
[FvIndex
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
621 DEBUG ((EFI_D_INFO
, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex
, FvInfo2Ppi
.AuthenticationStatus
));
623 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfo2Ppi
.FvInfo
));
628 if (PrivateData
->FvCount
>= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
629 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, PcdGet32 (PcdPeiCoreMaxFvSupported
)));
630 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
635 // Update internal PEI_CORE_FV array.
637 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo2Ppi
.FvInfo
;
638 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
639 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
640 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
641 CurFvCount
= PrivateData
->FvCount
;
644 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
646 (VOID
*) FvInfo2Ppi
.FvInfo
,
647 FvInfo2Ppi
.FvInfoSize
,
650 PrivateData
->FvCount
++;
653 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
657 Status
= FvPpi
->FindFileByType (
659 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
663 if (!EFI_ERROR (Status
)) {
664 Status
= FvPpi
->FindSectionByType (
666 EFI_SECTION_PEI_DEPEX
,
670 if (!EFI_ERROR (Status
)) {
671 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
673 // Dependency is not satisfied.
679 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, CurFvCount
, FvHandle
));
680 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[CurFvCount
], FileHandle
);
682 } while (FileHandle
!= NULL
);
684 DEBUG ((EFI_D_ERROR
, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi
.FvInfo
));
686 AddUnknownFormatFvInfo (PrivateData
, &FvInfo2Ppi
);
693 Verify the Guided Section GUID by checking if there is the Guided Section GUID HOB recorded the GUID itself.
695 @param GuidedSectionGuid The Guided Section GUID.
696 @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Ppi
697 for the Guided Section.
699 @return TRUE The GuidedSectionGuid could be identified, and the pointer to
700 the Guided Section Extraction Ppi will be returned to *GuidedSectionExtraction.
701 @return FALSE The GuidedSectionGuid could not be identified, or
702 the Guided Section Extraction Ppi has not been installed yet.
706 VerifyGuidedSectionGuid (
707 IN EFI_GUID
*GuidedSectionGuid
,
708 OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
**GuidedSectionExtraction
711 EFI_PEI_HOB_POINTERS Hob
;
712 EFI_GUID
*GuidRecorded
;
717 // Check if there is the Guided Section GUID HOB recorded the GUID itself.
719 Hob
.Raw
= GetFirstGuidHob (GuidedSectionGuid
);
720 if (Hob
.Raw
!= NULL
) {
721 GuidRecorded
= (EFI_GUID
*) GET_GUID_HOB_DATA (Hob
);
722 if (CompareGuid (GuidRecorded
, GuidedSectionGuid
)) {
724 // Found the recorded GuidedSectionGuid.
726 Status
= PeiServicesLocatePpi (GuidedSectionGuid
, 0, NULL
, (VOID
**) &Interface
);
727 if (!EFI_ERROR (Status
) && Interface
!= NULL
) {
729 // Found the supported Guided Section Extraction Ppi for the Guided Section.
731 *GuidedSectionExtraction
= (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*) Interface
;
742 Go through the file to search SectionType section.
743 Search within encapsulation sections (compression and GUIDed) recursively,
744 until the match section is found.
746 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
747 @param SectionType Filter to find only section of this type.
748 @param SectionInstance Pointer to the filter to find the specific instance of section.
749 @param Section From where to search.
750 @param SectionSize The file size to search.
751 @param OutputBuffer A pointer to the discovered section, if successful.
752 NULL if section not found
753 @param AuthenticationStatus Updated upon return to point to the authentication status for this section.
754 @param IsFfs3Fv Indicates the FV format.
756 @return EFI_NOT_FOUND The match section is not found.
757 @return EFI_SUCCESS The match section is found.
762 IN CONST EFI_PEI_SERVICES
**PeiServices
,
763 IN EFI_SECTION_TYPE SectionType
,
764 IN OUT UINTN
*SectionInstance
,
765 IN EFI_COMMON_SECTION_HEADER
*Section
,
766 IN UINTN SectionSize
,
767 OUT VOID
**OutputBuffer
,
768 OUT UINT32
*AuthenticationStatus
,
773 UINT32 SectionLength
;
775 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
776 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
780 UINT32 Authentication
;
781 PEI_CORE_INSTANCE
*PrivateData
;
782 EFI_GUID
*SectionDefinitionGuid
;
783 BOOLEAN SectionCached
;
784 VOID
*TempOutputBuffer
;
785 UINT32 TempAuthenticationStatus
;
786 UINT16 GuidedSectionAttributes
;
788 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
789 *OutputBuffer
= NULL
;
792 Status
= EFI_NOT_FOUND
;
795 while (ParsedLength
< SectionSize
) {
797 if (IS_SECTION2 (Section
)) {
798 ASSERT (SECTION2_SIZE (Section
) > 0x00FFFFFF);
800 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
801 SectionLength
= SECTION2_SIZE (Section
);
803 // SectionLength is adjusted it is 4 byte aligned.
804 // Go to the next section
806 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
807 ASSERT (SectionLength
!= 0);
808 ParsedLength
+= SectionLength
;
809 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ SectionLength
);
814 if (Section
->Type
== SectionType
) {
816 // The type matches, so check the instance count to see if it's the one we want.
818 (*SectionInstance
)--;
819 if (*SectionInstance
== 0) {
823 if (IS_SECTION2 (Section
)) {
824 *OutputBuffer
= (VOID
*)((UINT8
*) Section
+ sizeof (EFI_COMMON_SECTION_HEADER2
));
826 *OutputBuffer
= (VOID
*)((UINT8
*) Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
830 if (IS_SECTION2 (Section
)) {
831 SectionLength
= SECTION2_SIZE (Section
);
833 SectionLength
= SECTION_SIZE (Section
);
836 // SectionLength is adjusted it is 4 byte aligned.
837 // Go to the next section
839 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
840 ASSERT (SectionLength
!= 0);
841 ParsedLength
+= SectionLength
;
842 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
845 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
847 // Check the encapsulated section is extracted into the cache data.
849 SectionCached
= FALSE
;
850 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
851 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
852 SectionCached
= TRUE
;
853 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
854 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
855 Authentication
= PrivateData
->CacheSection
.AuthenticationStatus
[Index
];
857 // Search section directly from the cache data.
859 TempAuthenticationStatus
= 0;
860 Status
= ProcessSection (
867 &TempAuthenticationStatus
,
870 if (!EFI_ERROR (Status
)) {
871 *OutputBuffer
= TempOutputBuffer
;
872 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
879 // If SectionCached is TRUE, the section data has been cached and scanned.
881 if (!SectionCached
) {
882 Status
= EFI_NOT_FOUND
;
884 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
885 if (IS_SECTION2 (Section
)) {
886 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION2
*)Section
)->SectionDefinitionGuid
;
887 GuidedSectionAttributes
= ((EFI_GUID_DEFINED_SECTION2
*)Section
)->Attributes
;
889 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
;
890 GuidedSectionAttributes
= ((EFI_GUID_DEFINED_SECTION
*)Section
)->Attributes
;
892 if (VerifyGuidedSectionGuid (SectionDefinitionGuid
, &GuidSectionPpi
)) {
893 Status
= GuidSectionPpi
->ExtractSection (
900 } else if ((GuidedSectionAttributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
902 // Figure out the proper authentication status for GUIDED section without processing required
904 Status
= EFI_SUCCESS
;
905 if ((GuidedSectionAttributes
& EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) {
906 Authentication
|= EFI_AUTH_STATUS_IMAGE_SIGNED
| EFI_AUTH_STATUS_NOT_TESTED
;
908 if (IS_SECTION2 (Section
)) {
909 PpiOutputSize
= SECTION2_SIZE (Section
) - ((EFI_GUID_DEFINED_SECTION2
*) Section
)->DataOffset
;
910 PpiOutput
= (UINT8
*) Section
+ ((EFI_GUID_DEFINED_SECTION2
*) Section
)->DataOffset
;
912 PpiOutputSize
= SECTION_SIZE (Section
) - ((EFI_GUID_DEFINED_SECTION
*) Section
)->DataOffset
;
913 PpiOutput
= (UINT8
*) Section
+ ((EFI_GUID_DEFINED_SECTION
*) Section
)->DataOffset
;
916 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
917 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**) &DecompressPpi
);
918 if (!EFI_ERROR (Status
)) {
919 Status
= DecompressPpi
->Decompress (
921 (CONST EFI_COMPRESSION_SECTION
*) Section
,
928 if (!EFI_ERROR (Status
)) {
929 if ((Authentication
& EFI_AUTH_STATUS_NOT_TESTED
) == 0) {
931 // Update cache section data.
933 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
934 PrivateData
->CacheSection
.AllSectionCount
++;
936 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
937 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
938 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
939 PrivateData
->CacheSection
.AuthenticationStatus
[PrivateData
->CacheSection
.SectionIndex
] = Authentication
;
940 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
943 TempAuthenticationStatus
= 0;
944 Status
= ProcessSection (
951 &TempAuthenticationStatus
,
954 if (!EFI_ERROR (Status
)) {
955 *OutputBuffer
= TempOutputBuffer
;
956 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
963 if (IS_SECTION2 (Section
)) {
964 SectionLength
= SECTION2_SIZE (Section
);
966 SectionLength
= SECTION_SIZE (Section
);
969 // SectionLength is adjusted it is 4 byte aligned.
970 // Go to the next section
972 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
973 ASSERT (SectionLength
!= 0);
974 ParsedLength
+= SectionLength
;
975 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
978 return EFI_NOT_FOUND
;
983 Searches for the next matching section within the specified file.
985 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
986 @param SectionType Filter to find only sections of this type.
987 @param FileHandle Pointer to the current file to search.
988 @param SectionData A pointer to the discovered section, if successful.
989 NULL if section not found
991 @retval EFI_NOT_FOUND The section was not found.
992 @retval EFI_SUCCESS The section was found.
997 PeiFfsFindSectionData (
998 IN CONST EFI_PEI_SERVICES
**PeiServices
,
999 IN EFI_SECTION_TYPE SectionType
,
1000 IN EFI_PEI_FILE_HANDLE FileHandle
,
1001 OUT VOID
**SectionData
1004 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1006 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1007 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1008 return EFI_NOT_FOUND
;
1011 return CoreFvHandle
->FvPpi
->FindSectionByType (CoreFvHandle
->FvPpi
, SectionType
, FileHandle
, SectionData
);
1015 Searches for the next matching section within the specified file.
1017 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
1018 @param SectionType The value of the section type to find.
1019 @param SectionInstance Section instance to find.
1020 @param FileHandle Handle of the firmware file to search.
1021 @param SectionData A pointer to the discovered section, if successful.
1022 @param AuthenticationStatus A pointer to the authentication status for this section.
1024 @retval EFI_SUCCESS The section was found.
1025 @retval EFI_NOT_FOUND The section was not found.
1030 PeiFfsFindSectionData3 (
1031 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1032 IN EFI_SECTION_TYPE SectionType
,
1033 IN UINTN SectionInstance
,
1034 IN EFI_PEI_FILE_HANDLE FileHandle
,
1035 OUT VOID
**SectionData
,
1036 OUT UINT32
*AuthenticationStatus
1039 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1041 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1042 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1043 return EFI_NOT_FOUND
;
1046 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1047 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1048 return CoreFvHandle
->FvPpi
->FindSectionByType2 (CoreFvHandle
->FvPpi
, SectionType
, SectionInstance
, FileHandle
, SectionData
, AuthenticationStatus
);
1051 // The old FvPpi doesn't support to find section by section instance
1052 // and return authentication status, so return EFI_UNSUPPORTED.
1054 return EFI_UNSUPPORTED
;
1058 Searches for the next matching file in the firmware volume.
1060 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
1061 @param SearchType Filter to find only files of this type.
1062 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
1063 @param FvHandle Handle of firmware volume in which to search.
1064 @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
1065 at the beginning of the firmware volume. On exit, points the file handle of the next file
1066 in the volume or NULL if there are no more files.
1068 @retval EFI_NOT_FOUND The file was not found.
1069 @retval EFI_NOT_FOUND The header checksum was not zero.
1070 @retval EFI_SUCCESS The file was found.
1075 PeiFfsFindNextFile (
1076 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1077 IN UINT8 SearchType
,
1078 IN EFI_PEI_FV_HANDLE FvHandle
,
1079 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1082 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1084 CoreFvHandle
= FvHandleToCoreHandle (FvHandle
);
1087 // To make backward compatiblity, if can not find corresponding the handle of FV
1088 // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed
1089 // to the address of first byte of FV.
1091 if ((CoreFvHandle
== NULL
) && FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
1092 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1095 if ((CoreFvHandle
== NULL
) || CoreFvHandle
->FvPpi
== NULL
) {
1096 return EFI_NOT_FOUND
;
1099 return CoreFvHandle
->FvPpi
->FindFileByType (CoreFvHandle
->FvPpi
, SearchType
, FvHandle
, FileHandle
);
1104 Search the firmware volumes by index
1106 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
1107 @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
1109 @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
1111 @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
1112 @retval EFI_NOT_FOUND The volume was not found.
1113 @retval EFI_SUCCESS The volume was found.
1118 PeiFfsFindNextVolume (
1119 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1121 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
1124 PEI_CORE_INSTANCE
*Private
;
1125 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1127 if (VolumeHandle
== NULL
) {
1128 return EFI_INVALID_PARAMETER
;
1131 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
1133 CoreFvHandle
= FindNextCoreFvHandle (Private
, Instance
);
1134 if (CoreFvHandle
== NULL
) {
1135 *VolumeHandle
= NULL
;
1136 return EFI_NOT_FOUND
;
1139 *VolumeHandle
= CoreFvHandle
->FvHandle
;
1146 Find a file within a volume by its name.
1148 @param FileName A pointer to the name of the file to find within the firmware volume.
1149 @param VolumeHandle The firmware volume to search
1150 @param FileHandle Upon exit, points to the found file's handle
1151 or NULL if it could not be found.
1153 @retval EFI_SUCCESS File was found.
1154 @retval EFI_NOT_FOUND File was not found.
1155 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
1160 PeiFfsFindFileByName (
1161 IN CONST EFI_GUID
*FileName
,
1162 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1163 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1166 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1168 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1169 return EFI_INVALID_PARAMETER
;
1172 CoreFvHandle
= FvHandleToCoreHandle (VolumeHandle
);
1173 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1174 return EFI_NOT_FOUND
;
1177 return CoreFvHandle
->FvPpi
->FindFileByName (CoreFvHandle
->FvPpi
, FileName
, &VolumeHandle
, FileHandle
);
1181 Returns information about a specific file.
1183 @param FileHandle Handle of the file.
1184 @param FileInfo Upon exit, points to the file's information.
1186 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1187 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1188 @retval EFI_SUCCESS File information returned.
1194 IN EFI_PEI_FILE_HANDLE FileHandle
,
1195 OUT EFI_FV_FILE_INFO
*FileInfo
1198 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1200 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1201 return EFI_INVALID_PARAMETER
;
1205 // Retrieve the FirmwareVolume which the file resides in.
1207 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1208 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1209 return EFI_INVALID_PARAMETER
;
1212 return CoreFvHandle
->FvPpi
->GetFileInfo (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1216 Returns information about a specific file.
1218 @param FileHandle Handle of the file.
1219 @param FileInfo Upon exit, points to the file's information.
1221 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1222 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1223 @retval EFI_SUCCESS File information returned.
1228 PeiFfsGetFileInfo2 (
1229 IN EFI_PEI_FILE_HANDLE FileHandle
,
1230 OUT EFI_FV_FILE_INFO2
*FileInfo
1233 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1235 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1236 return EFI_INVALID_PARAMETER
;
1240 // Retrieve the FirmwareVolume which the file resides in.
1242 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1243 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1244 return EFI_INVALID_PARAMETER
;
1247 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1248 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1249 return CoreFvHandle
->FvPpi
->GetFileInfo2 (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1252 // The old FvPpi doesn't support to return file info with authentication status,
1253 // so return EFI_UNSUPPORTED.
1255 return EFI_UNSUPPORTED
;
1259 Returns information about the specified volume.
1261 This function returns information about a specific firmware
1262 volume, including its name, type, attributes, starting address
1265 @param VolumeHandle Handle of the volume.
1266 @param VolumeInfo Upon exit, points to the volume's information.
1268 @retval EFI_SUCCESS Volume information returned.
1269 @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
1270 @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
1271 @retval EFI_SUCCESS Information successfully returned.
1272 @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
1277 PeiFfsGetVolumeInfo (
1278 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1279 OUT EFI_FV_INFO
*VolumeInfo
1282 PEI_CORE_FV_HANDLE
*CoreHandle
;
1284 if ((VolumeInfo
== NULL
) || (VolumeHandle
== NULL
)) {
1285 return EFI_INVALID_PARAMETER
;
1288 CoreHandle
= FvHandleToCoreHandle (VolumeHandle
);
1290 if ((CoreHandle
== NULL
) || (CoreHandle
->FvPpi
== NULL
)) {
1291 return EFI_INVALID_PARAMETER
;
1294 return CoreHandle
->FvPpi
->GetVolumeInfo (CoreHandle
->FvPpi
, VolumeHandle
, VolumeInfo
);
1298 Find USED_SIZE FV_EXT_TYPE entry in FV extension header and get the FV used size.
1300 @param[in] FvHeader Pointer to FV header.
1301 @param[out] FvUsedSize Pointer to FV used size returned,
1302 only valid if USED_SIZE FV_EXT_TYPE entry is found.
1303 @param[out] EraseByte Pointer to erase byte returned,
1304 only valid if USED_SIZE FV_EXT_TYPE entry is found.
1306 @retval TRUE USED_SIZE FV_EXT_TYPE entry is found,
1307 FV used size and erase byte are returned.
1308 @retval FALSE No USED_SIZE FV_EXT_TYPE entry found.
1313 IN EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
,
1314 OUT UINT32
*FvUsedSize
,
1315 OUT UINT8
*EraseByte
1318 UINT16 ExtHeaderOffset
;
1319 EFI_FIRMWARE_VOLUME_EXT_HEADER
*ExtHeader
;
1320 EFI_FIRMWARE_VOLUME_EXT_ENTRY
*ExtEntryList
;
1321 EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE
*ExtEntryUsedSize
;
1323 ExtHeaderOffset
= ReadUnaligned16 (&FvHeader
->ExtHeaderOffset
);
1324 if (ExtHeaderOffset
!= 0) {
1325 ExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) ((UINT8
*) FvHeader
+ ExtHeaderOffset
);
1326 ExtEntryList
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY
*) (ExtHeader
+ 1);
1327 while ((UINTN
) ExtEntryList
< ((UINTN
) ExtHeader
+ ReadUnaligned32 (&ExtHeader
->ExtHeaderSize
))) {
1328 if (ReadUnaligned16 (&ExtEntryList
->ExtEntryType
) == EFI_FV_EXT_TYPE_USED_SIZE_TYPE
) {
1330 // USED_SIZE FV_EXT_TYPE entry is found.
1332 ExtEntryUsedSize
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE
*) ExtEntryList
;
1333 *FvUsedSize
= ReadUnaligned32 (&ExtEntryUsedSize
->UsedSize
);
1334 if ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_ERASE_POLARITY
) != 0) {
1341 "FV at 0x%x has 0x%x used size, and erase byte is 0x%02x\n",
1348 ExtEntryList
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY
*)
1349 ((UINT8
*) ExtEntryList
+ ReadUnaligned16 (&ExtEntryList
->ExtEntrySize
));
1354 // No USED_SIZE FV_EXT_TYPE entry found.
1360 Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob.
1362 @param PrivateData PeiCore's private data structure
1363 @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.
1364 @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image.
1366 @retval EFI_NOT_FOUND FV image can't be found.
1367 @retval EFI_SUCCESS Successfully to process it.
1368 @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image
1369 @retval EFI_SECURITY_VIOLATION Image is illegal
1370 @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section
1375 IN PEI_CORE_INSTANCE
*PrivateData
,
1376 IN PEI_CORE_FV_HANDLE
*ParentFvCoreHandle
,
1377 IN EFI_PEI_FILE_HANDLE ParentFvFileHandle
1381 EFI_FV_INFO ParentFvImageInfo
;
1384 EFI_PEI_HOB_POINTERS HobPtr
;
1385 EFI_PEI_FIRMWARE_VOLUME_PPI
*ParentFvPpi
;
1386 EFI_PEI_FV_HANDLE ParentFvHandle
;
1387 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
1388 EFI_FV_FILE_INFO FileInfo
;
1390 UINT32 AuthenticationStatus
;
1395 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1398 HobPtr
.Raw
= GetHobList ();
1399 while ((HobPtr
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobPtr
.Raw
)) != NULL
) {
1400 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)ParentFvFileHandle
)->Name
), &HobPtr
.FirmwareVolume2
->FileName
)) {
1402 // this FILE has been dispatched, it will not be dispatched again.
1404 DEBUG ((EFI_D_INFO
, "FV file %p has been dispatched!\r\n", ParentFvFileHandle
));
1407 HobPtr
.Raw
= GET_NEXT_HOB (HobPtr
);
1410 ParentFvHandle
= ParentFvCoreHandle
->FvHandle
;
1411 ParentFvPpi
= ParentFvCoreHandle
->FvPpi
;
1414 // Find FvImage in FvFile
1416 AuthenticationStatus
= 0;
1417 if ((ParentFvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1418 (ParentFvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1419 Status
= ParentFvPpi
->FindSectionByType2 (
1421 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1425 &AuthenticationStatus
1428 Status
= ParentFvPpi
->FindSectionByType (
1430 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1435 if (EFI_ERROR (Status
)) {
1439 Status
= VerifyPeim (PrivateData
, ParentFvHandle
, ParentFvFileHandle
, AuthenticationStatus
);
1440 if (Status
== EFI_SECURITY_VIOLATION
) {
1445 // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
1446 // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
1447 // its initial linked location and maintain its alignment.
1449 if ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_WEAK_ALIGNMENT
) != EFI_FVB2_WEAK_ALIGNMENT
) {
1451 // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
1453 FvAlignment
= 1 << ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_ALIGNMENT
) >> 16);
1454 if (FvAlignment
< 8) {
1460 "%a() FV at 0x%x, FvAlignment required is 0x%x\n",
1467 // Check FvImage alignment.
1469 if ((UINTN
) FvHeader
% FvAlignment
!= 0) {
1470 FvLength
= ReadUnaligned64 (&FvHeader
->FvLength
);
1471 NewFvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvLength
), FvAlignment
);
1472 if (NewFvBuffer
== NULL
) {
1473 return EFI_OUT_OF_RESOURCES
;
1475 if (GetFvUsedSize (FvHeader
, &FvUsedSize
, &EraseByte
)) {
1477 // Copy the used bytes and fill the rest with the erase value.
1479 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
) FvUsedSize
);
1481 (UINT8
*) NewFvBuffer
+ FvUsedSize
,
1482 (UINTN
) (FvLength
- FvUsedSize
),
1486 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
) FvLength
);
1488 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) NewFvBuffer
;
1492 Status
= ParentFvPpi
->GetVolumeInfo (ParentFvPpi
, ParentFvHandle
, &ParentFvImageInfo
);
1493 ASSERT_EFI_ERROR (Status
);
1495 Status
= ParentFvPpi
->GetFileInfo (ParentFvPpi
, ParentFvFileHandle
, &FileInfo
);
1496 ASSERT_EFI_ERROR (Status
);
1499 // Install FvInfo(2) Ppi
1500 // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated
1501 // FVs inherit the proper AuthenticationStatus.
1503 PeiServicesInstallFvInfo2Ppi(
1504 &FvHeader
->FileSystemGuid
,
1506 (UINT32
)FvHeader
->FvLength
,
1507 &ParentFvImageInfo
.FvName
,
1509 AuthenticationStatus
1512 PeiServicesInstallFvInfoPpi (
1513 &FvHeader
->FileSystemGuid
,
1515 (UINT32
) FvHeader
->FvLength
,
1516 &ParentFvImageInfo
.FvName
,
1521 // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase
1524 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1529 // Makes the encapsulated volume show up in DXE phase to skip processing of
1530 // encapsulated file again.
1533 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1535 &ParentFvImageInfo
.FvName
,
1540 // Build FV3 HOB with authentication status to be propagated to DXE.
1543 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1545 AuthenticationStatus
,
1547 &ParentFvImageInfo
.FvName
,
1555 Process a firmware volume and create a volume handle.
1557 Create a volume handle from the information in the buffer. For
1558 memory-mapped firmware volumes, Buffer and BufferSize refer to
1559 the start of the firmware volume and the firmware volume size.
1560 For non memory-mapped firmware volumes, this points to a
1561 buffer which contains the necessary information for creating
1562 the firmware volume handle. Normally, these values are derived
1563 from the EFI_FIRMWARE_VOLUME_INFO_PPI.
1566 @param This Points to this instance of the
1567 EFI_PEI_FIRMWARE_VOLUME_PPI.
1568 @param Buffer Points to the start of the buffer.
1569 @param BufferSize Size of the buffer.
1570 @param FvHandle Points to the returned firmware volume
1571 handle. The firmware volume handle must
1572 be unique within the system.
1574 @retval EFI_SUCCESS Firmware volume handle created.
1575 @retval EFI_VOLUME_CORRUPTED Volume was corrupt.
1580 PeiFfsFvPpiProcessVolume (
1581 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1583 IN UINTN BufferSize
,
1584 OUT EFI_PEI_FV_HANDLE
*FvHandle
1589 ASSERT (FvHandle
!= NULL
);
1591 if (Buffer
== NULL
) {
1592 return EFI_VOLUME_CORRUPTED
;
1596 // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped
1597 // FV image and the handle is pointed to Fv image's buffer.
1599 *FvHandle
= (EFI_PEI_FV_HANDLE
) Buffer
;
1602 // Do verify for given FV buffer.
1604 Status
= VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER
*) Buffer
);
1605 if (EFI_ERROR(Status
)) {
1606 DEBUG ((EFI_D_ERROR
, "Fail to verify FV which address is 0x%11p", Buffer
));
1607 return EFI_VOLUME_CORRUPTED
;
1614 Finds the next file of the specified type.
1616 This service enables PEI modules to discover additional firmware files.
1617 The FileHandle must be unique within the system.
1619 @param This Points to this instance of the
1620 EFI_PEI_FIRMWARE_VOLUME_PPI.
1621 @param SearchType A filter to find only files of this type. Type
1622 EFI_FV_FILETYPE_ALL causes no filtering to be
1624 @param FvHandle Handle of firmware volume in which to
1626 @param FileHandle Points to the current handle from which to
1627 begin searching or NULL to start at the
1628 beginning of the firmware volume. Updated
1629 upon return to reflect the file found.
1631 @retval EFI_SUCCESS The file was found.
1632 @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.
1637 PeiFfsFvPpiFindFileByType (
1638 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1639 IN EFI_FV_FILETYPE SearchType
,
1640 IN EFI_PEI_FV_HANDLE FvHandle
,
1641 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1644 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1648 Find a file within a volume by its name.
1650 This service searches for files with a specific name, within
1651 either the specified firmware volume or all firmware volumes.
1653 @param This Points to this instance of the
1654 EFI_PEI_FIRMWARE_VOLUME_PPI.
1655 @param FileName A pointer to the name of the file to find
1656 within the firmware volume.
1657 @param FvHandle Upon entry, the pointer to the firmware
1658 volume to search or NULL if all firmware
1659 volumes should be searched. Upon exit, the
1660 actual firmware volume in which the file was
1662 @param FileHandle Upon exit, points to the found file's
1663 handle or NULL if it could not be found.
1665 @retval EFI_SUCCESS File was found.
1666 @retval EFI_NOT_FOUND File was not found.
1667 @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or
1674 PeiFfsFvPpiFindFileByName (
1675 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1676 IN CONST EFI_GUID
*FileName
,
1677 IN EFI_PEI_FV_HANDLE
*FvHandle
,
1678 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1682 PEI_CORE_INSTANCE
*PrivateData
;
1685 if ((FvHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1686 return EFI_INVALID_PARAMETER
;
1689 if (*FvHandle
!= NULL
) {
1690 Status
= FindFileEx (*FvHandle
, FileName
, 0, FileHandle
, NULL
);
1691 if (Status
== EFI_NOT_FOUND
) {
1696 // If *FvHandle = NULL, so search all FV for given filename
1698 Status
= EFI_NOT_FOUND
;
1700 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
1701 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1703 // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
1705 if (PrivateData
->Fv
[Index
].FvPpi
!= NULL
) {
1706 Status
= FindFileEx (PrivateData
->Fv
[Index
].FvHandle
, FileName
, 0, FileHandle
, NULL
);
1707 if (!EFI_ERROR (Status
)) {
1708 *FvHandle
= PrivateData
->Fv
[Index
].FvHandle
;
1719 Returns information about a specific file.
1721 This function returns information about a specific
1722 file, including its file name, type, attributes, starting
1725 @param This Points to this instance of the
1726 EFI_PEI_FIRMWARE_VOLUME_PPI.
1727 @param FileHandle Handle of the file.
1728 @param FileInfo Upon exit, points to the file's
1731 @retval EFI_SUCCESS File information returned.
1732 @retval EFI_INVALID_PARAMETER If FileHandle does not
1733 represent a valid file.
1734 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1739 PeiFfsFvPpiGetFileInfo (
1740 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1741 IN EFI_PEI_FILE_HANDLE FileHandle
,
1742 OUT EFI_FV_FILE_INFO
*FileInfo
1746 UINT8 ErasePolarity
;
1747 EFI_FFS_FILE_HEADER
*FileHeader
;
1748 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1749 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1751 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1752 return EFI_INVALID_PARAMETER
;
1756 // Retrieve the FirmwareVolume which the file resides in.
1758 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1759 if (CoreFvHandle
== NULL
) {
1760 return EFI_INVALID_PARAMETER
;
1763 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1765 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
1772 // Get FileState which is the highest bit of the State
1774 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
1776 switch (FileState
) {
1777 case EFI_FILE_DATA_VALID
:
1778 case EFI_FILE_MARKED_FOR_UPDATE
:
1781 return EFI_INVALID_PARAMETER
;
1784 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
1785 if (IS_FFS_FILE2 (FileHeader
)) {
1786 ASSERT (FFS_FILE2_SIZE (FileHeader
) > 0x00FFFFFF);
1787 if (!FwVolInstance
->IsFfs3Fv
) {
1788 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader
->Name
));
1789 return EFI_INVALID_PARAMETER
;
1791 FileInfo
->BufferSize
= FFS_FILE2_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
1792 FileInfo
->Buffer
= (UINT8
*) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
);
1794 FileInfo
->BufferSize
= FFS_FILE_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
1795 FileInfo
->Buffer
= (UINT8
*) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER
);
1797 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
1798 FileInfo
->FileType
= FileHeader
->Type
;
1799 FileInfo
->FileAttributes
= FfsAttributes2FvFileAttributes (FileHeader
->Attributes
);
1800 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_MEMORY_MAPPED
) == EFI_FVB2_MEMORY_MAPPED
) {
1801 FileInfo
->FileAttributes
|= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED
;
1807 Returns information about a specific file.
1809 This function returns information about a specific
1810 file, including its file name, type, attributes, starting
1811 address, size and authentication status.
1813 @param This Points to this instance of the
1814 EFI_PEI_FIRMWARE_VOLUME_PPI.
1815 @param FileHandle Handle of the file.
1816 @param FileInfo Upon exit, points to the file's
1819 @retval EFI_SUCCESS File information returned.
1820 @retval EFI_INVALID_PARAMETER If FileHandle does not
1821 represent a valid file.
1822 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1827 PeiFfsFvPpiGetFileInfo2 (
1828 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1829 IN EFI_PEI_FILE_HANDLE FileHandle
,
1830 OUT EFI_FV_FILE_INFO2
*FileInfo
1834 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1836 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1837 return EFI_INVALID_PARAMETER
;
1841 // Retrieve the FirmwareVolume which the file resides in.
1843 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1844 if (CoreFvHandle
== NULL
) {
1845 return EFI_INVALID_PARAMETER
;
1848 Status
= PeiFfsFvPpiGetFileInfo (This
, FileHandle
, (EFI_FV_FILE_INFO
*) FileInfo
);
1849 if (!EFI_ERROR (Status
)) {
1850 FileInfo
->AuthenticationStatus
= CoreFvHandle
->AuthenticationStatus
;
1857 This function returns information about the firmware volume.
1859 @param This Points to this instance of the
1860 EFI_PEI_FIRMWARE_VOLUME_PPI.
1861 @param FvHandle Handle to the firmware handle.
1862 @param VolumeInfo Points to the returned firmware volume
1865 @retval EFI_SUCCESS Information returned successfully.
1866 @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid
1867 firmware volume or VolumeInfo is NULL.
1872 PeiFfsFvPpiGetVolumeInfo (
1873 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1874 IN EFI_PEI_FV_HANDLE FvHandle
,
1875 OUT EFI_FV_INFO
*VolumeInfo
1878 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
1879 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
1881 if ((VolumeInfo
== NULL
) || (FvHandle
== NULL
)) {
1882 return EFI_INVALID_PARAMETER
;
1886 // VolumeHandle may not align at 8 byte,
1887 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
1888 // So, Copy FvHeader into the local FvHeader structure.
1890 CopyMem (&FwVolHeader
, FvHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
1893 // Check Fv Image Signature
1895 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
1896 return EFI_INVALID_PARAMETER
;
1899 ZeroMem (VolumeInfo
, sizeof (EFI_FV_INFO
));
1900 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
1901 VolumeInfo
->FvStart
= (VOID
*) FvHandle
;
1902 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
1903 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
1905 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
1906 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FvHandle
) + FwVolHeader
.ExtHeaderOffset
);
1907 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));
1914 Find the next matching section in the firmware file.
1916 This service enables PEI modules to discover sections
1917 of a given type within a valid file.
1919 @param This Points to this instance of the
1920 EFI_PEI_FIRMWARE_VOLUME_PPI.
1921 @param SearchType A filter to find only sections of this
1923 @param FileHandle Handle of firmware file in which to
1925 @param SectionData Updated upon return to point to the
1928 @retval EFI_SUCCESS Section was found.
1929 @retval EFI_NOT_FOUND Section of the specified type was not
1930 found. SectionData contains NULL.
1934 PeiFfsFvPpiFindSectionByType (
1935 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1936 IN EFI_SECTION_TYPE SearchType
,
1937 IN EFI_PEI_FILE_HANDLE FileHandle
,
1938 OUT VOID
**SectionData
1941 UINT32 AuthenticationStatus
;
1942 return PeiFfsFvPpiFindSectionByType2 (This
, SearchType
, 0, FileHandle
, SectionData
, &AuthenticationStatus
);
1946 Find the next matching section in the firmware file.
1948 This service enables PEI modules to discover sections
1949 of a given instance and type within a valid file.
1951 @param This Points to this instance of the
1952 EFI_PEI_FIRMWARE_VOLUME_PPI.
1953 @param SearchType A filter to find only sections of this
1955 @param SearchInstance A filter to find the specific instance
1957 @param FileHandle Handle of firmware file in which to
1959 @param SectionData Updated upon return to point to the
1961 @param AuthenticationStatus Updated upon return to point to the
1962 authentication status for this section.
1964 @retval EFI_SUCCESS Section was found.
1965 @retval EFI_NOT_FOUND Section of the specified type was not
1966 found. SectionData contains NULL.
1970 PeiFfsFvPpiFindSectionByType2 (
1971 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1972 IN EFI_SECTION_TYPE SearchType
,
1973 IN UINTN SearchInstance
,
1974 IN EFI_PEI_FILE_HANDLE FileHandle
,
1975 OUT VOID
**SectionData
,
1976 OUT UINT32
*AuthenticationStatus
1980 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
1982 EFI_COMMON_SECTION_HEADER
*Section
;
1983 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1984 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1986 UINT32 ExtractedAuthenticationStatus
;
1988 if (SectionData
== NULL
) {
1989 return EFI_NOT_FOUND
;
1992 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1995 // Retrieve the FirmwareVolume which the file resides in.
1997 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1998 if (CoreFvHandle
== NULL
) {
1999 return EFI_NOT_FOUND
;
2002 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
2004 if (IS_FFS_FILE2 (FfsFileHeader
)) {
2005 ASSERT (FFS_FILE2_SIZE (FfsFileHeader
) > 0x00FFFFFF);
2006 if (!FwVolInstance
->IsFfs3Fv
) {
2007 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
2008 return EFI_NOT_FOUND
;
2010 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
2011 FileSize
= FFS_FILE2_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
2013 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
2014 FileSize
= FFS_FILE_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
2017 Instance
= SearchInstance
+ 1;
2018 ExtractedAuthenticationStatus
= 0;
2019 Status
= ProcessSection (
2020 GetPeiServicesTablePointer (),
2026 &ExtractedAuthenticationStatus
,
2027 FwVolInstance
->IsFfs3Fv
2029 if (!EFI_ERROR (Status
)) {
2031 // Inherit the authentication status.
2033 *AuthenticationStatus
= ExtractedAuthenticationStatus
| CoreFvHandle
->AuthenticationStatus
;
2039 Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.
2041 @param FvHandle The handle of a FV.
2043 @retval NULL if can not find.
2044 @return Pointer of corresponding PEI_CORE_FV_HANDLE.
2046 PEI_CORE_FV_HANDLE
*
2047 FvHandleToCoreHandle (
2048 IN EFI_PEI_FV_HANDLE FvHandle
2052 PEI_CORE_INSTANCE
*PrivateData
;
2054 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
2055 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
2056 if (FvHandle
== PrivateData
->Fv
[Index
].FvHandle
) {
2057 return &PrivateData
->Fv
[Index
];
2065 Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.
2067 This routine also will install FvInfo ppi for FV hob in PI ways.
2069 @param Private Pointer of PEI_CORE_INSTANCE
2070 @param Instance The index of FV want to be searched.
2072 @return Instance of PEI_CORE_FV_HANDLE.
2074 PEI_CORE_FV_HANDLE
*
2075 FindNextCoreFvHandle (
2076 IN PEI_CORE_INSTANCE
*Private
,
2082 EFI_HOB_FIRMWARE_VOLUME
*FvHob
;
2085 // Handle Framework FvHob and Install FvInfo Ppi for it.
2087 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
2089 // Loop to search the wanted FirmwareVolume which supports FFS
2091 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetFirstHob (EFI_HOB_TYPE_FV
);
2092 while (FvHob
!= NULL
) {
2094 // Search whether FvHob has been installed into PeiCore's FV database.
2095 // If found, no need install new FvInfoPpi for it.
2097 for (Index
= 0, Match
= FALSE
; Index
< Private
->FvCount
; Index
++) {
2098 if ((EFI_PEI_FV_HANDLE
)(UINTN
)FvHob
->BaseAddress
== Private
->Fv
[Index
].FvHeader
) {
2105 // Search whether FvHob has been cached into PeiCore's Unknown FV database.
2106 // If found, no need install new FvInfoPpi for it.
2109 for (Index
= 0; Index
< Private
->UnknownFvInfoCount
; Index
++) {
2110 if ((UINTN
)FvHob
->BaseAddress
== (UINTN
)Private
->UnknownFvInfo
[Index
].FvInfo
) {
2118 // If the Fv in FvHob has not been installed into PeiCore's FV database and has
2119 // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi
2120 // for it then PeiCore will dispatch it in callback of FvInfoPpi.
2123 PeiServicesInstallFvInfoPpi (
2124 &(((EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)FvHob
->BaseAddress
)->FileSystemGuid
),
2125 (VOID
*)(UINTN
)FvHob
->BaseAddress
,
2126 (UINT32
)FvHob
->Length
,
2132 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetNextHob (EFI_HOB_TYPE_FV
, (VOID
*)((UINTN
)FvHob
+ FvHob
->Header
.HobLength
));
2136 ASSERT (Private
->FvCount
<= PcdGet32 (PcdPeiCoreMaxFvSupported
));
2137 if (Instance
>= Private
->FvCount
) {
2141 return &Private
->Fv
[Instance
];
2145 After PeiCore image is shadowed into permanent memory, all build-in FvPpi should
2146 be re-installed with the instance in permanent memory and all cached FvPpi pointers in
2147 PrivateData->Fv[] array should be fixed up to be pointed to the one in permanent
2150 @param PrivateData Pointer to PEI_CORE_INSTANCE.
2154 IN PEI_CORE_INSTANCE
*PrivateData
2158 EFI_PEI_PPI_DESCRIPTOR
*OldDescriptor
;
2163 // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
2166 Status
= PeiServicesLocatePpi (
2167 &gEfiFirmwareFileSystem2Guid
,
2172 ASSERT_EFI_ERROR (Status
);
2175 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
2176 // which is shadowed from flash to permanent memory within PeiCore image.
2178 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs2FvPpiList
);
2179 ASSERT_EFI_ERROR (Status
);
2182 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2184 for (Index
= 0; Index
< PcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
2185 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2186 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs2FwVol
.Fv
;
2191 // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which
2194 Status
= PeiServicesLocatePpi (
2195 &gEfiFirmwareFileSystem3Guid
,
2200 ASSERT_EFI_ERROR (Status
);
2203 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3
2204 // which is shadowed from flash to permanent memory within PeiCore image.
2206 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs3FvPpiList
);
2207 ASSERT_EFI_ERROR (Status
);
2210 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2212 for (Index
= 0; Index
< PcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
2213 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2214 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs3FwVol
.Fv
;
2220 Report the information for a new discoveried FV in unknown third-party format.
2222 If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but
2223 the FV in this format has been discoveried, then this FV's information will be cached into
2224 PEI_CORE_INSTANCE's UnknownFvInfo array.
2225 Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI
2226 is installed later by platform's PEIM, the original unknown third-party 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
;
2243 if (PrivateData
->UnknownFvInfoCount
+ 1 >= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
2244 return EFI_OUT_OF_RESOURCES
;
2247 NewUnknownFv
= &PrivateData
->UnknownFvInfo
[PrivateData
->UnknownFvInfoCount
];
2248 PrivateData
->UnknownFvInfoCount
++;
2250 CopyGuid (&NewUnknownFv
->FvFormat
, &FvInfo2Ppi
->FvFormat
);
2251 NewUnknownFv
->FvInfo
= FvInfo2Ppi
->FvInfo
;
2252 NewUnknownFv
->FvInfoSize
= FvInfo2Ppi
->FvInfoSize
;
2253 NewUnknownFv
->AuthenticationStatus
= FvInfo2Ppi
->AuthenticationStatus
;
2254 NewUnknownFv
->NotifyDescriptor
.Flags
= (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
);
2255 NewUnknownFv
->NotifyDescriptor
.Guid
= &NewUnknownFv
->FvFormat
;
2256 NewUnknownFv
->NotifyDescriptor
.Notify
= ThirdPartyFvPpiNotifyCallback
;
2258 PeiServicesNotifyPpi (&NewUnknownFv
->NotifyDescriptor
);
2263 Find the FV information according to third-party FV format guid.
2265 This routine also will remove the FV information found by given FV format guid from
2266 PrivateData->UnknownFvInfo[].
2268 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2269 @param Format Point to given FV format guid
2270 @param FvInfo On return, the pointer of FV information buffer
2271 @param FvInfoSize On return, the size of FV information buffer.
2272 @param AuthenticationStatus On return, the authentication status of FV information buffer.
2274 @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI
2275 @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2278 FindUnknownFormatFvInfo (
2279 IN PEI_CORE_INSTANCE
*PrivateData
,
2280 IN EFI_GUID
*Format
,
2282 OUT UINT32
*FvInfoSize
,
2283 OUT UINT32
*AuthenticationStatus
2290 for (; Index
< PrivateData
->UnknownFvInfoCount
; Index
++) {
2291 if (CompareGuid (Format
, &PrivateData
->UnknownFvInfo
[Index
].FvFormat
)) {
2296 if (Index
== PrivateData
->UnknownFvInfoCount
) {
2297 return EFI_NOT_FOUND
;
2300 *FvInfo
= PrivateData
->UnknownFvInfo
[Index
].FvInfo
;
2301 *FvInfoSize
= PrivateData
->UnknownFvInfo
[Index
].FvInfoSize
;
2302 *AuthenticationStatus
= PrivateData
->UnknownFvInfo
[Index
].AuthenticationStatus
;
2305 // Remove an entry from UnknownFvInfo array.
2308 for (;Index2
< PrivateData
->UnknownFvInfoCount
; Index2
++, Index
++) {
2309 CopyMem (&PrivateData
->UnknownFvInfo
[Index
], &PrivateData
->UnknownFvInfo
[Index2
], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO
));
2311 PrivateData
->UnknownFvInfoCount
--;
2316 Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.
2318 When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this
2319 routine is called to process all discoveried FVs in this format.
2321 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
2322 @param NotifyDescriptor Address of the notification descriptor data structure.
2323 @param Ppi Address of the PPI that was installed.
2325 @retval EFI_SUCCESS The notification callback is processed correctly.
2329 ThirdPartyFvPpiNotifyCallback (
2330 IN EFI_PEI_SERVICES
**PeiServices
,
2331 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
2335 PEI_CORE_INSTANCE
*PrivateData
;
2336 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
2339 UINT32 AuthenticationStatus
;
2341 EFI_PEI_FV_HANDLE FvHandle
;
2342 BOOLEAN IsProcessed
;
2344 EFI_PEI_FILE_HANDLE FileHandle
;
2348 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
2349 FvPpi
= (EFI_PEI_FIRMWARE_VOLUME_PPI
*) Ppi
;
2352 Status
= FindUnknownFormatFvInfo (PrivateData
, NotifyDescriptor
->Guid
, &FvInfo
, &FvInfoSize
, &AuthenticationStatus
);
2353 if (EFI_ERROR (Status
)) {
2358 // Process new found FV and get FV handle.
2360 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo
, FvInfoSize
, &FvHandle
);
2361 if (EFI_ERROR (Status
)) {
2362 DEBUG ((EFI_D_ERROR
, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo
));
2367 // Check whether the FV has already been processed.
2369 IsProcessed
= FALSE
;
2370 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
2371 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
2372 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfo
));
2382 if (PrivateData
->FvCount
>= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
2383 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, PcdGet32 (PcdPeiCoreMaxFvSupported
)));
2384 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
2389 // Update internal PEI_CORE_FV array.
2391 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo
;
2392 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
2393 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
2394 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= AuthenticationStatus
;
2395 CurFvCount
= PrivateData
->FvCount
;
2398 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
2399 (UINT32
) CurFvCount
,
2404 PrivateData
->FvCount
++;
2407 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
2411 Status
= FvPpi
->FindFileByType (
2413 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
2417 if (!EFI_ERROR (Status
)) {
2418 Status
= FvPpi
->FindSectionByType (
2420 EFI_SECTION_PEI_DEPEX
,
2424 if (!EFI_ERROR (Status
)) {
2425 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
2427 // Dependency is not satisfied.
2433 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, CurFvCount
, FvHandle
));
2434 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[CurFvCount
], FileHandle
);
2436 } while (FileHandle
!= NULL
);