summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal/EbcDxe/EbcInt.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Universal/EbcDxe/EbcInt.c')
-rw-r--r--MdeModulePkg/Universal/EbcDxe/EbcInt.c121
1 files changed, 117 insertions, 4 deletions
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);