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 #pragma warning( disable : 4305 )
27 BOOLEAN gInMemory
= FALSE
;
32 #define EFI_PPI_NEEDED_BY_DXE \
34 0x4d37da42, 0x3a0c, 0x4eda, 0xb9, 0xeb, 0xbc, 0x0e, 0x1d, 0xb4, 0x71, 0x3b \
36 EFI_GUID mPpiNeededByDxeGuid
= EFI_PPI_NEEDED_BY_DXE
;
39 // Module Globals used in the DXE to PEI handoff
40 // These must be module globals, so the stack can be switched
42 static EFI_DXE_IPL_PPI mDxeIplPpi
= {
46 static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi
= {
50 static EFI_PEI_PPI_DESCRIPTOR mPpiLoadFile
= {
51 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
52 &gEfiPeiFvFileLoaderPpiGuid
,
56 static EFI_PEI_PPI_DESCRIPTOR mPpiList
= {
57 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
62 static EFI_PEI_PPI_DESCRIPTOR mPpiPeiInMemory
= {
63 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
68 static EFI_PEI_PPI_DESCRIPTOR mPpiSignal
= {
69 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
70 &gEfiEndOfPeiSignalPpiGuid
,
74 DECOMPRESS_LIBRARY gEfiDecompress
= {
75 UefiDecompressGetInfo
,
79 DECOMPRESS_LIBRARY gTianoDecompress
= {
80 TianoDecompressGetInfo
,
84 DECOMPRESS_LIBRARY gCustomDecompress
= {
85 CustomDecompressGetInfo
,
98 OccupiedSize
= ActualSize
;
99 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
108 PeimInitializeDxeIpl (
109 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
110 IN EFI_PEI_SERVICES
**PeiServices
116 Initializes the Dxe Ipl PPI
120 FfsHeader - Pointer to FFS file header
121 PeiServices - General purpose services available to every PEIM.
130 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
131 EFI_BOOT_MODE BootMode
;
133 Status
= PeiServicesGetBootMode (&BootMode
);
135 ASSERT_EFI_ERROR (Status
);
137 Status
= PeiServicesLocatePpi (
144 if (EFI_ERROR (Status
) && (BootMode
!= BOOT_ON_S3_RESUME
)) {
146 // The DxeIpl has not yet been shadowed
148 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
151 // Shadow DxeIpl and then re-run its entry point
153 Status
= ShadowDxeIpl (FfsHeader
, PeiEfiPeiPeCoffLoader
);
154 if (EFI_ERROR (Status
)) {
159 if (BootMode
!= BOOT_ON_S3_RESUME
) {
161 // The DxeIpl has been shadowed
166 // Install LoadFile PPI
168 Status
= PeiServicesInstallPpi (&mPpiLoadFile
);
170 if (EFI_ERROR (Status
)) {
175 // Install DxeIpl PPI
177 PeiServicesInstallPpi (&mPpiList
);
179 if (EFI_ERROR (Status
)) {
191 IN EFI_DXE_IPL_PPI
*This
,
192 IN EFI_PEI_SERVICES
**PeiServices
,
193 IN EFI_PEI_HOB_POINTERS HobList
199 Main entry point to last PEIM
203 This - Entry point for DXE IPL PPI
204 PeiServices - General purpose services available to every PEIM.
205 HobList - Address to the Pei HOB list
209 EFI_SUCCESS - DEX core was successfully loaded.
210 EFI_OUT_OF_RESOURCES - There are not enough resources to load DXE core.
215 EFI_PHYSICAL_ADDRESS TopOfStack
;
216 EFI_PHYSICAL_ADDRESS BaseOfStack
;
217 EFI_PHYSICAL_ADDRESS BspStore
;
218 EFI_GUID DxeCoreFileName
;
219 VOID
*DxeCorePe32Data
;
220 EFI_PHYSICAL_ADDRESS DxeCoreAddress
;
222 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint
;
223 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
224 EFI_BOOT_MODE BootMode
;
225 EFI_PEI_RECOVERY_MODULE_PPI
*PeiRecovery
;
226 EFI_PEI_S3_RESUME_PPI
*S3Resume
;
227 EFI_PHYSICAL_ADDRESS PageTables
;
232 Status
= EFI_SUCCESS
;
235 // if in S3 Resume, restore configure
237 Status
= PeiServicesGetBootMode (&BootMode
);
239 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_ON_S3_RESUME
)) {
240 Status
= PeiServicesLocatePpi (
241 &gEfiPeiS3ResumePpiGuid
,
247 ASSERT_EFI_ERROR (Status
);
249 Status
= S3Resume
->S3RestoreConfig (PeiServices
);
251 ASSERT_EFI_ERROR (Status
);
254 Status
= EFI_SUCCESS
;
257 // Install the PEI Protocols that are shared between PEI and DXE
259 #ifdef EFI_NT_EMULATOR
260 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
261 ASSERT (PeiEfiPeiPeCoffLoader
!= NULL
);
263 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderX64Protocol ();
267 // Allocate 128KB for the Stack
269 PeiServicesAllocatePages (EfiBootServicesData
, EFI_SIZE_TO_PAGES (STACK_SIZE
), &BaseOfStack
);
270 ASSERT (BaseOfStack
!= 0);
273 // Compute the top of the stack we were allocated. Pre-allocate a 32 bytes
274 // for safety (PpisNeededByDxe and DxeCore).
276 TopOfStack
= BaseOfStack
+ EFI_SIZE_TO_PAGES (STACK_SIZE
) * EFI_PAGE_SIZE
- 32;
279 // Add architecture-specifc HOBs (including the BspStore HOB)
281 Status
= CreateArchSpecificHobs (&BspStore
);
282 ASSERT_EFI_ERROR (Status
);
285 // See if we are in crisis recovery
287 Status
= PeiServicesGetBootMode (&BootMode
);
288 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_IN_RECOVERY_MODE
)) {
289 Status
= PeiServicesLocatePpi (
290 &gEfiPeiRecoveryModulePpiGuid
,
293 (VOID
**)&PeiRecovery
296 ASSERT_EFI_ERROR (Status
);
297 Status
= PeiRecovery
->LoadRecoveryCapsule (PeiServices
, PeiRecovery
);
298 ASSERT_EFI_ERROR (Status
);
302 // Find the DXE Core in a Firmware Volume
304 Status
= PeiFindFile (
305 EFI_FV_FILETYPE_DXE_CORE
,
310 ASSERT_EFI_ERROR (Status
);
313 // Transfer control to the DXE Core
314 // The handoff state is simply a pointer to the HOB list
316 // PEI_PERF_END (PeiServices, L"DxeIpl", NULL, 0);
318 Status
= PeiServicesInstallPpi (&mPpiSignal
);
319 ASSERT_EFI_ERROR (Status
);
322 // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA \
323 // memory, it may be corrupted when copying FV to high-end memory
327 // Limit to 36 bits of addressing for debug. Should get it from CPU
329 PageTables
= CreateIdentityMappingPageTables (36);
333 // Load the DXE Core from a Firmware Volume
335 Status
= PeiLoadx64File (
336 PeiEfiPeiPeCoffLoader
,
343 ASSERT_EFI_ERROR (Status
);
347 // Add HOB for the DXE Core
357 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
361 EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
364 DEBUG ((EFI_D_INFO
, "DXE Core Entry\n"));
366 // Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
367 // Call x64 drivers passing in single argument, a pointer to the HOBs.
371 (EFI_PHYSICAL_ADDRESS
)(UINTN
)(HobList
.Raw
),
378 // If we get here, then the DXE Core returned. This is an error
380 ASSERT_EFI_ERROR (Status
);
382 return EFI_OUT_OF_RESOURCES
;
388 IN UINT16 SectionType
,
389 OUT EFI_GUID
*FileName
,
396 Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
397 described in the HOB list. Able to search in a compression set in a FFS file.
398 But only one level of compression is supported, that is, not able to search
399 in a compression set that is within another compression set.
403 Type - The Type of file to retrieve
405 SectionType - The type of section to retrieve from a file
407 FileName - The name of the file found in the Firmware Volume
409 Pe32Data - Pointer to the beginning of the PE/COFF file found in the Firmware Volume
413 EFI_SUCCESS - The file was found, and the name is returned in FileName, and a pointer to
414 the PE/COFF image is returned in Pe32Data
416 EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List
420 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
421 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
424 EFI_PEI_HOB_POINTERS Hob
;
428 FfsFileHeader
= NULL
;
432 // Foreach Firmware Volume, look for a specified type
433 // of file and break out when one is found
435 Hob
.Raw
= GetHobList ();
436 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
)) != NULL
) {
437 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) (Hob
.FirmwareVolume
->BaseAddress
);
438 Status
= PeiServicesFfsFindNextFile (
443 if (!EFI_ERROR (Status
)) {
444 Status
= PeiProcessFile (
449 CopyMem (FileName
, &FfsFileHeader
->Name
, sizeof (EFI_GUID
));
452 Hob
.Raw
= GET_NEXT_HOB (Hob
);
454 return EFI_NOT_FOUND
;
459 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
,
461 IN EFI_MEMORY_TYPE MemoryType
,
462 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
463 OUT UINT64
*ImageSize
,
464 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
470 Loads and relocates a PE/COFF image into memory.
474 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
476 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
478 ImageAddress - The base address of the relocated PE/COFF image
480 ImageSize - The size of the relocated PE/COFF image
482 EntryPoint - The entry point of the relocated PE/COFF image
486 EFI_SUCCESS - The file was loaded and relocated
487 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
492 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
493 EFI_PHYSICAL_ADDRESS MemoryBuffer
;
495 ZeroMem (&ImageContext
, sizeof (ImageContext
));
496 ImageContext
.Handle
= Pe32Data
;
497 Status
= GetImageReadFunction (&ImageContext
);
499 ASSERT_EFI_ERROR (Status
);
501 Status
= PeiEfiPeiPeCoffLoader
->GetImageInfo (PeiEfiPeiPeCoffLoader
, &ImageContext
);
502 if (EFI_ERROR (Status
)) {
506 // Allocate Memory for the image
509 // Allocate Memory for the image
511 PeiServicesAllocatePages (MemoryType
, EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
), &MemoryBuffer
);
512 ImageContext
.ImageAddress
= MemoryBuffer
;
513 ASSERT (ImageContext
.ImageAddress
!= 0);
516 // Load the image to our new buffer
519 Status
= PeiEfiPeiPeCoffLoader
->LoadImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
520 if (EFI_ERROR (Status
)) {
525 // Relocate the image in our new buffer
527 Status
= PeiEfiPeiPeCoffLoader
->RelocateImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
528 if (EFI_ERROR (Status
)) {
533 // Flush the instruction cache so the image data is written before we execute it
535 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
537 *ImageAddress
= ImageContext
.ImageAddress
;
538 *ImageSize
= ImageContext
.ImageSize
;
539 *EntryPoint
= ImageContext
.EntryPoint
;
546 IN EFI_FFS_FILE_HEADER
*DxeIplFileHeader
,
547 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
553 Shadow the DXE IPL to a different memory location. This occurs after permanent
554 memory has been discovered.
558 DxeIplFileHeader - Pointer to the FFS file header of the DXE IPL driver
560 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
564 EFI_SUCCESS - DXE IPL was successfully shadowed to a different memory location.
566 EFI_ ERROR - The shadow was unsuccessful.
572 UINTN OccupiedSectionLength
;
573 EFI_PHYSICAL_ADDRESS DxeIplAddress
;
575 EFI_PHYSICAL_ADDRESS DxeIplEntryPoint
;
577 EFI_COMMON_SECTION_HEADER
*Section
;
579 Section
= (EFI_COMMON_SECTION_HEADER
*) (DxeIplFileHeader
+ 1);
581 while ((Section
->Type
!= EFI_SECTION_PE32
) && (Section
->Type
!= EFI_SECTION_TE
)) {
582 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
583 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
584 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
588 // Relocate DxeIpl into memory by using loadfile service
590 Status
= PeiLoadx64File (
591 PeiEfiPeiPeCoffLoader
,
592 (VOID
*) (Section
+ 1),
599 if (Status
== EFI_SUCCESS
) {
601 // Install PeiInMemory to indicate the Dxeipl is shadowed
603 Status
= PeiServicesInstallPpi (&mPpiPeiInMemory
);
605 if (EFI_ERROR (Status
)) {
609 Status
= ((EFI_PEIM_ENTRY_POINT
) (UINTN
) DxeIplEntryPoint
) (DxeIplFileHeader
, GetPeiServicesTablePointer());
618 IN EFI_PEI_FV_FILE_LOADER_PPI
*This
,
619 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
620 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
621 OUT UINT64
*ImageSize
,
622 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
628 Given a pointer to an FFS file containing a PE32 image, get the
629 information on the PE32 image, and then "load" it so that it
634 This - pointer to our file loader protocol
635 FfsHeader - pointer to the FFS file header of the FFS file that
636 contains the PE32 image we want to load
637 ImageAddress - returned address where the PE32 image is loaded
638 ImageSize - returned size of the loaded PE32 image
639 EntryPoint - entry point to the loaded PE32 image
643 EFI_SUCCESS - The FFS file was successfully loaded.
644 EFI_ERROR - Unable to load the FFS file.
648 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
653 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
656 // Preprocess the FFS file to get a pointer to the PE32 information
657 // in the enclosed PE32 image.
659 Status
= PeiProcessFile (
665 if (EFI_ERROR (Status
)) {
669 // Load the PE image from the FFS file
671 Status
= PeiLoadx64File (
672 PeiEfiPeiPeCoffLoader
,
685 IN UINT16 SectionType
,
686 IN OUT EFI_FFS_FILE_HEADER
**RealFfsFileHeader
,
695 SectionType - The type of section in the FFS file to process.
697 FfsFileHeader - Pointer to the FFS file to process, looking for the
698 specified SectionType
700 Pe32Data - returned pointer to the start of the PE32 image found
705 EFI_SUCCESS - found the PE32 section in the FFS file
711 DECOMPRESS_LIBRARY
*DecompressLibrary
;
713 UINT8
*ScratchBuffer
;
714 UINT32 DstBufferSize
;
715 UINT32 ScratchBufferSize
;
716 EFI_COMMON_SECTION_HEADER
*CmpSection
;
717 UINTN CmpSectionLength
;
718 UINTN OccupiedCmpSectionLength
;
721 EFI_COMMON_SECTION_HEADER
*Section
;
723 UINTN OccupiedSectionLength
;
725 EFI_GUID_DEFINED_SECTION
*GuidedSectionHeader
;
726 UINT32 AuthenticationStatus
;
727 EFI_PEI_SECTION_EXTRACTION_PPI
*SectionExtract
;
730 EFI_PEI_SECURITY_PPI
*Security
;
731 BOOLEAN StartCrisisRecovery
;
733 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
734 EFI_COMPRESSION_SECTION
*CompressionSection
;
735 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
737 FfsFileHeader
= *RealFfsFileHeader
;
739 Status
= PeiServicesFfsFindSectionData (
740 EFI_SECTION_COMPRESSION
,
746 // Upon finding a DXE Core file, see if there is first a compression section
748 if (!EFI_ERROR (Status
)) {
750 // Yes, there is a compression section, so extract the contents
751 // Decompress the image here
753 Section
= (EFI_COMMON_SECTION_HEADER
*) (UINTN
) (VOID
*) ((UINT8
*) (FfsFileHeader
) + (UINTN
) sizeof (EFI_FFS_FILE_HEADER
));
756 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
757 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
760 // Was the DXE Core file encapsulated in a GUID'd section?
762 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
764 // Locate the GUID'd Section Extractor
766 GuidedSectionHeader
= (VOID
*) (Section
+ 1);
769 // This following code constitutes the addition of the security model
773 // Set a default authenticatino state
775 AuthenticationStatus
= 0;
777 Status
= PeiServicesLocatePpi (
778 &gEfiPeiSectionExtractionPpiGuid
,
781 (VOID
**)&SectionExtract
784 if (EFI_ERROR (Status
)) {
788 // Verify Authentication State
790 CopyMem (&TempGuid
, Section
+ 1, sizeof (EFI_GUID
));
792 Status
= SectionExtract
->PeiGetSection (
793 GetPeiServicesTablePointer(),
795 (EFI_SECTION_TYPE
*) &SectionType
,
800 &AuthenticationStatus
803 if (EFI_ERROR (Status
)) {
807 // If not ask the Security PPI, if exists, for disposition
810 Status
= PeiServicesLocatePpi (
811 &gEfiPeiSecurityPpiGuid
,
816 if (EFI_ERROR (Status
)) {
820 Status
= Security
->AuthenticationState (
821 GetPeiServicesTablePointer(),
822 (struct _EFI_PEI_SECURITY_PPI
*) Security
,
823 AuthenticationStatus
,
828 if (EFI_ERROR (Status
)) {
832 // If there is a security violation, report to caller and have
833 // the upper-level logic possible engender a crisis recovery
835 if (StartCrisisRecovery
) {
836 return EFI_SECURITY_VIOLATION
;
840 if (Section
->Type
== EFI_SECTION_PE32
) {
842 // This is what we want
844 *Pe32Data
= (VOID
*) (Section
+ 1);
846 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
848 // This is a compression set, expand it
850 CompressionSection
= (EFI_COMPRESSION_SECTION
*) Section
;
852 switch (CompressionSection
->CompressionType
) {
853 case EFI_STANDARD_COMPRESSION
:
854 DecompressLibrary
= &gTianoDecompress
;
857 case EFI_CUSTOMIZED_COMPRESSION
:
859 // Load user customized compression protocol.
861 DecompressLibrary
= &gCustomDecompress
;
864 case EFI_NOT_COMPRESSED
:
867 // Need to support not compressed file
869 ASSERT_EFI_ERROR (Status
);
870 return EFI_NOT_FOUND
;
873 Status
= DecompressLibrary
->GetInfo (
874 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
875 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
879 if (EFI_ERROR (Status
)) {
883 return EFI_NOT_FOUND
;
887 // Allocate scratch buffer
889 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
890 if (ScratchBuffer
== NULL
) {
891 return EFI_OUT_OF_RESOURCES
;
895 // Allocate destination buffer
897 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
898 if (DstBuffer
== NULL
) {
899 return EFI_OUT_OF_RESOURCES
;
903 // Call decompress function
905 Status
= DecompressLibrary
->Decompress (
906 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
911 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) DstBuffer
;
912 if (CmpSection
->Type
== EFI_SECTION_RAW
) {
914 // Skip the section header and
915 // adjust the pointer alignment to 16
917 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (DstBuffer
+ 16);
919 if (FvHeader
->Signature
== EFI_FVH_SIGNATURE
) {
920 FfsFileHeader
= NULL
;
921 BuildFvHob ((EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
, FvHeader
->FvLength
);
922 Status
= PeiServicesFfsFindNextFile (
923 EFI_FV_FILETYPE_DXE_CORE
,
928 if (EFI_ERROR (Status
)) {
929 return EFI_NOT_FOUND
;
933 // Reture the FfsHeader that contain Pe32Data.
935 *RealFfsFileHeader
= FfsFileHeader
;
936 return PeiProcessFile (SectionType
, RealFfsFileHeader
, Pe32Data
);
940 // Decompress successfully.
941 // Loop the decompressed data searching for expected section.
943 CmpFileData
= (VOID
*) DstBuffer
;
944 CmpFileSize
= DstBufferSize
;
946 CmpSectionLength
= *(UINT32
*) (CmpSection
->Size
) & 0x00ffffff;
947 if (CmpSection
->Type
== EFI_SECTION_PE32
) {
949 // This is what we want
951 *Pe32Data
= (VOID
*) (CmpSection
+ 1);
955 OccupiedCmpSectionLength
= GetOccupiedSize (CmpSectionLength
, 4);
956 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) CmpSection
+ OccupiedCmpSectionLength
);
957 } while (CmpSection
->Type
!= 0 && (UINTN
) ((UINT8
*) CmpSection
- (UINT8
*) CmpFileData
) < CmpFileSize
);
960 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
961 FileSize
= FfsFileHeader
->Size
[0] & 0xFF;
962 FileSize
+= (FfsFileHeader
->Size
[1] << 8) & 0xFF00;
963 FileSize
+= (FfsFileHeader
->Size
[2] << 16) & 0xFF0000;
964 FileSize
&= 0x00FFFFFF;
965 } while (Section
->Type
!= 0 && (UINTN
) ((UINT8
*) Section
- (UINT8
*) FfsFileHeader
) < FileSize
);
968 // End of the decompression activity
972 Status
= PeiServicesFfsFindSectionData (
978 if (EFI_ERROR (Status
)) {
979 Status
= PeiServicesFfsFindSectionData (
984 if (EFI_ERROR (Status
)) {
990 *Pe32Data
= SectionData
;