mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/EbcDxe: implement the PE/COFF emulator protocol
Implement the new EDK2 PE/COFF image emulator protocol so that we can remove the EBC specific handling in the DXE core and other places in the core code. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Hao Wu <hao.a.wu@intel.com>
This commit is contained in:
parent
26d60374b8
commit
095fcfc606
|
@ -84,6 +84,8 @@
|
|||
BaseMemoryLib
|
||||
DebugLib
|
||||
BaseLib
|
||||
CacheMaintenanceLib
|
||||
PeCoffLib
|
||||
|
||||
[Protocols]
|
||||
gEfiDebugSupportProtocolGuid ## PRODUCES
|
||||
|
@ -93,6 +95,7 @@
|
|||
gEfiEbcSimpleDebuggerProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiPciRootBridgeIoProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEdkiiPeCoffImageEmulatorProtocolGuid ## PRODUCES
|
||||
|
||||
[Guids]
|
||||
gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID
|
||||
|
|
|
@ -51,7 +51,9 @@
|
|||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
CacheMaintenanceLib
|
||||
MemoryAllocationLib
|
||||
PeCoffLib
|
||||
UefiBootServicesTableLib
|
||||
BaseMemoryLib
|
||||
UefiDriverEntryPoint
|
||||
|
@ -62,6 +64,7 @@
|
|||
[Protocols]
|
||||
gEfiDebugSupportProtocolGuid ## PRODUCES
|
||||
gEfiEbcProtocolGuid ## PRODUCES
|
||||
gEdkiiPeCoffImageEmulatorProtocolGuid ## PRODUCES
|
||||
gEfiEbcVmTestProtocolGuid ## SOMETIMES_PRODUCES
|
||||
gEfiEbcSimpleDebuggerProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
|
|
|
@ -343,6 +343,119 @@ UINTN mStackNum = 0;
|
|||
EFI_EVENT mEbcPeriodicEvent;
|
||||
VM_CONTEXT *mVmPtr = NULL;
|
||||
|
||||
/**
|
||||
Check whether the emulator supports executing a certain PE/COFF image
|
||||
|
||||
@param[in] This This pointer for EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL
|
||||
structure
|
||||
@param[in] ImageType Whether the image is an application, a boot time
|
||||
driver or a runtime driver.
|
||||
@param[in] DevicePath Path to device where the image originated
|
||||
(e.g., a PCI option ROM)
|
||||
|
||||
@retval TRUE The image is supported by the emulator
|
||||
@retval FALSE The image is not supported by the emulator.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
EbcIsImageSupported (
|
||||
IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This,
|
||||
IN UINT16 ImageType,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
if (ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION &&
|
||||
ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Register a supported PE/COFF image with the emulator. After this call
|
||||
completes successfully, the PE/COFF image may be started as usual, and
|
||||
it is the responsibility of the emulator implementation that any branch
|
||||
into the code section of the image (including returns from functions called
|
||||
from the foreign code) is executed as if it were running on the machine
|
||||
type it was built for.
|
||||
|
||||
@param[in] This This pointer for
|
||||
EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL structure
|
||||
@param[in] ImageBase The base address in memory of the PE/COFF image
|
||||
@param[in] ImageSize The size in memory of the PE/COFF image
|
||||
@param[in,out] EntryPoint The entry point of the PE/COFF image. Passed by
|
||||
reference so that the emulator may modify it.
|
||||
|
||||
@retval EFI_SUCCESS The image was registered with the emulator and
|
||||
can be started as usual.
|
||||
@retval other The image could not be registered.
|
||||
|
||||
If the PE/COFF machine type or image type are not supported by the emulator,
|
||||
then ASSERT().
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EbcRegisterImage (
|
||||
IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS ImageBase,
|
||||
IN UINT64 ImageSize,
|
||||
IN OUT EFI_IMAGE_ENTRY_POINT *EntryPoint
|
||||
)
|
||||
{
|
||||
DEBUG_CODE_BEGIN ();
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
EFI_STATUS Status;
|
||||
|
||||
ZeroMem (&ImageContext, sizeof (ImageContext));
|
||||
|
||||
ImageContext.Handle = (VOID *)(UINTN)ImageBase;
|
||||
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
|
||||
|
||||
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (ImageContext.Machine == EFI_IMAGE_MACHINE_EBC);
|
||||
ASSERT (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ||
|
||||
ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER);
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
EbcRegisterICacheFlush (NULL,
|
||||
(EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange);
|
||||
|
||||
return EbcCreateThunk (NULL, (VOID *)(UINTN)ImageBase,
|
||||
(VOID *)(UINTN)*EntryPoint, (VOID **)EntryPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
Unregister a PE/COFF image that has been registered with the emulator.
|
||||
This should be done before the image is unloaded from memory.
|
||||
|
||||
@param[in] This This pointer for EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL
|
||||
structure
|
||||
@param[in] ImageBase The base address in memory of the PE/COFF image
|
||||
|
||||
@retval EFI_SUCCESS The image was unregistered with the emulator.
|
||||
@retval other Image could not be unloaded.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EbcUnregisterImage (
|
||||
IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS ImageBase
|
||||
)
|
||||
{
|
||||
return EbcUnloadImage (NULL, (VOID *)(UINTN)ImageBase);
|
||||
}
|
||||
|
||||
STATIC EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL mPeCoffEmuProtocol = {
|
||||
EbcIsImageSupported,
|
||||
EbcRegisterImage,
|
||||
EbcUnregisterImage,
|
||||
EDKII_PECOFF_IMAGE_EMULATOR_VERSION,
|
||||
EFI_IMAGE_MACHINE_EBC
|
||||
};
|
||||
|
||||
/**
|
||||
Initializes the VM EFI interface. Allocates memory for the VM interface
|
||||
|
@ -431,11 +544,11 @@ InitializeEbcDriver (
|
|||
// Add the protocol so someone can locate us if we haven't already.
|
||||
//
|
||||
if (!Installed) {
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ImageHandle,
|
||||
&gEfiEbcProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
EbcProtocol
|
||||
&gEfiEbcProtocolGuid, EbcProtocol,
|
||||
&gEdkiiPeCoffImageEmulatorProtocolGuid, &mPeCoffEmuProtocol,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (EbcProtocol);
|
||||
|
|
|
@ -17,9 +17,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
#include <Protocol/Ebc.h>
|
||||
#include <Protocol/EbcVmTest.h>
|
||||
#include <Protocol/EbcSimpleDebugger.h>
|
||||
#include <Protocol/PeCoffImageEmulator.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PeCoffLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
|
Loading…
Reference in New Issue