2 Pei Core Firmware File System service routines.
4 Copyright (c) 2006 - 2009, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList
= {
18 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
19 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
20 FirmwareVolmeInfoPpiNotifyCallback
23 EFI_PEI_FIRMWARE_VOLUME_PPI mPeiFfs2FvPpi
= {
24 PeiFfs2FvPpiProcessVolume
,
25 PeiFfs2FvPpiFindFileByType
,
26 PeiFfs2FvPpiFindFileByName
,
27 PeiFfs2FvPpiGetFileInfo
,
28 PeiFfs2FvPpiGetVolumeInfo
,
29 PeiFfs2FvPpiFindSectionByType
32 EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList
= {
33 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
34 &gEfiFirmwareFileSystem2Guid
,
39 Returns the file state set by the highest zero bit in the State field
41 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
42 in the Attributes field.
43 @param FfsHeader Pointer to FFS File Header.
45 @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit
46 in the header State field.
50 IN UINT8 ErasePolarity
,
51 IN EFI_FFS_FILE_HEADER
*FfsHeader
54 EFI_FFS_FILE_STATE FileState
;
55 EFI_FFS_FILE_STATE HighestBit
;
57 FileState
= FfsHeader
->State
;
59 if (ErasePolarity
!= 0) {
60 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
64 // Get file state set by its highest none zero bit.
67 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
75 Calculates the checksum of the header of a file.
77 @param FileHeader Pointer to FFS File Header.
79 @return Checksum of the header.
80 Zero means the header is good.
81 Non-zero means the header is bad.
84 CalculateHeaderChecksum (
85 IN EFI_FFS_FILE_HEADER
*FileHeader
88 EFI_FFS_FILE_HEADER TestFileHeader
;
90 CopyMem (&TestFileHeader
, FileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
92 // Ingore State and File field in FFS header.
94 TestFileHeader
.State
= 0;
95 TestFileHeader
.IntegrityCheck
.Checksum
.File
= 0;
97 return CalculateSum8 ((CONST UINT8
*) &TestFileHeader
, sizeof (EFI_FFS_FILE_HEADER
));
101 Find FV handler according to FileHandle in that FV.
103 @param FileHandle Handle of file image
105 @return Pointer to instance of PEI_CORE_FV_HANDLE.
109 IN EFI_PEI_FILE_HANDLE FileHandle
113 PEI_CORE_INSTANCE
*PrivateData
;
114 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
116 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
118 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
119 FwVolHeader
= PrivateData
->Fv
[Index
].FvHeader
;
120 if (((UINT64
) (UINTN
) FileHandle
> (UINT64
) (UINTN
) FwVolHeader
) && \
121 ((UINT64
) (UINTN
) FileHandle
<= ((UINT64
) (UINTN
) FwVolHeader
+ FwVolHeader
->FvLength
- 1))) {
122 return &PrivateData
->Fv
[Index
];
129 Given the input file pointer, search for the first matching file in the
130 FFS volume as defined by SearchType. The search starts from FileHeader inside
131 the Firmware Volume defined by FwVolHeader.
132 If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.
133 If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
134 the first PEIM, or COMBINED PEIM or FV file type FFS file will return.
136 @param FvHandle Pointer to the FV header of the volume to search
137 @param FileName File name
138 @param SearchType Filter to find only files of this type.
139 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
140 @param FileHandle This parameter must point to a valid FFS volume.
141 @param AprioriFile Pointer to AprioriFile image in this FV if has
143 @return EFI_NOT_FOUND No files matching the search criteria were found
144 @retval EFI_SUCCESS Success to search given file
149 IN CONST EFI_PEI_FV_HANDLE FvHandle
,
150 IN CONST EFI_GUID
*FileName
, OPTIONAL
151 IN EFI_FV_FILETYPE SearchType
,
152 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
,
153 IN OUT EFI_PEI_FV_HANDLE
*AprioriFile OPTIONAL
156 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
157 EFI_FFS_FILE_HEADER
**FileHeader
;
158 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
160 UINT32 FileOccupiedSize
;
167 // Convert the handle of FV to FV header for memory-mapped firmware volume
169 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvHandle
;
170 FileHeader
= (EFI_FFS_FILE_HEADER
**)FileHandle
;
172 FvLength
= FwVolHeader
->FvLength
;
173 if ((FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
180 // If FileHeader is not specified (NULL) or FileName is not NULL,
181 // start with the first file in the firmware volume. Otherwise,
182 // start from the FileHeader.
184 if ((*FileHeader
== NULL
) || (FileName
!= NULL
)) {
185 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
188 // Length is 24 bits wide so mask upper 8 bits
189 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
191 FileLength
= *(UINT32
*)(*FileHeader
)->Size
& 0x00FFFFFF;
192 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
193 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
196 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
197 ASSERT (FileOffset
<= 0xFFFFFFFF);
199 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
201 // Get FileState which is the highest bit of the State
203 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
206 case EFI_FILE_HEADER_INVALID
:
207 FileOffset
+= sizeof(EFI_FFS_FILE_HEADER
);
208 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
211 case EFI_FILE_DATA_VALID
:
212 case EFI_FILE_MARKED_FOR_UPDATE
:
213 if (CalculateHeaderChecksum (FfsFileHeader
) != 0) {
216 return EFI_NOT_FOUND
;
219 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
220 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
222 if (FileName
!= NULL
) {
223 if (CompareGuid (&FfsFileHeader
->Name
, (EFI_GUID
*)FileName
)) {
224 *FileHeader
= FfsFileHeader
;
227 } else if (SearchType
== PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
) {
228 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
229 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
) ||
230 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
)) {
232 *FileHeader
= FfsFileHeader
;
234 } else if (AprioriFile
!= NULL
) {
235 if (FfsFileHeader
->Type
== EFI_FV_FILETYPE_FREEFORM
) {
236 if (CompareGuid (&FfsFileHeader
->Name
, &gPeiAprioriFileNameGuid
)) {
237 *AprioriFile
= FfsFileHeader
;
241 } else if (((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) &&
242 (FfsFileHeader
->Type
!= EFI_FV_FILETYPE_FFS_PAD
)) {
243 *FileHeader
= FfsFileHeader
;
247 FileOffset
+= FileOccupiedSize
;
248 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
251 case EFI_FILE_DELETED
:
252 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
253 FileOccupiedSize
= GET_OCCUPIED_SIZE(FileLength
, 8);
254 FileOffset
+= FileOccupiedSize
;
255 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
260 return EFI_NOT_FOUND
;
265 return EFI_NOT_FOUND
;
269 Initialize PeiCore Fv List.
271 @param PrivateData - Pointer to PEI_CORE_INSTANCE.
272 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
276 IN PEI_CORE_INSTANCE
*PrivateData
,
277 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
281 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
282 EFI_PEI_FV_HANDLE FvHandle
;
283 EFI_FIRMWARE_VOLUME_HEADER
*BfvHeader
;
286 // Install FV_PPI for FFS2 file system.
288 PeiServicesInstallPpi (&mPeiFfs2FvPpiList
);
290 BfvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
293 // The FV_PPI in BFV's format should be installed.
295 Status
= PeiServicesLocatePpi (
296 &BfvHeader
->FileSystemGuid
,
301 ASSERT_EFI_ERROR (Status
);
306 FvPpi
->ProcessVolume (
308 SecCoreData
->BootFirmwareVolumeBase
,
309 (UINTN
)BfvHeader
->FvLength
,
314 // Update internal PEI_CORE_FV array.
316 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= BfvHeader
;
317 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
318 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
321 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
322 (UINT32
) PrivateData
->FvCount
,
327 PrivateData
->FvCount
++;
330 // Post a call-back for the FvInfoPPI services to expose
331 // additional Fvs to PeiCore.
333 Status
= PeiServicesNotifyPpi (&mNotifyOnFvInfoList
);
334 ASSERT_EFI_ERROR (Status
);
339 Process Firmware Volum Information once FvInfoPPI install.
340 The FV Info will be registered into PeiCore private data structure.
341 And search the inside FV image, if found, the new FV INFO PPI will be installed.
343 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
344 @param NotifyDescriptor Address of the notification descriptor data structure.
345 @param Ppi Address of the PPI that was installed.
347 @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.
348 @return if not EFI_SUCESS, fail to verify FV.
353 FirmwareVolmeInfoPpiNotifyCallback (
354 IN EFI_PEI_SERVICES
**PeiServices
,
355 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
359 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*FvInfoPpi
;
360 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
361 PEI_CORE_INSTANCE
*PrivateData
;
363 EFI_PEI_FV_HANDLE FvHandle
;
365 EFI_PEI_FILE_HANDLE FileHandle
;
368 Status
= EFI_SUCCESS
;
369 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
371 if (PrivateData
->FvCount
>= FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
372 DEBUG ((EFI_D_ERROR
, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData
->FvCount
+ 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)));
373 DEBUG ((EFI_D_ERROR
, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
377 FvInfoPpi
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*)Ppi
;
380 // Locate the corresponding FV_PPI according to founded FV's format guid
382 Status
= PeiServicesLocatePpi (
383 &FvInfoPpi
->FvFormat
,
388 if (!EFI_ERROR (Status
)) {
390 // Process new found FV and get FV handle.
392 Status
= FvPpi
->ProcessVolume (FvPpi
, FvInfoPpi
->FvInfo
, FvInfoPpi
->FvInfoSize
, &FvHandle
);
393 if (EFI_ERROR (Status
)) {
394 DEBUG ((EFI_D_ERROR
, "Fail to process new found FV, FV may be corrupted!\n"));
399 // Check whether the FV has already been processed.
401 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
402 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
403 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvInfoPpi
->FvInfo
));
409 // Update internal PEI_CORE_FV array.
411 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfoPpi
->FvInfo
;
412 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= FvPpi
;
413 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
416 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",
417 (UINT32
) PrivateData
->FvCount
,
418 (VOID
*) FvInfoPpi
->FvInfo
,
419 FvInfoPpi
->FvInfoSize
,
422 PrivateData
->FvCount
++;
425 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
429 Status
= FvPpi
->FindFileByType (
431 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
435 if (!EFI_ERROR (Status
)) {
436 Status
= FvPpi
->FindSectionByType (
438 EFI_SECTION_PEI_DEPEX
,
442 if (!EFI_ERROR (Status
)) {
443 if (!PeimDispatchReadiness (PeiServices
, DepexData
)) {
445 // Dependency is not satisfied.
451 DEBUG ((EFI_D_INFO
, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle
, PrivateData
->FvCount
- 1, FvHandle
));
452 ProcessFvFile (&PrivateData
->Fv
[PrivateData
->FvCount
- 1], FileHandle
);
454 } while (FileHandle
!= NULL
);
456 DEBUG ((EFI_D_ERROR
, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfoPpi
->FvInfo
));
459 // If can not find EFI_FIRMWARE_VOLUME_PPI to process firmware to get FvHandle,
460 // use the address of FV buffer as its handle.
462 FvHandle
= FvInfoPpi
->FvInfo
;
465 // Check whether the FV has already been processed.
467 for (FvIndex
= 0; FvIndex
< PrivateData
->FvCount
; FvIndex
++) {
468 if (PrivateData
->Fv
[FvIndex
].FvHandle
== FvHandle
) {
469 DEBUG ((EFI_D_INFO
, "The Fv %p has already been processed!\n", FvHandle
));
474 PrivateData
->Fv
[PrivateData
->FvCount
].FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FvInfoPpi
->FvInfo
;
475 PrivateData
->Fv
[PrivateData
->FvCount
].FvPpi
= NULL
;
476 PrivateData
->Fv
[PrivateData
->FvCount
].FvHandle
= FvHandle
;
477 PrivateData
->FvCount
++;
484 Go through the file to search SectionType section.
485 Search within encapsulation sections (compression and GUIDed) recursively,
486 until the match section is found.
488 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
489 @param SectionType Filter to find only section of this type.
490 @param Section From where to search.
491 @param SectionSize The file size to search.
492 @param OutputBuffer A pointer to the discovered section, if successful.
493 NULL if section not found
495 @return EFI_NOT_FOUND The match section is not found.
496 @return EFI_SUCCESS The match section is found.
501 IN CONST EFI_PEI_SERVICES
**PeiServices
,
502 IN EFI_SECTION_TYPE SectionType
,
503 IN EFI_COMMON_SECTION_HEADER
*Section
,
504 IN UINTN SectionSize
,
505 OUT VOID
**OutputBuffer
509 UINT32 SectionLength
;
511 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*GuidSectionPpi
;
512 EFI_PEI_DECOMPRESS_PPI
*DecompressPpi
;
516 UINT32 Authentication
;
517 PEI_CORE_INSTANCE
*PrivateData
;
519 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
520 *OutputBuffer
= NULL
;
523 Status
= EFI_NOT_FOUND
;
526 while (ParsedLength
< SectionSize
) {
527 if (Section
->Type
== SectionType
) {
528 *OutputBuffer
= (VOID
*)(Section
+ 1);
530 } else if ((Section
->Type
== EFI_SECTION_GUID_DEFINED
) || (Section
->Type
== EFI_SECTION_COMPRESSION
)) {
532 // Check the encapsulated section is extracted into the cache data.
534 for (Index
= 0; Index
< PrivateData
->CacheSection
.AllSectionCount
; Index
++) {
535 if (Section
== PrivateData
->CacheSection
.Section
[Index
]) {
536 PpiOutput
= PrivateData
->CacheSection
.SectionData
[Index
];
537 PpiOutputSize
= PrivateData
->CacheSection
.SectionSize
[Index
];
539 // Search section directly from the cache data.
541 return ProcessSection (
551 Status
= EFI_NOT_FOUND
;
552 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
553 Status
= PeiServicesLocatePpi (
554 &((EFI_GUID_DEFINED_SECTION
*)Section
)->SectionDefinitionGuid
,
557 (VOID
**) &GuidSectionPpi
559 if (!EFI_ERROR (Status
)) {
560 Status
= GuidSectionPpi
->ExtractSection (
568 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
569 Status
= PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid
, 0, NULL
, (VOID
**) &DecompressPpi
);
570 if (!EFI_ERROR (Status
)) {
571 Status
= DecompressPpi
->Decompress (
573 (CONST EFI_COMPRESSION_SECTION
*) Section
,
580 if (!EFI_ERROR (Status
)) {
582 // Update cache section data.
584 if (PrivateData
->CacheSection
.AllSectionCount
< CACHE_SETION_MAX_NUMBER
) {
585 PrivateData
->CacheSection
.AllSectionCount
++;
587 PrivateData
->CacheSection
.Section
[PrivateData
->CacheSection
.SectionIndex
] = Section
;
588 PrivateData
->CacheSection
.SectionData
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutput
;
589 PrivateData
->CacheSection
.SectionSize
[PrivateData
->CacheSection
.SectionIndex
] = PpiOutputSize
;
590 PrivateData
->CacheSection
.SectionIndex
= (PrivateData
->CacheSection
.SectionIndex
+ 1)%CACHE_SETION_MAX_NUMBER
;
592 return ProcessSection (
603 // Size is 24 bits wide so mask upper 8 bits.
604 // SectionLength is adjusted it is 4 byte aligned.
605 // Go to the next section
607 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
608 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
609 ASSERT (SectionLength
!= 0);
610 ParsedLength
+= SectionLength
;
611 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
614 return EFI_NOT_FOUND
;
619 Searches for the next matching section within the specified file.
621 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
622 @param SectionType Filter to find only sections of this type.
623 @param FileHandle Pointer to the current file to search.
624 @param SectionData A pointer to the discovered section, if successful.
625 NULL if section not found
627 @retval EFI_NOT_FOUND The section was not found.
628 @retval EFI_SUCCESS The section was found.
633 PeiFfsFindSectionData (
634 IN CONST EFI_PEI_SERVICES
**PeiServices
,
635 IN EFI_SECTION_TYPE SectionType
,
636 IN EFI_PEI_FILE_HANDLE FileHandle
,
637 OUT VOID
**SectionData
640 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
642 CoreFvHandle
= FileHandleToVolume (FileHandle
);
643 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
644 return EFI_NOT_FOUND
;
647 return CoreFvHandle
->FvPpi
->FindSectionByType (CoreFvHandle
->FvPpi
, SectionType
, FileHandle
, SectionData
);
651 Searches for the next matching file in the firmware volume.
653 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
654 @param SearchType Filter to find only files of this type.
655 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
656 @param VolumeHandle Handle of firmware volume in which to search.
657 @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
658 at the beginning of the firmware volume. On exit, points the file handle of the next file
659 in the volume or NULL if there are no more files.
661 @retval EFI_NOT_FOUND The file was not found.
662 @retval EFI_NOT_FOUND The header checksum was not zero.
663 @retval EFI_SUCCESS The file was found.
669 IN CONST EFI_PEI_SERVICES
**PeiServices
,
671 IN EFI_PEI_FV_HANDLE FvHandle
,
672 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
675 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
677 CoreFvHandle
= FvHandleToCoreHandle (FvHandle
);
680 // To make backward compatiblity, if can not find corresponding the handle of FV
681 // then treat FV as build-in FFS2 format and memory mapped FV that FV handle is pointed
682 // to the address of first byte of FV.
684 if ((CoreFvHandle
== NULL
) && FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
685 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
688 if ((CoreFvHandle
== NULL
) || CoreFvHandle
->FvPpi
== NULL
) {
689 return EFI_NOT_FOUND
;
692 return CoreFvHandle
->FvPpi
->FindFileByType (CoreFvHandle
->FvPpi
, SearchType
, FvHandle
, FileHandle
);
697 Search the firmware volumes by index
699 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
700 @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
702 @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
704 @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
705 @retval EFI_NOT_FOUND The volume was not found.
706 @retval EFI_SUCCESS The volume was found.
711 PeiFfsFindNextVolume (
712 IN CONST EFI_PEI_SERVICES
**PeiServices
,
714 IN OUT EFI_PEI_FV_HANDLE
*VolumeHandle
717 PEI_CORE_INSTANCE
*Private
;
718 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
720 if (VolumeHandle
== NULL
) {
721 return EFI_INVALID_PARAMETER
;
724 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
726 CoreFvHandle
= FindNextCoreFvHandle (Private
, Instance
);
727 if (CoreFvHandle
== NULL
) {
728 *VolumeHandle
= NULL
;
729 return EFI_NOT_FOUND
;
732 *VolumeHandle
= CoreFvHandle
->FvHandle
;
739 Find a file within a volume by its name.
741 @param FileName A pointer to the name of the file to find within the firmware volume.
742 @param VolumeHandle The firmware volume to search
743 @param FileHandle Upon exit, points to the found file's handle
744 or NULL if it could not be found.
746 @retval EFI_SUCCESS File was found.
747 @retval EFI_NOT_FOUND File was not found.
748 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
753 PeiFfsFindFileByName (
754 IN CONST EFI_GUID
*FileName
,
755 IN EFI_PEI_FV_HANDLE VolumeHandle
,
756 OUT EFI_PEI_FILE_HANDLE
*FileHandle
759 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
761 if ((VolumeHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
762 return EFI_INVALID_PARAMETER
;
765 CoreFvHandle
= FvHandleToCoreHandle (VolumeHandle
);
766 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
767 return EFI_NOT_FOUND
;
770 return CoreFvHandle
->FvPpi
->FindFileByName (CoreFvHandle
->FvPpi
, FileName
, &VolumeHandle
, FileHandle
);
774 Returns information about a specific file.
776 @param FileHandle Handle of the file.
777 @param FileInfo Upon exit, points to the file’s information.
779 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
780 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
781 @retval EFI_SUCCESS File information returned.
787 IN EFI_PEI_FILE_HANDLE FileHandle
,
788 OUT EFI_FV_FILE_INFO
*FileInfo
791 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
793 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
794 return EFI_INVALID_PARAMETER
;
798 // Retrieve the FirmwareVolume which the file resides in.
800 CoreFvHandle
= FileHandleToVolume (FileHandle
);
801 if ((CoreFvHandle
== NULL
) || (CoreFvHandle
->FvPpi
== NULL
)) {
802 return EFI_INVALID_PARAMETER
;
805 return CoreFvHandle
->FvPpi
->GetFileInfo (CoreFvHandle
->FvPpi
, FileHandle
, FileInfo
);
810 Returns information about the specified volume.
812 This function returns information about a specific firmware
813 volume, including its name, type, attributes, starting address
816 @param VolumeHandle Handle of the volume.
817 @param VolumeInfo Upon exit, points to the volume's information.
819 @retval EFI_SUCCESS Volume information returned.
820 @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
821 @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
822 @retval EFI_SUCCESS Information successfully returned.
823 @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
828 PeiFfsGetVolumeInfo (
829 IN EFI_PEI_FV_HANDLE VolumeHandle
,
830 OUT EFI_FV_INFO
*VolumeInfo
833 PEI_CORE_FV_HANDLE
*CoreHandle
;
835 if (VolumeInfo
== NULL
) {
836 return EFI_INVALID_PARAMETER
;
839 CoreHandle
= FvHandleToCoreHandle (VolumeHandle
);
841 if ((CoreHandle
== NULL
) || (CoreHandle
->FvPpi
== NULL
)) {
842 return EFI_INVALID_PARAMETER
;
845 return CoreHandle
->FvPpi
->GetVolumeInfo (CoreHandle
->FvPpi
, VolumeHandle
, VolumeInfo
);
849 Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
851 @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.
852 @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image.
854 @retval EFI_NOT_FOUND FV image can't be found.
855 @retval EFI_SUCCESS Successfully to process it.
856 @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image
857 @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section
862 IN PEI_CORE_FV_HANDLE
*ParentFvCoreHandle
,
863 IN EFI_PEI_FILE_HANDLE ParentFvFileHandle
867 EFI_FV_INFO ParentFvImageInfo
;
870 EFI_PEI_HOB_POINTERS HobPtr
;
871 EFI_PEI_FIRMWARE_VOLUME_PPI
*ParentFvPpi
;
872 EFI_PEI_FV_HANDLE ParentFvHandle
;
873 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
874 EFI_FV_FILE_INFO FileInfo
;
877 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
880 HobPtr
.Raw
= GetHobList ();
881 while ((HobPtr
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobPtr
.Raw
)) != NULL
) {
882 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)ParentFvFileHandle
)->Name
), &HobPtr
.FirmwareVolume2
->FileName
)) {
884 // this FILE has been dispatched, it will not be dispatched again.
886 DEBUG ((EFI_D_INFO
, "FV file %p has been dispatched!\r\n", ParentFvFileHandle
));
889 HobPtr
.Raw
= GET_NEXT_HOB (HobPtr
);
892 ParentFvHandle
= ParentFvCoreHandle
->FvHandle
;
893 ParentFvPpi
= ParentFvCoreHandle
->FvPpi
;
896 // Find FvImage in FvFile
898 Status
= ParentFvPpi
->FindSectionByType (
900 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
905 if (EFI_ERROR (Status
)) {
910 // FvAlignment must be more than 8 bytes required by FvHeader structure.
912 FvAlignment
= 1 << ((FvHeader
->Attributes
& EFI_FVB2_ALIGNMENT
) >> 16);
913 if (FvAlignment
< 8) {
920 if ((UINTN
) FvHeader
% FvAlignment
!= 0) {
921 NewFvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvHeader
->FvLength
), FvAlignment
);
922 if (NewFvBuffer
== NULL
) {
923 return EFI_OUT_OF_RESOURCES
;
925 CopyMem (NewFvBuffer
, FvHeader
, (UINTN
) FvHeader
->FvLength
);
926 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) NewFvBuffer
;
929 Status
= ParentFvPpi
->GetVolumeInfo (ParentFvPpi
, ParentFvHandle
, &ParentFvImageInfo
);
930 ASSERT_EFI_ERROR (Status
);
932 Status
= ParentFvPpi
->GetFileInfo (ParentFvPpi
, ParentFvFileHandle
, &FileInfo
);
933 ASSERT_EFI_ERROR (Status
);
936 // Install FvPpi and Build FvHob
938 PeiServicesInstallFvInfoPpi (
939 &FvHeader
->FileSystemGuid
,
941 (UINT32
) FvHeader
->FvLength
,
942 &ParentFvImageInfo
.FvName
,
947 // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase
950 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
955 // Makes the encapsulated volume show up in DXE phase to skip processing of
956 // encapsulated file again.
959 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
,
961 &ParentFvImageInfo
.FvName
,
969 Process a firmware volume and create a volume handle.
971 Create a volume handle from the information in the buffer. For
972 memory-mapped firmware volumes, Buffer and BufferSize refer to
973 the start of the firmware volume and the firmware volume size.
974 For non memory-mapped firmware volumes, this points to a
975 buffer which contains the necessary information for creating
976 the firmware volume handle. Normally, these values are derived
977 from the EFI_FIRMWARE_VOLUME_INFO_PPI.
980 @param This Points to this instance of the
981 EFI_PEI_FIRMWARE_VOLUME_PPI.
982 @param Buffer Points to the start of the buffer.
983 @param BufferSize Size of the buffer.
984 @param FvHandle Points to the returned firmware volume
985 handle. The firmware volume handle must
986 be unique within the system.
988 @retval EFI_SUCCESS Firmware volume handle created.
989 @retval EFI_VOLUME_CORRUPTED Volume was corrupt.
994 PeiFfs2FvPpiProcessVolume (
995 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
998 OUT EFI_PEI_FV_HANDLE
*FvHandle
1003 ASSERT (FvHandle
!= NULL
);
1005 if (Buffer
== NULL
) {
1006 return EFI_VOLUME_CORRUPTED
;
1010 // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2 support memory-mapped
1011 // FV image and the handle is pointed to Fv image's buffer.
1013 *FvHandle
= (EFI_PEI_FV_HANDLE
) Buffer
;
1016 // Do verify for given FV buffer.
1018 Status
= VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER
*) Buffer
);
1019 if (EFI_ERROR(Status
)) {
1020 DEBUG ((EFI_D_ERROR
, "Fail to verify FV which address is 0x%11p", Buffer
));
1021 return EFI_VOLUME_CORRUPTED
;
1028 Finds the next file of the specified type.
1030 This service enables PEI modules to discover additional firmware files.
1031 The FileHandle must be unique within the system.
1033 @param This Points to this instance of the
1034 EFI_PEI_FIRMWARE_VOLUME_PPI.
1035 @param SearchType A filter to find only files of this type. Type
1036 EFI_FV_FILETYPE_ALL causes no filtering to be
1038 @param FvHandle Handle of firmware volume in which to
1040 @param FileHandle Points to the current handle from which to
1041 begin searching or NULL to start at the
1042 beginning of the firmware volume. Updated
1043 upon return to reflect the file found.
1045 @retval EFI_SUCCESS The file was found.
1046 @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.
1051 PeiFfs2FvPpiFindFileByType (
1052 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1053 IN EFI_FV_FILETYPE SearchType
,
1054 IN EFI_PEI_FV_HANDLE FvHandle
,
1055 IN OUT EFI_PEI_FILE_HANDLE
*FileHandle
1058 return FindFileEx (FvHandle
, NULL
, SearchType
, FileHandle
, NULL
);
1062 Find a file within a volume by its name.
1064 This service searches for files with a specific name, within
1065 either the specified firmware volume or all firmware volumes.
1067 @param This Points to this instance of the
1068 EFI_PEI_FIRMWARE_VOLUME_PPI.
1069 @param FileName A pointer to the name of the file to find
1070 within the firmware volume.
1071 @param FvHandle Upon entry, the pointer to the firmware
1072 volume to search or NULL if all firmware
1073 volumes should be searched. Upon exit, the
1074 actual firmware volume in which the file was
1076 @param FileHandle Upon exit, points to the found file's
1077 handle or NULL if it could not be found.
1079 @retval EFI_SUCCESS File was found.
1080 @retval EFI_NOT_FOUND File was not found.
1081 @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or
1088 PeiFfs2FvPpiFindFileByName (
1089 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1090 IN CONST EFI_GUID
*FileName
,
1091 IN EFI_PEI_FV_HANDLE
*FvHandle
,
1092 OUT EFI_PEI_FILE_HANDLE
*FileHandle
1096 PEI_CORE_INSTANCE
*PrivateData
;
1099 if ((FvHandle
== NULL
) || (FileName
== NULL
) || (FileHandle
== NULL
)) {
1100 return EFI_INVALID_PARAMETER
;
1103 if (*FvHandle
!= NULL
) {
1104 Status
= FindFileEx (*FvHandle
, FileName
, 0, FileHandle
, NULL
);
1105 if (Status
== EFI_NOT_FOUND
) {
1110 // If *FvHandle = NULL, so search all FV for given filename
1112 Status
= EFI_NOT_FOUND
;
1114 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
1115 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1117 // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
1119 if (PrivateData
->Fv
[Index
].FvPpi
!= NULL
) {
1120 Status
= FindFileEx (PrivateData
->Fv
[Index
].FvHandle
, FileName
, 0, FileHandle
, NULL
);
1121 if (!EFI_ERROR (Status
)) {
1122 *FvHandle
= PrivateData
->Fv
[Index
].FvHandle
;
1132 Returns information about a specific file.
1134 This function returns information about a specific
1135 file, including its file name, type, attributes, starting
1138 @param This Points to this instance of the
1139 EFI_PEI_FIRMWARE_VOLUME_PPI.
1140 @param FileHandle Handle of the file.
1141 @param FileInfo Upon exit, points to the file's
1144 @retval EFI_SUCCESS File information returned.
1145 @retval EFI_INVALID_PARAMETER If FileHandle does not
1146 represent a valid file.
1147 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
1152 PeiFfs2FvPpiGetFileInfo (
1153 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1154 IN EFI_PEI_FILE_HANDLE FileHandle
,
1155 OUT EFI_FV_FILE_INFO
*FileInfo
1159 UINT8 ErasePolarity
;
1160 EFI_FFS_FILE_HEADER
*FileHeader
;
1161 PEI_CORE_FV_HANDLE
*CoreFvHandle
;
1163 if ((FileHandle
== NULL
) || (FileInfo
== NULL
)) {
1164 return EFI_INVALID_PARAMETER
;
1168 // Retrieve the FirmwareVolume which the file resides in.
1170 CoreFvHandle
= FileHandleToVolume (FileHandle
);
1171 if (CoreFvHandle
== NULL
) {
1172 return EFI_INVALID_PARAMETER
;
1175 if (CoreFvHandle
->FvHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
1182 // Get FileState which is the highest bit of the State
1184 FileState
= GetFileState (ErasePolarity
, (EFI_FFS_FILE_HEADER
*)FileHandle
);
1186 switch (FileState
) {
1187 case EFI_FILE_DATA_VALID
:
1188 case EFI_FILE_MARKED_FOR_UPDATE
:
1191 return EFI_INVALID_PARAMETER
;
1194 FileHeader
= (EFI_FFS_FILE_HEADER
*)FileHandle
;
1195 CopyMem (&FileInfo
->FileName
, &FileHeader
->Name
, sizeof(EFI_GUID
));
1196 FileInfo
->FileType
= FileHeader
->Type
;
1197 FileInfo
->FileAttributes
= FileHeader
->Attributes
;
1198 FileInfo
->BufferSize
= ((*(UINT32
*)FileHeader
->Size
) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER
);
1199 FileInfo
->Buffer
= (FileHeader
+ 1);
1204 This function returns information about the firmware volume.
1206 @param This Points to this instance of the
1207 EFI_PEI_FIRMWARE_VOLUME_PPI.
1208 @param FvHandle Handle to the firmware handle.
1209 @param VolumeInfo Points to the returned firmware volume
1212 @retval EFI_SUCCESS Information returned successfully.
1213 @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid
1214 firmware volume or VolumeInfo is NULL.
1219 PeiFfs2FvPpiGetVolumeInfo (
1220 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1221 IN EFI_PEI_FV_HANDLE FvHandle
,
1222 OUT EFI_FV_INFO
*VolumeInfo
1225 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader
;
1226 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExHeaderInfo
;
1228 if (VolumeInfo
== NULL
) {
1229 return EFI_INVALID_PARAMETER
;
1233 // VolumeHandle may not align at 8 byte,
1234 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
1235 // So, Copy FvHeader into the local FvHeader structure.
1237 CopyMem (&FwVolHeader
, FvHandle
, sizeof (EFI_FIRMWARE_VOLUME_HEADER
));
1240 // Check Fv Image Signature
1242 if (FwVolHeader
.Signature
!= EFI_FVH_SIGNATURE
) {
1243 return EFI_INVALID_PARAMETER
;
1246 ZeroMem (VolumeInfo
, sizeof (EFI_FV_INFO
));
1247 VolumeInfo
->FvAttributes
= FwVolHeader
.Attributes
;
1248 VolumeInfo
->FvStart
= (VOID
*) FvHandle
;
1249 VolumeInfo
->FvSize
= FwVolHeader
.FvLength
;
1250 CopyMem (&VolumeInfo
->FvFormat
, &FwVolHeader
.FileSystemGuid
, sizeof(EFI_GUID
));
1252 if (FwVolHeader
.ExtHeaderOffset
!= 0) {
1253 FwVolExHeaderInfo
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*)(((UINT8
*)FvHandle
) + FwVolHeader
.ExtHeaderOffset
);
1254 CopyMem (&VolumeInfo
->FvName
, &FwVolExHeaderInfo
->FvName
, sizeof(EFI_GUID
));
1261 Find the next matching section in the firmware file.
1263 This service enables PEI modules to discover sections
1264 of a given type within a valid file.
1266 @param This Points to this instance of the
1267 EFI_PEI_FIRMWARE_VOLUME_PPI.
1268 @param SearchType A filter to find only sections of this
1270 @param FileHandle Handle of firmware file in which to
1272 @param SectionData Updated upon return to point to the
1275 @retval EFI_SUCCESS Section was found.
1276 @retval EFI_NOT_FOUND Section of the specified type was not
1277 found. SectionData contains NULL.
1281 PeiFfs2FvPpiFindSectionByType (
1282 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI
*This
,
1283 IN EFI_SECTION_TYPE SearchType
,
1284 IN EFI_PEI_FILE_HANDLE FileHandle
,
1285 OUT VOID
**SectionData
1288 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
1290 EFI_COMMON_SECTION_HEADER
*Section
;
1292 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)(FileHandle
);
1295 // Size is 24 bits wide so mask upper 8 bits.
1296 // Does not include FfsFileHeader header size
1297 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
1299 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
1300 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
1301 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
1303 return ProcessSection (
1304 GetPeiServicesTablePointer (),
1313 Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.
1315 @param FvHandle The handle of a FV.
1317 @retval NULL if can not find.
1318 @return Pointer of corresponding PEI_CORE_FV_HANDLE.
1320 PEI_CORE_FV_HANDLE
*
1321 FvHandleToCoreHandle (
1322 IN EFI_PEI_FV_HANDLE FvHandle
1326 PEI_CORE_INSTANCE
*PrivateData
;
1328 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());
1329 for (Index
= 0; Index
< PrivateData
->FvCount
; Index
++) {
1330 if (FvHandle
== PrivateData
->Fv
[Index
].FvHandle
) {
1331 return &PrivateData
->Fv
[Index
];
1339 Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.
1341 This routine also will install FvInfo ppi for FV hob in PI ways.
1343 @param Private Pointer of PEI_CORE_INSTANCE
1344 @param Instance The index of FV want to be searched.
1346 @return Instance of PEI_CORE_FV_HANDLE.
1348 PEI_CORE_FV_HANDLE
*
1349 FindNextCoreFvHandle (
1350 IN PEI_CORE_INSTANCE
*Private
,
1356 EFI_HOB_FIRMWARE_VOLUME
*FvHob
;
1359 // Handle Framework FvHob and Install FvInfo Ppi for it.
1361 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport
)) {
1363 // Loop to search the wanted FirmwareVolume which supports FFS
1365 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetFirstHob (EFI_HOB_TYPE_FV
);
1366 while (FvHob
!= NULL
) {
1367 for (Index
= 0, Match
= FALSE
; Index
< Private
->FvCount
; Index
++) {
1368 if ((EFI_PEI_FV_HANDLE
)(UINTN
)FvHob
->BaseAddress
== Private
->Fv
[Index
].FvHeader
) {
1374 // If Not Found, Install FvInfo Ppi for it.
1377 PeiServicesInstallFvInfoPpi (
1378 &(((EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)FvHob
->BaseAddress
)->FileSystemGuid
),
1379 (VOID
*)(UINTN
)FvHob
->BaseAddress
,
1380 (UINT32
)FvHob
->Length
,
1385 FvHob
= (EFI_HOB_FIRMWARE_VOLUME
*)GetNextHob (EFI_HOB_TYPE_FV
, (VOID
*)((UINTN
)FvHob
+ FvHob
->Header
.HobLength
));
1389 if (Instance
>= Private
->FvCount
) {
1393 return &Private
->Fv
[Instance
];
1397 After PeiCore image is shadowed into permanent memory, all build-in FvPpi should
1398 be re-installed with the instance in permanent memory and all cached FvPpi pointers in
1399 PrivateData->Fv[] array should be fixed up to be pointed to the one in permenant
1402 @param PrivateData Pointer to PEI_CORE_INSTANCE.
1406 IN PEI_CORE_INSTANCE
*PrivateData
1410 EFI_PEI_PPI_DESCRIPTOR
*OldDescriptor
;
1415 // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
1418 Status
= PeiServicesLocatePpi (
1419 &gEfiFirmwareFileSystem2Guid
,
1424 ASSERT_EFI_ERROR (Status
);
1427 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
1428 // which is shadowed from flash to permanent memory within PeiCore image.
1430 Status
= PeiServicesReInstallPpi (OldDescriptor
, &mPeiFfs2FvPpiList
);
1431 ASSERT_EFI_ERROR (Status
);
1434 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.
1436 for (Index
= 0; Index
< FixedPcdGet32 (PcdPeiCoreMaxFvSupported
); Index
++) {
1437 if (PrivateData
->Fv
[Index
].FvPpi
== OldFfs2FvPpi
) {
1438 PrivateData
->Fv
[Index
].FvPpi
= &mPeiFfs2FvPpi
;