/** @file
  Last PEIM.
  Responsibility of this module is to load the DXE Core from a Firmware Volume.

Copyright (c) 2016 HP Development Company, L.P.
Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DxeIpl.h"

//
// Module Globals used in the DXE to PEI hand off
// These must be module globals, so the stack can be switched
//
CONST EFI_DXE_IPL_PPI  mDxeIplPpi = {
  DxeLoadCore
};

CONST EFI_PEI_PPI_DESCRIPTOR  mDxeIplPpiList = {
  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
  &gEfiDxeIplPpiGuid,
  (VOID *)&mDxeIplPpi
};

CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI  mCustomGuidedSectionExtractionPpi = {
  CustomGuidedSectionExtract
};

CONST EFI_PEI_DECOMPRESS_PPI  mDecompressPpi = {
  Decompress
};

CONST EFI_PEI_PPI_DESCRIPTOR  mDecompressPpiList = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEfiPeiDecompressPpiGuid,
  (VOID *)&mDecompressPpi
};

CONST EFI_PEI_PPI_DESCRIPTOR  gEndOfPeiSignalPpi = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEfiEndOfPeiSignalPpiGuid,
  NULL
};

CONST EFI_PEI_NOTIFY_DESCRIPTOR  mMemoryDiscoveredNotifyList = {
  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEfiPeiMemoryDiscoveredPpiGuid,
  InstallIplPermanentMemoryPpis
};

/**
  Entry point of DXE IPL PEIM.

  This function installs DXE IPL PPI.  It also reloads
  itself to memory on non-S3 resume boot path.

  @param  FileHandle  Handle of the file being invoked.
  @param  PeiServices Describes the list of possible PEI Services.

  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
  @retval Others      Some error occurs during the execution of this function.

**/
EFI_STATUS
EFIAPI
PeimInitializeDxeIpl (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS     Status;
  EFI_BOOT_MODE  BootMode;
  VOID           *Dummy;

  BootMode = GetBootModeHob ();

  if (BootMode != BOOT_ON_S3_RESUME) {
    Status = PeiServicesRegisterForShadow (FileHandle);
    if (Status == EFI_SUCCESS) {
      //
      // EFI_SUCESS means it is the first time to call register for shadow.
      //
      return Status;
    }

    //
    // Ensure that DXE IPL is shadowed to permanent memory.
    //
    ASSERT (Status == EFI_ALREADY_STARTED);

    //
    // DXE core load requires permanent memory.
    //
    Status = PeiServicesLocatePpi (
               &gEfiPeiMemoryDiscoveredPpiGuid,
               0,
               NULL,
               (VOID **)&Dummy
               );
    ASSERT_EFI_ERROR (Status);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Now the permanent memory exists, install the PPIs for decompression
    // and section extraction.
    //
    Status = InstallIplPermanentMemoryPpis (NULL, NULL, NULL);
    ASSERT_EFI_ERROR (Status);
  } else {
    //
    // Install memory discovered PPI notification to install PPIs for
    // decompression and section extraction.
    //
    Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Install DxeIpl PPI.
  //
  Status = PeiServicesInstallPpi (&mDxeIplPpiList);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
   This function installs the PPIs that require permanent memory.

   @param  PeiServices      Indirect reference to the PEI Services Table.
   @param  NotifyDescriptor Address of the notification descriptor data structure.
   @param  Ppi              Address of the PPI that was installed.

   @return EFI_SUCCESS      The PPIs were installed successfully.
   @return Others           Some error occurs during the execution of this function.

**/
EFI_STATUS
EFIAPI
InstallIplPermanentMemoryPpis (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_STATUS              Status;
  EFI_GUID                *ExtractHandlerGuidTable;
  UINTN                   ExtractHandlerNumber;
  EFI_PEI_PPI_DESCRIPTOR  *GuidPpi;

  //
  // Get custom extract guided section method guid list
  //
  ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);

  //
  // Install custom guided section extraction PPI
  //
  if (ExtractHandlerNumber > 0) {
    GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *)AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));
    ASSERT (GuidPpi != NULL);
    while (ExtractHandlerNumber-- > 0) {
      GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
      GuidPpi->Ppi   = (VOID *)&mCustomGuidedSectionExtractionPpi;
      GuidPpi->Guid  = &ExtractHandlerGuidTable[ExtractHandlerNumber];
      Status         = PeiServicesInstallPpi (GuidPpi++);
      ASSERT_EFI_ERROR (Status);
    }
  }

  //
  // Install Decompress PPI.
  //
  Status = PeiServicesInstallPpi (&mDecompressPpiList);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
   Validate variable data for the MemoryTypeInformation.

   @param MemoryData       Variable data.
   @param MemoryDataSize   Variable data length.

   @return TRUE            The variable data is valid.
   @return FALSE           The variable data is invalid.

**/
BOOLEAN
ValidateMemoryTypeInfoVariable (
  IN EFI_MEMORY_TYPE_INFORMATION  *MemoryData,
  IN UINTN                        MemoryDataSize
  )
{
  UINTN  Count;
  UINTN  Index;

  // Check the input parameter.
  if (MemoryData == NULL) {
    return FALSE;
  }

  // Get Count
  Count = MemoryDataSize / sizeof (*MemoryData);

  // Check Size
  if (Count * sizeof (*MemoryData) != MemoryDataSize) {
    return FALSE;
  }

  // Check last entry type filed.
  if (MemoryData[Count - 1].Type != EfiMaxMemoryType) {
    return FALSE;
  }

  // Check the type filed.
  for (Index = 0; Index < Count - 1; Index++) {
    if (MemoryData[Index].Type >= EfiMaxMemoryType) {
      return FALSE;
    }
  }

  return TRUE;
}

/**
   Main entry point to last PEIM.

   This function finds DXE Core in the firmware volume and transfer the control to
   DXE core.

   @param This          Entry point for DXE IPL PPI.
   @param PeiServices   General purpose services available to every PEIM.
   @param HobList       Address to the Pei HOB list.

   @return EFI_SUCCESS              DXE core was successfully loaded.
   @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.

**/
EFI_STATUS
EFIAPI
DxeLoadCore (
  IN CONST EFI_DXE_IPL_PPI  *This,
  IN EFI_PEI_SERVICES       **PeiServices,
  IN EFI_PEI_HOB_POINTERS   HobList
  )
{
  EFI_STATUS                       Status;
  EFI_FV_FILE_INFO                 DxeCoreFileInfo;
  EFI_PHYSICAL_ADDRESS             DxeCoreAddress;
  UINT64                           DxeCoreSize;
  EFI_PHYSICAL_ADDRESS             DxeCoreEntryPoint;
  EFI_BOOT_MODE                    BootMode;
  EFI_PEI_FILE_HANDLE              FileHandle;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *Variable;
  EFI_PEI_LOAD_FILE_PPI            *LoadFile;
  UINTN                            Instance;
  UINT32                           AuthenticationState;
  UINTN                            DataSize;
  EFI_PEI_S3_RESUME2_PPI           *S3Resume;
  EFI_PEI_RECOVERY_MODULE_PPI      *PeiRecovery;
  EDKII_PEI_CAPSULE_ON_DISK_PPI    *PeiCapsuleOnDisk;
  EFI_MEMORY_TYPE_INFORMATION      MemoryData[EfiMaxMemoryType + 1];
  VOID                             *CapsuleOnDiskModePpi;

  //
  // if in S3 Resume, restore configure
  //
  BootMode = GetBootModeHob ();

  if (BootMode == BOOT_ON_S3_RESUME) {
    Status = PeiServicesLocatePpi (
               &gEfiPeiS3Resume2PpiGuid,
               0,
               NULL,
               (VOID **)&S3Resume
               );
    if (EFI_ERROR (Status)) {
      //
      // Report Status code that S3Resume PPI can not be found
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND)
        );
    }

    ASSERT_EFI_ERROR (Status);

    Status = S3Resume->S3RestoreConfig2 (S3Resume);
    ASSERT_EFI_ERROR (Status);
  } else if (BootMode == BOOT_IN_RECOVERY_MODE) {
    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN));
    Status = PeiServicesLocatePpi (
               &gEfiPeiRecoveryModulePpiGuid,
               0,
               NULL,
               (VOID **)&PeiRecovery
               );

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status));
      //
      // Report Status code the failure of locating Recovery PPI
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
        );
      CpuDeadLoop ();
    }

    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD));
    Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
      //
      // Report Status code that recovery image can not be found
      //
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE)
        );
      CpuDeadLoop ();
    }

    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START));
    //
    // Now should have a HOB with the DXE core
    //
  } else if (BootMode == BOOT_ON_FLASH_UPDATE) {
    //
    // If Capsule On Disk mode, call storage stack to read Capsule Relocation file
    // IoMmmu is highly recommmended to enable before reading
    //
    Status = PeiServicesLocatePpi (
               &gEdkiiPeiBootInCapsuleOnDiskModePpiGuid,
               0,
               NULL,
               &CapsuleOnDiskModePpi
               );
    if (!EFI_ERROR (Status)) {
      Status = PeiServicesLocatePpi (
                 &gEdkiiPeiCapsuleOnDiskPpiGuid,
                 0,
                 NULL,
                 (VOID **)&PeiCapsuleOnDisk
                 );

      //
      // Whether failed, still goes to Firmware Update boot path. BDS will clear corresponding indicator and reboot later on
      //
      if (!EFI_ERROR (Status)) {
        Status = PeiCapsuleOnDisk->LoadCapsuleOnDisk (PeiServices, PeiCapsuleOnDisk);
      }
    }
  }

  if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) {
    //
    // Don't build GuidHob if GuidHob has been installed.
    //
    Status = PeiServicesLocatePpi (
               &gEfiPeiReadOnlyVariable2PpiGuid,
               0,
               NULL,
               (VOID **)&Variable
               );
    if (!EFI_ERROR (Status)) {
      DataSize = sizeof (MemoryData);
      Status   = Variable->GetVariable (
                             Variable,
                             EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
                             &gEfiMemoryTypeInformationGuid,
                             NULL,
                             &DataSize,
                             &MemoryData
                             );
      if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable (MemoryData, DataSize)) {
        //
        // Build the GUID'd HOB for DXE
        //
        BuildGuidDataHob (
          &gEfiMemoryTypeInformationGuid,
          MemoryData,
          DataSize
          );
      }
    }
  }

  //
  // Look in all the FVs present in PEI and find the DXE Core FileHandle
  //
  FileHandle = DxeIplFindDxeCore ();

  //
  // Load the DXE Core from a Firmware Volume.
  //
  Instance = 0;
  do {
    Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **)&LoadFile);
    //
    // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.
    //
    ASSERT_EFI_ERROR (Status);

    Status = LoadFile->LoadFile (
                         LoadFile,
                         FileHandle,
                         &DxeCoreAddress,
                         &DxeCoreSize,
                         &DxeCoreEntryPoint,
                         &AuthenticationState
                         );
  } while (EFI_ERROR (Status));

  //
  // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name.
  //
  Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo);
  ASSERT_EFI_ERROR (Status);

  //
  // Add HOB for the DXE Core
  //
  BuildModuleHob (
    &DxeCoreFileInfo.FileName,
    DxeCoreAddress,
    ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE),
    DxeCoreEntryPoint
    );

  //
  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
  //
  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT));

  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint)));

  //
  // Transfer control to the DXE Core
  // The hand off state is simply a pointer to the HOB list
  //
  HandOffToDxeCore (DxeCoreEntryPoint, HobList);
  //
  // If we get here, then the DXE Core returned.  This is an error
  // DxeCore should not return.
  //
  ASSERT (FALSE);
  CpuDeadLoop ();

  return EFI_OUT_OF_RESOURCES;
}

/**
   Searches DxeCore in all firmware Volumes and loads the first
   instance that contains DxeCore.

   @return FileHandle of DxeCore to load DxeCore.

**/
EFI_PEI_FILE_HANDLE
DxeIplFindDxeCore (
  VOID
  )
{
  EFI_STATUS           Status;
  UINTN                Instance;
  EFI_PEI_FV_HANDLE    VolumeHandle;
  EFI_PEI_FILE_HANDLE  FileHandle;

  Instance = 0;
  while (TRUE) {
    //
    // Traverse all firmware volume instances
    //
    Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle);
    //
    // If some error occurs here, then we cannot find any firmware
    // volume that may contain DxeCore.
    //
    if (EFI_ERROR (Status)) {
      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));
    }

    ASSERT_EFI_ERROR (Status);

    //
    // Find the DxeCore file type from the beginning in this firmware volume.
    //
    FileHandle = NULL;
    Status     = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
    if (!EFI_ERROR (Status)) {
      //
      // Find DxeCore FileHandle in this volume, then we skip other firmware volume and
      // return the FileHandle.
      //
      return FileHandle;
    }

    //
    // We cannot find DxeCore in this firmware volume, then search the next volume.
    //
    Instance++;
  }
}

/**
  The ExtractSection() function processes the input section and
  returns a pointer to the section contents. If the section being
  extracted does not require processing (if the section
  GuidedSectionHeader.Attributes has the
  EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
  OutputBuffer is just updated to point to the start of the
  section's contents. Otherwise, *Buffer must be allocated
  from PEI permanent memory.

  @param This                   Indicates the
                                EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
                                Buffer containing the input GUIDed section to be
                                processed. OutputBuffer OutputBuffer is
                                allocated from PEI permanent memory and contains
                                the new section stream.
  @param InputSection           A pointer to the input buffer, which contains
                                the input section to be processed.
  @param OutputBuffer           A pointer to a caller-allocated buffer, whose
                                size is specified by the contents of OutputSize.
  @param OutputSize             A pointer to a caller-allocated
                                UINTN in which the size of *OutputBuffer
                                allocation is stored. If the function
                                returns anything other than EFI_SUCCESS,
                                the value of OutputSize is undefined.
  @param AuthenticationStatus   A pointer to a caller-allocated
                                UINT32 that indicates the
                                authentication status of the
                                output buffer. If the input
                                section's GuidedSectionHeader.
                                Attributes field has the
                                EFI_GUIDED_SECTION_AUTH_STATUS_VALID
                                bit as clear,
                                AuthenticationStatus must return
                                zero. These bits reflect the
                                status of the extraction
                                operation. If the function
                                returns anything other than
                                EFI_SUCCESS, the value of
                                AuthenticationStatus is
                                undefined.

  @retval EFI_SUCCESS           The InputSection was
                                successfully processed and the
                                section contents were returned.

  @retval EFI_OUT_OF_RESOURCES  The system has insufficient
                                resources to process the request.

  @retval EFI_INVALID_PARAMETER The GUID in InputSection does
                                not match this instance of the
                                GUIDed Section Extraction PPI.

**/
EFI_STATUS
EFIAPI
CustomGuidedSectionExtract (
  IN CONST  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI  *This,
  IN CONST  VOID                                   *InputSection,
  OUT       VOID                                   **OutputBuffer,
  OUT       UINTN                                  *OutputSize,
  OUT       UINT32                                 *AuthenticationStatus
  )
{
  EFI_STATUS  Status;
  UINT8       *ScratchBuffer;
  UINT32      ScratchBufferSize;
  UINT32      OutputBufferSize;
  UINT16      SectionAttribute;

  //
  // Init local variable
  //
  ScratchBuffer = NULL;

  //
  // Call GetInfo to get the size and attribute of input guided section data.
  //
  Status = ExtractGuidedSectionGetInfo (
             InputSection,
             &OutputBufferSize,
             &ScratchBufferSize,
             &SectionAttribute
             );

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
    return Status;
  }

  if (ScratchBufferSize != 0) {
    //
    // Allocate scratch buffer
    //
    ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
    if (ScratchBuffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && (OutputBufferSize > 0)) {
    //
    // Allocate output buffer
    //
    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));
    if (*OutputBuffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));
  }

  Status = ExtractGuidedSectionDecode (
             InputSection,
             OutputBuffer,
             ScratchBuffer,
             AuthenticationStatus
             );
  if (EFI_ERROR (Status)) {
    //
    // Decode failed
    //
    DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
    return Status;
  }

  *OutputSize = (UINTN)OutputBufferSize;

  return EFI_SUCCESS;
}

/**
   Decompresses a section to the output buffer.

   This function looks up the compression type field in the input section and
   applies the appropriate compression algorithm to compress the section to a
   callee allocated buffer.

   @param  This                  Points to this instance of the
                                 EFI_PEI_DECOMPRESS_PEI PPI.
   @param  CompressionSection    Points to the compressed section.
   @param  OutputBuffer          Holds the returned pointer to the decompressed
                                 sections.
   @param  OutputSize            Holds the returned size of the decompress
                                 section streams.

   @retval EFI_SUCCESS           The section was decompressed successfully.
                                 OutputBuffer contains the resulting data and
                                 OutputSize contains the resulting size.

**/
EFI_STATUS
EFIAPI
Decompress (
  IN CONST  EFI_PEI_DECOMPRESS_PPI   *This,
  IN CONST  EFI_COMPRESSION_SECTION  *CompressionSection,
  OUT       VOID                     **OutputBuffer,
  OUT       UINTN                    *OutputSize
  )
{
  EFI_STATUS  Status;
  UINT8       *DstBuffer;
  UINT8       *ScratchBuffer;
  UINT32      DstBufferSize;
  UINT32      ScratchBufferSize;
  VOID        *CompressionSource;
  UINT32      CompressionSourceSize;
  UINT32      UncompressedLength;
  UINT8       CompressionType;

  if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {
    ASSERT (FALSE);
    return EFI_INVALID_PARAMETER;
  }

  if (IS_SECTION2 (CompressionSection)) {
    CompressionSource     = (VOID *)((UINT8 *)CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));
    CompressionSourceSize = (UINT32)(SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));
    UncompressedLength    = ((EFI_COMPRESSION_SECTION2 *)CompressionSection)->UncompressedLength;
    CompressionType       = ((EFI_COMPRESSION_SECTION2 *)CompressionSection)->CompressionType;
  } else {
    CompressionSource     = (VOID *)((UINT8 *)CompressionSection + sizeof (EFI_COMPRESSION_SECTION));
    CompressionSourceSize = (UINT32)(SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));
    UncompressedLength    = CompressionSection->UncompressedLength;
    CompressionType       = CompressionSection->CompressionType;
  }

  //
  // This is a compression set, expand it
  //
  switch (CompressionType) {
    case EFI_STANDARD_COMPRESSION:
      if (FeaturePcdGet (PcdDxeIplSupportUefiDecompress)) {
        //
        // Load EFI standard compression.
        // For compressed data, decompress them to destination buffer.
        //
        Status = UefiDecompressGetInfo (
                   CompressionSource,
                   CompressionSourceSize,
                   &DstBufferSize,
                   &ScratchBufferSize
                   );
        if (EFI_ERROR (Status)) {
          //
          // GetInfo failed
          //
          DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));
          return EFI_NOT_FOUND;
        }

        //
        // Allocate scratch buffer
        //
        ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
        if (ScratchBuffer == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        //
        // Allocate destination buffer
        //
        DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
        if (DstBuffer == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        //
        // Call decompress function
        //
        Status = UefiDecompress (
                   CompressionSource,
                   DstBuffer,
                   ScratchBuffer
                   );
        if (EFI_ERROR (Status)) {
          //
          // Decompress failed
          //
          DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));
          return EFI_NOT_FOUND;
        }

        break;
      } else {
        //
        // PcdDxeIplSupportUefiDecompress is FALSE
        // Don't support UEFI decompression algorithm.
        //
        ASSERT (FALSE);
        return EFI_NOT_FOUND;
      }

    case EFI_NOT_COMPRESSED:
      //
      // Allocate destination buffer
      //
      DstBufferSize = UncompressedLength;
      DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
      if (DstBuffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // stream is not actually compressed, just encapsulated.  So just copy it.
      //
      CopyMem (DstBuffer, CompressionSource, DstBufferSize);
      break;

    default:
      //
      // Don't support other unknown compression type.
      //
      ASSERT (FALSE);
      return EFI_NOT_FOUND;
  }

  *OutputSize   = DstBufferSize;
  *OutputBuffer = DstBuffer;

  return EFI_SUCCESS;
}

/**
   Updates the Stack HOB passed to DXE phase.

   This function traverses the whole HOB list and update the stack HOB to
   reflect the real stack that is used by DXE core.

   @param BaseAddress           The lower address of stack used by DxeCore.
   @param Length                The length of stack used by DxeCore.

**/
VOID
UpdateStackHob (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length
  )
{
  EFI_PEI_HOB_POINTERS  Hob;

  Hob.Raw = GetHobList ();
  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
      //
      // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to
      // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some
      // PEIMs may also keep key information on stack
      //
      BuildMemoryAllocationHob (
        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
        EfiBootServicesData
        );
      //
      // Update the BSP Stack Hob to reflect the new stack info.
      //
      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength      = Length;
      break;
    }

    Hob.Raw = GET_NEXT_HOB (Hob);
  }
}
