dxeloadx64.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,545 行 · 第 1/4 页
C
1,545 行
/*++
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"
#pragma warning( disable : 4305 )
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 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;
#define EFI_BREAK \
{ \
0x5B60CCFD, 0x1011, 0x4BCF, 0xb7, 0xd1, 0xbb, 0x99, 0xca, 0x96, 0xa6, 0x03 \
}
EFI_GUID mBreakGuid = EFI_BREAK;
//
// 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
);
VOID
EfiCommonLibZeroMem (
IN VOID *Buffer,
IN UINTN Size
);
EFI_STATUS
PeiFindFfs (
IN EFI_PEI_SERVICES **PeiServices,
IN UINT16 SectionType,
OUT EFI_GUID *FileName,
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;
VOID *DxeCorePe32Data;
EFI_PHYSICAL_ADDRESS DxeCoreAddress;
UINT64 DxeCoreSize;
EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint;
VOID *PpisNeededByDxePe32Data;
EFI_PHYSICAL_ADDRESS PpisNeededByDxeAddress;
UINT64 PpisNeededByDxeSize;
EFI_PHYSICAL_ADDRESS PpisNeededByDxeEntryPoint;
EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *PeiEfiPeiFlushInstructionCache;
EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;
EFI_BOOT_MODE BootMode;
PEI_RECOVERY_MODULE_INTERFACE *PeiRecovery;
PEI_S3_RESUME_PPI *S3Resume;
EFI_PHYSICAL_ADDRESS PageTables;
PEI_PERF_START (PeiServices, L"DxeIpl", NULL, 0);
TopOfStack = 0;
BaseOfStack = 0;
BspStore = 0;
Status = EFI_SUCCESS;
//
// 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);
}
//
// Install the PEI Protocols that are shared between PEI and DXE
//
PeiEfiPeiPeCoffLoader = NULL;
Status = InstallEfiPeiFlushInstructionCache (&PeiEfiPeiFlushInstructionCache);
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);
//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?