3 Responsibility of this module is to load the DXE Core from a Firmware Volume.
5 Copyright (c) 2006 - 2007 Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Ppi/GuidedSectionExtraction.h>
18 #include <FrameworkPei.h>
21 CustomDecompressExtractSection (
22 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*This
,
23 IN CONST VOID
*InputSection
,
24 OUT VOID
**OutputBuffer
,
25 OUT UINTN
*OutputSize
,
26 OUT UINT32
*AuthenticationStatus
33 IN CONST EFI_PEI_DECOMPRESS_PPI
*This
,
34 IN CONST EFI_COMPRESSION_SECTION
*InputSection
,
35 OUT VOID
**OutputBuffer
,
40 BOOLEAN gInMemory
= FALSE
;
43 // Module Globals used in the DXE to PEI handoff
44 // These must be module globals, so the stack can be switched
46 static EFI_DXE_IPL_PPI mDxeIplPpi
= {
50 STATIC EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomDecompressExtractiongPpi
= {
51 CustomDecompressExtractSection
54 STATIC EFI_PEI_DECOMPRESS_PPI mDecompressPpi
= {
58 static EFI_PEI_PPI_DESCRIPTOR mPpiList
[] = {
60 EFI_PEI_PPI_DESCRIPTOR_PPI
,
65 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
66 &gEfiPeiDecompressPpiGuid
,
71 static EFI_PEI_PPI_DESCRIPTOR mPpiSignal
= {
72 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
73 &gEfiEndOfPeiSignalPpiGuid
,
77 STATIC EFI_PEI_FIRMWARE_VOLUME_INFO_PPI mFvInfoPpiTemplate
= {
78 EFI_FIRMWARE_FILE_SYSTEM2_GUID
,
82 NULL
//ParentFileName;
86 Initializes the Dxe Ipl PPI
88 @param FfsHandle The handle of FFS file.
89 @param PeiServices General purpose services available to
95 PeimInitializeDxeIpl (
96 IN EFI_PEI_FILE_HANDLE FfsHandle
,
97 IN EFI_PEI_SERVICES
**PeiServices
101 EFI_BOOT_MODE BootMode
;
102 EFI_GUID
**DecompressGuidList
;
103 UINT32 DecompressMethodNumber
;
104 EFI_PEI_PPI_DESCRIPTOR
*GuidPpi
;
106 Status
= PeiServicesGetBootMode (&BootMode
);
107 ASSERT_EFI_ERROR (Status
);
109 if (BootMode
!= BOOT_ON_S3_RESUME
) {
110 Status
= PeiServicesRegisterForShadow (FfsHandle
);
111 if (Status
== EFI_SUCCESS
) {
115 // EFI_SUCESS means the first time call register for shadow
118 } else if (Status
== EFI_ALREADY_STARTED
) {
122 // Get custom decompress method guid list
124 DecompressGuidList
= NULL
;
125 DecompressMethodNumber
= 0;
126 Status
= CustomDecompressGetAlgorithms (DecompressGuidList
, &DecompressMethodNumber
);
127 if (Status
== EFI_OUT_OF_RESOURCES
) {
128 DecompressGuidList
= (EFI_GUID
**) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber
* sizeof (EFI_GUID
*)));
129 ASSERT (DecompressGuidList
!= NULL
);
130 Status
= CustomDecompressGetAlgorithms (DecompressGuidList
, &DecompressMethodNumber
);
132 ASSERT_EFI_ERROR(Status
);
135 // Install custom decompress extraction guid ppi
137 if (DecompressMethodNumber
> 0) {
139 GuidPpi
= (EFI_PEI_PPI_DESCRIPTOR
*) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber
* sizeof (EFI_PEI_PPI_DESCRIPTOR
)));
140 ASSERT (GuidPpi
!= NULL
);
141 while (DecompressMethodNumber
-- > 0) {
142 GuidPpi
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
143 GuidPpi
->Ppi
= &mCustomDecompressExtractiongPpi
;
144 GuidPpi
->Guid
= DecompressGuidList
[DecompressMethodNumber
];
145 Status
= PeiServicesInstallPpi (GuidPpi
++);
146 ASSERT_EFI_ERROR(Status
);
150 ASSERT_EFI_ERROR (FALSE
);
155 // Install FvFileLoader and DxeIpl PPIs.
157 Status
= PeiServicesInstallPpi (mPpiList
);
158 ASSERT_EFI_ERROR(Status
);
164 Main entry point to last PEIM
166 @param This Entry point for DXE IPL PPI
167 @param PeiServices General purpose services available to every PEIM.
168 @param HobList Address to the Pei HOB list
170 @return EFI_SUCCESS DXE core was successfully loaded.
171 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.
176 IN EFI_DXE_IPL_PPI
*This
,
177 IN EFI_PEI_SERVICES
**PeiServices
,
178 IN EFI_PEI_HOB_POINTERS HobList
182 EFI_GUID DxeCoreFileName
;
183 EFI_PHYSICAL_ADDRESS DxeCoreAddress
;
185 EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint
;
186 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
187 EFI_BOOT_MODE BootMode
;
188 EFI_PEI_RECOVERY_MODULE_PPI
*PeiRecovery
;
189 EFI_PEI_S3_RESUME_PPI
*S3Resume
;
190 EFI_PEI_FV_HANDLE VolumeHandle
;
191 EFI_PEI_FILE_HANDLE FileHandle
;
195 // if in S3 Resume, restore configure
197 Status
= PeiServicesGetBootMode (&BootMode
);
198 ASSERT_EFI_ERROR(Status
);
200 if (BootMode
== BOOT_ON_S3_RESUME
) {
201 Status
= PeiServicesLocatePpi (
202 &gEfiPeiS3ResumePpiGuid
,
207 ASSERT_EFI_ERROR (Status
);
209 Status
= S3Resume
->S3RestoreConfig (PeiServices
);
210 ASSERT_EFI_ERROR (Status
);
211 } else if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
213 Status
= PeiServicesLocatePpi (
214 &gEfiPeiRecoveryModulePpiGuid
,
217 (VOID
**)&PeiRecovery
219 ASSERT_EFI_ERROR (Status
);
221 Status
= PeiRecovery
->LoadRecoveryCapsule (PeiServices
, PeiRecovery
);
222 if (EFI_ERROR (Status
)) {
223 DEBUG ((EFI_D_ERROR
, "Load Recovery Capsule Failed.(Status = %r)\n", Status
));
228 // Now should have a HOB with the DXE core w/ the old HOB destroyed
233 // Install the PEI Protocols that are shared between PEI and DXE
235 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*) GetPeCoffLoaderProtocol ();
236 ASSERT (PeiEfiPeiPeCoffLoader
!= NULL
);
239 // If any FV contains an encapsulated FV extract that FV
241 DxeIplAddEncapsulatedFirmwareVolumes ();
244 // Look in all the FVs present in PEI and find the DXE Core
247 Status
= DxeIplFindFirmwareVolumeInstance (&Instance
, EFI_FV_FILETYPE_DXE_CORE
, &VolumeHandle
, &FileHandle
);
248 ASSERT_EFI_ERROR (Status
);
250 CopyMem(&DxeCoreFileName
, &(((EFI_FFS_FILE_HEADER
*)FileHandle
)->Name
), sizeof (EFI_GUID
));
253 // Load the DXE Core from a Firmware Volume
255 Status
= PeiLoadFile (
262 ASSERT_EFI_ERROR (Status
);
265 // Add HOB for the DXE Core
275 // Add HOB for the PE/COFF Loader Protocol
278 &gEfiPeiPeCoffLoaderGuid
,
279 (VOID
*)&PeiEfiPeiPeCoffLoader
,
283 // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
287 EFI_SOFTWARE_PEI_MODULE
| EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
291 // Transfer control to the DXE Core
292 // The handoff state is simply a pointer to the HOB list
294 DEBUG ((EFI_D_INFO
, "DXE Core Entry Point 0x%08x\n", (UINTN
) DxeCoreEntryPoint
));
295 HandOffToDxeCore (DxeCoreEntryPoint
, HobList
, &mPpiSignal
);
297 // If we get here, then the DXE Core returned. This is an error
298 // Dxe Core should not return.
303 return EFI_OUT_OF_RESOURCES
;
310 IN EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
,
311 OUT UINT32
*FvAlignment
315 // Because FvLength in FvHeader is UINT64 type,
316 // so FvHeader must meed at least 8 bytes alignment.
317 // Get the appropriate alignment requirement.
319 if ((FvHeader
->Attributes
& EFI_FVB2_ALIGNMENT
) < EFI_FVB2_ALIGNMENT_8
) {
320 return EFI_UNSUPPORTED
;
323 *FvAlignment
= 1 << ((FvHeader
->Attributes
& EFI_FVB2_ALIGNMENT
) >> 16);
328 Search EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE image and expand
331 @return EFI_OUT_OF_RESOURCES There are no memory space to exstract FV
332 @return EFI_SUCESS Sucess to find the FV
335 DxeIplAddEncapsulatedFirmwareVolumes (
340 EFI_STATUS VolumeStatus
;
342 EFI_FV_INFO VolumeInfo
;
343 EFI_PEI_FV_HANDLE VolumeHandle
;
344 EFI_PEI_FILE_HANDLE FileHandle
;
345 UINT32 SectionLength
;
346 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
347 EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*SectionHeader
;
350 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*FvInfoPpi
;
351 EFI_PEI_PPI_DESCRIPTOR
*FvInfoPpiDescriptor
;
353 Status
= EFI_NOT_FOUND
;
357 VolumeStatus
= DxeIplFindFirmwareVolumeInstance (
359 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
364 if (!EFI_ERROR (VolumeStatus
)) {
365 Status
= PeiServicesFfsFindSectionData (
366 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
367 (EFI_FFS_FILE_HEADER
*)FileHandle
,
371 if (!EFI_ERROR (Status
)) {
372 if (FvHeader
->Signature
== EFI_FVH_SIGNATURE
) {
374 // Because FvLength in FvHeader is UINT64 type,
375 // so FvHeader must meed at least 8 bytes alignment.
376 // If current FvImage base address doesn't meet its alignment,
377 // we need to reload this FvImage to another correct memory address.
379 Status
= GetFvAlignment(FvHeader
, &FvAlignment
);
380 if (EFI_ERROR(Status
)) {
383 if (((UINTN
) FvHeader
% FvAlignment
) != 0) {
384 SectionHeader
= (EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*)((UINTN
)FvHeader
- sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION
));
385 SectionLength
= *(UINT32
*)SectionHeader
->Size
& 0x00FFFFFF;
387 DstBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN
) SectionLength
- sizeof (EFI_COMMON_SECTION_HEADER
)), FvAlignment
);
388 if (DstBuffer
== NULL
) {
389 return EFI_OUT_OF_RESOURCES
;
391 CopyMem (DstBuffer
, FvHeader
, (UINTN
) SectionLength
- sizeof (EFI_COMMON_SECTION_HEADER
));
392 FvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) DstBuffer
;
396 // This new Firmware Volume comes from a firmware file within a firmware volume.
397 // Record the original Firmware Volume Name.
399 PeiServicesFfsGetVolumeInfo (&VolumeHandle
, &VolumeInfo
);
402 // Prepare to install FirmwareVolumeInfo PPI to expose new FV to PeiCore.
404 FvInfoPpi
= AllocateCopyPool (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
), &mFvInfoPpiTemplate
);
405 ASSERT(FvInfoPpi
!= NULL
);
407 FvInfoPpi
->FvInfo
= (VOID
*)FvHeader
;
408 FvInfoPpi
->FvInfoSize
= (UINT32
)FvHeader
->FvLength
;
410 &FvInfoPpi
->ParentFvName
,
411 &(VolumeInfo
.FvName
),
415 &FvInfoPpi
->ParentFileName
,
416 &(((EFI_FFS_FILE_HEADER
*)FileHandle
)->Name
),
420 FvInfoPpiDescriptor
= AllocatePool (sizeof(EFI_PEI_PPI_DESCRIPTOR
));
421 ASSERT (FvInfoPpiDescriptor
!= NULL
);
423 FvInfoPpiDescriptor
->Flags
= EFI_PEI_PPI_DESCRIPTOR_PPI
|EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
;
424 FvInfoPpiDescriptor
->Guid
= &gEfiPeiFirmwareVolumeInfoPpiGuid
;
425 FvInfoPpiDescriptor
->Ppi
= (VOID
*) FvInfoPpi
;
427 Status
= PeiServicesInstallPpi (FvInfoPpiDescriptor
);
428 ASSERT_EFI_ERROR (Status
);
431 // Makes the encapsulated volume show up in DXE phase to skip processing of
432 // encapsulated file again.
435 (EFI_PHYSICAL_ADDRESS
)(UINTN
)FvHeader
,
438 &(((EFI_FFS_FILE_HEADER
*)FileHandle
)->Name
)
444 } while (!EFI_ERROR (VolumeStatus
));
450 Find the First Volume that contains the first FileType.
452 @param Instance The Fv instance.
453 @param SeachType The type of file to search.
454 @param VolumeHandle Pointer to Fv which contains the file to search.
455 @param FileHandle Pointer to FFS file to search.
457 @return EFI_SUCESS Success to find the FFS in specificed FV
458 @return others Fail to find the FFS in specificed FV
461 DxeIplFindFirmwareVolumeInstance (
462 IN OUT UINTN
*Instance
,
463 IN EFI_FV_FILETYPE SeachType
,
464 OUT EFI_PEI_FV_HANDLE
*VolumeHandle
,
465 OUT EFI_PEI_FILE_HANDLE
*FileHandle
469 EFI_STATUS VolumeStatus
;
472 VolumeStatus
= PeiServicesFfsFindNextVolume (*Instance
, VolumeHandle
);
473 if (!EFI_ERROR (VolumeStatus
)) {
475 Status
= PeiServicesFfsFindNextFile (SeachType
, *VolumeHandle
, FileHandle
);
476 if (!EFI_ERROR (Status
)) {
481 } while (!EFI_ERROR (VolumeStatus
));
487 Loads and relocates a PE/COFF image into memory.
489 @param FileHandle The image file handle
490 @param ImageAddress The base address of the relocated PE/COFF image
491 @param ImageSize The size of the relocated PE/COFF image
492 @param EntryPoint The entry point of the relocated PE/COFF image
494 @return EFI_SUCCESS The file was loaded and relocated
495 @return EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file
499 IN EFI_PEI_FILE_HANDLE FileHandle
,
500 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
501 OUT UINT64
*ImageSize
,
502 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
507 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
509 EFI_PEI_PE_COFF_LOADER_PROTOCOL
*PeiEfiPeiPeCoffLoader
;
511 PeiEfiPeiPeCoffLoader
= (EFI_PEI_PE_COFF_LOADER_PROTOCOL
*)GetPeCoffLoaderProtocol ();
513 // First try to find the required section in this ffs file.
515 Status
= PeiServicesFfsFindSectionData (
521 if (EFI_ERROR (Status
)) {
522 Status
= PeiServicesFfsFindSectionData (
529 if (EFI_ERROR (Status
)) {
531 // NO image types we support so exit.
536 ZeroMem (&ImageContext
, sizeof (ImageContext
));
537 ImageContext
.Handle
= Pe32Data
;
538 Status
= GetImageReadFunction (&ImageContext
);
540 ASSERT_EFI_ERROR (Status
);
542 Status
= PeiEfiPeiPeCoffLoader
->GetImageInfo (PeiEfiPeiPeCoffLoader
, &ImageContext
);
543 if (EFI_ERROR (Status
)) {
547 // Allocate Memory for the image
549 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32
) ImageContext
.ImageSize
));
550 ASSERT (ImageContext
.ImageAddress
!= 0);
553 // Load the image to our new buffer
555 Status
= PeiEfiPeiPeCoffLoader
->LoadImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
556 if (EFI_ERROR (Status
)) {
560 // Relocate the image in our new buffer
562 Status
= PeiEfiPeiPeCoffLoader
->RelocateImage (PeiEfiPeiPeCoffLoader
, &ImageContext
);
563 if (EFI_ERROR (Status
)) {
568 // Flush the instruction cache so the image data is written before we execute it
570 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)ImageContext
.ImageAddress
, (UINTN
)ImageContext
.ImageSize
);
572 *ImageAddress
= ImageContext
.ImageAddress
;
573 *ImageSize
= ImageContext
.ImageSize
;
574 *EntryPoint
= ImageContext
.EntryPoint
;
580 The ExtractSection() function processes the input section and
581 returns a pointer to the section contents. If the section being
582 extracted does not require processing (if the section
583 GuidedSectionHeader.Attributes has the
584 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
585 OutputBuffer is just updated to point to the start of the
586 section's contents. Otherwise, *Buffer must be allocated
587 from PEI permanent memory.
589 @param This Indicates the
590 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
591 Buffer containing the input GUIDed section to be
592 processed. OutputBuffer OutputBuffer is
593 allocated from PEI permanent memory and contains
594 the new section stream.
596 @param OutputSize A pointer to a caller-allocated
597 UINTN in which the size of *OutputBuffer
598 allocation is stored. If the function
599 returns anything other than EFI_SUCCESS,
600 the value of OutputSize is undefined.
602 @param AuthenticationStatus A pointer to a caller-allocated
603 UINT32 that indicates the
604 authentication status of the
605 output buffer. If the input
606 section's GuidedSectionHeader.
607 Attributes field has the
608 EFI_GUIDED_SECTION_AUTH_STATUS_VALID
610 AuthenticationStatus must return
611 zero. These bits reflect the
612 status of the extraction
613 operation. If the function
614 returns anything other than
615 EFI_SUCCESS, the value of
616 AuthenticationStatus is
619 @retval EFI_SUCCESS The InputSection was
620 successfully processed and the
621 section contents were returned.
623 @retval EFI_OUT_OF_RESOURCES The system has insufficient
624 resources to process the request.
626 @reteval EFI_INVALID_PARAMETER The GUID in InputSection does
627 not match this instance of the
628 GUIDed Section Extraction PPI.
631 CustomDecompressExtractSection (
632 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
*This
,
633 IN CONST VOID
*InputSection
,
634 OUT VOID
**OutputBuffer
,
635 OUT UINTN
*OutputSize
,
636 OUT UINT32
*AuthenticationStatus
640 UINT8
*ScratchBuffer
;
642 UINT32 SectionLength
;
643 UINT32 DestinationSize
;
646 // Set authentic value to zero.
648 *AuthenticationStatus
= 0;
650 // Calculate Section data Size
652 SectionLength
= *(UINT32
*) (((EFI_COMMON_SECTION_HEADER
*) InputSection
)->Size
) & 0x00ffffff;
654 // Get compressed data information
656 Status
= CustomDecompressGetInfo (
657 (GUID
*) ((UINT8
*) InputSection
+ sizeof (EFI_COMMON_SECTION_HEADER
)),
658 (UINT8
*) InputSection
+ sizeof (EFI_GUID_DEFINED_SECTION
),
659 SectionLength
- sizeof (EFI_GUID_DEFINED_SECTION
),
663 if (EFI_ERROR (Status
)) {
667 DEBUG ((EFI_D_ERROR
, "Extract guided section Failed - %r\n", Status
));
672 // Allocate scratch buffer
674 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchSize
));
675 if (ScratchBuffer
== NULL
) {
676 return EFI_OUT_OF_RESOURCES
;
679 // Allocate destination buffer
681 *OutputSize
= (UINTN
) DestinationSize
;
682 *OutputBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (*OutputSize
));
683 if (*OutputBuffer
== NULL
) {
684 return EFI_OUT_OF_RESOURCES
;
688 // Call decompress function
690 Status
= CustomDecompress (
691 (GUID
*) ((UINT8
*) InputSection
+ sizeof (EFI_COMMON_SECTION_HEADER
)),
692 (UINT8
*) InputSection
+ sizeof (EFI_GUID_DEFINED_SECTION
),
697 if (EFI_ERROR (Status
)) {
701 DEBUG ((EFI_D_ERROR
, "Extract guided section Failed - %r\n", Status
));
712 IN CONST EFI_PEI_DECOMPRESS_PPI
*This
,
713 IN CONST EFI_COMPRESSION_SECTION
*CompressionSection
,
714 OUT VOID
**OutputBuffer
,
715 OUT UINTN
*OutputSize
720 UINT8
*ScratchBuffer
;
722 UINT32 ScratchBufferSize
;
723 EFI_COMMON_SECTION_HEADER
*Section
;
726 if (CompressionSection
->CommonHeader
.Type
!= EFI_SECTION_COMPRESSION
) {
728 return EFI_INVALID_PARAMETER
;
731 Section
= (EFI_COMMON_SECTION_HEADER
*) CompressionSection
;
732 SectionLength
= *(UINT32
*) (Section
->Size
) & 0x00ffffff;
735 // This is a compression set, expand it
737 switch (CompressionSection
->CompressionType
) {
738 case EFI_STANDARD_COMPRESSION
:
740 // Load EFI standard compression.
741 // For compressed data, decompress them to dstbuffer.
743 Status
= UefiDecompressGetInfo (
744 (UINT8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
745 (UINT32
) SectionLength
- sizeof (EFI_COMPRESSION_SECTION
),
746 (UINT32
*) &DstBufferSize
,
749 if (EFI_ERROR (Status
)) {
753 DEBUG ((EFI_D_ERROR
, "Decompress GetInfo Failed - %r\n", Status
));
754 return EFI_NOT_FOUND
;
757 // Allocate scratch buffer
759 ScratchBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize
));
760 if (ScratchBuffer
== NULL
) {
761 return EFI_OUT_OF_RESOURCES
;
764 // Allocate destination buffer
766 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
767 if (DstBuffer
== NULL
) {
768 return EFI_OUT_OF_RESOURCES
;
771 // Call decompress function
773 Status
= UefiDecompress (
774 (CHAR8
*) ((EFI_COMPRESSION_SECTION
*) Section
+ 1),
778 if (EFI_ERROR (Status
)) {
782 DEBUG ((EFI_D_ERROR
, "Decompress Failed - %r\n", Status
));
783 return EFI_NOT_FOUND
;
787 // porting note the original branch for customized compress is removed, it should be change to use GUID compress
789 case EFI_NOT_COMPRESSED
:
791 // Allocate destination buffer
793 DstBufferSize
= CompressionSection
->UncompressedLength
;
794 DstBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize
));
795 if (DstBuffer
== NULL
) {
796 return EFI_OUT_OF_RESOURCES
;
799 // stream is not actually compressed, just encapsulated. So just copy it.
801 CopyMem (DstBuffer
, CompressionSection
+ 1, DstBufferSize
);
806 // Don't support other unknown compression type.
809 return EFI_NOT_FOUND
;
812 *OutputSize
= DstBufferSize
;
813 *OutputBuffer
= DstBuffer
;