mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-23 04:48:17 +00:00
parent
ecc98c293e
commit
800f9d1e44
@ -70,6 +70,8 @@ SRC_CC += Devices/build/VBoxDD.cpp
|
|||||||
SRC_CC += GuestHost/HGSMI/HGSMICommon.cpp
|
SRC_CC += GuestHost/HGSMI/HGSMICommon.cpp
|
||||||
SRC_CC += GuestHost/HGSMI/HGSMIMemAlloc.cpp
|
SRC_CC += GuestHost/HGSMI/HGSMIMemAlloc.cpp
|
||||||
|
|
||||||
|
SRC_CC += devxhci.cc
|
||||||
|
|
||||||
INC_DIR += $(VBOX_DIR)/Devices/build
|
INC_DIR += $(VBOX_DIR)/Devices/build
|
||||||
INC_DIR += $(VBOX_DIR)/Devices/Bus
|
INC_DIR += $(VBOX_DIR)/Devices/Bus
|
||||||
|
|
||||||
@ -108,4 +110,4 @@ vboxssdt-cpuhotplug.hex: vbox-cpuhotplug.dsl
|
|||||||
rm $@.tmp $@.pre $@.pre1
|
rm $@.tmp $@.pre $@.pre1
|
||||||
|
|
||||||
vpath %.dsl $(VBOX_DIR)/Devices/PC
|
vpath %.dsl $(VBOX_DIR)/Devices/PC
|
||||||
vpath %.cc $(REP_DIR)/src/virtualbox
|
vpath devxhci.cc $(REP_DIR)/src/virtualbox5
|
||||||
|
@ -1 +1 @@
|
|||||||
94dea6e6f2eba1626d6c6f96933a121d6ae8a30b
|
7e47c93bea1d7b2a3b69817994b7d3d0a5f0a460
|
||||||
|
24
repos/ports/run/vbox5_win7_64.run
Normal file
24
repos/ports/run/vbox5_win7_64.run
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#
|
||||||
|
# Windows 7 64bit in VirtualBox
|
||||||
|
#
|
||||||
|
|
||||||
|
assert_spec 64bit
|
||||||
|
|
||||||
|
set flavor "win7_64"
|
||||||
|
|
||||||
|
set use_vbox4 0
|
||||||
|
set use_vbox5 1
|
||||||
|
|
||||||
|
set use_rumpfs 1
|
||||||
|
# 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]
|
||||||
|
|
||||||
|
set use_vms 1
|
||||||
|
set use_cpu_load 0
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/ports/run/vbox_win.inc
|
@ -127,7 +127,7 @@ append config_of_app {
|
|||||||
</start>
|
</start>
|
||||||
|
|
||||||
<start name="nitpicker" priority="-1">
|
<start name="nitpicker" priority="-1">
|
||||||
<resource name="RAM" quantum="4M"/>
|
<resource name="RAM" quantum="12M"/>
|
||||||
<provides><service name="Nitpicker"/></provides>
|
<provides><service name="Nitpicker"/></provides>
|
||||||
<route>
|
<route>
|
||||||
<service name="Framebuffer"> <child name="fb_drv" /> </service>
|
<service name="Framebuffer"> <child name="fb_drv" /> </service>
|
||||||
|
@ -53,7 +53,9 @@
|
|||||||
<PXEDebug enabled="false"/>
|
<PXEDebug enabled="false"/>
|
||||||
</BIOS>
|
</BIOS>
|
||||||
<USB>
|
<USB>
|
||||||
<Controllers/>
|
<Controllers>
|
||||||
|
<Controller name="OHCI" type="OHCI"/>
|
||||||
|
</Controllers>
|
||||||
<DeviceFilters/>
|
<DeviceFilters/>
|
||||||
</USB>
|
</USB>
|
||||||
<Network>
|
<Network>
|
||||||
|
@ -53,7 +53,9 @@
|
|||||||
<PXEDebug enabled="false"/>
|
<PXEDebug enabled="false"/>
|
||||||
</BIOS>
|
</BIOS>
|
||||||
<USB>
|
<USB>
|
||||||
<Controllers/>
|
<Controllers>
|
||||||
|
<Controller name="OHCI" type="OHCI"/>
|
||||||
|
</Controllers>
|
||||||
<DeviceFilters/>
|
<DeviceFilters/>
|
||||||
</USB>
|
</USB>
|
||||||
<Network>
|
<Network>
|
||||||
|
@ -608,7 +608,8 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>,
|
|||||||
|
|
||||||
if (!TRPMHasTrap(pVCpu)) {
|
if (!TRPMHasTrap(pVCpu)) {
|
||||||
bool res = VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI);
|
bool res = VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI);
|
||||||
Assert(!res);
|
if (res)
|
||||||
|
Vmm::log("NMI was set");
|
||||||
|
|
||||||
if (VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC |
|
if (VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC |
|
||||||
VMCPU_FF_INTERRUPT_PIC))) {
|
VMCPU_FF_INTERRUPT_PIC))) {
|
||||||
|
@ -68,6 +68,8 @@ extern "C" int VBoxDevicesRegister(PPDMDEVREGCB pCallbacks, uint32_t u32Version)
|
|||||||
REGISTER(DevicePciIch9Bridge);
|
REGISTER(DevicePciIch9Bridge);
|
||||||
REGISTER(DeviceLPC);
|
REGISTER(DeviceLPC);
|
||||||
|
|
||||||
|
REGISTER(DeviceXHCI);
|
||||||
|
|
||||||
return VINF_SUCCESS;
|
return VINF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
593
repos/ports/src/virtualbox5/devxhci.cc
Normal file
593
repos/ports/src/virtualbox5/devxhci.cc
Normal file
@ -0,0 +1,593 @@
|
|||||||
|
/*
|
||||||
|
* \brief NEC XHCI device frontend
|
||||||
|
* \author Josef Soentgen
|
||||||
|
* \author Sebastian Sumpf
|
||||||
|
* \date 2015-12-10
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2017 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/attached_rom_dataspace.h>
|
||||||
|
#include <util/list.h>
|
||||||
|
|
||||||
|
/* qemu-usb includes */
|
||||||
|
#include <qemu/usb.h>
|
||||||
|
|
||||||
|
/* Virtualbox includes */
|
||||||
|
#define LOG_GROUP LOG_GROUP_DEV_EHCI
|
||||||
|
#include <VBox/pci.h>
|
||||||
|
#include <VBox/vmm/pdm.h>
|
||||||
|
#include <VBox/vmm/pgm.h>
|
||||||
|
#include <VBox/vmm/mm.h>
|
||||||
|
#include <VBox/err.h>
|
||||||
|
#include <VBox/log.h>
|
||||||
|
#include <iprt/assert.h>
|
||||||
|
#include <iprt/string.h>
|
||||||
|
#include <iprt/asm.h>
|
||||||
|
#include <iprt/asm-math.h>
|
||||||
|
#include <iprt/semaphore.h>
|
||||||
|
#include <iprt/critsect.h>
|
||||||
|
#ifdef IN_RING3
|
||||||
|
# include <iprt/alloca.h>
|
||||||
|
# include <iprt/mem.h>
|
||||||
|
# include <iprt/thread.h>
|
||||||
|
# include <iprt/uuid.h>
|
||||||
|
#endif
|
||||||
|
#include <VBox/vusb.h>
|
||||||
|
#include <VBoxDD.h>
|
||||||
|
|
||||||
|
/* VBox Genode specific */
|
||||||
|
#include "vmm.h"
|
||||||
|
|
||||||
|
static bool const verbose_timer = false;
|
||||||
|
|
||||||
|
|
||||||
|
/************************
|
||||||
|
** xHCI device struct **
|
||||||
|
************************/
|
||||||
|
|
||||||
|
struct Timer_queue;
|
||||||
|
struct Destruction_helper;
|
||||||
|
|
||||||
|
|
||||||
|
struct XHCI
|
||||||
|
{
|
||||||
|
/** The PCI device. */
|
||||||
|
PDMPCIDEV PciDev;
|
||||||
|
|
||||||
|
/** Pointer to the device instance - R3 ptr. */
|
||||||
|
PPDMDEVINSR3 pDevInsR3;
|
||||||
|
|
||||||
|
/** Pointer to the device instance - R0 ptr */
|
||||||
|
PPDMDEVINSR0 pDevInsR0;
|
||||||
|
|
||||||
|
/** Pointer to the device instance - RC ptr. */
|
||||||
|
PPDMDEVINSRC pDevInsRC;
|
||||||
|
|
||||||
|
/** Address of the MMIO region assigned by PCI. */
|
||||||
|
RTGCPHYS32 MMIOBase;
|
||||||
|
|
||||||
|
/** Receiver thread that handles all USB signals. */
|
||||||
|
PPDMTHREAD pThread;
|
||||||
|
|
||||||
|
PTMTIMERR3 controller_timer;
|
||||||
|
Timer_queue *timer_queue;
|
||||||
|
Qemu::Controller *ctl;
|
||||||
|
|
||||||
|
Genode::Signal_receiver *usb_sig_rec;
|
||||||
|
Destruction_helper *destruction_helper;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Pointer to XHCI device data. */
|
||||||
|
typedef struct XHCI *PXHCI;
|
||||||
|
/** Read-only pointer to the XHCI device data. */
|
||||||
|
typedef struct XHCI const *PCXHCI;
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************
|
||||||
|
** Qemu::Controller helper classes **
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
struct Timer_queue : public Qemu::Timer_queue
|
||||||
|
{
|
||||||
|
struct Context : public Genode::List<Context>::Element
|
||||||
|
{
|
||||||
|
uint64_t timeout_abs_ns = ~0ULL;
|
||||||
|
bool pending = false;
|
||||||
|
|
||||||
|
void *qtimer = nullptr;
|
||||||
|
void (*cb)(void*) = nullptr;
|
||||||
|
void *data = nullptr;
|
||||||
|
|
||||||
|
Context(void *qtimer, void (*cb)(void*), void *data)
|
||||||
|
: qtimer(qtimer), cb(cb), data(data) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
Genode::List<Context> _context_list;
|
||||||
|
PTMTIMER tm_timer;
|
||||||
|
|
||||||
|
void _append_new_context(void *qtimer, void (*cb)(void*), void *data)
|
||||||
|
{
|
||||||
|
Context *new_ctx = new (vmm_heap()) Context(qtimer, cb, data);
|
||||||
|
|
||||||
|
_context_list.insert(new_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
Context *_find_context(void const *qtimer)
|
||||||
|
{
|
||||||
|
for (Context *c = _context_list.first(); c; c = c->next())
|
||||||
|
if (c->qtimer == qtimer)
|
||||||
|
return c;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context *_min_pending()
|
||||||
|
{
|
||||||
|
Context *min = nullptr;
|
||||||
|
for (min = _context_list.first(); min; min = min->next())
|
||||||
|
if (min && min->pending)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!min || !min->next())
|
||||||
|
return min;
|
||||||
|
|
||||||
|
for (Context *c = min->next(); c; c = c->next()) {
|
||||||
|
if (c->timeout_abs_ns < min->timeout_abs_ns && c->pending)
|
||||||
|
min = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _program_min_timer()
|
||||||
|
{
|
||||||
|
Context *min = _min_pending();
|
||||||
|
if (min == nullptr) return;
|
||||||
|
|
||||||
|
if (TMTimerIsActive(tm_timer))
|
||||||
|
TMTimerStop(tm_timer);
|
||||||
|
|
||||||
|
TMTimerSetNano(tm_timer, min->timeout_abs_ns - TMTimerGetNano(tm_timer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _deactivate_timer(void *qtimer)
|
||||||
|
{
|
||||||
|
Context *c = _find_context(qtimer);
|
||||||
|
if (c == nullptr) {
|
||||||
|
Genode::error("qtimer: ", qtimer, " not found");
|
||||||
|
throw -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->pending) {
|
||||||
|
Context *min = _min_pending();
|
||||||
|
if (min == c) {
|
||||||
|
TMTimerStop(tm_timer);
|
||||||
|
_program_min_timer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c->pending = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer_queue(PTMTIMER timer) : tm_timer(timer) { }
|
||||||
|
|
||||||
|
void timeout()
|
||||||
|
{
|
||||||
|
uint64_t now = TMTimerGetNano(tm_timer);
|
||||||
|
|
||||||
|
for (Context *c = _context_list.first(); c; c = c->next()) {
|
||||||
|
if (c->pending && c->timeout_abs_ns <= now) {
|
||||||
|
Qemu::usb_timer_callback(c->cb, c->data);
|
||||||
|
c->pending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_program_min_timer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
** TMTimer callback **
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
q->timeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned count_timer()
|
||||||
|
{
|
||||||
|
unsigned res = 0;
|
||||||
|
|
||||||
|
for (Context *c = _context_list.first(); c; c = c->next()) {
|
||||||
|
if (c->pending) Genode::log("timer: ", c, " is pending");
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************
|
||||||
|
** Qemu::Timer_queue interface **
|
||||||
|
*********************************/
|
||||||
|
|
||||||
|
Qemu::int64_t get_ns() { return TMTimerGetNano(tm_timer); }
|
||||||
|
|
||||||
|
Genode::Lock _timer_lock;
|
||||||
|
|
||||||
|
void register_timer(void *qtimer, void (*cb)(void*), void *data) override
|
||||||
|
{
|
||||||
|
Genode::Lock::Guard lock_guard(_timer_lock);
|
||||||
|
if (verbose_timer)
|
||||||
|
Genode::log("qtimer: ", qtimer, " cb: ", cb, " data: ", data);
|
||||||
|
|
||||||
|
Context *c = _find_context(qtimer);
|
||||||
|
if (c != nullptr) {
|
||||||
|
Genode::error("qtimer: ", qtimer, " already registred");
|
||||||
|
throw -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_append_new_context(qtimer, cb, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_timer(void *qtimer) override
|
||||||
|
{
|
||||||
|
Genode::Lock::Guard lock_guard(_timer_lock);
|
||||||
|
if (verbose_timer)
|
||||||
|
Genode::log("qtimer: ", qtimer);
|
||||||
|
|
||||||
|
Context *c = _find_context(qtimer);
|
||||||
|
if (c == nullptr) {
|
||||||
|
Genode::error("qtimer: ", qtimer, " not found");
|
||||||
|
throw -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_deactivate_timer(qtimer);
|
||||||
|
|
||||||
|
_context_list.remove(c);
|
||||||
|
Genode::destroy(vmm_heap(), c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void activate_timer(void *qtimer, long long int expire_abs) override
|
||||||
|
{
|
||||||
|
Genode::Lock::Guard lock_guard(_timer_lock);
|
||||||
|
if (verbose_timer)
|
||||||
|
Genode::log("qtimer: ", qtimer, " expire: ", expire_abs);
|
||||||
|
|
||||||
|
Context *c = _find_context(qtimer);
|
||||||
|
if (c == nullptr) {
|
||||||
|
Genode::error("qtimer: ", qtimer, " not found");
|
||||||
|
throw -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->timeout_abs_ns = expire_abs;
|
||||||
|
c->pending = true;
|
||||||
|
|
||||||
|
_program_min_timer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deactivate_timer(void *qtimer) override
|
||||||
|
{
|
||||||
|
Genode::Lock::Guard lock_guard(_timer_lock);
|
||||||
|
if (verbose_timer)
|
||||||
|
Genode::log("qtimer: ", qtimer);
|
||||||
|
|
||||||
|
_deactivate_timer(qtimer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Pci_device : public Qemu::Pci_device
|
||||||
|
{
|
||||||
|
PPDMDEVINS pci_dev;
|
||||||
|
|
||||||
|
Pci_device(PPDMDEVINS pDevIns) : pci_dev(pDevIns) { }
|
||||||
|
|
||||||
|
void raise_interrupt(int level) override {
|
||||||
|
PDMDevHlpPCISetIrqNoWait(pci_dev, 0, level); }
|
||||||
|
|
||||||
|
int read_dma(Qemu::addr_t addr, void *buf, Qemu::size_t size) override {
|
||||||
|
return PDMDevHlpPhysRead(pci_dev, addr, buf, size); }
|
||||||
|
|
||||||
|
int write_dma(Qemu::addr_t addr, void const *buf, Qemu::size_t size) override {
|
||||||
|
return PDMDevHlpPhysWrite(pci_dev, addr, buf, size); }
|
||||||
|
|
||||||
|
void *map_dma(Qemu::addr_t base, Qemu::size_t size) override
|
||||||
|
{
|
||||||
|
PGMPAGEMAPLOCK lock;
|
||||||
|
void * vmm_addr = nullptr;
|
||||||
|
|
||||||
|
int rc = PDMDevHlpPhysGCPhys2CCPtr(pci_dev, base, 0, &vmm_addr, &lock);
|
||||||
|
Assert(rc == VINF_SUCCESS);
|
||||||
|
|
||||||
|
/* the mapping doesn't go away, so release internal lock immediately */
|
||||||
|
PDMDevHlpPhysReleasePageMappingLock(pci_dev, &lock);
|
||||||
|
return vmm_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unmap_dma(void *addr, Qemu::size_t size) override { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************
|
||||||
|
** Qemu::Usb signal thread backend **
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
struct Destruction_helper
|
||||||
|
{
|
||||||
|
Genode::Signal_receiver &sig_rec;
|
||||||
|
|
||||||
|
Genode::Signal_dispatcher<Destruction_helper> dispatcher {
|
||||||
|
sig_rec, *this, &Destruction_helper::handle };
|
||||||
|
|
||||||
|
void handle(unsigned) { }
|
||||||
|
|
||||||
|
Destruction_helper(Genode::Signal_receiver &sig_rec)
|
||||||
|
: sig_rec(sig_rec) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static DECLCALLBACK(int) usb_signal_thread(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
|
||||||
|
{
|
||||||
|
PXHCI pThis = PDMINS_2_DATA(pDevIns, PXHCI);
|
||||||
|
if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
|
||||||
|
return VINF_SUCCESS;
|
||||||
|
|
||||||
|
while (pThread->enmState == PDMTHREADSTATE_RUNNING)
|
||||||
|
{
|
||||||
|
Genode::Signal sig = pThis->usb_sig_rec->wait_for_signal();
|
||||||
|
int num = sig.num();
|
||||||
|
|
||||||
|
Genode::Signal_dispatcher_base *dispatcher;
|
||||||
|
dispatcher = dynamic_cast<Genode::Signal_dispatcher_base *>(sig.context());
|
||||||
|
if (dispatcher) {
|
||||||
|
dispatcher->dispatch(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return VINF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DECLCALLBACK(int) usb_signal_thread_wakeup(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
|
||||||
|
{
|
||||||
|
PXHCI pThis = PDMINS_2_DATA(pDevIns, PXHCI);
|
||||||
|
|
||||||
|
Genode::Signal_transmitter(pThis->destruction_helper->dispatcher).submit();
|
||||||
|
|
||||||
|
return VINF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************
|
||||||
|
** Virtualbox Device function implementation **
|
||||||
|
***********************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback_method_impl{FNIOMMMIOREAD}
|
||||||
|
*/
|
||||||
|
PDMBOTHCBDECL(int) xhciMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr,
|
||||||
|
void *pv, unsigned cb)
|
||||||
|
{
|
||||||
|
PXHCI pThis = PDMINS_2_DATA(pDevIns, PXHCI);
|
||||||
|
|
||||||
|
Genode::off_t offset = GCPhysAddr - pThis->MMIOBase;
|
||||||
|
Qemu::Controller *ctl = pThis->ctl;
|
||||||
|
|
||||||
|
ctl->mmio_read(offset, pv, cb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback_method_impl{FNIOMMMIOWRITE}
|
||||||
|
*/
|
||||||
|
PDMBOTHCBDECL(int) xhciMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr,
|
||||||
|
void const *pv, unsigned cb)
|
||||||
|
{
|
||||||
|
PXHCI pThis = PDMINS_2_DATA(pDevIns, PXHCI);
|
||||||
|
|
||||||
|
Genode::off_t offset = GCPhysAddr - pThis->MMIOBase;
|
||||||
|
Qemu::Controller *ctl = pThis->ctl;
|
||||||
|
|
||||||
|
ctl->mmio_write(offset, pv, cb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback_method_impl{FNPCIIOREGIONMAP}
|
||||||
|
*/
|
||||||
|
static DECLCALLBACK(int) xhciR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
|
||||||
|
uint32_t iRegion, RTGCPHYS GCPhysAddress,
|
||||||
|
RTGCPHYS cb, PCIADDRESSSPACE enmType)
|
||||||
|
{
|
||||||
|
PXHCI pThis = (PXHCI)pPciDev;
|
||||||
|
int rc = PDMDevHlpMMIORegister(pThis->CTX_SUFF(pDevIns), GCPhysAddress, cb, NULL /*pvUser*/,
|
||||||
|
IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_DWORD_ZEROED
|
||||||
|
// | IOMMMIO_FLAGS_DBGSTOP_ON_COMPLICATED_WRITE,
|
||||||
|
,
|
||||||
|
xhciMmioWrite, xhciMmioRead, "USB XHCI");
|
||||||
|
if (RT_FAILURE(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = PDMDevHlpMMIORegisterRC(pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/,
|
||||||
|
"xhciMmioWrite", "xhciMmioRead");
|
||||||
|
if (RT_FAILURE(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
pThis->MMIOBase = GCPhysAddress;
|
||||||
|
return VINF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface_method_impl{PDMDEVREG,pfnReset}
|
||||||
|
*/
|
||||||
|
static DECLCALLBACK(void) xhciReset(PPDMDEVINS pDevIns)
|
||||||
|
{
|
||||||
|
PXHCI pThis = PDMINS_2_DATA(pDevIns, PXHCI);
|
||||||
|
|
||||||
|
Qemu::usb_reset();
|
||||||
|
Qemu::usb_update_devices();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface_method_impl{PDMDEVREG,pfnDestruct}
|
||||||
|
*/
|
||||||
|
static DECLCALLBACK(int) xhciDestruct(PPDMDEVINS pDevIns)
|
||||||
|
{
|
||||||
|
Qemu::usb_reset();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface_method_impl{PDMDEVREG,pfnConstruct,XHCI constructor}
|
||||||
|
*/
|
||||||
|
static DECLCALLBACK(int) xhciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
|
||||||
|
{
|
||||||
|
PXHCI pThis = PDMINS_2_DATA(pDevIns, PXHCI);
|
||||||
|
PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
|
||||||
|
|
||||||
|
pThis->usb_sig_rec = new (vmm_heap()) Genode::Signal_receiver();
|
||||||
|
pThis->destruction_helper = new (vmm_heap())
|
||||||
|
Destruction_helper(*(pThis->usb_sig_rec));
|
||||||
|
|
||||||
|
int rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, Timer_queue::tm_timer_cb,
|
||||||
|
pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
|
||||||
|
"NEC-XHCI Timer", &pThis->controller_timer);
|
||||||
|
|
||||||
|
static Timer_queue timer_queue(pThis->controller_timer);
|
||||||
|
pThis->timer_queue = &timer_queue;
|
||||||
|
static Pci_device pci_device(pDevIns);
|
||||||
|
|
||||||
|
rc = PDMDevHlpThreadCreate(pDevIns, &pThis->pThread, pThis,
|
||||||
|
usb_signal_thread, usb_signal_thread_wakeup,
|
||||||
|
32 * 1024 , RTTHREADTYPE_IO, "usb_signal");
|
||||||
|
|
||||||
|
pThis->ctl = Qemu::usb_init(timer_queue, pci_device, *pThis->usb_sig_rec,
|
||||||
|
vmm_heap(), genode_env());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Init instance data.
|
||||||
|
*/
|
||||||
|
pThis->pDevInsR3 = pDevIns;
|
||||||
|
pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
|
||||||
|
pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
|
||||||
|
|
||||||
|
PCIDevSetVendorId (&pThis->PciDev, 0x1033); /* PCI_VENDOR_ID_NEC */
|
||||||
|
PCIDevSetDeviceId (&pThis->PciDev, 0x0194); /* PCI_DEVICE_ID_NEC_UPD720200 */
|
||||||
|
PCIDevSetClassProg (&pThis->PciDev, 0x30); /* xHCI */
|
||||||
|
PCIDevSetClassSub (&pThis->PciDev, 0x03);
|
||||||
|
PCIDevSetClassBase (&pThis->PciDev, 0x0c);
|
||||||
|
PCIDevSetInterruptPin (&pThis->PciDev, 0x01);
|
||||||
|
PCIDevSetByte (&pThis->PciDev, 0x60, 0x30); /* Serial Bus Release Number Register */
|
||||||
|
#ifdef VBOX_WITH_MSI_DEVICES
|
||||||
|
PCIDevSetStatus (&pThis->PciDev, VBOX_PCI_STATUS_CAP_LIST);
|
||||||
|
PCIDevSetCapabilityList(&pThis->PciDev, 0x80);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register PCI device and I/O region.
|
||||||
|
*/
|
||||||
|
rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev);
|
||||||
|
if (RT_FAILURE(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
#ifdef VBOX_WITH_MSI_DEVICES
|
||||||
|
PDMMSIREG MsiReg;
|
||||||
|
RT_ZERO(MsiReg);
|
||||||
|
MsiReg.cMsiVectors = 1;
|
||||||
|
MsiReg.iMsiCapOffset = 0x80;
|
||||||
|
MsiReg.iMsiNextOffset = 0x00;
|
||||||
|
rc = PDMDevHlpPCIRegisterMsi(pDevIns, &MsiReg);
|
||||||
|
if (RT_FAILURE(rc))
|
||||||
|
{
|
||||||
|
PCIDevSetCapabilityList(&pThis->PciDev, 0x0);
|
||||||
|
/* That's OK, we can work without MSI */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, pThis->ctl->mmio_size(),
|
||||||
|
PCI_ADDRESS_SPACE_MEM, xhciR3Map);
|
||||||
|
if (RT_FAILURE(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return VINF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PDMDEVREG g_DeviceXHCI =
|
||||||
|
{
|
||||||
|
/* u32version */
|
||||||
|
PDM_DEVREG_VERSION,
|
||||||
|
/* szName */
|
||||||
|
"nec-xhci",
|
||||||
|
/* szRCMod */
|
||||||
|
"VBoxDDGC.gc",
|
||||||
|
/* szR0Mod */
|
||||||
|
"VBoxDDR0.r0",
|
||||||
|
/* pszDescription */
|
||||||
|
"NEC XHCI USB controller.\n",
|
||||||
|
/* fFlags */
|
||||||
|
PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC,
|
||||||
|
/* fClass */
|
||||||
|
PDM_DEVREG_CLASS_BUS_USB,
|
||||||
|
/* cMaxInstances */
|
||||||
|
~0U,
|
||||||
|
/* cbInstance */
|
||||||
|
sizeof(XHCI),
|
||||||
|
/* pfnConstruct */
|
||||||
|
xhciR3Construct,
|
||||||
|
/* pfnDestruct */
|
||||||
|
xhciDestruct,
|
||||||
|
/* pfnRelocate */
|
||||||
|
NULL,
|
||||||
|
/* pfnMemSetup */
|
||||||
|
NULL,
|
||||||
|
/* pfnPowerOn */
|
||||||
|
NULL,
|
||||||
|
/* pfnReset */
|
||||||
|
xhciReset,
|
||||||
|
/* pfnSuspend */
|
||||||
|
NULL,
|
||||||
|
/* pfnResume */
|
||||||
|
NULL,
|
||||||
|
/* pfnAttach */
|
||||||
|
NULL,
|
||||||
|
/* pfnDetach */
|
||||||
|
NULL,
|
||||||
|
/* pfnQueryInterface */
|
||||||
|
NULL,
|
||||||
|
/* pfnInitComplete */
|
||||||
|
NULL,
|
||||||
|
/* pfnPowerOff */
|
||||||
|
NULL,
|
||||||
|
/* pfnSoftReset */
|
||||||
|
NULL,
|
||||||
|
/* u32VersionEnd */
|
||||||
|
PDM_DEVREG_VERSION
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool use_xhci_controller()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Genode::Attached_rom_dataspace config(genode_env(), "config");
|
||||||
|
return config.xml().attribute_value("xhci", false);
|
||||||
|
} catch (Genode::Rom_connection::Rom_connection_failed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -892,6 +892,24 @@ index a717aff..3d52b9f 100644
|
|||||||
|
|
||||||
void Console::i_attachStatusDriver(PCFGMNODE pCtlInst, PPDMLED *papLeds,
|
void Console::i_attachStatusDriver(PCFGMNODE pCtlInst, PPDMLED *papLeds,
|
||||||
uint64_t uFirst, uint64_t uLast,
|
uint64_t uFirst, uint64_t uLast,
|
||||||
|
@@ -1977,6 +1977,17 @@
|
||||||
|
}
|
||||||
|
} /* for every USB controller. */
|
||||||
|
|
||||||
|
+ extern bool use_xhci_controller();
|
||||||
|
+ if (use_xhci_controller()) {
|
||||||
|
+ /*
|
||||||
|
+ * NEC XHCI Device
|
||||||
|
+ */
|
||||||
|
+ InsertConfigNode(pDevices, "nec-xhci", &pDev);
|
||||||
|
+ InsertConfigNode(pDev, "0", &pInst);
|
||||||
|
+ InsertConfigNode(pInst, "Config", &pCfg);
|
||||||
|
+ InsertConfigInteger(pInst, "Trusted", 1);
|
||||||
|
+ hrc = pBusMgr->assignPCIDevice("nec-xhci", pInst); H();
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Virtual USB Devices.
|
||||||
@@ -2625,6 +2629,7 @@
|
@@ -2625,6 +2629,7 @@
|
||||||
* Parallel (LPT) Ports
|
* Parallel (LPT) Ports
|
||||||
*/
|
*/
|
||||||
@ -1049,3 +1067,14 @@ index a717aff..3d52b9f 100644
|
|||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************************************
|
/*********************************************************************************************************************************
|
||||||
|
--- a/src/app/virtualbox/src/VBox/Main/src-client/BusAssignmentManager.cpp
|
||||||
|
+++ b/src/app/virtualbox/src/VBox/Main/src-client/BusAssignmentManager.cpp
|
||||||
|
@@ -71,6 +71,8 @@
|
||||||
|
{"usb-ehci", 0, 11, 0, 0},
|
||||||
|
{"usb-xhci", 0, 12, 0, 0},
|
||||||
|
|
||||||
|
+ {"nec-xhci", 0, 29, 0, 0},
|
||||||
|
+
|
||||||
|
/* ACPI controller */
|
||||||
|
{"acpi", 0, 7, 0, 0},
|
||||||
|
|
||||||
|
@ -628,7 +628,8 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>,
|
|||||||
if (!TRPMHasTrap(pVCpu)) {
|
if (!TRPMHasTrap(pVCpu)) {
|
||||||
|
|
||||||
bool res = VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI);
|
bool res = VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI);
|
||||||
Assert(!res);
|
if (res)
|
||||||
|
Vmm::log("NMI was set");
|
||||||
|
|
||||||
if (VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC |
|
if (VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC |
|
||||||
VMCPU_FF_INTERRUPT_PIC))) {
|
VMCPU_FF_INTERRUPT_PIC))) {
|
||||||
|
10
repos/ports/src/virtualbox5/vmm.h
Normal file
10
repos/ports/src/virtualbox5/vmm.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _VMM_H_
|
||||||
|
#define _VMM_H_
|
||||||
|
|
||||||
|
#include <base/env.h>
|
||||||
|
#include <base/allocator.h>
|
||||||
|
|
||||||
|
Genode::Env & genode_env();
|
||||||
|
Genode::Allocator & vmm_heap();
|
||||||
|
|
||||||
|
#endif /* _VMM_H_ */
|
@ -54,6 +54,7 @@ vbox4_win7_64_multiple
|
|||||||
vbox4_win81_64
|
vbox4_win81_64
|
||||||
vbox4_win10_64
|
vbox4_win10_64
|
||||||
vbox5_win7_32
|
vbox5_win7_32
|
||||||
|
vbox5_win7_64
|
||||||
vbox5_win10_64
|
vbox5_win10_64
|
||||||
tz_vmm
|
tz_vmm
|
||||||
vmm
|
vmm
|
||||||
|
Loading…
Reference in New Issue
Block a user