diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2018-09-14 20:55:36 +0200 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2019-04-14 18:37:33 -0700 |
commit | 095fcfc606bd6bffe20d926a1022aa0721ce9576 (patch) | |
tree | 1b486d426bf253799eb5cddc9280df5ca92518d1 | |
parent | 26d60374b87d7ed4b0ded88f95a3eb991680e134 (diff) | |
download | edk2-095fcfc606bd6bffe20d926a1022aa0721ce9576.zip edk2-095fcfc606bd6bffe20d926a1022aa0721ce9576.tar.gz edk2-095fcfc606bd6bffe20d926a1022aa0721ce9576.tar.bz2 |
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>
-rw-r--r-- | MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf | 3 | ||||
-rw-r--r-- | MdeModulePkg/Universal/EbcDxe/EbcDxe.inf | 3 | ||||
-rw-r--r-- | MdeModulePkg/Universal/EbcDxe/EbcInt.c | 121 | ||||
-rw-r--r-- | MdeModulePkg/Universal/EbcDxe/EbcInt.h | 3 |
4 files changed, 126 insertions, 4 deletions
diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf b/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf index 6e634e5..e942317 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 f1b740e..a38700d 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 a511e93..eced1d5 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 1cab76c..16f5ed4 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>
|