summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal/EbcDxe
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2018-09-14 20:55:36 +0200
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2019-04-14 18:37:33 -0700
commit095fcfc606bd6bffe20d926a1022aa0721ce9576 (patch)
tree1b486d426bf253799eb5cddc9280df5ca92518d1 /MdeModulePkg/Universal/EbcDxe
parent26d60374b87d7ed4b0ded88f95a3eb991680e134 (diff)
downloadedk2-095fcfc606bd6bffe20d926a1022aa0721ce9576.tar.gz
edk2-095fcfc606bd6bffe20d926a1022aa0721ce9576.tar.bz2
edk2-095fcfc606bd6bffe20d926a1022aa0721ce9576.zip
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>
Diffstat (limited to 'MdeModulePkg/Universal/EbcDxe')
-rw-r--r--MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf3
-rw-r--r--MdeModulePkg/Universal/EbcDxe/EbcDxe.inf3
-rw-r--r--MdeModulePkg/Universal/EbcDxe/EbcInt.c121
-rw-r--r--MdeModulePkg/Universal/EbcDxe/EbcInt.h3
4 files changed, 126 insertions, 4 deletions
diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf b/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf
index 6e634e5ee9..e942317603 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf
+++ b/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf
@@ -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
diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
index f1b740e23f..a38700df56 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+++ b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
@@ -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
diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.c b/MdeModulePkg/Universal/EbcDxe/EbcInt.c
index a511e938e9..eced1d5c7f 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcInt.c
+++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.c
@@ -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);
diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.h b/MdeModulePkg/Universal/EbcDxe/EbcInt.h
index 1cab76c890..16f5ed4eb1 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcInt.h
+++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.h
@@ -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>