mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
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
This commit is contained in:
parent
4dbfbdb7c4
commit
57b90e8d75
12
repos/ports/lib/mk/spec/nova/virtualbox5-hwaccl.mk
Normal file
12
repos/ports/lib/mk/spec/nova/virtualbox5-hwaccl.mk
Normal file
@ -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/
|
10
repos/ports/lib/mk/virtualbox5-apiwrap.mk
Normal file
10
repos/ports/lib/mk/virtualbox5-apiwrap.mk
Normal file
@ -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)
|
37
repos/ports/lib/mk/virtualbox5-bios.mk
Normal file
37
repos/ports/lib/mk/virtualbox5-bios.mk
Normal file
@ -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)
|
104
repos/ports/lib/mk/virtualbox5-common.inc
Normal file
104
repos/ports/lib/mk/virtualbox5-common.inc
Normal file
@ -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 :
|
97
repos/ports/lib/mk/virtualbox5-devices.mk
Normal file
97
repos/ports/lib/mk/virtualbox5-devices.mk
Normal file
@ -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/<NL>/\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
|
19
repos/ports/lib/mk/virtualbox5-dis.mk
Normal file
19
repos/ports/lib/mk/virtualbox5-dis.mk
Normal file
@ -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
|
28
repos/ports/lib/mk/virtualbox5-drivers.mk
Normal file
28
repos/ports/lib/mk/virtualbox5-drivers.mk
Normal file
@ -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
|
8
repos/ports/lib/mk/virtualbox5-liblzf.mk
Normal file
8
repos/ports/lib/mk/virtualbox5-liblzf.mk
Normal file
@ -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)
|
95
repos/ports/lib/mk/virtualbox5-main.mk
Normal file
95
repos/ports/lib/mk/virtualbox5-main.mk
Normal file
@ -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)
|
29
repos/ports/lib/mk/virtualbox5-recompiler.mk
Normal file
29
repos/ports/lib/mk/virtualbox5-recompiler.mk
Normal file
@ -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
|
172
repos/ports/lib/mk/virtualbox5-runtime.mk
Normal file
172
repos/ports/lib/mk/virtualbox5-runtime.mk
Normal file
@ -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 $^ > $@
|
||||
|
17
repos/ports/lib/mk/virtualbox5-storage.mk
Normal file
17
repos/ports/lib/mk/virtualbox5-storage.mk
Normal file
@ -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
|
100
repos/ports/lib/mk/virtualbox5-vmm.mk
Normal file
100
repos/ports/lib/mk/virtualbox5-vmm.mk
Normal file
@ -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
|
23
repos/ports/lib/mk/virtualbox5-xml.mk
Normal file
23
repos/ports/lib/mk/virtualbox5-xml.mk
Normal file
@ -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)
|
7
repos/ports/lib/mk/virtualbox5-zlib.mk
Normal file
7
repos/ports/lib/mk/virtualbox5-zlib.mk
Normal file
@ -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)
|
1
repos/ports/ports/virtualbox5.hash
Normal file
1
repos/ports/ports/virtualbox5.hash
Normal file
@ -0,0 +1 @@
|
||||
14b453967da93f0915e476d45b80a8a400c37eb4
|
158
repos/ports/ports/virtualbox5.port
Normal file
158
repos/ports/ports/virtualbox5.port
Normal file
@ -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))"
|
@ -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
|
||||
|
@ -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
|
||||
|
21
repos/ports/run/vbox_auto_win7_vbox5.run
Normal file
21
repos/ports/run/vbox_auto_win7_vbox5.run
Normal file
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -148,8 +148,13 @@ append config_of_app {
|
||||
</provides>
|
||||
</start>
|
||||
|
||||
<start name="vbox" priority="-2">
|
||||
<binary name="virtualbox" />
|
||||
<start name="vbox" priority="-2">}
|
||||
append_if [expr $use_vbox4] config_of_app {
|
||||
<binary name="virtualbox" />}
|
||||
append_if [expr $use_vbox5] config_of_app {
|
||||
<binary name="virtualbox5" />}
|
||||
|
||||
append config_of_app {
|
||||
<resource name="RAM" quantum="1280M"/>}
|
||||
append config_of_app "
|
||||
<config ld_verbose=\"yes\" vbox_file=\"${vbox_file}\" vm_name=\"${flavor}\" xhci=\"yes\">"
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -26,6 +26,7 @@
|
||||
* Header Files *
|
||||
*******************************************************************************/
|
||||
#define LOG_GROUP LOG_GROUP_DRV_TUN
|
||||
#include <base/log.h>
|
||||
#include <VBox/log.h>
|
||||
#include <VBox/vmm/pdmdrv.h>
|
||||
#include <VBox/vmm/pdmnetifs.h>
|
||||
|
169
repos/ports/src/virtualbox5/dummies.cc
Normal file
169
repos/ports/src/virtualbox5/dummies.cc
Normal file
@ -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 <base/log.h>
|
||||
|
||||
#include <string.h> /* libc memcpy */
|
||||
|
||||
#include "VMMInternal.h"
|
||||
#include "EMInternal.h"
|
||||
#include "PDMInternal.h"
|
||||
|
||||
#include <iprt/err.h>
|
||||
#include <iprt/mem.h>
|
||||
#include <VBox/vmm/cpum.h>
|
||||
#include <VBox/vmm/mm.h>
|
||||
#include <VBox/vmm/dbgf.h>
|
||||
#include <VBox/vmm/ftm.h>
|
||||
#include <VBox/vmm/selm.h>
|
||||
#include <VBox/vmm/hm.h>
|
||||
#include <VBox/vmm/iom.h>
|
||||
|
||||
#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<RTR3PTR>(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<char *>(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
|
14
repos/ports/src/virtualbox5/frontend/ClientWatcher.h
Normal file
14
repos/ports/src/virtualbox5/frontend/ClientWatcher.h
Normal file
@ -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 */
|
10
repos/ports/src/virtualbox5/frontend/GenodeImpl.h
Normal file
10
repos/ports/src/virtualbox5/frontend/GenodeImpl.h
Normal file
@ -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
|
51
repos/ports/src/virtualbox5/frontend/VBoxEvents.h
Normal file
51
repos/ports/src/virtualbox5/frontend/VBoxEvents.h
Normal file
@ -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)
|
468
repos/ports/src/virtualbox5/frontend/VirtualBoxBase.h
Normal file
468
repos/ports/src/virtualbox5/frontend/VirtualBoxBase.h
Normal file
@ -0,0 +1,468 @@
|
||||
#ifndef ____H_VIRTUALBOXBASEIMPL
|
||||
#define ____H_VIRTUALBOXBASEIMPL
|
||||
|
||||
#include <base/log.h>
|
||||
|
||||
#include <iprt/cdefs.h>
|
||||
#include <iprt/thread.h>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#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<ComObjPtr<Medium> > MediaList;
|
||||
typedef std::list<Utf8Str> 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 <typename T>
|
||||
class Shareable
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
bool _verbose;
|
||||
T * _obj;
|
||||
|
||||
public:
|
||||
|
||||
Shareable<T> () : _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 <typename T>
|
||||
class Backupable : public Shareable<T>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Backupable() : Shareable<T>() { }
|
||||
|
||||
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
|
@ -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)
|
@ -0,0 +1,49 @@
|
||||
#ifndef ____H_VIRTUALBOXERRORINFO
|
||||
#define ____H_VIRTUALBOXERRORINFO
|
||||
|
||||
#include <VirtualBoxBase.h>
|
||||
|
||||
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 */
|
520
repos/ports/src/virtualbox5/frontend/console.cc
Normal file
520
repos/ports/src/virtualbox5/frontend/console.cc
Normal file
@ -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 <base/log.h>
|
||||
#include <util/xml_node.h>
|
||||
|
||||
#include <VBox/settings.h>
|
||||
#include <SharedClipboard/VBoxClipboard.h>
|
||||
#include <VBox/HostServices/VBoxClipboardSvc.h>
|
||||
|
||||
#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<IProgress> &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<GenodeConsole *>(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<Genodefb *>(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<Genodefb *>(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<Genodefb *>(pFramebuffer);
|
||||
|
||||
fb->mode_sigh(_mode_change_signal_dispatcher);
|
||||
|
||||
for (;;) {
|
||||
|
||||
Genode::Signal sig = _receiver.wait_for_signal();
|
||||
Genode::Signal_dispatcher_base *dispatcher =
|
||||
dynamic_cast<Genode::Signal_dispatcher_base *>(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<char>();
|
||||
|
||||
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<PRTUTF16>(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<PCRTUTF16>(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;
|
||||
}
|
234
repos/ports/src/virtualbox5/frontend/console.h
Normal file
234
repos/ports/src/virtualbox5/frontend/console.h
Normal file
@ -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 <base/log.h>
|
||||
#include <input/event.h>
|
||||
#include <input/keycodes.h>
|
||||
#include <input_session/connection.h>
|
||||
#include <os/attached_dataspace.h>
|
||||
#include <os/attached_rom_dataspace.h>
|
||||
#include <os/reporter.h>
|
||||
#include <report_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* included from os/src/drivers/input/spec/ps2 */
|
||||
#include <scan_code_set_1.h>
|
||||
|
||||
/* repos/ports includes */
|
||||
#include <vbox_pointer/shape_report.h>
|
||||
|
||||
/* 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<GenodeConsole> _input_signal_dispatcher;
|
||||
Genode::Signal_dispatcher<GenodeConsole> _mode_change_signal_dispatcher;
|
||||
Genode::Signal_dispatcher<GenodeConsole> _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<Input::Event *>(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<Vbox_pointer::Shape_report>()),
|
||||
_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);
|
||||
};
|
17
repos/ports/src/virtualbox5/frontend/dummy/autostart.cc
Normal file
17
repos/ports/src/virtualbox5/frontend/dummy/autostart.cc
Normal file
@ -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)
|
14
repos/ports/src/virtualbox5/frontend/dummy/errorinfo.cc
Normal file
14
repos/ports/src/virtualbox5/frontend/dummy/errorinfo.cc
Normal file
@ -0,0 +1,14 @@
|
||||
#include "VirtualBoxBase.h"
|
||||
|
||||
#include "dummy/macros.h"
|
||||
|
||||
#include <VBox/com/ErrorInfo.h>
|
||||
|
||||
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()
|
191
repos/ports/src/virtualbox5/frontend/dummy/host.cc
Normal file
191
repos/ports/src/virtualbox5/frontend/dummy/host.cc
Normal file
@ -0,0 +1,191 @@
|
||||
#include "VirtualBoxBase.h"
|
||||
|
||||
#include <VBox/usbfilter.h>
|
||||
|
||||
#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<Medium> &pMedium)
|
||||
DUMMY(E_FAIL)
|
||||
|
||||
HRESULT Host::i_findHostDriveById(DeviceType_T, com::Guid const&, bool,
|
||||
ComObjPtr<Medium>&)
|
||||
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<IHostNetworkInterface> &,
|
||||
ComPtr<IProgress> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::removeHostOnlyNetworkInterface(const com::Guid &,
|
||||
ComPtr<IProgress> &)
|
||||
DUMMY(E_FAIL)
|
||||
|
||||
|
||||
HRESULT Host::createUSBDeviceFilter(const com::Utf8Str &,
|
||||
ComPtr<IHostUSBDeviceFilter> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::insertUSBDeviceFilter(ULONG, const ComPtr<IHostUSBDeviceFilter> &)
|
||||
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<ComPtr<IMedium> > &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getFloppyDrives(std::vector<ComPtr<IMedium> > &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getMemorySize(ULONG *)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getMemoryAvailable(ULONG *)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getNameServers(std::vector<com::Utf8Str> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getNetworkInterfaces(std::vector<ComPtr<IHostNetworkInterface> > &)
|
||||
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<com::Utf8Str> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getUTCTime(LONG64 *)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getUSBDevices(std::vector<ComPtr<IHostUSBDevice> > &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getUSBDeviceFilters(std::vector<ComPtr<IHostUSBDeviceFilter> > &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::getVideoInputDevices(std::vector<ComPtr<IHostVideoInputDevice> > &)
|
||||
DUMMY(E_FAIL)
|
||||
|
||||
|
||||
HRESULT Host::findHostDVDDrive(const com::Utf8Str &, ComPtr<IMedium> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::findHostFloppyDrive(const com::Utf8Str &aName, ComPtr<IMedium> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::findHostNetworkInterfaceByName(const com::Utf8Str &,
|
||||
ComPtr<IHostNetworkInterface> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::findHostNetworkInterfaceById(const com::Guid &,
|
||||
ComPtr<IHostNetworkInterface> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::findHostNetworkInterfacesOfType(HostNetworkInterfaceType_T,
|
||||
std::vector<ComPtr<IHostNetworkInterface> > &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::findUSBDeviceByAddress(const com::Utf8Str &,
|
||||
ComPtr<IHostUSBDevice> &)
|
||||
DUMMY(E_FAIL)
|
||||
HRESULT Host::findUSBDeviceById(const com::Guid &, ComPtr<IHostUSBDevice> &)
|
||||
DUMMY(E_FAIL)
|
37
repos/ports/src/virtualbox5/frontend/dummy/macros.h
Normal file
37
repos/ports/src/virtualbox5/frontend/dummy/macros.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef ____H_MACROS
|
||||
#define ____H_MACROS
|
||||
|
||||
#include <base/log.h>
|
||||
|
||||
#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 */
|
127
repos/ports/src/virtualbox5/frontend/dummy/rest.cc
Normal file
127
repos/ports/src/virtualbox5/frontend/dummy/rest.cc
Normal file
@ -0,0 +1,127 @@
|
||||
#include "dummy/macros.h"
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
|
||||
/* ApplianceImplExport.cpp */
|
||||
|
||||
#include "MachineImpl.h"
|
||||
|
||||
HRESULT Machine::exportTo(const ComPtr<IAppliance> &aAppliance,
|
||||
const com::Utf8Str &aLocation,
|
||||
ComPtr<IVirtualSystemDescription> &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)
|
38
repos/ports/src/virtualbox5/frontend/dummy/virtualboxbase.cc
Normal file
38
repos/ports/src/virtualbox5/frontend/dummy/virtualboxbase.cc
Normal file
@ -0,0 +1,38 @@
|
||||
#include <base/log.h>
|
||||
|
||||
#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<IAppliance> &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()
|
225
repos/ports/src/virtualbox5/frontend/fb.h
Normal file
225
repos/ports/src/virtualbox5/frontend/fb.h
Normal file
@ -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 <framebuffer_session/connection.h>
|
||||
#include <nitpicker_session/nitpicker_session.h>
|
||||
#undef Framebuffer
|
||||
|
||||
#include <os/texture_rgb565.h>
|
||||
#include <os/texture_rgb888.h>
|
||||
#include <os/dither_painter.h>
|
||||
|
||||
/* 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<FramebufferCapabilities_T> 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<Pixel_src> texture((Pixel_src *)image, nullptr, area_vm);
|
||||
Surface<Pixel_dst> 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; }
|
||||
};
|
256
repos/ports/src/virtualbox5/frontend/main.cc
Normal file
256
repos/ports/src/virtualbox5/frontend/main.cc
Normal file
@ -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 <base/log.h>
|
||||
#include <os/config.h>
|
||||
|
||||
/* Virtualbox includes */
|
||||
#include <iprt/initterm.h>
|
||||
#include <iprt/assert.h>
|
||||
#include <iprt/err.h>
|
||||
#include <VBox/com/com.h>
|
||||
#include <VBox/vmm/vmapi.h>
|
||||
|
||||
/* 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<char *>(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> machine;
|
||||
rc = machine.createObject();
|
||||
if (FAILED(rc))
|
||||
return rc;
|
||||
|
||||
/* Virtualbox object */
|
||||
ComObjPtr<VirtualBox> 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> 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<IConsole> gConsole;
|
||||
rc = session->COMGETTER(Console)(gConsole.asOutParam());
|
||||
|
||||
/* handle input of Genode and forward it to VMM layer */
|
||||
ComPtr<GenodeConsole> genodeConsole = gConsole;
|
||||
RTLogPrintf("genodeConsole = %p\n", genodeConsole);
|
||||
|
||||
genodeConsole->init_clipboard();
|
||||
|
||||
/* Display object */
|
||||
ComPtr<IDisplay> 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 <IProgress> 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<IMouse> gMouse;
|
||||
rc = gConsole->COMGETTER(Mouse)(gMouse.asOutParam());
|
||||
if (FAILED(rc))
|
||||
return rc;
|
||||
Assert (&*gMouse);
|
||||
|
||||
/* request keyboard object */
|
||||
ComPtr<IKeyboard> 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(" <config vbox_file=\"...\" vm_name=\"...\">" );
|
||||
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;
|
||||
}
|
208
repos/ports/src/virtualbox5/hm.cc
Normal file
208
repos/ports/src/virtualbox5/hm.cc
Normal file
@ -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 <base/log.h>
|
||||
|
||||
/* VirtualBox includes */
|
||||
#include "HMInternal.h" /* enable access to hm.s.* */
|
||||
#include <VBox/vmm/hm.h>
|
||||
#include <VBox/vmm/vm.h>
|
||||
|
||||
/* 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; }
|
474
repos/ports/src/virtualbox5/mm.cc
Normal file
474
repos/ports/src/virtualbox5/mm.cc
Normal file
@ -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 <base/log.h>
|
||||
#include <util/string.h>
|
||||
#include <rm_session/connection.h>
|
||||
|
||||
#include <os/attached_ram_dataspace.h>
|
||||
|
||||
/* VirtualBox includes */
|
||||
#include <VBox/vmm/mm.h>
|
||||
#include <VBox/vmm/cfgm.h>
|
||||
#include <VBox/err.h>
|
||||
#include <VBox/vmm/gmm.h>
|
||||
#include <VBox/vmm/vm.h>
|
||||
#include <VBox/vmm/pgm.h>
|
||||
#include <iprt/err.h>
|
||||
#include <iprt/mem.h>
|
||||
#include <iprt/string.h>
|
||||
|
||||
/* libc memory allocator */
|
||||
#include <libc_mem_alloc.h>
|
||||
|
||||
#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<char *>(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<void>();
|
||||
}
|
||||
|
||||
|
||||
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<void *>(ptr);
|
||||
}
|
||||
|
||||
return reinterpret_cast<void *>(offHeap);
|
||||
}
|
||||
|
||||
|
||||
VMMDECL(uint32_t) MMHyperHeapPtrToOffset(PVM pVM, void *pv)
|
||||
{
|
||||
Genode::addr_t offset = reinterpret_cast<Genode::addr_t>(pv);
|
||||
|
||||
Assert (reinterpret_cast<void *>(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;
|
||||
}
|
||||
|
||||
}
|
79
repos/ports/src/virtualbox5/mm.h
Normal file
79
repos/ports/src/virtualbox5/mm.h
Normal file
@ -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 <rm_session/rm_session.h>
|
||||
#include <rm_session/connection.h>
|
||||
#include <region_map/client.h>
|
||||
|
||||
#include <util/retry.h>
|
||||
|
||||
/**
|
||||
* 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<Rm_session::Out_of_metadata>(
|
||||
[&] () {
|
||||
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<Genode::addr_t>(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; }
|
||||
};
|
51
repos/ports/src/virtualbox5/patches/dbg.patch
Normal file
51
repos/ports/src/virtualbox5/patches/dbg.patch
Normal file
@ -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
|
||||
}
|
||||
|
||||
|
137
repos/ports/src/virtualbox5/patches/iem_wip.patch
Normal file
137
repos/ports/src/virtualbox5/patches/iem_wip.patch
Normal file
@ -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 <base/log.h>
|
||||
+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)
|
9
repos/ports/src/virtualbox5/patches/series
Normal file
9
repos/ports/src/virtualbox5/patches/series
Normal file
@ -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
|
35
repos/ports/src/virtualbox5/patches/tm_smp.patch
Normal file
35
repos/ports/src/virtualbox5/patches/tm_smp.patch
Normal file
@ -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
|
118
repos/ports/src/virtualbox5/patches/usb.patch
Normal file
118
repos/ports/src/virtualbox5/patches/usb.patch
Normal file
@ -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);
|
47
repos/ports/src/virtualbox5/patches/vbox_inc.patch
Normal file
47
repos/ports/src/virtualbox5/patches/vbox_inc.patch
Normal file
@ -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;
|
1079
repos/ports/src/virtualbox5/patches/vbox_main.patch
Normal file
1079
repos/ports/src/virtualbox5/patches/vbox_main.patch
Normal file
File diff suppressed because it is too large
Load Diff
16
repos/ports/src/virtualbox5/patches/vga_vbva.patch
Normal file
16
repos/ports/src/virtualbox5/patches/vga_vbva.patch
Normal file
@ -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;
|
||||
}
|
||||
|
17
repos/ports/src/virtualbox5/patches/vmm.patch
Normal file
17
repos/ports/src/virtualbox5/patches/vmm.patch
Normal file
@ -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;
|
46
repos/ports/src/virtualbox5/patches/vmmdev.patch
Normal file
46
repos/ports/src/virtualbox5/patches/vmmdev.patch
Normal file
@ -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 <iprt/alloc.h>
|
||||
#include <iprt/asm.h>
|
||||
#include <iprt/assert.h>
|
58
repos/ports/src/virtualbox5/pgm.cc
Normal file
58
repos/ports/src/virtualbox5/pgm.cc
Normal file
@ -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 <base/log.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* VirtualBox includes */
|
||||
#include <VBox/vmm/pgm.h>
|
||||
|
||||
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;
|
||||
}
|
209
repos/ports/src/virtualbox5/spec/nova/pgm.cc
Normal file
209
repos/ports/src/virtualbox5/spec/nova/pgm.cc
Normal file
@ -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<Genode::uint64_t*>(PGM_PAGE_GET_HCPHYS(pPage) + (cr3 & PAGE_OFFSET_MASK));
|
||||
|
||||
Assert(pdpte != 0);
|
||||
|
||||
return pdpte;
|
||||
}
|
570
repos/ports/src/virtualbox5/spec/nova/sup.cc
Normal file
570
repos/ports/src/virtualbox5/spec/nova/sup.cc
Normal file
@ -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 <base/log.h>
|
||||
#include <base/semaphore.h>
|
||||
#include <util/flex_iterator.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/attached_rom_dataspace.h>
|
||||
#include <os/attached_ram_dataspace.h>
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
#include <vmm/vcpu_thread.h>
|
||||
#include <vmm/vcpu_dispatcher.h>
|
||||
|
||||
/* NOVA includes that come with Genode */
|
||||
#include <nova/syscalls.h>
|
||||
|
||||
/* Genode's VirtualBox includes */
|
||||
#include "vcpu.h"
|
||||
#include "vcpu_svm.h"
|
||||
#include "vcpu_vmx.h"
|
||||
|
||||
/* libc memory allocator */
|
||||
#include <libc_mem_alloc.h>
|
||||
|
||||
#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> &vcpu_handler_list()
|
||||
{
|
||||
static Genode::List<Vcpu_handler> _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<Nova::Hip>();
|
||||
|
||||
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<void>();
|
||||
|
||||
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<RTHCPHYS>(ds->local_addr<void>()) + 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<VM *>(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<PGMMALLOCATEPAGESREQ>(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<PGMMMAPUNMAPCHUNKREQ>(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<RTR3PTR>(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<PGMMMEMSTATSREQ>(pReqHdr);
|
||||
req->cAllocPages = 0;
|
||||
req->cMaxPages = 0;
|
||||
req->cBalloonedPages = 0;
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
case VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES:
|
||||
{
|
||||
PVM pVM = reinterpret_cast<PVM>(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<PVM>(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<PVM>(pVMR0);
|
||||
PGMMFREEPAGESREQ pReq = reinterpret_cast<PGMMFREEPAGESREQ>(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<void *>(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<addr_t>(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<Nova::Hip>();
|
||||
|
||||
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<unsigned long>(vcpu_handler) & 0xf));
|
||||
|
||||
vcpu_handler_list().insert(vcpu_handler);
|
||||
|
||||
*pthread = vcpu_handler;
|
||||
return true;
|
||||
}
|
112
repos/ports/src/virtualbox5/spec/nova/svm.h
Normal file
112
repos/ports/src/virtualbox5/spec/nova/svm.h
Normal file
@ -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_ */
|
868
repos/ports/src/virtualbox5/spec/nova/vcpu.h
Normal file
868
repos/ports/src/virtualbox5/spec/nova/vcpu.h
Normal file
@ -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 <base/log.h>
|
||||
#include <base/semaphore.h>
|
||||
#include <util/flex_iterator.h>
|
||||
#include <util/touch.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
#include <vmm/vcpu_thread.h>
|
||||
#include <vmm/vcpu_dispatcher.h>
|
||||
#include <vmm/printf.h>
|
||||
|
||||
/* NOVA includes that come with Genode */
|
||||
#include <nova/syscalls.h>
|
||||
|
||||
/* 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 <VBox/vmm/vm.h>
|
||||
#include <VBox/vmm/hm_svm.h>
|
||||
#include <VBox/err.h>
|
||||
|
||||
#include <VBox/vmm/pdmapi.h>
|
||||
|
||||
/* Genode's VirtualBox includes */
|
||||
#include "sup.h"
|
||||
|
||||
/* Genode libc pthread binding */
|
||||
#include "thread.h"
|
||||
|
||||
/* LibC includes */
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <VBox/vmm/rem.h>
|
||||
|
||||
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<pthread>,
|
||||
public Genode::List<Vcpu_handler>::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<Genode::addr_t>(data) & 0xF));
|
||||
asm volatile ("fxsave %0" : "=m" (*data));
|
||||
}
|
||||
|
||||
void fpu_load(char * data) {
|
||||
Assert(!(reinterpret_cast<Genode::addr_t>(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<char *>(&_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<void *>(&value - 1);
|
||||
Nova::reply(_stack_reply);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void _default_handler()
|
||||
{
|
||||
Nova::Utcb * utcb = reinterpret_cast<Nova::Utcb *>(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<Nova::Utcb *>(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 <unsigned NPT_EPT>
|
||||
__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<unsigned char *>(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 <unsigned EV, void (Vcpu_handler::*FUNC)()>
|
||||
void _register_handler(Genode::addr_t exc_base, Nova::Mtd mtd)
|
||||
{
|
||||
if (!register_handler<EV, Vcpu_handler, FUNC>(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<Nova::Utcb *>(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<pthread>(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<VM *>(pVMR0);
|
||||
PVMCPU pVCpu = &pVM->aCpus[_cpu_id];
|
||||
PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
|
||||
|
||||
Nova::Utcb *utcb = reinterpret_cast<Nova::Utcb *>(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<char *>(&_emt_fpu_state));
|
||||
/* write FPU state from pCtx to FPU registers */
|
||||
fpu_load(reinterpret_cast<char *>(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<char *>(&_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_ */
|
141
repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h
Normal file
141
repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h
Normal file
@ -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<Utcb *>(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 <unsigned X>
|
||||
__attribute__((noreturn)) void _svm_npt()
|
||||
{
|
||||
using namespace Nova;
|
||||
using namespace Genode;
|
||||
|
||||
Thread *myself = Thread::myself();
|
||||
Utcb *utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
||||
|
||||
_exc_memory<X>(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<RECALL, This,
|
||||
&This::_svm_recall> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<SVM_EXIT_IOIO, This,
|
||||
&This::_svm_ioio> (exc_base, Mtd(Mtd::ALL | Mtd::FPU));
|
||||
register_handler<SVM_EXIT_VINTR, This,
|
||||
&This::_svm_vintr> (exc_base, Mtd(Mtd::ALL | Mtd::FPU));
|
||||
register_handler<SVM_EXIT_RDTSC, This,
|
||||
&This::_svm_default> (exc_base, Mtd(Mtd::ALL | Mtd::FPU));
|
||||
register_handler<SVM_EXIT_MSR, This,
|
||||
&This::_svm_default> (exc_base, Mtd(Mtd::ALL | Mtd::FPU));
|
||||
register_handler<SVM_NPT, This,
|
||||
&This::_svm_npt<SVM_NPT>> (exc_base, Mtd(Mtd::ALL | Mtd::FPU));
|
||||
register_handler<SVM_EXIT_HLT, This,
|
||||
&This::_svm_default> (exc_base, Mtd(Mtd::ALL | Mtd::FPU));
|
||||
register_handler<SVM_EXIT_CPUID, This,
|
||||
&This::_svm_default> (exc_base, Mtd(Mtd::ALL | Mtd::FPU));
|
||||
register_handler<VCPU_STARTUP, This,
|
||||
&This::_svm_startup> (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_ */
|
274
repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h
Normal file
274
repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h
Normal file
@ -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 <stdlib.h>
|
||||
|
||||
/* VirtualBox includes */
|
||||
#include <VBox/vmm/hm_vmx.h>
|
||||
|
||||
/* Genode's VirtualBox includes */
|
||||
#include "vcpu.h"
|
||||
#include "vmx.h"
|
||||
|
||||
|
||||
class Vcpu_handler_vmx : public Vcpu_handler
|
||||
{
|
||||
private:
|
||||
|
||||
template <unsigned X>
|
||||
__attribute__((noreturn)) void _vmx_ept()
|
||||
{
|
||||
using namespace Nova;
|
||||
using namespace Genode;
|
||||
|
||||
Thread *myself = Thread::myself();
|
||||
Utcb *utcb = reinterpret_cast<Utcb *>(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<X>(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<Utcb *>(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<Nova::Utcb *>(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<void *>(&value - 1);
|
||||
|
||||
Genode::Thread *myself = Genode::Thread::myself();
|
||||
Nova::Utcb *utcb = reinterpret_cast<Nova::Utcb *>(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<VMX_EXIT_TRIPLE_FAULT, This,
|
||||
&This::_vmx_triple> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_INIT_SIGNAL, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_INT_WINDOW, This,
|
||||
&This::_vmx_irqwin> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_TASK_SWITCH, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_CPUID, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_HLT, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
|
||||
/* we don't support tsc offsetting for now - so let the rdtsc exit */
|
||||
register_handler<VMX_EXIT_RDTSC, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
|
||||
register_handler<VMX_EXIT_VMCALL, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_IO_INSTR, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_RDMSR, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_WRMSR, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_ERR_INVALID_GUEST_STATE, This,
|
||||
&This::_vmx_invalid> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
// register_handler<VMX_EXIT_PAUSE, This,
|
||||
// &This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_WBINVD, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_MOV_CRX, This,
|
||||
&This::_vmx_mov_crx> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_MOV_DRX, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_TPR_BELOW_THRESHOLD, This,
|
||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VMX_EXIT_EPT_VIOLATION, This,
|
||||
&This::_vmx_ept<VMX_EXIT_EPT_VIOLATION>> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<VCPU_STARTUP, This,
|
||||
&This::_vmx_startup> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||
register_handler<RECALL, This,
|
||||
&This::_vmx_recall> (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_ */
|
129
repos/ports/src/virtualbox5/spec/nova/vmx.h
Normal file
129
repos/ports/src/virtualbox5/spec/nova/vmx.h
Normal file
@ -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_ */
|
332
repos/ports/src/virtualbox5/sup.cc
Normal file
332
repos/ports/src/virtualbox5/sup.cc
Normal file
@ -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 <os/attached_ram_dataspace.h>
|
||||
#include <base/semaphore.h>
|
||||
#include <os/timed_semaphore.h>
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
/* Genode/Virtualbox includes */
|
||||
#include "sup.h"
|
||||
|
||||
/* VirtualBox includes */
|
||||
#include <iprt/semaphore.h>
|
||||
#include <iprt/ldr.h>
|
||||
#include <iprt/uint128.h>
|
||||
#include <VBox/err.h>
|
||||
|
||||
/* libc memory allocator */
|
||||
#include <libc_mem_alloc.h>
|
||||
|
||||
|
||||
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<SUPGLOBALINFOPAGE>();
|
||||
|
||||
/* 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<Genode::Semaphore *>(hEvent);
|
||||
return VINF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent)
|
||||
{
|
||||
if (hEvent)
|
||||
reinterpret_cast<Genode::Semaphore *>(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<Genode::Semaphore *>(hEvent)->down();
|
||||
else {
|
||||
Genode::error(__FUNCTION__, " called millis=", cMillies,
|
||||
" - not implemented");
|
||||
reinterpret_cast<Genode::Semaphore *>(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<SUPSEMEVENTMULTI>(sem);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION, SUPSEMEVENTMULTI hEvMulti)
|
||||
{
|
||||
return RTSemEventMultiDestroy(reinterpret_cast<RTSEMEVENTMULTI>(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<GVMMCREATEVMREQ &>(*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<PVM>(pVMR0);
|
||||
pVM->aCpus[idCpu].hNativeThreadR0 = RTThreadNativeSelf();
|
||||
}
|
45
repos/ports/src/virtualbox5/sup.h
Normal file
45
repos/ports/src/virtualbox5/sup.h
Normal file
@ -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 <cpu_session/cpu_session.h>
|
||||
|
||||
/* VirtualBox includes */
|
||||
#include <VBox/vmm/vm.h>
|
||||
#include <VBox/vmm/gvmm.h>
|
||||
#include <iprt/param.h>
|
||||
|
||||
/**
|
||||
* 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_ */
|
68
repos/ports/src/virtualbox5/target.mk
Normal file
68
repos/ports/src/virtualbox5/target.mk
Normal file
@ -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)
|
215
repos/ports/src/virtualbox5/unimpl.cc
Normal file
215
repos/ports/src/virtualbox5/unimpl.cc
Normal file
@ -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 <base/log.h>
|
||||
|
||||
#include <iprt/assert.h>
|
||||
|
||||
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" */
|
36
repos/ports/src/virtualbox5/util.h
Normal file
36
repos/ports/src/virtualbox5/util.h
Normal file
@ -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 <iprt/types.h>
|
||||
|
||||
|
||||
/**
|
||||
* 64bit-aware cast of pointer to RTRCPTR (uint32_t)
|
||||
*/
|
||||
template <typename T>
|
||||
RTRCPTR to_rtrcptr(T* ptr)
|
||||
{
|
||||
unsigned long long u64 = reinterpret_cast<unsigned long long>(ptr);
|
||||
RTRCPTR rtrcptr = u64 & 0xFFFFFFFFULL;
|
||||
|
||||
AssertMsg((u64 == rtrcptr) || (u64 >> 32) == 0xFFFFFFFFULL,
|
||||
("pointer transformation - %llx != %x", u64, rtrcptr));
|
||||
|
||||
return rtrcptr;
|
||||
}
|
||||
|
||||
#endif /* _UTIL_H_ */
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user