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
;
30 // Module Globals used in the DXE to PEI handoff
31 // These must be module globals, so the stack can be switched
33 static EFI_DXE_IPL_PPI mDxeIplPpi
= {
37 static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi
= {
41 static EFI_PEI_PPI_DESCRIPTOR mPpiLoadFile
= {
42 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
43 &gEfiPeiFvFileLoaderPpiGuid
,
47 static EFI_PEI_PPI_DESCRIPTOR mPpiList
= {
48 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
53 static EFI_PEI_PPI_DESCRIPTOR mPpiPeiInMemory
= {
54 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
59 static EFI_PEI_PPI_DESCRIPTOR mPpiSignal
= {
60 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
61 &gEfiEndOfPeiSignalPpiGuid
,
65 DECOMPRESS_LIBRARY gEfiDecompress
= {
66 UefiDecompressGetInfo
,
70 DECOMPRESS_LIBRARY gTianoDecompress
= {
71 TianoDecompressGetInfo
,
75 DECOMPRESS_LIBRARY gCustomDecompress
= {
76 CustomDecompressGetInfo
,
89 OccupiedSize
= ActualSize
;
90 while ((OccupiedSize
& (Alignment
- 1)) != 0) {
99 PeimInitializeDxeIpl (
100 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
101 IN EFI_PEI_SERVICES
**PeiServices
107 Initializes the Dxe Ipl PPI
111 FfsHeader - Pointer to FFS file header
112 PeiServices - General purpose services available to every PEIM.
121 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
122 EFI_BOOT_MODE BootMode
;
124 Status
= PeiServicesGetBootMode (&BootMode
);
126 ASSERT_EFI_ERROR (Status
);
128 Status
= PeiServicesLocatePpi (
135 if (EFI_ERROR (Status
) && (BootMode
!= BOOT_ON_S3_RESUME
)) {
137 // The DxeIpl has not yet been shadowed
139 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
142 // Shadow DxeIpl and then re-run its entry point
144 Status
= ShadowDxeIpl (FfsHeader
, PeiEfiPeiPeCoffLoader
);
145 if (EFI_ERROR (Status
)) {
150 if (BootMode
!= BOOT_ON_S3_RESUME
) {
152 // The DxeIpl has been shadowed
157 // Install LoadFile PPI
159 Status
= PeiServicesInstallPpi (&mPpiLoadFile
);
161 if (EFI_ERROR (Status
)) {
166 // Install DxeIpl PPI
168 PeiServicesInstallPpi (&mPpiList
);
170 if (EFI_ERROR (Status
)) {
182 IN EFI_DXE_IPL_PPI
*This
,
183 IN EFI_PEI_SERVICES
**PeiServices
,
184 IN EFI_PEI_HOB_POINTERS HobList
190 Main entry point to last PEIM
194 This - Entry point for DXE IPL PPI
195 PeiServices - General purpose services available to every PEIM.
196 HobList - Address to the Pei HOB list
200 EFI_SUCCESS - DEX core was successfully loaded.
201 EFI_OUT_OF_RESOURCES - There are not enough resources to load DXE core.
206 EFI_PHYSICAL_ADDRESS TopOfStack
;
207 EFI_PHYSICAL_ADDRESS BaseOfStack
;
208 EFI_PHYSICAL_ADDRESS BspStore
;
209 EFI_GUID DxeCoreFileName
;
210 VOID
*DxeCorePe32Data
;
211 EFI_PHYSICAL_ADDRESS DxeCoreAddress
;
213 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint
;
214 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
215 EFI_BOOT_MODE BootMode
;
216 EFI_PEI_RECOVERY_MODULE_PPI
*PeiRecovery
;
217 EFI_PEI_S3_RESUME_PPI
*S3Resume
;
218 EFI_PHYSICAL_ADDRESS PageTables
;
223 Status
= EFI_SUCCESS
;
226 // if in S3 Resume, restore configure
228 Status
= PeiServicesGetBootMode (&BootMode
);
230 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_ON_S3_RESUME
)) {
231 Status
= PeiServicesLocatePpi (
232 &gEfiPeiS3ResumePpiGuid
,
238 ASSERT_EFI_ERROR (Status
);
240 Status
= S3Resume
->S3RestoreConfig (PeiServices
);
242 ASSERT_EFI_ERROR (Status
);
245 Status
= EFI_SUCCESS
;
248 // Install the PEI Protocols that are shared between PEI and DXE
250 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderX64Protocol ();
251 ASSERT (PeiEfiPeiPeCoffLoader
!= NULL
);
254 // Allocate 128KB for the Stack
256 PeiServicesAllocatePages (EfiBootServicesData
, EFI_SIZE_TO_PAGES (STACK_SIZE
), &BaseOfStack
);
257 ASSERT (BaseOfStack
!= 0);
260 // Compute the top of the stack we were allocated. Pre-allocate a 32 bytes
261 // for safety (PpisNeededByDxe and DxeCore).
263 TopOfStack
= BaseOfStack
+ EFI_SIZE_TO_PAGES (STACK_SIZE
) * EFI_PAGE_SIZE
- 32;
266 // Add architecture-specifc HOBs (including the BspStore HOB)
268 Status
= CreateArchSpecificHobs (&BspStore
);
269 ASSERT_EFI_ERROR (Status
);
272 // See if we are in crisis recovery
274 Status
= PeiServicesGetBootMode (&BootMode
);
275 if (!EFI_ERROR (Status
) && (BootMode
== BOOT_IN_RECOVERY_MODE
)) {
276 Status
= PeiServicesLocatePpi (
277 &gEfiPeiRecoveryModulePpiGuid
,
280 (VOID
**)&PeiRecovery
283 ASSERT_EFI_ERROR (Status
);
284 Status
= PeiRecovery
->LoadRecoveryCapsule (PeiServices
, PeiRecovery
);
285 ASSERT_EFI_ERROR (Status
);
289 // Find the DXE Core in a Firmware Volume
291 Status
= PeiFindFile (
292 EFI_FV_FILETYPE_DXE_CORE
,
297 ASSERT_EFI_ERROR (Status
);
300 // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA \
301 // memory, it may be corrupted when copying FV to high-end memory
305 // Limit to 36 bits of addressing for debug. Should get it from CPU
307 PageTables
= CreateIdentityMappingPageTables (36);
311 // Load the DXE Core from a Firmware Volume
313 Status
= PeiLoadx64File (
314 PeiEfiPeiPeCoffLoader
,
321 ASSERT_EFI_ERROR (Status
);
324 // Transfer control to the DXE Core
325 // The handoff state is simply a pointer to the HOB list
328 Status
= PeiServicesInstallPpi (&mPpiSignal
);
329 ASSERT_EFI_ERROR (Status
);
333 // Add HOB for the DXE Core
343 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
347 EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
350 DEBUG ((EFI_D_INFO
, "DXE Core Entry\n"));
352 // Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
353 // Call x64 drivers passing in single argument, a pointer to the HOBs.
357 (EFI_PHYSICAL_ADDRESS
)(UINTN
)(HobList
.Raw
),
364 // If we get here, then the DXE Core returned. This is an error
366 ASSERT_EFI_ERROR (Status
);
368 return EFI_OUT_OF_RESOURCES
;
374 IN UINT16 SectionType
,
375 OUT EFI_GUID
*FileName
,
382 Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
383 described in the HOB list. Able to search in a compression set in a FFS file.
384 But only one level of compression is supported, that is, not able to search
385 in a compression set that is within another compression set.
389 Type - The Type of file to retrieve
391 SectionType - The type of section to retrieve from a file
393 FileName - The name of the file found in the Firmware Volume
395 Pe32Data - Pointer to the beginning of the PE/COFF file found in the Firmware Volume
399 EFI_SUCCESS - The file was found, and the name is returned in FileName, and a pointer to
400 the PE/COFF image is returned in Pe32Data
402 EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List
406 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
407 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
410 EFI_PEI_HOB_POINTERS Hob
;
414 FfsFileHeader
= NULL
;
418 // Foreach Firmware Volume, look for a specified type
419 // of file and break out when one is found
421 Hob
.Raw
= GetHobList ();
422 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
)) != NULL
) {
423 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) (Hob
.FirmwareVolume
->BaseAddress
);
424 Status
= PeiServicesFfsFindNextFile (
429 if (!EFI_ERROR (Status
)) {
430 Status
= PeiProcessFile (
435 CopyMem (FileName
, &FfsFileHeader
->Name
, sizeof (EFI_GUID
));
438 Hob
.Raw
= GET_NEXT_HOB (Hob
);
440 return EFI_NOT_FOUND
;
445 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
,
447 IN EFI_MEMORY_TYPE MemoryType
,
448 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
449 OUT UINT64
*ImageSize
,
450 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
456 Loads and relocates a PE/COFF image into memory.
460 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
462 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
464 ImageAddress - The base address of the relocated PE/COFF image
466 ImageSize - The size of the relocated PE/COFF image
468 EntryPoint - The entry point of the relocated PE/COFF image
472 EFI_SUCCESS - The file was loaded and relocated
473 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
478 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
479 EFI_PHYSICAL_ADDRESS MemoryBuffer
;
481 ZeroMem (&ImageContext
, sizeof (ImageContext
));
482 ImageContext
.Handle
= Pe32Data
;
483 Status
= GetImageReadFunction (&ImageContext
);
485 ASSERT_EFI_ERROR (Status
);
487 Status
= PeiEfiPeiPeCoffLoader
->GetImageInfo (PeiEfiPeiPeCoffLoader
, &ImageContext
);
488 if (EFI_ERROR (Status
)) {
492 // Allocate Memory for the image
495 // Allocate Memory for the image
497 PeiServicesAllocatePages (MemoryType
, EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
), &MemoryBuffer
);
498 ImageContext
.ImageAddress
= MemoryBuffer
;
499 ASSERT (ImageContext
.ImageAddress
!= 0);
502 // Load the image to our new buffer
505 Status
= PeiEfiPeiPeCoffLoader
->LoadImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
506 if (EFI_ERROR (Status
)) {
511 // Relocate the image in our new buffer
513 Status
= PeiEfiPeiPeCoffLoader
->RelocateImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
514 if (EFI_ERROR (Status
)) {
519 // Flush the instruction cache so the image data is written before we execute it
521 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
523 *ImageAddress
= ImageContext
.ImageAddress
;
524 *ImageSize
= ImageContext
.ImageSize
;
525 *EntryPoint
= ImageContext
.EntryPoint
;
532 IN EFI_FFS_FILE_HEADER
*DxeIplFileHeader
,
533 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
539 Shadow the DXE IPL to a different memory location. This occurs after permanent
540 memory has been discovered.
544 DxeIplFileHeader - Pointer to the FFS file header of the DXE IPL driver
546 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
550 EFI_SUCCESS - DXE IPL was successfully shadowed to a different memory location.
552 EFI_ ERROR - The shadow was unsuccessful.
558 UINTN OccupiedSectionLength
;
559 EFI_PHYSICAL_ADDRESS DxeIplAddress
;
561 EFI_PHYSICAL_ADDRESS DxeIplEntryPoint
;
563 EFI_COMMON_SECTION_HEADER
*Section
;
565 Section
= (EFI_COMMON_SECTION_HEADER
*) (DxeIplFileHeader
+ 1);
567 while ((Section
->Type
!= EFI_SECTION_PE32
) && (Section
->Type
!= EFI_SECTION_TE
)) {
568 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
569 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
570 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
574 // Relocate DxeIpl into memory by using loadfile service
576 Status
= PeiLoadx64File (
577 PeiEfiPeiPeCoffLoader
,
578 (VOID
*) (Section
+ 1),
585 if (Status
== EFI_SUCCESS
) {
587 // Install PeiInMemory to indicate the Dxeipl is shadowed
589 Status
= PeiServicesInstallPpi (&mPpiPeiInMemory
);
591 if (EFI_ERROR (Status
)) {
595 Status
= ((EFI_PEIM_ENTRY_POINT
) (UINTN
) DxeIplEntryPoint
) (DxeIplFileHeader
, GetPeiServicesTablePointer());
604 IN EFI_PEI_FV_FILE_LOADER_PPI
*This
,
605 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
606 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
607 OUT UINT64
*ImageSize
,
608 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
614 Given a pointer to an FFS file containing a PE32 image, get the
615 information on the PE32 image, and then "load" it so that it
620 This - pointer to our file loader protocol
621 FfsHeader - pointer to the FFS file header of the FFS file that
622 contains the PE32 image we want to load
623 ImageAddress - returned address where the PE32 image is loaded
624 ImageSize - returned size of the loaded PE32 image
625 EntryPoint - entry point to the loaded PE32 image
629 EFI_SUCCESS - The FFS file was successfully loaded.
630 EFI_ERROR - Unable to load the FFS file.
634 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
639 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
642 // Preprocess the FFS file to get a pointer to the PE32 information
643 // in the enclosed PE32 image.
645 Status
= PeiProcessFile (
651 if (EFI_ERROR (Status
)) {
655 // Load the PE image from the FFS file
657 Status
= PeiLoadx64File (
658 PeiEfiPeiPeCoffLoader
,
671 IN UINT16 SectionType
,
672 IN OUT EFI_FFS_FILE_HEADER
**RealFfsFileHeader
,
681 SectionType - The type of section in the FFS file to process.
683 FfsFileHeader - Pointer to the FFS file to process, looking for the
684 specified SectionType
686 Pe32Data - returned pointer to the start of the PE32 image found
691 EFI_SUCCESS - found the PE32 section in the FFS file
697 DECOMPRESS_LIBRARY
*DecompressLibrary
;
699 UINT8
*ScratchBuffer
;
700 UINT32 DstBufferSize
;
701 UINT32 ScratchBufferSize
;
702 EFI_COMMON_SECTION_HEADER
*CmpSection
;
703 UINTN CmpSectionLength
;
704 UINTN OccupiedCmpSectionLength
;
707 EFI_COMMON_SECTION_HEADER
*Section
;
709 UINTN OccupiedSectionLength
;
711 EFI_GUID_DEFINED_SECTION
*GuidedSectionHeader
;
712 UINT32 AuthenticationStatus
;
713 EFI_PEI_SECTION_EXTRACTION_PPI
*SectionExtract
;
716 EFI_PEI_SECURITY_PPI
*Security
;
717 BOOLEAN StartCrisisRecovery
;
719 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
720 EFI_COMPRESSION_SECTION
*CompressionSection
;
721 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
723 FfsFileHeader
= *RealFfsFileHeader
;
725 Status
= PeiServicesFfsFindSectionData (
726 EFI_SECTION_COMPRESSION
,
732 // Upon finding a DXE Core file, see if there is first a compression section
734 if (!EFI_ERROR (Status
)) {
736 // Yes, there is a compression section, so extract the contents
737 // Decompress the image here
739 Section
= (EFI_COMMON_SECTION_HEADER
*) (UINTN
) (VOID
*) ((UINT8
*) (FfsFileHeader
) + (UINTN
) sizeof (EFI_FFS_FILE_HEADER
));
742 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
743 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
746 // Was the DXE Core file encapsulated in a GUID'd section?
748 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
750 // Locate the GUID'd Section Extractor
752 GuidedSectionHeader
= (VOID
*) (Section
+ 1);
755 // This following code constitutes the addition of the security model
759 // Set a default authenticatino state
761 AuthenticationStatus
= 0;
763 Status
= PeiServicesLocatePpi (
764 &gEfiPeiSectionExtractionPpiGuid
,
767 (VOID
**)&SectionExtract
770 if (EFI_ERROR (Status
)) {
774 // Verify Authentication State
776 CopyMem (&TempGuid
, Section
+ 1, sizeof (EFI_GUID
));
778 Status
= SectionExtract
->PeiGetSection (
779 GetPeiServicesTablePointer(),
781 (EFI_SECTION_TYPE
*) &SectionType
,
786 &AuthenticationStatus
789 if (EFI_ERROR (Status
)) {
793 // If not ask the Security PPI, if exists, for disposition
796 Status
= PeiServicesLocatePpi (
797 &gEfiPeiSecurityPpiGuid
,
802 if (EFI_ERROR (Status
)) {
806 Status
= Security
->AuthenticationState (
807 GetPeiServicesTablePointer(),
808 (struct _EFI_PEI_SECURITY_PPI
*) Security
,
809 AuthenticationStatus
,
814 if (EFI_ERROR (Status
)) {
818 // If there is a security violation, report to caller and have
819 // the upper-level logic possible engender a crisis recovery
821 if (StartCrisisRecovery
) {
822 return EFI_SECURITY_VIOLATION
;
826 if (Section
->Type
== EFI_SECTION_PE32
) {
828 // This is what we want
830 *Pe32Data
= (VOID
*) (Section
+ 1);
832 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
834 // This is a compression set, expand it
836 CompressionSection
= (EFI_COMPRESSION_SECTION
*) Section
;
838 switch (CompressionSection
->CompressionType
) {
839 case EFI_STANDARD_COMPRESSION
:
840 DecompressLibrary
= &gTianoDecompress
;
843 case EFI_CUSTOMIZED_COMPRESSION
:
845 // Load user customized compression protocol.
847 DecompressLibrary
= &gCustomDecompress
;
850 case EFI_NOT_COMPRESSED
:
853 // Need to support not compressed file
855 ASSERT_EFI_ERROR (Status
);
856 return EFI_NOT_FOUND
;
859 Status
= DecompressLibrary
->GetInfo (
860 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
861 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
865 if (EFI_ERROR (Status
)) {
869 return EFI_NOT_FOUND
;
873 // Allocate scratch buffer
875 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
876 if (ScratchBuffer
== NULL
) {
877 return EFI_OUT_OF_RESOURCES
;
881 // Allocate destination buffer
883 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
884 if (DstBuffer
== NULL
) {
885 return EFI_OUT_OF_RESOURCES
;
889 // Call decompress function
891 Status
= DecompressLibrary
->Decompress (
892 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
897 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) DstBuffer
;
898 if (CmpSection
->Type
== EFI_SECTION_RAW
) {
900 // Skip the section header and
901 // adjust the pointer alignment to 16
903 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (DstBuffer
+ 16);
905 if (FvHeader
->Signature
== EFI_FVH_SIGNATURE
) {
906 FfsFileHeader
= NULL
;
907 BuildFvHob ((EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
, FvHeader
->FvLength
);
908 Status
= PeiServicesFfsFindNextFile (
909 EFI_FV_FILETYPE_DXE_CORE
,
914 if (EFI_ERROR (Status
)) {
915 return EFI_NOT_FOUND
;
919 // Reture the FfsHeader that contain Pe32Data.
921 *RealFfsFileHeader
= FfsFileHeader
;
922 return PeiProcessFile (SectionType
, RealFfsFileHeader
, Pe32Data
);
926 // Decompress successfully.
927 // Loop the decompressed data searching for expected section.
929 CmpFileData
= (VOID
*) DstBuffer
;
930 CmpFileSize
= DstBufferSize
;
932 CmpSectionLength
= *(UINT32
*) (CmpSection
->Size
) & 0x00ffffff;
933 if (CmpSection
->Type
== EFI_SECTION_PE32
) {
935 // This is what we want
937 *Pe32Data
= (VOID
*) (CmpSection
+ 1);
941 OccupiedCmpSectionLength
= GetOccupiedSize (CmpSectionLength
, 4);
942 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) CmpSection
+ OccupiedCmpSectionLength
);
943 } while (CmpSection
->Type
!= 0 && (UINTN
) ((UINT8
*) CmpSection
- (UINT8
*) CmpFileData
) < CmpFileSize
);
946 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
947 FileSize
= FfsFileHeader
->Size
[0] & 0xFF;
948 FileSize
+= (FfsFileHeader
->Size
[1] << 8) & 0xFF00;
949 FileSize
+= (FfsFileHeader
->Size
[2] << 16) & 0xFF0000;
950 FileSize
&= 0x00FFFFFF;
951 } while (Section
->Type
!= 0 && (UINTN
) ((UINT8
*) Section
- (UINT8
*) FfsFileHeader
) < FileSize
);
954 // End of the decompression activity
958 Status
= PeiServicesFfsFindSectionData (
964 if (EFI_ERROR (Status
)) {
965 Status
= PeiServicesFfsFindSectionData (
970 if (EFI_ERROR (Status
)) {
976 *Pe32Data
= SectionData
;