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.biesheu...@linaro.org>
Reviewed-by: Michael D Kinney <michael.d.kin...@intel.com>
---
 MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf |   3 +
 MdeModulePkg/Universal/EbcDxe/EbcDxe.inf      |   3 +
 MdeModulePkg/Universal/EbcDxe/EbcInt.c        | 121 +++++++++++++++++++-
 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 8f293f5c7c29..c7a9d519b080 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf
+++ b/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf
@@ -89,6 +89,8 @@
   BaseMemoryLib
   DebugLib
   BaseLib
+  CacheMaintenanceLib
+  PeCoffLib
 
 [Protocols]
   gEfiDebugSupportProtocolGuid                  ## PRODUCES
@@ -98,6 +100,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 d6ee6194a0c8..ecccf2c57ffe 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+++ b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
@@ -57,7 +57,9 @@
   MdeModulePkg/MdeModulePkg.dec
 
 [LibraryClasses]
+  CacheMaintenanceLib
   MemoryAllocationLib
+  PeCoffLib
   UefiBootServicesTableLib
   BaseMemoryLib
   UefiDriverEntryPoint
@@ -68,6 +70,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 727ba8bcae44..3376b5e45184 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcInt.c
+++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.c
@@ -349,6 +349,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
@@ -437,11 +550,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 8aa7a4abbd63..9b25e91f951c 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcInt.h
+++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.h
@@ -23,9 +23,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #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>
-- 
2.17.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#39011): https://edk2.groups.io/g/devel/message/39011
Mute This Topic: https://groups.io/mt/31133144/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to