From 57b90e8d759a01a2e8d371f27e88d8da10bf1b02 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Mon, 15 Aug 2016 12:27:54 +0200 Subject: [PATCH] vmm: experimental virtualbox 5 support The main feature for this version upgrade is the use of the instruction emulator (IEM) to speed up execution and less often the slow recompiler. issue #2059 --- .../lib/mk/spec/nova/virtualbox5-hwaccl.mk | 12 + repos/ports/lib/mk/virtualbox5-apiwrap.mk | 10 + repos/ports/lib/mk/virtualbox5-bios.mk | 37 + repos/ports/lib/mk/virtualbox5-common.inc | 104 ++ repos/ports/lib/mk/virtualbox5-devices.mk | 97 ++ repos/ports/lib/mk/virtualbox5-dis.mk | 19 + repos/ports/lib/mk/virtualbox5-drivers.mk | 28 + repos/ports/lib/mk/virtualbox5-liblzf.mk | 8 + repos/ports/lib/mk/virtualbox5-main.mk | 95 ++ repos/ports/lib/mk/virtualbox5-recompiler.mk | 29 + repos/ports/lib/mk/virtualbox5-runtime.mk | 172 +++ repos/ports/lib/mk/virtualbox5-storage.mk | 17 + repos/ports/lib/mk/virtualbox5-vmm.mk | 100 ++ repos/ports/lib/mk/virtualbox5-xml.mk | 23 + repos/ports/lib/mk/virtualbox5-zlib.mk | 7 + repos/ports/ports/virtualbox5.hash | 1 + repos/ports/ports/virtualbox5.port | 158 +++ repos/ports/run/vbox_auto_win7.run | 3 + repos/ports/run/vbox_auto_win7_share.run | 4 + repos/ports/run/vbox_auto_win7_vbox5.run | 21 + repos/ports/run/vbox_auto_win8.run | 3 + repos/ports/run/vbox_auto_win81_64.run | 3 + repos/ports/run/vbox_win.inc | 9 +- repos/ports/run/virtualbox_auto.inc | 8 +- repos/ports/src/virtualbox/devxhci.cc | 2 +- repos/ports/src/virtualbox/network.cpp | 1 + repos/ports/src/virtualbox5/dummies.cc | 169 +++ .../src/virtualbox5/frontend/ClientWatcher.h | 14 + .../src/virtualbox5/frontend/GenodeImpl.h | 10 + .../src/virtualbox5/frontend/VBoxEvents.h | 51 + .../src/virtualbox5/frontend/VirtualBoxBase.h | 468 +++++++ .../frontend/VirtualBoxErrorInfoImpl.cpp | 6 + .../frontend/VirtualBoxErrorInfoImpl.h | 49 + .../ports/src/virtualbox5/frontend/console.cc | 520 ++++++++ .../ports/src/virtualbox5/frontend/console.h | 234 ++++ .../virtualbox5/frontend/dummy/autostart.cc | 17 + .../virtualbox5/frontend/dummy/errorinfo.cc | 14 + .../src/virtualbox5/frontend/dummy/host.cc | 191 +++ .../src/virtualbox5/frontend/dummy/macros.h | 37 + .../src/virtualbox5/frontend/dummy/rest.cc | 127 ++ .../frontend/dummy/virtualboxbase.cc | 38 + repos/ports/src/virtualbox5/frontend/fb.h | 225 ++++ repos/ports/src/virtualbox5/frontend/main.cc | 256 ++++ repos/ports/src/virtualbox5/hm.cc | 208 ++++ repos/ports/src/virtualbox5/mm.cc | 474 ++++++++ repos/ports/src/virtualbox5/mm.h | 79 ++ repos/ports/src/virtualbox5/patches/dbg.patch | 51 + .../src/virtualbox5/patches/iem_wip.patch | 137 +++ repos/ports/src/virtualbox5/patches/series | 9 + .../src/virtualbox5/patches/tm_smp.patch | 35 + repos/ports/src/virtualbox5/patches/usb.patch | 118 ++ .../src/virtualbox5/patches/vbox_inc.patch | 47 + .../src/virtualbox5/patches/vbox_main.patch | 1079 +++++++++++++++++ .../src/virtualbox5/patches/vga_vbva.patch | 16 + repos/ports/src/virtualbox5/patches/vmm.patch | 17 + .../src/virtualbox5/patches/vmmdev.patch | 46 + repos/ports/src/virtualbox5/pgm.cc | 58 + repos/ports/src/virtualbox5/spec/nova/pgm.cc | 209 ++++ repos/ports/src/virtualbox5/spec/nova/sup.cc | 570 +++++++++ repos/ports/src/virtualbox5/spec/nova/svm.h | 112 ++ repos/ports/src/virtualbox5/spec/nova/vcpu.h | 868 +++++++++++++ .../src/virtualbox5/spec/nova/vcpu_svm.h | 141 +++ .../src/virtualbox5/spec/nova/vcpu_vmx.h | 274 +++++ repos/ports/src/virtualbox5/spec/nova/vmx.h | 129 ++ repos/ports/src/virtualbox5/sup.cc | 332 +++++ repos/ports/src/virtualbox5/sup.h | 45 + repos/ports/src/virtualbox5/target.mk | 68 ++ repos/ports/src/virtualbox5/unimpl.cc | 215 ++++ repos/ports/src/virtualbox5/util.h | 36 + tool/autopilot.list | 1 + 70 files changed, 8766 insertions(+), 5 deletions(-) create mode 100644 repos/ports/lib/mk/spec/nova/virtualbox5-hwaccl.mk create mode 100644 repos/ports/lib/mk/virtualbox5-apiwrap.mk create mode 100644 repos/ports/lib/mk/virtualbox5-bios.mk create mode 100644 repos/ports/lib/mk/virtualbox5-common.inc create mode 100644 repos/ports/lib/mk/virtualbox5-devices.mk create mode 100644 repos/ports/lib/mk/virtualbox5-dis.mk create mode 100644 repos/ports/lib/mk/virtualbox5-drivers.mk create mode 100644 repos/ports/lib/mk/virtualbox5-liblzf.mk create mode 100644 repos/ports/lib/mk/virtualbox5-main.mk create mode 100644 repos/ports/lib/mk/virtualbox5-recompiler.mk create mode 100644 repos/ports/lib/mk/virtualbox5-runtime.mk create mode 100644 repos/ports/lib/mk/virtualbox5-storage.mk create mode 100644 repos/ports/lib/mk/virtualbox5-vmm.mk create mode 100644 repos/ports/lib/mk/virtualbox5-xml.mk create mode 100644 repos/ports/lib/mk/virtualbox5-zlib.mk create mode 100644 repos/ports/ports/virtualbox5.hash create mode 100644 repos/ports/ports/virtualbox5.port create mode 100644 repos/ports/run/vbox_auto_win7_vbox5.run create mode 100644 repos/ports/src/virtualbox5/dummies.cc create mode 100644 repos/ports/src/virtualbox5/frontend/ClientWatcher.h create mode 100644 repos/ports/src/virtualbox5/frontend/GenodeImpl.h create mode 100644 repos/ports/src/virtualbox5/frontend/VBoxEvents.h create mode 100644 repos/ports/src/virtualbox5/frontend/VirtualBoxBase.h create mode 100644 repos/ports/src/virtualbox5/frontend/VirtualBoxErrorInfoImpl.cpp create mode 100644 repos/ports/src/virtualbox5/frontend/VirtualBoxErrorInfoImpl.h create mode 100644 repos/ports/src/virtualbox5/frontend/console.cc create mode 100644 repos/ports/src/virtualbox5/frontend/console.h create mode 100644 repos/ports/src/virtualbox5/frontend/dummy/autostart.cc create mode 100644 repos/ports/src/virtualbox5/frontend/dummy/errorinfo.cc create mode 100644 repos/ports/src/virtualbox5/frontend/dummy/host.cc create mode 100644 repos/ports/src/virtualbox5/frontend/dummy/macros.h create mode 100644 repos/ports/src/virtualbox5/frontend/dummy/rest.cc create mode 100644 repos/ports/src/virtualbox5/frontend/dummy/virtualboxbase.cc create mode 100644 repos/ports/src/virtualbox5/frontend/fb.h create mode 100644 repos/ports/src/virtualbox5/frontend/main.cc create mode 100644 repos/ports/src/virtualbox5/hm.cc create mode 100644 repos/ports/src/virtualbox5/mm.cc create mode 100644 repos/ports/src/virtualbox5/mm.h create mode 100644 repos/ports/src/virtualbox5/patches/dbg.patch create mode 100644 repos/ports/src/virtualbox5/patches/iem_wip.patch create mode 100644 repos/ports/src/virtualbox5/patches/series create mode 100644 repos/ports/src/virtualbox5/patches/tm_smp.patch create mode 100644 repos/ports/src/virtualbox5/patches/usb.patch create mode 100644 repos/ports/src/virtualbox5/patches/vbox_inc.patch create mode 100644 repos/ports/src/virtualbox5/patches/vbox_main.patch create mode 100644 repos/ports/src/virtualbox5/patches/vga_vbva.patch create mode 100644 repos/ports/src/virtualbox5/patches/vmm.patch create mode 100644 repos/ports/src/virtualbox5/patches/vmmdev.patch create mode 100644 repos/ports/src/virtualbox5/pgm.cc create mode 100644 repos/ports/src/virtualbox5/spec/nova/pgm.cc create mode 100644 repos/ports/src/virtualbox5/spec/nova/sup.cc create mode 100644 repos/ports/src/virtualbox5/spec/nova/svm.h create mode 100644 repos/ports/src/virtualbox5/spec/nova/vcpu.h create mode 100644 repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h create mode 100644 repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h create mode 100644 repos/ports/src/virtualbox5/spec/nova/vmx.h create mode 100644 repos/ports/src/virtualbox5/sup.cc create mode 100644 repos/ports/src/virtualbox5/sup.h create mode 100644 repos/ports/src/virtualbox5/target.mk create mode 100644 repos/ports/src/virtualbox5/unimpl.cc create mode 100644 repos/ports/src/virtualbox5/util.h diff --git a/repos/ports/lib/mk/spec/nova/virtualbox5-hwaccl.mk b/repos/ports/lib/mk/spec/nova/virtualbox5-hwaccl.mk new file mode 100644 index 0000000000..356af712aa --- /dev/null +++ b/repos/ports/lib/mk/spec/nova/virtualbox5-hwaccl.mk @@ -0,0 +1,12 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +SRC_CC = sup.cc pgm.cc + +INC_DIR += $(call select_from_repositories,src/lib/libc) +INC_DIR += $(call select_from_repositories,src/lib/pthread) + +INC_DIR += $(VBOX_DIR)/VMM/include +INC_DIR += $(REP_DIR)/src/virtualbox5 + +vpath sup.cc $(REP_DIR)/src/virtualbox5/spec/nova/ +vpath pgm.cc $(REP_DIR)/src/virtualbox5/spec/nova/ diff --git a/repos/ports/lib/mk/virtualbox5-apiwrap.mk b/repos/ports/lib/mk/virtualbox5-apiwrap.mk new file mode 100644 index 0000000000..2d45cac45e --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-apiwrap.mk @@ -0,0 +1,10 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +LIBS += stdcxx + +SRC_CC += $(addprefix VBoxAPIWrap/, $(notdir $(wildcard $(VIRTUALBOX_DIR)/VBoxAPIWrap/*.cpp))) + +INC_DIR += $(REP_DIR)/src/virtualbox5/frontend +INC_DIR += $(VBOX_DIR)/Main/include + +vpath %.cpp $(VIRTUALBOX_DIR) diff --git a/repos/ports/lib/mk/virtualbox5-bios.mk b/repos/ports/lib/mk/virtualbox5-bios.mk new file mode 100644 index 0000000000..585304944b --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-bios.mk @@ -0,0 +1,37 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +ifeq ($(shell which yasm),) +REQUIRES += installation_of_yasm +endif + +SRC_O += VBoxPcBiosBin.o VBoxVgaBiosBin.o VBoxBiosLogoBin.o + +VBox%Bin.o : VBox%Bin.rom + $(MSG_CONVERT)$@ + $(VERBOSE)echo ".global g_ab$*Binary, g_cb$*Binary;" \ + ".data;" \ + "g_cb$*Binary:; .long g_ab$*BinaryEnd - g_ab$*Binary;" \ + ".align 4096;" \ + "g_ab$*Binary:; .incbin \"$<\";" \ + "g_ab$*BinaryEnd:;" | \ + $(AS) $(AS_OPT) -f -o $@ - + +VBoxPcBiosBin.rom: Devices/PC/BIOS/VBoxBiosAlternative.asm + $(MSG_ASSEM) + $(VERBOSE)yasm -f bin -o $@ $< + +VBoxVgaBiosBin.rom: Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm + $(MSG_ASSEM) + $(VERBOSE)yasm -f bin -o $@ $< + +VBoxBiosLogoBin.o: Devices/Graphics/BIOS/ose_logo.bmp + $(MSG_CONVERT)$@ + $(VERBOSE)echo ".global g_abVgaDefBiosLogo, g_cbVgaDefBiosLogo;" \ + ".data;" \ + "g_cbVgaDefBiosLogo:; .long g_abVgaDefBiosLogoEnd - g_abVgaDefBiosLogo;" \ + ".align 4096;" \ + "g_abVgaDefBiosLogo:; .incbin \"$<\";" \ + "g_abVgaDefBiosLogoEnd:;" | \ + $(AS) $(AS_OPT) -f -o $@ - + +vpath %.bmp $(VBOX_DIR) diff --git a/repos/ports/lib/mk/virtualbox5-common.inc b/repos/ports/lib/mk/virtualbox5-common.inc new file mode 100644 index 0000000000..0655da5ae7 --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-common.inc @@ -0,0 +1,104 @@ +VBOX_MACH := $(filter $(SPECS), x86_32 x86_64) + +VBOX_MACH_CC_OPT_x86_32 = -DRT_ARCH_X86 -D__X86__ +VBOX_MACH_ASM_OPT_x86_32 = -f elf32 +VBOX_MACH_CC_OPT_x86_64 = -DRT_ARCH_AMD64 -D__AMD64__ +VBOX_MACH_ASM_OPT_x86_64 = -f elf64 + +ifeq ($(shell which yasm),) +REQUIRES += installation_of_yasm +REQUIRES += installation_of_iasl +endif + +VIRTUALBOX_DIR = $(call select_from_ports,virtualbox5)/src/app/virtualbox +VIRTUALBOX_SDK_DIR = $(call select_from_ports,virtualbox5)/src/app/virtualbox_sdk + +VBOX_DIR = $(VIRTUALBOX_DIR)/src/VBox + +VBOX_CC_OPT += -DIN_RING3 -DVBOX -DVBOX_OSE \ + -D_FILE_OFFSET_BITS=64 -DLOG_ENABLED + +VBOX_CC_OPT += $(VBOX_MACH_CC_OPT_$(VBOX_MACH)) + +VBOX_CC_OPT += -DVBOX_WITH_64_BITS_GUESTS +VBOX_CC_OPT += -DVBOX_WITH_NEW_MSR_CODE + +VBOX_CC_OPT += -DIN_SUP_R3 -DIN_VMM_R3 + +# we use the libc headers from FreeBSD +VBOX_CC_OPT += -DRT_OS_FREEBSD + +VBOX_CC_OPT += -DVBOX_WITH_REM +VBOX_CC_OPT += -DVBOX_WITH_2ND_IEM_STEP + +VBOX_CC_OPT += -DVBOX_WITH_HGCM -DVBOX_WITH_HGSMI + +VBOX_CC_OPT += -DVBOX_WITHOUT_TESTING_FEATURES + +VBOX_CC_OPT += -DVBOX_WITH_VIDEOHWACCEL + +VBOX_CC_OPT += -DVBOX_WITH_XPCOM + +VBOX_CC_OPT += -DRTLOG_REL_ENABLED -DRT_STRICT -DVBOX_STRICT + +VBOX_CC_OPT += -DVBOX_WITH_USB -DVBOX_WITH_VUSB + +# Enable Intel Network model E1000 +VBOX_CC_OPT += -DVBOX_WITH_E1000 + +VBOX_CC_OPT += -DVBOX_WITH_AHCI + +VIRTUALBOX_VERSION_MAJOR := $(shell cat $(VIRTUALBOX_DIR)/Config.kmk | grep "VBOX_VERSION_MAJOR = " | grep -v "'VBOX_VERSION_MAJOR" | sed "s/^.*= //") +VIRTUALBOX_VERSION_MINOR := $(shell cat $(VIRTUALBOX_DIR)/Config.kmk | grep "VBOX_VERSION_MINOR = " | grep -v "'VBOX_VERSION_MINOR" | sed "s/^.*= //") +VIRTUALBOX_VERSION_BUILD := $(shell cat $(VIRTUALBOX_DIR)/Config.kmk | grep "VBOX_VERSION_BUILD = " | grep -v "'VBOX_VERSION_BUILD" | sed "s/^.*= //") + +ifeq ($(VBOX_MACH),x86_32) +VIRTUALBOX_PACKAGE_STRING = GenodeOS_32BIT_GENERIC +else +VIRTUALBOX_PACKAGE_STRING = GenodeOS_64BIT_GENERIC +endif + +VBOX_CC_OPT += -DVBOX_VERSION_MAJOR=$(VIRTUALBOX_VERSION_MAJOR) \ + -DVBOX_VERSION_MINOR=$(VIRTUALBOX_VERSION_MINOR) \ + -DVBOX_VERSION_BUILD=$(VIRTUALBOX_VERSION_BUILD) \ + -DVBOX_VERSION_STRING=\"$(VIRTUALBOX_VERSION_MAJOR).$(VIRTUALBOX_VERSION_MINOR).$(VIRTUALBOX_VERSION_BUILD)_OSE\" \ + -DVBOX_PACKAGE_STRING=\"$(VIRTUALBOX_PACKAGE_STRING)\" \ + -DVBOX_API_VERSION_STRING=\"$(VIRTUALBOX_VERSION_MAJOR)_$(VIRTUALBOX_VERSION_MINOR)\" \ + -DIPRT_BLDCFG_VERSION_STRING=\"$(VIRTUALBOX_VERSION_MAJOR).$(VIRTUALBOX_VERSION_MINOR).$(VIRTUALBOX_VERSION_BUILD)_OSE\" \ + -DIPRT_BLDCFG_TARGET=\"genode\" \ + -DIPRT_BLDCFG_TARGET_ARCH=\"$(VBOX_MACH)\" \ + -DVBOX_BUILD_SERVER_BUILD + +VBOX_CC_OPT += -DVBOX_WITH_WDDM -DVBOX_WITH_WDDM_W8 -DVBOXWDDM_WITH_VBVA +VBOX_CC_OPT += -DVBOX_WITH_VDMA +VBOX_CC_OPT += -DVBOX_WITH_VMSVGA + + +VBOX_CC_OPT += -DVBOX_HDD_NO_DYNAMIC_BACKENDS + +CC_WARN += -Wno-trigraphs + +CC_OPT += $(VBOX_CC_OPT) + +# VirtualBox expects wchar_t to be a 16-bit type. yasm does not understand this +# flag, therefore it gets added to CC_OPT instead of VBOX_CC_OPT. +CC_OPT += -fshort-wchar + +LIBS += libc libm + +INC_DIR += $(REP_DIR)/src/virtualbox/include +INC_DIR += $(REP_DIR)/src/virtualbox/include/xpcom +INC_DIR += $(VIRTUALBOX_DIR)/include +INC_DIR += $(VIRTUALBOX_SDK_DIR)/sdk/bindings/xpcom/include +INC_DIR += $(VBOX_DIR)/Devices/build + +vpath %.cpp $(VBOX_DIR) +vpath %.c $(VBOX_DIR) +vpath %.asm $(VBOX_DIR) + +%.o: %.asm + $(MSG_ASSEM)$@ + $(VERBOSE)yasm $(VBOX_MACH_ASM_OPT_$(VBOX_MACH)) -DASM_FORMAT_ELF -D__YASM__ \ + $(addprefix -I,$(INC_DIR)) $(VBOX_CC_OPT) -o $@ $< + +# vi: set ft=make : diff --git a/repos/ports/lib/mk/virtualbox5-devices.mk b/repos/ports/lib/mk/virtualbox5-devices.mk new file mode 100644 index 0000000000..d74100a413 --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-devices.mk @@ -0,0 +1,97 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +SRC_CC += Devices/PC/DevFwCommon.cpp +SRC_CC += Devices/PC/DevPcBios.cpp +SRC_CC += Devices/Bus/DevPCI.cpp +SRC_CC += Devices/PC/DevACPI.cpp +SRC_CC += Devices/PC/ACPI/VBoxAcpi.cpp +SRC_C += Devices/PC/DevPcArch.c +SRC_CC += Devices/Input/DevPS2.cpp +SRC_CC += Devices/Input/PS2K.cpp +SRC_CC += Devices/PC/DevPit-i8254.cpp +SRC_CC += Devices/PC/DevPIC.cpp +SRC_CC += Devices/PC/DevRTC.cpp +SRC_CC += Devices/PC/DevDMA.cpp +SRC_CC += Devices/PC/DevAPIC.cpp +SRC_CC += Devices/Graphics/DevVGA.cpp +SRC_CC += Devices/Graphics/DevVGA_VBVA.cpp +SRC_CC += Devices/Graphics/DevVGA_VDMA.cpp +SRC_CC += Devices/Graphics/DevVGA-SVGA.cpp +SRC_CC += Devices/Graphics/HGSMI/HGSMIHost.cpp +SRC_CC += Devices/Graphics/HGSMI/SHGSMIHost.cpp +SRC_CC += Devices/Storage/ATAPIPassthrough.cpp +SRC_CC += Devices/Storage/DevAHCI.cpp +SRC_CC += Devices/Storage/DevATA.cpp +SRC_CC += Devices/Storage/Debug.cpp +SRC_CC += Devices/Storage/DevFdc.c +SRC_CC += Devices/Network/DevE1000.cpp +SRC_CC += Devices/Network/DevE1000Phy.cpp +SRC_CC += Devices/Network/DevEEPROM.cpp +SRC_CC += Devices/Network/DevPCNet.cpp +SRC_CC += Devices/VMMDev/VMMDev.cpp +SRC_CC += Devices/VMMDev/VMMDevHGCM.cpp +SRC_CC += Devices/Serial/DevSerial.cpp +SRC_CC += Devices/PC/DevIoApic.cpp + +SRC_CC += Devices/Audio/AudioMixBuffer.cpp +SRC_CC += Devices/Audio/AudioMixer.cpp +SRC_CC += Devices/Audio/DevIchAc97.cpp +SRC_CC += Devices/Audio/DevIchHda.cpp +SRC_CC += Devices/Audio/DevIchHdaCodec.cpp +SRC_CC += Devices/Audio/DrvAudioCommon.cpp +SRC_CC += Devices/USB/DevOHCI.cpp +SRC_CC += Devices/USB/USBProxyDevice.cpp +SRC_CC += Devices/USB/VUSBDevice.cpp +SRC_CC += Devices/USB/VUSBReadAhead.cpp +SRC_CC += Devices/USB/VUSBSniffer.cpp +SRC_CC += Devices/USB/VUSBUrb.cpp +SRC_CC += Devices/Input/UsbMouse.cpp +SRC_CC += Devices/Input/UsbKbd.cpp + +SRC_CC += Devices/build/VBoxDD.cpp + +SRC_CC += devxhci.cc +vpath devxhci.cc $(REP_DIR)/src/virtualbox + +SRC_CC += GuestHost/HGSMI/HGSMICommon.cpp +SRC_CC += GuestHost/HGSMI/HGSMIMemAlloc.cpp + +INC_DIR += $(VBOX_DIR)/Devices/build +INC_DIR += $(VBOX_DIR)/Devices/Bus + +CC_WARN += -Wno-unused-but-set-variable + +# found in src/VBox/Devices/Makefile.kmk +CC_OPT += -DVBOX_HGCM_HOST_CODE + +Devices/Graphics/DevVGA.o: vbetables.h + +vbetables.h: vbetables-gen + $(MSG_CONVERT)$@ + $(VERBOSE)./$^ > $@ + +vbetables-gen: Devices/Graphics/BIOS/vbetables-gen.c + $(MSG_BUILD)$@ + $(VERBOSE)gcc $(VBOX_CC_OPT) $(addprefix -I,$(INC_DIR)) -o $@ $^ + +Devices/PC/ACPI/VBoxAcpi.o: vboxaml.hex vboxssdt-standard.hex vboxssdt-cpuhotplug.hex + +vboxaml.hex: vbox.dsl + iasl -tc -vs -p $@ $^ + +vboxssdt-standard.hex: vbox-standard.dsl + iasl -tc -vs -p $@ $^ && \ + mv $@ $@.tmp && \ + sed "s/AmlCode/AmlCodeSsdtStandard/g" <$@.tmp >$@ && \ + rm $@.tmp + +vboxssdt-cpuhotplug.hex: vbox-cpuhotplug.dsl + gcc -E -P -x c -o $@.pre $< && \ + sed "s//\n/g" <$@.pre >$@.pre1 && \ + iasl -tc -vs -p $@ $@.pre1 && \ + mv $@ $@.tmp && \ + sed "s/AmlCode/AmlCodeSsdtCpuHotPlug/g" <$@.tmp >$@ && \ + rm $@.tmp $@.pre $@.pre1 + +vpath %.dsl $(VBOX_DIR)/Devices/PC +vpath %.cc $(REP_DIR)/src/virtualbox diff --git a/repos/ports/lib/mk/virtualbox5-dis.mk b/repos/ports/lib/mk/virtualbox5-dis.mk new file mode 100644 index 0000000000..991f6e2f0c --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-dis.mk @@ -0,0 +1,19 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +SRC_CC += VMM/VMMR3/CPUMDbg.cpp +SRC_CC += VMM/VMMR3/DBGF.cpp +SRC_CC += VMM/VMMR3/DBGFAddr.cpp +SRC_CC += VMM/VMMR3/DBGFDisas.cpp +SRC_CC += VMM/VMMR3/DBGFR3Trace.cpp +SRC_CC += VMM/VMMR3/DBGFReg.cpp + +SRC_CC += Disassembler/DisasmCore.cpp +SRC_CC += Disassembler/DisasmTables.cpp +SRC_CC += Disassembler/DisasmReg.cpp +SRC_CC += Disassembler/DisasmTablesX64.cpp +SRC_CC += Disassembler/DisasmFormatYasm.cpp +SRC_CC += Disassembler/DisasmFormatBytes.cpp + +INC_DIR += $(VBOX_DIR)/VMM/include + +CC_OPT += -DVBOX_IN_VMM diff --git a/repos/ports/lib/mk/virtualbox5-drivers.mk b/repos/ports/lib/mk/virtualbox5-drivers.mk new file mode 100644 index 0000000000..6731bb6a89 --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-drivers.mk @@ -0,0 +1,28 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +# +# Prevent inclusion of the Genode::Log definition after the vbox #define +# of 'Log'. Otherwise, the attempt to compile base/log.h will fail. +# +VBOX_CC_OPT += -include base/log.h + +SRC_CC += Devices/Input/DrvKeyboardQueue.cpp +SRC_CC += Devices/Input/DrvMouseQueue.cpp +SRC_CC += Devices/USB/DrvVUSBRootHub.cpp +SRC_CC += Devices/Storage/DrvBlock.cpp +SRC_CC += Devices/Storage/DrvMediaISO.cpp +SRC_CC += Devices/Storage/DrvVD.cpp +SRC_CC += Devices/Storage/DrvRawImage.cpp +SRC_CC += Devices/PC/DrvACPI.cpp +SRC_CC += Devices/Serial/DrvChar.cpp +SRC_CC += Devices/Serial/DrvRawFile.cpp +SRC_CC += Devices/Serial/DrvHostSerial.cpp +SRC_CC += Devices/Audio/DrvAudio.cpp + +#SRC_CC += audiodrv.cpp +SRC_CC += network.cpp + +INC_DIR += $(VBOX_DIR)/Devices/Audio + +#vpath audiodrv.cpp $(REP_DIR)/src/virtualbox +vpath network.cpp $(REP_DIR)/src/virtualbox diff --git a/repos/ports/lib/mk/virtualbox5-liblzf.mk b/repos/ports/lib/mk/virtualbox5-liblzf.mk new file mode 100644 index 0000000000..d9788df57f --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-liblzf.mk @@ -0,0 +1,8 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +LIBLZF_DIR = $(VIRTUALBOX_DIR)/src/libs/liblzf-3.4 +INC_DIR += $(LIBLZF_DIR) +CC_OPT += -DULTRA_FAST=1 -DHLOG=12 -DSTRICT_ALIGN=0 -DPIC +SRC_C = lzf_c.c lzf_d.c + +vpath % $(LIBLZF_DIR) diff --git a/repos/ports/lib/mk/virtualbox5-main.mk b/repos/ports/lib/mk/virtualbox5-main.mk new file mode 100644 index 0000000000..fac4c9efb0 --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-main.mk @@ -0,0 +1,95 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +VBOX_CC_OPT += -DVBOX_WITH_GENERIC_SESSION_WATCHER + +# +# Prevent inclusion of the Genode::Log definition after the vbox #define +# of 'Log'. Otherwise, the attemt to compile base/log.h will fail. +# +VBOX_CC_OPT += -include base/log.h + +LIBS += stdcxx + +SRC_CC += Main/xml/Settings.cpp + +SRC_CC += Main/src-all/AuthLibrary.cpp +SRC_CC += Main/src-all/AutoCaller.cpp +SRC_CC += Main/src-all/EventImpl.cpp +SRC_CC += Main/src-all/DisplayResampleImage.cpp +SRC_CC += Main/src-all/DisplayUtils.cpp +SRC_CC += Main/src-all/Global.cpp +SRC_CC += Main/src-all/HashedPw.cpp +SRC_CC += Main/src-all/PCIDeviceAttachmentImpl.cpp +SRC_CC += Main/src-all/ProgressImpl.cpp +SRC_CC += Main/src-all/SecretKeyStore.cpp +SRC_CC += Main/src-all/SharedFolderImpl.cpp +SRC_CC += Main/src-all/VirtualBoxBase.cpp + +SRC_CC += Main/src-client/AdditionsFacilityImpl.cpp +SRC_CC += Main/src-client/BusAssignmentManager.cpp +SRC_CC += Main/src-client/ConsoleImpl.cpp +SRC_CC += Main/src-client/ConsoleImpl2.cpp +SRC_CC += Main/src-client/ConsoleVRDPServer.cpp +SRC_CC += Main/src-client/DisplaySourceBitmapImpl.cpp +SRC_CC += Main/src-client/DisplayImpl.cpp +SRC_CC += Main/src-client/DisplayImplLegacy.cpp +SRC_CC += Main/src-client/DrvAudioVRDE.cpp +SRC_CC += Main/src-client/EmulatedUSBImpl.cpp +SRC_CC += Main/src-client/GuestImpl.cpp +SRC_CC += Main/src-client/GuestCtrlImpl.cpp +SRC_CC += Main/src-client/HGCM.cpp +SRC_CC += Main/src-client/HGCMObjects.cpp +SRC_CC += Main/src-client/HGCMThread.cpp +SRC_CC += Main/src-client/KeyboardImpl.cpp +SRC_CC += Main/src-client/MachineDebuggerImpl.cpp +SRC_CC += Main/src-client/MouseImpl.cpp +SRC_CC += Main/src-client/RemoteUSBBackend.cpp +SRC_CC += Main/src-client/RemoteUSBDeviceImpl.cpp +SRC_CC += Main/src-client/SessionImpl.cpp +SRC_CC += Main/src-client/UsbWebcamInterface.cpp +SRC_CC += Main/src-client/VBoxDriversRegister.cpp +SRC_CC += Main/src-client/VMMDevInterface.cpp +SRC_CC += Main/src-client/USBDeviceImpl.cpp + +SRC_CC += Main/src-server/AudioAdapterImpl.cpp +SRC_CC += Main/src-server/BandwidthControlImpl.cpp +SRC_CC += Main/src-server/BandwidthGroupImpl.cpp +SRC_CC += Main/src-server/BIOSSettingsImpl.cpp +SRC_CC += Main/src-server/ClientToken.cpp +SRC_CC += Main/src-server/DHCPServerImpl.cpp +SRC_CC += Main/src-server/GuestOSTypeImpl.cpp +SRC_CC += Main/src-server/MachineImpl.cpp +SRC_CC += Main/src-server/MachineImplCloneVM.cpp +SRC_CC += Main/src-server/Matching.cpp +SRC_CC += Main/src-server/MediumAttachmentImpl.cpp +SRC_CC += Main/src-server/MediumImpl.cpp +SRC_CC += Main/src-server/MediumFormatImpl.cpp +SRC_CC += Main/src-server/MediumLock.cpp +SRC_CC += Main/src-server/NATEngineImpl.cpp +SRC_CC += Main/src-server/NATNetworkImpl.cpp +SRC_CC += Main/src-server/NetworkAdapterImpl.cpp +SRC_CC += Main/src-server/NetworkServiceRunner.cpp +SRC_CC += Main/src-server/ParallelPortImpl.cpp +SRC_CC += Main/src-server/SerialPortImpl.cpp +SRC_CC += Main/src-server/SnapshotImpl.cpp +SRC_CC += Main/src-server/StorageControllerImpl.cpp +SRC_CC += Main/src-server/SystemPropertiesImpl.cpp +SRC_CC += Main/src-server/TokenImpl.cpp +SRC_CC += Main/src-server/USBControllerImpl.cpp +SRC_CC += Main/src-server/USBDeviceFilterImpl.cpp +SRC_CC += Main/src-server/USBDeviceFiltersImpl.cpp +SRC_CC += Main/src-server/VirtualBoxImpl.cpp +SRC_CC += Main/src-server/VRDEServerImpl.cpp + +SRC_CC += Main/glue/AutoLock.cpp +SRC_CC += Main/glue/EventQueue.cpp +SRC_CC += Main/glue/string.cpp +SRC_CC += Main/glue/xpcom/helpers.cpp + +INC_DIR += $(VBOX_DIR)/Main/xml +INC_DIR += $(VBOX_DIR)/Main/include +INC_DIR += $(REP_DIR)/src/virtualbox5/frontend +INC_DIR += $(VIRTUALBOX_DIR)/VBoxAPIWrap + +# search path to 'scan_code_set_2.h' +INC_DIR += $(call select_from_repositories,src/drivers/input/spec/ps2) diff --git a/repos/ports/lib/mk/virtualbox5-recompiler.mk b/repos/ports/lib/mk/virtualbox5-recompiler.mk new file mode 100644 index 0000000000..7227ea2a7c --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-recompiler.mk @@ -0,0 +1,29 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +RECOMPILER_DIR = $(VIRTUALBOX_DIR)/src/recompiler + +RECOMPILER_SRC_C = cpu-exec.c cutils.c exec.c host-utils.c tcg-runtime.c \ + translate-all.c VBoxRecompiler.c \ + tcg/tcg-dyngen.c tcg/tcg.c \ + fpu/softfloat-native.c \ + target-i386/helper.c target-i386/op_helper.c \ + target-i386/translate.c + +SRC_C = $(addprefix recompiler/,$(RECOMPILER_SRC_C)) + +INC_DIR += $(VBOX_DIR)/VMM/include +INC_DIR += $(RECOMPILER_DIR)/Sun/crt +INC_DIR += $(RECOMPILER_DIR)/Sun +INC_DIR += $(RECOMPILER_DIR)/target-i386 +INC_DIR += $(RECOMPILER_DIR)/tcg +INC_DIR += $(RECOMPILER_DIR)/tcg/i386 +INC_DIR += $(RECOMPILER_DIR)/fpu +INC_DIR += $(RECOMPILER_DIR) + +CC_OPT += -DIN_REM_R3 \ + -DREM_INCLUDE_CPU_H -DNEED_CPU_H -DLOG_USE_C99 -D_GNU_SOURCE + +CC_WARN += -Wno-unused-but-set-variable] + +vpath %.cpp $(VIRTUALBOX_DIR)/src +vpath %.c $(VIRTUALBOX_DIR)/src diff --git a/repos/ports/lib/mk/virtualbox5-runtime.mk b/repos/ports/lib/mk/virtualbox5-runtime.mk new file mode 100644 index 0000000000..7c82683ae1 --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-runtime.mk @@ -0,0 +1,172 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +INC_DIR += $(VBOX_DIR)/Runtime/include + +INC_DIR += $(VIRTUALBOX_DIR)/src/libs/liblzf-3.4 +INC_DIR += $(VIRTUALBOX_DIR)/src/libs/zlib-1.2.8 +INC_DIR += $(call select_from_ports,libiconv)/include/iconv + +GENERIC_SRC_CC = $(notdir $(wildcard $(VBOX_DIR)/Runtime/generic/*.cpp)) + +FILTERED_OUT_SRC_CC = fs-stubs-generic.cpp \ + http-curl.cpp \ + semrw-lockless-generic.cpp \ + tls-generic.cpp \ + RTDirExists-generic.cpp \ + RTFileExists-generic.cpp \ + RTLogDefaultInit-generic.cpp \ + RTLogWriteStdErr-generic.cpp \ + RTLogWriteStdOut-generic.cpp \ + RTMpGetDescription-generic-stub.cpp \ + RTMpOnPair-generic.cpp \ + RTSemEventWait-2-ex-generic.cpp \ + RTSemEventWait-generic.cpp \ + RTSemEventWaitNoResume-2-ex-generic.cpp \ + RTSemEventMultiWait-2-ex-generic.cpp \ + RTSemMutexRequest-generic.cpp \ + RTSemMutexRequestDebug-generic.cpp \ + RTTimeLocalExplode-generic.cpp + +CC_WARN += -Wno-unused-variable + +SRC_CC += Runtime/common/log/logrel.cpp \ + Runtime/r3/init.cpp \ + Runtime/common/misc/thread.cpp \ + $(addprefix Runtime/generic/,$(filter-out $(FILTERED_OUT_SRC_CC), $(GENERIC_SRC_CC))) + +SRC_CC += Runtime/common/alloc/memcache.cpp +SRC_CC += Runtime/common/alloc/heapoffset.cpp +SRC_CC += Runtime/common/checksum/alt-md5.cpp +SRC_CC += Runtime/common/checksum/alt-sha512.cpp +SRC_CC += Runtime/common/checksum/crc32.cpp +SRC_CC += Runtime/common/checksum/crc32c.cpp +SRC_CC += Runtime/common/checksum/ipv4.cpp +SRC_CC += Runtime/common/checksum/sha512str.cpp +SRC_CC += Runtime/common/err/errmsgxpcom.cpp +SRC_CC += Runtime/common/err/RTErrConvertFromErrno.cpp +SRC_CC += Runtime/common/log/log.cpp +SRC_CC += Runtime/common/log/log.cpp +SRC_CC += Runtime/common/log/logellipsis.cpp +SRC_CC += Runtime/common/log/logrelellipsis.cpp +SRC_CC += Runtime/common/log/logformat.cpp +SRC_CC += Runtime/common/misc/assert.cpp +SRC_CC += Runtime/common/misc/buildconfig.cpp +SRC_CC += Runtime/common/misc/cidr.cpp +SRC_CC += Runtime/common/misc/lockvalidator.cpp +SRC_CC += Runtime/common/misc/once.cpp +SRC_CC += Runtime/common/misc/req.cpp +SRC_CC += Runtime/common/misc/reqpool.cpp +SRC_CC += Runtime/common/misc/reqqueue.cpp +SRC_CC += Runtime/common/misc/sg.cpp +SRC_CC += Runtime/common/misc/term.cpp +SRC_CC += Runtime/common/misc/RTAssertMsg1Weak.cpp +SRC_CC += Runtime/common/misc/RTAssertMsg2AddWeak.cpp +SRC_CC += Runtime/common/misc/RTAssertMsg2AddWeakV.cpp +SRC_CC += Runtime/common/misc/RTAssertMsg2Weak.cpp +SRC_CC += Runtime/common/misc/RTAssertMsg2WeakV.cpp +SRC_CC += Runtime/common/misc/RTMemWipeThoroughly.cpp +SRC_CC += Runtime/common/net/netaddrstr2.cpp +SRC_CC += Runtime/common/path/comparepaths.cpp +SRC_CC += Runtime/common/path/RTPathAbsDup.cpp +SRC_CC += Runtime/common/path/RTPathAbsEx.cpp +SRC_CC += Runtime/common/path/RTPathAppendEx.cpp +SRC_CC += Runtime/common/path/RTPathCalcRelative.cpp +SRC_CC += Runtime/common/path/RTPathExt.cpp +SRC_CC += Runtime/common/path/RTPathFilename.cpp +SRC_CC += Runtime/common/path/RTPathHasPath.cpp +SRC_CC += Runtime/common/path/RTPathJoinA.cpp +SRC_CC += Runtime/common/path/RTPathJoinEx.cpp +SRC_CC += Runtime/common/path/RTPathParse.cpp +SRC_CC += Runtime/common/path/RTPathParseSimple.cpp +SRC_CC += Runtime/common/path/RTPathRealDup.cpp +SRC_CC += Runtime/common/path/RTPathStartsWithRoot.cpp +SRC_CC += Runtime/common/path/RTPathStripExt.cpp +SRC_CC += Runtime/common/path/RTPathStripFilename.cpp +SRC_CC += Runtime/common/path/RTPathStripTrailingSlash.cpp +SRC_CC += Runtime/common/path/rtPathVolumeSpecLen.cpp +SRC_CC += Runtime/common/path/rtPathRootSpecLen.cpp +SRC_CC += Runtime/common/rand/rand.cpp +SRC_CC += Runtime/common/rand/randadv.cpp +SRC_CC += Runtime/common/rand/randparkmiller.cpp +SRC_CC += Runtime/common/string/base64.cpp +SRC_CC += Runtime/common/string/RTStrCmp.cpp +SRC_CC += Runtime/common/string/RTStrCopy.cpp +SRC_CC += Runtime/common/string/RTStrCopyEx.cpp +SRC_CC += Runtime/common/string/RTStrCopyP.cpp +SRC_CC += Runtime/common/string/RTStrNCmp.cpp +SRC_CC += Runtime/common/string/RTStrNLen.cpp +SRC_CC += Runtime/common/string/RTStrNLenEx.cpp +SRC_CC += Runtime/common/string/RTStrPrintHexBytes.cpp +SRC_CC += Runtime/common/string/simplepattern.cpp +SRC_CC += Runtime/common/string/straprintf.cpp +SRC_CC += Runtime/common/string/strformat.cpp +SRC_CC += Runtime/common/string/strformatnum.cpp +SRC_CC += Runtime/common/string/strformatrt.cpp +SRC_CC += Runtime/common/string/strformattype.cpp +SRC_CC += Runtime/common/string/stringalloc.cpp +SRC_CC += Runtime/common/string/strprintf.cpp +SRC_CC += Runtime/common/string/strspace.cpp +SRC_CC += Runtime/common/string/strstrip.cpp +SRC_CC += Runtime/common/string/strtonum.cpp +SRC_CC += Runtime/common/string/unidata-lower.cpp +SRC_CC += Runtime/common/string/unidata-upper.cpp +SRC_CC += Runtime/common/string/utf-8.cpp +SRC_CC += Runtime/common/string/utf-8-case.cpp +SRC_CC += Runtime/common/string/utf-16.cpp +SRC_CC += Runtime/common/string/utf-16-case.cpp +SRC_CC += Runtime/common/table/avlohcphys.cpp +SRC_CC += Runtime/common/table/avlpv.cpp +SRC_CC += Runtime/common/table/avlroioport.cpp +SRC_CC += Runtime/common/table/avlrogcphys.cpp +SRC_CC += Runtime/common/table/avlul.cpp +SRC_CC += Runtime/common/table/avlu32.cpp +SRC_CC += Runtime/common/time/time.cpp +SRC_CC += Runtime/common/time/timeprog.cpp +SRC_CC += Runtime/common/time/timesup.cpp +SRC_CC += Runtime/common/time/timesupref.cpp +SRC_CC += Runtime/common/vfs/vfsbase.cpp +SRC_CC += Runtime/common/zip/zip.cpp +SRC_CC += Runtime/r3/alloc.cpp +SRC_CC += Runtime/r3/dir.cpp +SRC_CC += Runtime/r3/fileio.cpp +SRC_CC += Runtime/r3/fs.cpp +SRC_CC += Runtime/r3/path.cpp +SRC_CC += Runtime/r3/generic/semspinmutex-r3-generic.cpp +SRC_CC += Runtime/r3/posix/dir-posix.cpp +SRC_CC += Runtime/r3/posix/env-posix.cpp +SRC_CC += Runtime/r3/posix/fileio-posix.cpp +SRC_CC += Runtime/r3/posix/fileio2-posix.cpp +SRC_CC += Runtime/r3/posix/fs-posix.cpp +SRC_CC += Runtime/r3/posix/fs2-posix.cpp +SRC_CC += Runtime/r3/posix/fs3-posix.cpp +SRC_CC += Runtime/r3/posix/path-posix.cpp +SRC_CC += Runtime/r3/posix/path2-posix.cpp +SRC_CC += Runtime/r3/posix/pipe-posix.cpp +SRC_CC += Runtime/r3/posix/RTTimeNow-posix.cpp +SRC_CC += Runtime/r3/posix/semeventmulti-posix.cpp +SRC_CC += Runtime/r3/posix/semevent-posix.cpp +SRC_CC += Runtime/r3/posix/semmutex-posix.cpp +SRC_CC += Runtime/r3/posix/thread2-posix.cpp +SRC_CC += Runtime/r3/posix/thread-posix.cpp +SRC_CC += Runtime/r3/posix/time-posix.cpp +SRC_CC += Runtime/r3/posix/tls-posix.cpp +SRC_CC += Runtime/r3/posix/utf8-posix.cpp +SRC_CC += Runtime/r3/process.cpp +SRC_CC += Runtime/r3/stream.cpp +SRC_CC += Runtime/VBox/log-vbox.cpp +SRC_S += Runtime/common/asm/ASMAtomicCmpXchgExU64.asm +SRC_S += Runtime/common/asm/ASMAtomicCmpXchgU64.asm +SRC_S += Runtime/common/asm/ASMAtomicReadU64.asm +SRC_S += Runtime/common/asm/ASMAtomicUoReadU64.as +SRC_S += Runtime/common/asm/ASMAtomicXchgU64.asm +SRC_S += Runtime/common/asm/ASMCpuIdExSlow.asm +SRC_S += Runtime/common/asm/ASMGetXcr0.asm + +SRC_CC += Runtime/common/err/errmsg.cpp +Runtime/common/err/errmsg.o: errmsgdata.h + +errmsgdata.h: $(VIRTUALBOX_DIR)/include/iprt/err.h \ + $(VIRTUALBOX_DIR)/include/VBox/err.h + $(MSG_CONVERT)$@ + $(VERBOSE)sed -f $(VBOX_DIR)/Runtime/common/err/errmsg.sed $^ > $@ + diff --git a/repos/ports/lib/mk/virtualbox5-storage.mk b/repos/ports/lib/mk/virtualbox5-storage.mk new file mode 100644 index 0000000000..dd16373dbf --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-storage.mk @@ -0,0 +1,17 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +SRC_CC += Storage/VCICache.cpp +SRC_CC += Storage/VD.cpp +SRC_CC += Storage/VMDK.cpp +SRC_CC += Storage/DMG.cpp +SRC_CC += Storage/ISCSI.cpp +SRC_CC += Storage/Parallels.cpp +SRC_CC += Storage/QCOW.cpp +SRC_CC += Storage/QED.cpp +SRC_CC += Storage/RAW.cpp +SRC_CC += Storage/VD.cpp +SRC_CC += Storage/VDI.cpp +SRC_CC += Storage/VDIfVfs.cpp +SRC_CC += Storage/VHD.cpp +SRC_CC += Storage/VHDX.cpp +SRC_CC += Storage/VMDK.cpp diff --git a/repos/ports/lib/mk/virtualbox5-vmm.mk b/repos/ports/lib/mk/virtualbox5-vmm.mk new file mode 100644 index 0000000000..8aed3edce6 --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-vmm.mk @@ -0,0 +1,100 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +# +# Prevent inclusion of the Genode::Log definition after the vbox #define +# of 'Log'. Otherwise, the attempt to compile base/log.h will fail. +# +VBOX_CC_OPT += -include base/log.h + +SRC_CC += VMM/VMMR3/VM.cpp +SRC_CC += VMM/VMMAll/VMAll.cpp +SRC_CC += VMM/VMMAll/VMMAll.cpp +SRC_CC += VMM/VMMR3/VMM.cpp + +SRC_CC += VMM/VMMR3/STAM.cpp + +SRC_CC += VMM/VMMR3/SSM.cpp + +SRC_CC += VMM/VMMR3/PDM.cpp +SRC_CC += VMM/VMMR3/PDMBlkCache.cpp +SRC_CC += VMM/VMMR3/PDMDevice.cpp +SRC_CC += VMM/VMMR3/PDMQueue.cpp +SRC_CC += VMM/VMMR3/PDMCritSect.cpp +SRC_CC += VMM/VMMAll/PDMAll.cpp +SRC_CC += VMM/VMMAll/PDMAllQueue.cpp +SRC_CC += VMM/VMMAll/PDMAllCritSect.cpp +SRC_CC += VMM/VMMAll/PDMAllCritSectRw.cpp + +SRC_CC += VMM/VMMR3/TM.cpp +SRC_CC += VMM/VMMAll/TMAll.cpp +SRC_CC += VMM/VMMAll/TMAllVirtual.cpp +SRC_CC += VMM/VMMAll/TMAllReal.cpp +SRC_CC += VMM/VMMAll/TMAllCpu.cpp +SRC_CC += VMM/VMMAll/TRPMAll.cpp + +SRC_CC += VMM/VMMR3/CFGM.cpp + +SRC_CC += VMM/VMMR3/PDMDevHlp.cpp +SRC_CC += VMM/VMMR3/PDMDevMiscHlp.cpp +SRC_CC += VMM/VMMR3/PDMDriver.cpp +SRC_CC += VMM/VMMR3/PDMThread.cpp + +SRC_CC += VMM/VMMR3/PDMUsb.cpp + +SRC_CC += VMM/VMMAll/CPUMAllMsrs.cpp +SRC_CC += VMM/VMMAll/CPUMAllRegs.cpp + +SRC_CC += VMM/VMMR3/VMEmt.cpp +SRC_CC += VMM/VMMR3/VMReq.cpp + +SRC_CC += VMM/VMMAll/DBGFAll.cpp +SRC_CC += VMM/VMMR3/DBGFInfo.cpp + +SRC_CC += VMM/VMMR3/CPUM.cpp +SRC_CC += VMM/VMMR3/CPUMR3CpuId.cpp +SRC_CC += VMM/VMMR3/CPUMR3Db.cpp + +SRC_CC += VMM/VMMAll/EMAll.cpp +SRC_CC += VMM/VMMR3/EM.cpp +SRC_CC += VMM/VMMR3/EMHM.cpp + +SRC_CC += VMM/VMMR3/TRPM.cpp +SRC_CC += VMM/VMMAll/SELMAll.cpp + +SRC_CC += VMM/VMMAll/REMAll.cpp + +SRC_CC += VMM/VMMR3/VMMGuruMeditation.cpp + +SRC_CC += VMM/VMMAll/IEMAll.cpp +SRC_S += VMM/VMMAll/IEMAllAImpl.asm +SRC_CC += VMM/VMMAll/IEMAllAImplC.cpp +SRC_CC += VMM/VMMR3/IEMR3.cpp + +SRC_CC += VMM/VMMR3/GMM.cpp + +SRC_CC += VMM/VMMR3/PGM.cpp +SRC_CC += VMM/VMMR3/PGMHandler.cpp +SRC_CC += VMM/VMMR3/PGMPhys.cpp +SRC_CC += VMM/VMMR3/PGMPool.cpp +SRC_CC += VMM/VMMAll/PGMAll.cpp +SRC_CC += VMM/VMMAll/PGMAllHandler.cpp +SRC_CC += VMM/VMMAll/PGMAllPhys.cpp +SRC_CC += VMM/VMMAll/PGMAllPool.cpp + +SRC_CC += VMM/VMMR3/IOM.cpp +SRC_CC += VMM/VMMAll/IOMAll.cpp +SRC_CC += VMM/VMMAll/IOMAllMMIO.cpp + +CC_OPT += -DVBOX_IN_VMM + +# definitions needed by SSM.cpp +CC_OPT += -DKBUILD_TYPE=\"debug\" \ + -DKBUILD_TARGET=\"genode\" \ + -DKBUILD_TARGET_ARCH=\"x86\" + +# definitions needed by VMMAll.cpp +CC_OPT += -DVBOX_SVN_REV=~0 + +INC_DIR += $(VBOX_DIR)/VMM/include + +CC_WARN += -Wno-unused-but-set-variable diff --git a/repos/ports/lib/mk/virtualbox5-xml.mk b/repos/ports/lib/mk/virtualbox5-xml.mk new file mode 100644 index 0000000000..8b18cebc64 --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-xml.mk @@ -0,0 +1,23 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +ZLIB_DIR = $(VIRTUALBOX_DIR)/src/libs/zlib-1.2.8 +LIBXML_DIR = $(VIRTUALBOX_DIR)/src/libs/libxml2-2.9.2 + +INC_DIR += $(ZLIB_DIR) +INC_DIR += $(LIBXML_DIR)/include +INC_DIR += $(call select_from_ports,libiconv)/include/iconv + +LIBS += stdcxx + +VBOX_CC_OPT += -DLIBXML_THREAD_ENABLED + +SRC_C += buf.c catalog.c chvalid.c debugXML.c dict.c encoding.c error.c entities.c +SRC_C += globals.c hash.c list.c parser.c parserInternals.c pattern.c +SRC_C += relaxng.c threads.c tree.c uri.c valid.c HTMLtree.c HTMLparser.c +SRC_C += SAX.c SAX2.c xmlIO.c xmlmemory.c xmlreader.c xmlregexp.c xmlschemas.c +SRC_C += xmlschemastypes.c xmlsave.c xmlstring.c xmlunicode.c xpath.c xpointer.c + +SRC_CC += Runtime/r3/xml.cpp +SRC_CC += Runtime/common/string/ministring.cpp + +vpath %.c $(LIBXML_DIR) diff --git a/repos/ports/lib/mk/virtualbox5-zlib.mk b/repos/ports/lib/mk/virtualbox5-zlib.mk new file mode 100644 index 0000000000..0daf77b897 --- /dev/null +++ b/repos/ports/lib/mk/virtualbox5-zlib.mk @@ -0,0 +1,7 @@ +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +ZLIB_DIR = $(VIRTUALBOX_DIR)/src/libs/zlib-1.2.8 +INC_DIR += $(ZLIB_DIR) +SRC_C = $(notdir $(wildcard $(ZLIB_DIR)/*.c)) + +vpath % $(ZLIB_DIR) diff --git a/repos/ports/ports/virtualbox5.hash b/repos/ports/ports/virtualbox5.hash new file mode 100644 index 0000000000..8cf9b42721 --- /dev/null +++ b/repos/ports/ports/virtualbox5.hash @@ -0,0 +1 @@ +14b453967da93f0915e476d45b80a8a400c37eb4 diff --git a/repos/ports/ports/virtualbox5.port b/repos/ports/ports/virtualbox5.port new file mode 100644 index 0000000000..f8fb9fdff6 --- /dev/null +++ b/repos/ports/ports/virtualbox5.port @@ -0,0 +1,158 @@ +LICENSE := GPLv2 +VERSION := 5.0.26 +DOWNLOADS := virtualbox.archive virtualbox_sdk.archive + +VIRTUALBOX_TBZ2 := VirtualBox-$(VERSION).tar.bz2 +VIRTUALBOX_SDK_ZIP := VirtualBoxSDK-$(VERSION)-108824.zip + +URL(virtualbox) := http://download.virtualbox.org/virtualbox/$(VERSION)/$(VIRTUALBOX_TBZ2) +DIR(virtualbox) := src/app/virtualbox +SHA(virtualbox) := 5e58c952f010b679a80ba3ce7ccb2641895f515f + +URL(virtualbox_sdk) := http://download.virtualbox.org/virtualbox/$(VERSION)/$(VIRTUALBOX_SDK_ZIP) +DIR(virtualbox_sdk) := src/app/virtualbox_sdk +SHA(virtualbox_sdk) := 8c03425d13095a951725d763a8a3a6f51a64ed67 + +PATCHES_DIR := src/virtualbox5/patches +PATCHES_DIR_VBOX4 := src/virtualbox/patches +PATCHES := $(addprefix $(PATCHES_DIR)/, $(shell cat $(REP_DIR)/$(PATCHES_DIR)/series)) +PATCHES += $(addprefix $(PATCHES_DIR_VBOX4)/, $(shell cat $(REP_DIR)/$(PATCHES_DIR_VBOX4)/series_common)) +PATCH_OPT := -p1 + +$(call check_tool,xsltproc) +$(call check_tool,yasm) +$(call check_tool,iasl) + +VBOX_MAIN_GLUE := AutoLock EventQueue string xpcom/helpers + +VBOX_MAIN_ALL := AuthLibrary AutoCaller DisplayResampleImage DisplayUtils EventImpl Global HashedPw +VBOX_MAIN_ALL += PCIDeviceAttachmentImpl ProgressImpl SharedFolderImpl SecretKeyStore +VBOX_MAIN_ALL += VirtualBoxBase + +VBOX_MAIN_CLI := AdditionsFacilityImpl BusAssignmentManager +VBOX_MAIN_CLI += ConsoleImpl ConsoleImpl2 ConsoleVRDPServer +VBOX_MAIN_CLI += DisplayImpl DisplayImplLegacy DisplaySourceBitmapImpl +VBOX_MAIN_CLI += DrvAudioVRDE EmulatedUSBImpl GuestCtrlImpl GuestImpl +VBOX_MAIN_CLI += HGCM HGCMThread HGCMObjects +VBOX_MAIN_CLI += KeyboardImpl SessionImpl VMMDevInterface +VBOX_MAIN_CLI += MouseImpl MachineDebuggerImpl +VBOX_MAIN_CLI += USBDeviceImpl UsbWebcamInterface VBoxDriversRegister +VBOX_MAIN_CLI += RemoteUSBDeviceImpl RemoteUSBBackend + +VBOX_MAIN_SRV := AudioAdapterImpl ClientToken DHCPServerImpl Matching +VBOX_MAIN_SRV += MediumAttachmentImpl NATEngineImpl NATNetworkImpl SerialPortImpl +VBOX_MAIN_SRV += BandwidthControlImpl GuestOSTypeImpl HostUSBDeviceImpl +VBOX_MAIN_SRV += MediumFormatImpl NetworkAdapterImpl SnapshotImpl +VBOX_MAIN_SRV += BandwidthGroupImpl MachineImplCloneVM MediumImpl +VBOX_MAIN_SRV += NetworkServiceRunner StorageControllerImpl VirtualBoxImpl +VBOX_MAIN_SRV += BIOSSettingsImpl MachineImpl MediumLock ParallelPortImpl +VBOX_MAIN_SRV += SystemPropertiesImpl VRDEServerImpl TokenImpl +VBOX_MAIN_SRV += USBControllerImpl USBDeviceFilterImpl USBDeviceFiltersImpl + +VBOX_MAIN_INC := AdditionsFacilityImpl AudioAdapterImpl AuthLibrary +VBOX_MAIN_INC += AutoCaller AutostartDb AutoStateDep BandwidthControlImpl +VBOX_MAIN_INC += BandwidthGroupImpl BIOSSettingsImpl BusAssignmentManager Nvram +VBOX_MAIN_INC += ClientToken ConsoleImpl DHCPServerImpl DisplayImpl HostImpl +VBOX_MAIN_INC += DisplayUtils DrvAudioVRDE EventImpl ExtPackManagerImpl Global +VBOX_MAIN_INC += GuestCtrlImplPrivate GuestDirectoryImpl Logging +VBOX_MAIN_INC += GuestFileImpl GuestFsObjInfoImpl GuestImpl GuestOSTypeImpl +VBOX_MAIN_INC += GuestSessionImpl HashedPw KeyboardImpl MachineImplCloneVM +VBOX_MAIN_INC += HGCM HGCMThread HGCMObjects +VBOX_MAIN_INC += MachineImpl MediumAttachmentImpl MediumFormatImpl MediumImpl +VBOX_MAIN_INC += MediumLock MouseImpl NATEngineImpl NATNetworkImpl +VBOX_MAIN_INC += NetworkAdapterImpl NetworkServiceRunner +VBOX_MAIN_INC += objectslist ObjectState +VBOX_MAIN_INC += ParallelPortImpl PCIDeviceAttachmentImpl Performance +VBOX_MAIN_INC += ProgressImpl ProgressProxyImpl SnapshotImpl +VBOX_MAIN_INC += SecretKeyStore SerialPortImpl SessionImpl SharedFolderImpl +VBOX_MAIN_INC += StorageControllerImpl SystemPropertiesImpl TokenImpl VMMDev +VBOX_MAIN_INC += UsbWebcamInterface +VBOX_MAIN_INC += USBControllerImpl USBDeviceFilterImpl USBDeviceFiltersImpl +VBOX_MAIN_INC += USBIdDatabase USBProxyService VirtualBoxImpl VRDEServerImpl GuestProcessImpl +VBOX_MAIN_INC += USBDeviceImpl HostUSBDeviceImpl Matching Wrapper +VBOX_MAIN_INC += RemoteUSBDeviceImpl RemoteUSBBackend ConsoleVRDPServer +VBOX_MAIN_INC += MachineDebuggerImpl EmulatedUSBImpl + +VBOX_SRC_VBOX := VMM Devices Runtime GuestHost/HGSMI Storage Disassembler +VBOX_SRC_VBOX += HostServices/SharedFolders Main/xml/Settings.cpp +VBOX_SRC_VBOX += HostServices/SharedClipboard +VBOX_SRC_VBOX += Main/xml/VirtualBox-settings.xsd Main/xml/SchemaDefs.xsl +VBOX_SRC_VBOX += Main/idl/docstrip.xsl Main/idl/VirtualBox.xidl +VBOX_SRC_VBOX += Main/idl/apiwrap-server.xsl +VBOX_SRC_VBOX += Main/idl/typemap-shared.inc.xsl +VBOX_SRC_VBOX += $(addsuffix .h, $(addprefix Main/include/, $(VBOX_MAIN_INC))) +VBOX_SRC_VBOX += $(addsuffix .cpp, $(addprefix Main/src-client/, $(VBOX_MAIN_CLI))) +VBOX_SRC_VBOX += $(addsuffix .cpp, $(addprefix Main/src-server/, $(VBOX_MAIN_SRV))) +VBOX_SRC_VBOX += $(addsuffix .cpp, $(addprefix Main/src-all/, $(VBOX_MAIN_ALL))) +VBOX_SRC_VBOX += $(addsuffix .cpp, $(addprefix Main/glue/, $(VBOX_MAIN_GLUE))) + +VBOX_INC += types.h cdefs.h hgcmsvc.h err.h dis.h disopcode.h log.h sup.h pci.h +VBOX_INC += param.h ostypes.h VMMDev.h VMMDev2.h vusb.h dbg.h version.h HGSMI +VBOX_INC += VBoxVideo.h Hardware bioslogo.h scsi.h shflsvc.h VBoxGuest2.h vd.h +VBOX_INC += vd-plugin.h vd-ifs.h vd-ifs-internal.h vd-image-backend.h +VBOX_INC += vd-cache-backend.h vd-filter-backend.h msi.h asmdefs.mac err.mac +VBOX_INC += VBoxVideoHost3D.h VBoxVideo3D.h settings.h VBoxAuth.h +VBOX_INC += usb.h usbfilter.h vrdpusb.h +VBOX_INC += RemoteDesktop ExtPack/ExtPack.h + +VBOX_INC_COM := array.h assert.h AutoLock.h ErrorInfo.h EventQueue.h Guid.h +VBOX_INC_COM += list.h MultiResult.h string.h + +VBOX_CONTENT += $(addprefix src/VBox/,$(VBOX_SRC_VBOX)) +VBOX_CONTENT += $(addprefix include/VBox/, $(VBOX_INC)) +VBOX_CONTENT += $(addprefix include/VBox/com/, $(VBOX_INC_COM)) +VBOX_CONTENT += include/VBox/HostServices/ + +VBOX_CONTENT += src/libs/zlib-1.2.8 src/libs/liblzf-3.4 src/libs/libxml2-2.9.2 +VBOX_CONTENT += src/recompiler include/VBox/vmm include/iprt Config.kmk + + +TAR_OPT(virtualbox) := \ + --strip-components 1 \ + $(addprefix $(VIRTUALBOX_TBZ2:.tar.bz2=)/,$(VBOX_CONTENT)) + +UNZIP_OPT(virtualbox_sdk) := $(VIRTUALBOX_SDK_ZIP) sdk/bindings/xpcom/include/VirtualBox_XPCOM.h \# + + +default : additional_steps +additional_steps : $(DOWNLOADS) + @xsltproc --stringparam mode declare \ + -o src/app/virtualbox/src/VBox/Main/xml/SchemaDefs.h \ + src/app/virtualbox/src/VBox/Main/xml/SchemaDefs.xsl \ + src/app/virtualbox/src/VBox/Main/xml/VirtualBox-settings.xsd + xsltproc -o VirtualBox_stripped.xidl \ + src/app/virtualbox/src/VBox/Main/idl/docstrip.xsl \ + src/app/virtualbox/src/VBox/Main/idl/VirtualBox.xidl + xsltproc --stringparam KBUILD_HOST genode \ + --stringparam generating "headers" -o VBoxAPIWrap/apiwrappers-headers \ + src/app/virtualbox/src/VBox/Main/idl/apiwrap-server.xsl \ + VirtualBox_stripped.xidl + xsltproc --stringparam KBUILD_HOST genode \ + --stringparam generating "sources" --param reminder 0 \ + -o VBoxAPIWrap/apiwrappers-sources-even \ + src/app/virtualbox/src/VBox/Main/idl/apiwrap-server.xsl \ + VirtualBox_stripped.xidl + xsltproc --stringparam KBUILD_HOST genode \ + --stringparam generating "sources" --param reminder 1 \ + -o VBoxAPIWrap/apiwrappers-sources-odd \ + src/app/virtualbox/src/VBox/Main/idl/apiwrap-server.xsl \ + VirtualBox_stripped.xidl + mkdir -p src/app/virtualbox/VBoxAPIWrap + csplit -s -n 1 -f "VBoxAPIWrap/xx" VBoxAPIWrap/apiwrappers-headers '/##### ENDFILE.*$$/' '{*}' && \ + i=0 && \ + for f in $$(grep "BEGINFILE \"" VBoxAPIWrap/apiwrappers-headers | sed "s,//.*BEGINFILE \",,g" | sed "s,\",,g"); do \ + mv "VBoxAPIWrap/xx$$((i++))" "src/app/virtualbox/VBoxAPIWrap/$$f"; \ + done && \ + rm "VBoxAPIWrap/xx$$((i))" + csplit -s -n 1 -f "VBoxAPIWrap/xx" VBoxAPIWrap/apiwrappers-sources-even '/##### ENDFILE.*$$/' '{*}' && \ + i=0 && \ + for f in $$(grep "BEGINFILE \"" VBoxAPIWrap/apiwrappers-sources-even | sed "s,//.*BEGINFILE \",,g" | sed "s,\",,g"); do \ + mv "VBoxAPIWrap/xx$$((i++))" "src/app/virtualbox/VBoxAPIWrap/$$f"; \ + done && \ + rm "VBoxAPIWrap/xx$$((i))" + csplit -s -n 1 -f "VBoxAPIWrap/xx" VBoxAPIWrap/apiwrappers-sources-odd '/##### ENDFILE.*$$/' '{*}' && \ + i=0 && \ + for f in $$(grep "BEGINFILE \"" VBoxAPIWrap/apiwrappers-sources-odd | sed "s,//.*BEGINFILE \",,g" | sed "s,\",,g"); do \ + mv "VBoxAPIWrap/xx$$((i++))" "src/app/virtualbox/VBoxAPIWrap/$$f"; \ + done && \ + rm "VBoxAPIWrap/xx$$((i))" diff --git a/repos/ports/run/vbox_auto_win7.run b/repos/ports/run/vbox_auto_win7.run index 9d225943cd..a16251fc4b 100644 --- a/repos/ports/run/vbox_auto_win7.run +++ b/repos/ports/run/vbox_auto_win7.run @@ -4,6 +4,9 @@ set flavor "win7" +set use_vbox4 1 +set use_vbox5 0 + # Write overlay only into ram set use_ram_fs 1 # However read initial overlay from disk diff --git a/repos/ports/run/vbox_auto_win7_share.run b/repos/ports/run/vbox_auto_win7_share.run index 1bbf913fa0..888f147eb4 100644 --- a/repos/ports/run/vbox_auto_win7_share.run +++ b/repos/ports/run/vbox_auto_win7_share.run @@ -69,6 +69,10 @@ if {(![have_spec nova] && ![have_spec hw_x86_64_muen])} { } set flavor "win7" + +set use_vbox4 1 +set use_vbox5 0 + set vdi_image "${flavor}.vdi" # Write overlay back to harddisk if set to 0 set use_ram_fs 0 diff --git a/repos/ports/run/vbox_auto_win7_vbox5.run b/repos/ports/run/vbox_auto_win7_vbox5.run new file mode 100644 index 0000000000..aa5a40c8be --- /dev/null +++ b/repos/ports/run/vbox_auto_win7_vbox5.run @@ -0,0 +1,21 @@ +# +# Windows 7 in VirtualBox 5 +# + +assert_spec nova +assert_spec 64bit + +set flavor "win7" + +set use_vbox4 0 +set use_vbox5 5 + +# Write overlay only into ram +set use_ram_fs 1 +# However read initial overlay from disk +set use_overlay_from_disk 1 + +set use_usb 1 +set use_ps2 [have_spec ps2] + +source ${genode_dir}/repos/ports/run/vbox_win.inc diff --git a/repos/ports/run/vbox_auto_win8.run b/repos/ports/run/vbox_auto_win8.run index 975a15f2cb..d49c177318 100644 --- a/repos/ports/run/vbox_auto_win8.run +++ b/repos/ports/run/vbox_auto_win8.run @@ -6,6 +6,9 @@ assert_spec 64bit set flavor "win8" +set use_vbox4 1 +set use_vbox5 0 + # Write overlay back to harddisk if set to 0 set use_ram_fs 0 set use_overlay_from_disk 0 diff --git a/repos/ports/run/vbox_auto_win81_64.run b/repos/ports/run/vbox_auto_win81_64.run index 014d404d07..5abbdad513 100644 --- a/repos/ports/run/vbox_auto_win81_64.run +++ b/repos/ports/run/vbox_auto_win81_64.run @@ -6,6 +6,9 @@ assert_spec 64bit set flavor "win81_64" +set use_vbox4 1 +set use_vbox5 0 + # Write overlay back to harddisk if set to 0 set use_ram_fs 0 set use_overlay_from_disk 0 diff --git a/repos/ports/run/vbox_win.inc b/repos/ports/run/vbox_win.inc index fbcfa170cc..1a6b406add 100644 --- a/repos/ports/run/vbox_win.inc +++ b/repos/ports/run/vbox_win.inc @@ -148,8 +148,13 @@ append config_of_app { - - + } +append_if [expr $use_vbox4] config_of_app { + } +append_if [expr $use_vbox5] config_of_app { + } + +append config_of_app { } append config_of_app " " diff --git a/repos/ports/run/virtualbox_auto.inc b/repos/ports/run/virtualbox_auto.inc index 017514d568..2fc3bab348 100644 --- a/repos/ports/run/virtualbox_auto.inc +++ b/repos/ports/run/virtualbox_auto.inc @@ -9,7 +9,7 @@ if {[have_include "power_on/qemu"]} { } append build_components { - core init virtualbox + core init server/part_blk server/rump_fs server/fs_rom @@ -18,6 +18,8 @@ append build_components { drivers/timer } +lappend_if [expr $use_vbox4] build_components virtualbox +lappend_if [expr $use_vbox5] build_components virtualbox5 lappend_if [expr $use_ps2] build_components drivers/input lappend_if [expr $use_usb] build_components drivers/usb lappend_if [expr $use_usb] build_components app/usb_report_filter @@ -270,9 +272,11 @@ append boot_modules { libc_pipe.lib.so libc_terminal.lib.so libiconv.lib.so stdcxx.lib.so rump.lib.so rump_fs.lib.so rump_fs - virtualbox qemu-usb.lib.so + qemu-usb.lib.so } +lappend_if [expr $use_vbox4] boot_modules virtualbox +lappend_if [expr $use_vbox5] boot_modules virtualbox5 lappend_if [expr $use_ram_fs || $use_usb] boot_modules ram_fs lappend_if [expr $use_ram_fs && !$use_overlay_from_disk] boot_modules ${overlay_image} diff --git a/repos/ports/src/virtualbox/devxhci.cc b/repos/ports/src/virtualbox/devxhci.cc index 5eabe02277..f429d38b59 100644 --- a/repos/ports/src/virtualbox/devxhci.cc +++ b/repos/ports/src/virtualbox/devxhci.cc @@ -196,7 +196,7 @@ struct Timer_queue : public Qemu::Timer_queue ** TMTimer callback ** **********************/ - static void tm_timer_cb(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) + static DECLCALLBACK(void) tm_timer_cb(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) { PXHCI pThis = PDMINS_2_DATA(pDevIns, PXHCI); Timer_queue *q = pThis->timer_queue; diff --git a/repos/ports/src/virtualbox/network.cpp b/repos/ports/src/virtualbox/network.cpp index 9977e94161..8746762614 100644 --- a/repos/ports/src/virtualbox/network.cpp +++ b/repos/ports/src/virtualbox/network.cpp @@ -26,6 +26,7 @@ * Header Files * *******************************************************************************/ #define LOG_GROUP LOG_GROUP_DRV_TUN +#include #include #include #include diff --git a/repos/ports/src/virtualbox5/dummies.cc b/repos/ports/src/virtualbox5/dummies.cc new file mode 100644 index 0000000000..84934a60e4 --- /dev/null +++ b/repos/ports/src/virtualbox5/dummies.cc @@ -0,0 +1,169 @@ +/* + * \brief Dummy implementations of symbols needed by VirtualBox + * \author Norman Feske + * \date 2013-08-22 + */ + +/* + * Copyright (C) 2013-2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include + +#include /* libc memcpy */ + +#include "VMMInternal.h" +#include "EMInternal.h" +#include "PDMInternal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" + +static const bool trace = false; + +#define TRACE(retval) \ + { \ + if (trace) \ + Genode::log(__func__, " called, return dummy, eip=", \ + __builtin_return_address(0)); \ + return retval; \ + } + + +RT_C_DECLS_BEGIN + +RTDECL(int) RTMemProtect(void *pv, size_t cb, unsigned fProtect) +{ + if (!trace) + return VINF_SUCCESS; + + char type[4]; + + if (fProtect & RTMEM_PROT_READ) + type[0] = 'r'; + else + type[0] = '-'; + + if (fProtect & RTMEM_PROT_WRITE) + type[1] = 'w'; + else + type[1] = '-'; + + if (fProtect & RTMEM_PROT_EXEC) + type[2] = 'x'; + else + type[2] = '-'; + + type[3] = 0; + + Genode::warning(__func__, " called - not implemented - ", pv, "+", + Genode::Hex(cb), " protect ", Genode::Hex(fProtect), " - " + "'", (char const *)type, "'"); + + return VINF_SUCCESS; +} + + +static_assert(sizeof(RTR0PTR) == sizeof(RTR3PTR), "pointer transformation bug"); +static_assert(sizeof(RTR0PTR) == sizeof(void *) , "pointer transformation bug"); +static_assert(sizeof(RTR3PTR) == sizeof(RTR0PTR), "pointer transformation bug"); + +RTR0PTR MMHyperR3ToR0(PVM pVM, RTR3PTR R3Ptr) { return (RTR0PTR)R3Ptr; } +RTRCPTR MMHyperR3ToRC(PVM pVM, RTR3PTR R3Ptr) { return to_rtrcptr(R3Ptr); } +RTR0PTR MMHyperCCToR0(PVM pVM, void *pv) { return (RTR0PTR)pv; } +RTRCPTR MMHyperCCToRC(PVM pVM, void *pv) { return to_rtrcptr(pv); } +RTR3PTR MMHyperR0ToR3(PVM pVM, RTR0PTR R0Ptr) { return (RTR3PTR*)(R0Ptr | 0UL); } +RTR3PTR MMHyperRCToR3(PVM pVM, RTRCPTR RCPtr) +{ + static_assert(sizeof(RCPtr) <= sizeof(RTR3PTR), "ptr transformation bug"); + return reinterpret_cast(0UL | RCPtr); +} + +/* debugger */ +int DBGFR3AsSymbolByAddr(PUVM, RTDBGAS, PCDBGFADDRESS, uint32_t, PRTGCINTPTR, + PRTDBGSYMBOL, PRTDBGMOD) TRACE(VERR_INVALID_HANDLE) + +/* called by 'VMMR3InitRC', but we don't use GC */ +void CPUMPushHyper(PVMCPU, uint32_t) TRACE() + +int PGMR3FinalizeMappings(PVM) TRACE(VINF_SUCCESS) +int pgmR3InitSavedState(PVM pVM, uint64_t cbRam) TRACE(VINF_SUCCESS) + +int vmmR3SwitcherInit(PVM pVM) TRACE(VINF_SUCCESS) +void vmmR3SwitcherRelocate(PVM, RTGCINTPTR) TRACE() +int VMMR3DisableSwitcher(PVM) TRACE(VINF_SUCCESS) + +int emR3InitDbg(PVM pVM) TRACE(VINF_SUCCESS) + +int FTMR3Init(PVM) TRACE(VINF_SUCCESS) +int FTMR3SetCheckpoint(PVM, FTMCHECKPOINTTYPE) TRACE(-1) +int FTMSetCheckpoint(PVM, FTMCHECKPOINTTYPE) TRACE(VINF_SUCCESS) +int FTMR3Term(PVM) TRACE(VINF_SUCCESS) + +int GIMR3Init(PVM) TRACE(VINF_SUCCESS) +void GIMR3Reset(PVM) TRACE() +bool GIMIsEnabled(PVM) TRACE(false) +bool GIMIsParavirtTscEnabled(PVM) TRACE(false) +int GIMR3InitCompleted(PVM pVM) +{ + /* from original GIMR3InitCompleted code */ + if (!TMR3CpuTickIsFixedRateMonotonic(pVM, true /* fWithParavirtEnabled */)) + Genode::warning("GIM: Warning!!! Host TSC is unstable. The guest may ", + "behave unpredictably with a paravirtualized clock."); + + TRACE(VINF_SUCCESS) +} + + +void HMR3Relocate(PVM) TRACE() +void HMR3Reset(PVM pVM) TRACE() + +int SELMR3Init(PVM) TRACE(VINF_SUCCESS) +int SELMR3Term(PVM) TRACE(VINF_SUCCESS) +int SELMR3InitFinalize(PVM) TRACE(VINF_SUCCESS) +void SELMR3Relocate(PVM) TRACE() +void SELMR3Reset(PVM) TRACE() +void SELMR3DisableMonitoring(PVM) TRACE() + +int SUPR3SetVMForFastIOCtl(PVMR0) TRACE(VINF_SUCCESS) + +_AVLOU32NodeCore* RTAvloU32RemoveBestFit(PAVLOU32TREE, AVLOU32KEY, bool) TRACE(VINF_SUCCESS) +int RTAvlrFileOffsetDestroy(PAVLRFOFFTREE, PAVLRFOFFCALLBACK, void*) TRACE(VINF_SUCCESS) + +/* module loader of pluggable device manager */ +int pdmR3LdrInitU(PUVM) TRACE(VINF_SUCCESS) +int PDMR3LdrLoadVMMR0U(PUVM) TRACE(VINF_SUCCESS) +void PDMR3LdrRelocateU(PUVM, RTGCINTPTR) TRACE() +int pdmR3LoadR3U(PUVM, const char *, const char *) TRACE(VINF_SUCCESS) +void pdmR3LdrTermU(PUVM) TRACE() + +char *pdmR3FileR3(const char * file, bool) +{ + char * pv = reinterpret_cast(RTMemTmpAllocZ(1)); + + if (trace) + Genode::log(__func__, ": file ", file, " ", (void *)pv, " ", __builtin_return_address(0)); + + TRACE(pv) +} + +void RTAssertMsg2Add(const char *pszFormat, ...) +{ + Genode::error(__func__, "not implemented"); + Genode::Lock lock(Genode::Lock::LOCKED); + lock.lock(); +} + +RT_C_DECLS_END diff --git a/repos/ports/src/virtualbox5/frontend/ClientWatcher.h b/repos/ports/src/virtualbox5/frontend/ClientWatcher.h new file mode 100644 index 0000000000..92707ddfec --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/ClientWatcher.h @@ -0,0 +1,14 @@ +#ifndef ____H_CLIENTWATCHER +#define ____H_CLIENTWATCHER + +class VirtualBox::ClientWatcher +{ + public: + + ClientWatcher(VirtualBox* const) { } + + bool isReady() { return true; } + void update() { } + void addProcess(RTPROCESS pid); +}; +#endif /* !____H_CLIENTWATCHER */ diff --git a/repos/ports/src/virtualbox5/frontend/GenodeImpl.h b/repos/ports/src/virtualbox5/frontend/GenodeImpl.h new file mode 100644 index 0000000000..505377349f --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/GenodeImpl.h @@ -0,0 +1,10 @@ +#ifndef ____H_GENODEIMPL +#define ____H_GENODEIMPL + +/* GuestControlSvc.h */ + +typedef struct { } VBOXGUESTCTRLHOSTCBCTX, *PVBOXGUESTCTRLHOSTCBCTX; +typedef struct { } VBOXGUESTCTRLHOSTCALLBACK, *PVBOXGUESTCTRLHOSTCALLBACK; +enum GUEST_FILE_SEEKTYPE { }; + +#endif // !____H_GENODEIMPL diff --git a/repos/ports/src/virtualbox5/frontend/VBoxEvents.h b/repos/ports/src/virtualbox5/frontend/VBoxEvents.h new file mode 100644 index 0000000000..a7a709f441 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/VBoxEvents.h @@ -0,0 +1,51 @@ +#include "EventImpl.h" + +void fireStateChangedEvent(IEventSource* aSource, MachineState_T a_state); + +void fireRuntimeErrorEvent(IEventSource* aSource, BOOL a_fatal, CBSTR a_id, + CBSTR a_message); + +#define fireAdditionsStateChangedEvent(a) + +#define fireBandwidthGroupChangedEvent(a, b) + +#define fireClipboardModeChangedEvent(a, b) +#define fireCPUChangedEvent(a, b, c) +#define fireCPUExecutionCapChangedEvent(a, b) + +#define fireDnDModeChangedEvent(a, b) + +#define fireExtraDataChangedEvent(a, b, c, d) + +#define fireGuestUserStateChangedEvent(a, b, c, d, e) +#define fireGuestMonitorChangedEvent(a, b, c, d, e, f, g) + +#define fireHostNameResolutionConfigurationChangeEvent(a) +#define fireHostPCIDevicePlugEvent(a, b, c, d, e, f) + +#define fireKeyboardLedsChangedEvent(a, b, c, d) + +#define fireMediumChangedEvent(a, b) +#define fireMousePointerShapeChangedEvent(a, b, c, d, e, f, g, h) +#define fireMouseCapabilityChangedEvent(a, b, c, d, e) + +#define fireNATRedirectEvent(a, b, c, d, e, f, g, h, i, j) +#define fireNATNetworkChangedEvent(a, b) +#define fireNATNetworkPortForwardEvent(a, b, c, d, e, f, g, h, i, j) +#define fireNATNetworkSettingEvent(a, b, c, d, e, f, g) +#define fireNATNetworkStartStopEvent(a, b, c) +#define fireNetworkAdapterChangedEvent(a, b) + +#define fireParallelPortChangedEvent(a, b) + +#define fireSerialPortChangedEvent(a, b) +#define fireSharedFolderChangedEvent(a, b) +#define fireStorageControllerChangedEvent(a) +#define fireStorageDeviceChangedEvent(a, b, c, d) + +#define fireUSBControllerChangedEvent(a) +#define fireUSBDeviceStateChangedEvent(a, b, c, d) + +#define fireVideoCaptureChangedEvent(a) +#define fireVRDEServerChangedEvent(a) +#define fireVRDEServerInfoChangedEvent(a) diff --git a/repos/ports/src/virtualbox5/frontend/VirtualBoxBase.h b/repos/ports/src/virtualbox5/frontend/VirtualBoxBase.h new file mode 100644 index 0000000000..a7a0eb806f --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/VirtualBoxBase.h @@ -0,0 +1,468 @@ +#ifndef ____H_VIRTUALBOXBASEIMPL +#define ____H_VIRTUALBOXBASEIMPL + +#include + +#include +#include + +#include +#include + +#include "ObjectState.h" + +#include "VBox/com/AutoLock.h" +#include "VBox/com/string.h" +#include "VBox/com/Guid.h" + +#include "VBox/com/VirtualBox.h" + +namespace com +{ + class ErrorInfo; +} + +using namespace com; +using namespace util; + +class AutoInitSpan; +class AutoUninitSpan; + +class VirtualBox; +class Machine; +class Medium; + +typedef std::list > MediaList; +typedef std::list StringsList; + +class VirtualBoxTranslatable : public util::Lockable +{ + public: + + /* should be used for translations */ + inline static const char *tr(const char *pcszSourceText, + const char *aComment = NULL) + { + return pcszSourceText; + } +}; + +class VirtualBoxBase : public VirtualBoxTranslatable +{ + + private: + + RWLockHandle *_lock; + + + /** Primary state of this object */ + ObjectState mState; + + /** Thread that caused the last state change */ + RTTHREAD mStateChangeThread; + /** Total number of active calls to this object */ + unsigned mCallers; + /** Posted when the number of callers drops to zero */ + RTSEMEVENT mZeroCallersSem; + /** Posted when the object goes from InInit/InUninit to some other state */ + RTSEMEVENTMULTI mInitUninitSem; + /** Number of threads waiting for mInitUninitDoneSem */ + unsigned mInitUninitWaiters; + + /** User-level object lock for subclasses */ + mutable RWLockHandle *mObjectLock; + + friend class AutoInitSpan; + friend class AutoReinitSpan; + friend class AutoUninitSpan; + + protected: + + HRESULT BaseFinalConstruct() { return S_OK; } + + void BaseFinalRelease() { } + + public: + + VirtualBoxBase(); // : _lock(nullptr) { } + ~VirtualBoxBase(); + + virtual void uninit() { } + + ObjectState &getObjectState() + { + return mState; + } + + virtual const char* getComponentName() const = 0; + + static HRESULT handleUnexpectedExceptions(VirtualBoxBase *const aThis, RT_SRC_POS_DECL); + static HRESULT initializeComForThread(void); + static void uninitializeComForThread(void); + static void clearError(void); + + HRESULT setError(HRESULT aResultCode); + HRESULT setError(HRESULT aResultCode, const char *pcsz, ...); + HRESULT setError(const com::ErrorInfo &ei); + HRESULT setErrorVrc(int vrc); + HRESULT setErrorVrc(int vrc, const char *pcszMsgFmt, ...); + HRESULT setErrorBoth(HRESULT hrc, int vrc); + HRESULT setErrorBoth(HRESULT hrc, int vrc, const char *pcszMsgFmt, ...); + HRESULT setErrorNoLog(HRESULT aResultCode, const char *pcsz, ...); + + static HRESULT setErrorInternal(HRESULT aResultCode, + const GUID &aIID, + const char *aComponent, + Utf8Str aText, + bool aWarning, + bool aLogIt); + + virtual VBoxLockingClass getLockingClass() const + { + return LOCKCLASS_OTHEROBJECT; + } + + RWLockHandle * lockHandle() const; +}; + + +/** + * Dummy macro that is used to shut down Qt's lupdate tool warnings in some + * situations. This macro needs to be present inside (better at the very + * beginning) of the declaration of the class that inherits from + * VirtualBoxTranslatable, to make lupdate happy. + */ +#define Q_OBJECT + + +template +class Shareable +{ + + private: + + bool _verbose; + T * _obj; + + public: + + Shareable () : _verbose(false), _obj(nullptr) { } + + /* operators */ + T * operator->() const { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); return _obj; } + + bool isNull() const { return _obj == nullptr; } + bool operator!() const { return isNull(); } + + void allocate() { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); _obj = new T; } + void attach(T * t) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); } + void attach(Shareable &s) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); } + void share(const Shareable &s) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); _obj = s._obj; } + void share(T * obj) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); _obj = obj; } + void free() { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); } + void attachCopy(const T *) { if(_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); } + void attachCopy(const Shareable &) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); } + + T *data() const { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); return _obj; } + + bool isShared() const { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); return false; } +}; + +template +class Backupable : public Shareable +{ + + public: + + Backupable() : Shareable() { } + + void backup() { } + void rollback() { } + void commit() { } + void commitCopy() { } + void assignCopy(const T *) { } + void assignCopy(const Backupable &) { } + + HRESULT backupEx() { return S_OK; } + + T *backedUpData() const { Genode::log(__PRETTY_FUNCTION__, " called"); return nullptr; } + bool isBackedUp() const { return false; } +}; + +/** + * Special version of the Assert macro to be used within VirtualBoxBase + * subclasses. + * + * In the debug build, this macro is equivalent to Assert. + * In the release build, this macro uses |setError(E_FAIL, ...)| to set the + * error info from the asserted expression. + * + * @see VirtualBoxBase::setError + * + * @param expr Expression which should be true. + */ +#if defined(DEBUG) +#define ComAssert(expr) Assert(expr) +#else +#define ComAssert(expr) \ + do { \ + if (RT_UNLIKELY(!(expr))) \ + setError(E_FAIL, \ + "Assertion failed: [%s] at '%s' (%d) in %s.\nPlease contact the product vendor!", \ + #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (0) +#endif + +/** + * Special version of the AssertFailed macro to be used within VirtualBoxBase + * subclasses. + * + * In the debug build, this macro is equivalent to AssertFailed. + * In the release build, this macro uses |setError(E_FAIL, ...)| to set the + * error info from the asserted expression. + * + * @see VirtualBoxBase::setError + * + */ +#if defined(DEBUG) +#define ComAssertFailed() AssertFailed() +#else +#define ComAssertFailed() \ + do { \ + setError(E_FAIL, \ + "Assertion failed: at '%s' (%d) in %s.\nPlease contact the product vendor!", \ + __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (0) +#endif + +/** + * Special version of the AssertMsg macro to be used within VirtualBoxBase + * subclasses. + * + * See ComAssert for more info. + * + * @param expr Expression which should be true. + * @param a printf argument list (in parenthesis). + */ +#if defined(DEBUG) +#define ComAssertMsg(expr, a) AssertMsg(expr, a) +#else +#define ComAssertMsg(expr, a) \ + do { \ + if (RT_UNLIKELY(!(expr))) \ + setError(E_FAIL, \ + "Assertion failed: [%s] at '%s' (%d) in %s.\n%s.\nPlease contact the product vendor!", \ + #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__, Utf8StrFmt a .c_str()); \ + } while (0) +#endif + +/** + * Special version of the AssertComRC macro to be used within VirtualBoxBase + * subclasses. + * + * See ComAssert for more info. + * + * @param rc COM result code + */ +#if defined(DEBUG) +#define ComAssertComRC(rc) AssertComRC(rc) +#else +#define ComAssertComRC(rc) ComAssertMsg(SUCCEEDED(rc), ("COM RC = %Rhrc (0x%08X)", (rc), (rc))) +#endif + +/** + * Special version of the AssertMsgRC macro to be used within VirtualBoxBase + * subclasses. + * + * See ComAssert for more info. + * + * @param vrc VBox status code. + * @param msg printf argument list (in parenthesis). + */ +#if defined(DEBUG) +#define ComAssertMsgRC(vrc, msg) AssertMsgRC(vrc, msg) +#else +#define ComAssertMsgRC(vrc, msg) ComAssertMsg(RT_SUCCESS(vrc), msg) +#endif + +/** + * Special version of the AssertRC macro to be used within VirtualBoxBase + * subclasses. + * + * See ComAssert for more info. + * + * @param vrc VBox status code. + */ +#if defined(DEBUG) +#define ComAssertRC(vrc) AssertRC(vrc) +#else +#define ComAssertRC(vrc) ComAssertMsgRC(vrc, ("%Rra", vrc)) +#endif + +/** Special version of ComAssert that returns ret if expr fails */ +#define ComAssertRet(expr, ret) \ + do { ComAssert(expr); if (!(expr)) return (ret); } while (0) +/** Special version of ComAssertMsg that returns ret if expr fails */ +#define ComAssertMsgRet(expr, a, ret) \ + do { ComAssertMsg(expr, a); if (!(expr)) return (ret); } while (0) +/** Special version of ComAssertComRC that returns ret if rc does not succeed */ +#define ComAssertComRCRet(rc, ret) \ + do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return (ret); } while (0) +/** Special version of ComAssertMsg that evaluates eval and breaks if expr fails */ +#define ComAssertMsgBreak(expr, a, eval) \ + if (1) { ComAssertMsg(expr, a); if (!(expr)) { eval; break; } } else do {} while (0) +/** Special version of ComAssert that evaluates eval and throws it if expr fails */ +#define ComAssertThrow(expr, eval) \ + do { ComAssert(expr); if (!(expr)) { throw (eval); } } while (0) +/** Special version of ComAssertRC that evaluates eval and throws it if vrc does not succeed */ +#define ComAssertRCThrow(vrc, eval) \ + do { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) { throw (eval); } } while (0) +/** Special version of ComAssertFailed that returns ret */ +#define ComAssertFailedRet(ret) \ + do { ComAssertFailed(); return (ret); } while (0) +/** Special version of ComAssertFailed that returns ret */ +#define ComAssertFailedRet(ret) \ + do { ComAssertFailed(); return (ret); } while (0) +/** Special version of ComAssertRC that returns ret if vrc does not succeed */ +#define ComAssertRCRet(vrc, ret) \ + do { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) return (ret); } while (0) +/** Special version of ComAssertComRC that just throws rc if rc does not succeed */ +#define ComAssertComRCThrowRC(rc) \ + do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) { throw rc; } } while (0) +/** Special version of ComAssertComRC that returns rc if rc does not succeed */ +#define ComAssertComRCRetRC(rc) \ + do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return (rc); } while (0) + +/** + * Checks that the pointer argument is not NULL and returns E_INVALIDARG + + * extended error info on failure. + * @param arg Input pointer-type argument (strings, interface pointers...) + */ +#define CheckComArgNotNull(arg) \ + do { \ + if (RT_UNLIKELY((arg) == NULL)) \ + return setError(E_INVALIDARG, tr("Argument %s is NULL"), #arg); \ + } while (0) + +/** + * Checks that the given expression (that must involve the argument) is true and + * returns E_INVALIDARG + extended error info on failure. + * @param arg Argument. + * @param expr Expression to evaluate. + */ +#define CheckComArgExpr(arg, expr) \ + do { \ + if (RT_UNLIKELY(!(expr))) \ + return setError(E_INVALIDARG, \ + tr("Argument %s is invalid (must be %s)"), #arg, #expr); \ + } while (0) + +/** + * Checks that the given pointer to an output argument is valid and returns + * E_POINTER + extended error info otherwise. + * @param arg Pointer argument. + */ +#define CheckComArgOutPointerValid(arg) \ + do { \ + if (RT_UNLIKELY(!VALID_PTR(arg))) \ + return setError(E_POINTER, \ + tr("Output argument %s points to invalid memory location (%p)"), \ + #arg, (void *)(arg)); \ + } while (0) + +/** + * Checks that a string input argument is valid (not NULL or obviously invalid + * pointer), returning E_INVALIDARG + extended error info if invalid. + * @param a_bstrIn Input string argument (IN_BSTR). + */ +#define CheckComArgStr(a_bstrIn) \ + do { \ + IN_BSTR const bstrInCheck = (a_bstrIn); /* type check */ \ + if (RT_UNLIKELY(!RT_VALID_PTR(bstrInCheck))) \ + return setError(E_INVALIDARG, tr("Argument %s is an invalid pointer"), #a_bstrIn); \ + } while (0) + +/** + * Checks that the string argument is not a NULL, a invalid pointer or an empty + * string, returning E_INVALIDARG + extended error info on failure. + * @param a_bstrIn Input string argument (BSTR etc.). + */ +#define CheckComArgStrNotEmptyOrNull(a_bstrIn) \ + do { \ + IN_BSTR const bstrInCheck = (a_bstrIn); /* type check */ \ + if (RT_UNLIKELY(!RT_VALID_PTR(bstrInCheck) || *(bstrInCheck) == '\0')) \ + return setError(E_INVALIDARG, tr("Argument %s is empty or an invalid pointer"), #a_bstrIn); \ + } while (0) + +/** + * Checks that the given pointer to an output safe array argument is valid and + * returns E_POINTER + extended error info otherwise. + * @param arg Safe array argument. + */ +#define CheckComArgOutSafeArrayPointerValid(arg) \ + do { \ + if (RT_UNLIKELY(ComSafeArrayOutIsNull(arg))) \ + return setError(E_POINTER, \ + tr("Output argument %s points to invalid memory location (%p)"), \ + #arg, (void*)(arg)); \ + } while (0) + +/** + * Checks that safe array argument is not NULL and returns E_INVALIDARG + + * extended error info on failure. + * @param arg Input safe array argument (strings, interface pointers...) + */ +#define CheckComArgSafeArrayNotNull(arg) \ + do { \ + if (RT_UNLIKELY(ComSafeArrayInIsNull(arg))) \ + return setError(E_INVALIDARG, tr("Argument %s is NULL"), #arg); \ + } while (0) + +/** + * Sets the extended error info and returns E_NOTIMPL. + */ +#define ReturnComNotImplemented() \ + do { \ + return setError(E_NOTIMPL, tr("Method %s is not implemented"), __FUNCTION__); \ + } while (0) + + +#define DECLARE_EMPTY_CTOR_DTOR(X) public: X(); ~X(); + +#define DEFINE_EMPTY_CTOR_DTOR(X) X::X() {} X::~X() {} + + +#define VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface) \ + virtual const GUID& getClassIID() const \ + { \ + return cls::getStaticClassIID(); \ + } \ + static const GUID& getStaticClassIID() \ + { \ + return COM_IIDOF(iface); \ + } \ + virtual const char* getComponentName() const \ + { \ + return cls::getStaticComponentName(); \ + } \ + static const char* getStaticComponentName() \ + { \ + return #cls; \ + } + +/** + * VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT: + * This macro must be used once in the declaration of any class derived + * from VirtualBoxBase. It implements the pure virtual getClassIID() and + * getComponentName() methods. If this macro is not present, instances + * of a class derived from VirtualBoxBase cannot be instantiated. + * + * @param X The class name, e.g. "Class". + * @param IX The interface name which this class implements, e.g. "IClass". + */ + #define VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(cls, iface) \ + VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface) + +#include "GenodeImpl.h" + +#endif // !____H_VIRTUALBOXBASEIMPL diff --git a/repos/ports/src/virtualbox5/frontend/VirtualBoxErrorInfoImpl.cpp b/repos/ports/src/virtualbox5/frontend/VirtualBoxErrorInfoImpl.cpp new file mode 100644 index 0000000000..874b99cc51 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/VirtualBoxErrorInfoImpl.cpp @@ -0,0 +1,6 @@ +#include "dummy/macros.h" + +#include "VirtualBoxErrorInfoImpl.h" + +HRESULT VirtualBoxErrorInfo::init(HRESULT, const GUID &, const char *, + const Utf8Str &, IVirtualBoxErrorInfo *) DUMMY(E_FAIL) diff --git a/repos/ports/src/virtualbox5/frontend/VirtualBoxErrorInfoImpl.h b/repos/ports/src/virtualbox5/frontend/VirtualBoxErrorInfoImpl.h new file mode 100644 index 0000000000..19afd6e105 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/VirtualBoxErrorInfoImpl.h @@ -0,0 +1,49 @@ +#ifndef ____H_VIRTUALBOXERRORINFO +#define ____H_VIRTUALBOXERRORINFO + +#include + +class VirtualBoxErrorInfo : + public VirtualBoxBase, + VBOX_SCRIPTABLE_IMPL(IVirtualBoxErrorInfo) +{ + public: + + VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(VirtualBoxErrorInfo, IVirtualBoxErrorInfo) + + DECLARE_NOT_AGGREGATABLE(VirtualBoxErrorInfo) + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + BEGIN_COM_MAP(VirtualBoxErrorInfo) + COM_INTERFACE_ENTRY(IErrorInfo) + COM_INTERFACE_ENTRY(IVirtualBoxErrorInfo) + COM_INTERFACE_ENTRY(IDispatch) + END_COM_MAP() + + HRESULT init(HRESULT aResultCode, const GUID &aIID, + const char *pcszComponent, const com::Utf8Str &strText, + IVirtualBoxErrorInfo *aNext = NULL); + HRESULT FinalConstruct() { return S_OK; } + + /* readonly attribute long resultCode; */ + HRESULT GetResultCode(PRInt32 *aResultCode) { return S_OK; } + + /* readonly attribute long resultDetail; */ + HRESULT GetResultDetail(PRInt32 *aResultDetail) { return S_OK; } + + /* readonly attribute wstring interfaceID; */ + HRESULT GetInterfaceID(PRUnichar * *aInterfaceID) { return S_OK; } + + /* readonly attribute wstring component; */ + HRESULT GetComponent(PRUnichar * *aComponent) { return S_OK; } + + /* readonly attribute wstring text; */ + HRESULT GetText(PRUnichar * *aText) { return S_OK; } + + /* readonly attribute IVirtualBoxErrorInfo next; */ + HRESULT GetNext(IVirtualBoxErrorInfo * *aNext) { return S_OK; } + +}; + +#endif /* ____H_VIRTUALBOXERRORINFO */ diff --git a/repos/ports/src/virtualbox5/frontend/console.cc b/repos/ports/src/virtualbox5/frontend/console.cc new file mode 100644 index 0000000000..e7662c6358 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/console.cc @@ -0,0 +1,520 @@ +/* + * \brief Port of VirtualBox to Genode + * \author Norman Feske + * \author Alexander Boettcher + */ + +/* + * Copyright (C) 2013-2015 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + +#include +#include +#include + +#include "ConsoleImpl.h" +#include "MouseImpl.h" +#include "DisplayImpl.h" +#include "GuestImpl.h" + +#include "dummy/macros.h" + +#include "console.h" +#include "fb.h" + +static const bool debug = false; + +static Genode::Attached_rom_dataspace *clipboard_rom = nullptr; +static Genode::Reporter *clipboard_reporter = nullptr; +static char *decoded_clipboard_content = nullptr; + + +void Console::uninit() + DUMMY() +HRESULT Console::teleport(const com::Utf8Str &, ULONG, const com::Utf8Str &, + ULONG, ComPtr &aProgress) + DUMMY(E_FAIL) +HRESULT Console::i_teleporterTrg(PUVM, IMachine *, Utf8Str *, bool, Progress *, + bool *) + DUMMY(E_FAIL) + +HRESULT Console::i_attachToTapInterface(INetworkAdapter *networkAdapter) +{ + ULONG slot = 0; + HRESULT rc = networkAdapter->COMGETTER(Slot)(&slot); + AssertComRC(rc); + + maTapFD[slot] = (RTFILE)1; + + TRACE(rc) +} + +HRESULT Console::i_detachFromTapInterface(INetworkAdapter *networkAdapter) +{ + ULONG slot = 0; + HRESULT rc = networkAdapter->COMGETTER(Slot)(&slot); + AssertComRC(rc); + + if (maTapFD[slot] != NIL_RTFILE) + maTapFD[slot] = NIL_RTFILE; + + TRACE(rc) +} + +void fireStateChangedEvent(IEventSource* aSource, + MachineState_T a_state) +{ + if (a_state != MachineState_PoweredOff) + return; + + Genode::env()->parent()->exit(0); +} + +void fireRuntimeErrorEvent(IEventSource* aSource, BOOL a_fatal, + CBSTR a_id, CBSTR a_message) +{ + Genode::error(__func__, " : ", a_fatal, " ", + Utf8Str(a_id).c_str(), " ", + Utf8Str(a_message).c_str()); + + TRACE(); +} + +void Console::i_onAdditionsStateChange() +{ + dynamic_cast(this)->update_video_mode(); +} + +void GenodeConsole::update_video_mode() +{ + Display *d = i_getDisplay(); + Guest *g = i_getGuest(); + + IFramebuffer *pFramebuffer = NULL; + HRESULT rc = d->QueryFramebuffer(0, &pFramebuffer); + Assert(SUCCEEDED(rc) && pFramebuffer); + + Genodefb *fb = dynamic_cast(pFramebuffer); + + LONG64 ignored = 0; + + if (fb && (fb->w() == 0) && (fb->h() == 0)) { + /* interpret a size of 0x0 as indication to quit VirtualBox */ + if (PowerButton() != S_OK) + Genode::error("ACPI shutdown failed"); + return; + } + + AdditionsFacilityType_T is_graphics; + g->GetFacilityStatus(AdditionsFacilityType_Graphics, &ignored, &is_graphics); + + if (fb && is_graphics) + d->SetVideoModeHint(0 /*=display*/, + true /*=enabled*/, false /*=changeOrigin*/, + 0 /*=originX*/, 0 /*=originY*/, + fb->w(), fb->h(), + /* Windows 8 only accepts 32-bpp modes */ + 32); +} + +void GenodeConsole::handle_input(unsigned) +{ + static LONG64 mt_events [64]; + unsigned mt_number = 0; + + /* read out input capabilities of guest */ + bool guest_abs = false, guest_rel = false, guest_multi = false; + _vbox_mouse->COMGETTER(AbsoluteSupported)(&guest_abs); + _vbox_mouse->COMGETTER(RelativeSupported)(&guest_rel); + _vbox_mouse->COMGETTER(MultiTouchSupported)(&guest_multi); + + for (int i = 0, num_ev = _input.flush(); i < num_ev; ++i) { + Input::Event &ev = _ev_buf[i]; + + bool const press = ev.type() == Input::Event::PRESS; + bool const release = ev.type() == Input::Event::RELEASE; + bool const key = press || release; + bool const motion = ev.type() == Input::Event::MOTION; + bool const wheel = ev.type() == Input::Event::WHEEL; + bool const touch = ev.type() == Input::Event::TOUCH; + + if (key) { + Scan_code scan_code(ev.keycode()); + + unsigned char const release_bit = + (ev.type() == Input::Event::RELEASE) ? 0x80 : 0; + + if (scan_code.normal()) + _vbox_keyboard->PutScancode(scan_code.code() | release_bit); + + if (scan_code.ext()) { + _vbox_keyboard->PutScancode(0xe0); + _vbox_keyboard->PutScancode(scan_code.ext() | release_bit); + } + } + + /* + * Track press/release status of keys and buttons. Currently, + * only the mouse-button states are actually used. + */ + if (press) + _key_status[ev.keycode()] = true; + + if (release) + _key_status[ev.keycode()] = false; + + bool const mouse_button_event = + key && _mouse_button(ev.keycode()); + + bool const mouse_event = mouse_button_event || motion; + + if (mouse_event) { + unsigned const buttons = (_key_status[Input::BTN_LEFT] ? MouseButtonState_LeftButton : 0) + | (_key_status[Input::BTN_RIGHT] ? MouseButtonState_RightButton : 0) + | (_key_status[Input::BTN_MIDDLE] ? MouseButtonState_MiddleButton : 0); + if (ev.absolute_motion()) { + + _last_received_motion_event_was_absolute = true; + + /* transform absolute to relative if guest is so odd */ + if (!guest_abs && guest_rel) { + int const boundary = 20; + int rx = ev.ax() - _ax; + int ry = ev.ay() - _ay; + rx = Genode::min(boundary, Genode::max(-boundary, rx)); + ry = Genode::min(boundary, Genode::max(-boundary, ry)); + _vbox_mouse->PutMouseEvent(rx, ry, 0, 0, buttons); + } else + _vbox_mouse->PutMouseEventAbsolute(ev.ax(), ev.ay(), 0, + 0, buttons); + + _ax = ev.ax(); + _ay = ev.ay(); + + } else if (ev.relative_motion()) { + + _last_received_motion_event_was_absolute = false; + + /* prefer relative motion event */ + if (guest_rel) + _vbox_mouse->PutMouseEvent(ev.rx(), ev.ry(), 0, 0, buttons); + else if (guest_abs) { + _ax += ev.rx(); + _ay += ev.ry(); + _vbox_mouse->PutMouseEventAbsolute(_ax, _ay, 0, 0, buttons); + } + } + /* only the buttons changed */ + else { + + if (_last_received_motion_event_was_absolute) { + /* prefer absolute button event */ + if (guest_abs) + _vbox_mouse->PutMouseEventAbsolute(_ax, _ay, 0, 0, buttons); + else if (guest_rel) + _vbox_mouse->PutMouseEvent(0, 0, 0, 0, buttons); + } else { + /* prefer relative button event */ + if (guest_rel) + _vbox_mouse->PutMouseEvent(0, 0, 0, 0, buttons); + else if (guest_abs) + _vbox_mouse->PutMouseEventAbsolute(_ax, _ay, 0, 0, buttons); + } + + } + } + + if (wheel) { + if (_last_received_motion_event_was_absolute) + _vbox_mouse->PutMouseEventAbsolute(_ax, _ay, -ev.ry(), -ev.rx(), 0); + else + _vbox_mouse->PutMouseEvent(0, 0, -ev.ry(), -ev.rx(), 0); + } + + if (touch) { + /* if multitouch queue is full - send it */ + if (mt_number >= sizeof(mt_events) / sizeof(mt_events[0])) { + _vbox_mouse->PutEventMultiTouch(mt_number, mt_number, + mt_events, RTTimeMilliTS()); + mt_number = 0; + } + + int x = ev.ax(); + int y = ev.ay(); + int slot = ev.code(); + + /* Mouse::putEventMultiTouch drops values of 0 */ + if (x <= 0) x = 1; + if (y <= 0) y = 1; + + enum MultiTouch { + None = 0x0, + InContact = 0x01, + InRange = 0x02 + }; + + int status = MultiTouch::InContact | MultiTouch::InRange; + if (ev.touch_release()) + status = MultiTouch::None; + + uint16_t const s = RT_MAKE_U16(slot, status); + mt_events[mt_number++] = RT_MAKE_U64_FROM_U16(x, y, s, 0); + } + + } + + /* if there are elements - send it */ + if (mt_number) + _vbox_mouse->PutEventMultiTouch(mt_number, mt_number, mt_events, + RTTimeMilliTS()); +} + +void GenodeConsole::handle_mode_change(unsigned) +{ + IFramebuffer *pFramebuffer = NULL; + HRESULT rc = i_getDisplay()->QueryFramebuffer(0, &pFramebuffer); + Assert(SUCCEEDED(rc) && pFramebuffer); + + Genodefb *fb = dynamic_cast(pFramebuffer); + + fb->update_mode(); + update_video_mode(); +} + +void GenodeConsole::init_clipboard() +{ + if (!&*i_machine()) + return; + + ClipboardMode_T mode; + i_machine()->COMGETTER(ClipboardMode)(&mode); + + if (mode == ClipboardMode_Bidirectional || + mode == ClipboardMode_HostToGuest) { + + _clipboard_rom = new Genode::Attached_rom_dataspace("clipboard"); + _clipboard_rom->sigh(_clipboard_signal_dispatcher); + + clipboard_rom = _clipboard_rom; + } + + if (mode == ClipboardMode_Bidirectional || + mode == ClipboardMode_GuestToHost) { + + _clipboard_reporter = new Genode::Reporter("clipboard"); + _clipboard_reporter->enabled(true); + + clipboard_reporter = _clipboard_reporter; + } +} + +void GenodeConsole::handle_cb_rom_change(unsigned) +{ + if (!_clipboard_rom) + return; + + vboxClipboardSync(nullptr); +} + +void GenodeConsole::event_loop(IKeyboard * gKeyboard, IMouse * gMouse) +{ + _vbox_keyboard = gKeyboard; + _vbox_mouse = gMouse; + + /* register the mode change signal dispatcher at the framebuffer */ + IFramebuffer *pFramebuffer = NULL; + HRESULT rc = i_getDisplay()->QueryFramebuffer(0, &pFramebuffer); + Assert(SUCCEEDED(rc) && pFramebuffer); + + Genodefb *fb = dynamic_cast(pFramebuffer); + + fb->mode_sigh(_mode_change_signal_dispatcher); + + for (;;) { + + Genode::Signal sig = _receiver.wait_for_signal(); + Genode::Signal_dispatcher_base *dispatcher = + dynamic_cast(sig.context()); + + if (dispatcher) + dispatcher->dispatch(sig.num()); + } + +} + +void GenodeConsole::i_onMouseCapabilityChange(BOOL supportsAbsolute, + BOOL supportsRelative, + BOOL supportsMT, + BOOL needsHostCursor) +{ + if (supportsAbsolute) { + /* let the guest hide the software cursor */ + Mouse *gMouse = i_getMouse(); + gMouse->PutMouseEventAbsolute(-1, -1, 0, 0, 0); + } +} + + + + +/********************** + * Clipboard handling * + **********************/ + +struct _VBOXCLIPBOARDCONTEXT +{ + VBOXCLIPBOARDCLIENTDATA *pClient; +}; + +static VBOXCLIPBOARDCONTEXT context; + +int vboxClipboardInit (void) { return VINF_SUCCESS; } + +void vboxClipboardDestroy (void) +{ + free(decoded_clipboard_content); + clipboard_rom = nullptr; +} + +int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless) +{ + if (!pClient || context.pClient != NULL) + return VERR_NOT_SUPPORTED; + + vboxSvcClipboardLock(); + + pClient->pCtx = &context; + pClient->pCtx->pClient = pClient; + + vboxSvcClipboardUnlock(); + + int rc = vboxClipboardSync (pClient); + + return rc; +} + +void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient) +{ + if (!pClient || !pClient->pCtx) + return; + + vboxSvcClipboardLock(); + pClient->pCtx->pClient = NULL; + vboxSvcClipboardUnlock(); +} + +void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient, + uint32_t formats) +{ + if (!pClient) + return; + + vboxSvcClipboardReportMsg (pClient, + VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, + formats); +} + +int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t format, + void *pv, uint32_t const cb, uint32_t *pcbActual) +{ + if (!clipboard_rom || format != VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) + return VERR_NOT_SUPPORTED; + + if (!pv || !pcbActual || cb == 0) + return VERR_INVALID_PARAMETER; + + clipboard_rom->update(); + + if (!clipboard_rom->valid()) { + Genode::error("invalid clipboard dataspace"); + return VERR_NOT_SUPPORTED; + } + + char * data = clipboard_rom->local_addr(); + + try { + + Genode::Xml_node node(data); + if (!node.has_type("clipboard")) { + Genode::error("invalid clipboard xml syntax"); + return VERR_INVALID_PARAMETER; + } + + free(decoded_clipboard_content); + + decoded_clipboard_content = (char*)malloc(node.content_size()); + + if (!decoded_clipboard_content) { + Genode::error("could not allocate buffer for decoded clipboard content"); + return 0; + } + + size_t const len = node.decoded_content(decoded_clipboard_content, + node.content_size()); + size_t written = 0; + + PRTUTF16 utf16_string = reinterpret_cast(pv); + int rc = RTStrToUtf16Ex(decoded_clipboard_content, len, &utf16_string, cb, &written); + + if (RT_SUCCESS(rc)) { + if ((written * 2) + 2 > cb) + written = (cb - 2) / 2; + + /* +1 stuff required for Windows guests ... linux guest doesn't care */ + *pcbActual = (written + 1) * 2; + utf16_string[written] = 0; + } else + *pcbActual = 0; + + } catch (Genode::Xml_node::Invalid_syntax) { + Genode::error("invalid clipboard xml syntax"); + return VERR_INVALID_PARAMETER; + } + + return VINF_SUCCESS; +} + +void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, + uint32_t cb, uint32_t format) +{ + if (format != VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT || !pv || !pClient || + !clipboard_reporter) + return; + + PCRTUTF16 utf16str = reinterpret_cast(pv); + char * message = 0; + + int rc = RTUtf16ToUtf8(utf16str, &message); + + if (!RT_SUCCESS(rc) || !message) + return; + + try { + Genode::Reporter::Xml_generator xml(*clipboard_reporter, [&] () { + xml.append_sanitized(message, strlen(message)); }); + } catch (...) { + Genode::error("could not write clipboard data"); + } + + RTStrFree(message); +} + +int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient) +{ + if (!pClient) + pClient = context.pClient; + + if (!pClient) + return VERR_NOT_SUPPORTED; + + vboxSvcClipboardReportMsg (pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, + VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT); + + return VINF_SUCCESS; +} diff --git a/repos/ports/src/virtualbox5/frontend/console.h b/repos/ports/src/virtualbox5/frontend/console.h new file mode 100644 index 0000000000..f1d7be65ea --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/console.h @@ -0,0 +1,234 @@ +/* + * \brief Console implementation of VirtualBox for Genode + * \author Alexander Boettcher + * \author Norman Feske + * \date 2013-10-16 + */ + +/* + * Copyright (C) 2013-2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* included from os/src/drivers/input/spec/ps2 */ +#include + +/* repos/ports includes */ +#include + +/* VirtualBox includes */ +#include "ConsoleImpl.h" + + +class Scan_code +{ + private: + + class Converter + { + public: + + unsigned char scan_code [Input::KEY_UNKNOWN]; + unsigned char scan_code_ext [Input::KEY_UNKNOWN]; + + private: + + unsigned char _search_scan_code(Input::Keycode keycode) + { + for (unsigned i = 0; i < SCAN_CODE_SET_1_NUM_KEYS; i++) + if (scan_code_set_1[i] == keycode) + return i; + return 0; + } + + unsigned char _search_scan_code_ext(Input::Keycode keycode) + { + for (unsigned i = 0; i < SCAN_CODE_SET_1_NUM_KEYS; i++) + if (scan_code_set_1_0xe0[i] == keycode) + return i; + return 0; + } + + public: + + Converter() + { + init_scan_code_set_1_0xe0(); + + for (unsigned i = 0; i < Input::KEY_UNKNOWN; i++) { + scan_code [i] = _search_scan_code ((Input::Keycode)i); + scan_code_ext [i] = _search_scan_code_ext((Input::Keycode)i); + } + } + }; + + static Converter &converter() + { + static Converter inst; + return inst; + } + + Input::Keycode _keycode; + + public: + + Scan_code(Input::Keycode keycode) : _keycode(keycode) { } + + bool normal() const { return converter().scan_code[_keycode]; } + + bool valid() const + { + return normal() || ext(); + } + + unsigned char code() const + { + return converter().scan_code[_keycode]; + } + + unsigned char ext() const + { + return converter().scan_code_ext[_keycode]; + } +}; + + +class GenodeConsole : public Console { + + private: + + Input::Connection _input; + Genode::Signal_receiver _receiver; + Input::Event *_ev_buf; + unsigned _ax, _ay; + bool _last_received_motion_event_was_absolute; + Report::Connection _shape_report_connection; + Genode::Attached_dataspace _shape_report_ds; + Vbox_pointer::Shape_report *_shape_report; + Genode::Reporter *_clipboard_reporter; + Genode::Attached_rom_dataspace *_clipboard_rom; + IKeyboard *_vbox_keyboard; + IMouse *_vbox_mouse; + Genode::Signal_dispatcher _input_signal_dispatcher; + Genode::Signal_dispatcher _mode_change_signal_dispatcher; + Genode::Signal_dispatcher _clipboard_signal_dispatcher; + + bool _key_status[Input::KEY_MAX + 1]; + + static bool _mouse_button(Input::Keycode keycode) + { + return keycode == Input::BTN_LEFT + || keycode == Input::BTN_RIGHT + || keycode == Input::BTN_MIDDLE; + } + + public: + + GenodeConsole() + : + Console(), + _ev_buf(static_cast(Genode::env()->rm_session()->attach(_input.dataspace()))), + _ax(0), _ay(0), + _last_received_motion_event_was_absolute(false), + _shape_report_connection("shape", sizeof(Vbox_pointer::Shape_report)), + _shape_report_ds(_shape_report_connection.dataspace()), + _shape_report(_shape_report_ds.local_addr()), + _clipboard_reporter(nullptr), + _clipboard_rom(nullptr), + _vbox_keyboard(0), + _vbox_mouse(0), + _input_signal_dispatcher(_receiver, *this, &GenodeConsole::handle_input), + _mode_change_signal_dispatcher(_receiver, *this, &GenodeConsole::handle_mode_change), + _clipboard_signal_dispatcher(_receiver, *this, &GenodeConsole::handle_cb_rom_change) + { + for (unsigned i = 0; i <= Input::KEY_MAX; i++) + _key_status[i] = 0; + + _input.sigh(_input_signal_dispatcher); + } + + void init_clipboard(); + + void event_loop(IKeyboard * gKeyboard, IMouse * gMouse); + + void i_onMouseCapabilityChange(BOOL supportsAbsolute, + BOOL supportsRelative, BOOL supportsMT, + BOOL needsHostCursor); + + void i_onMousePointerShapeChange(bool fVisible, bool fAlpha, + uint32_t xHot, uint32_t yHot, + uint32_t width, uint32_t height, + const uint8_t *pu8Shape, + uint32_t cbShape) + { + if (fVisible && ((width == 0) || (height == 0))) + return; + + _shape_report->visible = fVisible; + _shape_report->x_hot = xHot; + _shape_report->y_hot = yHot; + _shape_report->width = width; + _shape_report->height = height; + + unsigned int and_mask_size = (_shape_report->width + 7) / 8 * + _shape_report->height; + + const unsigned char *and_mask = pu8Shape; + + const unsigned char *shape = and_mask + ((and_mask_size + 3) & ~3); + + size_t shape_size = cbShape - (shape - and_mask); + + if (shape_size > Vbox_pointer::MAX_SHAPE_SIZE) { + Genode::error(__func__, ": shape data buffer is too small for ", + shape_size, " bytes"); + return; + } + + Genode::memcpy(_shape_report->shape, + shape, + shape_size); + + if (fVisible && !fAlpha) { + + for (unsigned int i = 0; i < width * height; i++) { + + unsigned int *color = + &((unsigned int*)_shape_report->shape)[i]; + + /* heuristic from VBoxSDL.cpp */ + + if (and_mask[i / 8] & (1 << (7 - (i % 8)))) { + + if (*color & 0x00ffffff) + *color = 0xff000000; + else + *color = 0x00000000; + + } else + *color |= 0xff000000; + } + } + + _shape_report_connection.submit(sizeof(Vbox_pointer::Shape_report)); + } + + void update_video_mode(); + + void handle_input(unsigned); + void handle_mode_change(unsigned); + void handle_cb_rom_change(unsigned); +}; diff --git a/repos/ports/src/virtualbox5/frontend/dummy/autostart.cc b/repos/ports/src/virtualbox5/frontend/dummy/autostart.cc new file mode 100644 index 0000000000..b75420939e --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/dummy/autostart.cc @@ -0,0 +1,17 @@ +#include "VirtualBoxBase.h" + +#include "dummy/macros.h" + +#include "AutostartDb.h" + +static bool debug = false; + + +int AutostartDb::addAutostartVM(const char *pszVMId) DUMMY(-1) +int AutostartDb::addAutostopVM(char const*) DUMMY(-1) +int AutostartDb::removeAutostopVM(char const*) DUMMY(-1) +int AutostartDb::removeAutostartVM(char const*) DUMMY(-1) + +AutostartDb::AutostartDb() TRACE() +AutostartDb::~AutostartDb() DUMMY() +int AutostartDb::setAutostartDbPath(char const*path) TRACE(VINF_SUCCESS) diff --git a/repos/ports/src/virtualbox5/frontend/dummy/errorinfo.cc b/repos/ports/src/virtualbox5/frontend/dummy/errorinfo.cc new file mode 100644 index 0000000000..b8e1a783aa --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/dummy/errorinfo.cc @@ -0,0 +1,14 @@ +#include "VirtualBoxBase.h" + +#include "dummy/macros.h" + +#include + +static bool debug = false; + + +void ErrorInfo::init(bool aKeepObj) TRACE() +void ErrorInfo::cleanup() TRACE() +HRESULT ErrorInfoKeeper::restore() TRACE(S_OK) + +void ErrorInfo::copyFrom(const ErrorInfo &x) DUMMY() diff --git a/repos/ports/src/virtualbox5/frontend/dummy/host.cc b/repos/ports/src/virtualbox5/frontend/dummy/host.cc new file mode 100644 index 0000000000..12c88850d0 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/dummy/host.cc @@ -0,0 +1,191 @@ +#include "VirtualBoxBase.h" + +#include + +#include "dummy/macros.h" + +#include "HostImpl.h" + +static bool debug = false; + + +DEFINE_EMPTY_CTOR_DTOR(Host) + +HRESULT Host::i_findHostDriveByName(DeviceType_T mediumType, + const Utf8Str &strLocationFull, + bool fRefresh, + ComObjPtr &pMedium) + DUMMY(E_FAIL) + +HRESULT Host::i_findHostDriveById(DeviceType_T, com::Guid const&, bool, + ComObjPtr&) + TRACE(VBOX_E_OBJECT_NOT_FOUND) +HRESULT Host::i_saveSettings(settings::Host&) + TRACE(S_OK) +HRESULT Host::i_loadSettings(const settings::Host &) + TRACE(S_OK) +HRESULT Host::FinalConstruct() + TRACE(S_OK) + + +HRESULT Host::init(VirtualBox *aParent) +{ + /* Enclose the state transition NotReady->InInit->Ready */ + AutoInitSpan autoInitSpan(this); + AssertReturn(autoInitSpan.isOk(), E_FAIL); + + /* Confirm a successful initialization */ + autoInitSpan.setSucceeded(); + + return S_OK; +} + +void Host::uninit() + DUMMY() + +void Host::i_generateMACAddress(Utf8Str &mac) +{ + static unsigned counter = 1; + + mac = Utf8StrFmt("080027%06X", counter++); + + TRACE(); +} + +HRESULT Host::generateMACAddress(com::Utf8Str &aAddress) +{ + i_generateMACAddress(aAddress); + return S_OK; +} + +HRESULT Host::getProcessorFeature(ProcessorFeature_T feature, BOOL *supported) +{ + CheckComArgOutPointerValid(supported); + + switch (feature) + { + case ProcessorFeature_HWVirtEx: + *supported = true; + break; + case ProcessorFeature_PAE: + *supported = true; + break; + case ProcessorFeature_LongMode: + *supported = (sizeof(void *) > 4); + break; + case ProcessorFeature_NestedPaging: + *supported = true; + break; + default: + return setError(E_INVALIDARG, tr("The feature value is out of range.")); + } + return S_OK; +} + +#ifdef VBOX_WITH_USB +USBProxyService* Host::i_usbProxyService() +{ + TRACE(nullptr) +} + +VirtualBox* Host::i_parent() + DUMMY(nullptr) + +void Host::i_getUSBFilters(Host::USBDeviceFilterList *aGlobalFilters) + DUMMY() + +HRESULT Host::i_checkUSBProxyService() + TRACE(S_OK) + +/* +#include "HostUSBDeviceImpl.h" +#include "USBDeviceFilterImpl.h" + +bool HostUSBDevice::isMatch(const USBDeviceFilter::Data &aData) + DUMMY(false) +*/ +#endif + + +HRESULT Host::createHostOnlyNetworkInterface(ComPtr &, + ComPtr &) + DUMMY(E_FAIL) +HRESULT Host::removeHostOnlyNetworkInterface(const com::Guid &, + ComPtr &) + DUMMY(E_FAIL) + + +HRESULT Host::createUSBDeviceFilter(const com::Utf8Str &, + ComPtr &) + DUMMY(E_FAIL) +HRESULT Host::insertUSBDeviceFilter(ULONG, const ComPtr &) + DUMMY(E_FAIL) +HRESULT Host::removeUSBDeviceFilter(ULONG aPosition) + DUMMY(E_FAIL) + + +HRESULT Host::getAcceleration3DAvailable(BOOL *) + DUMMY(E_FAIL) +HRESULT Host::getDomainName(com::Utf8Str &) + DUMMY(E_FAIL) +HRESULT Host::getDVDDrives(std::vector > &) + DUMMY(E_FAIL) +HRESULT Host::getFloppyDrives(std::vector > &) + DUMMY(E_FAIL) +HRESULT Host::getMemorySize(ULONG *) + DUMMY(E_FAIL) +HRESULT Host::getMemoryAvailable(ULONG *) + DUMMY(E_FAIL) +HRESULT Host::getNameServers(std::vector &) + DUMMY(E_FAIL) +HRESULT Host::getNetworkInterfaces(std::vector > &) + DUMMY(E_FAIL) +HRESULT Host::getOperatingSystem(com::Utf8Str &) + DUMMY(E_FAIL) +HRESULT Host::getOSVersion(com::Utf8Str &) + DUMMY(E_FAIL) +HRESULT Host::getProcessorCount(ULONG *) + DUMMY(E_FAIL) +HRESULT Host::getProcessorCoreCount(ULONG *) + DUMMY(E_FAIL) +HRESULT Host::getProcessorDescription(ULONG, com::Utf8Str &) + DUMMY(E_FAIL) +HRESULT Host::getProcessorOnlineCount(ULONG *) + DUMMY(E_FAIL) +HRESULT Host::getProcessorOnlineCoreCount(ULONG *) + DUMMY(E_FAIL) +HRESULT Host::getProcessorSpeed(ULONG, ULONG *) + DUMMY(E_FAIL) +HRESULT Host::getProcessorCPUIDLeaf(ULONG, ULONG, ULONG, ULONG *, ULONG *, + ULONG *, ULONG *) + DUMMY(E_FAIL) +HRESULT Host::getSearchStrings(std::vector &) + DUMMY(E_FAIL) +HRESULT Host::getUTCTime(LONG64 *) + DUMMY(E_FAIL) +HRESULT Host::getUSBDevices(std::vector > &) + DUMMY(E_FAIL) +HRESULT Host::getUSBDeviceFilters(std::vector > &) + DUMMY(E_FAIL) +HRESULT Host::getVideoInputDevices(std::vector > &) + DUMMY(E_FAIL) + + +HRESULT Host::findHostDVDDrive(const com::Utf8Str &, ComPtr &) + DUMMY(E_FAIL) +HRESULT Host::findHostFloppyDrive(const com::Utf8Str &aName, ComPtr &) + DUMMY(E_FAIL) +HRESULT Host::findHostNetworkInterfaceByName(const com::Utf8Str &, + ComPtr &) + DUMMY(E_FAIL) +HRESULT Host::findHostNetworkInterfaceById(const com::Guid &, + ComPtr &) + DUMMY(E_FAIL) +HRESULT Host::findHostNetworkInterfacesOfType(HostNetworkInterfaceType_T, + std::vector > &) + DUMMY(E_FAIL) +HRESULT Host::findUSBDeviceByAddress(const com::Utf8Str &, + ComPtr &) + DUMMY(E_FAIL) +HRESULT Host::findUSBDeviceById(const com::Guid &, ComPtr &) + DUMMY(E_FAIL) diff --git a/repos/ports/src/virtualbox5/frontend/dummy/macros.h b/repos/ports/src/virtualbox5/frontend/dummy/macros.h new file mode 100644 index 0000000000..77121bbb76 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/dummy/macros.h @@ -0,0 +1,37 @@ +#ifndef ____H_MACROS +#define ____H_MACROS + +#include + +#define TRACE(X) \ + { \ + if (debug) \ + Genode::log(__func__, " called (", __FILE__, ") - eip=", \ + __builtin_return_address(0)); \ + return X; \ + } + +#define DUMMY(X) \ + { \ + Genode::error(__func__, " called (", __FILE__, ":", __LINE__, "), " \ + "not implemented, eip=", \ + __builtin_return_address(0)); \ + while (1) \ + asm volatile ("ud2a"); \ + \ + return X; \ + } + +#define DUMMY_STATIC(X) \ + { \ + static X dummy; \ + Genode::error(__func__, " called (", __FILE__, "), " \ + "not implemented, eip=", \ + __builtin_return_address(0)); \ + while (1) \ + asm volatile ("ud2a"); \ + \ + return dummy; \ + } + +#endif /* ____H_MACROS */ diff --git a/repos/ports/src/virtualbox5/frontend/dummy/rest.cc b/repos/ports/src/virtualbox5/frontend/dummy/rest.cc new file mode 100644 index 0000000000..1cea6abc28 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/dummy/rest.cc @@ -0,0 +1,127 @@ +#include "dummy/macros.h" + +static bool debug = false; + + +/* ApplianceImplExport.cpp */ + +#include "MachineImpl.h" + +HRESULT Machine::exportTo(const ComPtr &aAppliance, + const com::Utf8Str &aLocation, + ComPtr &aDescription) DUMMY(E_FAIL) + +/* com.cpp */ + +#include "VBox/com/Guid.h" + +const com::Guid com::Guid::Empty; + + +/* DisplayPNGUtil.cpp */ + +#include "DisplayImpl.h" + +int DisplayMakePNG(uint8_t *, uint32_t, uint32_t, uint8_t **, uint32_t *, + uint32_t *, uint32_t *, uint8_t) DUMMY(-1) + + +/* ErrorInfo.cpp */ + +#include "VBox/com/ErrorInfo.h" + +com::ProgressErrorInfo::ProgressErrorInfo(IProgress*) DUMMY() + + +/* EventImpl.cpp */ + +#include "EventImpl.h" + +HRESULT VBoxEventDesc::init(IEventSource* aSource, VBoxEventType_T aType, ...) TRACE(S_OK) +HRESULT VBoxEventDesc::reinit(VBoxEventType_T aType, ...) TRACE(S_OK) + + +/* initterm.cpp */ + +#include "VBox/com/com.h" + +HRESULT com::Initialize(bool fGui) TRACE(S_OK) +HRESULT com::Shutdown() DUMMY(E_FAIL) + + +/* ProgressProxyImpl.cpp */ + +#include "ProgressProxyImpl.h" + +STDMETHODIMP ProgressProxy::Cancel() DUMMY(E_FAIL) +void ProgressProxy::clearOtherProgressObjectInternal(bool fEarly) DUMMY() +STDMETHODIMP ProgressProxy::COMGETTER(Cancelable)(BOOL *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(Percent)(ULONG *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(TimeRemaining)(LONG *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(Completed)(BOOL *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(Canceled)(BOOL *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(ResultCode)(LONG *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(ErrorInfo)(IVirtualBoxErrorInfo **) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(Operation)(ULONG *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(OperationDescription)(BSTR *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(OperationPercent)(ULONG *) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMSETTER(Timeout)(ULONG) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::COMGETTER(Timeout)(ULONG *) DUMMY(E_FAIL) +void ProgressProxy::copyProgressInfo(IProgress *pOtherProgress, bool fEarly) DUMMY() +HRESULT ProgressProxy::FinalConstruct() DUMMY(E_FAIL) +void ProgressProxy::FinalRelease() DUMMY() +HRESULT ProgressProxy::init(VirtualBox*, IUnknown*, unsigned short const*, + bool) DUMMY(E_FAIL) +HRESULT ProgressProxy::init(VirtualBox*, void*, unsigned short const*, bool, + unsigned int, unsigned short const*, unsigned int, + unsigned int) DUMMY(E_FAIL) +HRESULT ProgressProxy::notifyComplete(HRESULT) DUMMY(E_FAIL) +HRESULT ProgressProxy::notifyComplete(HRESULT, GUID const&, char const*, + char const*, ...) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::SetCurrentOperationProgress(ULONG aPercent) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::SetNextOperation(IN_BSTR, ULONG) DUMMY(E_FAIL) +bool ProgressProxy::setOtherProgressObject(IProgress*) DUMMY(false) +void ProgressProxy::uninit() DUMMY() +STDMETHODIMP ProgressProxy::WaitForCompletion(LONG aTimeout) DUMMY(E_FAIL) +STDMETHODIMP ProgressProxy::WaitForOperationCompletion(ULONG, LONG) DUMMY(E_FAIL) + + +/* SharedFolderImpl.cpp */ + +#include "SharedFolderImpl.h" + +HRESULT SharedFolder::init(Console*, com::Utf8Str const&, com::Utf8Str const&, + bool, bool, bool) DUMMY(E_FAIL) + + +/* USBFilter.cpp */ + +#include "VBox/usbfilter.h" + +USBFILTERMATCH USBFilterGetMatchingMethod(PCUSBFILTER, USBFILTERIDX) DUMMY(USBFILTERMATCH_INVALID) +int USBFilterGetNum(PCUSBFILTER pFilter, USBFILTERIDX enmFieldIdx) DUMMY(-1) +const char * USBFilterGetString(PCUSBFILTER pFilter, USBFILTERIDX enmFieldIdx) DUMMY(nullptr) +void USBFilterInit(PUSBFILTER pFilter, USBFILTERTYPE enmType) DUMMY() +bool USBFilterIsMethodNumeric(USBFILTERMATCH enmMatchingMethod) DUMMY(false) +bool USBFilterIsMethodString(USBFILTERMATCH enmMatchingMethod) DUMMY(false) +bool USBFilterIsNumericField(USBFILTERIDX enmFieldIdx) DUMMY(false) +bool USBFilterIsStringField(USBFILTERIDX enmFieldIdx) DUMMY(false) +bool USBFilterMatch(PCUSBFILTER pFilter, PCUSBFILTER pDevice) DUMMY(false) +int USBFilterSetIgnore(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx) DUMMY(-1) +int USBFilterSetNumExact(PUSBFILTER, USBFILTERIDX, uint16_t, bool) DUMMY(-1) +int USBFilterSetNumExpression(PUSBFILTER, USBFILTERIDX, const char *, bool) DUMMY(-1) +int USBFilterSetStringExact(PUSBFILTER, USBFILTERIDX, const char *, bool) DUMMY(-1) +int USBFilterSetStringPattern(PUSBFILTER, USBFILTERIDX, const char *, bool) DUMMY(-1) +int USBFilterSetStringExact(PUSBFILTER, USBFILTERIDX, const char *, bool, + bool) DUMMY(-1) + + +/* USBProxyService.cpp */ + +#include "USBProxyService.h" + +HRESULT USBProxyService::autoCaptureDevicesForVM(SessionMachine *) DUMMY(E_FAIL) +HRESULT USBProxyService::captureDeviceForVM(SessionMachine *, IN_GUID, + com::Utf8Str const&) DUMMY(E_FAIL) +HRESULT USBProxyService::detachAllDevicesFromVM(SessionMachine*, bool, bool) DUMMY(E_FAIL) +HRESULT USBProxyService::detachDeviceFromVM(SessionMachine*, IN_GUID, bool) DUMMY(E_FAIL) diff --git a/repos/ports/src/virtualbox5/frontend/dummy/virtualboxbase.cc b/repos/ports/src/virtualbox5/frontend/dummy/virtualboxbase.cc new file mode 100644 index 0000000000..82f4a3b7fc --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/dummy/virtualboxbase.cc @@ -0,0 +1,38 @@ +#include + +#include "VirtualBoxImpl.h" +#include "VBox/com/MultiResult.h" + +#include "dummy/macros.h" + +static bool debug = false; + +HRESULT VirtualBoxBase::setError(HRESULT aResultCode, const char *pcsz, ...) +{ + va_list list; + va_start(list, pcsz); + + Genode::error(this->getComponentName(), " : ", Utf8Str(pcsz, list).c_str()); + + va_end(list); + + TRACE(aResultCode); +} + +HRESULT VirtualBox::createAppliance(ComPtr &aAppliance) DUMMY(E_FAIL) + +HRESULT VirtualBoxBase::setErrorBoth(HRESULT, int) DUMMY(E_FAIL) +HRESULT VirtualBoxBase::setErrorBoth(HRESULT, int, const char *, ...) DUMMY(E_FAIL) +HRESULT VirtualBoxBase::setErrorVrc(int) DUMMY(E_FAIL) +HRESULT VirtualBoxBase::setErrorVrc(int, char const*, ...) DUMMY(E_FAIL) +HRESULT VirtualBoxBase::setErrorNoLog(HRESULT, const char *, ...) DUMMY(E_FAIL) + +void VirtualBoxBase::clearError() TRACE() +HRESULT VirtualBoxBase::setError(HRESULT aResultCode) DUMMY(E_FAIL) +HRESULT VirtualBoxBase::setError(const com::ErrorInfo &ei) DUMMY(E_FAIL) +HRESULT VirtualBoxBase::handleUnexpectedExceptions(VirtualBoxBase *const, + RT_SRC_POS_DECL) TRACE(E_FAIL) +HRESULT VirtualBoxBase::setErrorInternal(HRESULT, GUID const&, char const*, + com::Utf8Str, bool, bool) DUMMY(E_FAIL) +HRESULT VirtualBoxBase::initializeComForThread(void) TRACE(S_OK) +void VirtualBoxBase::uninitializeComForThread(void) TRACE() diff --git a/repos/ports/src/virtualbox5/frontend/fb.h b/repos/ports/src/virtualbox5/frontend/fb.h new file mode 100644 index 0000000000..2930e524e3 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/fb.h @@ -0,0 +1,225 @@ +/* + * \brief Virtualbox framebuffer implementation for Genode + * \author Alexander Boettcher + * \date 2013-10-16 + */ + +/* + * Copyright (C) 2013-2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#define Framebuffer Fb_Genode +#include +#include +#undef Framebuffer + +#include +#include +#include + +/* VirtualBox includes */ + +#include "Global.h" +#include "VirtualBoxBase.h" + +class Genodefb : + VBOX_SCRIPTABLE_IMPL(IFramebuffer) +{ + private: + + Fb_Genode::Connection _fb; + + /* The mode matching the currently attached dataspace */ + Fb_Genode::Mode _fb_mode; + + /* The mode at the time when the mode change signal was received */ + Fb_Genode::Mode _next_fb_mode; + + /* + * The mode currently used by the VM. Can be smaller than the + * framebuffer mode. + */ + Fb_Genode::Mode _virtual_fb_mode; + + void *_fb_base; + RTCRITSECT _fb_lock; + + void _clear_screen() + { + size_t const num_pixels = _fb_mode.width() * _virtual_fb_mode.height(); + memset(_fb_base, 0, num_pixels * _fb_mode.bytes_per_pixel()); + _fb.refresh(0, 0, _virtual_fb_mode.width(), _virtual_fb_mode.height()); + } + + public: + + Genodefb () + : + _fb_mode(_fb.mode()), + _next_fb_mode(_fb_mode), + _virtual_fb_mode(_fb_mode), + _fb_base(Genode::env()->rm_session()->attach(_fb.dataspace())) + { + int rc = RTCritSectInit(&_fb_lock); + Assert(rc == VINF_SUCCESS); + } + + /* Return the next mode of the framebuffer */ + int w() const { return _next_fb_mode.width(); } + int h() const { return _next_fb_mode.height(); } + + void mode_sigh(Genode::Signal_context_capability sigh) + { + _fb.mode_sigh(sigh); + } + + void update_mode() + { + Lock(); + _next_fb_mode = _fb.mode(); + Unlock(); + } + + STDMETHODIMP Lock() + { + return Global::vboxStatusCodeToCOM(RTCritSectEnter(&_fb_lock)); + } + + STDMETHODIMP Unlock() + { + return Global::vboxStatusCodeToCOM(RTCritSectLeave(&_fb_lock)); + } + + STDMETHODIMP NotifyChange(PRUint32 screen, PRUint32, PRUint32, + PRUint32 w, PRUint32 h) override + { + HRESULT result = E_FAIL; + + Lock(); + + bool ok = (w <= (ULONG)_next_fb_mode.width()) && + (h <= (ULONG)_next_fb_mode.height()); + + if (ok) { + Genode::log("fb resize : [", screen, "] ", + _virtual_fb_mode.width(), "x", + _virtual_fb_mode.height(), " -> ", + w, "x", h); + + if ((w < (ULONG)_next_fb_mode.width()) || + (h < (ULONG)_next_fb_mode.height())) { + /* clear the old content around the new, smaller area. */ + _clear_screen(); + } + + _fb_mode = _next_fb_mode; + + _virtual_fb_mode = Fb_Genode::Mode(w, h, Fb_Genode::Mode::RGB565); + + Genode::env()->rm_session()->detach(_fb_base); + + _fb_base = Genode::env()->rm_session()->attach(_fb.dataspace()); + + result = S_OK; + + } else + Genode::log("fb resize : [", screen, "] ", + _virtual_fb_mode.width(), "x", + _virtual_fb_mode.height(), " -> ", + w, "x", h, " ignored"); + + Unlock(); + + return result; + } + + STDMETHODIMP COMGETTER(Capabilities)(ComSafeArrayOut(FramebufferCapabilities_T, enmCapabilities)) override + { + if (ComSafeArrayOutIsNull(enmCapabilities)) + return E_POINTER; + + com::SafeArray caps; + caps.resize(1); + caps[0] = FramebufferCapabilities_UpdateImage; + //caps[0] = FramebufferCapabilities_VHWA; + caps.detachTo(ComSafeArrayOutArg(enmCapabilities)); + + return S_OK; + } + + STDMETHODIMP COMGETTER(HeightReduction) (ULONG *reduce) override + { + if (!reduce) + return E_POINTER; + + *reduce = 0; + return S_OK; + } + + STDMETHODIMP NotifyUpdateImage(PRUint32 o_x, PRUint32 o_y, + PRUint32 width, PRUint32 height, + PRUint32 imageSize, + PRUint8 *image) override + { + Nitpicker::Area area_fb = Nitpicker::Area(_fb_mode.width(), + _fb_mode.height()); + Nitpicker::Area area_vm = Nitpicker::Area(width, height); + + using namespace Genode; + + typedef Pixel_rgb888 Pixel_src; + typedef Pixel_rgb565 Pixel_dst; + + Texture texture((Pixel_src *)image, nullptr, area_vm); + Surface surface((Pixel_dst *)_fb_base, area_fb); + + Dither_painter::paint(surface, texture, Surface_base::Point(o_x, o_y)); + + _fb.refresh(o_x, o_y, area_vm.w(), area_vm.h()); + + return S_OK; + } + + STDMETHODIMP COMGETTER(Overlay) (IFramebufferOverlay **) override { + return E_NOTIMPL; } + + STDMETHODIMP COMGETTER(WinId) (PRInt64 *winId) override { + return E_NOTIMPL; } + + STDMETHODIMP VideoModeSupported(ULONG, ULONG, ULONG, BOOL *) override { + return E_NOTIMPL; } + + STDMETHODIMP Notify3DEvent(PRUint32, PRUint32, PRUint8 *) override { + return E_NOTIMPL; } + + STDMETHODIMP ProcessVHWACommand(BYTE *pCommand) override { + return E_NOTIMPL; } + + STDMETHODIMP GetVisibleRegion(BYTE *, ULONG, ULONG *) override { + return E_NOTIMPL; } + + STDMETHODIMP SetVisibleRegion(BYTE *, ULONG) override { + return E_NOTIMPL; } + + STDMETHODIMP COMGETTER(PixelFormat) (ULONG *format) override { + return E_NOTIMPL; } + + HRESULT NotifyUpdate(ULONG x, ULONG y, ULONG w, ULONG h) override { + return E_NOTIMPL; } + + STDMETHODIMP COMGETTER(BitsPerPixel)(ULONG *bits) override { + return E_NOTIMPL; } + + STDMETHODIMP COMGETTER(BytesPerLine)(ULONG *line) override { + return E_NOTIMPL; } + + STDMETHODIMP COMGETTER(Width)(ULONG *width) override { + return E_NOTIMPL; } + + STDMETHODIMP COMGETTER(Height)(ULONG *height) override { + return E_NOTIMPL; } +}; diff --git a/repos/ports/src/virtualbox5/frontend/main.cc b/repos/ports/src/virtualbox5/frontend/main.cc new file mode 100644 index 0000000000..60d40ac693 --- /dev/null +++ b/repos/ports/src/virtualbox5/frontend/main.cc @@ -0,0 +1,256 @@ +/* + * \brief Port of VirtualBox to Genode + * \author Norman Feske + * \author Alexander Boettcher + * \date 2013-08-20 + */ + +/* + * Copyright (C) 2013-2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + + +/* Genode includes */ +#include +#include + +/* Virtualbox includes */ +#include +#include +#include +#include +#include + +/* Virtualbox includes of generic Main frontend */ +#include "ConsoleImpl.h" +#include "MachineImpl.h" +#include "MouseImpl.h" +#include "SessionImpl.h" +#include "VirtualBoxImpl.h" + +/* Genode port specific includes */ +#include "console.h" +#include "fb.h" + +static char c_vbox_file[128]; +static char c_vbox_vmname[128]; + + +/** + * xpcom style memory allocation + */ +void * nsMemory::Alloc(size_t size) +{ + return new char[size]; +} +void nsMemory::Free(void* ptr) +{ + Assert(ptr); + delete [] reinterpret_cast(ptr); +} +void *nsMemory::Realloc(void* ptr, size_t size) +{ + Assert(!"not implemented"); + return nullptr; +} +void * nsMemory::Clone(const void*, size_t) +{ + Assert(!"not implemented"); + return nullptr; +} + +/** + * Other stuff + */ + +int com::GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen, bool fCreateDir) +{ + AssertReturn(aDir, VERR_INVALID_POINTER); + AssertReturn(aDirLen > 1, VERR_BUFFER_OVERFLOW); + + memcpy(aDir, "/", 1); + aDir[1] = 0; + return VINF_SUCCESS; +} + +extern "C" +RTDECL(int) RTPathUserHome(char *pszPath, size_t cchPath) +{ + return com::GetVBoxUserHomeDirectory(pszPath, cchPath); +} + + +extern "C" VirtualBox * genode_global_vbox_pointer; +VirtualBox * genode_global_vbox_pointer = nullptr; + +HRESULT setupmachine() +{ + HRESULT rc; + + static com::Utf8Str vm_config(c_vbox_file); + static com::Utf8Str vm_name(c_vbox_vmname); + + /* Machine object */ + ComObjPtr machine; + rc = machine.createObject(); + if (FAILED(rc)) + return rc; + + /* Virtualbox object */ + ComObjPtr virtualbox; + rc = virtualbox.createObject(); + if (FAILED(rc)) + return rc; + + /* + * Used in src-client/ConsoleImpl.cpp, which constructs Progress objects, + * which requires the only-one pointer to VirtualBox object + */ + genode_global_vbox_pointer = virtualbox; + + rc = machine->initFromSettings(virtualbox, vm_config, nullptr); + if (FAILED(rc)) + return rc; + + rc = virtualbox->RegisterMachine(machine); + + if (FAILED(rc)) + return rc; + + + // open a session + ComObjPtr session; + rc = session.createObject(); + if (FAILED(rc)) + return rc; + + rc = machine->LockMachine(session, LockType_VM); + if (FAILED(rc)) + return rc; + + /* Validate configured memory of vbox file and Genode config */ + ULONG memory_vbox; + rc = machine->COMGETTER(MemorySize)(&memory_vbox); + if (FAILED(rc)) + return rc; + + /* request max available memory */ + size_t memory_genode = Genode::env()->ram_session()->avail() >> 20; + size_t memory_vmm = 28; + + if (memory_vbox + memory_vmm > memory_genode) { + using Genode::error; + error("Configured memory ", memory_vmm, " MB (vbox file) is insufficient."); + error(memory_genode, " MB (1) - ", + memory_vmm, " MB (2) = ", + memory_genode - memory_vmm, " MB (3)"); + error("(1) available memory based defined by Genode config"); + error("(2) minimum memory required for VBox VMM"); + error("(3) maximal available memory to VM"); + return E_FAIL; + } + + /* Console object */ + ComPtr gConsole; + rc = session->COMGETTER(Console)(gConsole.asOutParam()); + + /* handle input of Genode and forward it to VMM layer */ + ComPtr genodeConsole = gConsole; + RTLogPrintf("genodeConsole = %p\n", genodeConsole); + + genodeConsole->init_clipboard(); + + /* Display object */ + ComPtr display; + rc = gConsole->COMGETTER(Display)(display.asOutParam()); + if (FAILED(rc)) + return rc; + + ULONG cMonitors = 1; + rc = machine->COMGETTER(MonitorCount)(&cMonitors); + if (FAILED(rc)) + return rc; + + static Bstr gaFramebufferId[64]; + + unsigned uScreenId; + for (uScreenId = 0; uScreenId < cMonitors; uScreenId++) + { + Genodefb *fb = new Genodefb(); + HRESULT rc = display->AttachFramebuffer(uScreenId, fb, gaFramebufferId[uScreenId].asOutParam()); + if (FAILED(rc)) + return rc; + } + + /* Power up the VMM */ + ComPtr progress; + rc = gConsole->PowerUp(progress.asOutParam()); + if (FAILED(rc)) + return rc; + + /* wait until VM is up */ + MachineState_T machineState = MachineState_Null; + do { + if (machineState != MachineState_Null) + RTThreadSleep(1000); + + rc = machine->COMGETTER(State)(&machineState); + } while (machineState == MachineState_Starting); + if (rc != S_OK || (machineState != MachineState_Running)) + return E_FAIL; + + /* request mouse object */ + static ComPtr gMouse; + rc = gConsole->COMGETTER(Mouse)(gMouse.asOutParam()); + if (FAILED(rc)) + return rc; + Assert (&*gMouse); + + /* request keyboard object */ + ComPtr gKeyboard; + rc = gConsole->COMGETTER(Keyboard)(gKeyboard.asOutParam()); + if (FAILED(rc)) + return rc; + Assert (&*gKeyboard); + + genodeConsole->event_loop(gKeyboard, gMouse); + + Assert(!"return not expected"); + return E_FAIL; +} + + +int main(int argc, char **argv) +{ + try { + using namespace Genode; + + Xml_node node = config()->xml_node(); + Xml_node::Attribute vbox_file = node.attribute("vbox_file"); + vbox_file.value(c_vbox_file, sizeof(c_vbox_file)); + Xml_node::Attribute vm_name = node.attribute("vm_name"); + vm_name.value(c_vbox_vmname, sizeof(c_vbox_vmname)); + } catch (...) { + Genode::error("missing attributes in configuration, minimum requirements: "); + Genode::error(" " ); + throw; + } + + int rc = RTR3InitExe(argc, &argv, 0); + if (RT_FAILURE(rc)) + return -1; + + HRESULT hrc = setupmachine(); + if (FAILED(hrc)) { + Genode::error("startup of VMM failed - reason ", hrc, " '", + RTErrCOMGet(hrc)->pszMsgFull, "' - exiting ..."); + return -2; + } + + Genode::error("VMM exiting ..."); + + return 0; +} diff --git a/repos/ports/src/virtualbox5/hm.cc b/repos/ports/src/virtualbox5/hm.cc new file mode 100644 index 0000000000..616dd0e13f --- /dev/null +++ b/repos/ports/src/virtualbox5/hm.cc @@ -0,0 +1,208 @@ +/* + * \brief VirtualBox hardware-acceleration manager + * \author Norman Feske + * \date 2013-08-20 + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include + +/* VirtualBox includes */ +#include "HMInternal.h" /* enable access to hm.s.* */ +#include +#include + +/* Genode's VirtualBox includes */ +#include "sup.h" + +enum { VERBOSE_HM = false }; + +static bool enabled_hm = true; +static bool enable_pae_nx = false; +static bool enable_64bit = false; + +VMMR3DECL(int) HMR3Init(PVM pVM) +{ + PCFGMNODE pCfgHM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "HM/"); + + /* check whether to stay for non-paged modi in recompiler */ + int rc = CFGMR3QueryBoolDef(pCfgHM, "EnableUX", + &pVM->hm.s.vmx.fAllowUnrestricted, true); + AssertRCReturn(rc, rc); + + /* check whether to enable pae and nx bit - in 64bit host mode */ + rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "EnablePAE", &enable_pae_nx, + false); + AssertRCReturn(rc, rc); + + /* check whether to enable long-mode bit - in 64bit host mode */ + rc = CFGMR3QueryBoolDef(pCfgHM, "64bitEnabled", &enable_64bit, false); + AssertRCReturn(rc, rc); + + /* + * We always set the fHMEnabled flag. Otherwise, the EM won't + * consult us for taking scheduling decisions. The actual switch to + * HW accelerated mode is still dependent on the result of the + * HMR3CanExecuteGuest function. + */ + pVM->fHMEnabled = true; + + for (VMCPUID i = 0; i < pVM->cCpus; i++) + pVM->aCpus[i].hm.s.fActive = false; + + pVM->hm.s.fNestedPaging = true; + +#if HC_ARCH_BITS == 64 + PGMSetLargePageUsage(pVM, true); +#endif + + return VINF_SUCCESS; +} + + +VMMR3_INT_DECL(int) HMR3Term(PVM pVM) +{ + return VINF_SUCCESS; +} + + +VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat) +{ + enabled_hm = pVM->hm.s.svm.fSupported || pVM->hm.s.vmx.fSupported; + + if (!enabled_hm || enmWhat != VMINITCOMPLETED_RING0) + return VINF_SUCCESS; + + int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HM_SETUP_VM, 0, NULL); + + if (rc == VINF_SUCCESS) { + CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP); + + /* nova kernel supports solely on 64bit the following features */ + if (sizeof(void *) > 4 && enable_pae_nx) { + CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE); + CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX); + } + if (sizeof(void *) > 4 && enable_64bit) { + CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LONG_MODE); + CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SYSCALL); + CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LAHF); + } + } + + return rc; +} + + +VMMDECL(bool) HMIsEnabledNotMacro(PVM pVM) +{ + return pVM->fHMEnabled; +} + + +VMMR3DECL(bool) HMR3IsVmxPreemptionTimerUsed(PVM pVM) +{ + if (VERBOSE_HM) + Genode::log(__func__, "called"); + + return false; +} + + +VMMR3DECL(bool) HMR3IsActive(PVMCPU pVCpu) +{ + return pVCpu->hm.s.fActive; +} + +VMM_INT_DECL(bool) HMIsLongModeAllowed(PVM pVM) +{ + return HMIsEnabled(pVM) && pVM->hm.s.fAllow64BitGuests; +} + +VMMR3DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx) +{ + if (pVM->hm.s.vmx.fAllowUnrestricted) + return false; + + return !CPUMIsGuestInPagedProtectedModeEx(pCtx); +} + + +VMMR3DECL(bool) HMR3IsEventPending(PVMCPU pVCpu) +{ + return false; +} + + +VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx) +{ + if (!enabled_hm) + return false; + + PVMCPU pVCpu = VMMGetCpu(pVM); + + if (pVM->hm.s.vmx.fAllowUnrestricted) { + pVCpu->hm.s.fActive = true; + } else + /* enable H/W acceleration in protected and paged mode only */ + pVCpu->hm.s.fActive = CPUMIsGuestInPagedProtectedModeEx(pCtx); + + return pVCpu->hm.s.fActive; +} + + +VMM_INT_DECL(int) HMFlushTLB(PVMCPU pVCpu) { + return VINF_SUCCESS; +} + +VMM_INT_DECL(bool) HMAreNestedPagingAndFullGuestExecEnabled(PVM pVM) +{ + return HMIsEnabled(pVM) + && ( (pVM->hm.s.vmx.fSupported && pVM->hm.s.vmx.fAllowUnrestricted) + || pVM->hm.s.svm.fSupported); +} + + +VMMR3_INT_DECL(void) HMR3ResetCpu(PVMCPU pVCpu) +{ + pVCpu->hm.s.fActive = false; +} + + +VMM_INT_DECL(bool) HMIsNestedPagingActive(PVM pVM) +{ + return HMIsEnabled(pVM); +} + +/* VMM/VMMAll/HMAll.cpp */ +VMM_INT_DECL(PGMMODE) HMGetShwPagingMode(PVM pVM) +{ + Assert(HMIsNestedPagingActive(pVM)); + + if (pVM->hm.s.svm.fSupported) + return PGMMODE_NESTED; + +// Assert(pVM->hm.s.vmx.fSupported); + return PGMMODE_EPT; +} + +VMMR3_INT_DECL(void) HMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode) +{ +} + +VMM_INT_DECL(int) HMFlushTLBOnAllVCpus(PVM pVM) +{ + if (VERBOSE_HM) + Genode::log(__func__, "called"); + return VINF_SUCCESS; +} + +VBOXSTRICTRC HMR3RestartPendingIOInstr(PVM, PVMCPU, PCPUMCTX) { + return VERR_NOT_FOUND; } diff --git a/repos/ports/src/virtualbox5/mm.cc b/repos/ports/src/virtualbox5/mm.cc new file mode 100644 index 0000000000..b65170b2e5 --- /dev/null +++ b/repos/ports/src/virtualbox5/mm.cc @@ -0,0 +1,474 @@ +/* + * \brief VirtualBox memory manager (MMR3) + * \author Norman Feske + * \date 2013-08-20 + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include +#include +#include + +#include + +/* VirtualBox includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* libc memory allocator */ +#include + +#include "util.h" +#include "mm.h" + +enum { VERBOSE_MM = false }; + +static struct { + Sub_rm_connection * conn; + Libc::Mem_alloc_impl * heap; +} memory_regions [MM_TAG_HM + 1]; + + +static Libc::Mem_alloc * heap_by_mmtag(MMTAG enmTag) +{ + enum { REGION_SIZE = 4096 * 4096 }; + static Genode::Lock memory_init_lock; + + Assert(enmTag < sizeof(memory_regions) / sizeof(memory_regions[0])); + + if (memory_regions[enmTag].conn) + return memory_regions[enmTag].heap; + + Genode::Lock::Guard guard(memory_init_lock); + + if (memory_regions[enmTag].conn) + return memory_regions[enmTag].heap; + + memory_regions[enmTag].conn = new Sub_rm_connection(REGION_SIZE); + memory_regions[enmTag].heap = new Libc::Mem_alloc_impl(memory_regions[enmTag].conn); + + return memory_regions[enmTag].heap; +} + + +static Libc::Mem_alloc * heap_by_pointer(void * pv) +{ + for (unsigned i = 0; i < sizeof(memory_regions) / sizeof(memory_regions[0]); i++) { + if (!memory_regions[i].heap) + continue; + + if (memory_regions[i].conn->contains(pv)) + return memory_regions[i].heap; + } + + return nullptr; +} + + +int MMR3Init(PVM) { return VINF_SUCCESS; } +int MMR3Term(PVM) { return VINF_SUCCESS; } +int MMR3InitUVM(PUVM) { return VINF_SUCCESS; } +void MMR3TermUVM(PUVM) { } + + +void *MMR3HeapAllocU(PUVM pUVM, MMTAG enmTag, size_t cbSize) +{ + return heap_by_mmtag(enmTag)->alloc(cbSize, Genode::log2(RTMEM_ALIGNMENT)); +} + + +/** + * Return alignment to be used for allocations of given tag + */ +static unsigned align_by_mmtag(MMTAG enmTag) +{ + switch (enmTag) { + case MM_TAG_PGM: + case MM_TAG_PDM_DEVICE: + case MM_TAG_PDM_DEVICE_USER: + case MM_TAG_VMM: + case MM_TAG_CPUM_CTX: + return 12; + case MM_TAG_CPUM_CPUID: + case MM_TAG_CPUM_MSRS: + return Genode::log2(32); + case MM_TAG_PGM_PHYS: + return Genode::log2(16); + default: + return Genode::log2(RTMEM_ALIGNMENT); + } +} + + +/** + * Round allocation size for a given tag + */ +static size_t round_size_by_mmtag(MMTAG enmTag, size_t cb) +{ + return Genode::align_addr(cb, align_by_mmtag(enmTag)); +} + + +void *MMR3HeapAlloc(PVM pVM, MMTAG enmTag, size_t cbSize) +{ + size_t const rounded_size = round_size_by_mmtag(enmTag, cbSize); + return heap_by_mmtag(enmTag)->alloc(rounded_size, align_by_mmtag(enmTag)); +} + +void *MMR3HeapAllocZ(PVM pVM, MMTAG enmTag, size_t cbSize) +{ + void * const ret = MMR3HeapAlloc(pVM, enmTag, cbSize); + + if (ret) + Genode::memset(ret, 0, cbSize); + + return ret; +} + +void * MMR3HeapAllocZU(PUVM pUVM, MMTAG enmTag, size_t cbSize) { + void * const ret = MMR3HeapAllocU(pUVM, enmTag, cbSize); + + if (ret) + Genode::memset(ret, 0, cbSize); + + return ret; +} + +void * MMR3UkHeapAllocZ(PVM pVM, MMTAG enmTag, size_t cbSize, PRTR0PTR pR0Ptr) +{ + if (pR0Ptr) + *pR0Ptr = NIL_RTR0PTR; + return MMR3HeapAllocZ(pVM, enmTag, cbSize); +} + +int MMR3HeapAllocZEx(PVM pVM, MMTAG enmTag, size_t cbSize, void **ppv) +{ + *ppv = MMR3HeapAllocZ(pVM, enmTag, cbSize); + + return VINF_SUCCESS; +} + + +int MMR3HyperInitFinalize(PVM) +{ + Genode::log(__func__, "called"); + return VINF_SUCCESS; +} + + +int MMR3HyperSetGuard(PVM, void* ptr, size_t, bool) +{ + Genode::log(__func__, "called ", ptr); + return VINF_SUCCESS; +} + + +int MMR3HyperAllocOnceNoRel(PVM pVM, size_t cb, unsigned uAlignment, + MMTAG enmTag, void **ppv) +{ + AssertRelease(align_by_mmtag(enmTag) >= (uAlignment ? Genode::log2(uAlignment) : 0)); + + unsigned const align_log2 = uAlignment ? Genode::log2(uAlignment) + : align_by_mmtag(enmTag); + + size_t const rounded_size = round_size_by_mmtag(enmTag, cb); + + void *ret = heap_by_mmtag(enmTag)->alloc(rounded_size, align_log2); + if (ret) + Genode::memset(ret, 0, cb); + + *ppv = ret; + + return VINF_SUCCESS; +} + + +int MMR3HyperAllocOnceNoRelEx(PVM pVM, size_t cb, uint32_t uAlignment, + MMTAG enmTag, uint32_t fFlags, void **ppv) +{ + AssertRelease(align_by_mmtag(enmTag) >= (uAlignment ? Genode::log2(uAlignment) : 0)); + + return MMR3HyperAllocOnceNoRel(pVM, cb, uAlignment, enmTag, ppv); +} + + +int MMHyperAlloc(PVM pVM, size_t cb, unsigned uAlignment, MMTAG enmTag, void **ppv) +{ + + if (!(align_by_mmtag(enmTag) >= (uAlignment ? Genode::log2(uAlignment) : 0))) + Genode::error(__func__, " ", (int)enmTag, " ", uAlignment, " ", (int)MM_TAG_PGM); + AssertRelease(align_by_mmtag(enmTag) >= (uAlignment ? Genode::log2(uAlignment) : 0)); + + *ppv = MMR3HeapAllocZ(pVM, enmTag, cb); + + return VINF_SUCCESS; +} + + +int MMHyperFree(PVM pVM, void *pv) +{ + MMR3HeapFree(pv); + return VINF_SUCCESS; +} + + +int MMHyperDupMem(PVM pVM, const void *pvSrc, size_t cb, + unsigned uAlignment, MMTAG enmTag, void **ppv) +{ + int rc = MMHyperAlloc(pVM, cb, uAlignment, enmTag, ppv); + if (RT_SUCCESS(rc)) + memcpy(*ppv, pvSrc, cb); + + return rc; +} + +bool MMHyperIsInsideArea(PVM, RTGCPTR ptr) +{ + Genode::log(__func__, "called"); + + return false; +} + +void MMR3HeapFree(void *pv) +{ + Libc::Mem_alloc *heap = heap_by_pointer(pv); + + Assert(heap); + + heap->free(pv); +} + + +uint64_t MMR3PhysGetRamSize(PVM pVM) +{ + /* when called from REMR3Init, it is expected to return 0 */ + return 0; +} + + +int MMR3HyperMapHCPhys(PVM pVM, void *pvR3, RTR0PTR pvR0, RTHCPHYS HCPhys, + size_t cb, const char *pszDesc, PRTGCPTR pGCPtr) +{ + static_assert(sizeof(*pGCPtr) == sizeof(HCPhys) , "pointer transformation bug"); + *pGCPtr = (RTGCPTR)HCPhys; + + return VINF_SUCCESS; +} + + +int MMR3HyperReserve(PVM pVM, unsigned cb, const char *pszDesc, PRTGCPTR pGCPtr) +{ + if (VERBOSE_MM) + Genode::log("MMR3HyperReserve: cb=", Genode::Hex(cb), ", " + "pszDesc=", pszDesc); + + return VINF_SUCCESS; +} + + +VMMR3DECL(int) MMR3IncreaseBaseReservation(PVM pVM, uint64_t cAddBasePages) +{ + return VINF_SUCCESS; +} + + +int MMR3AdjustFixedReservation(PVM, int32_t, const char *pszDesc) +{ + if (VERBOSE_MM) + Genode::log(__func__, " called for '", pszDesc, "'"); + return VINF_SUCCESS; +} + + +int MMR3HyperMapMMIO2(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, + RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, + PRTRCPTR pRCPtr) +{ + if (VERBOSE_MM) + Genode::log("pszDesc=", pszDesc, " iRegion=", iRegion, " " + "off=", Genode::Hex(off), " cb=", Genode::Hex(cb)); + + return VINF_SUCCESS; +} + + +/* + * Based on 'VBox/VMM/VMMR3/MM.cpp' + */ +int MMR3InitPaging(PVM pVM) +{ + /* + * Query the CFGM values. + */ + int rc; + PCFGMNODE pMMCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "MM"); + if (!pMMCfg) + { + rc = CFGMR3InsertNode(CFGMR3GetRoot(pVM), "MM", &pMMCfg); + AssertRCReturn(rc, rc); + } + + /** @cfgm{RamSize, uint64_t, 0, 16TB, 0} + * Specifies the size of the base RAM that is to be set up during + * VM initialization. + */ + uint64_t cbRam; + rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &cbRam); + if (rc == VERR_CFGM_VALUE_NOT_FOUND) + cbRam = 0; + else + AssertMsgRCReturn(rc, ("Configuration error: Failed to query integer \"RamSize\", rc=%Rrc.\n", rc), rc); + cbRam &= X86_PTE_PAE_PG_MASK; + + /** @cfgm{RamHoleSize, uint32_t, 0, 4032MB, 512MB} + * Specifies the size of the memory hole. The memory hole is used + * to avoid mapping RAM to the range normally used for PCI memory regions. + * Must be aligned on a 4MB boundary. */ + uint32_t cbRamHole; + rc = CFGMR3QueryU32Def(CFGMR3GetRoot(pVM), "RamHoleSize", &cbRamHole, MM_RAM_HOLE_SIZE_DEFAULT); + uint64_t const offRamHole = _4G - cbRamHole; + + /* + * Make the initial memory reservation with GMM. + */ + LogFlow(("GMMR3INitialReservation missing\n")); + + /* + * If RamSize is 0 we're done now. + */ + if (cbRam < PAGE_SIZE) + { + Log(("MM: No RAM configured\n")); + return VINF_SUCCESS; + } + + /* + * Setup the base ram (PGM). + */ + if (cbRam > offRamHole) + { + rc = PGMR3PhysRegisterRam(pVM, 0, offRamHole, "Base RAM"); + if (RT_SUCCESS(rc)) + rc = PGMR3PhysRegisterRam(pVM, _4G, cbRam - offRamHole, "Above 4GB Base RAM"); + } + else + rc = PGMR3PhysRegisterRam(pVM, 0, RT_MIN(cbRam, offRamHole), "Base RAM"); + + LogFlow(("MMR3InitPaging: returns %Rrc\n", rc)); + return rc; +} + + +char * MMR3HeapStrDupU(PUVM pUVM, MMTAG enmTag, const char *string) +{ + if (!string) + return NULL; + + size_t len = strlen(string) + 1; + char *dup = reinterpret_cast(MMR3HeapAllocU(pUVM, enmTag, len)); + if (dup) + memcpy(dup, string, len); + + return dup; +} + + +char * MMR3HeapStrDup(PVM pVM, MMTAG enmTag, const char *string) +{ + Assert(pVM); + Assert(pVM->pUVM); + return MMR3HeapStrDupU(pVM->pUVM, enmTag, string); +} + + +char * MMR3HeapAPrintfVU(PUVM pUVM, MMTAG enmTag, const char *pszFormat, va_list va) +{ + /* + * The lazy bird way. + */ + char *psz; + int cch = RTStrAPrintfV(&psz, pszFormat, va); + if (cch < 0) + return NULL; + Assert(psz[cch] == '\0'); + char *pszRet = (char *)MMR3HeapAllocU(pUVM, enmTag, cch + 1); + if (pszRet) + memcpy(pszRet, psz, cch + 1); + RTStrFree(psz); + Genode::log(__func__, " called ", Genode::Cstring(pszRet), " ", Genode::Cstring(pszFormat)); + return pszRet; +} + + +VMMR3DECL(RTHCPHYS) MMR3HyperHCVirt2HCPhys(PVM pVM, void *pvR3) { + return (RTHCPHYS)(uintptr_t)pvR3; } + + +VMMDECL(RTHCPHYS) MMPage2Phys(PVM pVM, void *pvPage) { + return (RTHCPHYS)(uintptr_t)pvPage; } + + +VMMR3DECL(void *) MMR3PageAlloc(PVM pVM) +{ + using Genode::Attached_ram_dataspace; + Attached_ram_dataspace * ds = new Attached_ram_dataspace(Genode::env()->ram_session(), 4096); + return ds->local_addr(); +} + + +VMMR3DECL(void *) MMR3PageAllocLow(PVM pVM) { return MMR3PageAlloc(pVM); } + +int MMR3ReserveHandyPages(PVM pVM, uint32_t cHandyPages) +{ + Genode::log(__func__, " called"); + return VINF_SUCCESS; +} + + +VMMDECL(void *) MMHyperHeapOffsetToPtr(PVM pVM, uint32_t offHeap) +{ + if (sizeof(void*) == 8) { + uint64_t ptr = offHeap; + return reinterpret_cast(ptr); + } + + return reinterpret_cast(offHeap); +} + + +VMMDECL(uint32_t) MMHyperHeapPtrToOffset(PVM pVM, void *pv) +{ + Genode::addr_t offset = reinterpret_cast(pv); + + Assert (reinterpret_cast(offset) == pv); + + return offset; +} + + +extern "C" { + +char * MMR3HeapAPrintf(PVM pVM, MMTAG enmTag, const char *pszFormat, ...) +{ + va_list va; + va_start(va, pszFormat); + char *psz = MMR3HeapAPrintfVU(pVM->pUVM, enmTag, pszFormat, va); + va_end(va); + return psz; +} + +} diff --git a/repos/ports/src/virtualbox5/mm.h b/repos/ports/src/virtualbox5/mm.h new file mode 100644 index 0000000000..5986df40a8 --- /dev/null +++ b/repos/ports/src/virtualbox5/mm.h @@ -0,0 +1,79 @@ +/* + * \brief VirtualBox memory manager (MMR3) + * \author Norman Feske + * \date 2013-08-20 + */ + +/* + * Copyright (C) 2013-2016 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include +#include + +#include + +/** + * Sub rm_session as backend for the Libc::Mem_alloc implementation. + * Purpose is that memory allocation by vbox of a specific type (MMTYP) are + * all located within a 2G virtual window. Reason is that virtualbox converts + * internally pointers at several places in base + offset, whereby offset is + * a int32_t type. + */ +class Sub_rm_connection : private Genode::Rm_connection, + public Genode::Region_map_client +{ + + private: + + Genode::addr_t const _offset; + Genode::size_t const _size; + + public: + + Sub_rm_connection(Genode::size_t size) + : + Genode::Region_map_client(Rm_connection::create(size)), + _offset(Genode::env()->rm_session()->attach(dataspace())), + _size(size) + { } + + Local_addr attach(Genode::Dataspace_capability ds, + Genode::size_t size = 0, Genode::off_t offset = 0, + bool use_local_addr = false, + Local_addr local_addr = (void *)0, + bool executable = false) override + { + Local_addr addr = Genode::retry( + [&] () { + return Region_map_client::attach(ds, size, offset, + use_local_addr, + local_addr, + executable); }, + [&] () { + char quota[] = "ram_quota=8192"; + Genode::env()->parent()->upgrade(this->cap(), quota); + }); + + Genode::addr_t new_addr = addr; + new_addr += _offset; + return Local_addr(new_addr); + } + + bool contains(void * ptr) const + { + Genode::addr_t addr = reinterpret_cast(ptr); + + return (_offset <= addr && addr < _offset + _size); + } + + bool contains(Genode::addr_t addr) const { + return (_offset <= addr && addr < _offset + _size); } + + Genode::addr_t local_addr(Genode::addr_t addr) const { + return _offset + addr; } +}; diff --git a/repos/ports/src/virtualbox5/patches/dbg.patch b/repos/ports/src/virtualbox5/patches/dbg.patch new file mode 100644 index 0000000000..465664664b --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/dbg.patch @@ -0,0 +1,51 @@ +--- a/src/app/virtualbox/src/VBox/VMM/VMMR3/DBGF.cpp ++++ b/src/app/virtualbox/src/VBox/VMM/VMMR3/DBGF.cpp +@@ -152,6 +152,7 @@ + rc = dbgfR3RegInit(pUVM); + if (RT_SUCCESS(rc)) + { ++#if 0 + rc = dbgfR3AsInit(pUVM); + if (RT_SUCCESS(rc)) + { +@@ -164,7 +165,9 @@ + rc = dbgfR3PlugInInit(pUVM); + if (RT_SUCCESS(rc)) + { ++#endif + return VINF_SUCCESS; ++#if 0 + } + dbgfR3OSTerm(pUVM); + } +@@ -172,6 +175,7 @@ + dbgfR3AsTerm(pUVM); + } + dbgfR3RegTerm(pUVM); ++#endif + } + dbgfR3TraceTerm(pVM); + } +@@ -190,10 +194,11 @@ + VMMR3_INT_DECL(int) DBGFR3Term(PVM pVM) + { + PUVM pUVM = pVM->pUVM; +- ++#if 0 + dbgfR3PlugInTerm(pUVM); + dbgfR3OSTerm(pUVM); + dbgfR3AsTerm(pUVM); ++#endif + dbgfR3RegTerm(pUVM); + dbgfR3TraceTerm(pVM); + dbgfR3InfoTerm(pUVM); +@@ -310,7 +315,9 @@ + VMMR3_INT_DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta) + { + dbgfR3TraceRelocate(pVM); ++#if 0 + dbgfR3AsRelocate(pVM->pUVM, offDelta); ++#endif + } + + diff --git a/repos/ports/src/virtualbox5/patches/iem_wip.patch b/repos/ports/src/virtualbox5/patches/iem_wip.patch new file mode 100644 index 0000000000..8bdc0a233e --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/iem_wip.patch @@ -0,0 +1,137 @@ +--- a/src/app/virtualbox/src/VBox/VMM/VMMR3/PGM.cpp ++++ b/src/app/virtualbox/src/VBox/VMM/VMMR3/PGM.cpp +@@ -2159,7 +2159,7 @@ + VMMR3DECL(int) PGMR3InitFinalize(PVM pVM) + { + int rc; +- ++#if 0 + /* + * Reserve space for the dynamic mappings. + * Initialize the dynamic mapping pages with dummy pages to simply the cache. +@@ -2180,6 +2180,7 @@ + rc = PGMMap(pVM, pVM->pgm.s.pbDynPageMapBaseGC + offDynMap, HCPhysDummy, PAGE_SIZE, 0); + AssertRCReturn(rc, rc); + } ++#endif /* #if 0 */ + + /* + * Determine the max physical address width (MAXPHYADDR) and apply it to +@@ -2377,7 +2378,7 @@ + * (One or more of them have changed, that's why we're here.) + */ + pVM->pgm.s.pMappingsRC = MMHyperR3ToRC(pVM, pVM->pgm.s.pMappingsR3); +- for (PPGMMAPPING pCur = pVM->pgm.s.pMappingsR3; pCur->pNextR3; pCur = pCur->pNextR3) ++ for (PPGMMAPPING pCur = pVM->pgm.s.pMappingsR3; pCur && pCur->pNextR3; pCur = pCur->pNextR3) + pCur->pNextRC = MMHyperR3ToRC(pVM, pCur->pNextR3); + + /* Relocate GC addresses of Page Tables. */ +@@ -2390,6 +2391,7 @@ + } + } + ++#if 0 + /* + * Dynamic page mapping area. + */ +@@ -2412,6 +2414,7 @@ + paPages[iPage].uPte.pPae += offDelta; + } + } ++#endif /* #if 0 */ + + /* + * The Zero page. +--- a/src/app/virtualbox/src/VBox/VMM/VMMAll/PGMAllHandler.cpp ++++ b/src/app/virtualbox/src/VBox/VMM/VMMAll/PGMAllHandler.cpp +@@ -263,6 +263,9 @@ + * @param pCur The physical handler. + * @param pRam The RAM range. + */ ++#include ++extern "C" bool PGMUnmapMemoryGenode(void *, size_t size); ++ + static int pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(PVM pVM, PPGMPHYSHANDLER pCur, PPGMRAMRANGE pRam) + { + /* +@@ -298,6 +301,13 @@ + i++; + } + ++ if (pRam->pvR3 != 0) { ++ if (pCur->cPages != pRam->cb / 4096) ++ Genode::warning("dubious ? phys=", Genode::Hex(pRam->GCPhys)); ++ ++ PGMUnmapMemoryGenode(pRam->pvR3, pRam->cb); ++ } ++ + if (fFlushTLBs) + { + PGM_INVL_ALL_VCPU_TLBS(pVM); +--- a/src/app/virtualbox/include/VBox/vmm/vm.h ++++ b/src/app/virtualbox/include/VBox/vmm/vm.h +@@ -1011,7 +1011,7 @@ + #ifdef ___PGMInternal_h + struct PGM s; + #endif +- uint8_t padding[4096*2+6080]; /* multiple of 64 */ ++ uint8_t padding[4096*4 + 6080]; /* multiple of 64 */ + } pgm; + + /** HM part. */ +--- a/src/app/virtualbox/include/VBox/param.h ++++ b/src/app/virtualbox/include/VBox/param.h +@@ -92,13 +92,13 @@ + */ + /** The number of handy pages. + * This should be a power of two. */ +-#define PGM_HANDY_PAGES 128 ++#define PGM_HANDY_PAGES 512 + /** The threshold at which allocation of more handy pages is flagged. */ +-#define PGM_HANDY_PAGES_SET_FF 32 ++#define PGM_HANDY_PAGES_SET_FF 0 + /** The threshold at which we will allocate more when in ring-3. + * This is must be smaller than both PGM_HANDY_PAGES_SET_FF and + * PGM_HANDY_PAGES_MIN. */ +-#define PGM_HANDY_PAGES_R3_ALLOC 8 ++#define PGM_HANDY_PAGES_R3_ALLOC 0 + /** The threshold at which we will allocate more when in ring-0 or raw mode. + * The idea is that we should never go below this threshold while in ring-0 or + * raw mode because of PGM_HANDY_PAGES_RZ_TO_R3. However, should this happen and +@@ -107,16 +107,16 @@ + * + * This is must be smaller than both PGM_HANDY_PAGES_SET_FF and + * PGM_HANDY_PAGES_MIN. */ +-#define PGM_HANDY_PAGES_RZ_ALLOC 8 ++#define PGM_HANDY_PAGES_RZ_ALLOC 0 + /** The threshold at which we force return to R3 ASAP. + * The idea is that this should be large enough to get out of any code and up to + * the main EM loop when we are out of memory. + * This must be less or equal to PGM_HANDY_PAGES_MIN. */ +-#define PGM_HANDY_PAGES_RZ_TO_R3 24 ++#define PGM_HANDY_PAGES_RZ_TO_R3 0 + /** The minimum number of handy pages (after allocation). + * This must be greater or equal to PGM_HANDY_PAGES_SET_FF. + * Another name would be PGM_HANDY_PAGES_EXTRA_RESERVATION or _PARANOIA. :-) */ +-#define PGM_HANDY_PAGES_MIN 32 ++#define PGM_HANDY_PAGES_MIN 0 + /** @} */ + + +--- a/src/app/virtualbox/src/VBox/VMM/VMMR3/PGMPhys.cpp ++++ b/src/app/virtualbox/src/VBox/VMM/VMMR3/PGMPhys.cpp +@@ -4518,6 +4518,14 @@ + if (pVM->pgm.s.aHandyPages[i].idPage == idPage) + { + pVM->pgm.s.aHandyPages[i].idPage = NIL_GMM_PAGEID; ++ /** ++ * Required to avoid assertion during reboot of a VM on Genode. ++ * could be it solves the ++ * "todo re-test this later. Appeared to be a PGM init bug." in ++ * src/VBox/VMM/VMMR0/GMMR0.cpp of VBox 5.0.12 ++ * - todo: send email to vbox mailing list about that ++ */ ++ pVM->pgm.s.aHandyPages[i].HCPhysGCPhys = NIL_RTHCPHYS; + break; + } + if (pVM->pgm.s.aHandyPages[i].idSharedPage == idPage) diff --git a/repos/ports/src/virtualbox5/patches/series b/repos/ports/src/virtualbox5/patches/series new file mode 100644 index 0000000000..278e2d8cbe --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/series @@ -0,0 +1,9 @@ +vbox_inc.patch +vbox_main.patch +vga_vbva.patch +vmmdev.patch +usb.patch +tm_smp.patch +vmm.patch +iem_wip.patch +dbg.patch diff --git a/repos/ports/src/virtualbox5/patches/tm_smp.patch b/repos/ports/src/virtualbox5/patches/tm_smp.patch new file mode 100644 index 0000000000..085d180bc3 --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/tm_smp.patch @@ -0,0 +1,35 @@ +tm_smp.patch + +diff --git a/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp b/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp +index c3bc22d..33d705c 100644 +--- a/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp ++++ b/src/app/virtualbox/src/VBox/VMM/VMMR3/TM.cpp +@@ -210,7 +210,7 @@ VMM_INT_DECL(int) TMR3Init(PVM pVM) + pVM->tm.s.paTimerQueuesRC = MMHyperR3ToRC(pVM, pv); + + pVM->tm.s.offVM = RT_OFFSETOF(VM, tm.s); +- pVM->tm.s.idTimerCpu = pVM->cCpus - 1; /* The last CPU. */ ++ pVM->tm.s.idTimerCpu = 0; /* The first CPU. */ + pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].enmClock = TMCLOCK_VIRTUAL; + pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].u64Expire = INT64_MAX; + pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].enmClock = TMCLOCK_VIRTUAL_SYNC; +@@ -1901,10 +1901,18 @@ static DECLCALLBACK(void) tmR3TimerCallback(PRTTIMER pTimer, void *pvUser, uint6 + AssertCompile(TMCLOCK_MAX == 4); + STAM_COUNTER_INC(&pVM->tm.s.StatTimerCallback); + ++ if (VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)) { + #ifdef DEBUG_Sander /* very annoying, keep it private. */ +- if (VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER)) + Log(("tmR3TimerCallback: timer event still pending!!\n")); + #endif ++ /* ++ * The VMCPU_FF_TIMER flag could have been set by a non-destination ++ * EMT thread without waking the destination EMT thread. ++ */ ++ VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM); ++ return; ++ } ++ + if ( !VMCPU_FF_IS_SET(pVCpuDst, VMCPU_FF_TIMER) + && ( pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL_SYNC].offSchedule /** @todo FIXME - reconsider offSchedule as a reason for running the timer queues. */ + || pVM->tm.s.paTimerQueuesR3[TMCLOCK_VIRTUAL].offSchedule diff --git a/repos/ports/src/virtualbox5/patches/usb.patch b/repos/ports/src/virtualbox5/patches/usb.patch new file mode 100644 index 0000000000..677ea0e490 --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/usb.patch @@ -0,0 +1,118 @@ +usb.patch + +diff --git a/src/app/virtualbox/src/VBox/Devices/USB/USBProxyDevice.cpp b/src/app/virtualbox/src/VBox/Devices/USB/USBProxyDevice.cpp +index a51bc36..bed42e8 100644 +--- a/src/app/virtualbox/src/VBox/Devices/USB/USBProxyDevice.cpp ++++ b/src/app/virtualbox/src/VBox/Devices/USB/USBProxyDevice.cpp +@@ -843,10 +843,14 @@ static DECLCALLBACK(int) usbProxyConstruct(PPDMUSBINS pUsbIns, int iInstance, PC + /* + * Select backend and open the device. + */ ++ ++ return PDMUSB_SET_ERROR(pUsbIns, VERR_NOT_SUPPORTED, N_("USBProxy: not supported on Genode")); ++#if 0 + if (!fRemote) + pThis->pOps = &g_USBProxyDeviceHost; + else + pThis->pOps = &g_USBProxyDeviceVRDP; ++#endif /* if 0 */ + + pThis->pvInstanceDataR3 = RTMemAllocZ(pThis->pOps->cbBackend); + if (!pThis->pvInstanceDataR3) +diff --git a/src/app/virtualbox/src/VBox/Devices/USB/VUSBDevice.cpp b/src/app/virtualbox/src/VBox/Devices/USB/VUSBDevice.cpp +index 4790fcb..d649ad6 100644 +--- a/src/app/virtualbox/src/VBox/Devices/USB/VUSBDevice.cpp ++++ b/src/app/virtualbox/src/VBox/Devices/USB/VUSBDevice.cpp +@@ -1134,7 +1143,7 @@ static DECLCALLBACK(int) vusbDevUrbIoThread(RTTHREAD hThread, void *pvUser) + vusbUrbDoReapAsyncDev(pDev, RT_INDEFINITE_WAIT); + + /* Process any URBs waiting to be cancelled first. */ +- int rc = RTReqQueueProcess(pDev->hReqQueueSync, 0); /* Don't wait if there is nothing to do. */ ++ int rc = RTReqQueueProcess(pDev->hReqQueueSync, pDev->enmState == VUSB_DEVICE_STATE_RESET ? 5 : 0); /* if in reset state (takes 10ms) sleep a bit - otherwise this thread consumes in this loop a lot of cpu time */ + Assert(RT_SUCCESS(rc) || rc == VERR_TIMEOUT); + } + +diff --git a/src/app/virtualbox/src/VBox/Devices/build/VBoxDD.cpp b/src/app/virtualbox/src/VBox/Devices/build/VBoxDD.cpp +index 3173a36..8105987 100644 +--- a/src/app/virtualbox/src/VBox/Devices/build/VBoxDD.cpp ++++ b/src/app/virtualbox/src/VBox/Devices/build/VBoxDD.cpp +@@ -39,6 +39,7 @@ const void *g_apvVBoxDDDependencies[] = + NULL, + }; + ++#if 0 + + /** + * Register builtin devices. +@@ -329,6 +330,7 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_ + return VINF_SUCCESS; + } + ++#endif /* if 0 */ + + /** + * Register builtin USB device. +diff --git a/src/app/virtualbox/src/VBox/Main/include/Matching.h b/src/app/virtualbox/src/VBox/Main/include/Matching.h +index 2f01f69..9b13e37 100644 +--- a/src/app/virtualbox/src/VBox/Main/include/Matching.h ++++ b/src/app/virtualbox/src/VBox/Main/include/Matching.h +@@ -291,10 +291,12 @@ public: + return mValueAny || mValue == aValue; + } + ++#if 0 + bool isMatch (const BOOL aValue) const + { + return isMatch (bool (aValue == TRUE)); + } ++#endif /* if 0 */ + + private: + +--- a/src/app/virtualbox/src/VBox/Main/src-server/MachineImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/MachineImpl.cpp +@@ -13219,6 +13225,7 @@ + { + LogFlowThisFunc(("\n")); + ++ return S_OK; + #ifdef VBOX_WITH_USB + HRESULT rc = mUSBDeviceFilters->i_notifyProxy(true /* aInsertFilters */); + AssertComRC(rc); +@@ -13246,6 +13253,7 @@ + { + LogFlowThisFunc(("\n")); + ++ return S_OK; + #ifdef VBOX_WITH_USB + HRESULT rc = mUSBDeviceFilters->i_notifyProxy(false /* aInsertFilters */); + AssertComRC(rc); +diff --git a/src/app/virtualbox/src/VBox/Main/src-server/USBDeviceFiltersImpl.cpp b/src/app/virtualbox/src/VBox/Main/src-server/USBDeviceFiltersImpl.cpp +index 09b42f5..c179ca6 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-server/USBDeviceFiltersImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/USBDeviceFiltersImpl.cpp +@@ -1037,13 +1037,10 @@ HRESULT USBDeviceFilters::notifyProxy(bool aInsertFilters) + LogFlowThisFunc(("aInsertFilters=%RTbool\n", aInsertFilters)); + + AutoCaller autoCaller(this); +- AssertComRCReturn(autoCaller.rc(), false); ++ AssertComRCReturnRC(autoCaller.rc()); + + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + +- USBProxyService *pProxySvc = m->pHost->i_usbProxyService(); +- AssertReturn(pProxySvc, E_FAIL); +- + DeviceFilterList::const_iterator it = m->llDeviceFilters->begin(); + while (it != m->llDeviceFilters->end()) + { +@@ -1054,6 +1051,9 @@ HRESULT USBDeviceFilters::notifyProxy(bool aInsertFilters) + && pFilter->getData().mRemote.isMatch(false) /* and if the filter is NOT remote */ + ) + { ++ USBProxyService *pProxySvc = m->pHost->i_usbProxyService(); ++ AssertReturn(pProxySvc, E_FAIL); ++ + if (aInsertFilters) + { + AssertReturn(pFilter->getId() == NULL, E_FAIL); diff --git a/repos/ports/src/virtualbox5/patches/vbox_inc.patch b/repos/ports/src/virtualbox5/patches/vbox_inc.patch new file mode 100644 index 0000000000..8145e07fe9 --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/vbox_inc.patch @@ -0,0 +1,47 @@ +vbox_inc.patch + +diff --git a/src/app/virtualbox/include/VBox/com/ErrorInfo.h b/src/app/virtualbox/include/VBox/com/ErrorInfo.h +index 869b998..c6adf70 100644 +--- a/src/app/virtualbox/include/VBox/com/ErrorInfo.h ++++ b/src/app/virtualbox/include/VBox/com/ErrorInfo.h +@@ -31,8 +31,8 @@ + * @{ + */ + +-COM_STRUCT_OR_CLASS(IProgress); +-COM_STRUCT_OR_CLASS(IVirtualBoxErrorInfo); ++//COM_STRUCT_OR_CLASS(IProgress); ++//COM_STRUCT_OR_CLASS(IVirtualBoxErrorInfo); + + namespace com + { +diff --git a/src/app/virtualbox/include/VBox/com/array.h b/src/app/virtualbox/include/VBox/com/array.h +index 77f9d60..dcbad41 100644 +--- a/src/app/virtualbox/include/VBox/com/array.h ++++ b/src/app/virtualbox/include/VBox/com/array.h +@@ -219,10 +219,10 @@ struct SafeArrayTraits + protected: + + /** Initializes memory for aElem. */ +- static void Init(T &aElem) { aElem = 0; } ++ static void Init(T &aElem) { /*aElem = 0; */ } + + /** Initializes memory occupied by aElem. */ +- static void Uninit(T &aElem) { aElem = 0; } ++ static void Uninit(T &aElem) { /* aElem = 0; */ } + + /** Creates a deep copy of aFrom and stores it in aTo. */ + static void Copy(const T &aFrom, T &aTo) { aTo = aFrom; } +diff --git a/src/app/virtualbox/include/VBox/com/string.h b/src/app/virtualbox/include/VBox/com/string.h +index 263dc40..768c336 100644 +--- a/src/app/virtualbox/include/VBox/com/string.h ++++ b/src/app/virtualbox/include/VBox/com/string.h +@@ -247,7 +247,7 @@ public: + * returns a pointer to a global variable containing an empty BSTR with a proper zero + * length prefix so that Windows is happy. + */ +- CBSTR raw() const ++ BSTR raw() const + { + if (m_bstr) + return m_bstr; diff --git a/repos/ports/src/virtualbox5/patches/vbox_main.patch b/repos/ports/src/virtualbox5/patches/vbox_main.patch new file mode 100644 index 0000000000..d9a545bf37 --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/vbox_main.patch @@ -0,0 +1,1079 @@ +vbox_main.patch + +diff --git a/src/app/virtualbox/src/VBox/Main/include/NetworkServiceRunner.h b/src/app/virtualbox/src/VBox/Main/include/NetworkServiceRunner.h +index f0ec275..78a390e 100644 +--- a/src/app/virtualbox/src/VBox/Main/include/NetworkServiceRunner.h ++++ b/src/app/virtualbox/src/VBox/Main/include/NetworkServiceRunner.h +@@ -15,6 +15,9 @@ + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + ++#ifndef ____H_H_NetworkServiceRunner ++#define ____H_H_NetworkServiceRunner ++ + #include + #include + #include +@@ -55,3 +58,5 @@ private: + struct Data; + Data *m; + }; ++ ++#endif /* ____H_H_NetworkServiceRunner */ +diff --git a/src/app/virtualbox/src/VBox/Main/include/ProgressProxyImpl.h b/src/app/virtualbox/src/VBox/Main/include/ProgressProxyImpl.h +index 66f2b31..0ac7ab8 100644 +--- a/src/app/virtualbox/src/VBox/Main/include/ProgressProxyImpl.h ++++ b/src/app/virtualbox/src/VBox/Main/include/ProgressProxyImpl.h +@@ -52,7 +52,7 @@ public: + #if !defined (VBOX_COM_INPROC) + VirtualBox *pParent, + #endif +- IUnknown *pInitiator, ++ void *pInitiator, + CBSTR bstrDescription, + BOOL fCancelable, + ULONG uTotalOperationsWeight, +diff --git a/src/app/virtualbox/src/VBox/Main/include/SessionImpl.h b/src/app/virtualbox/src/VBox/Main/include/SessionImpl.h +index b0f600e..bcd6b4c 100644 +--- a/src/app/virtualbox/src/VBox/Main/include/SessionImpl.h ++++ b/src/app/virtualbox/src/VBox/Main/include/SessionImpl.h +@@ -24,6 +24,8 @@ + # include "win/resource.h" + #endif + ++class GenodeConsole; ++ + #ifdef RT_OS_WINDOWS + [threading(free)] + #endif +@@ -122,7 +124,7 @@ private: + ComPtr mControl; + + #ifndef VBOX_COM_INPROC_API_CLIENT +- ComObjPtr mConsole; ++ ComObjPtr mConsole; + #endif + + ComPtr mRemoteMachine; +diff --git a/src/app/virtualbox/src/VBox/Main/src-all/EventImpl.cpp b/src/app/virtualbox/src/VBox/Main/src-all/EventImpl.cpp +index 182f267..90b8716 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-all/EventImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-all/EventImpl.cpp +@@ -1263,7 +1263,8 @@ STDMETHODIMP EventSource::EventProcessed(IEventListener *aListener, + */ + class ATL_NO_VTABLE PassiveEventListener : + public VirtualBoxBase, +- VBOX_SCRIPTABLE_IMPL(IEventListener) ++ public IEventListener ++// VBOX_SCRIPTABLE_IMPL(IEventListener) + { + public: + +@@ -1302,7 +1303,8 @@ public: + /* Proxy listener class, used to aggregate multiple event sources into one */ + class ATL_NO_VTABLE ProxyEventListener : + public VirtualBoxBase, +- VBOX_SCRIPTABLE_IMPL(IEventListener) ++ public IEventListener ++// VBOX_SCRIPTABLE_IMPL(IEventListener) + { + ComPtr mSource; + public: +@@ -1349,8 +1351,9 @@ public: + }; + + class ATL_NO_VTABLE EventSourceAggregator : +- public VirtualBoxBase, +- VBOX_SCRIPTABLE_IMPL(IEventSource) ++// public VirtualBoxBase, ++ public EventSource ++// VBOX_SCRIPTABLE_IMPL(IEventSource) + { + typedef std::list > EventSourceList; + /* key is weak reference */ +@@ -1417,6 +1420,7 @@ public: + HRESULT removeProxyListener(IEventListener *aListener); + }; + ++#if 0 + #ifdef VBOX_WITH_XPCOM + NS_DECL_CLASSINFO(ProxyEventListener) + NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ProxyEventListener, IEventListener) +@@ -1431,6 +1435,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1_CI(EventSource, IEventSource) + NS_DECL_CLASSINFO(EventSourceAggregator) + NS_IMPL_THREADSAFE_ISUPPORTS1_CI(EventSourceAggregator, IEventSource) + #endif ++#endif + + + STDMETHODIMP EventSource::CreateListener(IEventListener **aListener) +diff --git a/src/app/virtualbox/src/VBox/Main/src-all/ProgressImpl.cpp b/src/app/virtualbox/src/VBox/Main/src-all/ProgressImpl.cpp +index fa3ecea..ac1a203 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-all/ProgressImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-all/ProgressImpl.cpp +@@ -20,9 +20,9 @@ + + + #if defined(VBOX_WITH_XPCOM) +-#include +-#include +-#include ++//#include ++//#include ++//#include + #endif /* defined(VBOX_WITH_XPCOM) */ + + #include "ProgressImpl.h" +@@ -368,6 +370,7 @@ HRESULT Progress::i_notifyComplete(HRESULT aResultCode) + if (rc == S_OK && err) + rc = err.queryInterfaceTo(errorInfo.asOutParam()); + #else /* !defined(VBOX_WITH_XPCOM) */ ++/* + nsCOMPtr es; + es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rc); + if (NS_SUCCEEDED(rc)) +@@ -374,6 +376,7 @@ HRESULT Progress::i_notifyComplete(HRESULT aResultCode) + } + } + } ++*/ + #endif /* !defined(VBOX_WITH_XPCOM) */ + + AssertMsg(rc == S_OK, ("Couldn't get error info (rc=%08X) while trying to set a failed result (%08X)!\n", +diff --git a/src/app/virtualbox/src/VBox/Main/src-all/VirtualBoxBase.cpp b/src/app/virtualbox/src/VBox/Main/src-all/VirtualBoxBase.cpp +index b43f5a6..6aef9df 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-all/VirtualBoxBase.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-all/VirtualBoxBase.cpp +@@ -23,6 +23,7 @@ + + #include + ++#if 0 + #if !defined(VBOX_WITH_XPCOM) + #include + #include +@@ -31,6 +32,7 @@ + #include + #include + #endif /* !defined(VBOX_WITH_XPCOM) */ ++#endif + + #include "VirtualBoxBase.h" + #include "AutoCaller.h" +@@ -296,6 +298,7 @@ void VirtualBoxBase::releaseCaller() + AssertMsgFailed (("mState = %d!", mState)); + } + ++#if 0 + /** + * Handles unexpected exceptions by turning them into COM errors in release + * builds or by hitting a breakpoint in the release builds. +@@ -770,6 +773,7 @@ void VirtualBoxBase::clearError(void) + #endif + } + ++#endif /* if 0 */ + + //////////////////////////////////////////////////////////////////////////////// + // +diff --git a/src/app/virtualbox/src/VBox/Main/src-client/MouseImpl.cpp b/src/app/virtualbox/src/VBox/Main/src-client/MouseImpl.cpp +index 652f2df..877b775 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-client/MouseImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-client/MouseImpl.cpp +@@ -816,7 +816,11 @@ HRESULT Mouse::putEventMultiTouch(LONG aCount, + } + } + +- if (SUCCEEDED(rc)) ++ /* ++ * Contrary to the comment of the previous if clause, the usb model ++ * triggers various assertions if 0 contacts are propagated. ++ */ ++ if (SUCCEEDED(rc) && cContacts) + { + rc = reportMultiTouchEventToDevice(cContacts, cContacts? pau64Contacts: NULL, (uint32_t)aScanTime); + +diff --git a/src/app/virtualbox/src/VBox/Main/src-client/SessionImpl.cpp b/src/app/virtualbox/src/VBox/Main/src-client/SessionImpl.cpp +index 6ea10d3..267be48 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-client/SessionImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-client/SessionImpl.cpp +@@ -17,11 +17,15 @@ + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ ++#include "console.h" + + #include "SessionImpl.h" + #include "ConsoleImpl.h" ++#include "MachineImpl.h" + #include "Global.h" ++#if 0 + #include "ClientTokenHolder.h" ++#endif + + #include "AutoCaller.h" + #include "Logging.h" +@@ -329,7 +334,9 @@ STDMETHODIMP Session::AssignMachine(IMachine *aMachine, LockType_T aLockType, + + /* query IInternalMachineControl interface */ + mControl = aMachine; ++#if 0 + AssertReturn(!!mControl, E_FAIL); ++#endif + + #ifndef VBOX_COM_INPROC_API_CLIENT + HRESULT rc = mConsole.createObject(); +@@ -349,6 +356,7 @@ STDMETHODIMP Session::AssignMachine(IMachine *aMachine, LockType_T aLockType, + AssertPtr(aToken); + #endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */ + /* create the machine client token */ ++#if 0 + try + { + #ifndef VBOX_WITH_GENERIC_SESSION_WATCHER +@@ -367,6 +375,7 @@ STDMETHODIMP Session::AssignMachine(IMachine *aMachine, LockType_T aLockType, + { + rc = E_OUTOFMEMORY; + } ++#endif + + /* + * Reference the VirtualBox object to ensure the server is up +@@ -1217,12 +1226,14 @@ HRESULT Session::unlockMachine(bool aFinalRelease, bool aFromServer, AutoWriteLo + + if (mType == SessionType_WriteLock) + { ++#if 0 + if (mClientTokenHolder) + { + delete mClientTokenHolder; + mClientTokenHolder = NULL; + } + ++#endif + if (!aFinalRelease && !aFromServer) + { + /* +diff --git a/src/app/virtualbox/src/VBox/Main/src-client/VBoxDriversRegister.cpp b/src/app/virtualbox/src/VBox/Main/src-client/VBoxDriversRegister.cpp +index 7fa0f99..d85976d 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-client/VBoxDriversRegister.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-client/VBoxDriversRegister.cpp +@@ -25,7 +25,9 @@ + #include "VMMDev.h" + #include "AudioSnifferInterface.h" + #include "Nvram.h" ++#if 0 + #include "UsbWebcamInterface.h" ++#endif + #ifdef VBOX_WITH_USB_CARDREADER + # include "UsbCardReader.h" + #endif +@@ -46,7 +48,7 @@ + * @param pCallbacks Pointer to the callback table. + * @param u32Version VBox version number. + */ +-extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_t u32Version) ++extern "C" DECLEXPORT(int) VBoxDriversRegister_Main(PCPDMDRVREGCB pCallbacks, uint32_t u32Version) + { + LogFlow(("VBoxDriversRegister: u32Version=%#x\n", u32Version)); + AssertReleaseMsg(u32Version == VBOX_VERSION, ("u32Version=%#x VBOX_VERSION=%#x\n", u32Version, VBOX_VERSION)); +@@ -67,6 +69,7 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_ + if (RT_FAILURE(rc)) + return rc; + ++#if 0 + rc = pCallbacks->pfnRegister(pCallbacks, &AudioVRDE::DrvReg); + if (RT_FAILURE(rc)) + return rc; +@@ -78,6 +81,7 @@ extern "C" DECLEXPORT(int) VBoxDriversRegister(PCPDMDRVREGCB pCallbacks, uint32_ + rc = pCallbacks->pfnRegister(pCallbacks, &EmWebcam::DrvReg); + if (RT_FAILURE(rc)) + return rc; ++#endif + + #ifdef VBOX_WITH_USB_CARDREADER + rc = pCallbacks->pfnRegister(pCallbacks, &UsbCardReader::DrvReg); +diff --git a/src/app/virtualbox/src/VBox/Main/src-client/VMMDevInterface.cpp b/src/app/virtualbox/src/VBox/Main/src-client/VMMDevInterface.cpp +index b4f4da4..a341e45 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-client/VMMDevInterface.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-client/VMMDevInterface.cpp +@@ -553,7 +553,9 @@ DECLCALLBACK(int) vmmdevIsPageFusionEnabled(PPDMIVMMDEVCONNECTOR pInterface, boo + { + PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface); + Console *pConsole = pDrv->pVMMDev->getParent(); ++#if 0 + BOOL val = 0; ++#endif + + if (!pfPageFusionEnabled) + return VERR_INVALID_POINTER; +diff --git a/src/app/virtualbox/src/VBox/Main/src-server/ClientToken.cpp b/src/app/virtualbox/src/VBox/Main/src-server/ClientToken.cpp +index be0afb8..54d5ba4 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-server/ClientToken.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/ClientToken.cpp +@@ -179,11 +179,7 @@ Machine::ClientToken::ClientToken(const ComObjPtr &pMachine, + { + mClientToken = pToken; + if (mClientToken) +- { +- rc = mClientToken->AddRef(); +- if (FAILED(rc)) +- mClientToken = NULL; +- } ++ mClientToken->AddRef(); + } + } + pToken.setNull(); +diff --git a/src/app/virtualbox/src/VBox/Main/src-server/MachineImplCloneVM.cpp b/src/app/virtualbox/src/VBox/Main/src-server/MachineImplCloneVM.cpp +index 3a7507d..ce9a2b3 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-server/MachineImplCloneVM.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/MachineImplCloneVM.cpp +@@ -889,7 +889,7 @@ HRESULT MachineCloneVM::start(IProgress **pProgress) + rc = d->pProgress.createObject(); + if (FAILED(rc)) throw rc; + rc = d->pProgress->init(p->i_getVirtualBox(), +- static_cast(d->pSrcMachine) /* aInitiator */, ++ nullptr /* aInitiator */, + Bstr(p->tr("Cloning Machine")).raw(), + true /* fCancellable */, + uCount, +diff --git a/src/app/virtualbox/src/VBox/Main/src-server/SnapshotImpl.cpp b/src/app/virtualbox/src/VBox/Main/src-server/SnapshotImpl.cpp +index ddce18b..55065d2 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-server/SnapshotImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/SnapshotImpl.cpp +@@ -2863,7 +2864,7 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask) + pAtt = findAttachment(pMachine->mMediaData->mAttachments, it->mpSource); + ComObjPtr pChildSnapshot = task.m_pSnapshot->i_getFirstChild(); + if (pChildSnapshot) + { +- pMachine = pChildSnapshot->i_getSnapshotMachine(); ++ pMachine = &*pChildSnapshot->i_getSnapshotMachine(); + childSnapshotId = pChildSnapshot->i_getId(); + } + pAtt = i_findAttachment(pMachine->mMediaData->mAttachments, it->mpSource); +diff --git a/src/app/virtualbox/src/VBox/Main/src-server/VRDEServerImpl.cpp b/src/app/virtualbox/src/VBox/Main/src-server/VRDEServerImpl.cpp +index a717aff..3d52b9f 100644 +--- a/src/app/virtualbox/src/VBox/Main/src-server/VRDEServerImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/VRDEServerImpl.cpp +@@ -486,6 +486,7 @@ STDMETHODIMP VRDEServer::GetVRDEProperty(IN_BSTR aKey, BSTR *aValue) + return S_OK; + } + ++#if 0 + static int loadVRDELibrary(const char *pszLibraryName, RTLDRMOD *phmod, PFNVRDESUPPORTEDPROPERTIES *ppfn) + { + int rc = VINF_SUCCESS; +@@ -530,6 +531,7 @@ static int loadVRDELibrary(const char *pszLibraryName, RTLDRMOD *phmod, PFNVRDES + + return rc; + } ++#endif + + STDMETHODIMP VRDEServer::COMGETTER(VRDEProperties)(ComSafeArrayOut(BSTR, aProperties)) + { +@@ -584,13 +586,14 @@ STDMETHODIMP VRDEServer::COMGETTER(VRDEProperties)(ComSafeArrayOut(BSTR, aProper + /* + * Load the VRDE library and start the server, if it is enabled. + */ +- PFNVRDESUPPORTEDPROPERTIES pfn = NULL; ++// PFNVRDESUPPORTEDPROPERTIES pfn = NULL; + RTLDRMOD hmod = NIL_RTLDRMOD; +- vrc = loadVRDELibrary(strVrdeLibrary.c_str(), &hmod, &pfn); ++// vrc = loadVRDELibrary(strVrdeLibrary.c_str(), &hmod, &pfn); ++ vrc = !vrc; + Log(("VRDEPROP: load library [%s] rc %Rrc\n", strVrdeLibrary.c_str(), vrc)); + if (RT_SUCCESS(vrc)) + { +- const char * const *papszNames = pfn(); ++ const char * const *papszNames = nullptr; //pfn(); + + if (papszNames) + { +--- a/src/app/virtualbox/include/iprt/string.h ++++ b/src/app/virtualbox/include/iprt/string.h +@@ -113,12 +113,6 @@ + RT_C_DECLS_END + #endif + +-#if !defined(RT_OS_LINUX) || !defined(_GNU_SOURCE) +-RT_C_DECLS_BEGIN +-void *memrchr(const char *pv, int ch, size_t cb); +-RT_C_DECLS_END +-#endif +- + + /** @def RT_USE_RTC_3629 + * When defined the UTF-8 range will stop at 0x10ffff. If not defined, the +--- a/src/app/virtualbox/src/VBox/Main/include/ConsoleImpl.h ++++ b/src/app/virtualbox/src/VBox/Main/include/ConsoleImpl.h +@@ -211,10 +212,12 @@ + ULONG aBalloonedVMM, ULONG aSharedVMM, + ULONG aVmNetRx, ULONG aVmNetTx) + { ++#if 0 + mControl->ReportVmStatistics(aValidStats, aCpuUser, aCpuKernel, aCpuIdle, + aMemTotal, aMemFree, aMemBalloon, aMemShared, + aMemCache, aPageTotal, aAllocVMM, aFreeVMM, + aBalloonedVMM, aSharedVMM, aVmNetRx, aVmNetTx); ++#endif /* if 0 */ + } + void i_enableVMMStatistics(BOOL aEnable); + +@@ -225,13 +228,13 @@ + + // callback callers (partly; for some events console callbacks are notified + // directly from IInternalSessionControl event handlers declared above) +- void i_onMousePointerShapeChange(bool fVisible, bool fAlpha, +- uint32_t xHot, uint32_t yHot, +- uint32_t width, uint32_t height, +- const uint8_t *pu8Shape, +- uint32_t cbShape); +- void i_onMouseCapabilityChange(BOOL supportsAbsolute, BOOL supportsRelative, +- BOOL supportsMT, BOOL needsHostCursor); ++ virtual void i_onMousePointerShapeChange(bool fVisible, bool fAlpha, ++ uint32_t xHot, uint32_t yHot, ++ uint32_t width, uint32_t height, ++ const uint8_t *pu8Shape, ++ uint32_t cbShape) = 0; ++ virtual void i_onMouseCapabilityChange(BOOL supportsAbsolute, BOOL supportsRelative, ++ BOOL supportsMT, BOOL needsHostCursor) = 0; + void i_onStateChange(MachineState_T aMachineState); + void i_onAdditionsStateChange(); + void i_onAdditionsOutdated(); +--- a/src/app/virtualbox/src/VBox/Main/src-server/MediumImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/MediumImpl.cpp +@@ -43,7 +43,7 @@ + #include + #include + +-#include ++//#include + + typedef std::list GuidList; + +@@ -787,7 +787,7 @@ + delete pTask; + + /* complete the progress if run asynchronously */ +- if (!pProgress.isNull()) ++ if (pProgress && !pProgress.isNull()) + pProgress->i_notifyComplete(rc); + + LogFlowFunc(("rc=%Rhrc\n", rc)); +@@ -2530,7 +2530,7 @@ + + pProgress.createObject(); + rc = pProgress->init(m->pVirtualBox, +- static_cast(this), ++ nullptr, + (mediumVariantFlags & MediumVariant_Fixed) + ? BstrFmt(tr("Creating fixed medium storage unit '%s'"), m->strLocationFull.c_str()).raw() + : BstrFmt(tr("Creating dynamic medium storage unit '%s'"), m->strLocationFull.c_str()).raw(), +--- a/src/app/virtualbox/src/VBox/HostServices/SharedFolders/vbsf.cpp ++++ b/src/app/virtualbox/src/VBox/HostServices/SharedFolders/vbsf.cpp +@@ -1865,7 +1865,6 @@ + + char *pszFullNewPath = NULL; + char *pszFullOldPath = NULL; +- const char *pszOldPath = (const char *)pOldPath->String.utf8; + + /* XXX: no support for UCS2 at the moment. */ + if (!BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8)) +--- a/src/app/virtualbox/src/VBox/Main/src-client/ConsoleVRDPServer.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-client/ConsoleVRDPServer.cpp +@@ -43,7 +43,9 @@ + + #include + #include ++#if 0 + #include ++#endif + #include + + class VRDPConsoleListener +@@ -125,9 +127,11 @@ + ConsoleVRDPServer *m_server; + }; + ++#if 0 + typedef ListenerImpl VRDPConsoleListenerImpl; + + VBOX_LISTENER_DECLARE(VRDPConsoleListenerImpl) ++#endif + + #ifdef DEBUG_sunlover + #define LOGDUMPPTR Log +@@ -1344,7 +1348,7 @@ + m_InputSynch.fClientNumLock = false; + m_InputSynch.fClientCapsLock = false; + m_InputSynch.fClientScrollLock = false; +- ++#if 0 + { + ComPtr es; + console->COMGETTER(EventSource)(es.asOutParam()); +@@ -1358,7 +1362,7 @@ + eventTypes.push_back(VBoxEventType_OnKeyboardLedsChanged); + es->RegisterListener(mConsoleListener, ComSafeArrayAsInParam(eventTypes), true); + } +- ++#endif + mVRDPBindPort = -1; + + #ifndef VBOX_WITH_VRDEAUTH_IN_VBOXSVC +@@ -1395,6 +1399,7 @@ + { + Stop(); + ++#if 0 + if (mConsoleListener) + { + ComPtr es; +@@ -1402,6 +1407,7 @@ + es->UnregisterListener(mConsoleListener); + mConsoleListener.setNull(); + } ++#endif + + unsigned i; + for (i = 0; i < RT_ELEMENTS(maSourceBitmaps); i++) +--- a/src/app/virtualbox/src/VBox/Main/src-server/VirtualBoxImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/VirtualBoxImpl.cpp +@@ -42,7 +42,7 @@ + #include + #include + +-#include ++//#include + + #include + #include +@@ -76,7 +76,7 @@ + #include "AutoCaller.h" + #include "Logging.h" + +-#include ++//#include + + #ifdef RT_OS_WINDOWS + # include "win/svchlp.h" +@@ -4069,6 +4069,9 @@ + */ + HRESULT VirtualBox::i_saveSettings() + { ++ Genode::log(__func__, " skipped"); ++ return S_OK; ++ + AutoCaller autoCaller(this); + AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); + +@@ -5044,8 +5047,8 @@ + + return rc; + #else +- NOREF(aName); +- NOREF(aNatNetwork); ++ NOREF(aNetworkName); ++ NOREF(aNetwork); + return E_NOTIMPL; + #endif + } +@@ -5080,7 +5083,7 @@ + found.queryInterfaceTo(aNetwork.asOutParam()); + return rc; + #else +- NOREF(aName); ++ NOREF(aNetwork); + NOREF(aNetworkName); + return E_NOTIMPL; + #endif +--- a/src/app/virtualbox/src/VBox/Runtime/common/err/errmsgxpcom.cpp ++++ b/src/app/virtualbox/src/VBox/Runtime/common/err/errmsgxpcom.cpp +@@ -106,9 +106,11 @@ + MY_ERR("NS_ERROR_FILE_ACCESS_DENIED", "NS_ERROR_FILE_ACCESS_DENIED", UINT32_C(0x80520015)), + MY_ERR("NS_SUCCESS_FILE_DIRECTORY_EMPTY", "NS_SUCCESS_FILE_DIRECTORY_EMPTY", UINT32_C(0x00520001)), + ++#if 0 + #if defined(VBOX) && !defined(IN_GUEST) && !defined(DOXYGEN_RUNNING) + # include "errmsgvboxcomdata.h" + #endif ++#endif + + { NULL, NULL, 0 } + #undef MY_ERR +--- a/src/app/virtualbox/src/VBox/Main/src-server/MachineImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/MachineImpl.cpp +@@ -8227,8 +8227,14 @@ + { + AutoCaller autoCaller(this); + AssertComRCReturnRC(autoCaller.rc()); ++#if 0 + AssertComRCReturn( getObjectState().getState() == ObjectState::InInit + || getObjectState().getState() == ObjectState::Limited, E_FAIL); ++#else ++ if (getObjectState().getState() == ObjectState::InInit || ++ getObjectState().getState() == ObjectState::Limited, E_FAIL) ++ Genode::log(__func__, " skip assertion"); ++#endif + + AssertReturn(!mData->mAccessible, E_FAIL); + +@@ -13316,8 +13322,9 @@ + Assert(mData->mSession.mProgress.isNull()); + ComObjPtr progress; + progress.createObject(); +- ComPtr pPeer(mPeer); +- progress->init(mParent, pPeer, ++ Genode::log(__func__, " skip pPeer construction"); ++// ComPtr pPeer(mPeer); ++ progress->init(mParent, nullptr, + Bstr(tr("Closing session")).raw(), + FALSE /* aCancelable */); + progress.queryInterfaceTo(aProgress.asOutParam()); +--- a/src/app/virtualbox/src/VBox/Main/src-client/ConsoleImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-client/ConsoleImpl.cpp +@@ -75,7 +75,9 @@ + + #include + #include "VBox/com/ErrorInfo.h" ++#if 0 + #include ++#endif + + #include + #include +@@ -237,6 +239,8 @@ + {} + }; + ++#if 0 ++ + // Handler for global events + //////////////////////////////////////////////////////////////////////////////// + inline static const char *networkAdapterTypeToName(NetworkAdapterType_T adapterType); +@@ -346,6 +350,7 @@ + + VBOX_LISTENER_DECLARE(VmEventListenerImpl) + ++#endif /* #if 0 */ + + // constructor / destructor + ///////////////////////////////////////////////////////////////////////////// +@@ -512,6 +517,7 @@ + rc = mDisplay->init(this); + AssertComRCReturnRC(rc); + ++#if 0 + unconst(mVRDEServerInfo).createObject(); + rc = mVRDEServerInfo->init(this); + AssertComRCReturnRC(rc); +@@ -520,6 +526,7 @@ + rc = mEmulatedUSB->init(this); + AssertComRCReturnRC(rc); + ++#endif + /* Grab global and machine shared folder lists */ + + rc = i_fetchSharedFolders(true /* aGlobal */); +@@ -527,10 +534,12 @@ + rc = i_fetchSharedFolders(false /* aGlobal */); + AssertComRCReturnRC(rc); + ++#if 0 + /* Create other child objects */ + + unconst(mConsoleVRDPServer) = new ConsoleVRDPServer(this); + AssertReturn(mConsoleVRDPServer, E_FAIL); ++#endif + + /* Figure out size of meAttachmentType vector */ + ComPtr pVirtualBox; +@@ -558,8 +567,10 @@ + || enmFirmwareType == FirmwareType_EFI64 + || enmFirmwareType == FirmwareType_EFIDUAL) + { ++#if 0 + unconst(mNvram) = new Nvram(this); + AssertReturn(mNvram, E_FAIL); ++#endif + } + + #ifdef VBOX_WITH_USB_CARDREADER +@@ -573,6 +584,7 @@ + unconst(m_pKeyStore) = new SecretKeyStore(true /* fKeyBufNonPageable */); + AssertReturn(m_pKeyStore, E_FAIL); + ++#if 0 + /* VirtualBox events registration. */ + { + ComPtr pES; +@@ -590,6 +602,7 @@ + rc = pES->RegisterListener(aVmListener, ComSafeArrayAsInParam(eventTypes), true); + AssertComRC(rc); + } ++#endif + } + + /* Confirm a successful initialization when it's the case */ +@@ -606,6 +619,7 @@ + return S_OK; + } + ++#if 0 + /** + * Uninitializes the Console object. + */ +@@ -1014,6 +1028,8 @@ + + #endif /* VBOX_WITH_GUEST_PROPS */ + ++#endif /* #if 0 */ ++ + bool Console::i_isResetTurnedIntoPowerOff(void) + { + Bstr value; +@@ -1943,8 +1959,11 @@ + + HRESULT Console::getEmulatedUSB(ComPtr &aEmulatedUSB) + { ++ Assert(!"emulated USB issue!!!"); ++#if 0 + /* mEmulatedUSB is constant during life time, no need to lock */ + mEmulatedUSB.queryInterfaceTo(aEmulatedUSB.asOutParam()); ++#endif + + return S_OK; + } +@@ -6614,6 +6634,7 @@ + fireStateChangedEvent(mEventSource, machineState); + } + ++#if 0 + void Console::i_onAdditionsStateChange() + { + AutoCaller autoCaller(this); +@@ -6621,6 +6642,7 @@ + + fireAdditionsStateChangedEvent(mEventSource); + } ++#endif + + /** + * @remarks This notification only is for reporting an incompatible +@@ -6920,6 +6942,8 @@ + } + } + ++#if 0 ++ + char szError[RTPATH_MAX + 128]; + int vrc = com::VBoxLogRelCreate("VM", logFile.c_str(), + RTLOGFLAGS_PREFIX_TIME_PROG | RTLOGFLAGS_RESTRICT_GROUPS, +@@ -6940,6 +6964,8 @@ + if (SUCCEEDED(hrc) || cHistoryFiles) + RTDirFlush(logDir.c_str()); + ++#endif /* if 0 */ ++ + return hrc; + } + +@@ -6951,6 +6977,8 @@ + * @param aProgress Where to return the progress object. + * @param aPaused true if PowerUpPaused called. + */ ++extern "C" VirtualBox * genode_global_vbox_pointer; ++ + HRESULT Console::i_powerUp(IProgress **aProgress, bool aPaused) + { + +@@ -7228,7 +7255,8 @@ + ++cOperations; + ulTotalOperationsWeight += 1; + } +- rc = pPowerupProgress->init(static_cast(this), ++ rc = pPowerupProgress->init(genode_global_vbox_pointer, ++ static_cast(this), + progressDesc.raw(), + TRUE, // Cancelable + cOperations, +@@ -7240,13 +7268,15 @@ + else if ( mMachineState == MachineState_Saved + || (!fTeleporterEnabled && !fFaultToleranceSyncEnabled)) + { +- rc = pPowerupProgress->init(static_cast(this), ++ rc = pPowerupProgress->init(genode_global_vbox_pointer, ++ static_cast(this), + progressDesc.raw(), + FALSE /* aCancelable */); + } + else if (fTeleporterEnabled) + { +- rc = pPowerupProgress->init(static_cast(this), ++ rc = pPowerupProgress->init(genode_global_vbox_pointer, ++ static_cast(this), + progressDesc.raw(), + TRUE /* aCancelable */, + 3 /* cOperations */, +@@ -7256,7 +7286,8 @@ + } + else if (fFaultToleranceSyncEnabled) + { +- rc = pPowerupProgress->init(static_cast(this), ++ rc = pPowerupProgress->init(genode_global_vbox_pointer, ++ static_cast(this), + progressDesc.raw(), + TRUE /* aCancelable */, + 3 /* cOperations */, +@@ -8598,6 +8631,7 @@ + Address.c_str(), uuid.raw())); + + void *pvRemoteBackend = NULL; ++#if 0 + if (fRemote) + { + RemoteUSBDevice *pRemoteUSBDevice = static_cast(aHostDevice); +@@ -8605,7 +8639,7 @@ + if (!pvRemoteBackend) + return E_INVALIDARG; /* The clientId is invalid then. */ + } +- ++#endif + USHORT portVersion = 0; + hrc = aHostDevice->COMGETTER(PortVersion)(&portVersion); + AssertComRCReturnRC(hrc); +@@ -8719,12 +8753,13 @@ + i_setErrorStatic(hrc2, "GetRemote() failed"); + + PCRTUUID pUuid = aHostDevice->i_id().raw(); ++#if 0 + if (fRemote) + { + Guid guid(*pUuid); + i_consoleVRDPServer()->USBBackendReleasePointer(&guid); + } +- ++#endif + alock.release(); + int vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), 0 /* idDstCpu (saved state, see #6232) */, + (PFNRT)i_usbDetachCallback, 5, +@@ -8768,7 +8803,7 @@ + return vrc; + } + #endif /* VBOX_WITH_USB */ +- ++#if 0 + /* Note: FreeBSD needs this whether netflt is used or not. */ + #if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || defined(RT_OS_FREEBSD)) + /** +@@ -9004,6 +9039,8 @@ + } + #endif /* (RT_OS_LINUX || RT_OS_FREEBSD) && !VBOX_WITH_NETFLT */ + ++#endif /* #if 0 */ ++ + /** + * Called at power down to terminate host interface networking. + * +@@ -9464,6 +9501,7 @@ + /* Create the VRDP server. In case of headless operation, this will + * also create the framebuffer, required at VM creation. + */ ++#if 0 + ConsoleVRDPServer *server = pConsole->i_consoleVRDPServer(); + Assert(server); + +@@ -9510,6 +9548,7 @@ + vrc, errMsg.c_str())); + throw i_setErrorStatic(E_FAIL, errMsg.c_str()); + } ++#endif + + ComPtr pMachine = pConsole->i_machine(); + ULONG cCpus = 1; +@@ -9534,8 +9573,10 @@ + + alock.acquire(); + ++#if 0 + /* Enable client connections to the server. */ + pConsole->i_consoleVRDPServer()->EnableConnections(); ++#endif + + if (RT_SUCCESS(vrc)) + { +--- a/src/app/virtualbox/src/VBox/Main/src-client/ConsoleImpl2.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-client/ConsoleImpl2.cpp +@@ -128,6 +128,7 @@ + *********************************************************************************************************************************/ + static Utf8Str *GetExtraDataBoth(IVirtualBox *pVirtualBox, IMachine *pMachine, const char *pszName, Utf8Str *pStrValue); + ++#if 0 + + /* Darwin compile kludge */ + #undef PVM +@@ -135,6 +136,7 @@ + /* Comment out the following line to remove VMWare compatibility hack. */ + #define VMWARE_NET_IN_SLOT_11 + ++#endif + /** + * Translate IDE StorageControllerType_T to string representation. + */ +@@ -529,6 +531,7 @@ + return VINF_SUCCESS; + } + ++#if 0 + #ifdef VBOX_WITH_PCI_PASSTHROUGH + HRESULT Console::i_attachRawPCIDevices(PUVM pUVM, BusAssignmentManager *pBusMgr, PCFGMNODE pDevices) + { +@@ -668,6 +671,7 @@ + } + #endif + ++#endif /* if 0 */ + + void Console::i_attachStatusDriver(PCFGMNODE pCtlInst, PPDMLED *papLeds, + uint64_t uFirst, uint64_t uLast, +@@ -2625,6 +2629,7 @@ + * Parallel (LPT) Ports + */ + /* parallel enabled mask to be passed to dev ACPI */ ++#if 0 + uint16_t auParallelIoPortBase[SchemaDefs::ParallelPortCount] = {0}; + uint8_t auParallelIrq[SchemaDefs::ParallelPortCount] = {0}; + InsertConfigNode(pDevices, "parallel", &pDev); +@@ -2661,7 +2666,7 @@ + InsertConfigString(pLunL1, "DevicePath", bstr); + } + } +- ++#endif + /* + * VMM Device + */ +@@ -3083,12 +3088,13 @@ + InsertConfigInteger(pCfg, "Serial3IoPortBase", auSerialIoPortBase[3]); + InsertConfigInteger(pCfg, "Serial3Irq", auSerialIrq[3]); + } +- ++#if 0 + InsertConfigInteger(pCfg, "Parallel0IoPortBase", auParallelIoPortBase[0]); + InsertConfigInteger(pCfg, "Parallel0Irq", auParallelIrq[0]); + + InsertConfigInteger(pCfg, "Parallel1IoPortBase", auParallelIoPortBase[1]); + InsertConfigInteger(pCfg, "Parallel1Irq", auParallelIrq[1]); ++#endif + + InsertConfigNode(pInst, "LUN#0", &pLunL0); + InsertConfigString(pLunL0, "Driver", "ACPIHost"); +@@ -3820,6 +3826,8 @@ + ComPtr pMedium; + hrc = pMediumAtt->COMGETTER(Medium)(pMedium.asOutParam()); H(); + ++#if 0 ++ + /* + * 1. Only check this for hard disk images. + * 2. Only check during VM creation and not later, especially not during +@@ -4004,6 +4012,8 @@ + } + } + ++#endif /* if 0 */ ++ + if (pMedium) + { + BOOL fHostDrive; +@@ -4134,7 +4144,7 @@ + // InsertConfig* throws + try + { +- int rc = VINF_SUCCESS; ++// int rc = VINF_SUCCESS; + HRESULT hrc; + Bstr bstr; + PCFGMNODE pLunL1 = NULL; +--- a/src/app/virtualbox/src/VBox/Main/src-client/DisplayImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-client/DisplayImpl.cpp +@@ -956,7 +956,9 @@ + + /* Inform the VRDP server about the change of display parameters. */ + LogRelFlowFunc(("Calling VRDP\n")); ++#if 0 + mParent->i_consoleVRDPServer()->SendResize(); ++#endif + + /* And re-send the seamless rectangles if necessary. */ + if (mfSeamlessEnabled) +@@ -1076,7 +1078,9 @@ + * either in VideoAccelFlush or displayVBVAUpdateProcess. + * Inform the server here only if VBVA is disabled. + */ ++#if 0 + mParent->i_consoleVRDPServer()->SendUpdateBitmap(uScreenId, x, y, w, h); ++#endif + } + } + +@@ -2452,8 +2456,10 @@ + rc = VERR_INVALID_PARAMETER; + } + ++#if 0 + if (RT_SUCCESS(rc)) + pDisplay->mParent->i_consoleVRDPServer()->SendUpdateBitmap(aScreenId, x, y, width, height); ++#endif + + return rc; + } +@@ -3023,6 +3029,7 @@ + * The server can now process redraw requests from clients or initial + * fullscreen updates for new clients. + */ ++#if 0 + for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++) + { + DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId]; +@@ -3030,6 +3037,7 @@ + Assert(pDisplay->mParent && pDisplay->mParent->i_consoleVRDPServer()); + pDisplay->mParent->i_consoleVRDPServer()->SendUpdate(uScreenId, NULL, 0); + } ++#endif + } + + #ifdef VBOX_WITH_VPX +@@ -3830,7 +3838,9 @@ + pHdrUnconst->y -= (int16_t)pFBInfo->yOrigin; + + /* @todo new SendUpdate entry which can get a separate cmd header or coords. */ ++#if 0 + pThis->mParent->i_consoleVRDPServer()->SendUpdate(uScreenId, pCmd, (uint32_t)cbCmd); ++#endif + + *pHdrUnconst = hdrSaved; + } +@@ -4031,7 +4041,9 @@ + { + /* VRDP server still need this notification. */ + LogRelFlowFunc(("Calling VRDP\n")); ++#if 0 + pThis->mParent->i_consoleVRDPServer()->SendResize(); ++#endif + } + return VINF_SUCCESS; + } +--- a/src/app/virtualbox/src/VBox/Main/src-server/SystemPropertiesImpl.cpp ++++ b/src/app/virtualbox/src/VBox/Main/src-server/SystemPropertiesImpl.cpp +@@ -1191,8 +1191,8 @@ + HRESULT SystemProperties::i_setLoggingLevel(const com::Utf8Str &aLoggingLevel) + { + Utf8Str useLoggingLevel(aLoggingLevel); +- if (useLoggingLevel.isEmpty()) +- useLoggingLevel = VBOXSVC_LOG_DEFAULT; ++// if (useLoggingLevel.isEmpty()) ++// useLoggingLevel = VBOXSVC_LOG_DEFAULT; + int rc = RTLogGroupSettings(RTLogRelGetDefaultInstance(), useLoggingLevel.c_str()); + // If failed and not the default logging level - try to use the default logging level. + if (RT_FAILURE(rc)) diff --git a/repos/ports/src/virtualbox5/patches/vga_vbva.patch b/repos/ports/src/virtualbox5/patches/vga_vbva.patch new file mode 100644 index 0000000000..2355c0bbd2 --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/vga_vbva.patch @@ -0,0 +1,16 @@ +vga_vbva.patch + +diff --git a/src/app/virtualbox/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp b/src/app/virtualbox/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp +index 28ab4a8..1cc8e6b 100644 +--- a/src/app/virtualbox/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp ++++ b/src/app/virtualbox/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp +@@ -546,7 +546,8 @@ static int vbvaDisable (unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pC + pVGAState->fGuestCaps = 0; + pVGAState->pDrv->pfnVBVAGuestCapabilityUpdate(pVGAState->pDrv, pVGAState->fGuestCaps); + } +- pVGAState->pDrv->pfnVBVADisable(pVGAState->pDrv, uScreenId); ++ if (pVGAState->pDrv->pfnVBVADisable) ++ pVGAState->pDrv->pfnVBVADisable(pVGAState->pDrv, uScreenId); + return VINF_SUCCESS; + } + diff --git a/repos/ports/src/virtualbox5/patches/vmm.patch b/repos/ports/src/virtualbox5/patches/vmm.patch new file mode 100644 index 0000000000..d60ee0d305 --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/vmm.patch @@ -0,0 +1,17 @@ +--- a/src/app/virtualbox/src/VBox/VMM/VMMR3/EM.cpp ++++ b/src/app/virtualbox/src/VBox/VMM/VMMR3/EM.cpp +@@ -2211,10 +2227,11 @@ + */ + case VINF_EM_RESCHEDULE_REM: + Assert(!pVM->em.s.fIemExecutesAll || pVCpu->em.s.enmState != EMSTATE_IEM); +- if (HMIsEnabled(pVM)) ++ if (HMIsEnabled(pVM) && ++ !(VM_FF_IS_PENDING(pVM, VM_FF_ALL_REM_MASK) || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))) + { +- Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d -> %d (EMSTATE_IEM_THEN_REM)\n", +- enmOldState, EMSTATE_IEM_THEN_REM)); ++ Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d, %d -> %d (EMSTATE_IEM_THEN_REM)\n", ++ pVCpu->em.s.enmState, enmOldState, EMSTATE_IEM_THEN_REM)); + if (pVCpu->em.s.enmState != EMSTATE_IEM_THEN_REM) + { + pVCpu->em.s.enmState = EMSTATE_IEM_THEN_REM; diff --git a/repos/ports/src/virtualbox5/patches/vmmdev.patch b/repos/ports/src/virtualbox5/patches/vmmdev.patch new file mode 100644 index 0000000000..cbdded4ad5 --- /dev/null +++ b/repos/ports/src/virtualbox5/patches/vmmdev.patch @@ -0,0 +1,46 @@ +vmmdev.patch + +diff --git a/src/app/virtualbox/src/VBox/Devices/VMMDev/VMMDev.cpp b/src/app/virtualbox/src/VBox/Devices/VMMDev/VMMDev.cpp +index 8ce46a8..a6b84b0 100644 +--- a/src/app/virtualbox/src/VBox/Devices/VMMDev/VMMDev.cpp ++++ b/src/app/virtualbox/src/VBox/Devices/VMMDev/VMMDev.cpp +@@ -2179,6 +2179,10 @@ static int vmmdevReqHandler_GetPageSharingStatus(PVMMDEV pThis, VMMDevRequestHea + ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER); + + pReq->fEnabled = false; ++ ++ if (!pThis || !pThis->pDrv || !pThis->pDrv->pfnIsPageFusionEnabled) ++ return VINF_SUCCESS; ++ + int rc = pThis->pDrv->pfnIsPageFusionEnabled(pThis->pDrv, &pReq->fEnabled); + if (RT_FAILURE(rc)) + pReq->fEnabled = false; +@@ -2404,7 +2408,6 @@ static int vmmdevReqDispatcher(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr, RTGC + pReqHdr->rc = vmmdevReqHandler_HGCMCall(pThis, pReqHdr, GCPhysReqHdr); + *pfDelayedUnlock = true; + break; +-#endif /* VBOX_WITH_HGCM */ + + case VMMDevReq_HGCMCancel: + pReqHdr->rc = vmmdevReqHandler_HGCMCancel(pThis, pReqHdr, GCPhysReqHdr); +@@ -2414,6 +2417,7 @@ static int vmmdevReqDispatcher(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr, RTGC + case VMMDevReq_HGCMCancel2: + pReqHdr->rc = vmmdevReqHandler_HGCMCancel2(pThis, pReqHdr); + break; ++#endif /* VBOX_WITH_HGCM */ + + case VMMDevReq_VideoAccelEnable: + pReqHdr->rc = vmmdevReqHandler_VideoAccelEnable(pThis, pReqHdr); +diff --git a/src/app/virtualbox/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp b/src/app/virtualbox/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp +index d495599..21dfada 100644 +--- a/src/app/virtualbox/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp ++++ b/src/app/virtualbox/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp +@@ -19,7 +19,7 @@ + /********************************************************************************************************************************* + * Header Files * + *********************************************************************************************************************************/ +-#define LOG_GROUP LOG_GROUP_DEV_VMM ++#define LOG_GROUP LOG_GROUP_HGCM + #include + #include + #include diff --git a/repos/ports/src/virtualbox5/pgm.cc b/repos/ports/src/virtualbox5/pgm.cc new file mode 100644 index 0000000000..d2fcd35ab4 --- /dev/null +++ b/repos/ports/src/virtualbox5/pgm.cc @@ -0,0 +1,58 @@ +/* + * \brief VirtualBox page manager (PGM) + * \author Norman Feske + * \date 2013-08-20 + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include +#include + +/* VirtualBox includes */ +#include + +static bool verbose = false; + +int PGMMap(PVM pVM, RTGCUINTPTR GCPtr, RTHCPHYS HCPhys, uint32_t cbPages, + unsigned fFlags) +{ + /* GCPtr steams from the #unimplemented# MMR3HyperReserve call, which + * returns a value - seems to be used solely in RC mode */ + + if (verbose) + Genode::log(__func__, ": GCPtr=", Genode::Hex(GCPtr), " " + "HCPHys=", Genode::Hex(HCPhys), " " + "cbPages=", Genode::Hex(cbPages), " , " + "flags=", Genode::Hex(fFlags), " " + "rip=", __builtin_return_address(0)); + + return VINF_SUCCESS; +} + + +int PGMMapSetPage(PVM pVM, RTGCPTR GCPtr, uint64_t cb, uint64_t fFlags) +{ + if (verbose) + Genode::log(__func__, ": GCPtr=", Genode::Hex(GCPtr), " " + "cb=", Genode::Hex(cb), " " + "flags=", Genode::Hex(fFlags)); + + return VINF_SUCCESS; +} + + +int PGMR3MappingsSize(PVM pVM, uint32_t *pcb) +{ + Genode::log(__func__, ": not implemented ", __builtin_return_address(0)); + + *pcb = 0; + + return 0; +} diff --git a/repos/ports/src/virtualbox5/spec/nova/pgm.cc b/repos/ports/src/virtualbox5/spec/nova/pgm.cc new file mode 100644 index 0000000000..4ddd302905 --- /dev/null +++ b/repos/ports/src/virtualbox5/spec/nova/pgm.cc @@ -0,0 +1,209 @@ +/* + * \brief Genode/Nova specific PGM code to resolve EPT faults + * \author Alexander Boettcher + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include "vcpu.h" +#include "PGMInline.h" + +enum { VERBOSE_PGM = false }; + +int Vcpu_handler::map_memory(RTGCPHYS GCPhys, size_t cbWrite, + RTGCUINT vbox_fault_reason, + Genode::Flexpage_iterator &fli, bool &writeable) +{ + using Genode::Flexpage_iterator; + using Genode::addr_t; + + PVM pVM = _current_vm; + PVMCPU pVCpu = _current_vcpu; + + _ept_fault_addr_type = PGMPAGETYPE_INVALID; + + /* DON'T USE normal printf in this function - corrupts unsaved UTCB !!! */ + + PPGMRAMRANGE pRam = pgmPhysGetRangeAtOrAbove(pVM, GCPhys); + if (!pRam) + return VERR_PGM_DYNMAP_FAILED; + +/* XXX pgmLock/pgmUnlock XXX */ + + RTGCPHYS off = GCPhys - pRam->GCPhys; + if (off >= pRam->cb) + return VERR_PGM_DYNMAP_FAILED; + + unsigned iPage = off >> PAGE_SHIFT; + PPGMPAGE pPage = &pRam->aPages[iPage]; + + _ept_fault_addr_type = PGM_PAGE_GET_TYPE(pPage); + + if (PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage) || + PGM_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage) || + PGM_PAGE_IS_ZERO(pPage)) { + + if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO && + !PGM_PAGE_IS_ZERO(pPage)) { + + Vmm::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " ", + PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage), " ", + PGM_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage), " ", + PGM_PAGE_IS_ZERO(pPage), " " + " vbox_fault_reason=", Genode::Hex(vbox_fault_reason)); + Vmm::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " " + "host=", Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), " " + "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)), " " + "writeable=", writeable, " " + "state=", Genode::Hex(PGM_PAGE_GET_STATE(pPage))); + } + return VERR_PGM_DYNMAP_FAILED; + } + + if (!PGM_PAGE_IS_ALLOCATED(pPage)) + Vmm::log("unknown page state ", Genode::Hex(PGM_PAGE_GET_STATE(pPage)), + " GCPhys=", Genode::Hex(GCPhys)); + Assert(PGM_PAGE_IS_ALLOCATED(pPage)); + + if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_RAM && + PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO2 && + PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_ROM) + { + if (VERBOSE_PGM) + Vmm::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " " + "vbox_fault_reason=", Genode::Hex(vbox_fault_reason), " " + "host=", Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), " " + "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)), " " + "state=", Genode::Hex(PGM_PAGE_GET_STATE(pPage))); + return VERR_PGM_DYNMAP_FAILED; + } + + Assert(!PGM_PAGE_IS_ZERO(pPage)); + + /* write fault on a ROM region */ + if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_ROM && + vbox_fault_reason & VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE) { + Vmm::warning(__func__, " - write fault on ROM region!? gp=", + Genode::Hex(GCPhys)); + return VERR_PGM_DYNMAP_FAILED; + } + + /* nothing should be mapped - otherwise we get endless overmap loops */ + Assert(!(vbox_fault_reason & VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT)); + + writeable = PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_ROM; + + PPGMPHYSHANDLER handler = pgmHandlerPhysicalLookup(pVM, GCPhys); + + if (VERBOSE_PGM && PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO2 && + !handler) + Vmm::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " ", + "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)), " " + "state=", Genode::Hex(PGM_PAGE_GET_STATE(pPage)), " " + "- MMIO2 w/o handler"); + + if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO2 && handler) { + PFNPGMPHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, handler)->CTX_SUFF(pfnHandler); + if (!pfnHandler) { + Vmm::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " " + "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage))); + return VERR_PGM_DYNMAP_FAILED; + } + void *pvUser = handler->CTX_SUFF(pvUser); + if (!pvUser) { + Vmm::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " " + "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage))); + return VERR_PGM_DYNMAP_FAILED; + } + + PGMACCESSTYPE access_type = (vbox_fault_reason & VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE) ? PGMACCESSTYPE_WRITE : PGMACCESSTYPE_READ; + + VBOXSTRICTRC rcStrict = pfnHandler(pVM, pVCpu, GCPhys, nullptr, nullptr, 0, access_type, PGMACCESSORIGIN_HM, pvUser); + if (rcStrict != VINF_PGM_HANDLER_DO_DEFAULT) { + Vmm::log(__LINE__, " nodefault GCPhys=", Genode::Hex(GCPhys), " " + "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)), " " + "pfnHandler=", pfnHandler); + return VERR_PGM_DYNMAP_FAILED; + } + } + +/* + Vmm::printf("0x%lx->0x%lx type=%u state=0x%u pde=%u iPage=%u range_size=0x%lx pages=%u\n", + PGM_PAGE_GET_HCPHYS(pPage), GCPhys, PGM_PAGE_GET_TYPE(pPage), + PGM_PAGE_GET_STATE(pPage), PGM_PAGE_GET_PDE_TYPE(pPage), + iPage, pRam->cb, pRam->cb >> PAGE_SHIFT); +*/ + + if (PGM_PAGE_GET_PDE_TYPE(pPage) == PGM_PAGE_PDE_TYPE_PDE) { + Genode::addr_t const max_pages = pRam->cb >> PAGE_SHIFT; + Genode::addr_t const superpage_pages = (1 << 21) / 4096; + Genode::addr_t mask = (1 << 21) - 1; + Genode::addr_t super_gcphys = GCPhys & ~mask; + + RTGCPHYS max_off = super_gcphys - pRam->GCPhys; + Assert (max_off < pRam->cb); + + Genode::addr_t super_hcphys = PGM_PAGE_GET_HCPHYS(pPage) & ~mask; + + unsigned const i_s = max_off >> PAGE_SHIFT; + + Assert (i_s + superpage_pages <= max_pages); + + if (VERBOSE_PGM) + Vmm::log(Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), "->", + Genode::Hex(GCPhys), " - iPage ", iPage, " [", + i_s, ",", i_s + superpage_pages, ")", " " + "range_size=", Genode::Hex(pRam->cb)); + + /* paranoia sanity checks */ + for (Genode::addr_t i = i_s; i < i_s + superpage_pages; i++) { + PPGMPAGE page = &pRam->aPages[i]; + + Genode::addr_t gcpage = pRam->GCPhys + i << PAGE_SHIFT; + + Assert(super_hcphys == (PGM_PAGE_GET_HCPHYS(page) & ~mask)); + Assert(super_gcphys == (gcpage & ~mask)); + Assert(PGM_PAGE_GET_PDE_TYPE(page) == PGM_PAGE_PDE_TYPE_PDE); + Assert(PGM_PAGE_GET_TYPE(page) == PGM_PAGE_GET_TYPE(pPage)); + Assert(PGM_PAGE_GET_STATE(page) == PGM_PAGE_GET_STATE(pPage)); + } + + fli = Flexpage_iterator(super_hcphys, 1 << 21, + super_gcphys, 1 << 21, super_gcphys); + } else + fli = Flexpage_iterator(PGM_PAGE_GET_HCPHYS(pPage), 4096, + GCPhys & ~0xFFFUL, 4096, GCPhys & ~0xFFFUL); + + return VINF_SUCCESS; +} + + +Genode::uint64_t * Vcpu_handler::pdpte_map(VM *pVM, RTGCPHYS cr3) +{ + PPGMRAMRANGE pRam = pgmPhysGetRangeAtOrAbove(pVM, cr3); + Assert (pRam); + +/* XXX pgmLock/pgmUnlock XXX */ + + RTGCPHYS off = cr3 - pRam->GCPhys; + Assert (off < pRam->cb); + + unsigned iPage = off >> PAGE_SHIFT; + PPGMPAGE pPage = &pRam->aPages[iPage]; + +/* + Vmm::printf("%u gcphys=0x%lx host=0x%lx type=%lx state=0x%lx\n", __LINE__, + cr3, PGM_PAGE_GET_HCPHYS(pPage), PGM_PAGE_GET_TYPE(pPage), PGM_PAGE_GET_STATE(pPage)); +*/ + + Genode::uint64_t *pdpte = reinterpret_cast(PGM_PAGE_GET_HCPHYS(pPage) + (cr3 & PAGE_OFFSET_MASK)); + + Assert(pdpte != 0); + + return pdpte; +} diff --git a/repos/ports/src/virtualbox5/spec/nova/sup.cc b/repos/ports/src/virtualbox5/spec/nova/sup.cc new file mode 100644 index 0000000000..8dbdf872fb --- /dev/null +++ b/repos/ports/src/virtualbox5/spec/nova/sup.cc @@ -0,0 +1,570 @@ +/* + * \brief Genode/Nova specific VirtualBox SUPLib supplements + * \author Alexander Boettcher + * \author Norman Feske + * \author Christian Helmuth + */ + +/* + * Copyright (C) 2013-2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* NOVA includes that come with Genode */ +#include + +/* Genode's VirtualBox includes */ +#include "vcpu.h" +#include "vcpu_svm.h" +#include "vcpu_vmx.h" + +/* libc memory allocator */ +#include + +#include "mm.h" + +extern "C" bool PGMUnmapMemoryGenode(void *, size_t); + +/* XXX does not work on 32bit host - since vm memory is from 0 - 4G and + * such large areas can't be attached to a process + * We need several sub_rm areas .... XXX + */ +static Sub_rm_connection vm_memory((sizeof(void *) == 4 ? 2UL : 4UL) * 1024 * 1024 * 1024); + +static Genode::List &vcpu_handler_list() +{ + static Genode::List _inst; + return _inst; +} + + +static Vcpu_handler *lookup_vcpu_handler(unsigned int cpu_id) +{ + for (Vcpu_handler *vcpu_handler = vcpu_handler_list().first(); + vcpu_handler; + vcpu_handler = vcpu_handler->next()) + if (vcpu_handler->cpu_id() == cpu_id) + return vcpu_handler; + + return 0; +} + + +/* Genode specific function */ + +static Genode::Attached_rom_dataspace hip_rom("hypervisor_info_page"); + +void SUPR3QueryHWACCLonGenodeSupport(VM * pVM) +{ + try { + Nova::Hip * hip = hip_rom.local_addr(); + + pVM->hm.s.svm.fSupported = hip->has_feature_svm(); + pVM->hm.s.vmx.fSupported = hip->has_feature_vmx(); + + if (hip->has_feature_svm() || hip->has_feature_vmx()) { + Genode::log("Using ", hip->has_feature_svm() ? "SVM " : "VMX ", + "virtualization extension."); + return; + } + } catch (...) { /* if we get an exception let hardware support off */ } + + Genode::warning("No virtualization hardware acceleration available"); +} + + +/* VirtualBox SUPLib interface */ +int SUPR3QueryVTxSupported(void) { return VINF_SUCCESS; } + + +int SUPR3CallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, VMCPUID idCpu) +{ + switch (uOperation) { + case SUP_VMMR0_DO_HM_RUN: + Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu); + Assert(vcpu_handler); + return vcpu_handler->run_hw(pVMR0); + } + return VERR_INTERNAL_ERROR; +} + +int SUPR3PageAllocEx(size_t cPages, uint32_t fFlags, void **ppvPages, + PRTR0PTR pR0Ptr, PSUPPAGE paPages) +{ + Assert(ppvPages); + Assert(!fFlags); + + Genode::log(__func__, " cPages ", cPages, " flags=", Genode::Hex(fFlags), + " r3=", ppvPages, " r0=", pR0Ptr); + + using Genode::Attached_ram_dataspace; + Attached_ram_dataspace * ds = new Attached_ram_dataspace(Genode::env()->ram_session(), cPages * 4096); /* XXX PAGE_SIZE ? */ + *ppvPages = ds->local_addr(); + + Genode::log(__func__, " cPages ", cPages, " alloc=", *ppvPages, " done"); + + if (!paPages) + return VINF_SUCCESS; + + for (unsigned iPage = 0; iPage < cPages; iPage++) + { + paPages[iPage].uReserved = 0; + paPages[iPage].Phys = reinterpret_cast(ds->local_addr()) + iPage * 4096; + } + + return VINF_SUCCESS; +} + + +int SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned + uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr) +{ + static unsigned long chunkid = 1500; + + switch (uOperation) { + + case VMMR0_DO_GVMM_CREATE_VM: + genode_VMMR0_DO_GVMM_CREATE_VM(pReqHdr); + return VINF_SUCCESS; + + case VMMR0_DO_GVMM_REGISTER_VMCPU: + genode_VMMR0_DO_GVMM_REGISTER_VMCPU(pVMR0, idCpu); + return VINF_SUCCESS; + + case VMMR0_DO_GVMM_SCHED_HALT: + { + Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu); + Assert(vcpu_handler); +/* + char txt_name[32]; + Genode::Thread_base::myself()->name(txt_name, sizeof(txt_name)); + PINF("%s - halt - rip=%p", txt_name, __builtin_return_address(0)); +*/ + vcpu_handler->halt(); +// PINF("%s - woken up", txt_name); + return VINF_SUCCESS; + } + + case VMMR0_DO_GVMM_SCHED_WAKE_UP: + { + Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu); + Assert(vcpu_handler); +/* + char txt_name[32]; + Genode::Thread_base::myself()->name(txt_name, sizeof(txt_name)); + PINF("%s - wakeup - rip=%p", txt_name, __builtin_return_address(0)); +*/ + vcpu_handler->wake_up(); + return VINF_SUCCESS; + } + + /* called by 'vmR3HaltGlobal1Halt' */ + case VMMR0_DO_GVMM_SCHED_POLL: + return VINF_SUCCESS; + + case VMMR0_DO_VMMR0_INIT: + SUPR3QueryHWACCLonGenodeSupport(reinterpret_cast(pVMR0)); + return VINF_SUCCESS; + + case VMMR0_DO_GVMM_DESTROY_VM: + case VMMR0_DO_VMMR0_TERM: + case VMMR0_DO_HM_SETUP_VM: + return VINF_SUCCESS; + + case VMMR0_DO_HM_ENABLE: + return VINF_SUCCESS; + + case VMMR0_DO_GVMM_SCHED_POKE: + { + Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu); + Assert(vcpu_handler); + if (vcpu_handler) + vcpu_handler->recall(); + return VINF_SUCCESS; + } + case VMMR0_DO_GMM_ALLOCATE_PAGES: + { + static_assert(PGM_HANDY_PAGES * 4096 == GMM_CHUNK_SIZE, "Don't do that - you're going to waste tons of memory"); + Assert(pReqHdr->u32Magic == SUPVMMR0REQHDR_MAGIC); +/* XXX VMM/VMMR0/GMMR0.cpp check there XXX */ + + Genode::log("ALLOCATE_PAGES pReq ", pReqHdr); + + PGMMALLOCATEPAGESREQ req = reinterpret_cast(pReqHdr); + + for (unsigned i = 0; i < req->cPages; i++) { + RTHCPHYS guest_addr = req->aPages[i].HCPhysGCPhys; + unsigned long chunkid = (req->aPages[i].HCPhysGCPhys / GMM_CHUNK_SIZE) + 1; + unsigned long pageidx = (req->aPages[i].HCPhysGCPhys % GMM_CHUNK_SIZE) / 4096; + Assert (pageidx <= GMM_PAGEID_IDX_MASK); + Assert (chunkid < 1500 || chunkid > 2047); /* XXX reserved at the moment */ + + req->aPages[i].idPage = (chunkid << GMM_CHUNKID_SHIFT) | pageidx; + req->aPages[i].HCPhysGCPhys = vm_memory.local_addr(req->aPages[i].HCPhysGCPhys); + Assert(vm_memory.contains(req->aPages[i].HCPhysGCPhys)); + + Genode::log("cPages ", Genode::Hex(req->cPages), " " + "chunkID=", req->aPages[i].idPage >> GMM_CHUNKID_SHIFT, " " + "pageIDX=", req->aPages[i].idPage & GMM_PAGEID_IDX_MASK, " " + "idPage=", Genode::Hex(req->aPages[i].idPage), " " + "GCPhys=", Genode::Hex(guest_addr), " " + "HCPhys=", Genode::Hex(req->aPages[i].HCPhysGCPhys), " " + "start_vm=", vm_memory.local_addr(0)); + } + + return VINF_SUCCESS; + } + case VMMR0_DO_GMM_MAP_UNMAP_CHUNK: + { + PGMMMAPUNMAPCHUNKREQ req = reinterpret_cast(pReqHdr); + + Assert(pReqHdr->u32Magic == SUPVMMR0REQHDR_MAGIC); + +// PINF("UNMAP_CHUNK map=%u unmap=%u pvR3=%p start", req->idChunkMap, req->idChunkUnmap, req->pvR3); + + Assert(req->idChunkUnmap == NIL_GMM_CHUNKID); + Assert(req->idChunkMap != NIL_GMM_CHUNKID); + + Genode::Ram_dataspace_capability ds = Genode::env()->ram_session()->alloc(GMM_CHUNK_SIZE); + Genode::addr_t local_addr_offset = (req->idChunkMap - 1) << GMM_CHUNK_SHIFT; + + enum { OFFSET_DS = 0, USE_LOCAL_ADDR = true }; + Genode::addr_t to = vm_memory.attach(ds, GMM_CHUNK_SIZE, OFFSET_DS, + USE_LOCAL_ADDR, local_addr_offset); + Assert(to == vm_memory.local_addr(local_addr_offset)); + + req->pvR3 = reinterpret_cast(to); + +// PINF("UNMAP_CHUNK map=%u unmap=%u pvR3=%p done", req->idChunkMap, req->idChunkUnmap, req->pvR3); + + return VINF_SUCCESS; + } + case VMMR0_DO_GMM_QUERY_MEM_STATS: + { + PGMMMEMSTATSREQ req = reinterpret_cast(pReqHdr); + req->cAllocPages = 0; + req->cMaxPages = 0; + req->cBalloonedPages = 0; + return VINF_SUCCESS; + } + case VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES: + { + PVM pVM = reinterpret_cast(pVMR0); + + /* based on PGMR0PhysAllocateHandyPages() in VMM/VMMR0/PGMR0.cpp - start */ + uint32_t iFirst = pVM->pgm.s.cHandyPages; + uint32_t cPages = RT_ELEMENTS(pVM->pgm.s.aHandyPages) - iFirst; + uint32_t cPagesToUpdate = cPages; + uint32_t cPagesToAlloc = cPages; + /* based on PGMR0PhysAllocateHandyPages() in VMM/VMMR0/PGMR0.cpp - end */ + + /* based on GMMR0AllocateHandyPages in VMM/VMMR0/GMMR0.cpp - start */ + unsigned iPage = 0; + for (; iPage < cPagesToUpdate; iPage++) + { + AssertMsgReturn( ( pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys <= GMM_GCPHYS_LAST + && !(pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys & PAGE_OFFSET_MASK)) + || pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys == NIL_RTHCPHYS + || pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys == GMM_GCPHYS_UNSHAREABLE, + ("#%#x: %RHp\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys), + VERR_INVALID_PARAMETER); + AssertMsgReturn( pVM->pgm.s.aHandyPages[iFirst + iPage].idPage <= GMM_PAGEID_LAST + /*|| pVM->pgm.s.aHandyPages[iFirst + iPage].idPage == NIL_GMM_PAGEID*/, + ("#%#x: %#x\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].idPage), VERR_INVALID_PARAMETER); + AssertMsgReturn( pVM->pgm.s.aHandyPages[iFirst + iPage].idPage <= GMM_PAGEID_LAST + /*|| pVM->pgm.s.aHandyPages[iFirst + iPage].idSharedPage == NIL_GMM_PAGEID*/, + ("#%#x: %#x\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].idSharedPage), VERR_INVALID_PARAMETER); + } + + for (; iPage < cPagesToAlloc; iPage++) + { + AssertMsgReturn(pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys == NIL_RTHCPHYS, ("#%#x: %RHp\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys), VERR_INVALID_PARAMETER); + AssertMsgReturn(pVM->pgm.s.aHandyPages[iFirst + iPage].idPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].idPage), VERR_INVALID_PARAMETER); + AssertMsgReturn(pVM->pgm.s.aHandyPages[iFirst + iPage].idSharedPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].idSharedPage), VERR_INVALID_PARAMETER); + } + + Assert (chunkid >= 1500 && chunkid <= 2047); /* XXX reserved at the moment */ + + if (cPagesToAlloc != GMM_CHUNK_SIZE / 4096) + Genode::log("special chunkid=", chunkid, " " + "toupdate=", cPagesToUpdate, " " + "toalloc=", cPagesToAlloc, " " + "virt=", Genode::Hex(vm_memory.local_addr(((chunkid - 1) << GMM_CHUNK_SHIFT)))); + + for (unsigned i = 0; i < cPagesToUpdate; i++) { + if (pVM->pgm.s.aHandyPages[iFirst + i].idPage != NIL_GMM_PAGEID) + { + pVM->pgm.s.aHandyPages[iFirst + i].idPage = NIL_GMM_PAGEID; + pVM->pgm.s.aHandyPages[iFirst + i].HCPhysGCPhys = NIL_RTHCPHYS; + } + + if (pVM->pgm.s.aHandyPages[iFirst + i].idSharedPage != NIL_GMM_PAGEID) + AssertMsgReturn(false, ("%s %u - not implemented", __func__, __LINE__), VERR_GENERAL_FAILURE); + } + + for (unsigned i = 0; i < cPagesToAlloc; i++) + { + Assert(pVM->pgm.s.aHandyPages[iFirst + i].HCPhysGCPhys == NIL_RTHCPHYS); + Assert(pVM->pgm.s.aHandyPages[iFirst + i].idPage == NIL_GMM_PAGEID); + Assert(pVM->pgm.s.aHandyPages[iFirst + i].idSharedPage == NIL_GMM_PAGEID); + } + + for (unsigned i = 0; i < cPagesToUpdate; i++) { + unsigned reverse = i; //cPagesToUpdate - 1 - i; + Assert (pVM->pgm.s.aHandyPages[iFirst + i].HCPhysGCPhys == NIL_RTHCPHYS); + { + pVM->pgm.s.aHandyPages[iFirst + i].idPage = (chunkid << GMM_CHUNKID_SHIFT) | (iFirst + reverse); + pVM->pgm.s.aHandyPages[iFirst + i].idSharedPage = NIL_GMM_PAGEID; + + pVM->pgm.s.aHandyPages[iFirst + i].HCPhysGCPhys = vm_memory.local_addr(((chunkid - 1) << GMM_CHUNK_SHIFT) | ((iFirst + reverse) * 4096)); /* XXX PAGE_SIZE XXX */ + } + } + /* based on GMMR0AllocateHandyPages in VMM/VMMR0/GMMR0.cpp - end */ + + /* based on PGMR0PhysAllocateHandyPages() in VMM/VMMR0/PGMR0.cpp - start */ + pVM->pgm.s.cHandyPages = RT_ELEMENTS(pVM->pgm.s.aHandyPages); + + for (uint32_t i = 0; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++) + { + Assert(pVM->pgm.s.aHandyPages[i].idPage != NIL_GMM_PAGEID); + Assert(pVM->pgm.s.aHandyPages[i].idPage <= GMM_PAGEID_LAST); + Assert(pVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID); + Assert(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys != NIL_RTHCPHYS); + Assert(!(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys & ~X86_PTE_PAE_PG_MASK)); + } + /* based on PGMR0PhysAllocateHandyPages() in VMM/VMMR0/PGMR0.cpp - end */ + + chunkid ++; /* XXX */ + + return VINF_SUCCESS; + } + case VMMR0_DO_PGM_ALLOCATE_LARGE_HANDY_PAGE: + { + PVM pVM = reinterpret_cast(pVMR0); + + Assert(pVM); + Assert(pVM->pgm.s.cLargeHandyPages == 0); + + pVM->pgm.s.aLargeHandyPage[0].idPage = (chunkid << GMM_CHUNKID_SHIFT); + pVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys = vm_memory.local_addr(((chunkid - 1) << GMM_CHUNK_SHIFT)); + + pVM->pgm.s.cLargeHandyPages = 1; + + chunkid ++; /* XXX */ + + return VINF_SUCCESS; + } + case VMMR0_DO_GMM_BALLOONED_PAGES: + { + /* during VM shutdown - ignore */ + return VINF_SUCCESS; + } + case VMMR0_DO_GMM_RESET_SHARED_MODULES: + { + /* during VM shutdown - ignore */ + return VINF_SUCCESS; + } + case VMMR0_DO_PGM_FLUSH_HANDY_PAGES: + { + /* during VM shutdown - ignore */ + return VINF_SUCCESS; + } + case VMMR0_DO_GMM_FREE_PAGES: + { + if (u64Arg) + return VERR_INVALID_PARAMETER; + + PVM pVM = reinterpret_cast(pVMR0); + PGMMFREEPAGESREQ pReq = reinterpret_cast(pReqHdr); + + AssertPtrReturn(pVM, VERR_INVALID_POINTER); + AssertPtrReturn(pReq, VERR_INVALID_POINTER); + AssertMsgReturn(pReq->Hdr.cbReq >= RT_UOFFSETOF(GMMFREEPAGESREQ, aPages[0]), + ("%#x < %#x\n", pReq->Hdr.cbReq, RT_UOFFSETOF(GMMFREEPAGESREQ, aPages[0])), + VERR_INVALID_PARAMETER); + AssertMsgReturn(pReq->Hdr.cbReq == RT_UOFFSETOF(GMMFREEPAGESREQ, aPages[pReq->cPages]), + ("%#x != %#x\n", pReq->Hdr.cbReq, RT_UOFFSETOF(GMMFREEPAGESREQ, aPages[pReq->cPages])), + VERR_INVALID_PARAMETER); + + uint32_t cPages = pReq->cPages; + PGMMFREEPAGEDESC paPages = &pReq->aPages[0]; + GMMACCOUNT enmAccount = pReq->enmAccount; + + AssertPtrReturn(paPages, VERR_INVALID_PARAMETER); + AssertMsgReturn(enmAccount > GMMACCOUNT_INVALID && enmAccount < GMMACCOUNT_END, ("%d\n", enmAccount), VERR_INVALID_PARAMETER); + AssertMsgReturn(cPages > 0 && cPages < RT_BIT(32 - PAGE_SHIFT), ("%#x\n", cPages), VERR_INVALID_PARAMETER); + + for (unsigned iPage = 0; iPage < cPages; iPage++) + AssertMsgReturn( paPages[iPage].idPage <= GMM_PAGEID_LAST + /*|| paPages[iPage].idPage == NIL_GMM_PAGEID*/, + ("#%#x: %#x\n", iPage, paPages[iPage].idPage), VERR_INVALID_PARAMETER); + + uint32_t fPage = (paPages[0].idPage >> GMM_CHUNKID_SHIFT); + void * vmm_local = reinterpret_cast(vm_memory.local_addr((fPage - 1) << GMM_CHUNK_SHIFT)); + PGMUnmapMemoryGenode(vmm_local, GMM_CHUNK_SIZE); + + uint32_t iPage; + for (iPage = 0; iPage < cPages; iPage++) + { + uint32_t idPage = paPages[iPage].idPage; + if ((idPage >> GMM_CHUNKID_SHIFT) != fPage) { + Genode::log(iPage, " idPage=", Genode::Hex(idPage), " " + "(id=", idPage >> GMM_CHUNKID_SHIFT, " " + "page=%u)", idPage & GMM_PAGEID_IDX_MASK, " " + "vm_memory.local=", Genode::Hex(vm_memory.local_addr((((idPage >>GMM_CHUNKID_SHIFT) - 1) << GMM_CHUNK_SHIFT)))); + } + paPages[iPage].idPage = NIL_GMM_PAGEID; + } + + return VINF_SUCCESS; + } + default: + Genode::error("SUPR3CallVMMR0Ex: unhandled uOperation ", uOperation, + " ", (int)VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES, " ", + (int)VMMR0_DO_GMM_QUERY_MEM_STATS); + return VERR_GENERAL_FAILURE; + } +} + + +/** + * Various support stuff - base-nova specific. + */ +uint64_t genode_cpu_hz() +{ + static uint64_t cpu_freq = 0; + + if (!cpu_freq) { + try { + using namespace Genode; + + Rom_connection hip_rom("hypervisor_info_page"); + + Nova::Hip * const hip = env()->rm_session()->attach(hip_rom.dataspace()); + + cpu_freq = hip->tsc_freq * 1000; + + } catch (...) { + Genode::error("could not read out CPU frequency."); + Genode::Lock lock; + lock.lock(); + } + } + + return cpu_freq; +} + + +void genode_update_tsc(void (*update_func)(void), unsigned long update_us) +{ + using namespace Genode; + using namespace Nova; + + enum { TSC_FACTOR = 1000ULL }; + + Genode::addr_t sem = Thread::myself()->native_thread().exc_pt_sel + Nova::SM_SEL_EC; + unsigned long tsc_khz = (genode_cpu_hz() / 1000) / TSC_FACTOR; + + Trace::Timestamp us_64 = update_us; + + for (;;) { + update_func(); + + Trace::Timestamp now = Trace::timestamp(); + + /* block until timeout fires or it gets canceled */ + unsigned long long tsc_absolute = now + us_64 * tsc_khz; + Genode::uint8_t res = sm_ctrl(sem, SEMAPHORE_DOWN, tsc_absolute); + if (res != Nova::NOVA_OK && res != Nova::NOVA_TIMEOUT) + nova_die(); + } +} + + +bool PGMUnmapMemoryGenode(void * vmm_local, size_t size) +{ + Assert(vmm_local); + + using namespace Genode; + + Flexpage_iterator fli(reinterpret_cast(vmm_local), size, 0, ~0UL, 0); + + Flexpage revoke_page = fli.page(); + while (revoke_page.valid()) { + Assert(revoke_page.log2_order >= 12); + Assert(!(((1UL << revoke_page.log2_order) - 1) & revoke_page.addr)); + + using namespace Nova; + + Rights const revoke_rwx(true, true, true); + Crd crd = Mem_crd(revoke_page.addr >> 12, revoke_page.log2_order - 12, + revoke_rwx); + revoke(crd, false); + + /* request next page(s) to be revoked */ + revoke_page = fli.page(); + } + + return true; +} + + +extern "C" void pthread_yield(void) +{ + Nova::ec_ctrl(Nova::EC_YIELD); +} + + +void *operator new (Genode::size_t size, int log2_align) +{ + static Libc::Mem_alloc_impl heap(Genode::env()->rm_session()); + return heap.alloc(size, log2_align); +} + + +bool create_emt_vcpu(pthread_t * pthread, size_t stack, + const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg, + Genode::Cpu_session * cpu_session, + Genode::Affinity::Location location, + unsigned int cpu_id) +{ + Nova::Hip * hip = hip_rom.local_addr(); + + if (!hip->has_feature_vmx() && !hip->has_feature_svm()) + return false; + + Vcpu_handler *vcpu_handler = 0; + + if (hip->has_feature_vmx()) + vcpu_handler = new (0x10) Vcpu_handler_vmx(stack, attr, start_routine, + arg, cpu_session, location, + cpu_id); + + if (hip->has_feature_svm()) + vcpu_handler = new (0x10) Vcpu_handler_svm(stack, attr, start_routine, + arg, cpu_session, location, + cpu_id); + + Assert(!(reinterpret_cast(vcpu_handler) & 0xf)); + + vcpu_handler_list().insert(vcpu_handler); + + *pthread = vcpu_handler; + return true; +} diff --git a/repos/ports/src/virtualbox5/spec/nova/svm.h b/repos/ports/src/virtualbox5/spec/nova/svm.h new file mode 100644 index 0000000000..e41343f405 --- /dev/null +++ b/repos/ports/src/virtualbox5/spec/nova/svm.h @@ -0,0 +1,112 @@ +/* + * \brief Genode/Nova specific VirtualBox SUPLib supplements + * \author Norman Feske + * \author Alexander Boettcher + */ + +/* + * Copyright (C) 2013-2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _VIRTUALBOX__SPEC__NOVA__SVM_H_ +#define _VIRTUALBOX__SPEC__NOVA__SVM_H_ + +/* based on HWSVMR0.h - adjusted to Genode/Nova */ + +#define GENODE_SVM_ASSERT_SELREG(REG) \ + AssertMsg(!pCtx->REG.Attr.n.u1Present || \ + (pCtx->REG.Attr.n.u1Granularity \ + ? (pCtx->REG.u32Limit & 0xfffU) == 0xfffU \ + : pCtx->REG.u32Limit <= 0xfffffU), \ + ("%u %u %#x %#x %#llx\n", pCtx->REG.Attr.n.u1Present, \ + pCtx->REG.Attr.n.u1Granularity, pCtx->REG.u32Limit, \ + pCtx->REG.Attr.u, pCtx->REG.u64Base)) + +#define GENODE_READ_SELREG(REG) \ + pCtx->REG.Sel = utcb->REG.sel; \ + pCtx->REG.ValidSel = utcb->REG.sel; \ + pCtx->REG.fFlags = CPUMSELREG_FLAGS_VALID; \ + pCtx->REG.u32Limit = utcb->REG.limit; \ + pCtx->REG.u64Base = utcb->REG.base; \ + pCtx->REG.Attr.u = sel_ar_conv_from_nova(utcb->REG.ar) + +static inline bool svm_save_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) +{ + PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); + + GENODE_READ_SELREG(cs); + GENODE_READ_SELREG(ds); + GENODE_READ_SELREG(es); + GENODE_READ_SELREG(fs); + GENODE_READ_SELREG(gs); + GENODE_READ_SELREG(ss); + + GENODE_SVM_ASSERT_SELREG(cs); + GENODE_SVM_ASSERT_SELREG(ds); + GENODE_SVM_ASSERT_SELREG(es); + GENODE_SVM_ASSERT_SELREG(fs); + GENODE_SVM_ASSERT_SELREG(gs); + GENODE_SVM_ASSERT_SELREG(ss); + + GENODE_READ_SELREG(ldtr); + GENODE_READ_SELREG(tr); + + return true; +} + +#undef GENODE_ASSERT_SELREG +#undef GENODE_READ_SELREG + + + + +#define GENODE_WRITE_SELREG(REG) \ + Assert(pCtx->REG.fFlags & CPUMSELREG_FLAGS_VALID); \ + Assert(pCtx->REG.ValidSel == pCtx->REG.Sel); \ + utcb->REG.sel = pCtx->REG.Sel; \ + utcb->REG.limit = pCtx->REG.u32Limit; \ + utcb->REG.base = pCtx->REG.u64Base; \ + utcb->REG.ar = sel_ar_conv_to_nova(pCtx->REG.Attr.u) + +static inline bool svm_load_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) +{ + PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); + +#ifdef __x86_64__ + utcb->mtd |= Nova::Mtd::EFER; + utcb->efer = pCtx->msrEFER | MSR_K6_EFER_SVME; + /* unimplemented */ + if (CPUMIsGuestInLongModeEx(pCtx)) + return false; + utcb->efer &= ~MSR_K6_EFER_LME; +#endif + + utcb->mtd |= Nova::Mtd::ESDS; + GENODE_WRITE_SELREG(es); + GENODE_WRITE_SELREG(ds); + + utcb->mtd |= Nova::Mtd::FSGS; + GENODE_WRITE_SELREG(fs); + GENODE_WRITE_SELREG(gs); + + utcb->mtd |= Nova::Mtd::CSSS; + GENODE_WRITE_SELREG(cs); + GENODE_WRITE_SELREG(ss); + + /* ldtr */ + utcb->mtd |= Nova::Mtd::LDTR; + GENODE_WRITE_SELREG(ldtr); + + /* tr */ + utcb->mtd |= Nova::Mtd::TR; + GENODE_WRITE_SELREG(tr); + + return true; +} + +#undef GENODE_WRITE_SELREG + +#endif /* _VIRTUALBOX__SPEC__NOVA__SVM_H_ */ diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu.h b/repos/ports/src/virtualbox5/spec/nova/vcpu.h new file mode 100644 index 0000000000..dcb308790a --- /dev/null +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu.h @@ -0,0 +1,868 @@ +/* + * \brief Genode/Nova specific VirtualBox SUPLib supplements + * \author Alexander Boettcher + * \author Norman Feske + * \author Christian Helmuth + */ + +/* + * Copyright (C) 2013-2016 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _VIRTUALBOX__SPEC__NOVA__VCPU_H_ +#define _VIRTUALBOX__SPEC__NOVA__VCPU_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* NOVA includes that come with Genode */ +#include + +/* VirtualBox includes */ +#include "PGMInternal.h" /* enable access to pgm.s.* */ + +#include "HMInternal.h" /* enable access to hm.s.* */ +#include "CPUMInternal.h" /* enable access to cpum.s.* */ + +#include +#include +#include + +#include + +/* Genode's VirtualBox includes */ +#include "sup.h" + +/* Genode libc pthread binding */ +#include "thread.h" + +/* LibC includes */ +#include + +#include + +static bool debug_map_memory = false; + +/* + * VirtualBox stores segment attributes in Intel format using a 32-bit + * value. NOVA represents the attributes in packed format using a 16-bit + * value. + */ +static inline Genode::uint16_t sel_ar_conv_to_nova(Genode::uint32_t v) +{ + return (v & 0xff) | ((v & 0x1f000) >> 4); +} + + +static inline Genode::uint32_t sel_ar_conv_from_nova(Genode::uint16_t v) +{ + return (v & 0xff) | (((uint32_t )v << 4) & 0x1f000); +} + + +class Vcpu_handler : public Vmm::Vcpu_dispatcher, + public Genode::List::Element +{ + private: + + X86FXSTATE _guest_fpu_state __attribute__((aligned(0x10))); + X86FXSTATE _emt_fpu_state __attribute__((aligned(0x10))); + + Vmm::Vcpu_other_pd _vcpu; + + Genode::addr_t _ec_sel; + bool _irq_win; + + unsigned int _cpu_id; + Genode::Semaphore _halt_sem; + + unsigned int _last_inj_info; + unsigned int _last_inj_error; + + void fpu_save(char * data) { + Assert(!(reinterpret_cast(data) & 0xF)); + asm volatile ("fxsave %0" : "=m" (*data)); + } + + void fpu_load(char * data) { + Assert(!(reinterpret_cast(data) & 0xF)); + asm volatile ("fxrstor %0" : : "m" (*data)); + } + + enum { + NOVA_REQ_IRQWIN_EXIT = 0x1000U, + IRQ_INJ_VALID_MASK = 0x80000000UL, + IRQ_INJ_NONE = 0U, + + /* + * Intel® 64 and IA-32 Architectures Software Developer’s Manual + * Volume 3C, Chapter 24.4.2. + * May 2012 + */ + BLOCKING_BY_STI = 1U << 0, + BLOCKING_BY_MOV_SS = 1U << 1, + ACTIVITY_STATE_ACTIVE = 0U, + INTERRUPT_STATE_NONE = 0U, + }; + + /* + * 'longjmp()' restores some FPU registers saved by 'setjmp()', + * so we need to save the guest FPU state before calling 'longjmp()' + */ + __attribute__((noreturn)) void _fpu_save_and_longjmp() + { + fpu_save(reinterpret_cast(&_guest_fpu_state)); + longjmp(_env, 1); + } + + int map_memory(RTGCPHYS GCPhys, + size_t cbWrite, RTGCUINT vbox_fault_reason, + Genode::Flexpage_iterator &fli, bool &writeable); + + protected: + + struct { + Nova::mword_t mtd; + unsigned intr_state; + unsigned ctrl[2]; + } next_utcb; + + PVM _current_vm; + PVMCPU _current_vcpu; + unsigned _ept_fault_addr_type; + void * _stack_reply; + jmp_buf _env; + + Genode::uint64_t * pdpte_map(VM *pVM, RTGCPHYS cr3); + + void switch_to_hw() + { + unsigned long value; + + if (!setjmp(_env)) { + _stack_reply = reinterpret_cast(&value - 1); + Nova::reply(_stack_reply); + } + } + + __attribute__((noreturn)) void _default_handler() + { + Nova::Utcb * utcb = reinterpret_cast(Thread::utcb()); + + Assert(utcb->actv_state == ACTIVITY_STATE_ACTIVE); + Assert(!(utcb->inj_info & IRQ_INJ_VALID_MASK)); + + /* go back to VirtualBox */ + _fpu_save_and_longjmp(); + } + + __attribute__((noreturn)) void _recall_handler() + { + Nova::Utcb * utcb = reinterpret_cast(Thread::utcb()); + + Assert(utcb->actv_state == ACTIVITY_STATE_ACTIVE); + + if (utcb->inj_info & IRQ_INJ_VALID_MASK) { + + Assert(utcb->flags & X86_EFL_IF); + + if (utcb->intr_state != INTERRUPT_STATE_NONE) + Vmm::log("intr state ", Genode::Hex(utcb->intr_state), + " ", Genode::Hex(utcb->intr_state & 0xf)); + + Assert(utcb->intr_state == INTERRUPT_STATE_NONE); + +/* + if (!continue_hw_accelerated(utcb)) + Vmm::log("WARNING - recall ignored during IRQ delivery"); +*/ + /* got recall during irq injection and the guest is ready for + * delivery of IRQ - just continue */ + Nova::reply(_stack_reply); + } + + /* are we forced to go back to emulation mode ? */ + if (!continue_hw_accelerated(utcb)) { + /* go back to emulation mode */ + _fpu_save_and_longjmp(); + } + + /* check whether we have to request irq injection window */ + utcb->mtd = Nova::Mtd::FPU; + if (check_to_request_irq_window(utcb, _current_vcpu)) { + _irq_win = true; + Nova::reply(_stack_reply); + } + + /* nothing to do at all - continue hardware accelerated */ + + Assert(!_irq_win); + + /* + * Print a debug message if there actually IS something to do now. + * This can happen, for example, if one of the worker threads has + * set a flag in the meantime. Usually, setting a flag is followed + * by a recall request, but we haven't verified this for each flag + * yet. + */ + continue_hw_accelerated(utcb, true); + + Nova::reply(_stack_reply); + } + + template + __attribute__((noreturn)) inline + void _exc_memory(Genode::Thread * myself, Nova::Utcb * utcb, + bool unmap, Genode::addr_t guest_fault, + RTGCUINT vbox_errorcode) + { + using namespace Nova; + using namespace Genode; + + Assert(utcb->actv_state == ACTIVITY_STATE_ACTIVE); + + if (unmap) { + Vmm::log("error: unmap not implemented"); + Nova::reply(_stack_reply); + } + + enum { MAP_SIZE = 0x1000UL }; + + bool writeable = true; + Flexpage_iterator fli; + + Genode::addr_t gp_map_addr = guest_fault & ~((1UL << 12) - 1); + int res = map_memory(gp_map_addr, MAP_SIZE, vbox_errorcode, + fli, writeable); + + /* emulator has to take over if fault region is not ram */ + if (res != VINF_SUCCESS) { + /* see hmR0VmxExitEptViolation of VMM/VMMR0/HMVMXR0.cpp */ +// PVMCPU pVCpu = &_current_vm->aCpus[_cpu_id]; +// TRPMAssertXcptPF(pVCpu, guest_fault, vbox_errorcode); + + /* event re-injection is not handled yet for this case */ + Assert(!(utcb->inj_info & IRQ_INJ_VALID_MASK)); + _fpu_save_and_longjmp(); + } + + /* fault region can be mapped - prepare utcb */ + utcb->set_msg_word(0); + utcb->mtd = Mtd::FPU; + + if (utcb->inj_info & IRQ_INJ_VALID_MASK) { + /* + * The EPT violation occurred during event injection, + * so the event needs to be injected again. + */ + utcb->mtd |= Mtd::INJ; + utcb->inj_info = _last_inj_info; + utcb->inj_error = _last_inj_error; + } + + enum { + USER_PD = false, GUEST_PGT = true, + READABLE = true, EXECUTABLE = true + }; + + Rights permission(READABLE, writeable, EXECUTABLE); + + + /* add map items until no space is left on utcb anymore */ + do { + Flexpage flexpage = fli.page(); + if (!flexpage.valid() || flexpage.log2_order < 12) + break; + + /* touch memory - otherwise no mapping will take place */ + addr_t touch_me = flexpage.addr; + while (touch_me < flexpage.addr + (1UL << flexpage.log2_order)) { + touch_read(reinterpret_cast(touch_me)); + touch_me += 0x1000UL; + } + + Crd crd = Mem_crd(flexpage.addr >> 12, flexpage.log2_order - 12, + permission); + res = utcb->append_item(crd, flexpage.hotspot, USER_PD, GUEST_PGT); + + if (debug_map_memory) + Vmm::log("map guest mem ", Genode::Hex(flexpage.addr), + "+", 1UL << flexpage.log2_order, " -> ", + Genode::Hex(flexpage.hotspot), " ", + "guestf fault at ", Genode::Hex(guest_fault)); + } while (res); + + Nova::reply(_stack_reply); + } + + /** + * Shortcut for calling 'Vmm::Vcpu_dispatcher::register_handler' + * with 'Vcpu_dispatcher' as template argument + */ + template + void _register_handler(Genode::addr_t exc_base, Nova::Mtd mtd) + { + if (!register_handler(exc_base, mtd)) + Genode::error("could not register handler ", + Genode::Hex(exc_base + EV)); + } + + + Vmm::Vcpu_other_pd &vcpu() { return _vcpu; } + + + inline bool vbox_to_utcb(Nova::Utcb * utcb, VM *pVM, PVMCPU pVCpu) + { + PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); + + using namespace Nova; + + utcb->mtd |= Mtd::EIP; + utcb->ip = pCtx->rip; + + utcb->mtd |= Mtd::ESP; + utcb->sp = pCtx->rsp; + + utcb->mtd |= Mtd::ACDB; + utcb->ax = pCtx->rax; + utcb->bx = pCtx->rbx; + utcb->cx = pCtx->rcx; + utcb->dx = pCtx->rdx; + + utcb->mtd |= Mtd::EBSD; + utcb->bp = pCtx->rbp; + utcb->si = pCtx->rsi; + utcb->di = pCtx->rdi; + + utcb->mtd |= Mtd::R8_R15; + utcb->write_r8(pCtx->r8); + utcb->write_r9(pCtx->r9); + utcb->write_r10(pCtx->r10); + utcb->write_r11(pCtx->r11); + utcb->write_r12(pCtx->r12); + utcb->write_r13(pCtx->r13); + utcb->write_r14(pCtx->r14); + utcb->write_r15(pCtx->r15); + + utcb->mtd |= Mtd::EFL; + utcb->flags = pCtx->rflags.u; + + utcb->mtd |= Mtd::SYS; + utcb->sysenter_cs = pCtx->SysEnter.cs; + utcb->sysenter_sp = pCtx->SysEnter.esp; + utcb->sysenter_ip = pCtx->SysEnter.eip; + + utcb->mtd |= Mtd::DR; + utcb->dr7 = pCtx->dr[7]; + + utcb->mtd |= Mtd::CR; + utcb->cr0 = pCtx->cr0; + + utcb->mtd |= Mtd::CR; + utcb->cr2 = pCtx->cr2; + + utcb->mtd |= Mtd::CR; + utcb->cr3 = pCtx->cr3; + + utcb->mtd |= Mtd::CR; + utcb->cr4 = pCtx->cr4; + + utcb->mtd |= Mtd::IDTR; + utcb->idtr.limit = pCtx->idtr.cbIdt; + utcb->idtr.base = pCtx->idtr.pIdt; + + utcb->mtd |= Mtd::GDTR; + utcb->gdtr.limit = pCtx->gdtr.cbGdt; + utcb->gdtr.base = pCtx->gdtr.pGdt; + + utcb->mtd |= Mtd::EFER; + utcb->write_efer(CPUMGetGuestEFER(pVCpu)); + + /* + * Update the PDPTE registers if necessary + * + * Intel manual sections 4.4.1 of Vol. 3A and 26.3.2.4 of Vol. 3C + * indicate the conditions when this is the case. The following + * code currently does not check if the recompiler modified any + * CR registers, which means the update can happen more often + * than really necessary. + */ + if (pVM->hm.s.vmx.fSupported && + CPUMIsGuestPagingEnabledEx(pCtx) && + CPUMIsGuestInPAEModeEx(pCtx)) { + + Genode::uint64_t *pdpte = pdpte_map(pVM, utcb->cr3); + + utcb->mtd |= Mtd::PDPTE; + + utcb->pdpte[0] = pdpte[0]; + utcb->pdpte[1] = pdpte[1]; + utcb->pdpte[2] = pdpte[2]; + utcb->pdpte[3] = pdpte[3]; + } + + utcb->mtd |= Mtd::SYSCALL_SWAPGS; + utcb->write_star(pCtx->msrSTAR); + utcb->write_lstar(pCtx->msrLSTAR); + utcb->write_fmask(pCtx->msrSFMASK); + utcb->write_kernel_gs_base(pCtx->msrKERNELGSBASE); + + /* from HMVMXR0.cpp */ + bool interrupt_pending = false; + uint8_t tpr = 0; + uint8_t pending_interrupt = 0; + PDMApicGetTPR(pVCpu, &tpr, &interrupt_pending, &pending_interrupt); + utcb->mtd |= Mtd::TPR; + utcb->write_tpr(tpr); + utcb->write_tpr_threshold(0); + if (interrupt_pending) { + const uint8_t pending_priority = (pending_interrupt >> 4) & 0xf; + const uint8_t tpr_priority = (tpr >> 4) & 0xf; + if (pending_priority <= tpr_priority) + utcb->write_tpr_threshold(pending_priority); + else + utcb->write_tpr_threshold(tpr_priority); + } + + Assert(!(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))); + + return true; + } + + + inline bool utcb_to_vbox(Nova::Utcb * utcb, VM *pVM, PVMCPU pVCpu) + { + PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); + + pCtx->rip = utcb->ip; + pCtx->rsp = utcb->sp; + + pCtx->rax = utcb->ax; + pCtx->rbx = utcb->bx; + pCtx->rcx = utcb->cx; + pCtx->rdx = utcb->dx; + + pCtx->rbp = utcb->bp; + pCtx->rsi = utcb->si; + pCtx->rdi = utcb->di; + pCtx->rflags.u = utcb->flags; + + pCtx->r8 = utcb->read_r8(); + pCtx->r9 = utcb->read_r9(); + pCtx->r10 = utcb->read_r10(); + pCtx->r11 = utcb->read_r11(); + pCtx->r12 = utcb->read_r12(); + pCtx->r13 = utcb->read_r13(); + pCtx->r14 = utcb->read_r14(); + pCtx->r15 = utcb->read_r15(); + + pCtx->dr[7] = utcb->dr7; + + if (pCtx->SysEnter.cs != utcb->sysenter_cs) + CPUMSetGuestMsr(pVCpu, MSR_IA32_SYSENTER_CS, utcb->sysenter_cs); + + if (pCtx->SysEnter.esp != utcb->sysenter_sp) + CPUMSetGuestMsr(pVCpu, MSR_IA32_SYSENTER_ESP, utcb->sysenter_sp); + + if (pCtx->SysEnter.eip != utcb->sysenter_ip) + CPUMSetGuestMsr(pVCpu, MSR_IA32_SYSENTER_EIP, utcb->sysenter_ip); + + if (pCtx->idtr.cbIdt != utcb->idtr.limit || + pCtx->idtr.pIdt != utcb->idtr.base) + CPUMSetGuestIDTR(pVCpu, utcb->idtr.base, utcb->idtr.limit); + + if (pCtx->gdtr.cbGdt != utcb->gdtr.limit || + pCtx->gdtr.pGdt != utcb->gdtr.base) + CPUMSetGuestGDTR(pVCpu, utcb->gdtr.base, utcb->gdtr.limit); + + CPUMSetGuestEFER(pVCpu, utcb->read_efer()); + + if (pCtx->cr0 != utcb->cr0) + CPUMSetGuestCR0(pVCpu, utcb->cr0); + + if (pCtx->cr2 != utcb->cr2) + CPUMSetGuestCR2(pVCpu, utcb->cr2); + + if (pCtx->cr3 != utcb->cr3) { + CPUMSetGuestCR3(pVCpu, utcb->cr3); + VMCPU_FF_SET(pVCpu, VMCPU_FF_HM_UPDATE_CR3); + } + + if (pCtx->cr4 != utcb->cr4) + CPUMSetGuestCR4(pVCpu, utcb->cr4); + + if (pCtx->msrSTAR != utcb->read_star()) + CPUMSetGuestMsr(pVCpu, MSR_K6_STAR, utcb->read_star()); + + if (pCtx->msrLSTAR != utcb->read_lstar()) + CPUMSetGuestMsr(pVCpu, MSR_K8_LSTAR, utcb->read_lstar()); + + if (pCtx->msrSFMASK != utcb->read_fmask()) + CPUMSetGuestMsr(pVCpu, MSR_K8_SF_MASK, utcb->read_fmask()); + + if (pCtx->msrKERNELGSBASE != utcb->read_kernel_gs_base()) + CPUMSetGuestMsr(pVCpu, MSR_K8_KERNEL_GS_BASE, utcb->read_kernel_gs_base()); + + PDMApicSetTPR(pVCpu, utcb->read_tpr()); + + VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3); + + /* tell rem compiler that FPU register changed XXX optimizations ? */ + CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM); /* redundant ? XXX */ + pVCpu->cpum.s.fUseFlags |= (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM); /* redundant ? XXX */ + + if (utcb->intr_state != 0) { + Assert(utcb->intr_state == BLOCKING_BY_STI || + utcb->intr_state == BLOCKING_BY_MOV_SS); + EMSetInhibitInterruptsPC(pVCpu, pCtx->rip); + } else + VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); + + return true; + } + + + inline bool check_to_request_irq_window(Nova::Utcb * utcb, PVMCPU pVCpu) + { + if (!TRPMHasTrap(pVCpu) && + !VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | + VMCPU_FF_INTERRUPT_PIC))) + return false; + + unsigned vector = 0; + utcb->inj_info = NOVA_REQ_IRQWIN_EXIT | vector; + utcb->mtd |= Nova::Mtd::INJ; + + return true; + } + + + __attribute__((noreturn)) void _irq_window() + { + Nova::Utcb * utcb = reinterpret_cast(Thread::utcb()); + + PVMCPU pVCpu = _current_vcpu; + + Assert(utcb->intr_state == INTERRUPT_STATE_NONE); + Assert(utcb->flags & X86_EFL_IF); + Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)); + Assert(!(utcb->inj_info & IRQ_INJ_VALID_MASK)); + + Assert(_irq_win); + _irq_win = false; + + if (!TRPMHasTrap(pVCpu)) { + + bool res = VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI); + Assert(!res); + + if (VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | + VMCPU_FF_INTERRUPT_PIC))) { + + uint8_t irq; + int rc = PDMGetInterrupt(pVCpu, &irq); + Assert(RT_SUCCESS(rc)); + + rc = TRPMAssertTrap(pVCpu, irq, TRPM_HARDWARE_INT); + Assert(RT_SUCCESS(rc)); + } + } + + /* + * If we have no IRQ for injection, something with requesting the + * IRQ window went wrong. Probably it was forgotten to be reset. + */ + Assert(TRPMHasTrap(pVCpu)); + + /* interrupt can be dispatched */ + uint8_t u8Vector; + TRPMEVENT enmType; + SVMEVENT Event; + RTGCUINT u32ErrorCode; + RTGCUINTPTR GCPtrFaultAddress; + uint8_t cbInstr; + + Event.u = 0; + + /* If a new event is pending, then dispatch it now. */ + int rc = TRPMQueryTrapAll(pVCpu, &u8Vector, &enmType, &u32ErrorCode, 0, 0); + AssertRC(rc); + Assert(enmType == TRPM_HARDWARE_INT); + Assert(u8Vector != X86_XCPT_NMI); + + /* Clear the pending trap. */ + rc = TRPMResetTrap(pVCpu); + AssertRC(rc); + + Event.n.u8Vector = u8Vector; + Event.n.u1Valid = 1; + Event.n.u32ErrorCode = u32ErrorCode; + + Event.n.u3Type = SVM_EVENT_EXTERNAL_IRQ; + + utcb->inj_info = Event.u; + utcb->inj_error = Event.n.u32ErrorCode; + + _last_inj_info = utcb->inj_info; + _last_inj_error = utcb->inj_error; + +/* + Vmm::log("type:info:vector ", Genode::Hex(Event.n.u3Type), + Genode::Hex(utcb->inj_info), Genode::Hex(u8Vector), + " intr:actv - ", Genode::Hex(utcb->intr_state), + Genode::Hex(utcb->actv_state), " mtd ", + Genode::Hex(utcb->mtd)); +*/ + utcb->mtd = Nova::Mtd::INJ | Nova::Mtd::FPU; + Nova::reply(_stack_reply); + } + + + inline bool continue_hw_accelerated(Nova::Utcb * utcb, bool verbose = false) + { + Assert(!(VMCPU_FF_IS_SET(_current_vcpu, VMCPU_FF_INHIBIT_INTERRUPTS))); + + uint32_t check_vm = VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST + | VM_FF_PGM_POOL_FLUSH_PENDING + | VM_FF_PDM_DMA; + uint32_t check_vcpu = VMCPU_FF_HM_TO_R3_MASK + | VMCPU_FF_PGM_SYNC_CR3 + | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL + | VMCPU_FF_REQUEST; + + if (!VM_FF_IS_PENDING(_current_vm, check_vm) && + !VMCPU_FF_IS_PENDING(_current_vcpu, check_vcpu)) + return true; + + Assert(!(VM_FF_IS_PENDING(_current_vm, VM_FF_PGM_NO_MEMORY))); + +#define VERBOSE_VM(flag) \ + do { \ + if (VM_FF_IS_PENDING(_current_vm, flag)) \ + Vmm::log("flag ", flag, " pending"); \ + } while (0) + +#define VERBOSE_VMCPU(flag) \ + do { \ + if (VMCPU_FF_IS_PENDING(_current_vcpu, flag)) \ + Vmm::log("flag ", flag, " pending"); \ + } while (0) + + if (verbose) { + /* + * VM_FF_HM_TO_R3_MASK + */ + VERBOSE_VM(VM_FF_TM_VIRTUAL_SYNC); + VERBOSE_VM(VM_FF_PGM_NEED_HANDY_PAGES); + /* handled by the assertion above */ + /* VERBOSE_VM(VM_FF_PGM_NO_MEMORY); */ + VERBOSE_VM(VM_FF_PDM_QUEUES); + VERBOSE_VM(VM_FF_EMT_RENDEZVOUS); + + VERBOSE_VM(VM_FF_REQUEST); + VERBOSE_VM(VM_FF_PGM_POOL_FLUSH_PENDING); + VERBOSE_VM(VM_FF_PDM_DMA); + + /* + * VMCPU_FF_HM_TO_R3_MASK + */ + VERBOSE_VMCPU(VMCPU_FF_TO_R3); + /* when this flag gets set, a recall request follows */ + /* VERBOSE_VMCPU(VMCPU_FF_TIMER); */ + VERBOSE_VMCPU(VMCPU_FF_PDM_CRITSECT); + + VERBOSE_VMCPU(VMCPU_FF_PGM_SYNC_CR3); + VERBOSE_VMCPU(VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL); + VERBOSE_VMCPU(VMCPU_FF_REQUEST); + } + +#undef VERBOSE_VMCPU +#undef VERBOSE_VM + + return false; + } + + virtual bool hw_load_state(Nova::Utcb *, VM *, PVMCPU) = 0; + virtual bool hw_save_state(Nova::Utcb *, VM *, PVMCPU) = 0; + virtual int vm_exit_requires_instruction_emulation(PCPUMCTX) = 0; + + public: + + enum Exit_condition + { + SVM_NPT = 0xfc, + SVM_INVALID = 0xfd, + + VCPU_STARTUP = 0xfe, + + RECALL = 0xff, + }; + + + Vcpu_handler(size_t stack_size, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg, + Genode::Cpu_session * cpu_session, + Genode::Affinity::Location location, + unsigned int cpu_id) + : + Vmm::Vcpu_dispatcher(stack_size, *Genode::env()->pd_session(), + cpu_session, location, + attr ? *attr : 0, start_routine, arg), + _vcpu(cpu_session, location), + _ec_sel(Genode::cap_map()->insert()), + _irq_win(false), + _cpu_id(cpu_id) + { } + + unsigned int cpu_id() { return _cpu_id; } + + void start() { + _vcpu.start(_ec_sel); + } + + void recall() + { + using namespace Nova; + + if (ec_ctrl(EC_RECALL, _ec_sel) != NOVA_OK) { + Genode::error("recall failed"); + Genode::Lock lock(Genode::Lock::LOCKED); + lock.lock(); + } + } + + void halt() + { + _halt_sem.down(); + } + + void wake_up() + { + _halt_sem.up(); + } + + int run_hw(PVMR0 pVMR0) + { + VM * pVM = reinterpret_cast(pVMR0); + PVMCPU pVCpu = &pVM->aCpus[_cpu_id]; + PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); + + Nova::Utcb *utcb = reinterpret_cast(Thread::utcb()); + + Assert(Thread::utcb() == Thread::myself()->utcb()); + + Genode::addr_t old = pCtx->rip; + + /* take the utcb state prepared during the last exit */ + utcb->mtd = next_utcb.mtd; + utcb->inj_info = IRQ_INJ_NONE; + utcb->intr_state = next_utcb.intr_state; + utcb->actv_state = ACTIVITY_STATE_ACTIVE; + utcb->ctrl[0] = next_utcb.ctrl[0]; + utcb->ctrl[1] = next_utcb.ctrl[1]; + + using namespace Nova; + + /* Transfer vCPU state from vBox to Nova format */ + if (!vbox_to_utcb(utcb, pVM, pVCpu) || + !hw_load_state(utcb, pVM, pVCpu)) { + + Genode::error("loading vCPU state failed"); + return VERR_INTERNAL_ERROR; + } + + /* check whether to request interrupt window for injection */ + _irq_win = check_to_request_irq_window(utcb, pVCpu); + + /* + * Flag vCPU to be "pokeable" by external events such as interrupts + * from virtual devices. Only if this flag is set, the + * 'vmR3HaltGlobal1NotifyCpuFF' function calls 'SUPR3CallVMMR0Ex' + * with VMMR0_DO_GVMM_SCHED_POKE as argument to indicate such + * events. This function, in turn, will recall the vCPU. + */ + VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC); + + /* save current FPU state */ + fpu_save(reinterpret_cast(&_emt_fpu_state)); + /* write FPU state from pCtx to FPU registers */ + fpu_load(reinterpret_cast(pCtx->pXStateR3)); + /* tell kernel to transfer current fpu registers to vCPU */ + utcb->mtd |= Mtd::FPU; + + _current_vm = pVM; + _current_vcpu = pVCpu; + + /* switch to hardware accelerated mode */ + switch_to_hw(); + + Assert(utcb->actv_state == ACTIVITY_STATE_ACTIVE); + + _current_vm = 0; + _current_vcpu = 0; + + /* write FPU state of vCPU (in current FPU registers) to pCtx */ + Genode::memcpy(pCtx->pXStateR3, &_guest_fpu_state, sizeof(X86FXSTATE)); + + /* load saved FPU state of EMT thread */ + fpu_load(reinterpret_cast(&_emt_fpu_state)); + + /* see hmR0VmxExitToRing3 - sync recompiler state */ + CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_SYSENTER_MSR | + CPUM_CHANGED_LDTR | CPUM_CHANGED_GDTR | + CPUM_CHANGED_IDTR | CPUM_CHANGED_TR | + CPUM_CHANGED_HIDDEN_SEL_REGS | + CPUM_CHANGED_GLOBAL_TLB_FLUSH); + + VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED); + + /* Transfer vCPU state from Nova to vBox format */ + if (!utcb_to_vbox(utcb, pVM, pVCpu) || + !hw_save_state(utcb, pVM, pVCpu)) { + + Genode::error("saving vCPU state failed"); + return VERR_INTERNAL_ERROR; + } + + /* reset message transfer descriptor for next invocation */ + Assert (!(utcb->inj_info & IRQ_INJ_VALID_MASK)); + /* Reset irq window next time if we are still requesting it */ + next_utcb.mtd = _irq_win ? Mtd::INJ : 0; + + next_utcb.intr_state = utcb->intr_state; + next_utcb.ctrl[0] = utcb->ctrl[0]; + next_utcb.ctrl[1] = utcb->ctrl[1]; + + if (next_utcb.intr_state & 3) { + next_utcb.intr_state &= ~3U; + next_utcb.mtd |= Mtd::STA; + } + +#ifdef VBOX_WITH_REM + /* XXX see VMM/VMMR0/HMVMXR0.cpp - not necessary every time ! XXX */ + REMFlushTBs(pVM); +#endif + + /* track guest mode changes - see VMM/VMMAll/IEMAllCImpl.cpp.h */ + PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER); + + int rc = vm_exit_requires_instruction_emulation(pCtx); + + /* evaluated in VMM/include/EMHandleRCTmpl.h */ + return rc; + } +}; + +#endif /* _VIRTUALBOX__SPEC__NOVA__VCPU_H_ */ diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h b/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h new file mode 100644 index 0000000000..6e79f82a6d --- /dev/null +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h @@ -0,0 +1,141 @@ +/* + * \brief Genode/Nova specific VirtualBox SUPLib supplements + * \author Alexander Boettcher + * \date 2013-11-18 + */ + +/* + * Copyright (C) 2013-2016 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _VIRTUALBOX__SPEC__NOVA__VCPU_SVM_H_ +#define _VIRTUALBOX__SPEC__NOVA__VCPU_SVM_H_ + +/* Genode's VirtualBox includes */ +#include "vcpu.h" +#include "svm.h" + +class Vcpu_handler_svm : public Vcpu_handler +{ + private: + + __attribute__((noreturn)) void _svm_default() { _default_handler(); } + + __attribute__((noreturn)) void _svm_vintr() { _irq_window(); } + + __attribute__((noreturn)) void _svm_ioio() + { + using namespace Nova; + using namespace Genode; + + Thread *myself = Thread::myself(); + Utcb *utcb = reinterpret_cast(myself->utcb()); + + if (utcb->qual[0] & 0x4) { + unsigned ctrl0 = utcb->ctrl[0]; + + Vmm::warning("invalid gueststate"); + + utcb->ctrl[0] = ctrl0; + utcb->ctrl[1] = 0; + utcb->mtd = Mtd::CTRL; + + Nova::reply(_stack_reply); + } + + _default_handler(); + } + + template + __attribute__((noreturn)) void _svm_npt() + { + using namespace Nova; + using namespace Genode; + + Thread *myself = Thread::myself(); + Utcb *utcb = reinterpret_cast(myself->utcb()); + + _exc_memory(myself, utcb, utcb->qual[0] & 1, + utcb->qual[1], utcb->qual[0]); + } + + __attribute__((noreturn)) void _svm_startup() + { + using namespace Nova; + + /* enable VM exits for CPUID */ + next_utcb.mtd = Nova::Mtd::CTRL; + next_utcb.ctrl[0] = SVM_CTRL1_INTERCEPT_CPUID; + next_utcb.ctrl[1] = 0; + + void *exit_status = _start_routine(_arg); + pthread_exit(exit_status); + + Nova::reply(nullptr); + } + + __attribute__((noreturn)) void _svm_recall() + { + Vcpu_handler::_recall_handler(); + } + + public: + + Vcpu_handler_svm(size_t stack_size, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg, + Genode::Cpu_session * cpu_session, + Genode::Affinity::Location location, + unsigned int cpu_id) + : + Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session, + location, cpu_id) + { + using namespace Nova; + + Genode::addr_t const exc_base = vcpu().exc_base(); + + typedef Vcpu_handler_svm This; + + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + register_handler> (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + + start(); + } + + bool hw_save_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) { + return svm_save_state(utcb, pVM, pVCpu); + } + + bool hw_load_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) { + return svm_load_state(utcb, pVM, pVCpu); + } + + int vm_exit_requires_instruction_emulation(PCPUMCTX) + { + if (exit_reason == RECALL) + return VINF_SUCCESS; + + return VINF_EM_RAW_EMULATE_INSTR; + } +}; + +#endif /* _VIRTUALBOX__SPEC__NOVA__VCPU_SVM_H_ */ diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h b/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h new file mode 100644 index 0000000000..f662b586ae --- /dev/null +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h @@ -0,0 +1,274 @@ +/* + * \brief Genode/Nova specific VirtualBox SUPLib supplements + * \author Alexander Boettcher + * \author Norman Feske + * \author Christian Helmuth + */ + +/* + * Copyright (C) 2013-2016 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _VIRTUALBOX__SPEC__NOVA__VCPU_VMX_H_ +#define _VIRTUALBOX__SPEC__NOVA__VCPU_VMX_H_ + +/* libc includes */ +#include + +/* VirtualBox includes */ +#include + +/* Genode's VirtualBox includes */ +#include "vcpu.h" +#include "vmx.h" + + +class Vcpu_handler_vmx : public Vcpu_handler +{ + private: + + template + __attribute__((noreturn)) void _vmx_ept() + { + using namespace Nova; + using namespace Genode; + + Thread *myself = Thread::myself(); + Utcb *utcb = reinterpret_cast(myself->utcb()); + + addr_t exit_qual = utcb->qual[0]; + addr_t exit_addr = utcb->qual[1]; + + RTGCUINT vbox_errorcode = 0; + if (exit_qual & VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH) + vbox_errorcode |= X86_TRAP_PF_ID; + if (exit_qual & VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE) + vbox_errorcode |= X86_TRAP_PF_RW; + if (exit_qual & VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT) + vbox_errorcode |= X86_TRAP_PF_P; + + _exc_memory(myself, utcb, exit_qual & 0x38, exit_addr, + vbox_errorcode); + } + + __attribute__((noreturn)) void _vmx_default() { _default_handler(); } + + __attribute__((noreturn)) void _vmx_startup() + { + using namespace Nova; + + Genode::Thread *myself = Genode::Thread::myself(); + Utcb *utcb = reinterpret_cast(myself->utcb()); + + /* configure VM exits to get */ + next_utcb.mtd = Nova::Mtd::CTRL; + /* from src/VBox/VMM/VMMR0/HWVMXR0.cpp of virtualbox sources */ + next_utcb.ctrl[0] = VMX_VMCS_CTRL_PROC_EXEC_HLT_EXIT | + VMX_VMCS_CTRL_PROC_EXEC_MOV_DR_EXIT | + VMX_VMCS_CTRL_PROC_EXEC_UNCOND_IO_EXIT | +/* XXX commented out because TinyCore Linux won't run as guest otherwise + VMX_VMCS_CTRL_PROC_EXEC_MONITOR_EXIT | + VMX_VMCS_CTRL_PROC_EXEC_MWAIT_EXIT | +*/ +/* VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT | + VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT |*/ + VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW | + VMX_VMCS_CTRL_PROC_EXEC_RDPMC_EXIT; +/* VMX_VMCS_CTRL_PROC_EXEC_PAUSE_EXIT | */ + /* + * Disable trapping RDTSC for now as it creates a huge load with + * VM guests that execute it frequently. + */ + // VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT; + + next_utcb.ctrl[1] = VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC | + VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT | + VMX_VMCS_CTRL_PROC_EXEC2_UNRESTRICTED_GUEST | + VMX_VMCS_CTRL_PROC_EXEC2_VPID | +/* VMX_VMCS_CTRL_PROC_EXEC2_X2APIC | */ + VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP | + VMX_VMCS_CTRL_PROC_EXEC2_EPT; + + void *exit_status = _start_routine(_arg); + pthread_exit(exit_status); + + Nova::reply(nullptr); + } + + __attribute__((noreturn)) void _vmx_triple() + { + Vmm::error("triple fault - dead"); + exit(-1); + } + + __attribute__((noreturn)) void _vmx_irqwin() { _irq_window(); } + + __attribute__((noreturn)) void _vmx_recall() + { + Vcpu_handler::_recall_handler(); + } + + __attribute__((noreturn)) void _vmx_invalid() + { + Genode::Thread *myself = Genode::Thread::myself(); + Nova::Utcb *utcb = reinterpret_cast(myself->utcb()); + + unsigned const dubious = utcb->inj_info | + utcb->intr_state | utcb->actv_state; + if (dubious) + Vmm::warning(__func__, " - dubious -" + " inj_info=", Genode::Hex(utcb->inj_info), + " inj_error=", Genode::Hex(utcb->inj_error), + " intr_state=", Genode::Hex(utcb->intr_state), + " actv_state=", Genode::Hex(utcb->actv_state)); + + Vmm::error("invalid guest state - dead"); + exit(-1); + } + + /* + * This VM exit is in part handled by the NOVA kernel (writing the CR + * register) and in part by VirtualBox (updating the PDPTE registers, + * which requires access to the guest physical memory). + * Intel manual sections 4.4.1 of Vol. 3A and 26.3.2.4 of Vol. 3C + * indicate the conditions when the PDPTE registers need to get + * updated. + */ + __attribute__((noreturn)) void _vmx_mov_crx() + { + unsigned long value; + void *stack_reply = reinterpret_cast(&value - 1); + + Genode::Thread *myself = Genode::Thread::myself(); + Nova::Utcb *utcb = reinterpret_cast(myself->utcb()); + + unsigned int cr = utcb->qual[0] & 0xf; + + if (cr == 8) + _default_handler(); + + Genode::uint64_t *pdpte = pdpte_map(_current_vm, utcb->cr3); + + Assert(pdpte != 0); + + utcb->pdpte[0] = pdpte[0]; + utcb->pdpte[1] = pdpte[1]; + utcb->pdpte[2] = pdpte[2]; + utcb->pdpte[3] = pdpte[3]; + + utcb->mtd = Nova::Mtd::PDPTE | Nova::Mtd::FPU; + + Nova::reply(stack_reply); + } + + public: + + Vcpu_handler_vmx(size_t stack_size, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg, + Genode::Cpu_session * cpu_session, + Genode::Affinity::Location location, + unsigned int cpu_id) + : + Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session, + location, cpu_id) + { + using namespace Nova; + + typedef Vcpu_handler_vmx This; + + Genode::addr_t const exc_base = vcpu().exc_base(); + + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + + /* we don't support tsc offsetting for now - so let the rdtsc exit */ + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); +// register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler> (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + + start(); + } + + bool hw_save_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) { + return vmx_save_state(utcb, pVM, pVCpu); + } + + bool hw_load_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) { + return vmx_load_state(utcb, pVM, pVCpu); + } + + int vm_exit_requires_instruction_emulation(PCPUMCTX pCtx) + { + switch (exit_reason) { + case VMX_EXIT_HLT: + pCtx->rip++; + return VINF_EM_HALT; + case VMX_EXIT_IO_INSTR: + /* EMHandleRCTmpl.h does not distinguish READ/WRITE rc */ + return VINF_IOM_R3_IOPORT_WRITE; + case VMX_EXIT_RDMSR: + return VINF_CPUM_R3_MSR_READ; + case VMX_EXIT_WRMSR: + return VINF_CPUM_R3_MSR_WRITE; + case VMX_EXIT_TPR_BELOW_THRESHOLD: + /* the instruction causing the exit has already been executed */ + case RECALL: + return VINF_SUCCESS; + case VMX_EXIT_EPT_VIOLATION: + if (_ept_fault_addr_type == PGMPAGETYPE_MMIO) + /* EMHandleRCTmpl.h does not distinguish READ/WRITE rc */ + return VINF_IOM_R3_MMIO_READ_WRITE; + case VMX_EXIT_MOV_DRX: + /* looks complicated in original R0 code -> emulate instead */ + return VINF_EM_RAW_EMULATE_INSTR; + default: + if (exit_reason != VMX_EXIT_EPT_VIOLATION && + exit_reason != VMX_EXIT_CPUID) + Genode::log("leave exit_reason=", exit_reason, " - " + "optimize ?"); + + return VINF_EM_RAW_EMULATE_INSTR; + } + } +}; + +#endif /* _VIRTUALBOX__SPEC__NOVA__VCPU_VMX_H_ */ diff --git a/repos/ports/src/virtualbox5/spec/nova/vmx.h b/repos/ports/src/virtualbox5/spec/nova/vmx.h new file mode 100644 index 0000000000..2accfd5b67 --- /dev/null +++ b/repos/ports/src/virtualbox5/spec/nova/vmx.h @@ -0,0 +1,129 @@ +/* + * \brief Genode/Nova specific VirtualBox SUPLib supplements + * \author Norman Feske + * \author Alexander Boettcher + */ + +/* + * Copyright (C) 2013-2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _VIRTUALBOX__SPEC__NOVA__VMX_H_ +#define _VIRTUALBOX__SPEC__NOVA__VMX_H_ + +#define GENODE_READ_SELREG_REQUIRED(REG) \ + (pCtx->REG.Sel != utcb->REG.sel) || \ + (pCtx->REG.ValidSel != utcb->REG.sel) || \ + (pCtx->REG.fFlags != CPUMSELREG_FLAGS_VALID) || \ + (pCtx->REG.u32Limit != utcb->REG.limit) || \ + (pCtx->REG.u64Base != utcb->REG.base) || \ + (pCtx->REG.Attr.u != sel_ar_conv_from_nova(utcb->REG.ar)) + +#define GENODE_READ_SELREG(REG) \ + pCtx->REG.Sel = utcb->REG.sel; \ + pCtx->REG.ValidSel = utcb->REG.sel; \ + pCtx->REG.fFlags = CPUMSELREG_FLAGS_VALID; \ + pCtx->REG.u32Limit = utcb->REG.limit; \ + pCtx->REG.u64Base = utcb->REG.base; \ + pCtx->REG.Attr.u = sel_ar_conv_from_nova(utcb->REG.ar) + +static inline bool vmx_save_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) +{ + PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); + + GENODE_READ_SELREG(cs); + GENODE_READ_SELREG(ds); + GENODE_READ_SELREG(es); + GENODE_READ_SELREG(fs); + GENODE_READ_SELREG(gs); + GENODE_READ_SELREG(ss); + + if (GENODE_READ_SELREG_REQUIRED(ldtr)) { + GENODE_READ_SELREG(ldtr); + CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_LDTR); + } + if (GENODE_READ_SELREG_REQUIRED(tr)) { + GENODE_READ_SELREG(tr); + CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_TR); + } + + return true; +} + +#undef GENODE_READ_SELREG_REQUIRED +#undef GENODE_READ_SELREG + + +enum { VMCS_SEG_UNUSABLE = 0x10000 }; + +#define GENODE_WRITE_SELREG(REG) \ + Assert(pCtx->REG.fFlags & CPUMSELREG_FLAGS_VALID); \ + Assert(pCtx->REG.ValidSel == pCtx->REG.Sel); \ + utcb->REG.sel = pCtx->REG.Sel; \ + utcb->REG.limit = pCtx->REG.u32Limit; \ + utcb->REG.base = pCtx->REG.u64Base; \ + utcb->REG.ar = sel_ar_conv_to_nova(pCtx->REG.Attr.u ? : VMCS_SEG_UNUSABLE); + +static inline bool vmx_load_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) +{ + PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu); + + { + utcb->mtd |= Nova::Mtd::ESDS; + GENODE_WRITE_SELREG(es); + GENODE_WRITE_SELREG(ds); + } + + { + utcb->mtd |= Nova::Mtd::FSGS; + GENODE_WRITE_SELREG(fs); + GENODE_WRITE_SELREG(gs); + } + + { + utcb->mtd |= Nova::Mtd::CSSS; + GENODE_WRITE_SELREG(cs); + GENODE_WRITE_SELREG(ss); + } + + /* ldtr */ + if (pCtx->ldtr.Sel == 0) { + { + utcb->mtd |= Nova::Mtd::LDTR; + + utcb->ldtr.sel = 0; + utcb->ldtr.limit = 0; + utcb->ldtr.base = 0; + utcb->ldtr.ar = sel_ar_conv_to_nova(0x82); + } + } else { + { + utcb->mtd |= Nova::Mtd::LDTR; + + utcb->ldtr.sel = pCtx->ldtr.Sel; + utcb->ldtr.limit = pCtx->ldtr.u32Limit; + utcb->ldtr.base = pCtx->ldtr.u64Base; + utcb->ldtr.ar = sel_ar_conv_to_nova(pCtx->ldtr.Attr.u); + } + } + + /* tr */ + Assert(pCtx->tr.Attr.u & X86_SEL_TYPE_SYS_TSS_BUSY_MASK); + { + utcb->mtd |= Nova::Mtd::TR; + + utcb->tr.sel = pCtx->tr.Sel; + utcb->tr.limit = pCtx->tr.u32Limit; + utcb->tr.base = pCtx->tr.u64Base; + utcb->tr.ar = sel_ar_conv_to_nova(pCtx->tr.Attr.u); + } + + return true; +} + +#undef GENODE_WRITE_SELREG + +#endif /* _VIRTUALBOX__SPEC__NOVA__VMX_H_ */ diff --git a/repos/ports/src/virtualbox5/sup.cc b/repos/ports/src/virtualbox5/sup.cc new file mode 100644 index 0000000000..1285487b51 --- /dev/null +++ b/repos/ports/src/virtualbox5/sup.cc @@ -0,0 +1,332 @@ +/* + * \brief VirtualBox SUPLib supplements + * \author Norman Feske + * \date 2013-08-20 + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include +#include +#include +#include + +/* Genode/Virtualbox includes */ +#include "sup.h" + +/* VirtualBox includes */ +#include +#include +#include +#include + +/* libc memory allocator */ +#include + + +enum { + UPDATE_HZ = 1000, + UPDATE_US = 1000 * 1000 / UPDATE_HZ, + UPDATE_NS = UPDATE_US * 1000, +}; + + +PSUPGLOBALINFOPAGE g_pSUPGlobalInfoPage; + + +struct Periodic_gip : public Genode::Thread_deprecated<4096> +{ + Periodic_gip() : Thread_deprecated("periodic_gip") { start(); } + + static void update() + { + /** + * We're using rdtsc here since timer_session->elapsed_ms produces + * instable results when the timer service is using the Genode PIC + * driver as done for base-nova currently. + */ + + Genode::uint64_t tsc_current = Genode::Trace::timestamp(); + + /* + * Convert tsc to nanoseconds. + * + * There is no 'uint128_t' type on x86_32, so we use the 128-bit type + * and functions provided by VirtualBox. + * + * nanots128 = tsc_current * 1000*1000*1000 / genode_cpu_hz() + * + */ + + RTUINT128U nanots128; + RTUInt128AssignU64(&nanots128, tsc_current); + + RTUINT128U multiplier; + RTUInt128AssignU32(&multiplier, 1000*1000*1000); + RTUInt128AssignMul(&nanots128, &multiplier); + + RTUINT128U divisor; + RTUInt128AssignU64(&divisor, genode_cpu_hz()); + RTUInt128AssignDiv(&nanots128, &divisor); + + SUPGIPCPU *cpu = &g_pSUPGlobalInfoPage->aCPUs[0]; + + /* + * Transaction id must be incremented before and after update, + * read struct SUPGIPCPU description for more details. + */ + ASMAtomicIncU32(&cpu->u32TransactionId); + + cpu->u64TSC = tsc_current; + cpu->u64NanoTS = nanots128.s.Lo; + + /* + * Transaction id must be incremented before and after update, + * read struct SUPGIPCPU description for more details. + */ + ASMAtomicIncU32(&cpu->u32TransactionId); + } + + void entry() override { genode_update_tsc(update, UPDATE_US); } +}; + + +struct Attached_gip : Genode::Attached_ram_dataspace +{ + Attached_gip() + : Attached_ram_dataspace(Genode::env()->ram_session(), PAGE_SIZE) + { + g_pSUPGlobalInfoPage = local_addr(); + + /* checked by TMR3Init */ + g_pSUPGlobalInfoPage->u32Version = SUPGLOBALINFOPAGE_VERSION; + g_pSUPGlobalInfoPage->u32Magic = SUPGLOBALINFOPAGE_MAGIC; + g_pSUPGlobalInfoPage->u32Mode = SUPGIPMODE_SYNC_TSC; + g_pSUPGlobalInfoPage->cCpus = 1; + g_pSUPGlobalInfoPage->cPages = 1; + g_pSUPGlobalInfoPage->u32UpdateHz = UPDATE_HZ; + g_pSUPGlobalInfoPage->u32UpdateIntervalNS = UPDATE_NS; + g_pSUPGlobalInfoPage->cOnlineCpus = 0; + g_pSUPGlobalInfoPage->cPresentCpus = 0; + g_pSUPGlobalInfoPage->cPossibleCpus = 0; + g_pSUPGlobalInfoPage->idCpuMax = 0; + g_pSUPGlobalInfoPage->u64CpuHz = genode_cpu_hz(); + /* evaluated by rtTimeNanoTSInternalRediscover in Runtime/common/time/timesup.cpp */ + g_pSUPGlobalInfoPage->fGetGipCpu = SUPGIPGETCPU_APIC_ID; + + SUPGIPCPU *cpu = &g_pSUPGlobalInfoPage->aCPUs[0]; + + cpu->u32TransactionId = 0; + cpu->u32UpdateIntervalTSC = genode_cpu_hz() / UPDATE_HZ; + cpu->u64NanoTS = 0ULL; + cpu->u64TSC = 0ULL; + cpu->u64CpuHz = genode_cpu_hz(); + cpu->cErrors = 0; + cpu->iTSCHistoryHead = 0; + cpu->u32PrevUpdateIntervalNS = UPDATE_NS; + cpu->enmState = SUPGIPCPUSTATE_ONLINE; + cpu->idCpu = 0; + cpu->iCpuSet = 0; + cpu->idApic = 0; + + /* schedule periodic call of GIP update function */ + static Periodic_gip periodic_gip; + } +} static gip; + + +int SUPR3Init(PSUPDRVSESSION *ppSession) +{ + return VINF_SUCCESS; +} + +SUPR3DECL(SUPPAGINGMODE) SUPR3GetPagingMode(void) +{ + return sizeof(void *) == 4 ? SUPPAGINGMODE_32_BIT : SUPPAGINGMODE_AMD64_NX; +} + +int SUPR3Term(bool) { return VINF_SUCCESS; } + + +int SUPR3GipGetPhys(PRTHCPHYS pHCPhys) +{ + /* + * Return VMM-local address as physical address. This address is + * then fed to MMR3HyperMapHCPhys. (TMR3Init) + */ + *pHCPhys = (RTHCPHYS)g_pSUPGlobalInfoPage; + + return VINF_SUCCESS; +} + + +int SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, + uint32_t fFlags, PRTERRINFO pErrInfo) +{ + return RTLdrLoad(pszFilename, phLdrMod); +} + + +SUPR3DECL(int) SUPR3PageFreeEx(void *pvPages, size_t cPages) +{ + Genode::log(__func__, " pvPages=", pvPages, " pages=", cPages); + return VINF_SUCCESS; +} + + +uint32_t SUPSemEventMultiGetResolution(PSUPDRVSESSION) +{ + return 100000*10; /* called by 'vmR3HaltGlobal1Init' */ +} + +int SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent) +{ + *phEvent = (SUPSEMEVENT)new Genode::Semaphore(); + return VINF_SUCCESS; +} + + +int SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent) +{ + if (hEvent) + delete reinterpret_cast(hEvent); + return VINF_SUCCESS; +} + + +int SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent) +{ + if (hEvent) + reinterpret_cast(hEvent)->up(); + else + Genode::error(__FUNCTION__, " called - not implemented"); + + return VINF_SUCCESS; +} + + +int SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, + uint32_t cMillies) +{ + if (hEvent && cMillies == RT_INDEFINITE_WAIT) + reinterpret_cast(hEvent)->down(); + else { + Genode::error(__FUNCTION__, " called millis=", cMillies, + " - not implemented"); + reinterpret_cast(hEvent)->down(); + } + + return VINF_SUCCESS; +} + + +SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION, + PSUPSEMEVENTMULTI phEventMulti) +{ + RTSEMEVENTMULTI sem; + + /* + * Input validation. + */ + AssertPtrReturn(phEventMulti, VERR_INVALID_POINTER); + + /* + * Create the event semaphore object. + */ + int rc = RTSemEventMultiCreate(&sem); + + static_assert(sizeof(sem) == sizeof(*phEventMulti), "oi"); + *phEventMulti = reinterpret_cast(sem); + return rc; +} + + +SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION, SUPSEMEVENTMULTI hEvMulti) +{ + return RTSemEventMultiDestroy(reinterpret_cast(hEvMulti)); +} + + +int SUPR3CallVMMR0(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, + void *pvArg) +{ + if (uOperation == VMMR0_DO_CALL_HYPERVISOR) { + Genode::log(__func__, ": VMMR0_DO_CALL_HYPERVISOR - doing nothing"); + return VINF_SUCCESS; + } + if (uOperation == VMMR0_DO_VMMR0_TERM) { + Genode::log(__func__, ": VMMR0_DO_VMMR0_TERM - doing nothing"); + return VINF_SUCCESS; + } + if (uOperation == VMMR0_DO_GVMM_DESTROY_VM) { + Genode::log(__func__, ": VMMR0_DO_GVMM_DESTROY_VM - doing nothing"); + return VINF_SUCCESS; + } + + AssertMsg(uOperation != VMMR0_DO_VMMR0_TERM && + uOperation != VMMR0_DO_CALL_HYPERVISOR && + uOperation != VMMR0_DO_GVMM_DESTROY_VM, + ("SUPR3CallVMMR0: unhandled uOperation %d", uOperation)); + return VERR_GENERAL_FAILURE; +} + + +void genode_VMMR0_DO_GVMM_CREATE_VM(PSUPVMMR0REQHDR pReqHdr) +{ + GVMMCREATEVMREQ &req = reinterpret_cast(*pReqHdr); + + size_t const cCpus = req.cCpus; + + /* + * Allocate and initialize VM struct + * + * The VM struct is followed by the variable-sizedA array of VMCPU + * objects. 'RT_UOFFSETOF' is used to determine the size including + * the VMCPU array. + * + * VM struct must be page-aligned, which is checked at least in + * PDMR3CritSectGetNop(). + */ + size_t const cbVM = RT_UOFFSETOF(VM, aCpus[cCpus]); + VM *pVM = (VM *)Libc::mem_alloc()->alloc(cbVM, Genode::log2(PAGE_SIZE)); + Genode::memset(pVM, 0, cbVM); + + /* + * On Genode, VMMR0 and VMMR3 share a single address space. Hence, the + * same pVM pointer is valid as pVMR0 and pVMR3. + */ + pVM->enmVMState = VMSTATE_CREATING; + pVM->pVMR0 = (RTHCUINTPTR)pVM; + pVM->pVMRC = (RTGCUINTPTR)pVM; + pVM->pSession = req.pSession; + pVM->cbSelf = cbVM; + pVM->cCpus = cCpus; + pVM->uCpuExecutionCap = 100; /* expected by 'vmR3CreateU()' */ + pVM->offVMCPU = RT_UOFFSETOF(VM, aCpus); + + for (uint32_t i = 0; i < cCpus; i++) { + pVM->aCpus[i].pVMR0 = pVM->pVMR0; + pVM->aCpus[i].pVMR3 = pVM; + pVM->aCpus[i].idHostCpu = NIL_RTCPUID; + pVM->aCpus[i].hNativeThreadR0 = NIL_RTNATIVETHREAD; + } + + pVM->aCpus[0].hNativeThreadR0 = RTThreadNativeSelf(); + + /* out parameters of the request */ + req.pVMR0 = pVM->pVMR0; + req.pVMR3 = pVM; +} + + +void genode_VMMR0_DO_GVMM_REGISTER_VMCPU(PVMR0 pVMR0, VMCPUID idCpu) +{ + PVM pVM = reinterpret_cast(pVMR0); + pVM->aCpus[idCpu].hNativeThreadR0 = RTThreadNativeSelf(); +} diff --git a/repos/ports/src/virtualbox5/sup.h b/repos/ports/src/virtualbox5/sup.h new file mode 100644 index 0000000000..b2029feeee --- /dev/null +++ b/repos/ports/src/virtualbox5/sup.h @@ -0,0 +1,45 @@ +/* + * \brief Common VirtualBox SUPLib supplements + * \author Norman Feske + * \date 2013-08-20 + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _SUP_H_ +#define _SUP_H_ + +/* Genode includes */ +#include + +/* VirtualBox includes */ +#include +#include +#include + +/** + * Returns true if a vCPU could be started. If false we run without + * hardware acceleration support. + */ +bool create_emt_vcpu(pthread_t * pthread, size_t stack, + const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg, + Genode::Cpu_session * cpu_session, + Genode::Affinity::Location location, + unsigned int cpu_id); + + +uint64_t genode_cpu_hz(); +void genode_update_tsc(void (*update_func)(void), unsigned long update_us); + +Genode::Cpu_session * get_vcpu_cpu_session(); + +void genode_VMMR0_DO_GVMM_CREATE_VM(PSUPVMMR0REQHDR pReqHdr); +void genode_VMMR0_DO_GVMM_REGISTER_VMCPU(PVMR0 pVMR0, VMCPUID idCpu); + +#endif /* _SUP_H_ */ diff --git a/repos/ports/src/virtualbox5/target.mk b/repos/ports/src/virtualbox5/target.mk new file mode 100644 index 0000000000..aebfb660fa --- /dev/null +++ b/repos/ports/src/virtualbox5/target.mk @@ -0,0 +1,68 @@ +REQUIRES = nova + +VBOX_CC_OPT += -DVBOX_WITH_HARDENING +VBOX_CC_OPT += -DVBOX_WITH_GENERIC_SESSION_WATCHER + +include $(REP_DIR)/lib/mk/virtualbox5-common.inc + +CC_WARN += -Wall + +TARGET = virtualbox5 +SRC_CC = frontend/main.cc frontend/console.cc \ + frontend/VirtualBoxErrorInfoImpl.cpp \ + devices.cc drivers.cc dummies.cc libc.cc \ + logger.cc mm.cc pdm.cc pgm.cc rt.cc sup.cc \ + hm.cc thread.cc dynlib.cc unimpl.cc + +# use implementation of VBOX 4 +vpath devices.cc $(REP_DIR)/src/virtualbox +vpath drivers.cc $(REP_DIR)/src/virtualbox +vpath dynlib.cc $(REP_DIR)/src/virtualbox +vpath libc.cc $(REP_DIR)/src/virtualbox +vpath logger.cc $(REP_DIR)/src/virtualbox +vpath pdm.cc $(REP_DIR)/src/virtualbox +vpath rt.cc $(REP_DIR)/src/virtualbox +vpath thread.cc $(REP_DIR)/src/virtualbox + +LIBS += base +LIBS += config_args +LIBS += stdcxx + +LIBS += virtualbox5-bios virtualbox5-recompiler virtualbox5-runtime \ + virtualbox5-vmm virtualbox5-devices virtualbox5-drivers \ + virtualbox5-storage virtualbox5-zlib virtualbox5-liblzf \ + virtualbox5-xml virtualbox5-main virtualbox5-apiwrap \ + virtualbox5-dis virtualbox5-hwaccl + +LIBS += pthread libc_terminal libc_pipe libiconv + +LIBS += qemu-usb + +INC_DIR += $(call select_from_repositories,src/lib/libc) +INC_DIR += $(call select_from_repositories,src/lib/pthread) + +INC_DIR += $(VBOX_DIR)/Runtime/include + +SRC_CC += HostServices/SharedFolders/service.cpp +SRC_CC += HostServices/SharedFolders/mappings.cpp +SRC_CC += HostServices/SharedFolders/vbsf.cpp +SRC_CC += HostServices/SharedFolders/vbsfpath.cpp +SRC_CC += HostServices/SharedFolders/shflhandle.cpp + +SRC_CC += HostServices/SharedClipboard/service.cpp + +SRC_CC += frontend/dummy/errorinfo.cc frontend/dummy/virtualboxbase.cc +SRC_CC += frontend/dummy/autostart.cc frontend/dummy/rest.cc +SRC_CC += frontend/dummy/host.cc + +INC_DIR += $(VBOX_DIR)/Main/include +INC_DIR += $(VBOX_DIR)/VMM/include + +INC_DIR += $(REP_DIR)/src/virtualbox5/frontend +INC_DIR += $(VIRTUALBOX_DIR)/VBoxAPIWrap + +INC_DIR += $(VBOX_DIR)/Main/xml +INC_DIR += $(VBOX_DIR)/HostServices + +# search path to 'scan_code_set_2.h' +INC_DIR += $(call select_from_repositories,src/drivers/input/spec/ps2) diff --git a/repos/ports/src/virtualbox5/unimpl.cc b/repos/ports/src/virtualbox5/unimpl.cc new file mode 100644 index 0000000000..d7e7fd7f9f --- /dev/null +++ b/repos/ports/src/virtualbox5/unimpl.cc @@ -0,0 +1,215 @@ +/* + * \brief Dummy implementations of symbols needed by VirtualBox + * \author Norman Feske + * \date 2013-08-22 + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include + +#include + +extern "C" { + +#define DUMMY(name) \ +void name(void) { \ + Genode::warning(__func__, ": " #name " called, not implemented, eip=", \ + __builtin_return_address(0)); \ + while (1) { Assert(!"not implemented"); } \ +} + +DUMMY(DBGFR3CoreWrite) +DUMMY(DBGCRegisterCommands) +DUMMY(DBGFR3LogModifyDestinations) +DUMMY(DBGFR3LogModifyFlags) +DUMMY(DBGFR3LogModifyGroups) +DUMMY(DBGFR3OSDetect) +DUMMY(DBGFR3OSQueryNameAndVersion) +DUMMY(DBGFR3OSQueryInterface) +DUMMY(DBGFR3PlugInLoad) +DUMMY(DBGFR3PlugInLoadAll) +DUMMY(DBGFR3StackWalkBegin) +DUMMY(DBGFR3StackWalkBeginEx) +DUMMY(DBGFR3StackWalkNext) +DUMMY(DBGFR3StackWalkEnd) +DUMMY(DBGFR3PlugInUnload) +DUMMY(DBGFR3PlugInUnloadAll) + +DUMMY(HBDMgrDestroy) + +DUMMY(HMGetPaePdpes) +DUMMY(HMInvalidatePage) +DUMMY(HMInvalidatePageOnAllVCpus) +DUMMY(HMInvalidatePhysPage) +DUMMY(HMSetSingleInstruction) + +DUMMY(HMR3CheckError) +DUMMY(HMR3DisablePatching) +DUMMY(HMR3EnablePatching) +DUMMY(HMR3EmulateIoBlock) +DUMMY(HMR3IsEnabled) +DUMMY(HMR3IsNestedPagingActive) +DUMMY(HMR3IsUXActive) +DUMMY(HMR3IsVpidActive) +DUMMY(HMR3PatchTprInstr) + +DUMMY(MMHyperR0ToCC) +DUMMY(MMHyperRCToCC) + +DUMMY(MMR3HeapAPrintfV) +DUMMY(MMR3HyperRealloc) +DUMMY(MMR3LockCall) +DUMMY(MMR3PageDummyHCPhys) +DUMMY(MMR3UkHeapFree) + +DUMMY(PDMR3AsyncCompletionBwMgrSetMaxForFile) +DUMMY(PDMR3LdrGetInterfaceSymbols) +DUMMY(PDMR3LdrQueryRCModFromPC) +DUMMY(PDMCritSectBothFF) + +DUMMY(pgmMapActivateCR3) +DUMMY(pgmMapDeactivateCR3) +DUMMY(pgmMapResolveConflicts) +DUMMY(pgmR3SyncPTResolveConflict) +DUMMY(pgmR3SyncPTResolveConflictPAE) + +DUMMY(PGMR3HandlerVirtualRegister) + +DUMMY(DBGFR3PagingDumpEx) +DUMMY(MMPagePhys2PageEx) +DUMMY(PGMR3DbgR3Ptr2GCPhys) + +DUMMY(PGMR3MappingsUnfix) +DUMMY(PGMR3MappingsFix) +DUMMY(PGMR3MappingsDisable) +DUMMY(PGMR3MapPT) + +DUMMY(PGMR3SharedModuleCheckAll) +DUMMY(PGMR3SharedModuleUnregister) +DUMMY(PGMR3SharedModuleRegister) + +DUMMY(pgmR3MapInfo) + +DUMMY(RTTraceBufCarve) +DUMMY(RTTraceBufEnumEntries) +DUMMY(RTTraceBufGetEntryCount) +DUMMY(RTTraceBufGetEntrySize) + +DUMMY(RTPoll) +DUMMY(RTPollSetAdd) +DUMMY(RTPollSetCreate) +DUMMY(RTPollSetEventsChange) +DUMMY(RTPollSetRemove) +DUMMY(RTPollSetDestroy) + +DUMMY(RTProcCreate) +DUMMY(RTProcTerminate) +DUMMY(RTProcWait) +DUMMY(RTLdrGetSuff) +DUMMY(RTLdrLoadAppPriv) + +DUMMY(RTPathAppend) +DUMMY(RTPathChangeToDosSlashes) +DUMMY(RTSemEventWaitEx) +DUMMY(RTSemPing) +DUMMY(RTSemPingWait) + +DUMMY(RTMemDupExTag) +DUMMY(RTMemDupTag) +DUMMY(RTMemExecFree) + +DUMMY(SELMR3GetSelectorInfo) +DUMMY(SELMR3GetShadowSelectorInfo) + +DUMMY(SUPReadTscWithDelta) +DUMMY(SUPR3HardenedLdrLoadPlugIn) +DUMMY(SUPR3PageAlloc) +DUMMY(SUPR3PageFree) +DUMMY(SUPR3PageMapKernel) +DUMMY(SUPR3ReadTsc) +DUMMY(SUPGetCpuHzFromGipForAsyncMode) + +DUMMY(SUPSemEventMultiSignal) +DUMMY(SUPSemEventMultiWaitNoResume) +DUMMY(SUPSemEventMultiReset) + +DUMMY(VMMR3GetHostToGuestSwitcher) + +DUMMY(RTHeapSimpleRelocate) +DUMMY(RTHeapSimpleAlloc) +DUMMY(RTHeapSimpleInit) +DUMMY(RTHeapSimpleFree) +DUMMY(RTAvloU32Remove) +DUMMY(RTAvloU32Get) +DUMMY(RTAvloU32GetBestFit) +DUMMY(RTAvloU32DoWithAll) +DUMMY(RTAvloU32Insert) + +DUMMY(IOMInterpretOUT) +DUMMY(IOMInterpretOUTS) +DUMMY(IOMInterpretIN) +DUMMY(IOMInterpretINS) + +DUMMY(DISInstrToStrWithReader) +DUMMY(DISInstrToStrEx) + +DUMMY(RTFileQueryFsSizes) + +DUMMY(RTAvlrFileOffsetGet) +DUMMY(RTAvlrFileOffsetGetBestFit) +DUMMY(RTAvlrFileOffsetInsert) +DUMMY(RTAvlrFileOffsetRemove) +DUMMY(RTAvlrU64Destroy) +DUMMY(RTAvlrU64DoWithAll) +DUMMY(RTAvlrU64GetBestFit) +DUMMY(RTAvlrU64Insert) +DUMMY(RTAvlrU64RangeGet) +DUMMY(RTAvlrU64RangeRemove) +DUMMY(RTAvlrU64Remove) +DUMMY(RTSocketToNative) + +DUMMY(RTStrCat) +DUMMY(RTStrCatP) +DUMMY(RTStrStr) + +DUMMY(RTTcpClientCloseEx) +DUMMY(RTTcpClientConnectEx) +DUMMY(RTTcpFlush) +DUMMY(RTTcpGetLocalAddress) +DUMMY(RTTcpGetPeerAddress) +DUMMY(RTTcpRead) +DUMMY(RTTcpReadNB) +DUMMY(RTTcpSelectOne) +DUMMY(RTTcpSelectOneEx) +DUMMY(RTTcpSetSendCoalescing) +DUMMY(RTTcpSgWrite) +DUMMY(RTTcpSgWriteNB) +DUMMY(RTTcpWrite) +DUMMY(RTTcpWriteNB) +DUMMY(RTTimeLocalExplode) + +DUMMY(RTSymlinkCreate) +DUMMY(RTSymlinkRead) +DUMMY(RTSymlinkDelete) + +DUMMY(RTNetIPv6PseudoChecksumEx) + +DUMMY(pthread_mutex_timedlock) +DUMMY(pthread_kill) + +DUMMY(RTZipXarFsStreamFromIoStream) + +DUMMY(FTMR3CancelStandby) +DUMMY(FTMR3PowerOn) + +DUMMY(GIMReadMsr) +DUMMY(GIMR3Term) +DUMMY(GIMWriteMsr) + +} /* extern "C" */ diff --git a/repos/ports/src/virtualbox5/util.h b/repos/ports/src/virtualbox5/util.h new file mode 100644 index 0000000000..d2779c59ff --- /dev/null +++ b/repos/ports/src/virtualbox5/util.h @@ -0,0 +1,36 @@ +/* + * \brief VirtualBox utilities + * \author Christian Helmuth + * \date 2013-08-28 + */ + +/* + * Copyright (C) 2013-2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +/* VirtualBox includes */ +#include + + +/** + * 64bit-aware cast of pointer to RTRCPTR (uint32_t) + */ +template +RTRCPTR to_rtrcptr(T* ptr) +{ + unsigned long long u64 = reinterpret_cast(ptr); + RTRCPTR rtrcptr = u64 & 0xFFFFFFFFULL; + + AssertMsg((u64 == rtrcptr) || (u64 >> 32) == 0xFFFFFFFFULL, + ("pointer transformation - %llx != %x", u64, rtrcptr)); + + return rtrcptr; +} + +#endif /* _UTIL_H_ */ diff --git a/tool/autopilot.list b/tool/autopilot.list index e336fe9158..b1f07be5d5 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -48,6 +48,7 @@ rump_ext2 thread pthread vbox_auto_win7 +vbox_auto_win7_vbox5 vbox_auto_win7_share vbox_auto_win8 vbox_auto_win81_64