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 if (EFI_ERROR (Status
)) {
286 DEBUG ((EFI_D_ERROR
, "Load Recovery Capsule Failed.(Status = %r)\n", Status
));
292 // Find the DXE Core in a Firmware Volume
294 Status
= PeiFindFile (
295 EFI_FV_FILETYPE_DXE_CORE
,
300 ASSERT_EFI_ERROR (Status
);
303 // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA \
304 // memory, it may be corrupted when copying FV to high-end memory
308 // Limit to 36 bits of addressing for debug. Should get it from CPU
310 PageTables
= CreateIdentityMappingPageTables (36);
314 // Load the DXE Core from a Firmware Volume
316 Status
= PeiLoadx64File (
317 PeiEfiPeiPeCoffLoader
,
324 ASSERT_EFI_ERROR (Status
);
327 // Transfer control to the DXE Core
328 // The handoff state is simply a pointer to the HOB list
331 Status
= PeiServicesInstallPpi (&mPpiSignal
);
332 ASSERT_EFI_ERROR (Status
);
336 // Add HOB for the DXE Core
346 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
350 EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
353 DEBUG ((EFI_D_INFO
, "DXE Core Entry\n"));
355 // Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
356 // Call x64 drivers passing in single argument, a pointer to the HOBs.
360 (EFI_PHYSICAL_ADDRESS
)(UINTN
)(HobList
.Raw
),
367 // If we get here, then the DXE Core returned. This is an error
368 // Dxe Core should not return.
373 return EFI_OUT_OF_RESOURCES
;
379 IN UINT16 SectionType
,
380 OUT EFI_GUID
*FileName
,
387 Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
388 described in the HOB list. Able to search in a compression set in a FFS file.
389 But only one level of compression is supported, that is, not able to search
390 in a compression set that is within another compression set.
394 Type - The Type of file to retrieve
396 SectionType - The type of section to retrieve from a file
398 FileName - The name of the file found in the Firmware Volume
400 Pe32Data - Pointer to the beginning of the PE/COFF file found in the Firmware Volume
404 EFI_SUCCESS - The file was found, and the name is returned in FileName, and a pointer to
405 the PE/COFF image is returned in Pe32Data
407 EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List
411 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
412 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
415 EFI_PEI_HOB_POINTERS Hob
;
419 FfsFileHeader
= NULL
;
423 // Foreach Firmware Volume, look for a specified type
424 // of file and break out when one is found
426 Hob
.Raw
= GetHobList ();
427 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV
, Hob
.Raw
)) != NULL
) {
428 FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) (Hob
.FirmwareVolume
->BaseAddress
);
429 Status
= PeiServicesFfsFindNextFile (
434 if (!EFI_ERROR (Status
)) {
435 Status
= PeiProcessFile (
440 CopyMem (FileName
, &FfsFileHeader
->Name
, sizeof (EFI_GUID
));
443 Hob
.Raw
= GET_NEXT_HOB (Hob
);
445 return EFI_NOT_FOUND
;
450 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
,
452 IN EFI_MEMORY_TYPE MemoryType
,
453 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
454 OUT UINT64
*ImageSize
,
455 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
461 Loads and relocates a PE/COFF image into memory.
465 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
467 Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
469 ImageAddress - The base address of the relocated PE/COFF image
471 ImageSize - The size of the relocated PE/COFF image
473 EntryPoint - The entry point of the relocated PE/COFF image
477 EFI_SUCCESS - The file was loaded and relocated
478 EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
483 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
484 EFI_PHYSICAL_ADDRESS MemoryBuffer
;
486 ZeroMem (&ImageContext
, sizeof (ImageContext
));
487 ImageContext
.Handle
= Pe32Data
;
488 Status
= GetImageReadFunction (&ImageContext
);
490 ASSERT_EFI_ERROR (Status
);
492 Status
= PeiEfiPeiPeCoffLoader
->GetImageInfo (PeiEfiPeiPeCoffLoader
, &ImageContext
);
493 if (EFI_ERROR (Status
)) {
497 // Allocate Memory for the image
500 // Allocate Memory for the image
502 PeiServicesAllocatePages (MemoryType
, EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
), &MemoryBuffer
);
503 ImageContext
.ImageAddress
= MemoryBuffer
;
504 ASSERT (ImageContext
.ImageAddress
!= 0);
507 // Load the image to our new buffer
510 Status
= PeiEfiPeiPeCoffLoader
->LoadImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
511 if (EFI_ERROR (Status
)) {
516 // Relocate the image in our new buffer
518 Status
= PeiEfiPeiPeCoffLoader
->RelocateImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
519 if (EFI_ERROR (Status
)) {
524 // Flush the instruction cache so the image data is written before we execute it
526 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
528 *ImageAddress
= ImageContext
.ImageAddress
;
529 *ImageSize
= ImageContext
.ImageSize
;
530 *EntryPoint
= ImageContext
.EntryPoint
;
537 IN EFI_FFS_FILE_HEADER
*DxeIplFileHeader
,
538 IN EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
544 Shadow the DXE IPL to a different memory location. This occurs after permanent
545 memory has been discovered.
549 DxeIplFileHeader - Pointer to the FFS file header of the DXE IPL driver
551 PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
555 EFI_SUCCESS - DXE IPL was successfully shadowed to a different memory location.
557 EFI_ ERROR - The shadow was unsuccessful.
563 UINTN OccupiedSectionLength
;
564 EFI_PHYSICAL_ADDRESS DxeIplAddress
;
566 EFI_PHYSICAL_ADDRESS DxeIplEntryPoint
;
568 EFI_COMMON_SECTION_HEADER
*Section
;
570 Section
= (EFI_COMMON_SECTION_HEADER
*) (DxeIplFileHeader
+ 1);
572 while ((Section
->Type
!= EFI_SECTION_PE32
) && (Section
->Type
!= EFI_SECTION_TE
)) {
573 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
574 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
575 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
579 // Relocate DxeIpl into memory by using loadfile service
581 Status
= PeiLoadx64File (
582 PeiEfiPeiPeCoffLoader
,
583 (VOID
*) (Section
+ 1),
590 if (Status
== EFI_SUCCESS
) {
592 // Install PeiInMemory to indicate the Dxeipl is shadowed
594 Status
= PeiServicesInstallPpi (&mPpiPeiInMemory
);
596 if (EFI_ERROR (Status
)) {
600 Status
= ((EFI_PEIM_ENTRY_POINT
) (UINTN
) DxeIplEntryPoint
) (DxeIplFileHeader
, GetPeiServicesTablePointer());
609 IN EFI_PEI_FV_FILE_LOADER_PPI
*This
,
610 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
611 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
612 OUT UINT64
*ImageSize
,
613 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
619 Given a pointer to an FFS file containing a PE32 image, get the
620 information on the PE32 image, and then "load" it so that it
625 This - pointer to our file loader protocol
626 FfsHeader - pointer to the FFS file header of the FFS file that
627 contains the PE32 image we want to load
628 ImageAddress - returned address where the PE32 image is loaded
629 ImageSize - returned size of the loaded PE32 image
630 EntryPoint - entry point to the loaded PE32 image
634 EFI_SUCCESS - The FFS file was successfully loaded.
635 EFI_ERROR - Unable to load the FFS file.
639 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
644 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
647 // Preprocess the FFS file to get a pointer to the PE32 information
648 // in the enclosed PE32 image.
650 Status
= PeiProcessFile (
656 if (EFI_ERROR (Status
)) {
660 // Load the PE image from the FFS file
662 Status
= PeiLoadx64File (
663 PeiEfiPeiPeCoffLoader
,
676 IN UINT16 SectionType
,
677 IN OUT EFI_FFS_FILE_HEADER
**RealFfsFileHeader
,
686 SectionType - The type of section in the FFS file to process.
688 FfsFileHeader - Pointer to the FFS file to process, looking for the
689 specified SectionType
691 Pe32Data - returned pointer to the start of the PE32 image found
696 EFI_SUCCESS - found the PE32 section in the FFS file
702 DECOMPRESS_LIBRARY
*DecompressLibrary
;
704 UINT8
*ScratchBuffer
;
705 UINT32 DstBufferSize
;
706 UINT32 ScratchBufferSize
;
707 EFI_COMMON_SECTION_HEADER
*CmpSection
;
708 UINTN CmpSectionLength
;
709 UINTN OccupiedCmpSectionLength
;
712 EFI_COMMON_SECTION_HEADER
*Section
;
714 UINTN OccupiedSectionLength
;
716 EFI_GUID_DEFINED_SECTION
*GuidedSectionHeader
;
717 UINT32 AuthenticationStatus
;
718 EFI_PEI_SECTION_EXTRACTION_PPI
*SectionExtract
;
721 EFI_PEI_SECURITY_PPI
*Security
;
722 BOOLEAN StartCrisisRecovery
;
724 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
725 EFI_COMPRESSION_SECTION
*CompressionSection
;
726 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
728 FfsFileHeader
= *RealFfsFileHeader
;
730 Status
= PeiServicesFfsFindSectionData (
731 EFI_SECTION_COMPRESSION
,
737 // Upon finding a DXE Core file, see if there is first a compression section
739 if (!EFI_ERROR (Status
)) {
741 // Yes, there is a compression section, so extract the contents
742 // Decompress the image here
744 Section
= (EFI_COMMON_SECTION_HEADER
*) (UINTN
) (VOID
*) ((UINT8
*) (FfsFileHeader
) + (UINTN
) sizeof (EFI_FFS_FILE_HEADER
));
747 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
748 OccupiedSectionLength
= GetOccupiedSize (SectionLength
, 4);
751 // Was the DXE Core file encapsulated in a GUID'd section?
753 if (Section
->Type
== EFI_SECTION_GUID_DEFINED
) {
755 // Locate the GUID'd Section Extractor
757 GuidedSectionHeader
= (VOID
*) (Section
+ 1);
760 // This following code constitutes the addition of the security model
764 // Set a default authenticatino state
766 AuthenticationStatus
= 0;
768 Status
= PeiServicesLocatePpi (
769 &gEfiPeiSectionExtractionPpiGuid
,
772 (VOID
**)&SectionExtract
775 if (EFI_ERROR (Status
)) {
779 // Verify Authentication State
781 CopyMem (&TempGuid
, Section
+ 1, sizeof (EFI_GUID
));
783 Status
= SectionExtract
->PeiGetSection (
784 GetPeiServicesTablePointer(),
786 (EFI_SECTION_TYPE
*) &SectionType
,
791 &AuthenticationStatus
794 if (EFI_ERROR (Status
)) {
798 // If not ask the Security PPI, if exists, for disposition
801 Status
= PeiServicesLocatePpi (
802 &gEfiPeiSecurityPpiGuid
,
807 if (EFI_ERROR (Status
)) {
811 Status
= Security
->AuthenticationState (
812 GetPeiServicesTablePointer(),
813 (struct _EFI_PEI_SECURITY_PPI
*) Security
,
814 AuthenticationStatus
,
819 if (EFI_ERROR (Status
)) {
823 // If there is a security violation, report to caller and have
824 // the upper-level logic possible engender a crisis recovery
826 if (StartCrisisRecovery
) {
827 return EFI_SECURITY_VIOLATION
;
831 if (Section
->Type
== EFI_SECTION_PE32
) {
833 // This is what we want
835 *Pe32Data
= (VOID
*) (Section
+ 1);
837 } else if (Section
->Type
== EFI_SECTION_COMPRESSION
) {
839 // This is a compression set, expand it
841 CompressionSection
= (EFI_COMPRESSION_SECTION
*) Section
;
843 switch (CompressionSection
->CompressionType
) {
844 case EFI_STANDARD_COMPRESSION
:
845 DecompressLibrary
= &gTianoDecompress
;
848 case EFI_CUSTOMIZED_COMPRESSION
:
850 // Load user customized compression protocol.
852 DecompressLibrary
= &gCustomDecompress
;
855 case EFI_NOT_COMPRESSED
:
858 // Need to support not compressed file
860 ASSERT_EFI_ERROR (Status
);
861 return EFI_NOT_FOUND
;
864 Status
= DecompressLibrary
->GetInfo (
865 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
866 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
870 if (EFI_ERROR (Status
)) {
874 return EFI_NOT_FOUND
;
878 // Allocate scratch buffer
880 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
881 if (ScratchBuffer
== NULL
) {
882 return EFI_OUT_OF_RESOURCES
;
886 // Allocate destination buffer
888 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
889 if (DstBuffer
== NULL
) {
890 return EFI_OUT_OF_RESOURCES
;
894 // Call decompress function
896 Status
= DecompressLibrary
->Decompress (
897 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
902 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) DstBuffer
;
903 if (CmpSection
->Type
== EFI_SECTION_RAW
) {
905 // Skip the section header and
906 // adjust the pointer alignment to 16
908 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (DstBuffer
+ 16);
910 if (FvHeader
->Signature
== EFI_FVH_SIGNATURE
) {
911 FfsFileHeader
= NULL
;
912 BuildFvHob ((EFI_PHYSICAL_ADDRESS
) (UINTN
) FvHeader
, FvHeader
->FvLength
);
913 Status
= PeiServicesFfsFindNextFile (
914 EFI_FV_FILETYPE_DXE_CORE
,
919 if (EFI_ERROR (Status
)) {
920 return EFI_NOT_FOUND
;
924 // Reture the FfsHeader that contain Pe32Data.
926 *RealFfsFileHeader
= FfsFileHeader
;
927 return PeiProcessFile (SectionType
, RealFfsFileHeader
, Pe32Data
);
931 // Decompress successfully.
932 // Loop the decompressed data searching for expected section.
934 CmpFileData
= (VOID
*) DstBuffer
;
935 CmpFileSize
= DstBufferSize
;
937 CmpSectionLength
= *(UINT32
*) (CmpSection
->Size
) & 0x00ffffff;
938 if (CmpSection
->Type
== EFI_SECTION_PE32
) {
940 // This is what we want
942 *Pe32Data
= (VOID
*) (CmpSection
+ 1);
946 OccupiedCmpSectionLength
= GetOccupiedSize (CmpSectionLength
, 4);
947 CmpSection
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) CmpSection
+ OccupiedCmpSectionLength
);
948 } while (CmpSection
->Type
!= 0 && (UINTN
) ((UINT8
*) CmpSection
- (UINT8
*) CmpFileData
) < CmpFileSize
);
951 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ OccupiedSectionLength
);
952 FileSize
= FfsFileHeader
->Size
[0] & 0xFF;
953 FileSize
+= (FfsFileHeader
->Size
[1] << 8) & 0xFF00;
954 FileSize
+= (FfsFileHeader
->Size
[2] << 16) & 0xFF0000;
955 FileSize
&= 0x00FFFFFF;
956 } while (Section
->Type
!= 0 && (UINTN
) ((UINT8
*) Section
- (UINT8
*) FfsFileHeader
) < FileSize
);
959 // End of the decompression activity
963 Status
= PeiServicesFfsFindSectionData (
969 if (EFI_ERROR (Status
)) {
970 Status
= PeiServicesFfsFindSectionData (
975 if (EFI_ERROR (Status
)) {
981 *Pe32Data
= SectionData
;