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
= PeiCoreGetBootMode (&BootMode
);
124 ASSERT_EFI_ERROR (Status
);
126 Status
= PeiCoreLocatePpi (
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
= PeiCoreInstallPpi (&mPpiLoadFile
);
159 if (EFI_ERROR (Status
)) {
164 // Install DxeIpl PPI
166 PeiCoreInstallPpi (&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
= PeiCoreGetBootMode (&BootMode
);
228 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_ON_S3_RESUME
)) {
229 Status
= PeiCoreLocatePpi (
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
= PeiCoreGetBootMode (&BootMode
);
312 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_IN_RECOVERY_MODE
)) {
314 Status
= PeiCoreLocatePpi (
315 &gEfiPeiRecoveryModulePpiGuid
,
318 (VOID
**)&PeiRecovery
321 ASSERT_EFI_ERROR (Status
);
322 Status
= PeiRecovery
->LoadRecoveryCapsule (PeiServices
, PeiRecovery
);
323 ASSERT_EFI_ERROR (Status
);
326 // Now should have a HOB with the DXE core w/ the old HOB destroyed
331 // Find the EFI_FV_FILETYPE_RAW type compressed Firmware Volume file in FTW spare block
332 // The file found will be processed by PeiProcessFile: It will first be decompressed to
333 // a normal FV, then a corresponding FV type hob will be built which is provided for DXE
334 // core to find and dispatch drivers in this FV. Because PeiProcessFile typically checks
335 // for EFI_FV_FILETYPE_DXE_CORE type file, in this condition we need not check returned
338 Status
= PeiFindFile (
346 // Find the DXE Core in a Firmware Volume
348 Status
= PeiFindFile (
349 EFI_FV_FILETYPE_DXE_CORE
,
355 ASSERT_EFI_ERROR (Status
);
358 // Load the DXE Core from a Firmware Volume
360 Status
= PeiLoadFile (
361 PeiEfiPeiPeCoffLoader
,
368 ASSERT_EFI_ERROR (Status
);
371 // Transfer control to the DXE Core
372 // The handoff state is simply a pointer to the HOB list
374 // PERF_END (PeiServices, L"DxeIpl", NULL, 0);
376 Status
= PeiCoreInstallPpi (&mPpiSignal
);
378 ASSERT_EFI_ERROR (Status
);
381 // Add HOB for the DXE Core
391 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
395 EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
398 DEBUG ((EFI_D_INFO
, "DXE Core Entry\n"));
400 (SWITCH_STACK_ENTRY_POINT
)(UINTN
)DxeCoreEntryPoint
,
402 (VOID
*) (UINTN
) BspStore
,
407 // If we get here, then the DXE Core returned. This is an error
409 ASSERT_EFI_ERROR (Status
);
411 return EFI_OUT_OF_RESOURCES
;
417 IN UINT16 SectionType
,
418 OUT EFI_GUID
*FileName
,
425 Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
426 described in the HOB list. Able to search in a compression set in a FFS file.
427 But only one level of compression is supported, that is, not able to search
428 in a compression set that is within another compression set.
432 Type - The Type of file to retrieve
434 SectionType - The type of section to retrieve from a file
436 FileName - The name of the file found in the Firmware Volume
438 Pe32Data - Pointer to the beginning of the PE/COFF file found in the Firmware Volume
442 EFI_SUCCESS - The file was found, and the name is returned in FileName, and a pointer to
443 the PE/COFF image is returned in Pe32Data
445 EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List
449 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
450 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
453 EFI_PEI_HOB_POINTERS Hob
;
457 FfsFileHeader
= NULL
;
461 // Foreach Firmware Volume, look for a specified type
462 // of file and break out when one is found
464 Hob
.Raw
= GetHobList ();
465 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
)) != NULL
) {
466 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) (Hob
.FirmwareVolume
->BaseAddress
);
467 Status
= PeiCoreFfsFindNextFile (
472 if (!EFI_ERROR (Status
)) {
473 CopyMem (FileName
, &FfsFileHeader
->Name
, sizeof (EFI_GUID
));
474 Status
= PeiProcessFile (
481 Hob
.Raw
= GET_NEXT_HOB (Hob
);
483 return EFI_NOT_FOUND
;
488 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
,
490 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
491 OUT UINT64
*ImageSize
,
492 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
498 Loads and relocates a PE/COFF image into memory.
502 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
504 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
506 ImageAddress - The base address of the relocated PE/COFF image
508 ImageSize - The size of the relocated PE/COFF image
510 EntryPoint - The entry point of the relocated PE/COFF image
514 EFI_SUCCESS - The file was loaded and relocated
516 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
521 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
523 ZeroMem (&ImageContext
, sizeof (ImageContext
));
524 ImageContext
.Handle
= Pe32Data
;
525 Status
= GetImageReadFunction (&ImageContext
);
527 ASSERT_EFI_ERROR (Status
);
529 Status
= PeiEfiPeiPeCoffLoader
->GetImageInfo (PeiEfiPeiPeCoffLoader
, &ImageContext
);
530 if (EFI_ERROR (Status
)) {
534 // Allocate Memory for the image
536 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
));
537 ASSERT (ImageContext
.ImageAddress
!= 0);
540 // Load the image to our new buffer
542 Status
= PeiEfiPeiPeCoffLoader
->LoadImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
543 if (EFI_ERROR (Status
)) {
547 // Relocate the image in our new buffer
549 Status
= PeiEfiPeiPeCoffLoader
->RelocateImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
550 if (EFI_ERROR (Status
)) {
555 // Flush the instruction cache so the image data is written before we execute it
557 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
559 *ImageAddress
= ImageContext
.ImageAddress
;
560 *ImageSize
= ImageContext
.ImageSize
;
561 *EntryPoint
= ImageContext
.EntryPoint
;
568 IN EFI_FFS_FILE_HEADER
*DxeIplFileHeader
,
569 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
575 Shadow the DXE IPL to a different memory location. This occurs after permanent
576 memory has been discovered.
580 DxeIplFileHeader - Pointer to the FFS file header of the DXE IPL driver
582 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
586 EFI_SUCCESS - DXE IPL was successfully shadowed to a different memory location.
588 EFI_ ERROR - The shadow was unsuccessful.
594 UINTN OccupiedSectionLength
;
595 EFI_PHYSICAL_ADDRESS DxeIplAddress
;
597 EFI_PHYSICAL_ADDRESS DxeIplEntryPoint
;
599 EFI_COMMON_SECTION_HEADER
*Section
;
601 Section
= (EFI_COMMON_SECTION_HEADER
*) (DxeIplFileHeader
+ 1);
603 while ((Section
->Type
!= EFI_SECTION_PE32
) && (Section
->Type
!= EFI_SECTION_TE
)) {
604 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
605 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
606 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
609 // Relocate DxeIpl into memory by using loadfile service
611 Status
= PeiLoadFile (
612 PeiEfiPeiPeCoffLoader
,
613 (VOID
*) (Section
+ 1),
619 if (Status
== EFI_SUCCESS
) {
621 // Install PeiInMemory to indicate the Dxeipl is shadowed
623 Status
= PeiCoreInstallPpi (&mPpiPeiInMemory
);
625 if (EFI_ERROR (Status
)) {
629 Status
= ((EFI_PEIM_ENTRY_POINT
) (UINTN
) DxeIplEntryPoint
) (DxeIplFileHeader
, GetPeiServicesTablePointer());
638 IN EFI_PEI_FV_FILE_LOADER_PPI
*This
,
639 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
640 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
641 OUT UINT64
*ImageSize
,
642 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
648 Given a pointer to an FFS file containing a PE32 image, get the
649 information on the PE32 image, and then "load" it so that it
654 This - pointer to our file loader protocol
656 FfsHeader - pointer to the FFS file header of the FFS file that
657 contains the PE32 image we want to load
659 ImageAddress - returned address where the PE32 image is loaded
661 ImageSize - returned size of the loaded PE32 image
663 EntryPoint - entry point to the loaded PE32 image
667 EFI_SUCCESS - The FFS file was successfully loaded.
669 EFI_ERROR - Unable to load the FFS file.
673 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
678 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
681 // Preprocess the FFS file to get a pointer to the PE32 information
682 // in the enclosed PE32 image.
684 Status
= PeiProcessFile (
690 if (EFI_ERROR (Status
)) {
694 // Load the PE image from the FFS file
696 Status
= PeiLoadFile (
697 PeiEfiPeiPeCoffLoader
,
709 IN UINT16 SectionType
,
710 IN EFI_FFS_FILE_HEADER
*FfsFileHeader
,
719 SectionType - The type of section in the FFS file to process.
721 FfsFileHeader - Pointer to the FFS file to process, looking for the
722 specified SectionType
724 Pe32Data - returned pointer to the start of the PE32 image found
729 EFI_SUCCESS - found the PE32 section in the FFS file
735 DECOMPRESS_LIBRARY
*DecompressLibrary
;
737 UINT8
*ScratchBuffer
;
738 UINT32 DstBufferSize
;
739 UINT32 ScratchBufferSize
;
740 EFI_COMMON_SECTION_HEADER
*CmpSection
;
741 UINTN CmpSectionLength
;
742 UINTN OccupiedCmpSectionLength
;
745 EFI_COMMON_SECTION_HEADER
*Section
;
747 UINTN OccupiedSectionLength
;
749 EFI_GUID_DEFINED_SECTION
*GuidedSectionHeader
;
750 UINT32 AuthenticationStatus
;
751 EFI_PEI_SECTION_EXTRACTION_PPI
*SectionExtract
;
754 EFI_PEI_SECURITY_PPI
*Security
;
755 BOOLEAN StartCrisisRecovery
;
757 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
758 EFI_COMPRESSION_SECTION
*CompressionSection
;
760 Status
= PeiCoreFfsFindSectionData (
761 EFI_SECTION_COMPRESSION
,
767 // Upon finding a DXE Core file, see if there is first a compression section
769 if (!EFI_ERROR (Status
)) {
771 // Yes, there is a compression section, so extract the contents
772 // Decompress the image here
774 Section
= (EFI_COMMON_SECTION_HEADER
*) (UINTN
) (VOID
*) ((UINT8
*) (FfsFileHeader
) + (UINTN
) sizeof (EFI_FFS_FILE_HEADER
));
777 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
778 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
781 // Was the DXE Core file encapsulated in a GUID'd section?
783 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
785 // Locate the GUID'd Section Extractor
787 GuidedSectionHeader
= (VOID
*) (Section
+ 1);
790 // This following code constitutes the addition of the security model
794 // Set a default authenticatino state
796 AuthenticationStatus
= 0;
798 Status
= PeiCoreLocatePpi (
799 &gEfiPeiSectionExtractionPpiGuid
,
802 (VOID
**)&SectionExtract
805 if (EFI_ERROR (Status
)) {
809 // Verify Authentication State
811 CopyMem (&TempGuid
, Section
+ 1, sizeof (EFI_GUID
));
813 Status
= SectionExtract
->PeiGetSection (
814 GetPeiServicesTablePointer(),
816 (EFI_SECTION_TYPE
*) &SectionType
,
821 &AuthenticationStatus
824 if (EFI_ERROR (Status
)) {
828 // If not ask the Security PPI, if exists, for disposition
831 Status
= PeiCoreLocatePpi (
832 &gEfiPeiSecurityPpiGuid
,
837 if (EFI_ERROR (Status
)) {
841 Status
= Security
->AuthenticationState (
842 GetPeiServicesTablePointer(),
843 (struct _EFI_PEI_SECURITY_PPI
*) Security
,
844 AuthenticationStatus
,
849 if (EFI_ERROR (Status
)) {
853 // If there is a security violation, report to caller and have
854 // the upper-level logic possible engender a crisis recovery
856 if (StartCrisisRecovery
) {
857 return EFI_SECURITY_VIOLATION
;
861 if (Section
->Type
== EFI_SECTION_PE32
) {
863 // This is what we want
865 *Pe32Data
= (VOID
*) (Section
+ 1);
867 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
869 // This is a compression set, expand it
871 CompressionSection
= (EFI_COMPRESSION_SECTION
*) Section
;
873 switch (CompressionSection
->CompressionType
) {
874 case EFI_STANDARD_COMPRESSION
:
875 DecompressLibrary
= &gTianoDecompress
;
878 case EFI_CUSTOMIZED_COMPRESSION
:
880 // Load user customized compression protocol.
882 DecompressLibrary
= &gCustomDecompress
;
885 case EFI_NOT_COMPRESSED
:
888 // Need to support not compressed file
890 ASSERT_EFI_ERROR (Status
);
891 return EFI_NOT_FOUND
;
894 Status
= DecompressLibrary
->GetInfo (
895 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
896 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
900 if (EFI_ERROR (Status
)) {
904 return EFI_NOT_FOUND
;
908 // Allocate scratch buffer
910 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
911 if (ScratchBuffer
== NULL
) {
912 return EFI_OUT_OF_RESOURCES
;
916 // Allocate destination buffer
918 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
919 if (DstBuffer
== NULL
) {
920 return EFI_OUT_OF_RESOURCES
;
924 // Call decompress function
926 Status
= DecompressLibrary
->Decompress (
927 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
932 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) DstBuffer
;
933 if (CmpSection
->Type
== EFI_SECTION_RAW
) {
935 // Skip the section header and
936 // adjust the pointer alignment to 16
938 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (DstBuffer
+ 16);
940 if (FvHeader
->Signature
== EFI_FVH_SIGNATURE
) {
941 FfsFileHeader
= NULL
;
942 BuildFvHob ((EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
, FvHeader
->FvLength
);
943 Status
= PeiCoreFfsFindNextFile (
944 EFI_FV_FILETYPE_DXE_CORE
,
949 if (EFI_ERROR (Status
)) {
950 return EFI_NOT_FOUND
;
953 return PeiProcessFile (SectionType
, FfsFileHeader
, Pe32Data
);
957 // Decompress successfully.
958 // Loop the decompressed data searching for expected section.
960 CmpFileData
= (VOID
*) DstBuffer
;
961 CmpFileSize
= DstBufferSize
;
963 CmpSectionLength
= *(UINT32
*) (CmpSection
->Size
) & 0x00ffffff;
964 if (CmpSection
->Type
== EFI_SECTION_PE32
) {
966 // This is what we want
968 *Pe32Data
= (VOID
*) (CmpSection
+ 1);
972 OccupiedCmpSectionLength
= GetOccupiedSize (CmpSectionLength
, 4);
973 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) CmpSection
+ OccupiedCmpSectionLength
);
974 } while (CmpSection
->Type
!= 0 && (UINTN
) ((UINT8
*) CmpSection
- (UINT8
*) CmpFileData
) < CmpFileSize
);
977 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
978 FileSize
= FfsFileHeader
->Size
[0] & 0xFF;
979 FileSize
+= (FfsFileHeader
->Size
[1] << 8) & 0xFF00;
980 FileSize
+= (FfsFileHeader
->Size
[2] << 16) & 0xFF0000;
981 FileSize
&= 0x00FFFFFF;
982 } while (Section
->Type
!= 0 && (UINTN
) ((UINT8
*) Section
- (UINT8
*) FfsFileHeader
) < FileSize
);
985 // End of the decompression activity
989 Status
= PeiCoreFfsFindSectionData (
995 if (EFI_ERROR (Status
)) {
996 Status
= PeiCoreFfsFindSectionData (
1001 if (EFI_ERROR (Status
)) {
1007 *Pe32Data
= SectionData
;