2 Pei Core Firmware File System service routines.
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList
[] = {
19 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
20 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
21 FirmwareVolmeInfoPpiNotifyCallback
24 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
25 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
26 FirmwareVolmeInfoPpiNotifyCallback
30 PEI_FW_VOL_INSTANCE mPeiFfs2FwVol
= {
34 PeiFfsFvPpiProcessVolume
,
35 PeiFfsFvPpiFindFileByType
,
36 PeiFfsFvPpiFindFileByName
,
37 PeiFfsFvPpiGetFileInfo
,
38 PeiFfsFvPpiGetVolumeInfo
,
39 PeiFfsFvPpiFindSectionByType
,
40 PeiFfsFvPpiGetFileInfo2
,
41 PeiFfsFvPpiFindSectionByType2
,
42 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
,
43 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
47 PEI_FW_VOL_INSTANCE mPeiFfs3FwVol
= {
51 PeiFfsFvPpiProcessVolume
,
52 PeiFfsFvPpiFindFileByType
,
53 PeiFfsFvPpiFindFileByName
,
54 PeiFfsFvPpiGetFileInfo
,
55 PeiFfsFvPpiGetVolumeInfo
,
56 PeiFfsFvPpiFindSectionByType
,
57 PeiFfsFvPpiGetFileInfo2
,
58 PeiFfsFvPpiFindSectionByType2
,
59 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
,
60 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
64 EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList
= {
65 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
66 &gEfiFirmwareFileSystem2Guid
,
70 EFI_PEI_PPI_DESCRIPTOR mPeiFfs3FvPpiList
= {
71 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
72 &gEfiFirmwareFileSystem3Guid
,
77 Required Alignment Alignment Value in FFS Alignment Value in
78 (bytes) Attributes Field Firmware Volume Interfaces
88 UINT8 mFvAttributes
[] = {0, 4, 7, 9, 10, 12, 15, 16};
91 Convert the FFS File Attributes to FV File Attributes
93 @param FfsAttributes The attributes of UINT8 type.
95 @return The attributes of EFI_FV_FILE_ATTRIBUTES
98 EFI_FV_FILE_ATTRIBUTES
99 FfsAttributes2FvFileAttributes (
100 IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
104 EFI_FV_FILE_ATTRIBUTES FileAttribute
;
106 DataAlignment
= (UINT8
) ((FfsAttributes
& FFS_ATTRIB_DATA_ALIGNMENT
) >> 3);
107 ASSERT (DataAlignment
< 8);
109 FileAttribute
= (EFI_FV_FILE_ATTRIBUTES
) mFvAttributes
[DataAlignment
];
111 if ((FfsAttributes
& FFS_ATTRIB_FIXED
) == FFS_ATTRIB_FIXED
) {
112 FileAttribute
|= EFI_FV_FILE_ATTRIB_FIXED
;
115 return FileAttribute
;
119 Returns the file state set by the highest zero bit in the State field
121 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
122 in the Attributes field.
123 @param FfsHeader Pointer to FFS File Header.
125 @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit
126 in the header State field.
130 IN UINT8 ErasePolarity
,
131 IN EFI_FFS_FILE_HEADER
*FfsHeader
134 EFI_FFS_FILE_STATE FileState
;
135 EFI_FFS_FILE_STATE HighestBit
;
137 FileState
= FfsHeader
->State
;
139 if (ErasePolarity
!= 0) {
140 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
144 // Get file state set by its highest none zero bit.
147 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
155 Calculates the checksum of the header of a file.
157 @param FileHeader Pointer to FFS File Header.
159 @return Checksum of the header.
160 Zero means the header is good.
161 Non-zero means the header is bad.
164 CalculateHeaderChecksum (
165 IN EFI_FFS_FILE_HEADER
*FileHeader
168 EFI_FFS_FILE_HEADER2 TestFileHeader
;
170 if (IS_FFS_FILE2 (FileHeader
)) {
171 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER2
));
173 // Ingore State and File field in FFS header.
175 TestFileHeader
.State
= 0;
176 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
178 return CalculateSum8 ((CONST UINT8
*) &TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER2
));
180 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
182 // Ingore State and File field in FFS header.
184 TestFileHeader
.State
= 0;
185 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
187 return CalculateSum8 ((CONST UINT8
*) &TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
192 Find FV handler according to FileHandle in that FV.
194 @param FileHandle Handle of file image
196 @return Pointer to instance of PEI_CORE_FV_HANDLE.
200 IN EFI_PEI_FILE_HANDLE FileHandle
204 PEI_CORE_INSTANCE
*PrivateData
;
205 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
207 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
209 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
210 FwVolHeader
= PrivateData
->Fv
[Index
].FvHeader
;
211 if (((UINT64
) (UINTN
) FileHandle
> (UINT64
) (UINTN
) FwVolHeader
) && \
212 ((UINT64
) (UINTN
) FileHandle
<= ((UINT64
) (UINTN
) FwVolHeader
+ FwVolHeader
->FvLength
- 1))) {
213 return &PrivateData
->Fv
[Index
];
220 Given the input file pointer, search for the first matching file in the
221 FFS volume as defined by SearchType. The search starts from FileHeader inside
222 the Firmware Volume defined by FwVolHeader.
223 If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.
224 If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
225 the first PEIM, or COMBINED PEIM or FV file type FFS file will return.
227 @param FvHandle Pointer to the FV header of the volume to search
228 @param FileName File name
229 @param SearchType Filter to find only files of this type.
230 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
231 @param FileHandle This parameter must point to a valid FFS volume.
232 @param AprioriFile Pointer to AprioriFile image in this FV if has
234 @return EFI_NOT_FOUND No files matching the search criteria were found
235 @retval EFI_SUCCESS Success to search given file
240 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
241 IN CONST EFI_GUID
*FileName
, OPTIONAL
242 IN EFI_FV_FILETYPE SearchType
,
243 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
,
244 IN OUT EFI_PEI_FILE_HANDLE
*AprioriFile OPTIONAL
247 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
248 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExtHeader
;
249 EFI_FFS_FILE_HEADER
**FileHeader
;
250 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
252 UINT32 FileOccupiedSize
;
261 // Convert the handle of FV to FV header for memory-mapped firmware volume
263 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvHandle
;
264 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
266 IsFfs3Fv
= CompareGuid (&FwVolHeader
->FileSystemGuid
, &gEfiFirmwareFileSystem3Guid
);
268 FvLength
= FwVolHeader
->FvLength
;
269 if ((FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
276 // If FileHeader is not specified (NULL) or FileName is not NULL,
277 // start with the first file in the firmware volume. Otherwise,
278 // start from the FileHeader.
280 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
281 if (FwVolHeader
->ExtHeaderOffset
!= 0) {
283 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
285 FwVolExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) ((UINT8
*) FwVolHeader
+ FwVolHeader
->ExtHeaderOffset
);
286 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FwVolExtHeader
+ FwVolExtHeader
->ExtHeaderSize
);
287 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ALIGN_POINTER (FfsFileHeader
, 8);
289 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*) FwVolHeader
+ FwVolHeader
->HeaderLength
);
292 if (IS_FFS_FILE2 (*FileHeader
)) {
294 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader
)->Name
));
296 FileLength
= FFS_FILE2_SIZE (*FileHeader
);
297 ASSERT (FileLength
> 0x00FFFFFF);
299 FileLength
= FFS_FILE_SIZE (*FileHeader
);
302 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
304 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
305 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
308 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
309 ASSERT (FileOffset
<= 0xFFFFFFFF);
311 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
313 // Get FileState which is the highest bit of the State
315 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
318 case EFI_FILE_HEADER_CONSTRUCTION
:
319 case EFI_FILE_HEADER_INVALID
:
320 if (IS_FFS_FILE2 (FfsFileHeader
)) {
322 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
324 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER2
);
325 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
327 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER
);
328 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
332 case EFI_FILE_DATA_VALID
:
333 case EFI_FILE_MARKED_FOR_UPDATE
:
334 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
337 return EFI_NOT_FOUND
;
340 if (IS_FFS_FILE2 (FfsFileHeader
)) {
341 FileLength
= FFS_FILE2_SIZE (FfsFileHeader
);
342 ASSERT (FileLength
> 0x00FFFFFF);
343 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
345 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
346 FileOffset
+= FileOccupiedSize
;
347 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ FileOccupiedSize
);
351 FileLength
= FFS_FILE_SIZE (FfsFileHeader
);
352 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
355 DataCheckSum
= FFS_FIXED_CHECKSUM
;
356 if ((FfsFileHeader
->Attributes
& FFS_ATTRIB_CHECKSUM
) == FFS_ATTRIB_CHECKSUM
) {
357 if (IS_FFS_FILE2 (FfsFileHeader
)) {
358 DataCheckSum
= CalculateCheckSum8 ((CONST UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
), FileLength
- sizeof(EFI_FFS_FILE_HEADER2
));
360 DataCheckSum
= CalculateCheckSum8 ((CONST UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
), FileLength
- sizeof(EFI_FFS_FILE_HEADER
));
363 if (FfsFileHeader
->IntegrityCheck
.Checksum
.File
!= DataCheckSum
) {
366 return EFI_NOT_FOUND
;
369 if (FileName
!= NULL
) {
370 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
371 *FileHeader
= FfsFileHeader
;
374 } else if (SearchType
== PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
) {
375 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
376 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
) ||
377 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
)) {
379 *FileHeader
= FfsFileHeader
;
381 } else if (AprioriFile
!= NULL
) {
382 if (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FREEFORM
) {
383 if (CompareGuid (&FfsFileHeader
->Name
, &gPeiAprioriFileNameGuid
)) {
384 *AprioriFile
= FfsFileHeader
;
388 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
389 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
390 *FileHeader
= FfsFileHeader
;
394 FileOffset
+= FileOccupiedSize
;
395 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
398 case EFI_FILE_DELETED
:
399 if (IS_FFS_FILE2 (FfsFileHeader
)) {
401 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
403 FileLength
= FFS_FILE2_SIZE (FfsFileHeader
);
404 ASSERT (FileLength
> 0x00FFFFFF);
406 FileLength
= FFS_FILE_SIZE (FfsFileHeader
);
408 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
409 FileOffset
+= FileOccupiedSize
;
410 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
415 return EFI_NOT_FOUND
;
420 return EFI_NOT_FOUND
;
424 Initialize PeiCore Fv List.
426 @param PrivateData - Pointer to PEI_CORE_INSTANCE.
427 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
431 IN PEI_CORE_INSTANCE
*PrivateData
,
432 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
436 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
437 EFI_PEI_FV_HANDLE FvHandle
;
438 EFI_FIRMWARE_VOLUME_HEADER
*BfvHeader
;
441 // Install FV_PPI for FFS2 file system.
443 PeiServicesInstallPpi (&mPeiFfs2FvPpiList
);
446 // Install FV_PPI for FFS3 file system.
448 PeiServicesInstallPpi (&mPeiFfs3FvPpiList
);
450 BfvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
453 // The FV_PPI in BFV's format should be installed.
455 Status
= PeiServicesLocatePpi (
456 &BfvHeader
->FileSystemGuid
,
461 ASSERT_EFI_ERROR (Status
);
466 FvPpi
->ProcessVolume (
468 SecCoreData
->BootFirmwareVolumeBase
,
469 (UINTN
)BfvHeader
->FvLength
,
474 // Update internal PEI_CORE_FV array.
476 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= BfvHeader
;
477 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
478 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
479 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= 0;
482 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
483 (UINT32
) PrivateData
->FvCount
,
488 PrivateData
->FvCount
++;
491 // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose
492 // additional Fvs to PeiCore.
494 Status
= PeiServicesNotifyPpi (mNotifyOnFvInfoList
);
495 ASSERT_EFI_ERROR (Status
);
500 Process Firmware Volum Information once FvInfoPPI or FvInfo2PPI install.
501 The FV Info will be registered into PeiCore private data structure.
502 And search the inside FV image, if found, the new FV INFO(2) PPI will be installed.
504 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
505 @param NotifyDescriptor Address of the notification descriptor data structure.
506 @param Ppi Address of the PPI that was installed.
508 @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.
509 @return if not EFI_SUCESS, fail to verify FV.
514 FirmwareVolmeInfoPpiNotifyCallback (
515 IN EFI_PEI_SERVICES
**PeiServices
,
516 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
520 EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI FvInfo2Ppi
;
521 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
522 PEI_CORE_INSTANCE
*PrivateData
;
524 EFI_PEI_FV_HANDLE FvHandle
;
526 EFI_PEI_FILE_HANDLE FileHandle
;
530 Status
= EFI_SUCCESS
;
531 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
533 if (PrivateData
->FvCount
>= FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
534 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)));
535 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
539 if (CompareGuid (NotifyDescriptor
->Guid
, &gEfiPeiFirmwareVolumeInfo2PpiGuid
)) {
543 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
));
549 CopyMem (&FvInfo2Ppi
, Ppi
, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
));
550 FvInfo2Ppi
.AuthenticationStatus
= 0;
555 // Locate the corresponding FV_PPI according to founded FV's format guid
557 Status
= PeiServicesLocatePpi (
558 &FvInfo2Ppi
.FvFormat
,
563 if (!EFI_ERROR (Status
)) {
565 // Process new found FV and get FV handle.
567 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo2Ppi
.FvInfo
, FvInfo2Ppi
.FvInfoSize
, &FvHandle
);
568 if (EFI_ERROR (Status
)) {
569 DEBUG ((EFI_D_ERROR
, "Fail to process new found FV, FV may be corrupted!\n"));
574 // Check whether the FV has already been processed.
576 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
577 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
578 if (IsFvInfo2
&& (FvInfo2Ppi
.AuthenticationStatus
!= PrivateData
->Fv
[FvIndex
].AuthenticationStatus
)) {
579 PrivateData
->Fv
[FvIndex
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
580 DEBUG ((EFI_D_INFO
, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex
, FvInfo2Ppi
.AuthenticationStatus
));
582 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfo2Ppi
.FvInfo
));
588 // Update internal PEI_CORE_FV array.
590 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo2Ppi
.FvInfo
;
591 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
592 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
593 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= FvInfo2Ppi
.AuthenticationStatus
;
596 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
597 (UINT32
) PrivateData
->FvCount
,
598 (VOID
*) FvInfo2Ppi
.FvInfo
,
599 FvInfo2Ppi
.FvInfoSize
,
602 PrivateData
->FvCount
++;
605 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
609 Status
= FvPpi
->FindFileByType (
611 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
615 if (!EFI_ERROR (Status
)) {
616 Status
= FvPpi
->FindSectionByType (
618 EFI_SECTION_PEI_DEPEX
,
622 if (!EFI_ERROR (Status
)) {
623 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
625 // Dependency is not satisfied.
631 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, PrivateData
->FvCount
- 1, FvHandle
));
632 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[PrivateData
->FvCount
- 1], FileHandle
);
634 } while (FileHandle
!= NULL
);
636 DEBUG ((EFI_D_ERROR
, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi
.FvInfo
));
638 AddUnknownFormatFvInfo (PrivateData
, &FvInfo2Ppi
);
645 Verify the Guided Section GUID by checking if there is the Guided Section GUID HOB recorded the GUID itself.
647 @param GuidedSectionGuid The Guided Section GUID.
648 @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Ppi
649 for the Guided Section.
651 @return TRUE The GuidedSectionGuid could be identified, and the pointer to
652 the Guided Section Extraction Ppi will be returned to *GuidedSectionExtraction.
653 @return FALSE The GuidedSectionGuid could not be identified, or
654 the Guided Section Extraction Ppi has not been installed yet.
658 VerifyGuidedSectionGuid (
659 IN EFI_GUID
*GuidedSectionGuid
,
660 OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
**GuidedSectionExtraction
663 EFI_PEI_HOB_POINTERS Hob
;
664 EFI_GUID
*GuidRecorded
;
669 // Check if there is the Guided Section GUID HOB recorded the GUID itself.
671 Hob
.Raw
= GetFirstGuidHob (GuidedSectionGuid
);
672 if (Hob
.Raw
!= NULL
) {
673 GuidRecorded
= (EFI_GUID
*) GET_GUID_HOB_DATA (Hob
);
674 if (CompareGuid (GuidRecorded
, GuidedSectionGuid
)) {
676 // Found the recorded GuidedSectionGuid.
678 Status
= PeiServicesLocatePpi (GuidedSectionGuid
, 0, NULL
, (VOID
**) &Interface
);
679 if (!EFI_ERROR (Status
) && Interface
!= NULL
) {
681 // Found the supported Guided Section Extraction Ppi for the Guided Section.
683 *GuidedSectionExtraction
= (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*) Interface
;
694 Go through the file to search SectionType section.
695 Search within encapsulation sections (compression and GUIDed) recursively,
696 until the match section is found.
698 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
699 @param SectionType Filter to find only section of this type.
700 @param SectionInstance Pointer to the filter to find the specific instance of section.
701 @param Section From where to search.
702 @param SectionSize The file size to search.
703 @param OutputBuffer A pointer to the discovered section, if successful.
704 NULL if section not found
705 @param AuthenticationStatus Updated upon return to point to the authentication status for this section.
706 @param IsFfs3Fv Indicates the FV format.
708 @return EFI_NOT_FOUND The match section is not found.
709 @return EFI_SUCCESS The match section is found.
714 IN CONST EFI_PEI_SERVICES
**PeiServices
,
715 IN EFI_SECTION_TYPE SectionType
,
716 IN OUT UINTN
*SectionInstance
,
717 IN EFI_COMMON_SECTION_HEADER
*Section
,
718 IN UINTN SectionSize
,
719 OUT VOID
**OutputBuffer
,
720 OUT UINT32
*AuthenticationStatus
,
725 UINT32 SectionLength
;
727 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
728 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
732 UINT32 Authentication
;
733 PEI_CORE_INSTANCE
*PrivateData
;
734 EFI_GUID
*SectionDefinitionGuid
;
735 BOOLEAN SectionCached
;
736 VOID
*TempOutputBuffer
;
737 UINT32 TempAuthenticationStatus
;
739 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
740 *OutputBuffer
= NULL
;
743 Status
= EFI_NOT_FOUND
;
746 while (ParsedLength
< SectionSize
) {
748 if (IS_SECTION2 (Section
)) {
749 ASSERT (SECTION2_SIZE (Section
) > 0x00FFFFFF);
751 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
752 SectionLength
= SECTION2_SIZE (Section
);
754 // SectionLength is adjusted it is 4 byte aligned.
755 // Go to the next section
757 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
758 ASSERT (SectionLength
!= 0);
759 ParsedLength
+= SectionLength
;
760 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ SectionLength
);
765 if (Section
->Type
== SectionType
) {
767 // The type matches, so check the instance count to see if it's the one we want.
769 (*SectionInstance
)--;
770 if (*SectionInstance
== 0) {
774 if (IS_SECTION2 (Section
)) {
775 *OutputBuffer
= (VOID
*)((UINT8
*) Section
+ sizeof (EFI_COMMON_SECTION_HEADER2
));
777 *OutputBuffer
= (VOID
*)((UINT8
*) Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
781 if (IS_SECTION2 (Section
)) {
782 SectionLength
= SECTION2_SIZE (Section
);
784 SectionLength
= SECTION_SIZE (Section
);
787 // SectionLength is adjusted it is 4 byte aligned.
788 // Go to the next section
790 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
791 ASSERT (SectionLength
!= 0);
792 ParsedLength
+= SectionLength
;
793 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
796 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
798 // Check the encapsulated section is extracted into the cache data.
800 SectionCached
= FALSE
;
801 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
802 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
803 SectionCached
= TRUE
;
804 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
805 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
806 Authentication
= PrivateData
->CacheSection
.AuthenticationStatus
[Index
];
808 // Search section directly from the cache data.
810 TempAuthenticationStatus
= 0;
811 Status
= ProcessSection (
818 &TempAuthenticationStatus
,
821 if (!EFI_ERROR (Status
)) {
822 *OutputBuffer
= TempOutputBuffer
;
823 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
830 // If SectionCached is TRUE, the section data has been cached and scanned.
832 if (!SectionCached
) {
833 Status
= EFI_NOT_FOUND
;
835 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
836 if (IS_SECTION2 (Section
)) {
837 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION2
*)Section
)->SectionDefinitionGuid
;
839 SectionDefinitionGuid
= &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
;
841 if (VerifyGuidedSectionGuid (SectionDefinitionGuid
, &GuidSectionPpi
)) {
842 Status
= GuidSectionPpi
->ExtractSection (
850 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
851 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**) &DecompressPpi
);
852 if (!EFI_ERROR (Status
)) {
853 Status
= DecompressPpi
->Decompress (
855 (CONST EFI_COMPRESSION_SECTION
*) Section
,
862 if (!EFI_ERROR (Status
)) {
864 // Update cache section data.
866 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
867 PrivateData
->CacheSection
.AllSectionCount
++;
869 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
870 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
871 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
872 PrivateData
->CacheSection
.AuthenticationStatus
[PrivateData
->CacheSection
.SectionIndex
] = Authentication
;
873 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
875 TempAuthenticationStatus
= 0;
876 Status
= ProcessSection (
883 &TempAuthenticationStatus
,
886 if (!EFI_ERROR (Status
)) {
887 *OutputBuffer
= TempOutputBuffer
;
888 *AuthenticationStatus
= TempAuthenticationStatus
| Authentication
;
895 if (IS_SECTION2 (Section
)) {
896 SectionLength
= SECTION2_SIZE (Section
);
898 SectionLength
= SECTION_SIZE (Section
);
901 // SectionLength is adjusted it is 4 byte aligned.
902 // Go to the next section
904 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
905 ASSERT (SectionLength
!= 0);
906 ParsedLength
+= SectionLength
;
907 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
910 return EFI_NOT_FOUND
;
915 Searches for the next matching section within the specified file.
917 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
918 @param SectionType Filter to find only sections of this type.
919 @param FileHandle Pointer to the current file to search.
920 @param SectionData A pointer to the discovered section, if successful.
921 NULL if section not found
923 @retval EFI_NOT_FOUND The section was not found.
924 @retval EFI_SUCCESS The section was found.
929 PeiFfsFindSectionData (
930 IN CONST EFI_PEI_SERVICES
**PeiServices
,
931 IN EFI_SECTION_TYPE SectionType
,
932 IN EFI_PEI_FILE_HANDLE FileHandle
,
933 OUT VOID
**SectionData
936 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
938 CoreFvHandle
= FileHandleToVolume (FileHandle
);
939 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
940 return EFI_NOT_FOUND
;
943 return CoreFvHandle
->FvPpi
->FindSectionByType (CoreFvHandle
->FvPpi
, SectionType
, FileHandle
, SectionData
);
947 Searches for the next matching section within the specified file.
949 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
950 @param SectionType The value of the section type to find.
951 @param SectionInstance Section instance to find.
952 @param FileHandle Handle of the firmware file to search.
953 @param SectionData A pointer to the discovered section, if successful.
954 @param AuthenticationStatus A pointer to the authentication status for this section.
956 @retval EFI_SUCCESS The section was found.
957 @retval EFI_NOT_FOUND The section was not found.
962 PeiFfsFindSectionData3 (
963 IN CONST EFI_PEI_SERVICES
**PeiServices
,
964 IN EFI_SECTION_TYPE SectionType
,
965 IN UINTN SectionInstance
,
966 IN EFI_PEI_FILE_HANDLE FileHandle
,
967 OUT VOID
**SectionData
,
968 OUT UINT32
*AuthenticationStatus
971 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
973 CoreFvHandle
= FileHandleToVolume (FileHandle
);
974 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
975 return EFI_NOT_FOUND
;
978 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
979 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
980 return CoreFvHandle
->FvPpi
->FindSectionByType2 (CoreFvHandle
->FvPpi
, SectionType
, SectionInstance
, FileHandle
, SectionData
, AuthenticationStatus
);
983 // The old FvPpi doesn't support to find section by section instance
984 // and return authentication status, so return EFI_UNSUPPORTED.
986 return EFI_UNSUPPORTED
;
990 Searches for the next matching file in the firmware volume.
992 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
993 @param SearchType Filter to find only files of this type.
994 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
995 @param FvHandle Handle of firmware volume in which to search.
996 @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
997 at the beginning of the firmware volume. On exit, points the file handle of the next file
998 in the volume or NULL if there are no more files.
1000 @retval EFI_NOT_FOUND The file was not found.
1001 @retval EFI_NOT_FOUND The header checksum was not zero.
1002 @retval EFI_SUCCESS The file was found.
1007 PeiFfsFindNextFile (
1008 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1009 IN UINT8 SearchType
,
1010 IN EFI_PEI_FV_HANDLE FvHandle
,
1011 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1014 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1016 CoreFvHandle
= FvHandleToCoreHandle (FvHandle
);
1019 // To make backward compatiblity, if can not find corresponding the handle of FV
1020 // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed
1021 // to the address of first byte of FV.
1023 if ((CoreFvHandle
== NULL
) && FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
1024 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1027 if ((CoreFvHandle
== NULL
) || CoreFvHandle
->FvPpi
== NULL
) {
1028 return EFI_NOT_FOUND
;
1031 return CoreFvHandle
->FvPpi
->FindFileByType (CoreFvHandle
->FvPpi
, SearchType
, FvHandle
, FileHandle
);
1036 Search the firmware volumes by index
1038 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
1039 @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
1041 @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
1043 @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
1044 @retval EFI_NOT_FOUND The volume was not found.
1045 @retval EFI_SUCCESS The volume was found.
1050 PeiFfsFindNextVolume (
1051 IN CONST EFI_PEI_SERVICES
**PeiServices
,
1053 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
1056 PEI_CORE_INSTANCE
*Private
;
1057 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1059 if (VolumeHandle
== NULL
) {
1060 return EFI_INVALID_PARAMETER
;
1063 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
1065 CoreFvHandle
= FindNextCoreFvHandle (Private
, Instance
);
1066 if (CoreFvHandle
== NULL
) {
1067 *VolumeHandle
= NULL
;
1068 return EFI_NOT_FOUND
;
1071 *VolumeHandle
= CoreFvHandle
->FvHandle
;
1078 Find a file within a volume by its name.
1080 @param FileName A pointer to the name of the file to find within the firmware volume.
1081 @param VolumeHandle The firmware volume to search
1082 @param FileHandle Upon exit, points to the found file's handle
1083 or NULL if it could not be found.
1085 @retval EFI_SUCCESS File was found.
1086 @retval EFI_NOT_FOUND File was not found.
1087 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
1092 PeiFfsFindFileByName (
1093 IN CONST EFI_GUID
*FileName
,
1094 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1095 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1098 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1100 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1101 return EFI_INVALID_PARAMETER
;
1104 CoreFvHandle
= FvHandleToCoreHandle (VolumeHandle
);
1105 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1106 return EFI_NOT_FOUND
;
1109 return CoreFvHandle
->FvPpi
->FindFileByName (CoreFvHandle
->FvPpi
, FileName
, &VolumeHandle
, FileHandle
);
1113 Returns information about a specific file.
1115 @param FileHandle Handle of the file.
1116 @param FileInfo Upon exit, points to the file's information.
1118 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1119 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1120 @retval EFI_SUCCESS File information returned.
1126 IN EFI_PEI_FILE_HANDLE FileHandle
,
1127 OUT EFI_FV_FILE_INFO
*FileInfo
1130 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1132 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1133 return EFI_INVALID_PARAMETER
;
1137 // Retrieve the FirmwareVolume which the file resides in.
1139 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1140 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1141 return EFI_INVALID_PARAMETER
;
1144 return CoreFvHandle
->FvPpi
->GetFileInfo (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1148 Returns information about a specific file.
1150 @param FileHandle Handle of the file.
1151 @param FileInfo Upon exit, points to the file's information.
1153 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1154 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
1155 @retval EFI_SUCCESS File information returned.
1160 PeiFfsGetFileInfo2 (
1161 IN EFI_PEI_FILE_HANDLE FileHandle
,
1162 OUT EFI_FV_FILE_INFO2
*FileInfo
1165 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1167 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1168 return EFI_INVALID_PARAMETER
;
1172 // Retrieve the FirmwareVolume which the file resides in.
1174 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1175 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
1176 return EFI_INVALID_PARAMETER
;
1179 if ((CoreFvHandle
->FvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1180 (CoreFvHandle
->FvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1181 return CoreFvHandle
->FvPpi
->GetFileInfo2 (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
1184 // The old FvPpi doesn't support to return file info with authentication status,
1185 // so return EFI_UNSUPPORTED.
1187 return EFI_UNSUPPORTED
;
1191 Returns information about the specified volume.
1193 This function returns information about a specific firmware
1194 volume, including its name, type, attributes, starting address
1197 @param VolumeHandle Handle of the volume.
1198 @param VolumeInfo Upon exit, points to the volume's information.
1200 @retval EFI_SUCCESS Volume information returned.
1201 @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
1202 @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
1203 @retval EFI_SUCCESS Information successfully returned.
1204 @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
1209 PeiFfsGetVolumeInfo (
1210 IN EFI_PEI_FV_HANDLE VolumeHandle
,
1211 OUT EFI_FV_INFO
*VolumeInfo
1214 PEI_CORE_FV_HANDLE
*CoreHandle
;
1216 if ((VolumeInfo
== NULL
) || (VolumeHandle
== NULL
)) {
1217 return EFI_INVALID_PARAMETER
;
1220 CoreHandle
= FvHandleToCoreHandle (VolumeHandle
);
1222 if ((CoreHandle
== NULL
) || (CoreHandle
->FvPpi
== NULL
)) {
1223 return EFI_INVALID_PARAMETER
;
1226 return CoreHandle
->FvPpi
->GetVolumeInfo (CoreHandle
->FvPpi
, VolumeHandle
, VolumeInfo
);
1230 Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob.
1232 @param PrivateData PeiCore's private data structure
1233 @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.
1234 @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image.
1236 @retval EFI_NOT_FOUND FV image can't be found.
1237 @retval EFI_SUCCESS Successfully to process it.
1238 @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image
1239 @retval EFI_SECURITY_VIOLATION Image is illegal
1240 @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section
1245 IN PEI_CORE_INSTANCE
*PrivateData
,
1246 IN PEI_CORE_FV_HANDLE
*ParentFvCoreHandle
,
1247 IN EFI_PEI_FILE_HANDLE ParentFvFileHandle
1251 EFI_FV_INFO ParentFvImageInfo
;
1254 EFI_PEI_HOB_POINTERS HobPtr
;
1255 EFI_PEI_FIRMWARE_VOLUME_PPI
*ParentFvPpi
;
1256 EFI_PEI_FV_HANDLE ParentFvHandle
;
1257 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
1258 EFI_FV_FILE_INFO FileInfo
;
1260 UINT32 AuthenticationStatus
;
1263 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
1266 HobPtr
.Raw
= GetHobList ();
1267 while ((HobPtr
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobPtr
.Raw
)) != NULL
) {
1268 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)ParentFvFileHandle
)->Name
), &HobPtr
.FirmwareVolume2
->FileName
)) {
1270 // this FILE has been dispatched, it will not be dispatched again.
1272 DEBUG ((EFI_D_INFO
, "FV file %p has been dispatched!\r\n", ParentFvFileHandle
));
1275 HobPtr
.Raw
= GET_NEXT_HOB (HobPtr
);
1278 ParentFvHandle
= ParentFvCoreHandle
->FvHandle
;
1279 ParentFvPpi
= ParentFvCoreHandle
->FvPpi
;
1282 // Find FvImage in FvFile
1284 AuthenticationStatus
= 0;
1285 if ((ParentFvPpi
->Signature
== EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE
) &&
1286 (ParentFvPpi
->Revision
== EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
)) {
1287 Status
= ParentFvPpi
->FindSectionByType2 (
1289 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1293 &AuthenticationStatus
1296 Status
= ParentFvPpi
->FindSectionByType (
1298 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
1303 if (EFI_ERROR (Status
)) {
1307 Status
= VerifyPeim (PrivateData
, ParentFvHandle
, ParentFvFileHandle
, AuthenticationStatus
);
1308 if (Status
== EFI_SECURITY_VIOLATION
) {
1313 // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
1314 // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
1315 // its initial linked location and maintain its alignment.
1317 if ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_WEAK_ALIGNMENT
) != EFI_FVB2_WEAK_ALIGNMENT
) {
1319 // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
1321 FvAlignment
= 1 << ((ReadUnaligned32 (&FvHeader
->Attributes
) & EFI_FVB2_ALIGNMENT
) >> 16);
1322 if (FvAlignment
< 8) {
1329 if ((UINTN
) FvHeader
% FvAlignment
!= 0) {
1330 FvLength
= ReadUnaligned64 (&FvHeader
->FvLength
);
1331 NewFvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvLength
), FvAlignment
);
1332 if (NewFvBuffer
== NULL
) {
1333 return EFI_OUT_OF_RESOURCES
;
1335 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
) FvLength
);
1336 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) NewFvBuffer
;
1340 Status
= ParentFvPpi
->GetVolumeInfo (ParentFvPpi
, ParentFvHandle
, &ParentFvImageInfo
);
1341 ASSERT_EFI_ERROR (Status
);
1343 Status
= ParentFvPpi
->GetFileInfo (ParentFvPpi
, ParentFvFileHandle
, &FileInfo
);
1344 ASSERT_EFI_ERROR (Status
);
1347 // Install FvInfo(2) Ppi
1349 PeiServicesInstallFvInfoPpi (
1350 &FvHeader
->FileSystemGuid
,
1352 (UINT32
) FvHeader
->FvLength
,
1353 &ParentFvImageInfo
.FvName
,
1357 PeiServicesInstallFvInfo2Ppi (
1358 &FvHeader
->FileSystemGuid
,
1360 (UINT32
) FvHeader
->FvLength
,
1361 &ParentFvImageInfo
.FvName
,
1363 AuthenticationStatus
1367 // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase
1370 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1375 // Makes the encapsulated volume show up in DXE phase to skip processing of
1376 // encapsulated file again.
1379 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
1381 &ParentFvImageInfo
.FvName
,
1389 Process a firmware volume and create a volume handle.
1391 Create a volume handle from the information in the buffer. For
1392 memory-mapped firmware volumes, Buffer and BufferSize refer to
1393 the start of the firmware volume and the firmware volume size.
1394 For non memory-mapped firmware volumes, this points to a
1395 buffer which contains the necessary information for creating
1396 the firmware volume handle. Normally, these values are derived
1397 from the EFI_FIRMWARE_VOLUME_INFO_PPI.
1400 @param This Points to this instance of the
1401 EFI_PEI_FIRMWARE_VOLUME_PPI.
1402 @param Buffer Points to the start of the buffer.
1403 @param BufferSize Size of the buffer.
1404 @param FvHandle Points to the returned firmware volume
1405 handle. The firmware volume handle must
1406 be unique within the system.
1408 @retval EFI_SUCCESS Firmware volume handle created.
1409 @retval EFI_VOLUME_CORRUPTED Volume was corrupt.
1414 PeiFfsFvPpiProcessVolume (
1415 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1417 IN UINTN BufferSize
,
1418 OUT EFI_PEI_FV_HANDLE
*FvHandle
1423 ASSERT (FvHandle
!= NULL
);
1425 if (Buffer
== NULL
) {
1426 return EFI_VOLUME_CORRUPTED
;
1430 // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped
1431 // FV image and the handle is pointed to Fv image's buffer.
1433 *FvHandle
= (EFI_PEI_FV_HANDLE
) Buffer
;
1436 // Do verify for given FV buffer.
1438 Status
= VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER
*) Buffer
);
1439 if (EFI_ERROR(Status
)) {
1440 DEBUG ((EFI_D_ERROR
, "Fail to verify FV which address is 0x%11p", Buffer
));
1441 return EFI_VOLUME_CORRUPTED
;
1448 Finds the next file of the specified type.
1450 This service enables PEI modules to discover additional firmware files.
1451 The FileHandle must be unique within the system.
1453 @param This Points to this instance of the
1454 EFI_PEI_FIRMWARE_VOLUME_PPI.
1455 @param SearchType A filter to find only files of this type. Type
1456 EFI_FV_FILETYPE_ALL causes no filtering to be
1458 @param FvHandle Handle of firmware volume in which to
1460 @param FileHandle Points to the current handle from which to
1461 begin searching or NULL to start at the
1462 beginning of the firmware volume. Updated
1463 upon return to reflect the file found.
1465 @retval EFI_SUCCESS The file was found.
1466 @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.
1471 PeiFfsFvPpiFindFileByType (
1472 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1473 IN EFI_FV_FILETYPE SearchType
,
1474 IN EFI_PEI_FV_HANDLE FvHandle
,
1475 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1478 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1482 Find a file within a volume by its name.
1484 This service searches for files with a specific name, within
1485 either the specified firmware volume or all firmware volumes.
1487 @param This Points to this instance of the
1488 EFI_PEI_FIRMWARE_VOLUME_PPI.
1489 @param FileName A pointer to the name of the file to find
1490 within the firmware volume.
1491 @param FvHandle Upon entry, the pointer to the firmware
1492 volume to search or NULL if all firmware
1493 volumes should be searched. Upon exit, the
1494 actual firmware volume in which the file was
1496 @param FileHandle Upon exit, points to the found file's
1497 handle or NULL if it could not be found.
1499 @retval EFI_SUCCESS File was found.
1500 @retval EFI_NOT_FOUND File was not found.
1501 @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or
1508 PeiFfsFvPpiFindFileByName (
1509 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1510 IN CONST EFI_GUID
*FileName
,
1511 IN EFI_PEI_FV_HANDLE
*FvHandle
,
1512 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1516 PEI_CORE_INSTANCE
*PrivateData
;
1519 if ((FvHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1520 return EFI_INVALID_PARAMETER
;
1523 if (*FvHandle
!= NULL
) {
1524 Status
= FindFileEx (*FvHandle
, FileName
, 0, FileHandle
, NULL
);
1525 if (Status
== EFI_NOT_FOUND
) {
1530 // If *FvHandle = NULL, so search all FV for given filename
1532 Status
= EFI_NOT_FOUND
;
1534 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
1535 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1537 // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
1539 if (PrivateData
->Fv
[Index
].FvPpi
!= NULL
) {
1540 Status
= FindFileEx (PrivateData
->Fv
[Index
].FvHandle
, FileName
, 0, FileHandle
, NULL
);
1541 if (!EFI_ERROR (Status
)) {
1542 *FvHandle
= PrivateData
->Fv
[Index
].FvHandle
;
1553 Returns information about a specific file.
1555 This function returns information about a specific
1556 file, including its file name, type, attributes, starting
1559 @param This Points to this instance of the
1560 EFI_PEI_FIRMWARE_VOLUME_PPI.
1561 @param FileHandle Handle of the file.
1562 @param FileInfo Upon exit, points to the file's
1565 @retval EFI_SUCCESS File information returned.
1566 @retval EFI_INVALID_PARAMETER If FileHandle does not
1567 represent a valid file.
1568 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1573 PeiFfsFvPpiGetFileInfo (
1574 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1575 IN EFI_PEI_FILE_HANDLE FileHandle
,
1576 OUT EFI_FV_FILE_INFO
*FileInfo
1580 UINT8 ErasePolarity
;
1581 EFI_FFS_FILE_HEADER
*FileHeader
;
1582 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1583 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1585 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1586 return EFI_INVALID_PARAMETER
;
1590 // Retrieve the FirmwareVolume which the file resides in.
1592 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1593 if (CoreFvHandle
== NULL
) {
1594 return EFI_INVALID_PARAMETER
;
1597 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1599 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
1606 // Get FileState which is the highest bit of the State
1608 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
1610 switch (FileState
) {
1611 case EFI_FILE_DATA_VALID
:
1612 case EFI_FILE_MARKED_FOR_UPDATE
:
1615 return EFI_INVALID_PARAMETER
;
1618 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
1619 if (IS_FFS_FILE2 (FileHeader
)) {
1620 ASSERT (FFS_FILE2_SIZE (FileHeader
) > 0x00FFFFFF);
1621 if (!FwVolInstance
->IsFfs3Fv
) {
1622 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader
->Name
));
1623 return EFI_INVALID_PARAMETER
;
1625 FileInfo
->BufferSize
= FFS_FILE2_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
1626 FileInfo
->Buffer
= (UINT8
*) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
);
1628 FileInfo
->BufferSize
= FFS_FILE_SIZE (FileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
1629 FileInfo
->Buffer
= (UINT8
*) FileHeader
+ sizeof (EFI_FFS_FILE_HEADER
);
1631 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
1632 FileInfo
->FileType
= FileHeader
->Type
;
1633 FileInfo
->FileAttributes
= FfsAttributes2FvFileAttributes (FileHeader
->Attributes
);
1634 if ((CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_MEMORY_MAPPED
) == EFI_FVB2_MEMORY_MAPPED
) {
1635 FileInfo
->FileAttributes
|= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED
;
1641 Returns information about a specific file.
1643 This function returns information about a specific
1644 file, including its file name, type, attributes, starting
1645 address, size and authentication status.
1647 @param This Points to this instance of the
1648 EFI_PEI_FIRMWARE_VOLUME_PPI.
1649 @param FileHandle Handle of the file.
1650 @param FileInfo Upon exit, points to the file's
1653 @retval EFI_SUCCESS File information returned.
1654 @retval EFI_INVALID_PARAMETER If FileHandle does not
1655 represent a valid file.
1656 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1661 PeiFfsFvPpiGetFileInfo2 (
1662 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1663 IN EFI_PEI_FILE_HANDLE FileHandle
,
1664 OUT EFI_FV_FILE_INFO2
*FileInfo
1668 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1670 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1671 return EFI_INVALID_PARAMETER
;
1675 // Retrieve the FirmwareVolume which the file resides in.
1677 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1678 if (CoreFvHandle
== NULL
) {
1679 return EFI_INVALID_PARAMETER
;
1682 Status
= PeiFfsFvPpiGetFileInfo (This
, FileHandle
, (EFI_FV_FILE_INFO
*) FileInfo
);
1683 if (!EFI_ERROR (Status
)) {
1684 FileInfo
->AuthenticationStatus
= CoreFvHandle
->AuthenticationStatus
;
1691 This function returns information about the firmware volume.
1693 @param This Points to this instance of the
1694 EFI_PEI_FIRMWARE_VOLUME_PPI.
1695 @param FvHandle Handle to the firmware handle.
1696 @param VolumeInfo Points to the returned firmware volume
1699 @retval EFI_SUCCESS Information returned successfully.
1700 @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid
1701 firmware volume or VolumeInfo is NULL.
1706 PeiFfsFvPpiGetVolumeInfo (
1707 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1708 IN EFI_PEI_FV_HANDLE FvHandle
,
1709 OUT EFI_FV_INFO
*VolumeInfo
1712 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
1713 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
1715 if ((VolumeInfo
== NULL
) || (FvHandle
== NULL
)) {
1716 return EFI_INVALID_PARAMETER
;
1720 // VolumeHandle may not align at 8 byte,
1721 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
1722 // So, Copy FvHeader into the local FvHeader structure.
1724 CopyMem (&FwVolHeader
, FvHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
1727 // Check Fv Image Signature
1729 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
1730 return EFI_INVALID_PARAMETER
;
1733 ZeroMem (VolumeInfo
, sizeof (EFI_FV_INFO
));
1734 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
1735 VolumeInfo
->FvStart
= (VOID
*) FvHandle
;
1736 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
1737 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
1739 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
1740 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FvHandle
) + FwVolHeader
.ExtHeaderOffset
);
1741 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));
1748 Find the next matching section in the firmware file.
1750 This service enables PEI modules to discover sections
1751 of a given type within a valid file.
1753 @param This Points to this instance of the
1754 EFI_PEI_FIRMWARE_VOLUME_PPI.
1755 @param SearchType A filter to find only sections of this
1757 @param FileHandle Handle of firmware file in which to
1759 @param SectionData Updated upon return to point to the
1762 @retval EFI_SUCCESS Section was found.
1763 @retval EFI_NOT_FOUND Section of the specified type was not
1764 found. SectionData contains NULL.
1768 PeiFfsFvPpiFindSectionByType (
1769 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1770 IN EFI_SECTION_TYPE SearchType
,
1771 IN EFI_PEI_FILE_HANDLE FileHandle
,
1772 OUT VOID
**SectionData
1775 UINT32 AuthenticationStatus
;
1776 return PeiFfsFvPpiFindSectionByType2 (This
, SearchType
, 0, FileHandle
, SectionData
, &AuthenticationStatus
);
1780 Find the next matching section in the firmware file.
1782 This service enables PEI modules to discover sections
1783 of a given instance and type within a valid file.
1785 @param This Points to this instance of the
1786 EFI_PEI_FIRMWARE_VOLUME_PPI.
1787 @param SearchType A filter to find only sections of this
1789 @param SearchInstance A filter to find the specific instance
1791 @param FileHandle Handle of firmware file in which to
1793 @param SectionData Updated upon return to point to the
1795 @param AuthenticationStatus Updated upon return to point to the
1796 authentication status for this section.
1798 @retval EFI_SUCCESS Section was found.
1799 @retval EFI_NOT_FOUND Section of the specified type was not
1800 found. SectionData contains NULL.
1804 PeiFfsFvPpiFindSectionByType2 (
1805 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1806 IN EFI_SECTION_TYPE SearchType
,
1807 IN UINTN SearchInstance
,
1808 IN EFI_PEI_FILE_HANDLE FileHandle
,
1809 OUT VOID
**SectionData
,
1810 OUT UINT32
*AuthenticationStatus
1814 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
1816 EFI_COMMON_SECTION_HEADER
*Section
;
1817 PEI_FW_VOL_INSTANCE
*FwVolInstance
;
1818 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1820 UINT32 ExtractedAuthenticationStatus
;
1822 if (SectionData
== NULL
) {
1823 return EFI_NOT_FOUND
;
1826 FwVolInstance
= PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This
);
1829 // Retrieve the FirmwareVolume which the file resides in.
1831 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1832 if (CoreFvHandle
== NULL
) {
1833 return EFI_NOT_FOUND
;
1836 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
1838 if (IS_FFS_FILE2 (FfsFileHeader
)) {
1839 ASSERT (FFS_FILE2_SIZE (FfsFileHeader
) > 0x00FFFFFF);
1840 if (!FwVolInstance
->IsFfs3Fv
) {
1841 DEBUG ((EFI_D_ERROR
, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader
->Name
));
1842 return EFI_NOT_FOUND
;
1844 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER2
));
1845 FileSize
= FFS_FILE2_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER2
);
1847 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
1848 FileSize
= FFS_FILE_SIZE (FfsFileHeader
) - sizeof (EFI_FFS_FILE_HEADER
);
1851 Instance
= SearchInstance
+ 1;
1852 ExtractedAuthenticationStatus
= 0;
1853 Status
= ProcessSection (
1854 GetPeiServicesTablePointer (),
1860 &ExtractedAuthenticationStatus
,
1861 FwVolInstance
->IsFfs3Fv
1863 if (!EFI_ERROR (Status
)) {
1865 // Inherit the authentication status.
1867 *AuthenticationStatus
= ExtractedAuthenticationStatus
| CoreFvHandle
->AuthenticationStatus
;
1873 Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.
1875 @param FvHandle The handle of a FV.
1877 @retval NULL if can not find.
1878 @return Pointer of corresponding PEI_CORE_FV_HANDLE.
1880 PEI_CORE_FV_HANDLE
*
1881 FvHandleToCoreHandle (
1882 IN EFI_PEI_FV_HANDLE FvHandle
1886 PEI_CORE_INSTANCE
*PrivateData
;
1888 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
1889 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1890 if (FvHandle
== PrivateData
->Fv
[Index
].FvHandle
) {
1891 return &PrivateData
->Fv
[Index
];
1899 Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.
1901 This routine also will install FvInfo ppi for FV hob in PI ways.
1903 @param Private Pointer of PEI_CORE_INSTANCE
1904 @param Instance The index of FV want to be searched.
1906 @return Instance of PEI_CORE_FV_HANDLE.
1908 PEI_CORE_FV_HANDLE
*
1909 FindNextCoreFvHandle (
1910 IN PEI_CORE_INSTANCE
*Private
,
1916 EFI_HOB_FIRMWARE_VOLUME
*FvHob
;
1919 // Handle Framework FvHob and Install FvInfo Ppi for it.
1921 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
1923 // Loop to search the wanted FirmwareVolume which supports FFS
1925 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetFirstHob (EFI_HOB_TYPE_FV
);
1926 while (FvHob
!= NULL
) {
1928 // Search whether FvHob has been installed into PeiCore's FV database.
1929 // If found, no need install new FvInfoPpi for it.
1931 for (Index
= 0, Match
= FALSE
; Index
< Private
->FvCount
; Index
++) {
1932 if ((EFI_PEI_FV_HANDLE
)(UINTN
)FvHob
->BaseAddress
== Private
->Fv
[Index
].FvHeader
) {
1939 // Search whether FvHob has been cached into PeiCore's Unknown FV database.
1940 // If found, no need install new FvInfoPpi for it.
1943 for (Index
= 0; Index
< Private
->UnknownFvInfoCount
; Index
++) {
1944 if ((UINTN
)FvHob
->BaseAddress
== (UINTN
)Private
->UnknownFvInfo
[Index
].FvInfo
) {
1952 // If the Fv in FvHob has not been installed into PeiCore's FV database and has
1953 // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi
1954 // for it then PeiCore will dispatch it in callback of FvInfoPpi.
1957 PeiServicesInstallFvInfoPpi (
1958 &(((EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)FvHob
->BaseAddress
)->FileSystemGuid
),
1959 (VOID
*)(UINTN
)FvHob
->BaseAddress
,
1960 (UINT32
)FvHob
->Length
,
1966 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetNextHob (EFI_HOB_TYPE_FV
, (VOID
*)((UINTN
)FvHob
+ FvHob
->Header
.HobLength
));
1970 ASSERT (Private
->FvCount
<= FixedPcdGet32 (PcdPeiCoreMaxFvSupported
));
1971 if (Instance
>= Private
->FvCount
) {
1975 return &Private
->Fv
[Instance
];
1979 After PeiCore image is shadowed into permanent memory, all build-in FvPpi should
1980 be re-installed with the instance in permanent memory and all cached FvPpi pointers in
1981 PrivateData->Fv[] array should be fixed up to be pointed to the one in permenant
1984 @param PrivateData Pointer to PEI_CORE_INSTANCE.
1988 IN PEI_CORE_INSTANCE
*PrivateData
1992 EFI_PEI_PPI_DESCRIPTOR
*OldDescriptor
;
1997 // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
2000 Status
= PeiServicesLocatePpi (
2001 &gEfiFirmwareFileSystem2Guid
,
2006 ASSERT_EFI_ERROR (Status
);
2009 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
2010 // which is shadowed from flash to permanent memory within PeiCore image.
2012 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs2FvPpiList
);
2013 ASSERT_EFI_ERROR (Status
);
2016 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2018 for (Index
= 0; Index
< FixedPcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
2019 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2020 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs2FwVol
.Fv
;
2025 // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which
2028 Status
= PeiServicesLocatePpi (
2029 &gEfiFirmwareFileSystem3Guid
,
2034 ASSERT_EFI_ERROR (Status
);
2037 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3
2038 // which is shadowed from flash to permanent memory within PeiCore image.
2040 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs3FvPpiList
);
2041 ASSERT_EFI_ERROR (Status
);
2044 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
2046 for (Index
= 0; Index
< FixedPcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
2047 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfsFvPpi
) {
2048 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs3FwVol
.Fv
;
2054 Report the information for a new discoveried FV in unknown third-party format.
2056 If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but
2057 the FV in this format has been discoveried, then this FV's information will be cached into
2058 PEI_CORE_INSTANCE's UnknownFvInfo array.
2059 Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI
2060 is installed later by platform's PEIM, the original unknown third-party FV will be processed by
2061 using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2063 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2064 @param FvInfo2Ppi Point to FvInfo2 PPI.
2066 @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.
2067 @retval EFI_SUCCESS Success to add the information for unknown FV.
2070 AddUnknownFormatFvInfo (
2071 IN PEI_CORE_INSTANCE
*PrivateData
,
2072 IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI
*FvInfo2Ppi
2075 PEI_CORE_UNKNOW_FORMAT_FV_INFO
*NewUnknownFv
;
2077 if (PrivateData
->UnknownFvInfoCount
+ 1 >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
2078 return EFI_OUT_OF_RESOURCES
;
2081 NewUnknownFv
= &PrivateData
->UnknownFvInfo
[PrivateData
->UnknownFvInfoCount
];
2082 PrivateData
->UnknownFvInfoCount
++;
2084 CopyGuid (&NewUnknownFv
->FvFormat
, &FvInfo2Ppi
->FvFormat
);
2085 NewUnknownFv
->FvInfo
= FvInfo2Ppi
->FvInfo
;
2086 NewUnknownFv
->FvInfoSize
= FvInfo2Ppi
->FvInfoSize
;
2087 NewUnknownFv
->AuthenticationStatus
= FvInfo2Ppi
->AuthenticationStatus
;
2088 NewUnknownFv
->NotifyDescriptor
.Flags
= (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
);
2089 NewUnknownFv
->NotifyDescriptor
.Guid
= &NewUnknownFv
->FvFormat
;
2090 NewUnknownFv
->NotifyDescriptor
.Notify
= ThirdPartyFvPpiNotifyCallback
;
2092 PeiServicesNotifyPpi (&NewUnknownFv
->NotifyDescriptor
);
2097 Find the FV information according to third-party FV format guid.
2099 This routine also will remove the FV information found by given FV format guid from
2100 PrivateData->UnknownFvInfo[].
2102 @param PrivateData Point to instance of PEI_CORE_INSTANCE
2103 @param Format Point to given FV format guid
2104 @param FvInfo On return, the pointer of FV information buffer
2105 @param FvInfoSize On return, the size of FV information buffer.
2106 @param AuthenticationStatus On return, the authentication status of FV information buffer.
2108 @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI
2109 @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.
2112 FindUnknownFormatFvInfo (
2113 IN PEI_CORE_INSTANCE
*PrivateData
,
2114 IN EFI_GUID
*Format
,
2116 OUT UINT32
*FvInfoSize
,
2117 OUT UINT32
*AuthenticationStatus
2124 for (; Index
< PrivateData
->UnknownFvInfoCount
; Index
++) {
2125 if (CompareGuid (Format
, &PrivateData
->UnknownFvInfo
[Index
].FvFormat
)) {
2130 if (Index
== PrivateData
->UnknownFvInfoCount
) {
2131 return EFI_NOT_FOUND
;
2134 *FvInfo
= PrivateData
->UnknownFvInfo
[Index
].FvInfo
;
2135 *FvInfoSize
= PrivateData
->UnknownFvInfo
[Index
].FvInfoSize
;
2136 *AuthenticationStatus
= PrivateData
->UnknownFvInfo
[Index
].AuthenticationStatus
;
2139 // Remove an entry from UnknownFvInfo array.
2142 for (;Index2
< PrivateData
->UnknownFvInfoCount
; Index2
++, Index
++) {
2143 CopyMem (&PrivateData
->UnknownFvInfo
[Index
], &PrivateData
->UnknownFvInfo
[Index2
], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO
));
2145 PrivateData
->UnknownFvInfoCount
--;
2150 Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.
2152 When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this
2153 routine is called to process all discoveried FVs in this format.
2155 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
2156 @param NotifyDescriptor Address of the notification descriptor data structure.
2157 @param Ppi Address of the PPI that was installed.
2159 @retval EFI_SUCCESS The notification callback is processed correctly.
2163 ThirdPartyFvPpiNotifyCallback (
2164 IN EFI_PEI_SERVICES
**PeiServices
,
2165 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
2169 PEI_CORE_INSTANCE
*PrivateData
;
2170 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
2173 UINT32 AuthenticationStatus
;
2175 EFI_PEI_FV_HANDLE FvHandle
;
2176 BOOLEAN IsProcessed
;
2178 EFI_PEI_FILE_HANDLE FileHandle
;
2181 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
2182 FvPpi
= (EFI_PEI_FIRMWARE_VOLUME_PPI
*) Ppi
;
2185 Status
= FindUnknownFormatFvInfo (PrivateData
, NotifyDescriptor
->Guid
, &FvInfo
, &FvInfoSize
, &AuthenticationStatus
);
2186 if (EFI_ERROR (Status
)) {
2191 // Process new found FV and get FV handle.
2193 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfo
, FvInfoSize
, &FvHandle
);
2194 if (EFI_ERROR (Status
)) {
2195 DEBUG ((EFI_D_ERROR
, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo
));
2200 // Check whether the FV has already been processed.
2202 IsProcessed
= FALSE
;
2203 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
2204 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
2205 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfo
));
2215 if (PrivateData
->FvCount
>= FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
2216 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)));
2217 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
2222 // Update internal PEI_CORE_FV array.
2224 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfo
;
2225 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
2226 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
2227 PrivateData
->Fv
[PrivateData
->FvCount
].AuthenticationStatus
= AuthenticationStatus
;
2230 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
2231 (UINT32
) PrivateData
->FvCount
,
2236 PrivateData
->FvCount
++;
2239 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
2243 Status
= FvPpi
->FindFileByType (
2245 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
2249 if (!EFI_ERROR (Status
)) {
2250 Status
= FvPpi
->FindSectionByType (
2252 EFI_SECTION_PEI_DEPEX
,
2256 if (!EFI_ERROR (Status
)) {
2257 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
2259 // Dependency is not satisfied.
2265 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, PrivateData
->FvCount
- 1, FvHandle
));
2266 ProcessFvFile (PrivateData
, &PrivateData
->Fv
[PrivateData
->FvCount
- 1], FileHandle
);
2268 } while (FileHandle
!= NULL
);