2 Pei Core Firmware File System service routines.
4 Copyright (c) 2015 HP Development Company, L.P.
5 Copyright (c) 2006 - 2018, 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 Status
= FvPpi
->ProcessVolume (
500 SecCoreData
->BootFirmwareVolumeBase
,
501 (UINTN
)BfvHeader
->FvLength
,
504 ASSERT_EFI_ERROR (Status
);
507 // Update internal PEI_CORE_FV array.
509 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= BfvHeader
;
510 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
511 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
512 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= 0;
515 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
516 (UINT32
) PrivateData
->FvCount
,
518 (UINT32
) BfvHeader
->FvLength
,
521 PrivateData
->FvCount
++;
524 // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose
525 // additional Fvs to PeiCore.
527 Status
= PeiServicesNotifyPpi (mNotifyOnFvInfoList
);
528 ASSERT_EFI_ERROR (Status
);
533 Process Firmware Volum Information once FvInfoPPI or FvInfo2PPI install.
534 The FV Info will be registered into PeiCore private data structure.
535 And search the inside FV image, if found, the new FV INFO(2) PPI will be installed.
537 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
538 @param NotifyDescriptor Address of the notification descriptor data structure.
539 @param Ppi Address of the PPI that was installed.
541 @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.
542 @return if not EFI_SUCESS, fail to verify FV.
547 FirmwareVolmeInfoPpiNotifyCallback (
548 IN EFI_PEI_SERVICES
**PeiServices
,
549 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
553 EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI FvInfo2Ppi
;
554 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
555 PEI_CORE_INSTANCE
*PrivateData
;
557 EFI_PEI_FV_HANDLE FvHandle
;
559 EFI_PEI_FILE_HANDLE FileHandle
;
564 Status
= EFI_SUCCESS
;
565 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
567 if (CompareGuid (NotifyDescriptor
->Guid
, &gEfiPeiFirmwareVolumeInfo2PpiGuid
)) {
571 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
));
577 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
));
578 FvInfo2Ppi
.AuthenticationStatus
= 0;
582 if (CompareGuid (&FvInfo2Ppi
.FvFormat
, &gEfiFirmwareFileSystem2Guid
)) {
584 // gEfiFirmwareFileSystem2Guid is specified for FvFormat, then here to check the
585 // FileSystemGuid pointed by FvInfo against gEfiFirmwareFileSystem2Guid to make sure
586 // FvInfo has the firmware file system 2 format.
588 // If the ASSERT really appears, FvFormat needs to be specified correctly, for example,
589 // gEfiFirmwareFileSystem3Guid can be used for firmware file system 3 format, or
590 // ((EFI_FIRMWARE_VOLUME_HEADER *) FvInfo)->FileSystemGuid can be just used for both
591 // firmware file system 2 and 3 format.
593 ASSERT (CompareGuid (&(((EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo2Ppi
.FvInfo
)->FileSystemGuid
), &gEfiFirmwareFileSystem2Guid
));
597 // Locate the corresponding FV_PPI according to founded FV's format guid
599 Status
= PeiServicesLocatePpi (
600 &FvInfo2Ppi
.FvFormat
,
605 if (!EFI_ERROR (Status
)) {
607 // Process new found FV and get FV handle.
609 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo2Ppi
.FvInfo
, FvInfo2Ppi
.FvInfoSize
, &FvHandle
);
610 if (EFI_ERROR (Status
)) {
611 DEBUG ((EFI_D_ERROR
, "Fail to process new found FV, FV may be corrupted!\n"));
616 // Check whether the FV has already been processed.
618 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
619 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
620 if (IsFvInfo2
&& (FvInfo2Ppi
.AuthenticationStatus
!= PrivateData
->Fv
[FvIndex
].AuthenticationStatus
)) {
621 PrivateData
->Fv
[FvIndex
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
622 DEBUG ((EFI_D_INFO
, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex
, FvInfo2Ppi
.AuthenticationStatus
));
624 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfo2Ppi
.FvInfo
));
629 if (PrivateData
->FvCount
>= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
630 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, PcdGet32 (PcdPeiCoreMaxFvSupported
)));
631 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
636 // Update internal PEI_CORE_FV array.
638 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo2Ppi
.FvInfo
;
639 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
640 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
641 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
642 CurFvCount
= PrivateData
->FvCount
;
645 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
647 (VOID
*) FvInfo2Ppi
.FvInfo
,
648 FvInfo2Ppi
.FvInfoSize
,
651 PrivateData
->FvCount
++;
654 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
658 Status
= FvPpi
->FindFileByType (
660 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
664 if (!EFI_ERROR (Status
)) {
665 Status
= FvPpi
->FindSectionByType (
667 EFI_SECTION_PEI_DEPEX
,
671 if (!EFI_ERROR (Status
)) {
672 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
674 // Dependency is not satisfied.
680 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, CurFvCount
, FvHandle
));
681 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[CurFvCount
], FileHandle
);
683 } while (FileHandle
!= NULL
);
685 DEBUG ((EFI_D_ERROR
, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi
.FvInfo
));
687 AddUnknownFormatFvInfo (PrivateData
, &FvInfo2Ppi
);
694 Verify the Guided Section GUID by checking if there is the Guided Section GUID HOB recorded the GUID itself.
696 @param GuidedSectionGuid The Guided Section GUID.
697 @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Ppi
698 for the Guided Section.
700 @return TRUE The GuidedSectionGuid could be identified, and the pointer to
701 the Guided Section Extraction Ppi will be returned to *GuidedSectionExtraction.
702 @return FALSE The GuidedSectionGuid could not be identified, or
703 the Guided Section Extraction Ppi has not been installed yet.
707 VerifyGuidedSectionGuid (
708 IN EFI_GUID
*GuidedSectionGuid
,
709 OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
**GuidedSectionExtraction
712 EFI_PEI_HOB_POINTERS Hob
;
713 EFI_GUID
*GuidRecorded
;
718 // Check if there is the Guided Section GUID HOB recorded the GUID itself.
720 Hob
.Raw
= GetFirstGuidHob (GuidedSectionGuid
);
721 if (Hob
.Raw
!= NULL
) {
722 GuidRecorded
= (EFI_GUID
*) GET_GUID_HOB_DATA (Hob
);
723 if (CompareGuid (GuidRecorded
, GuidedSectionGuid
)) {
725 // Found the recorded GuidedSectionGuid.
727 Status
= PeiServicesLocatePpi (GuidedSectionGuid
, 0, NULL
, (VOID
**) &Interface
);
728 if (!EFI_ERROR (Status
) && Interface
!= NULL
) {
730 // Found the supported Guided Section Extraction Ppi for the Guided Section.
732 *GuidedSectionExtraction
= (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*) Interface
;
743 Go through the file to search SectionType section.
744 Search within encapsulation sections (compression and GUIDed) recursively,
745 until the match section is found.
747 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
748 @param SectionType Filter to find only section of this type.
749 @param SectionInstance Pointer to the filter to find the specific instance of section.
750 @param Section From where to search.
751 @param SectionSize The file size to search.
752 @param OutputBuffer A pointer to the discovered section, if successful.
753 NULL if section not found
754 @param AuthenticationStatus Updated upon return to point to the authentication status for this section.
755 @param IsFfs3Fv Indicates the FV format.
757 @return EFI_NOT_FOUND The match section is not found.
758 @return EFI_SUCCESS The match section is found.
763 IN CONST EFI_PEI_SERVICES
**PeiServices
,
764 IN EFI_SECTION_TYPE SectionType
,
765 IN OUT UINTN
*SectionInstance
,
766 IN EFI_COMMON_SECTION_HEADER
*Section
,
767 IN UINTN SectionSize
,
768 OUT VOID
**OutputBuffer
,
769 OUT UINT32
*AuthenticationStatus
,
774 UINT32 SectionLength
;
776 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
777 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
781 UINT32 Authentication
;
782 PEI_CORE_INSTANCE
*PrivateData
;
783 EFI_GUID
*SectionDefinitionGuid
;
784 BOOLEAN SectionCached
;
785 VOID
*TempOutputBuffer
;
786 UINT32 TempAuthenticationStatus
;
787 UINT16 GuidedSectionAttributes
;
789 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
790 *OutputBuffer
= NULL
;
793 Status
= EFI_NOT_FOUND
;
796 while (ParsedLength
< SectionSize
) {
798 if (IS_SECTION2 (Section
)) {
799 ASSERT (SECTION2_SIZE (Section
) > 0x00FFFFFF);
801 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
802 SectionLength
= SECTION2_SIZE (Section
);
804 // SectionLength is adjusted it is 4 byte aligned.
805 // Go to the next section
807 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
808 ASSERT (SectionLength
!= 0);
809 ParsedLength
+= SectionLength
;
810 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ SectionLength
);
815 if (Section
->Type
== SectionType
) {
817 // The type matches, so check the instance count to see if it's the one we want.
819 (*SectionInstance
)--;
820 if (*SectionInstance
== 0) {
824 if (IS_SECTION2 (Section
)) {
825 *OutputBuffer
= (VOID
*)((UINT8
*) Section
+ sizeof (EFI_COMMON_SECTION_HEADER2
));
827 *OutputBuffer
= (VOID
*)((UINT8
*) Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
831 if (IS_SECTION2 (Section
)) {
832 SectionLength
= SECTION2_SIZE (Section
);
834 SectionLength
= SECTION_SIZE (Section
);
837 // SectionLength is adjusted it is 4 byte aligned.
838 // Go to the next section
840 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
841 ASSERT (SectionLength
!= 0);
842 ParsedLength
+= SectionLength
;
843 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
846 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
848 // Check the encapsulated section is extracted into the cache data.
850 SectionCached
= FALSE
;
851 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
852 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
853 SectionCached
= TRUE
;
854 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
855 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
856 Authentication
= PrivateData
->CacheSection
.AuthenticationStatus
[Index
];
858 // Search section directly from the cache data.
860 TempAuthenticationStatus
= 0;
861 Status
= ProcessSection (
868 &TempAuthenticationStatus
,
871 if (!EFI_ERROR (Status
)) {
872 *OutputBuffer
= TempOutputBuffer
;
873 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
880 // If SectionCached is TRUE, the section data has been cached and scanned.
882 if (!SectionCached
) {
883 Status
= EFI_NOT_FOUND
;
885 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
886 if (IS_SECTION2 (Section
)) {
887 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION2
*)Section
)->SectionDefinitionGuid
;
888 GuidedSectionAttributes
= ((EFI_GUID_DEFINED_SECTION2
*)Section
)->Attributes
;
890 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
;
891 GuidedSectionAttributes
= ((EFI_GUID_DEFINED_SECTION
*)Section
)->Attributes
;
893 if (VerifyGuidedSectionGuid (SectionDefinitionGuid
, &GuidSectionPpi
)) {
894 Status
= GuidSectionPpi
->ExtractSection (
901 } else if ((GuidedSectionAttributes
& EFI_GUIDED_SECTION_PROCESSING_REQUIRED
) == 0) {
903 // Figure out the proper authentication status for GUIDED section without processing required
905 Status
= EFI_SUCCESS
;
906 if ((GuidedSectionAttributes
& EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID
) {
907 Authentication
|= EFI_AUTH_STATUS_IMAGE_SIGNED
| EFI_AUTH_STATUS_NOT_TESTED
;
909 if (IS_SECTION2 (Section
)) {
910 PpiOutputSize
= SECTION2_SIZE (Section
) - ((EFI_GUID_DEFINED_SECTION2
*) Section
)->DataOffset
;
911 PpiOutput
= (UINT8
*) Section
+ ((EFI_GUID_DEFINED_SECTION2
*) Section
)->DataOffset
;
913 PpiOutputSize
= SECTION_SIZE (Section
) - ((EFI_GUID_DEFINED_SECTION
*) Section
)->DataOffset
;
914 PpiOutput
= (UINT8
*) Section
+ ((EFI_GUID_DEFINED_SECTION
*) Section
)->DataOffset
;
917 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
918 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**) &DecompressPpi
);
919 if (!EFI_ERROR (Status
)) {
920 Status
= DecompressPpi
->Decompress (
922 (CONST EFI_COMPRESSION_SECTION
*) Section
,
929 if (!EFI_ERROR (Status
)) {
930 if ((Authentication
& EFI_AUTH_STATUS_NOT_TESTED
) == 0) {
932 // Update cache section data.
934 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
935 PrivateData
->CacheSection
.AllSectionCount
++;
937 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
938 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
939 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
940 PrivateData
->CacheSection
.AuthenticationStatus
[PrivateData
->CacheSection
.SectionIndex
] = Authentication
;
941 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
944 TempAuthenticationStatus
= 0;
945 Status
= ProcessSection (
952 &TempAuthenticationStatus
,
955 if (!EFI_ERROR (Status
)) {
956 *OutputBuffer
= TempOutputBuffer
;
957 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
964 if (IS_SECTION2 (Section
)) {
965 SectionLength
= SECTION2_SIZE (Section
);
967 SectionLength
= SECTION_SIZE (Section
);
970 // SectionLength is adjusted it is 4 byte aligned.
971 // Go to the next section
973 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
974 ASSERT (SectionLength
!= 0);
975 ParsedLength
+= SectionLength
;
976 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
979 return EFI_NOT_FOUND
;
984 Searches for the next matching section within the specified file.
986 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
987 @param SectionType Filter to find only sections of this type.
988 @param FileHandle Pointer to the current file to search.
989 @param SectionData A pointer to the discovered section, if successful.
990 NULL if section not found
992 @retval EFI_NOT_FOUND The section was not found.
993 @retval EFI_SUCCESS The section was found.
998 PeiFfsFindSectionData (
999 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1000 IN EFI_SECTION_TYPE SectionType
,
1001 IN EFI_PEI_FILE_HANDLE FileHandle
,
1002 OUT VOID
**SectionData
1005 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1007 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1008 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1009 return EFI_NOT_FOUND
;
1012 return CoreFvHandle
->FvPpi
->FindSectionByType (CoreFvHandle
->FvPpi
, SectionType
, FileHandle
, SectionData
);
1016 Searches for the next matching section within the specified file.
1018 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
1019 @param SectionType The value of the section type to find.
1020 @param SectionInstance Section instance to find.
1021 @param FileHandle Handle of the firmware file to search.
1022 @param SectionData A pointer to the discovered section, if successful.
1023 @param AuthenticationStatus A pointer to the authentication status for this section.
1025 @retval EFI_SUCCESS The section was found.
1026 @retval EFI_NOT_FOUND The section was not found.
1031 PeiFfsFindSectionData3 (
1032 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1033 IN EFI_SECTION_TYPE SectionType
,
1034 IN UINTN SectionInstance
,
1035 IN EFI_PEI_FILE_HANDLE FileHandle
,
1036 OUT VOID
**SectionData
,
1037 OUT UINT32
*AuthenticationStatus
1040 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1042 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1043 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1044 return EFI_NOT_FOUND
;
1047 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1048 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1049 return CoreFvHandle
->FvPpi
->FindSectionByType2 (CoreFvHandle
->FvPpi
, SectionType
, SectionInstance
, FileHandle
, SectionData
, AuthenticationStatus
);
1052 // The old FvPpi doesn't support to find section by section instance
1053 // and return authentication status, so return EFI_UNSUPPORTED.
1055 return EFI_UNSUPPORTED
;
1059 Searches for the next matching file in the firmware volume.
1061 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
1062 @param SearchType Filter to find only files of this type.
1063 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
1064 @param FvHandle Handle of firmware volume in which to search.
1065 @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
1066 at the beginning of the firmware volume. On exit, points the file handle of the next file
1067 in the volume or NULL if there are no more files.
1069 @retval EFI_NOT_FOUND The file was not found.
1070 @retval EFI_NOT_FOUND The header checksum was not zero.
1071 @retval EFI_SUCCESS The file was found.
1076 PeiFfsFindNextFile (
1077 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1078 IN UINT8 SearchType
,
1079 IN EFI_PEI_FV_HANDLE FvHandle
,
1080 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1083 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1085 CoreFvHandle
= FvHandleToCoreHandle (FvHandle
);
1088 // To make backward compatiblity, if can not find corresponding the handle of FV
1089 // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed
1090 // to the address of first byte of FV.
1092 if ((CoreFvHandle
== NULL
) && FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
1093 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1096 if ((CoreFvHandle
== NULL
) || CoreFvHandle
->FvPpi
== NULL
) {
1097 return EFI_NOT_FOUND
;
1100 return CoreFvHandle
->FvPpi
->FindFileByType (CoreFvHandle
->FvPpi
, SearchType
, FvHandle
, FileHandle
);
1105 Search the firmware volumes by index
1107 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
1108 @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
1110 @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
1112 @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
1113 @retval EFI_NOT_FOUND The volume was not found.
1114 @retval EFI_SUCCESS The volume was found.
1119 PeiFfsFindNextVolume (
1120 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1122 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
1125 PEI_CORE_INSTANCE
*Private
;
1126 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1128 if (VolumeHandle
== NULL
) {
1129 return EFI_INVALID_PARAMETER
;
1132 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
1134 CoreFvHandle
= FindNextCoreFvHandle (Private
, Instance
);
1135 if (CoreFvHandle
== NULL
) {
1136 *VolumeHandle
= NULL
;
1137 return EFI_NOT_FOUND
;
1140 *VolumeHandle
= CoreFvHandle
->FvHandle
;
1147 Find a file within a volume by its name.
1149 @param FileName A pointer to the name of the file to find within the firmware volume.
1150 @param VolumeHandle The firmware volume to search
1151 @param FileHandle Upon exit, points to the found file's handle
1152 or NULL if it could not be found.
1154 @retval EFI_SUCCESS File was found.
1155 @retval EFI_NOT_FOUND File was not found.
1156 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
1161 PeiFfsFindFileByName (
1162 IN CONST EFI_GUID
*FileName
,
1163 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1164 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1167 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1169 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1170 return EFI_INVALID_PARAMETER
;
1173 CoreFvHandle
= FvHandleToCoreHandle (VolumeHandle
);
1174 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1175 return EFI_NOT_FOUND
;
1178 return CoreFvHandle
->FvPpi
->FindFileByName (CoreFvHandle
->FvPpi
, FileName
, &VolumeHandle
, FileHandle
);
1182 Returns information about a specific file.
1184 @param FileHandle Handle of the file.
1185 @param FileInfo Upon exit, points to the file's information.
1187 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1188 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1189 @retval EFI_SUCCESS File information returned.
1195 IN EFI_PEI_FILE_HANDLE FileHandle
,
1196 OUT EFI_FV_FILE_INFO
*FileInfo
1199 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1201 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1202 return EFI_INVALID_PARAMETER
;
1206 // Retrieve the FirmwareVolume which the file resides in.
1208 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1209 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1210 return EFI_INVALID_PARAMETER
;
1213 return CoreFvHandle
->FvPpi
->GetFileInfo (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1217 Returns information about a specific file.
1219 @param FileHandle Handle of the file.
1220 @param FileInfo Upon exit, points to the file's information.
1222 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1223 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1224 @retval EFI_SUCCESS File information returned.
1229 PeiFfsGetFileInfo2 (
1230 IN EFI_PEI_FILE_HANDLE FileHandle
,
1231 OUT EFI_FV_FILE_INFO2
*FileInfo
1234 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1236 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1237 return EFI_INVALID_PARAMETER
;
1241 // Retrieve the FirmwareVolume which the file resides in.
1243 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1244 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1245 return EFI_INVALID_PARAMETER
;
1248 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1249 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1250 return CoreFvHandle
->FvPpi
->GetFileInfo2 (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1253 // The old FvPpi doesn't support to return file info with authentication status,
1254 // so return EFI_UNSUPPORTED.
1256 return EFI_UNSUPPORTED
;
1260 Returns information about the specified volume.
1262 This function returns information about a specific firmware
1263 volume, including its name, type, attributes, starting address
1266 @param VolumeHandle Handle of the volume.
1267 @param VolumeInfo Upon exit, points to the volume's information.
1269 @retval EFI_SUCCESS Volume information returned.
1270 @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
1271 @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
1272 @retval EFI_SUCCESS Information successfully returned.
1273 @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
1278 PeiFfsGetVolumeInfo (
1279 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1280 OUT EFI_FV_INFO
*VolumeInfo
1283 PEI_CORE_FV_HANDLE
*CoreHandle
;
1285 if ((VolumeInfo
== NULL
) || (VolumeHandle
== NULL
)) {
1286 return EFI_INVALID_PARAMETER
;
1289 CoreHandle
= FvHandleToCoreHandle (VolumeHandle
);
1291 if ((CoreHandle
== NULL
) || (CoreHandle
->FvPpi
== NULL
)) {
1292 return EFI_INVALID_PARAMETER
;
1295 return CoreHandle
->FvPpi
->GetVolumeInfo (CoreHandle
->FvPpi
, VolumeHandle
, VolumeInfo
);
1299 Find USED_SIZE FV_EXT_TYPE entry in FV extension header and get the FV used size.
1301 @param[in] FvHeader Pointer to FV header.
1302 @param[out] FvUsedSize Pointer to FV used size returned,
1303 only valid if USED_SIZE FV_EXT_TYPE entry is found.
1304 @param[out] EraseByte Pointer to erase byte returned,
1305 only valid if USED_SIZE FV_EXT_TYPE entry is found.
1307 @retval TRUE USED_SIZE FV_EXT_TYPE entry is found,
1308 FV used size and erase byte are returned.
1309 @retval FALSE No USED_SIZE FV_EXT_TYPE entry found.
1314 IN EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
,
1315 OUT UINT32
*FvUsedSize
,
1316 OUT UINT8
*EraseByte
1319 UINT16 ExtHeaderOffset
;
1320 EFI_FIRMWARE_VOLUME_EXT_HEADER
*ExtHeader
;
1321 EFI_FIRMWARE_VOLUME_EXT_ENTRY
*ExtEntryList
;
1322 EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE
*ExtEntryUsedSize
;
1324 ExtHeaderOffset
= ReadUnaligned16 (&FvHeader
->ExtHeaderOffset
);
1325 if (ExtHeaderOffset
!= 0) {
1326 ExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) ((UINT8
*) FvHeader
+ ExtHeaderOffset
);
1327 ExtEntryList
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY
*) (ExtHeader
+ 1);
1328 while ((UINTN
) ExtEntryList
< ((UINTN
) ExtHeader
+ ReadUnaligned32 (&ExtHeader
->ExtHeaderSize
))) {
1329 if (ReadUnaligned16 (&ExtEntryList
->ExtEntryType
) == EFI_FV_EXT_TYPE_USED_SIZE_TYPE
) {
1331 // USED_SIZE FV_EXT_TYPE entry is found.
1333 ExtEntryUsedSize
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE
*) ExtEntryList
;
1334 *FvUsedSize
= ReadUnaligned32 (&ExtEntryUsedSize
->UsedSize
);
1335 if ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_ERASE_POLARITY
) != 0) {
1342 "FV at 0x%x has 0x%x used size, and erase byte is 0x%02x\n",
1349 ExtEntryList
= (EFI_FIRMWARE_VOLUME_EXT_ENTRY
*)
1350 ((UINT8
*) ExtEntryList
+ ReadUnaligned16 (&ExtEntryList
->ExtEntrySize
));
1355 // No USED_SIZE FV_EXT_TYPE entry found.
1361 Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob.
1363 @param PrivateData PeiCore's private data structure
1364 @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.
1365 @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image.
1367 @retval EFI_NOT_FOUND FV image can't be found.
1368 @retval EFI_SUCCESS Successfully to process it.
1369 @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image
1370 @retval EFI_SECURITY_VIOLATION Image is illegal
1371 @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section
1376 IN PEI_CORE_INSTANCE
*PrivateData
,
1377 IN PEI_CORE_FV_HANDLE
*ParentFvCoreHandle
,
1378 IN EFI_PEI_FILE_HANDLE ParentFvFileHandle
1382 EFI_FV_INFO ParentFvImageInfo
;
1385 EFI_PEI_HOB_POINTERS HobPtr
;
1386 EFI_PEI_FIRMWARE_VOLUME_PPI
*ParentFvPpi
;
1387 EFI_PEI_FV_HANDLE ParentFvHandle
;
1388 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
1389 EFI_FV_FILE_INFO FileInfo
;
1391 UINT32 AuthenticationStatus
;
1396 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1399 HobPtr
.Raw
= GetHobList ();
1400 while ((HobPtr
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobPtr
.Raw
)) != NULL
) {
1401 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)ParentFvFileHandle
)->Name
), &HobPtr
.FirmwareVolume2
->FileName
)) {
1403 // this FILE has been dispatched, it will not be dispatched again.
1405 DEBUG ((EFI_D_INFO
, "FV file %p has been dispatched!\r\n", ParentFvFileHandle
));
1408 HobPtr
.Raw
= GET_NEXT_HOB (HobPtr
);
1411 ParentFvHandle
= ParentFvCoreHandle
->FvHandle
;
1412 ParentFvPpi
= ParentFvCoreHandle
->FvPpi
;
1415 // Find FvImage in FvFile
1417 AuthenticationStatus
= 0;
1418 if ((ParentFvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1419 (ParentFvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1420 Status
= ParentFvPpi
->FindSectionByType2 (
1422 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1426 &AuthenticationStatus
1429 Status
= ParentFvPpi
->FindSectionByType (
1431 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1436 if (EFI_ERROR (Status
)) {
1440 Status
= VerifyPeim (PrivateData
, ParentFvHandle
, ParentFvFileHandle
, AuthenticationStatus
);
1441 if (Status
== EFI_SECURITY_VIOLATION
) {
1446 // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
1447 // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
1448 // its initial linked location and maintain its alignment.
1450 if ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_WEAK_ALIGNMENT
) != EFI_FVB2_WEAK_ALIGNMENT
) {
1452 // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
1454 FvAlignment
= 1 << ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_ALIGNMENT
) >> 16);
1455 if (FvAlignment
< 8) {
1461 "%a() FV at 0x%x, FvAlignment required is 0x%x\n",
1468 // Check FvImage alignment.
1470 if ((UINTN
) FvHeader
% FvAlignment
!= 0) {
1471 FvLength
= ReadUnaligned64 (&FvHeader
->FvLength
);
1472 NewFvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvLength
), FvAlignment
);
1473 if (NewFvBuffer
== NULL
) {
1474 return EFI_OUT_OF_RESOURCES
;
1476 if (GetFvUsedSize (FvHeader
, &FvUsedSize
, &EraseByte
)) {
1478 // Copy the used bytes and fill the rest with the erase value.
1480 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
) FvUsedSize
);
1482 (UINT8
*) NewFvBuffer
+ FvUsedSize
,
1483 (UINTN
) (FvLength
- FvUsedSize
),
1487 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
) FvLength
);
1489 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) NewFvBuffer
;
1493 Status
= ParentFvPpi
->GetVolumeInfo (ParentFvPpi
, ParentFvHandle
, &ParentFvImageInfo
);
1494 ASSERT_EFI_ERROR (Status
);
1496 Status
= ParentFvPpi
->GetFileInfo (ParentFvPpi
, ParentFvFileHandle
, &FileInfo
);
1497 ASSERT_EFI_ERROR (Status
);
1500 // Install FvInfo(2) Ppi
1501 // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated
1502 // FVs inherit the proper AuthenticationStatus.
1504 PeiServicesInstallFvInfo2Ppi(
1505 &FvHeader
->FileSystemGuid
,
1507 (UINT32
)FvHeader
->FvLength
,
1508 &ParentFvImageInfo
.FvName
,
1510 AuthenticationStatus
1513 PeiServicesInstallFvInfoPpi (
1514 &FvHeader
->FileSystemGuid
,
1516 (UINT32
) FvHeader
->FvLength
,
1517 &ParentFvImageInfo
.FvName
,
1522 // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase
1525 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1530 // Makes the encapsulated volume show up in DXE phase to skip processing of
1531 // encapsulated file again.
1534 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1536 &ParentFvImageInfo
.FvName
,
1541 // Build FV3 HOB with authentication status to be propagated to DXE.
1544 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1546 AuthenticationStatus
,
1548 &ParentFvImageInfo
.FvName
,
1556 Process a firmware volume and create a volume handle.
1558 Create a volume handle from the information in the buffer. For
1559 memory-mapped firmware volumes, Buffer and BufferSize refer to
1560 the start of the firmware volume and the firmware volume size.
1561 For non memory-mapped firmware volumes, this points to a
1562 buffer which contains the necessary information for creating
1563 the firmware volume handle. Normally, these values are derived
1564 from the EFI_FIRMWARE_VOLUME_INFO_PPI.
1567 @param This Points to this instance of the
1568 EFI_PEI_FIRMWARE_VOLUME_PPI.
1569 @param Buffer Points to the start of the buffer.
1570 @param BufferSize Size of the buffer.
1571 @param FvHandle Points to the returned firmware volume
1572 handle. The firmware volume handle must
1573 be unique within the system.
1575 @retval EFI_SUCCESS Firmware volume handle created.
1576 @retval EFI_VOLUME_CORRUPTED Volume was corrupt.
1581 PeiFfsFvPpiProcessVolume (
1582 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1584 IN UINTN BufferSize
,
1585 OUT EFI_PEI_FV_HANDLE
*FvHandle
1590 ASSERT (FvHandle
!= NULL
);
1592 if (Buffer
== NULL
) {
1593 return EFI_VOLUME_CORRUPTED
;
1597 // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped
1598 // FV image and the handle is pointed to Fv image's buffer.
1600 *FvHandle
= (EFI_PEI_FV_HANDLE
) Buffer
;
1603 // Do verify for given FV buffer.
1605 Status
= VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER
*) Buffer
);
1606 if (EFI_ERROR(Status
)) {
1607 DEBUG ((EFI_D_ERROR
, "Fail to verify FV which address is 0x%11p", Buffer
));
1608 return EFI_VOLUME_CORRUPTED
;
1615 Finds the next file of the specified type.
1617 This service enables PEI modules to discover additional firmware files.
1618 The FileHandle must be unique within the system.
1620 @param This Points to this instance of the
1621 EFI_PEI_FIRMWARE_VOLUME_PPI.
1622 @param SearchType A filter to find only files of this type. Type
1623 EFI_FV_FILETYPE_ALL causes no filtering to be
1625 @param FvHandle Handle of firmware volume in which to
1627 @param FileHandle Points to the current handle from which to
1628 begin searching or NULL to start at the
1629 beginning of the firmware volume. Updated
1630 upon return to reflect the file found.
1632 @retval EFI_SUCCESS The file was found.
1633 @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.
1638 PeiFfsFvPpiFindFileByType (
1639 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1640 IN EFI_FV_FILETYPE SearchType
,
1641 IN EFI_PEI_FV_HANDLE FvHandle
,
1642 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1645 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1649 Find a file within a volume by its name.
1651 This service searches for files with a specific name, within
1652 either the specified firmware volume or all firmware volumes.
1654 @param This Points to this instance of the
1655 EFI_PEI_FIRMWARE_VOLUME_PPI.
1656 @param FileName A pointer to the name of the file to find
1657 within the firmware volume.
1658 @param FvHandle Upon entry, the pointer to the firmware
1659 volume to search or NULL if all firmware
1660 volumes should be searched. Upon exit, the
1661 actual firmware volume in which the file was
1663 @param FileHandle Upon exit, points to the found file's
1664 handle or NULL if it could not be found.
1666 @retval EFI_SUCCESS File was found.
1667 @retval EFI_NOT_FOUND File was not found.
1668 @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or
1675 PeiFfsFvPpiFindFileByName (
1676 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1677 IN CONST EFI_GUID
*FileName
,
1678 IN EFI_PEI_FV_HANDLE
*FvHandle
,
1679 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1683 PEI_CORE_INSTANCE
*PrivateData
;
1686 if ((FvHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1687 return EFI_INVALID_PARAMETER
;
1690 if (*FvHandle
!= NULL
) {
1691 Status
= FindFileEx (*FvHandle
, FileName
, 0, FileHandle
, NULL
);
1692 if (Status
== EFI_NOT_FOUND
) {
1697 // If *FvHandle = NULL, so search all FV for given filename
1699 Status
= EFI_NOT_FOUND
;
1701 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
1702 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1704 // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
1706 if (PrivateData
->Fv
[Index
].FvPpi
!= NULL
) {
1707 Status
= FindFileEx (PrivateData
->Fv
[Index
].FvHandle
, FileName
, 0, FileHandle
, NULL
);
1708 if (!EFI_ERROR (Status
)) {
1709 *FvHandle
= PrivateData
->Fv
[Index
].FvHandle
;
1720 Returns information about a specific file.
1722 This function returns information about a specific
1723 file, including its file name, type, attributes, starting
1726 @param This Points to this instance of the
1727 EFI_PEI_FIRMWARE_VOLUME_PPI.
1728 @param FileHandle Handle of the file.
1729 @param FileInfo Upon exit, points to the file's
1732 @retval EFI_SUCCESS File information returned.
1733 @retval EFI_INVALID_PARAMETER If FileHandle does not
1734 represent a valid file.
1735 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1740 PeiFfsFvPpiGetFileInfo (
1741 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1742 IN EFI_PEI_FILE_HANDLE FileHandle
,
1743 OUT EFI_FV_FILE_INFO
*FileInfo
1747 UINT8 ErasePolarity
;
1748 EFI_FFS_FILE_HEADER
*FileHeader
;
1749 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1750 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1752 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1753 return EFI_INVALID_PARAMETER
;
1757 // Retrieve the FirmwareVolume which the file resides in.
1759 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1760 if (CoreFvHandle
== NULL
) {
1761 return EFI_INVALID_PARAMETER
;
1764 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1766 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
1773 // Get FileState which is the highest bit of the State
1775 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
1777 switch (FileState
) {
1778 case EFI_FILE_DATA_VALID
:
1779 case EFI_FILE_MARKED_FOR_UPDATE
:
1782 return EFI_INVALID_PARAMETER
;
1785 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
1786 if (IS_FFS_FILE2 (FileHeader
)) {
1787 ASSERT (FFS_FILE2_SIZE (FileHeader
) > 0x00FFFFFF);
1788 if (!FwVolInstance
->IsFfs3Fv
) {
1789 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader
->Name
));
1790 return EFI_INVALID_PARAMETER
;
1792 FileInfo
->BufferSize
= FFS_FILE2_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
1793 FileInfo
->Buffer
= (UINT8
*) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
);
1795 FileInfo
->BufferSize
= FFS_FILE_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
1796 FileInfo
->Buffer
= (UINT8
*) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER
);
1798 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
1799 FileInfo
->FileType
= FileHeader
->Type
;
1800 FileInfo
->FileAttributes
= FfsAttributes2FvFileAttributes (FileHeader
->Attributes
);
1801 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_MEMORY_MAPPED
) == EFI_FVB2_MEMORY_MAPPED
) {
1802 FileInfo
->FileAttributes
|= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED
;
1808 Returns information about a specific file.
1810 This function returns information about a specific
1811 file, including its file name, type, attributes, starting
1812 address, size and authentication status.
1814 @param This Points to this instance of the
1815 EFI_PEI_FIRMWARE_VOLUME_PPI.
1816 @param FileHandle Handle of the file.
1817 @param FileInfo Upon exit, points to the file's
1820 @retval EFI_SUCCESS File information returned.
1821 @retval EFI_INVALID_PARAMETER If FileHandle does not
1822 represent a valid file.
1823 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1828 PeiFfsFvPpiGetFileInfo2 (
1829 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1830 IN EFI_PEI_FILE_HANDLE FileHandle
,
1831 OUT EFI_FV_FILE_INFO2
*FileInfo
1835 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1837 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1838 return EFI_INVALID_PARAMETER
;
1842 // Retrieve the FirmwareVolume which the file resides in.
1844 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1845 if (CoreFvHandle
== NULL
) {
1846 return EFI_INVALID_PARAMETER
;
1849 Status
= PeiFfsFvPpiGetFileInfo (This
, FileHandle
, (EFI_FV_FILE_INFO
*) FileInfo
);
1850 if (!EFI_ERROR (Status
)) {
1851 FileInfo
->AuthenticationStatus
= CoreFvHandle
->AuthenticationStatus
;
1858 This function returns information about the firmware volume.
1860 @param This Points to this instance of the
1861 EFI_PEI_FIRMWARE_VOLUME_PPI.
1862 @param FvHandle Handle to the firmware handle.
1863 @param VolumeInfo Points to the returned firmware volume
1866 @retval EFI_SUCCESS Information returned successfully.
1867 @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid
1868 firmware volume or VolumeInfo is NULL.
1873 PeiFfsFvPpiGetVolumeInfo (
1874 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1875 IN EFI_PEI_FV_HANDLE FvHandle
,
1876 OUT EFI_FV_INFO
*VolumeInfo
1879 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
1880 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
1882 if ((VolumeInfo
== NULL
) || (FvHandle
== NULL
)) {
1883 return EFI_INVALID_PARAMETER
;
1887 // VolumeHandle may not align at 8 byte,
1888 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
1889 // So, Copy FvHeader into the local FvHeader structure.
1891 CopyMem (&FwVolHeader
, FvHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
1894 // Check Fv Image Signature
1896 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
1897 return EFI_INVALID_PARAMETER
;
1900 ZeroMem (VolumeInfo
, sizeof (EFI_FV_INFO
));
1901 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
1902 VolumeInfo
->FvStart
= (VOID
*) FvHandle
;
1903 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
1904 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
1906 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
1907 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FvHandle
) + FwVolHeader
.ExtHeaderOffset
);
1908 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));
1915 Find the next matching section in the firmware file.
1917 This service enables PEI modules to discover sections
1918 of a given type within a valid file.
1920 @param This Points to this instance of the
1921 EFI_PEI_FIRMWARE_VOLUME_PPI.
1922 @param SearchType A filter to find only sections of this
1924 @param FileHandle Handle of firmware file in which to
1926 @param SectionData Updated upon return to point to the
1929 @retval EFI_SUCCESS Section was found.
1930 @retval EFI_NOT_FOUND Section of the specified type was not
1931 found. SectionData contains NULL.
1935 PeiFfsFvPpiFindSectionByType (
1936 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1937 IN EFI_SECTION_TYPE SearchType
,
1938 IN EFI_PEI_FILE_HANDLE FileHandle
,
1939 OUT VOID
**SectionData
1942 UINT32 AuthenticationStatus
;
1943 return PeiFfsFvPpiFindSectionByType2 (This
, SearchType
, 0, FileHandle
, SectionData
, &AuthenticationStatus
);
1947 Find the next matching section in the firmware file.
1949 This service enables PEI modules to discover sections
1950 of a given instance and type within a valid file.
1952 @param This Points to this instance of the
1953 EFI_PEI_FIRMWARE_VOLUME_PPI.
1954 @param SearchType A filter to find only sections of this
1956 @param SearchInstance A filter to find the specific instance
1958 @param FileHandle Handle of firmware file in which to
1960 @param SectionData Updated upon return to point to the
1962 @param AuthenticationStatus Updated upon return to point to the
1963 authentication status for this section.
1965 @retval EFI_SUCCESS Section was found.
1966 @retval EFI_NOT_FOUND Section of the specified type was not
1967 found. SectionData contains NULL.
1971 PeiFfsFvPpiFindSectionByType2 (
1972 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1973 IN EFI_SECTION_TYPE SearchType
,
1974 IN UINTN SearchInstance
,
1975 IN EFI_PEI_FILE_HANDLE FileHandle
,
1976 OUT VOID
**SectionData
,
1977 OUT UINT32
*AuthenticationStatus
1981 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
1983 EFI_COMMON_SECTION_HEADER
*Section
;
1984 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1985 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1987 UINT32 ExtractedAuthenticationStatus
;
1989 if (SectionData
== NULL
) {
1990 return EFI_NOT_FOUND
;
1993 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1996 // Retrieve the FirmwareVolume which the file resides in.
1998 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1999 if (CoreFvHandle
== NULL
) {
2000 return EFI_NOT_FOUND
;
2003 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
2005 if (IS_FFS_FILE2 (FfsFileHeader
)) {
2006 ASSERT (FFS_FILE2_SIZE (FfsFileHeader
) > 0x00FFFFFF);
2007 if (!FwVolInstance
->IsFfs3Fv
) {
2008 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
2009 return EFI_NOT_FOUND
;
2011 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
2012 FileSize
= FFS_FILE2_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
2014 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
2015 FileSize
= FFS_FILE_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
2018 Instance
= SearchInstance
+ 1;
2019 ExtractedAuthenticationStatus
= 0;
2020 Status
= ProcessSection (
2021 GetPeiServicesTablePointer (),
2027 &ExtractedAuthenticationStatus
,
2028 FwVolInstance
->IsFfs3Fv
2030 if (!EFI_ERROR (Status
)) {
2032 // Inherit the authentication status.
2034 *AuthenticationStatus
= ExtractedAuthenticationStatus
| CoreFvHandle
->AuthenticationStatus
;
2040 Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.
2042 @param FvHandle The handle of a FV.
2044 @retval NULL if can not find.
2045 @return Pointer of corresponding PEI_CORE_FV_HANDLE.
2047 PEI_CORE_FV_HANDLE
*
2048 FvHandleToCoreHandle (
2049 IN EFI_PEI_FV_HANDLE FvHandle
2053 PEI_CORE_INSTANCE
*PrivateData
;
2055 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
2056 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
2057 if (FvHandle
== PrivateData
->Fv
[Index
].FvHandle
) {
2058 return &PrivateData
->Fv
[Index
];
2066 Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.
2068 This routine also will install FvInfo ppi for FV hob in PI ways.
2070 @param Private Pointer of PEI_CORE_INSTANCE
2071 @param Instance The index of FV want to be searched.
2073 @return Instance of PEI_CORE_FV_HANDLE.
2075 PEI_CORE_FV_HANDLE
*
2076 FindNextCoreFvHandle (
2077 IN PEI_CORE_INSTANCE
*Private
,
2083 EFI_HOB_FIRMWARE_VOLUME
*FvHob
;
2086 // Handle Framework FvHob and Install FvInfo Ppi for it.
2088 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
2090 // Loop to search the wanted FirmwareVolume which supports FFS
2092 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetFirstHob (EFI_HOB_TYPE_FV
);
2093 while (FvHob
!= NULL
) {
2095 // Search whether FvHob has been installed into PeiCore's FV database.
2096 // If found, no need install new FvInfoPpi for it.
2098 for (Index
= 0, Match
= FALSE
; Index
< Private
->FvCount
; Index
++) {
2099 if ((EFI_PEI_FV_HANDLE
)(UINTN
)FvHob
->BaseAddress
== Private
->Fv
[Index
].FvHeader
) {
2106 // Search whether FvHob has been cached into PeiCore's Unknown FV database.
2107 // If found, no need install new FvInfoPpi for it.
2110 for (Index
= 0; Index
< Private
->UnknownFvInfoCount
; Index
++) {
2111 if ((UINTN
)FvHob
->BaseAddress
== (UINTN
)Private
->UnknownFvInfo
[Index
].FvInfo
) {
2119 // If the Fv in FvHob has not been installed into PeiCore's FV database and has
2120 // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi
2121 // for it then PeiCore will dispatch it in callback of FvInfoPpi.
2124 PeiServicesInstallFvInfoPpi (
2125 &(((EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)FvHob
->BaseAddress
)->FileSystemGuid
),
2126 (VOID
*)(UINTN
)FvHob
->BaseAddress
,
2127 (UINT32
)FvHob
->Length
,
2133 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetNextHob (EFI_HOB_TYPE_FV
, (VOID
*)((UINTN
)FvHob
+ FvHob
->Header
.HobLength
));
2137 ASSERT (Private
->FvCount
<= PcdGet32 (PcdPeiCoreMaxFvSupported
));
2138 if (Instance
>= Private
->FvCount
) {
2142 return &Private
->Fv
[Instance
];
2146 After PeiCore image is shadowed into permanent memory, all build-in FvPpi should
2147 be re-installed with the instance in permanent memory and all cached FvPpi pointers in
2148 PrivateData->Fv[] array should be fixed up to be pointed to the one in permanent
2151 @param PrivateData Pointer to PEI_CORE_INSTANCE.
2155 IN PEI_CORE_INSTANCE
*PrivateData
2159 EFI_PEI_PPI_DESCRIPTOR
*OldDescriptor
;
2164 // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
2167 Status
= PeiServicesLocatePpi (
2168 &gEfiFirmwareFileSystem2Guid
,
2173 ASSERT_EFI_ERROR (Status
);
2176 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
2177 // which is shadowed from flash to permanent memory within PeiCore image.
2179 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs2FvPpiList
);
2180 ASSERT_EFI_ERROR (Status
);
2183 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2185 for (Index
= 0; Index
< PcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
2186 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2187 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs2FwVol
.Fv
;
2192 // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which
2195 Status
= PeiServicesLocatePpi (
2196 &gEfiFirmwareFileSystem3Guid
,
2201 ASSERT_EFI_ERROR (Status
);
2204 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3
2205 // which is shadowed from flash to permanent memory within PeiCore image.
2207 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs3FvPpiList
);
2208 ASSERT_EFI_ERROR (Status
);
2211 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2213 for (Index
= 0; Index
< PcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
2214 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2215 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs3FwVol
.Fv
;
2221 Report the information for a new discoveried FV in unknown third-party format.
2223 If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but
2224 the FV in this format has been discoveried, then this FV's information will be cached into
2225 PEI_CORE_INSTANCE's UnknownFvInfo array.
2226 Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI
2227 is installed later by platform's PEIM, the original unknown third-party FV will be processed by
2228 using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2230 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2231 @param FvInfo2Ppi Point to FvInfo2 PPI.
2233 @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.
2234 @retval EFI_SUCCESS Success to add the information for unknown FV.
2237 AddUnknownFormatFvInfo (
2238 IN PEI_CORE_INSTANCE
*PrivateData
,
2239 IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
*FvInfo2Ppi
2242 PEI_CORE_UNKNOW_FORMAT_FV_INFO
*NewUnknownFv
;
2244 if (PrivateData
->UnknownFvInfoCount
+ 1 >= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
2245 return EFI_OUT_OF_RESOURCES
;
2248 NewUnknownFv
= &PrivateData
->UnknownFvInfo
[PrivateData
->UnknownFvInfoCount
];
2249 PrivateData
->UnknownFvInfoCount
++;
2251 CopyGuid (&NewUnknownFv
->FvFormat
, &FvInfo2Ppi
->FvFormat
);
2252 NewUnknownFv
->FvInfo
= FvInfo2Ppi
->FvInfo
;
2253 NewUnknownFv
->FvInfoSize
= FvInfo2Ppi
->FvInfoSize
;
2254 NewUnknownFv
->AuthenticationStatus
= FvInfo2Ppi
->AuthenticationStatus
;
2255 NewUnknownFv
->NotifyDescriptor
.Flags
= (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
);
2256 NewUnknownFv
->NotifyDescriptor
.Guid
= &NewUnknownFv
->FvFormat
;
2257 NewUnknownFv
->NotifyDescriptor
.Notify
= ThirdPartyFvPpiNotifyCallback
;
2259 PeiServicesNotifyPpi (&NewUnknownFv
->NotifyDescriptor
);
2264 Find the FV information according to third-party FV format guid.
2266 This routine also will remove the FV information found by given FV format guid from
2267 PrivateData->UnknownFvInfo[].
2269 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2270 @param Format Point to given FV format guid
2271 @param FvInfo On return, the pointer of FV information buffer
2272 @param FvInfoSize On return, the size of FV information buffer.
2273 @param AuthenticationStatus On return, the authentication status of FV information buffer.
2275 @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI
2276 @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2279 FindUnknownFormatFvInfo (
2280 IN PEI_CORE_INSTANCE
*PrivateData
,
2281 IN EFI_GUID
*Format
,
2283 OUT UINT32
*FvInfoSize
,
2284 OUT UINT32
*AuthenticationStatus
2291 for (; Index
< PrivateData
->UnknownFvInfoCount
; Index
++) {
2292 if (CompareGuid (Format
, &PrivateData
->UnknownFvInfo
[Index
].FvFormat
)) {
2297 if (Index
== PrivateData
->UnknownFvInfoCount
) {
2298 return EFI_NOT_FOUND
;
2301 *FvInfo
= PrivateData
->UnknownFvInfo
[Index
].FvInfo
;
2302 *FvInfoSize
= PrivateData
->UnknownFvInfo
[Index
].FvInfoSize
;
2303 *AuthenticationStatus
= PrivateData
->UnknownFvInfo
[Index
].AuthenticationStatus
;
2306 // Remove an entry from UnknownFvInfo array.
2309 for (;Index2
< PrivateData
->UnknownFvInfoCount
; Index2
++, Index
++) {
2310 CopyMem (&PrivateData
->UnknownFvInfo
[Index
], &PrivateData
->UnknownFvInfo
[Index2
], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO
));
2312 PrivateData
->UnknownFvInfoCount
--;
2317 Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.
2319 When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this
2320 routine is called to process all discoveried FVs in this format.
2322 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
2323 @param NotifyDescriptor Address of the notification descriptor data structure.
2324 @param Ppi Address of the PPI that was installed.
2326 @retval EFI_SUCCESS The notification callback is processed correctly.
2330 ThirdPartyFvPpiNotifyCallback (
2331 IN EFI_PEI_SERVICES
**PeiServices
,
2332 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
2336 PEI_CORE_INSTANCE
*PrivateData
;
2337 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
2340 UINT32 AuthenticationStatus
;
2342 EFI_PEI_FV_HANDLE FvHandle
;
2343 BOOLEAN IsProcessed
;
2345 EFI_PEI_FILE_HANDLE FileHandle
;
2349 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
2350 FvPpi
= (EFI_PEI_FIRMWARE_VOLUME_PPI
*) Ppi
;
2353 Status
= FindUnknownFormatFvInfo (PrivateData
, NotifyDescriptor
->Guid
, &FvInfo
, &FvInfoSize
, &AuthenticationStatus
);
2354 if (EFI_ERROR (Status
)) {
2359 // Process new found FV and get FV handle.
2361 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo
, FvInfoSize
, &FvHandle
);
2362 if (EFI_ERROR (Status
)) {
2363 DEBUG ((EFI_D_ERROR
, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo
));
2368 // Check whether the FV has already been processed.
2370 IsProcessed
= FALSE
;
2371 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
2372 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
2373 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfo
));
2383 if (PrivateData
->FvCount
>= PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
2384 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, PcdGet32 (PcdPeiCoreMaxFvSupported
)));
2385 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
2390 // Update internal PEI_CORE_FV array.
2392 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo
;
2393 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
2394 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
2395 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= AuthenticationStatus
;
2396 CurFvCount
= PrivateData
->FvCount
;
2399 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
2400 (UINT32
) CurFvCount
,
2405 PrivateData
->FvCount
++;
2408 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
2412 Status
= FvPpi
->FindFileByType (
2414 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
2418 if (!EFI_ERROR (Status
)) {
2419 Status
= FvPpi
->FindSectionByType (
2421 EFI_SECTION_PEI_DEPEX
,
2425 if (!EFI_ERROR (Status
)) {
2426 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
2428 // Dependency is not satisfied.
2434 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, CurFvCount
, FvHandle
));
2435 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[CurFvCount
], FileHandle
);
2437 } while (FileHandle
!= NULL
);