/*++

Copyright (c) 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  DxeLoad.c

Abstract:

  Last PEIM.
  Responsibility of this module is to load the DXE Core from a Firmware Volume.

--*/

#include <DxeIpl.h>

#pragma warning( disable : 4305 )

BOOLEAN gInMemory = FALSE;

//
// GUID for EM64T
//
#define EFI_PPI_NEEDED_BY_DXE \
  { \
    0x4d37da42, 0x3a0c, 0x4eda, 0xb9, 0xeb, 0xbc, 0x0e, 0x1d, 0xb4, 0x71, 0x3b \
  }
EFI_GUID mPpiNeededByDxeGuid = EFI_PPI_NEEDED_BY_DXE;

//
// Module Globals used in the DXE to PEI handoff
// These must be module globals, so the stack can be switched
//
static EFI_DXE_IPL_PPI mDxeIplPpi = {
  DxeLoadCore
};

static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = {
  DxeIplLoadFile
};

static EFI_PEI_PPI_DESCRIPTOR     mPpiLoadFile = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEfiPeiFvFileLoaderPpiGuid,
  &mLoadFilePpi
};

static EFI_PEI_PPI_DESCRIPTOR     mPpiList = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEfiDxeIplPpiGuid,
  &mDxeIplPpi
};

static EFI_PEI_PPI_DESCRIPTOR     mPpiPeiInMemory = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gPeiInMemoryGuid,
  NULL
};

static EFI_PEI_PPI_DESCRIPTOR     mPpiSignal = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEfiEndOfPeiSignalPpiGuid,
  NULL
};

DECOMPRESS_LIBRARY  gEfiDecompress = {
  UefiDecompressGetInfo,
  UefiDecompress
};

DECOMPRESS_LIBRARY  gTianoDecompress = {
  TianoDecompressGetInfo,
  TianoDecompress
};

DECOMPRESS_LIBRARY  gCustomDecompress = {
  CustomDecompressGetInfo,
  CustomDecompress
};

STATIC
UINTN
GetOccupiedSize (
  IN UINTN   ActualSize,
  IN UINTN   Alignment
  )
{
  UINTN OccupiedSize;

  OccupiedSize = ActualSize;
  while ((OccupiedSize & (Alignment - 1)) != 0) {
    OccupiedSize++;
  }

  return OccupiedSize;
}

EFI_STATUS
EFIAPI
PeimInitializeDxeIpl (
  IN EFI_FFS_FILE_HEADER       *FfsHeader,
  IN EFI_PEI_SERVICES          **PeiServices
  )
/*++

Routine Description:

  Initializes the Dxe Ipl PPI

Arguments:

  FfsHeader   - Pointer to FFS file header
  PeiServices - General purpose services available to every PEIM.

Returns:

  EFI_SUCCESS

--*/
{
  EFI_STATUS                                Status;
  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;
  EFI_BOOT_MODE                             BootMode;

  Status = PeiServicesGetBootMode (&BootMode);

  ASSERT_EFI_ERROR (Status);

  Status = PeiServicesLocatePpi (
             &gPeiInMemoryGuid,
             0,
             NULL,
             NULL
             );

  if (EFI_ERROR (Status) && (BootMode != BOOT_ON_S3_RESUME)) {   
    //
    // The DxeIpl has not yet been shadowed
    //
    PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();

    //
    // Shadow DxeIpl and then re-run its entry point
    //
    Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);
    if (EFI_ERROR (Status)) {
      return Status;
    }

  } else {
    if (BootMode != BOOT_ON_S3_RESUME) {
    //
    // The DxeIpl has been shadowed
    //
    gInMemory = TRUE;

    //
    // Install LoadFile PPI
    //
    Status = PeiServicesInstallPpi (&mPpiLoadFile);

    if (EFI_ERROR (Status)) {
      return Status;
      }
    }
    //
    // Install DxeIpl PPI
    //
    PeiServicesInstallPpi (&mPpiList);

    if (EFI_ERROR (Status)) {
      return Status;
    }

  }

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
DxeLoadCore (
  IN EFI_DXE_IPL_PPI       *This,
  IN EFI_PEI_SERVICES      **PeiServices,
  IN EFI_PEI_HOB_POINTERS  HobList
  )
/*++

Routine Description:

  Main entry point to last PEIM

Arguments:

  This         - Entry point for DXE IPL PPI
  PeiServices  - General purpose services available to every PEIM.
  HobList      - Address to the Pei HOB list

Returns:

  EFI_SUCCESS          - DEX core was successfully loaded.
  EFI_OUT_OF_RESOURCES - There are not enough resources to load DXE core.

--*/
{
  EFI_STATUS                                                Status;
  EFI_PHYSICAL_ADDRESS                                      TopOfStack;
  EFI_PHYSICAL_ADDRESS                                      BaseOfStack;
  EFI_PHYSICAL_ADDRESS                                      BspStore;
  EFI_GUID                                                  DxeCoreFileName;
  VOID                                                      *DxeCorePe32Data;
  EFI_PHYSICAL_ADDRESS                                      DxeCoreAddress;
  UINT64                                                    DxeCoreSize;
  EFI_PHYSICAL_ADDRESS                                      DxeCoreEntryPoint;
  EFI_PEI_PE_COFF_LOADER_PROTOCOL                           *PeiEfiPeiPeCoffLoader;
  EFI_BOOT_MODE                                             BootMode;
  EFI_PEI_RECOVERY_MODULE_PPI                               *PeiRecovery;
  EFI_PEI_S3_RESUME_PPI                                     *S3Resume;
  EFI_PHYSICAL_ADDRESS                                      PageTables;
  
  TopOfStack  = 0;
  BaseOfStack = 0;
  BspStore    = 0;
  Status      = EFI_SUCCESS;

  //
  // if in S3 Resume, restore configure
  //
  Status = PeiServicesGetBootMode (&BootMode);

  if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) {
    Status = PeiServicesLocatePpi (
               &gEfiPeiS3ResumePpiGuid,
               0,
               NULL,
               (VOID **)&S3Resume
               );

    ASSERT_EFI_ERROR (Status);

    Status = S3Resume->S3RestoreConfig (PeiServices);

    ASSERT_EFI_ERROR (Status);
  }

  Status = EFI_SUCCESS;

  //
  // Install the PEI Protocols that are shared between PEI and DXE
  //
#ifdef EFI_NT_EMULATOR
  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
  ASSERT (PeiEfiPeiPeCoffLoader != NULL);
#else
  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderX64Protocol ();
#endif 

  //
  // Allocate 128KB for the Stack
  //
  PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
  ASSERT (BaseOfStack != 0);

  //
  // Compute the top of the stack we were allocated. Pre-allocate a 32 bytes
  // for safety (PpisNeededByDxe and DxeCore).
  //
  TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;

  //
  // Add architecture-specifc HOBs (including the BspStore HOB)
  //
  Status = CreateArchSpecificHobs (&BspStore);
  ASSERT_EFI_ERROR (Status);

  //
  // See if we are in crisis recovery
  //
  Status = PeiServicesGetBootMode (&BootMode);
  if (!EFI_ERROR (Status) && (BootMode == BOOT_IN_RECOVERY_MODE)) {
    Status = PeiServicesLocatePpi (
               &gEfiPeiRecoveryModulePpiGuid,
               0,
               NULL,
               (VOID **)&PeiRecovery
               );

    ASSERT_EFI_ERROR (Status);
    Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Find the DXE Core in a Firmware Volume
  //
  Status = PeiFindFile (
             EFI_FV_FILETYPE_DXE_CORE,
             EFI_SECTION_PE32,
             &DxeCoreFileName,
             &DxeCorePe32Data
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Transfer control to the DXE Core
  // The handoff state is simply a pointer to the HOB list
  //
  // PEI_PERF_END (PeiServices, L"DxeIpl", NULL, 0);

  Status = PeiServicesInstallPpi (&mPpiSignal);
  ASSERT_EFI_ERROR (Status);

  //
  // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA \
  // memory, it may be corrupted when copying FV to high-end memory 
  LoadGo64Gdt();

  //
  // Limit to 36 bits of addressing for debug. Should get it from CPU
  //
  PageTables = CreateIdentityMappingPageTables (36);


  //
  // Load the DXE Core from a Firmware Volume
  //
  Status = PeiLoadx64File (
             PeiEfiPeiPeCoffLoader,
             DxeCorePe32Data,
             EfiBootServicesData,
             &DxeCoreAddress,
             &DxeCoreSize,
             &DxeCoreEntryPoint
             );
  ASSERT_EFI_ERROR (Status);

  //
  //
  // Add HOB for the DXE Core
  //
  BuildModuleHob (
    &DxeCoreFileName,
    DxeCoreAddress,
    DxeCoreSize,
    DxeCoreEntryPoint
    );

  //
  // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
  //
  REPORT_STATUS_CODE (
    EFI_PROGRESS_CODE,
    EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
    );

  DEBUG ((EFI_D_INFO, "DXE Core Entry\n"));
  //
  // Go to Long Mode. Interrupts will not get turned on until the CPU AP is loaded.
  // Call x64 drivers passing in single argument, a pointer to the HOBs.
  //
  ActivateLongMode (
    PageTables, 
    (EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw), 
    TopOfStack,
    0x00000000,
    DxeCoreEntryPoint
    );

  //
  // If we get here, then the DXE Core returned.  This is an error
  //
  ASSERT_EFI_ERROR (Status);

  return EFI_OUT_OF_RESOURCES;
}

EFI_STATUS
PeiFindFile (
  IN  UINT8                  Type,
  IN  UINT16                 SectionType,
  OUT EFI_GUID               *FileName,
  OUT VOID                   **Pe32Data
  )
/*++

Routine Description:

  Finds a PE/COFF of a specific Type and SectionType in the Firmware Volumes
  described in the HOB list. Able to search in a compression set in a FFS file.
  But only one level of compression is supported, that is, not able to search
  in a compression set that is within another compression set.

Arguments:

  Type        - The Type of file to retrieve

  SectionType - The type of section to retrieve from a file

  FileName    - The name of the file found in the Firmware Volume

  Pe32Data    - Pointer to the beginning of the PE/COFF file found in the Firmware Volume

Returns:

  EFI_SUCCESS   - The file was found, and the name is returned in FileName, and a pointer to
                  the PE/COFF image is returned in Pe32Data

  EFI_NOT_FOUND - The file was not found in the Firmware Volumes present in the HOB List

--*/
{
  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;
  EFI_FFS_FILE_HEADER         *FfsFileHeader;
  VOID                        *SectionData;
  EFI_STATUS                  Status;
  EFI_PEI_HOB_POINTERS        Hob;


  FwVolHeader   = NULL;
  FfsFileHeader = NULL;
  SectionData   = NULL;

  //
  // Foreach Firmware Volume, look for a specified type
  // of file and break out when one is found
  //
  Hob.Raw = GetHobList ();
  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw)) != NULL) {
    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (Hob.FirmwareVolume->BaseAddress);
    Status = PeiServicesFfsFindNextFile (
               Type,
               FwVolHeader,
               &FfsFileHeader
               );
    if (!EFI_ERROR (Status)) {
      Status = PeiProcessFile (
                 SectionType,
                 &FfsFileHeader,
                 Pe32Data
                 );
      CopyMem (FileName, &FfsFileHeader->Name, sizeof (EFI_GUID));
      return Status;
    }
    Hob.Raw = GET_NEXT_HOB (Hob);
  }
  return EFI_NOT_FOUND;
}

EFI_STATUS
PeiLoadx64File (
  IN  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,
  IN  VOID                                      *Pe32Data,
  IN  EFI_MEMORY_TYPE                           MemoryType,
  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,
  OUT UINT64                                    *ImageSize,
  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint
  )
/*++

Routine Description:

  Loads and relocates a PE/COFF image into memory.

Arguments:

  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol

  Pe32Data         - The base address of the PE/COFF file that is to be loaded and relocated

  ImageAddress     - The base address of the relocated PE/COFF image

  ImageSize        - The size of the relocated PE/COFF image

  EntryPoint       - The entry point of the relocated PE/COFF image

Returns:

  EFI_SUCCESS                     - The file was loaded and relocated
  EFI_OUT_OF_RESOURCES            - There was not enough memory to load and relocate the PE/COFF file

--*/
{
  EFI_STATUS                            Status;
  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;
  EFI_PHYSICAL_ADDRESS                  MemoryBuffer;

  ZeroMem (&ImageContext, sizeof (ImageContext));
  ImageContext.Handle = Pe32Data;
  Status              = GetImageReadFunction (&ImageContext);

  ASSERT_EFI_ERROR (Status);

  Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Allocate Memory for the image
  //
  //
  // Allocate Memory for the image
  //
  PeiServicesAllocatePages (MemoryType, EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize), &MemoryBuffer);
  ImageContext.ImageAddress = MemoryBuffer;
  ASSERT (ImageContext.ImageAddress != 0);

  //
  // Load the image to our new buffer
  //

  Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  //
  // Relocate the image in our new buffer
  //
  Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Flush the instruction cache so the image data is written before we execute it
  //
  InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);

  *ImageAddress = ImageContext.ImageAddress;
  *ImageSize    = ImageContext.ImageSize;
  *EntryPoint   = ImageContext.EntryPoint;

  return EFI_SUCCESS;
}

EFI_STATUS
ShadowDxeIpl (
  IN EFI_FFS_FILE_HEADER                       *DxeIplFileHeader,
  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader
  )
/*++

Routine Description:

  Shadow the DXE IPL to a different memory location. This occurs after permanent
  memory has been discovered.

Arguments:

  DxeIplFileHeader      - Pointer to the FFS file header of the DXE IPL driver

  PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol

Returns:

  EFI_SUCCESS   - DXE IPL was successfully shadowed to a different memory location.

  EFI_ ERROR    - The shadow was unsuccessful.


--*/
{
  UINTN                     SectionLength;
  UINTN                     OccupiedSectionLength;
  EFI_PHYSICAL_ADDRESS      DxeIplAddress;
  UINT64                    DxeIplSize;
  EFI_PHYSICAL_ADDRESS      DxeIplEntryPoint;
  EFI_STATUS                Status;
  EFI_COMMON_SECTION_HEADER *Section;

  Section = (EFI_COMMON_SECTION_HEADER *) (DxeIplFileHeader + 1);

  while ((Section->Type != EFI_SECTION_PE32) && (Section->Type != EFI_SECTION_TE)) {
    SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;
    OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);
    Section               = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
  }
  
  //
  // Relocate DxeIpl into memory by using loadfile service
  //
  Status = PeiLoadx64File (
            PeiEfiPeiPeCoffLoader,
            (VOID *) (Section + 1),
            EfiBootServicesData,
            &DxeIplAddress,
            &DxeIplSize,
            &DxeIplEntryPoint
            );
 
  if (Status == EFI_SUCCESS) {
    //
    // Install PeiInMemory to indicate the Dxeipl is shadowed
    //
    Status = PeiServicesInstallPpi (&mPpiPeiInMemory);

    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = ((EFI_PEIM_ENTRY_POINT) (UINTN) DxeIplEntryPoint) (DxeIplFileHeader, GetPeiServicesTablePointer());
  }

  return Status;
}

EFI_STATUS
EFIAPI
DxeIplLoadFile (
  IN EFI_PEI_FV_FILE_LOADER_PPI                 *This,
  IN  EFI_FFS_FILE_HEADER                       *FfsHeader,
  OUT EFI_PHYSICAL_ADDRESS                      *ImageAddress,
  OUT UINT64                                    *ImageSize,
  OUT EFI_PHYSICAL_ADDRESS                      *EntryPoint
  )
/*++

Routine Description:

  Given a pointer to an FFS file containing a PE32 image, get the
  information on the PE32 image, and then "load" it so that it
  can be executed.

Arguments:

  This  - pointer to our file loader protocol
  FfsHeader - pointer to the FFS file header of the FFS file that
              contains the PE32 image we want to load
  ImageAddress  - returned address where the PE32 image is loaded
  ImageSize     - returned size of the loaded PE32 image
  EntryPoint    - entry point to the loaded PE32 image

Returns:
 
  EFI_SUCCESS  - The FFS file was successfully loaded.
  EFI_ERROR    - Unable to load the FFS file.

--*/
{
  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;
  EFI_STATUS                                Status;
  VOID                                      *Pe32Data;

  Pe32Data = NULL;
  PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();

  //
  // Preprocess the FFS file to get a pointer to the PE32 information
  // in the enclosed PE32 image.
  //
  Status = PeiProcessFile (
            EFI_SECTION_PE32,
            &FfsHeader,
            &Pe32Data
            );

  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Load the PE image from the FFS file
  //
  Status = PeiLoadx64File (
            PeiEfiPeiPeCoffLoader,
            Pe32Data,
            EfiBootServicesData,
            ImageAddress,
            ImageSize,
            EntryPoint
            );

  return Status;
}

EFI_STATUS
PeiProcessFile (
  IN      UINT16                 SectionType,
  IN OUT  EFI_FFS_FILE_HEADER    **RealFfsFileHeader,
  OUT     VOID                   **Pe32Data
  )
/*++

Routine Description:

Arguments:

  SectionType       - The type of section in the FFS file to process.

  FfsFileHeader     - Pointer to the FFS file to process, looking for the
                      specified SectionType

  Pe32Data          - returned pointer to the start of the PE32 image found
                      in the FFS file.

Returns:

  EFI_SUCCESS       - found the PE32 section in the FFS file

--*/
{
  EFI_STATUS                      Status;
  VOID                            *SectionData;
  DECOMPRESS_LIBRARY              *DecompressLibrary;
  UINT8                           *DstBuffer;
  UINT8                           *ScratchBuffer;
  UINT32                          DstBufferSize;
  UINT32                          ScratchBufferSize;
  EFI_COMMON_SECTION_HEADER       *CmpSection;
  UINTN                           CmpSectionLength;
  UINTN                           OccupiedCmpSectionLength;
  VOID                            *CmpFileData;
  UINTN                           CmpFileSize;
  EFI_COMMON_SECTION_HEADER       *Section;
  UINTN                           SectionLength;
  UINTN                           OccupiedSectionLength;
  UINT64                          FileSize;
  EFI_GUID_DEFINED_SECTION        *GuidedSectionHeader;
  UINT32                          AuthenticationStatus;
  EFI_PEI_SECTION_EXTRACTION_PPI  *SectionExtract;
  UINT32                          BufferSize;
  UINT8                           *Buffer;
  EFI_PEI_SECURITY_PPI            *Security;
  BOOLEAN                         StartCrisisRecovery;
  EFI_GUID                        TempGuid;
  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;
  EFI_COMPRESSION_SECTION         *CompressionSection;
  EFI_FFS_FILE_HEADER             *FfsFileHeader;
  
  FfsFileHeader = *RealFfsFileHeader;

  Status = PeiServicesFfsFindSectionData (
             EFI_SECTION_COMPRESSION,
             FfsFileHeader,
             &SectionData
             );

  //
  // Upon finding a DXE Core file, see if there is first a compression section
  //
  if (!EFI_ERROR (Status)) {
    //
    // Yes, there is a compression section, so extract the contents
    // Decompress the image here
    //
    Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));

    do {
      SectionLength         = *(UINT32 *) (Section->Size) & 0x00ffffff;
      OccupiedSectionLength = GetOccupiedSize (SectionLength, 4);

      //
      // Was the DXE Core file encapsulated in a GUID'd section?
      //
      if (Section->Type == EFI_SECTION_GUID_DEFINED) {
        //
        // Locate the GUID'd Section Extractor
        //
        GuidedSectionHeader = (VOID *) (Section + 1);

        //
        // This following code constitutes the addition of the security model
        // to the DXE IPL.
        //
        //
        // Set a default authenticatino state
        //
        AuthenticationStatus = 0;

        Status = PeiServicesLocatePpi (
                   &gEfiPeiSectionExtractionPpiGuid,
                   0,
                   NULL,
                   (VOID **)&SectionExtract
                   );

        if (EFI_ERROR (Status)) {
          return Status;
        }
        //
        // Verify Authentication State
        //
        CopyMem (&TempGuid, Section + 1, sizeof (EFI_GUID));

        Status = SectionExtract->PeiGetSection (
                                  GetPeiServicesTablePointer(),
                                  SectionExtract,
                                  (EFI_SECTION_TYPE *) &SectionType,
                                  &TempGuid,
                                  0,
                                  (VOID **) &Buffer,
                                  &BufferSize,
                                  &AuthenticationStatus
                                  );

        if (EFI_ERROR (Status)) {
          return Status;
        }
        //
        // If not ask the Security PPI, if exists, for disposition
        //
        //
        Status = PeiServicesLocatePpi (
                   &gEfiPeiSecurityPpiGuid,
                   0,
                   NULL,
                   (VOID **)&Security
                   );
        if (EFI_ERROR (Status)) {
          return Status;
        }

        Status = Security->AuthenticationState (
                            GetPeiServicesTablePointer(),
                            (struct _EFI_PEI_SECURITY_PPI *) Security,
                            AuthenticationStatus,
                            FfsFileHeader,
                            &StartCrisisRecovery
                            );

        if (EFI_ERROR (Status)) {
          return Status;
        }
        //
        // If there is a security violation, report to caller and have
        // the upper-level logic possible engender a crisis recovery
        //
        if (StartCrisisRecovery) {
          return EFI_SECURITY_VIOLATION;
        }
      }

      if (Section->Type == EFI_SECTION_PE32) {
        //
        // This is what we want
        //
        *Pe32Data = (VOID *) (Section + 1);
        return EFI_SUCCESS;
      } else if (Section->Type == EFI_SECTION_COMPRESSION) {
        //
        // This is a compression set, expand it
        //
        CompressionSection  = (EFI_COMPRESSION_SECTION *) Section;

        switch (CompressionSection->CompressionType) {
        case EFI_STANDARD_COMPRESSION:
          DecompressLibrary = &gTianoDecompress;
          break;

        case EFI_CUSTOMIZED_COMPRESSION:
          //
          // Load user customized compression protocol.
          //
          DecompressLibrary = &gCustomDecompress;
          break;

        case EFI_NOT_COMPRESSED:
        default:
          //
          // Need to support not compressed file
          //
          ASSERT_EFI_ERROR (Status);
          return EFI_NOT_FOUND;
        }

        Status = DecompressLibrary->GetInfo (
                   (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
                   (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
                   &DstBufferSize,
                   &ScratchBufferSize
                   );
        if (EFI_ERROR (Status)) {
          //
          // GetInfo failed
          //
          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 = DecompressLibrary->Decompress (
                    (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
                    DstBuffer,
                    ScratchBuffer
                    );

        CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
        if (CmpSection->Type == EFI_SECTION_RAW) {
          //
          // Skip the section header and
          // adjust the pointer alignment to 16
          //
          FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (DstBuffer + 16);

          if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
            FfsFileHeader = NULL;
            BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);
            Status = PeiServicesFfsFindNextFile (
                       EFI_FV_FILETYPE_DXE_CORE,
                       FvHeader,
                       &FfsFileHeader
                       );

            if (EFI_ERROR (Status)) {
              return EFI_NOT_FOUND;
            }

            //
            // Reture the FfsHeader that contain Pe32Data.
            //
            *RealFfsFileHeader = FfsFileHeader;
            return PeiProcessFile (SectionType, RealFfsFileHeader, Pe32Data);
          }
        }
        //
        // Decompress successfully.
        // Loop the decompressed data searching for expected section.
        //
        CmpFileData = (VOID *) DstBuffer;
        CmpFileSize = DstBufferSize;
        do {
          CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;
          if (CmpSection->Type == EFI_SECTION_PE32) {
            //
            // This is what we want
            //
            *Pe32Data = (VOID *) (CmpSection + 1);
            return EFI_SUCCESS;
          }

          OccupiedCmpSectionLength  = GetOccupiedSize (CmpSectionLength, 4);
          CmpSection                = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
        } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
      }

      Section   = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
      FileSize  = FfsFileHeader->Size[0] & 0xFF;
      FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;
      FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
      FileSize &= 0x00FFFFFF;
    } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);

    //
    // End of the decompression activity
    //
  } else {

    Status = PeiServicesFfsFindSectionData (
               EFI_SECTION_PE32,
               FfsFileHeader,
               &SectionData
               );

    if (EFI_ERROR (Status)) {
      Status = PeiServicesFfsFindSectionData (
                 EFI_SECTION_TE,
                 FfsFileHeader,
                 &SectionData
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
  }

  *Pe32Data = SectionData;

  return EFI_SUCCESS;
}