3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Responsibility of this module is to load the DXE Core from a Firmware Volume.
25 BOOLEAN gInMemory
= FALSE
;
28 // Module Globals used in the DXE to PEI handoff
29 // These must be module globals, so the stack can be switched
31 static EFI_DXE_IPL_PPI mDxeIplPpi
= {
35 static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi
= {
39 static EFI_PEI_PPI_DESCRIPTOR mPpiLoadFile
= {
40 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
41 &gEfiPeiFvFileLoaderPpiGuid
,
45 static EFI_PEI_PPI_DESCRIPTOR mPpiList
= {
46 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
51 static EFI_PEI_PPI_DESCRIPTOR mPpiPeiInMemory
= {
52 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
57 static EFI_PEI_PPI_DESCRIPTOR mPpiSignal
= {
58 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
59 &gEfiEndOfPeiSignalPpiGuid
,
63 DECOMPRESS_LIBRARY gEfiDecompress
= {
64 UefiDecompressGetInfo
,
68 DECOMPRESS_LIBRARY gTianoDecompress
= {
69 TianoDecompressGetInfo
,
73 DECOMPRESS_LIBRARY gCustomDecompress
= {
74 CustomDecompressGetInfo
,
87 OccupiedSize
= ActualSize
;
88 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
97 PeimInitializeDxeIpl (
98 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
99 IN EFI_PEI_SERVICES
**PeiServices
105 Initializes the Dxe Ipl PPI
109 FfsHeader - Pointer to FFS file header
110 PeiServices - General purpose services available to every PEIM.
119 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
120 EFI_BOOT_MODE BootMode
;
122 Status
= PeiServicesGetBootMode (&BootMode
);
124 ASSERT_EFI_ERROR (Status
);
126 Status
= PeiServicesLocatePpi (
133 if (EFI_ERROR (Status
) && (BootMode
!= BOOT_ON_S3_RESUME
)) {
135 // The DxeIpl has not yet been shadowed
137 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
140 // Shadow DxeIpl and then re-run its entry point
142 Status
= ShadowDxeIpl (FfsHeader
, PeiEfiPeiPeCoffLoader
);
143 if (EFI_ERROR (Status
)) {
148 if (BootMode
!= BOOT_ON_S3_RESUME
) {
150 // The DxeIpl has been shadowed
155 // Install LoadFile PPI
157 Status
= PeiServicesInstallPpi (&mPpiLoadFile
);
159 if (EFI_ERROR (Status
)) {
164 // Install DxeIpl PPI
166 PeiServicesInstallPpi (&mPpiList
);
168 if (EFI_ERROR (Status
)) {
180 IN EFI_DXE_IPL_PPI
*This
,
181 IN EFI_PEI_SERVICES
**PeiServices
,
182 IN EFI_PEI_HOB_POINTERS HobList
188 Main entry point to last PEIM
191 This - Entry point for DXE IPL PPI
192 PeiServices - General purpose services available to every PEIM.
193 HobList - Address to the Pei HOB list
197 EFI_SUCCESS - DEX core was successfully loaded.
198 EFI_OUT_OF_RESOURCES - There are not enough resources to load DXE core.
205 EFI_PHYSICAL_ADDRESS BspStore
;
206 EFI_GUID DxeCoreFileName
;
207 EFI_GUID FirmwareFileName
;
209 EFI_PHYSICAL_ADDRESS DxeCoreAddress
;
211 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint
;
212 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
213 EFI_BOOT_MODE BootMode
;
214 EFI_PEI_RECOVERY_MODULE_PPI
*PeiRecovery
;
215 EFI_PEI_S3_RESUME_PPI
*S3Resume
;
217 // PERF_START (PeiServices, L"DxeIpl", NULL, 0);
221 Status
= EFI_SUCCESS
;
224 // if in S3 Resume, restore configure
226 Status
= PeiServicesGetBootMode (&BootMode
);
228 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_ON_S3_RESUME
)) {
229 Status
= PeiServicesLocatePpi (
230 &gEfiPeiS3ResumePpiGuid
,
236 ASSERT_EFI_ERROR (Status
);
238 Status
= S3Resume
->S3RestoreConfig (PeiServices
);
240 ASSERT_EFI_ERROR (Status
);
243 Status
= EFI_SUCCESS
;
246 // Install the PEI Protocols that are shared between PEI and DXE
248 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
249 ASSERT (PeiEfiPeiPeCoffLoader
!= NULL
);
253 // Allocate 128KB for the Stack
255 BaseOfStack
= AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE
));
256 ASSERT (BaseOfStack
!= NULL
);
259 // Compute the top of the stack we were allocated. Pre-allocate a UINTN
262 TopOfStack
= (VOID
*)((UINTN
)BaseOfStack
+ EFI_SIZE_TO_PAGES (STACK_SIZE
) * EFI_PAGE_SIZE
- sizeof (UINTN
));
265 // Add architecture-specifc HOBs (including the BspStore HOB)
267 Status
= CreateArchSpecificHobs (&BspStore
);
269 ASSERT_EFI_ERROR (Status
);
272 // Add HOB for the EFI Decompress Protocol
275 &gEfiDecompressProtocolGuid
,
276 (VOID
*)&gEfiDecompress
,
277 sizeof (gEfiDecompress
)
281 // Add HOB for the Tiano Decompress Protocol
284 &gEfiTianoDecompressProtocolGuid
,
285 (VOID
*)&gTianoDecompress
,
286 sizeof (gTianoDecompress
)
290 // Add HOB for the user customized Decompress Protocol
293 &gEfiCustomizedDecompressProtocolGuid
,
294 (VOID
*)&gCustomDecompress
,
295 sizeof (gCustomDecompress
)
299 // Add HOB for the PE/COFF Loader Protocol
302 &gEfiPeiPeCoffLoaderGuid
,
303 (VOID
*)&PeiEfiPeiPeCoffLoader
,
308 // See if we are in crisis recovery
310 Status
= PeiServicesGetBootMode (&BootMode
);
312 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_IN_RECOVERY_MODE
)) {
314 Status
= PeiServicesLocatePpi (
315 &gEfiPeiRecoveryModulePpiGuid
,
318 (VOID
**)&PeiRecovery
321 ASSERT_EFI_ERROR (Status
);
322 Status
= PeiRecovery
->LoadRecoveryCapsule (PeiServices
, PeiRecovery
);
323 if (EFI_ERROR (Status
)) {
324 DEBUG ((EFI_D_ERROR
, "Load Recovery Capsule Failed.(Status = %r)\n", Status
));
329 // Now should have a HOB with the DXE core w/ the old HOB destroyed
334 // Find the EFI_FV_FILETYPE_RAW type compressed Firmware Volume file in FTW spare block
335 // The file found will be processed by PeiProcessFile: It will first be decompressed to
336 // a normal FV, then a corresponding FV type hob will be built which is provided for DXE
337 // core to find and dispatch drivers in this FV. Because PeiProcessFile typically checks
338 // for EFI_FV_FILETYPE_DXE_CORE type file, in this condition we need not check returned
341 Status
= PeiFindFile (
349 // Find the DXE Core in a Firmware Volume
351 Status
= PeiFindFile (
352 EFI_FV_FILETYPE_DXE_CORE
,
358 ASSERT_EFI_ERROR (Status
);
361 // Load the DXE Core from a Firmware Volume
363 Status
= PeiLoadFile (
364 PeiEfiPeiPeCoffLoader
,
371 ASSERT_EFI_ERROR (Status
);
374 // Transfer control to the DXE Core
375 // The handoff state is simply a pointer to the HOB list
378 Status
= PeiServicesInstallPpi (&mPpiSignal
);
380 ASSERT_EFI_ERROR (Status
);
383 // Add HOB for the DXE Core
393 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
397 EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
400 DEBUG ((EFI_D_INFO
, "DXE Core Entry\n"));
402 (SWITCH_STACK_ENTRY_POINT
)(UINTN
)DxeCoreEntryPoint
,
406 (VOID
*) (UINTN
) BspStore
410 // If we get here, then the DXE Core returned. This is an error
411 // Dxe Core should not return.
416 return EFI_OUT_OF_RESOURCES
;
422 IN UINT16 SectionType
,
423 OUT EFI_GUID
*FileName
,
430 Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
431 described in the HOB list. Able to search in a compression set in a FFS file.
432 But only one level of compression is supported, that is, not able to search
433 in a compression set that is within another compression set.
437 Type - The Type of file to retrieve
439 SectionType - The type of section to retrieve from a file
441 FileName - The name of the file found in the Firmware Volume
443 Pe32Data - Pointer to the beginning of the PE/COFF file found in the Firmware Volume
447 EFI_SUCCESS - The file was found, and the name is returned in FileName, and a pointer to
448 the PE/COFF image is returned in Pe32Data
450 EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List
454 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
455 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
458 EFI_PEI_HOB_POINTERS Hob
;
462 FfsFileHeader
= NULL
;
466 // Foreach Firmware Volume, look for a specified type
467 // of file and break out when one is found
469 Hob
.Raw
= GetHobList ();
470 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
)) != NULL
) {
471 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) (Hob
.FirmwareVolume
->BaseAddress
);
472 Status
= PeiServicesFfsFindNextFile (
477 if (!EFI_ERROR (Status
)) {
478 Status
= PeiProcessFile (
483 CopyMem (FileName
, &FfsFileHeader
->Name
, sizeof (EFI_GUID
));
486 Hob
.Raw
= GET_NEXT_HOB (Hob
);
488 return EFI_NOT_FOUND
;
493 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
,
495 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
496 OUT UINT64
*ImageSize
,
497 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
503 Loads and relocates a PE/COFF image into memory.
507 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
509 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
511 ImageAddress - The base address of the relocated PE/COFF image
513 ImageSize - The size of the relocated PE/COFF image
515 EntryPoint - The entry point of the relocated PE/COFF image
519 EFI_SUCCESS - The file was loaded and relocated
521 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
526 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
528 ZeroMem (&ImageContext
, sizeof (ImageContext
));
529 ImageContext
.Handle
= Pe32Data
;
530 Status
= GetImageReadFunction (&ImageContext
);
532 ASSERT_EFI_ERROR (Status
);
534 Status
= PeiEfiPeiPeCoffLoader
->GetImageInfo (PeiEfiPeiPeCoffLoader
, &ImageContext
);
535 if (EFI_ERROR (Status
)) {
539 // Allocate Memory for the image
541 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
));
542 ASSERT (ImageContext
.ImageAddress
!= 0);
545 // Load the image to our new buffer
547 Status
= PeiEfiPeiPeCoffLoader
->LoadImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
548 if (EFI_ERROR (Status
)) {
552 // Relocate the image in our new buffer
554 Status
= PeiEfiPeiPeCoffLoader
->RelocateImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
555 if (EFI_ERROR (Status
)) {
560 // Flush the instruction cache so the image data is written before we execute it
562 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
564 *ImageAddress
= ImageContext
.ImageAddress
;
565 *ImageSize
= ImageContext
.ImageSize
;
566 *EntryPoint
= ImageContext
.EntryPoint
;
573 IN EFI_FFS_FILE_HEADER
*DxeIplFileHeader
,
574 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
580 Shadow the DXE IPL to a different memory location. This occurs after permanent
581 memory has been discovered.
585 DxeIplFileHeader - Pointer to the FFS file header of the DXE IPL driver
587 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
591 EFI_SUCCESS - DXE IPL was successfully shadowed to a different memory location.
593 EFI_ ERROR - The shadow was unsuccessful.
599 UINTN OccupiedSectionLength
;
600 EFI_PHYSICAL_ADDRESS DxeIplAddress
;
602 EFI_PHYSICAL_ADDRESS DxeIplEntryPoint
;
604 EFI_COMMON_SECTION_HEADER
*Section
;
606 Section
= (EFI_COMMON_SECTION_HEADER
*) (DxeIplFileHeader
+ 1);
608 while ((Section
->Type
!= EFI_SECTION_PE32
) && (Section
->Type
!= EFI_SECTION_TE
)) {
609 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
610 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
611 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
614 // Relocate DxeIpl into memory by using loadfile service
616 Status
= PeiLoadFile (
617 PeiEfiPeiPeCoffLoader
,
618 (VOID
*) (Section
+ 1),
624 if (Status
== EFI_SUCCESS
) {
626 // Install PeiInMemory to indicate the Dxeipl is shadowed
628 Status
= PeiServicesInstallPpi (&mPpiPeiInMemory
);
630 if (EFI_ERROR (Status
)) {
634 Status
= ((EFI_PEIM_ENTRY_POINT
) (UINTN
) DxeIplEntryPoint
) (DxeIplFileHeader
, GetPeiServicesTablePointer());
643 IN EFI_PEI_FV_FILE_LOADER_PPI
*This
,
644 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
645 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
646 OUT UINT64
*ImageSize
,
647 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
653 Given a pointer to an FFS file containing a PE32 image, get the
654 information on the PE32 image, and then "load" it so that it
659 This - pointer to our file loader protocol
661 FfsHeader - pointer to the FFS file header of the FFS file that
662 contains the PE32 image we want to load
664 ImageAddress - returned address where the PE32 image is loaded
666 ImageSize - returned size of the loaded PE32 image
668 EntryPoint - entry point to the loaded PE32 image
672 EFI_SUCCESS - The FFS file was successfully loaded.
674 EFI_ERROR - Unable to load the FFS file.
678 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
683 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
686 // Preprocess the FFS file to get a pointer to the PE32 information
687 // in the enclosed PE32 image.
689 Status
= PeiProcessFile (
695 if (EFI_ERROR (Status
)) {
699 // Load the PE image from the FFS file
701 Status
= PeiLoadFile (
702 PeiEfiPeiPeCoffLoader
,
714 IN UINT16 SectionType
,
715 IN OUT EFI_FFS_FILE_HEADER
**RealFfsFileHeader
,
724 SectionType - The type of section in the FFS file to process.
726 FfsFileHeader - Pointer to the FFS file to process, looking for the
727 specified SectionType
729 Pe32Data - returned pointer to the start of the PE32 image found
734 EFI_SUCCESS - found the PE32 section in the FFS file
740 DECOMPRESS_LIBRARY
*DecompressLibrary
;
742 UINT8
*ScratchBuffer
;
743 UINT32 DstBufferSize
;
744 UINT32 ScratchBufferSize
;
745 EFI_COMMON_SECTION_HEADER
*CmpSection
;
746 UINTN CmpSectionLength
;
747 UINTN OccupiedCmpSectionLength
;
750 EFI_COMMON_SECTION_HEADER
*Section
;
752 UINTN OccupiedSectionLength
;
754 EFI_GUID_DEFINED_SECTION
*GuidedSectionHeader
;
755 UINT32 AuthenticationStatus
;
756 EFI_PEI_SECTION_EXTRACTION_PPI
*SectionExtract
;
759 EFI_PEI_SECURITY_PPI
*Security
;
760 BOOLEAN StartCrisisRecovery
;
762 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
763 EFI_COMPRESSION_SECTION
*CompressionSection
;
764 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
766 FfsFileHeader
= *RealFfsFileHeader
;
768 Status
= PeiServicesFfsFindSectionData (
769 EFI_SECTION_COMPRESSION
,
775 // Upon finding a DXE Core file, see if there is first a compression section
777 if (!EFI_ERROR (Status
)) {
779 // Yes, there is a compression section, so extract the contents
780 // Decompress the image here
782 Section
= (EFI_COMMON_SECTION_HEADER
*) (UINTN
) (VOID
*) ((UINT8
*) (FfsFileHeader
) + (UINTN
) sizeof (EFI_FFS_FILE_HEADER
));
785 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
786 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
789 // Was the DXE Core file encapsulated in a GUID'd section?
791 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
793 // Locate the GUID'd Section Extractor
795 GuidedSectionHeader
= (VOID
*) (Section
+ 1);
798 // This following code constitutes the addition of the security model
802 // Set a default authenticatino state
804 AuthenticationStatus
= 0;
806 Status
= PeiServicesLocatePpi (
807 &gEfiPeiSectionExtractionPpiGuid
,
810 (VOID
**)&SectionExtract
813 if (EFI_ERROR (Status
)) {
817 // Verify Authentication State
819 CopyMem (&TempGuid
, Section
+ 1, sizeof (EFI_GUID
));
821 Status
= SectionExtract
->PeiGetSection (
822 GetPeiServicesTablePointer(),
824 (EFI_SECTION_TYPE
*) &SectionType
,
829 &AuthenticationStatus
832 if (EFI_ERROR (Status
)) {
836 // If not ask the Security PPI, if exists, for disposition
839 Status
= PeiServicesLocatePpi (
840 &gEfiPeiSecurityPpiGuid
,
845 if (EFI_ERROR (Status
)) {
849 Status
= Security
->AuthenticationState (
850 GetPeiServicesTablePointer(),
851 (struct _EFI_PEI_SECURITY_PPI
*) Security
,
852 AuthenticationStatus
,
857 if (EFI_ERROR (Status
)) {
861 // If there is a security violation, report to caller and have
862 // the upper-level logic possible engender a crisis recovery
864 if (StartCrisisRecovery
) {
865 return EFI_SECURITY_VIOLATION
;
869 if (Section
->Type
== EFI_SECTION_PE32
) {
871 // This is what we want
873 *Pe32Data
= (VOID
*) (Section
+ 1);
875 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
877 // This is a compression set, expand it
879 CompressionSection
= (EFI_COMPRESSION_SECTION
*) Section
;
881 switch (CompressionSection
->CompressionType
) {
882 case EFI_STANDARD_COMPRESSION
:
883 DecompressLibrary
= &gTianoDecompress
;
886 case EFI_CUSTOMIZED_COMPRESSION
:
888 // Load user customized compression protocol.
890 DecompressLibrary
= &gCustomDecompress
;
893 case EFI_NOT_COMPRESSED
:
896 // Need to support not compressed file
898 ASSERT_EFI_ERROR (Status
);
899 return EFI_NOT_FOUND
;
902 Status
= DecompressLibrary
->GetInfo (
903 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
904 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
908 if (EFI_ERROR (Status
)) {
912 return EFI_NOT_FOUND
;
916 // Allocate scratch buffer
918 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
919 if (ScratchBuffer
== NULL
) {
920 return EFI_OUT_OF_RESOURCES
;
924 // Allocate destination buffer
926 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
927 if (DstBuffer
== NULL
) {
928 return EFI_OUT_OF_RESOURCES
;
932 // Call decompress function
934 Status
= DecompressLibrary
->Decompress (
935 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
940 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) DstBuffer
;
941 if (CmpSection
->Type
== EFI_SECTION_RAW
) {
943 // Skip the section header and
944 // adjust the pointer alignment to 16
946 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (DstBuffer
+ 16);
948 if (FvHeader
->Signature
== EFI_FVH_SIGNATURE
) {
949 FfsFileHeader
= NULL
;
950 BuildFvHob ((EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
, FvHeader
->FvLength
);
951 Status
= PeiServicesFfsFindNextFile (
952 EFI_FV_FILETYPE_DXE_CORE
,
957 if (EFI_ERROR (Status
)) {
958 return EFI_NOT_FOUND
;
962 // Reture the FfsHeader that contain Pe32Data.
964 *RealFfsFileHeader
= FfsFileHeader
;
965 return PeiProcessFile (SectionType
, RealFfsFileHeader
, Pe32Data
);
969 // Decompress successfully.
970 // Loop the decompressed data searching for expected section.
972 CmpFileData
= (VOID
*) DstBuffer
;
973 CmpFileSize
= DstBufferSize
;
975 CmpSectionLength
= *(UINT32
*) (CmpSection
->Size
) & 0x00ffffff;
976 if (CmpSection
->Type
== EFI_SECTION_PE32
) {
978 // This is what we want
980 *Pe32Data
= (VOID
*) (CmpSection
+ 1);
984 OccupiedCmpSectionLength
= GetOccupiedSize (CmpSectionLength
, 4);
985 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) CmpSection
+ OccupiedCmpSectionLength
);
986 } while (CmpSection
->Type
!= 0 && (UINTN
) ((UINT8
*) CmpSection
- (UINT8
*) CmpFileData
) < CmpFileSize
);
989 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
990 FileSize
= FfsFileHeader
->Size
[0] & 0xFF;
991 FileSize
+= (FfsFileHeader
->Size
[1] << 8) & 0xFF00;
992 FileSize
+= (FfsFileHeader
->Size
[2] << 16) & 0xFF0000;
993 FileSize
&= 0x00FFFFFF;
994 } while (Section
->Type
!= 0 && (UINTN
) ((UINT8
*) Section
- (UINT8
*) FfsFileHeader
) < FileSize
);
997 // End of the decompression activity
1001 Status
= PeiServicesFfsFindSectionData (
1007 if (EFI_ERROR (Status
)) {
1008 Status
= PeiServicesFfsFindSectionData (
1013 if (EFI_ERROR (Status
)) {
1019 *Pe32Data
= SectionData
;