X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FEbcDxe%2FEbcInt.c;fp=MdeModulePkg%2FUniversal%2FEbcDxe%2FEbcInt.c;h=eced1d5c7f1e2a1639198061d375db261e4e5f45;hp=a511e938e95bd3b9705c84f4898593cb812d99d0;hb=095fcfc606bd6bffe20d926a1022aa0721ce9576;hpb=26d60374b87d7ed4b0ded88f95a3eb991680e134 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);