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
= PeiCoreGetBootMode (&BootMode
);
135 ASSERT_EFI_ERROR (Status
);
137 Status
= PeiCoreLocatePpi (
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
= PeiCoreInstallPpi (&mPpiLoadFile
);
170 if (EFI_ERROR (Status
)) {
175 // Install DxeIpl PPI
177 PeiCoreInstallPpi (&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 VOID
*PpisNeededByDxePe32Data
;
224 EFI_PHYSICAL_ADDRESS PpisNeededByDxeAddress
;
225 UINT64 PpisNeededByDxeSize
;
226 EFI_PHYSICAL_ADDRESS PpisNeededByDxeEntryPoint
;
227 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
228 EFI_BOOT_MODE BootMode
;
229 EFI_PEI_RECOVERY_MODULE_PPI
*PeiRecovery
;
230 EFI_PEI_S3_RESUME_PPI
*S3Resume
;
231 EFI_PHYSICAL_ADDRESS PageTables
;
236 Status
= EFI_SUCCESS
;
239 // if in S3 Resume, restore configure
241 Status
= PeiCoreGetBootMode (&BootMode
);
243 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_ON_S3_RESUME
)) {
244 Status
= PeiCoreLocatePpi (
245 &gEfiPeiS3ResumePpiGuid
,
251 ASSERT_EFI_ERROR (Status
);
253 Status
= S3Resume
->S3RestoreConfig (PeiServices
);
255 ASSERT_EFI_ERROR (Status
);
258 Status
= EFI_SUCCESS
;
261 // Install the PEI Protocols that are shared between PEI and DXE
263 #ifdef EFI_NT_EMULATOR
264 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
265 ASSERT (PeiEfiPeiPeCoffLoader
!= NULL
);
267 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderX64Protocol ();
271 Status
= InstallEfiPeiPeCoffLoader64 (PeiServices
, &PeiEfiPeiPeCoffLoader
, NULL
);
272 ASSERT_EFI_ERROR (Status
);
275 // Allocate 128KB for the Stack
277 PeiCoreAllocatePages (EfiBootServicesData
, EFI_SIZE_TO_PAGES (STACK_SIZE
), &BaseOfStack
);
278 ASSERT (BaseOfStack
!= 0);
281 // Compute the top of the stack we were allocated. Pre-allocate a 32 bytes
282 // for safety (PpisNeededByDxe and DxeCore).
284 TopOfStack
= BaseOfStack
+ EFI_SIZE_TO_PAGES (STACK_SIZE
) * EFI_PAGE_SIZE
- 32;
287 // Add architecture-specifc HOBs (including the BspStore HOB)
289 Status
= CreateArchSpecificHobs (&BspStore
);
290 ASSERT_EFI_ERROR (Status
);
293 // See if we are in crisis recovery
295 Status
= PeiCoreGetBootMode (&BootMode
);
296 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_IN_RECOVERY_MODE
)) {
297 Status
= PeiCoreLocatePpi (
298 &gEfiPeiRecoveryModulePpiGuid
,
301 (VOID
**)&PeiRecovery
304 ASSERT_EFI_ERROR (Status
);
305 Status
= PeiRecovery
->LoadRecoveryCapsule (PeiServices
, PeiRecovery
);
306 ASSERT_EFI_ERROR (Status
);
310 // Find the DXE Core in a Firmware Volume
312 Status
= PeiFindFile (
313 EFI_FV_FILETYPE_DXE_CORE
,
318 ASSERT_EFI_ERROR (Status
);
321 // Find the PpisNeededByDxe in a Firmware Volume
323 Status
= PeiFindFile (
326 &mPpiNeededByDxeGuid
,
327 &PpisNeededByDxePe32Data
329 ASSERT_EFI_ERROR (Status
);
332 // Transfer control to the DXE Core
333 // The handoff state is simply a pointer to the HOB list
335 // PEI_PERF_END (PeiServices, L"DxeIpl", NULL, 0);
337 Status
= PeiCoreInstallPpi (&mPpiSignal
);
338 ASSERT_EFI_ERROR (Status
);
341 // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA \
342 // memory, it may be corrupted when copying FV to high-end memory
346 // Limit to 36 bits of addressing for debug. Should get it from CPU
348 PageTables
= CreateIdentityMappingPageTables (36);
351 // Load the PpiNeededByDxe from a Firmware Volume
353 Status
= PeiLoadx64File (
354 PeiEfiPeiPeCoffLoader
,
355 PpisNeededByDxePe32Data
,
357 &PpisNeededByDxeAddress
,
358 &PpisNeededByDxeSize
,
359 &PpisNeededByDxeEntryPoint
361 ASSERT_EFI_ERROR (Status
);
365 // Load the DXE Core from a Firmware Volume
367 Status
= PeiLoadx64File (
368 PeiEfiPeiPeCoffLoader
,
375 ASSERT_EFI_ERROR (Status
);
379 // Add HOB for the DXE Core
389 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
393 EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
396 DEBUG ((EFI_D_INFO
, "DXE Core Entry\n"));
398 // Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
399 // Call x64 drivers passing in single argument, a pointer to the HOBs.
403 (EFI_PHYSICAL_ADDRESS
)(UINTN
)(HobList
.Raw
),
405 PpisNeededByDxeEntryPoint
,
410 // If we get here, then the DXE Core returned. This is an error
412 ASSERT_EFI_ERROR (Status
);
414 return EFI_OUT_OF_RESOURCES
;
420 IN UINT16 SectionType
,
421 OUT EFI_GUID
*FileName
,
428 Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
429 described in the HOB list. Able to search in a compression set in a FFS file.
430 But only one level of compression is supported, that is, not able to search
431 in a compression set that is within another compression set.
435 Type - The Type of file to retrieve
437 SectionType - The type of section to retrieve from a file
439 FileName - The name of the file found in the Firmware Volume
441 Pe32Data - Pointer to the beginning of the PE/COFF file found in the Firmware Volume
445 EFI_SUCCESS - The file was found, and the name is returned in FileName, and a pointer to
446 the PE/COFF image is returned in Pe32Data
448 EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List
452 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
453 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
456 EFI_PEI_HOB_POINTERS Hob
;
460 FfsFileHeader
= NULL
;
464 // Foreach Firmware Volume, look for a specified type
465 // of file and break out when one is found
467 Hob
.Raw
= GetHobList ();
468 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
)) != NULL
) {
469 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) (Hob
.FirmwareVolume
->BaseAddress
);
470 Status
= PeiCoreFfsFindNextFile (
475 if (!EFI_ERROR (Status
)) {
476 CopyMem (FileName
, &FfsFileHeader
->Name
, sizeof (EFI_GUID
));
477 Status
= PeiProcessFile (
484 Hob
.Raw
= GET_NEXT_HOB (Hob
);
486 return EFI_NOT_FOUND
;
491 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
,
493 IN EFI_MEMORY_TYPE MemoryType
,
494 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
495 OUT UINT64
*ImageSize
,
496 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
502 Loads and relocates a PE/COFF image into memory.
506 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
508 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
510 ImageAddress - The base address of the relocated PE/COFF image
512 ImageSize - The size of the relocated PE/COFF image
514 EntryPoint - The entry point of the relocated PE/COFF image
518 EFI_SUCCESS - The file was loaded and relocated
519 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
524 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
525 EFI_PHYSICAL_ADDRESS MemoryBuffer
;
527 ZeroMem (&ImageContext
, sizeof (ImageContext
));
528 ImageContext
.Handle
= Pe32Data
;
529 Status
= GetImageReadFunction (&ImageContext
);
531 ASSERT_EFI_ERROR (Status
);
533 Status
= PeiEfiPeiPeCoffLoader
->GetImageInfo (PeiEfiPeiPeCoffLoader
, &ImageContext
);
534 if (EFI_ERROR (Status
)) {
538 // Allocate Memory for the image
541 // Allocate Memory for the image
543 PeiCoreAllocatePages (MemoryType
, EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
), &MemoryBuffer
);
544 ImageContext
.ImageAddress
= MemoryBuffer
;
545 ASSERT (ImageContext
.ImageAddress
!= 0);
548 // Load the image to our new buffer
551 Status
= PeiEfiPeiPeCoffLoader
->LoadImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
552 if (EFI_ERROR (Status
)) {
557 // Relocate the image in our new buffer
559 Status
= PeiEfiPeiPeCoffLoader
->RelocateImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
560 if (EFI_ERROR (Status
)) {
565 // Flush the instruction cache so the image data is written before we execute it
567 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
569 *ImageAddress
= ImageContext
.ImageAddress
;
570 *ImageSize
= ImageContext
.ImageSize
;
571 *EntryPoint
= ImageContext
.EntryPoint
;
578 IN EFI_FFS_FILE_HEADER
*DxeIplFileHeader
,
579 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
585 Shadow the DXE IPL to a different memory location. This occurs after permanent
586 memory has been discovered.
590 DxeIplFileHeader - Pointer to the FFS file header of the DXE IPL driver
592 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
596 EFI_SUCCESS - DXE IPL was successfully shadowed to a different memory location.
598 EFI_ ERROR - The shadow was unsuccessful.
604 UINTN OccupiedSectionLength
;
605 EFI_PHYSICAL_ADDRESS DxeIplAddress
;
607 EFI_PHYSICAL_ADDRESS DxeIplEntryPoint
;
609 EFI_COMMON_SECTION_HEADER
*Section
;
611 Section
= (EFI_COMMON_SECTION_HEADER
*) (DxeIplFileHeader
+ 1);
613 while ((Section
->Type
!= EFI_SECTION_PE32
) && (Section
->Type
!= EFI_SECTION_TE
)) {
614 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
615 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
616 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
620 // Relocate DxeIpl into memory by using loadfile service
622 Status
= PeiLoadx64File (
623 PeiEfiPeiPeCoffLoader
,
624 (VOID
*) (Section
+ 1),
631 if (Status
== EFI_SUCCESS
) {
633 // Install PeiInMemory to indicate the Dxeipl is shadowed
635 Status
= PeiCoreInstallPpi (&mPpiPeiInMemory
);
637 if (EFI_ERROR (Status
)) {
641 Status
= ((EFI_PEIM_ENTRY_POINT
) (UINTN
) DxeIplEntryPoint
) (DxeIplFileHeader
, GetPeiServicesTablePointer());
650 IN EFI_PEI_FV_FILE_LOADER_PPI
*This
,
651 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
652 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
653 OUT UINT64
*ImageSize
,
654 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
660 Given a pointer to an FFS file containing a PE32 image, get the
661 information on the PE32 image, and then "load" it so that it
666 This - pointer to our file loader protocol
667 FfsHeader - pointer to the FFS file header of the FFS file that
668 contains the PE32 image we want to load
669 ImageAddress - returned address where the PE32 image is loaded
670 ImageSize - returned size of the loaded PE32 image
671 EntryPoint - entry point to the loaded PE32 image
675 EFI_SUCCESS - The FFS file was successfully loaded.
676 EFI_ERROR - Unable to load the FFS file.
680 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
685 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
688 // Preprocess the FFS file to get a pointer to the PE32 information
689 // in the enclosed PE32 image.
691 Status
= PeiProcessFile (
697 if (EFI_ERROR (Status
)) {
701 // Load the PE image from the FFS file
703 Status
= PeiLoadx64File (
704 PeiEfiPeiPeCoffLoader
,
717 IN UINT16 SectionType
,
718 IN EFI_FFS_FILE_HEADER
*FfsFileHeader
,
727 SectionType - The type of section in the FFS file to process.
729 FfsFileHeader - Pointer to the FFS file to process, looking for the
730 specified SectionType
732 Pe32Data - returned pointer to the start of the PE32 image found
737 EFI_SUCCESS - found the PE32 section in the FFS file
743 DECOMPRESS_LIBRARY
*DecompressLibrary
;
745 UINT8
*ScratchBuffer
;
746 UINT32 DstBufferSize
;
747 UINT32 ScratchBufferSize
;
748 EFI_COMMON_SECTION_HEADER
*CmpSection
;
749 UINTN CmpSectionLength
;
750 UINTN OccupiedCmpSectionLength
;
753 EFI_COMMON_SECTION_HEADER
*Section
;
755 UINTN OccupiedSectionLength
;
757 EFI_GUID_DEFINED_SECTION
*GuidedSectionHeader
;
758 UINT32 AuthenticationStatus
;
759 EFI_PEI_SECTION_EXTRACTION_PPI
*SectionExtract
;
762 EFI_PEI_SECURITY_PPI
*Security
;
763 BOOLEAN StartCrisisRecovery
;
765 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
766 EFI_COMPRESSION_SECTION
*CompressionSection
;
768 Status
= PeiCoreFfsFindSectionData (
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
= PeiCoreLocatePpi (
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
= PeiCoreLocatePpi (
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
= PeiCoreFfsFindNextFile (
952 EFI_FV_FILETYPE_DXE_CORE
,
957 if (EFI_ERROR (Status
)) {
958 return EFI_NOT_FOUND
;
961 return PeiProcessFile (SectionType
, FfsFileHeader
, Pe32Data
);
965 // Decompress successfully.
966 // Loop the decompressed data searching for expected section.
968 CmpFileData
= (VOID
*) DstBuffer
;
969 CmpFileSize
= DstBufferSize
;
971 CmpSectionLength
= *(UINT32
*) (CmpSection
->Size
) & 0x00ffffff;
972 if (CmpSection
->Type
== EFI_SECTION_PE32
) {
974 // This is what we want
976 *Pe32Data
= (VOID
*) (CmpSection
+ 1);
980 OccupiedCmpSectionLength
= GetOccupiedSize (CmpSectionLength
, 4);
981 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) CmpSection
+ OccupiedCmpSectionLength
);
982 } while (CmpSection
->Type
!= 0 && (UINTN
) ((UINT8
*) CmpSection
- (UINT8
*) CmpFileData
) < CmpFileSize
);
985 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
986 FileSize
= FfsFileHeader
->Size
[0] & 0xFF;
987 FileSize
+= (FfsFileHeader
->Size
[1] << 8) & 0xFF00;
988 FileSize
+= (FfsFileHeader
->Size
[2] << 16) & 0xFF0000;
989 FileSize
&= 0x00FFFFFF;
990 } while (Section
->Type
!= 0 && (UINTN
) ((UINT8
*) Section
- (UINT8
*) FfsFileHeader
) < FileSize
);
993 // End of the decompression activity
997 Status
= PeiCoreFfsFindSectionData (
1003 if (EFI_ERROR (Status
)) {
1004 Status
= PeiCoreFfsFindSectionData (
1009 if (EFI_ERROR (Status
)) {
1015 *Pe32Data
= SectionData
;