dxeload.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,324 行 · 第 1/3 页

C
1,324
字号
/*++

Copyright (c) 2004 - 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 "Tiano.h"
#include "Pei.h"
#include "DxeIpl.h"
#include "EfiHobLib.h"

EFI_PEI_SERVICES                  **gPeiServices;

//
// Interface and GUID for the Decompression APIs shared between PEI and DXE
//
EFI_GUID                          mPeiEfiDecompressProtocolGuid = EFI_DECOMPRESS_PROTOCOL_GUID;

//
// Interface and GUID for the Tiano Decompression APIs shared between PEI and DXE
//
EFI_GUID                          mPeiEfiTianoDecompressProtocolGuid = EFI_TIANO_DECOMPRESS_PROTOCOL_GUID;

//
// Interface and GUID for the user customized Decompression APIs shared between PEI and DXE
//
EFI_GUID                          mPeiEfiCustomizedDecompressProtocolGuid = EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL_GUID;

//
// Interface and GUID for the Instruction Cache Flushing APIs shared between PEI and DXE
//
EFI_GUID                          mPeiEfiPeiFlushInstructionCacheGuid = EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID;

//
// Interface and GUID for the PE/COFF Loader APIs shared between PEI and DXE
//
EFI_GUID                          mPeiEfiPeiPeCoffLoaderGuid = EFI_PEI_PE_COFF_LOADER_GUID;

//
// Interface and GUID for the setjump()/longjump() APIs shared between PEI and DXE
//
EFI_GUID                          mPeiEfiPeiTransferControlGuid = EFI_PEI_TRANSFER_CONTROL_GUID;

//
// GUID for the Firmware Volume type that PEI supports
//
// EFI_GUID  mPeiFwFileSysTypeGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID;
//
// Module Globals used in the DXE to PEI handoff
// These must be module globals, so the stack can be switched
//
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
  );

EFI_STATUS
ShadowDxeIpl (
  IN EFI_PEI_SERVICES                          **PeiServices,
  IN EFI_FFS_FILE_HEADER                       *DxeIpl,
  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader,
  IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL  *PeiEfiPeiFlushInstructionCache
  );

EFI_STATUS
EFIAPI
DxeLoadCore (
  IN EFI_DXE_IPL_PPI       *This,
  IN EFI_PEI_SERVICES      **PeiServices,
  IN EFI_PEI_HOB_POINTERS  HobList
  );

EFI_STATUS
PeiProcessFile (
  IN     EFI_PEI_SERVICES       **PeiServices,
  IN     UINT16                 SectionType,
  IN OUT EFI_FFS_FILE_HEADER    **FfsFileHeaderPoint,
  OUT    VOID                   **Pe32Data
  );

//
// 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),
  &gPeiFvFileLoaderPpiGuid,
  &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),
  &gEndOfPeiSignalPpiGuid,
  NULL
};

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
  );

EFI_PEIM_ENTRY_POINT (PeimInitializeDxeIpl)

typedef
EFI_STATUS
(EFIAPI *DXE_IPL_ENTRYPOINT) (
  IN EFI_FFS_FILE_HEADER       * FfsHeader,
  IN EFI_PEI_SERVICES          **PeiServices
  );

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_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL  *PeiEfiPeiFlushInstructionCache;
  EFI_BOOT_MODE                             BootMode;
 
  Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
  ASSERT_PEI_ERROR (PeiServices, Status);

  Status = (*PeiServices)->LocatePpi (
                            PeiServices,
                            &gPeiInMemoryGuid,
                            0,
                            NULL,
                            NULL
                            );

  if (EFI_ERROR (Status) && (BootMode != BOOT_ON_S3_RESUME)) {   
    //
    // The DxeIpl has not yet been shadowed
    //
    InstallEfiPeiFlushInstructionCache (&PeiEfiPeiFlushInstructionCache);
    InstallEfiPeiPeCoffLoader (PeiServices, &PeiEfiPeiPeCoffLoader, NULL);

    //
    // Shadow DxeIpl and then re-run its entry point
    //
    Status = ShadowDxeIpl (
              PeiServices,
              FfsHeader,
              PeiEfiPeiPeCoffLoader,
              PeiEfiPeiFlushInstructionCache
              );

    if (EFI_ERROR (Status)) {
      return Status;
    }

  } else {  
    if (BootMode != BOOT_ON_S3_RESUME) {
      //
      // The DxeIpl has been shadowed
      //
      gPeiServices = PeiServices;

      //
      // Install LoadFile PPI
      //
      Status = (*PeiServices)->InstallPpi (PeiServices, &mPpiLoadFile);

      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
    
    //
    // Install DxeIpl PPI
    //
    (*PeiServices)->InstallPpi (PeiServices, &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;
  EFI_GUID                                  FirmwareFileName;
  VOID                                      *Pe32Data;
  VOID                                      *Interface;
  EFI_PHYSICAL_ADDRESS                      DxeCoreAddress;
  UINT64                                    DxeCoreSize;
  EFI_PHYSICAL_ADDRESS                      DxeCoreEntryPoint;
  EFI_DECOMPRESS_PROTOCOL                   *PeiEfiDecompress;
  EFI_TIANO_DECOMPRESS_PROTOCOL             *PeiEfiTianoDecompress;
  EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL        *PeiEfiCustomizedDecompress;
  EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL  *PeiEfiPeiFlushInstructionCache;
  EFI_PEI_PE_COFF_LOADER_PROTOCOL           *PeiEfiPeiPeCoffLoader;
  EFI_PEI_TRANSFER_CONTROL_PROTOCOL         *PeiEfiPeiTransferControl;
  EFI_BOOT_MODE                             BootMode;
  PEI_RECOVERY_MODULE_INTERFACE             *PeiRecovery;
  PEI_S3_RESUME_PPI                         *S3Resume;

  PEI_PERF_START (PeiServices, L"DxeIpl", NULL, 0);

  TopOfStack  = 0;
  BaseOfStack = 0;
  BspStore    = 0;

  //
  // if in S3 Resume, restore configure
  //
  Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);

  if (!EFI_ERROR (Status) && (BootMode == BOOT_ON_S3_RESUME)) {
    Status = (*PeiServices)->LocatePpi (
                              PeiServices,
                              &gPeiS3ResumePpiGuid,
                              0,
                              NULL,
                              &S3Resume
                              );

    ASSERT_PEI_ERROR (PeiServices, Status);

    Status = S3Resume->S3RestoreConfig (PeiServices);

    ASSERT_PEI_ERROR (PeiServices, Status);
  }

  Status = EFI_SUCCESS;

  //
  // Get the EFI decompress functions for possible usage
  //
  Status = InstallEfiDecompress (&PeiEfiDecompress);

  ASSERT_PEI_ERROR (PeiServices, Status);

  //
  // Get the Tiano decompress functions for possible usage
  //
  Status = InstallTianoDecompress (&PeiEfiTianoDecompress);

  ASSERT_PEI_ERROR (PeiServices, Status);

  //
  // Get the user Customized decompress functions for possible usage
  //
  Status = InstallCustomizedDecompress (&PeiEfiCustomizedDecompress);

  ASSERT_PEI_ERROR (PeiServices, Status);

  //
  // Install the PEI Protocols that are shared between PEI and DXE
  //
  PeiEfiPeiPeCoffLoader = NULL;
  Status                = InstallEfiPeiFlushInstructionCache (&PeiEfiPeiFlushInstructionCache);

  ASSERT_PEI_ERROR (PeiServices, Status);

  Status = InstallEfiPeiTransferControl (&PeiEfiPeiTransferControl);

  ASSERT_PEI_ERROR (PeiServices, Status);

  Status = InstallEfiPeiPeCoffLoader (PeiServices, &PeiEfiPeiPeCoffLoader, NULL);

  ASSERT_PEI_ERROR (PeiServices, Status);

  //
  // Allocate 128KB for the Stack
  //
  Status = (*PeiServices)->AllocatePages (
                            PeiServices,
                            EfiBootServicesData,
                            EFI_SIZE_TO_PAGES (EFI_STACK_SIZE),
                            &BaseOfStack
                            );

  ASSERT_PEI_ERROR (PeiServices, Status);
  //
  // Compute the top of the stack we were allocated. Pre-allocate a UINTN
  // for safety.
  //
  TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (EFI_STACK_SIZE) * EFI_PAGE_SIZE - sizeof (UINTN);
  //
  // Add architecture-specifc HOBs (including the BspStore HOB)
  //
  Status = CreateArchSpecificHobs (
            PeiServices,
            &BspStore
            );

  ASSERT_PEI_ERROR (PeiServices, Status);

  //
  // Add HOB for the EFI Decompress Protocol
  //
  Interface = (VOID *) PeiEfiDecompress;

  Status = PeiBuildHobGuidData (
            PeiServices,
            &mPeiEfiDecompressProtocolGuid,
            &Interface,
            sizeof (VOID *)
            );

  ASSERT_PEI_ERROR (PeiServices, Status);

  //
  // Add HOB for the Tiano Decompress Protocol
  //
  Interface = (VOID *) PeiEfiTianoDecompress;

  Status = PeiBuildHobGuidData (
            PeiServices,
            &mPeiEfiTianoDecompressProtocolGuid,
            &Interface,
            sizeof (VOID *)
            );

  ASSERT_PEI_ERROR (PeiServices, Status);

  //
  // Add HOB for the user customized Decompress Protocol
  //
  Interface = (VOID *) PeiEfiCustomizedDecompress;

  Status = PeiBuildHobGuidData (
            PeiServices,
            &mPeiEfiCustomizedDecompressProtocolGuid,
            &Interface,
            sizeof (VOID *)
            );

  ASSERT_PEI_ERROR (PeiServices, Status);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?