qemu-usb: update port to 5.2.0

The contrib code is updated from 2.4.1 to version 5.2.0 and the used
device-model is changed to QEMU xHCI. Due to this change older guests
OSes, namely Windows 7, that relied on the NEC xHCI device-model will
not work anymore.

The 'Qemu::Controller' interface was extended by an 'info' method, which
returns the vendor and product ID. This allows for removing the
hard-coded values in the VirtualBox glue code.

Issue #4018.
This commit is contained in:
Josef Söntgen 2021-01-18 16:12:53 +01:00 committed by Norman Feske
parent a6f0b05834
commit 9918a8f88d
12 changed files with 507 additions and 163 deletions

View File

@ -21,10 +21,11 @@
namespace Qemu {
typedef Genode::size_t size_t;
typedef Genode::off_t off_t;
typedef Genode::int64_t int64_t;
typedef Genode::addr_t addr_t;
typedef Genode::size_t size_t;
typedef Genode::off_t off_t;
typedef Genode::int64_t int64_t;
typedef Genode::addr_t addr_t;
typedef Genode::uint16_t uint16_t;
/************************************
@ -83,6 +84,20 @@ namespace Qemu {
*/
struct Controller
{
/*
* Controller information
*/
struct Info
{
uint16_t vendor_id;
uint16_t product_id;
};
/**
* Get information of the controller
*/
virtual Info info() const = 0;
/**
* Size of the MMIO region of the controller
*/

View File

@ -9,7 +9,7 @@ LIBS = qemu-usb_include
SRC_CC = dummies.cc qemu_emul.cc host.cc
SRC_C = hcd-xhci.c core.c bus.c
SRC_C = hcd-xhci.c hcd-xhci-pci.c core.c bus.c
SHARED_LIB = yes

View File

@ -1 +1 @@
2ff18fbfd11a955148cfbdcaa81d4a1162750fcd
d716b4378eb2f243207f868646dfd7e62469228b

View File

@ -1,13 +1,14 @@
LICENSE := GPLv2
VERSION := 2.4.1
VERSION := 5.2.0
DOWNLOADS := qemu.archive
URL(qemu) := http://wiki.qemu-project.org/download/qemu-$(VERSION).tar.bz2
SHA(qemu) := e3d5cf4c8b1f9129c9c797329a515bfb6b3b1ded0ab8b394c8a316490fe3a177
URL(qemu) := https://download.qemu.org/qemu-$(VERSION).tar.xz
SHA(qemu) := cb18d889b628fbe637672b0326789d9b0e3b8027e0445b936537c78549df17bc
DIR(qemu) := src/lib/qemu
TAR_OPT(qemu) := --strip-components=1 --files-from $(REP_DIR)/src/lib/qemu-usb/files.list
LIST_FILE := $(REP_DIR)/src/lib/qemu-usb/files.list
TAR_OPT(qemu) := --strip-components=1 --files-from - < <(sed 's/-x.x.x/-$(VERSION)/g' $(LIST_FILE))
HASH_INPUT += $(REP_DIR)/src/lib/qemu-usb/files.list
PATCHES := src/lib/qemu-usb/patches/xhci_state.patch \
PATCHES := src/lib/qemu-usb/patches/xhci_pci_register.patch \
src/lib/qemu-usb/patches/usb_bus_nfree.patch
PATCH_OPT:= -p1

View File

@ -79,6 +79,13 @@ Object* object_dynamic_cast_assert(Object*, const char*, const char*, int, const
}
PCIBus *pci_get_bus(const PCIDevice *dev)
{
TRACE;
return nullptr;
}
bool pci_bus_is_express(PCIBus*)
{
TRACE;
@ -116,11 +123,11 @@ ObjectClass* object_get_class(Object*)
const char* object_get_typename(Object*)
{
TRACE;
return nullptr;
return "";
}
void qbus_set_bus_hotplug_handler(BusState *state, Error **error)
void qbus_set_bus_hotplug_handler(BusState *state)
{
TRACE;
}
@ -146,6 +153,25 @@ long int strtol(const char*, char**, int)
}
ObjectProperty *object_property_add_bool(Object *, const char *,
bool (*get)(Object *, Error **),
void (*set)(Object *, bool, Error **))
{
TRACE_AND_STOP;
return nullptr;
}
const PropertyInfo qdev_prop_link = { 0 };
const PropertyInfo qdev_prop_on_off_auto = { 0 };
void qdev_alias_all_properties(DeviceState *target, Object *source)
{
TRACE;
}
DeviceState* qdev_try_create(BusState*, const char*)
{
TRACE_AND_STOP;
@ -153,6 +179,27 @@ DeviceState* qdev_try_create(BusState*, const char*)
}
DeviceState *qdev_new(const char *name)
{
TRACE_AND_STOP;
return nullptr;
}
DeviceState *qdev_try_new(const char *name)
{
TRACE_AND_STOP;
return nullptr;
}
bool qdev_realize_and_unref(DeviceState *, BusState *, Error **)
{
TRACE_AND_STOP;
return false;
}
void monitor_printf(Monitor*, const char*, ...)
{
TRACE;
@ -179,6 +226,29 @@ const char* qdev_fw_name(DeviceState*)
}
AddressSpace *pci_get_address_space(PCIDevice *dev)
{
TRACE;
return nullptr;
}
void object_initialize_child_internal(Object *parent, const char *propname,
void *child, size_t size,
const char *type)
{
TRACE;
}
bool object_property_set_link(Object *obj, const char *name,
Object *value, Error **errp)
{
TRACE;
return true;
}
gchar* g_strdup(const gchar*)
{
TRACE;

View File

@ -1,6 +1,10 @@
qemu-2.4.1/include/hw/usb.h
qemu-2.4.1/include/qemu/queue.h
qemu-2.4.1/include/qom/object.h
qemu-2.4.1/hw/usb/bus.c
qemu-2.4.1/hw/usb/core.c
qemu-2.4.1/hw/usb/hcd-xhci.c
qemu-x.x.x/include/hw/usb.h
qemu-x.x.x/include/hw/usb/xhci.h
qemu-x.x.x/include/qemu/queue.h
qemu-x.x.x/hw/usb/bus.c
qemu-x.x.x/hw/usb/core.c
qemu-x.x.x/hw/usb/hcd-xhci.c
qemu-x.x.x/hw/usb/hcd-xhci.h
qemu-x.x.x/hw/usb/hcd-xhci-nec.c
qemu-x.x.x/hw/usb/hcd-xhci-pci.c
qemu-x.x.x/hw/usb/hcd-xhci-pci.h

View File

@ -18,8 +18,7 @@
#include <stdarg.h>
#include <base/fixed_stdint.h>
void q_printf(char const *, ...) __attribute__((format(printf, 1, 2)));
void q_vprintf(char const *, va_list);
void qemu_printf(char const *, ...) __attribute__((format(printf, 1, 2)));
typedef genode_uint8_t uint8_t;
typedef genode_uint16_t uint16_t;
@ -61,7 +60,7 @@ void *memcpy(void *dest, const void *src, size_t n);
void abort();
#define fprintf(fd, fmt, ...) q_printf(fmt, ##__VA_ARGS__)
#define fprintf(fd, fmt, ...) qemu_printf(fmt, ##__VA_ARGS__)
int snprintf(char *buf, size_t size, const char *fmt, ...);
int strcmp(const char *s1, const char *s2);
size_t strlen(char const *s);
@ -97,6 +96,29 @@ typedef struct MemoryRegion { unsigned dummy; } MemoryRegion;
struct tm;
struct Aml { unsigned dummy; };
typedef struct Aml Aml;
/*****************
** compiler.h> **
*****************/
#define typeof_field(type, field) typeof(((type *)0)->field)
#define type_check(t1,t2) ((t1*)0 - (t2*)0)
/******************
** qapi-types.h **
******************/
typedef enum OnOffAuto {
ON_OFF_AUTO_AUTO = 0,
ON_OFF_AUTO_ON = 1,
ON_OFF_AUTO_OFF = 2,
ON_OFF_AUTO__MAX = 3,
} OnOffAuto;
/******************
** qapi/error.h **
@ -108,8 +130,10 @@ void error_setg(Error **errp, const char *fmt, ...);
const char *error_get_pretty(Error *err);
void error_report(const char *fmt, ...);
void error_reportf_err(Error *err, const char *fmt, ...);
void error_free(Error *err);
void error_propagate(Error **dst_errp, Error *local_err);
void error_append_hint(Error *const *errp, const char *fmt, ...);
extern Error *error_abort;
@ -182,16 +206,32 @@ size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
typedef struct Object { unsigned dummy; } Object;
typedef struct ObjectClass { unsigned dummy; } ObjectClass;
typedef struct ObjectProperty { unsigned dummy; } ObjectProperty;
ObjectProperty *object_property_add_bool(Object *obj, const char *name,
bool (*get)(Object *, Error **),
void (*set)(Object *, bool, Error **));
#define object_initialize_child(parent, propname, child, type) \
object_initialize_child_internal((parent), (propname), \
(child), sizeof(*(child)), (type))
void object_initialize_child_internal(Object *parent, const char *propname,
void *child, size_t size,
const char *type);
bool object_property_set_link(Object *obj, const char *name,
Object *value, Error **errp);
struct DeviceState;
struct PCIDevice;
struct XHCIState;
struct PCIDevice *cast_PCIDevice(void *);
struct XHCIState *cast_XHCIState(void *);
struct DeviceState *cast_DeviceState(void *);
struct BusState *cast_BusState(void *);
struct Object *cast_object(void *);
struct USBDevice *cast_USBDevice(void *);
struct PCIDevice *cast_PCIDevice(void *);
struct XHCIState *cast_XHCIState(void *);
struct XHCIPciState *cast_XHCIPciState(void *);
struct DeviceState *cast_DeviceState(void *);
struct BusState *cast_BusState(void *);
struct Object *cast_object(void *);
struct USBDevice *cast_USBDevice(void *);
struct USBHostDevice *cast_USBHostDevice(void *);
struct PCIDeviceClass *cast_PCIDeviceClass(void *);
@ -201,6 +241,8 @@ struct HotplugHandlerClass *cast_HotplugHandlerClass(void *);
struct USBDeviceClass *cast_USBDeviceClass(void *);
struct USBBus *cast_USBBus(void *);
#define OBJECT_CHECK(type, obj, str) \
cast_##type((void *)obj)
@ -213,6 +255,41 @@ struct USBDeviceClass *cast_USBDeviceClass(void *);
#define OBJECT_GET_CLASS(klass, obj, str) \
OBJECT_CHECK(klass, obj, str)
#define DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
static inline InstanceType * \
OBJ_NAME(const void *obj) \
{ return OBJECT_CHECK(InstanceType, obj, TYPENAME); }
#define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
static inline ClassType * \
OBJ_NAME##_GET_CLASS(const void *obj) \
{ return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
\
static inline ClassType * \
OBJ_NAME##_CLASS(const void *klass) \
{ return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }
#define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
\
DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)
#define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
typedef struct InstanceType InstanceType; \
typedef struct ClassType ClassType; \
\
DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)
#define OBJECT_DECLARE_SIMPLE_TYPE(InstanceType, MODULE_OBJ_NAME) \
typedef struct InstanceType InstanceType; \
\
DECLARE_INSTANCE_CHECKER(InstanceType, MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)
void object_unref(void *obj);
typedef struct InterfaceInfo {
const char *type;
@ -225,6 +302,8 @@ typedef struct TypeInfo
char const *parent;
size_t instance_size;
void (*instance_init)(Object *obj);
bool abstract;
size_t class_size;
void (*class_init)(ObjectClass *klass, void *data);
@ -241,6 +320,12 @@ Type type_register_static(const TypeInfo *info);
const char *object_get_typename(Object *obj);
typedef struct Visitor Visitor;
#define TYPE_DEVICE "device"
OBJECT_DECLARE_TYPE(DeviceState, DeviceClass, DEVICE)
/********************
** glib emulation **
********************/
@ -254,6 +339,8 @@ void g_free(void *ptr);
t; \
})
#define g_new g_new0
#define g_malloc0(size) ({ \
void *t = g_malloc((size)); \
memset(t, 0, (size)); \
@ -289,6 +376,7 @@ typedef struct BusState BusState;
typedef struct DeviceState
{
char const *id;
BusState *parent_bus;
} DeviceState;
@ -296,12 +384,13 @@ struct VMStateDescription;
struct Property;
typedef void (*DeviceRealize)(DeviceState *dev, Error **errp);
typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
typedef void (*DeviceUnrealize)(DeviceState *dev);
typedef struct DeviceClass
{
DECLARE_BITMAP(categories, DEVICE_CATEGORY_MAX);
struct Property *props;
bool user_creatable;
void (*reset)(DeviceState *dev);
DeviceRealize realize;
DeviceUnrealize unrealize;
@ -339,11 +428,25 @@ enum Prop_type
BIT, UINT32, END
};
struct PropertyInfo { unsigned dummy; };
typedef struct PropertyInfo PropertyInfo;
extern const PropertyInfo qdev_prop_link;
extern const PropertyInfo qdev_prop_on_off_auto;
typedef struct Property
{
const char *name;
const PropertyInfo *info;
enum Prop_type type;
bool set_default;
union {
int64_t i;
uint64_t u;
} defval;
unsigned offset;
unsigned long value;
const char *link_type;
} Property;
@ -354,6 +457,28 @@ typedef struct Property
#define DEFINE_PROP_END_OF_LIST() { .type = END }
#define DEFINE_PROP_STRING(...) {}
#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) { \
.name = (_name), \
.info = &(_prop), \
.offset = offsetof(_state, _field) \
+ type_check(_type,typeof_field(_state, _field)), \
.set_default = true, \
.defval.i = (_type)_defval, \
}
#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto)
#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type) { \
.name = (_name), \
.info = &(qdev_prop_link), \
.offset = offsetof(_state, _field) \
+ type_check(_ptr_type, typeof_field(_state, _field)), \
.link_type = _type, \
}
void device_class_set_props(DeviceClass *dc, Property *props);
void device_legacy_reset(DeviceState *dev);
/* forward */
typedef struct DeviceState DeviceState;
@ -363,11 +488,18 @@ void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
void qbus_create_inplace(void *bus, size_t size, const char *typename,
DeviceState *parent, const char *name);
void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp);
void qbus_set_bus_hotplug_handler(BusState *bus);
DeviceState *qdev_create(BusState *bus, const char *name);
DeviceState *qdev_try_create(BusState *bus, const char *name);
char *qdev_get_dev_path(DeviceState *dev);
const char *qdev_fw_name(DeviceState *dev);
DeviceState *qdev_new(const char *name);
DeviceState *qdev_try_new(const char *name);
bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp);
void qdev_alias_all_properties(DeviceState *target, Object *source);
extern bool qdev_hotplug;
/******************
** hw/hotplug.h **
@ -404,6 +536,7 @@ typedef struct HotplugHandlerClass
struct USBBus *cast_DeviceStateToUSBBus(void);
#define MAX(a, b) ((a) < (b) ? (b) : (a))
#define MAX_CONST(a, b) MAX((a), (b))
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@ -483,10 +616,12 @@ void memory_region_del_subregion(MemoryRegion *mr,
typedef struct QEMUIOVector QEMUSGList;
void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint, AddressSpace *as);
void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
void qemu_sglist_destroy(QEMUSGList *qsg);
int dma_memory_read(AddressSpace *as, dma_addr_t addr, void *buf, dma_addr_t len);
int dma_memory_write(AddressSpace *as, dma_addr_t addr, const void *buf, dma_addr_t len);
static inline uint64_t ldq_le_dma(AddressSpace *as, dma_addr_t addr)
{
@ -526,6 +661,8 @@ typedef struct PCIDevice
uint8_t config[0x1000]; /* PCIe config space */
PCIBus *bus;
uint32_t cap_present;
uint8_t *msix_table;
uint8_t *msix_pba;
@ -572,21 +709,34 @@ AddressSpace *pci_get_address_space(PCIDevice *dev);
void pci_register_bar(PCIDevice *pci_dev, int region_num,
uint8_t attr, MemoryRegion *memory);
bool pci_bus_is_express(PCIBus *bus);
PCIBus *pci_get_bus(const PCIDevice *dev);
AddressSpace *pci_get_address_space(PCIDevice *dev);
int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset);
#define INTERFACE_PCIE_DEVICE "pci-express-device"
#define INTERFACE_CONVENTIONAL_PCI_DEVICE "conventional-pci-device"
#define PCI_VENDOR_ID_REDHAT 0x1b36
#define PCI_DEVICE_ID_REDHAT_XHCI 0x000d
enum {
QEMU_PCI_CAP_EXPRESS = 0x4,
};
/*********************
** hw/pci/msi(x).h **
*********************/
int msi_init(struct PCIDevice *dev, uint8_t offset,
unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask);
unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask, Error **errp);
int msix_init(PCIDevice *dev, unsigned short nentries,
MemoryRegion *table_bar, uint8_t table_bar_nr,
unsigned table_offset, MemoryRegion *pba_bar,
uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos);
uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos, Error **);
void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar);
bool msi_enabled(const PCIDevice *dev);
int msix_enabled(PCIDevice *dev);
@ -616,6 +766,7 @@ void msix_notify(PCIDevice *dev, unsigned vector);
#define VMSTATE_MSIX(...) {}
#define VMSTATE_TIMER_PTR(...) {}
#define VMSTATE_STRUCT(...) {}
#define VMSTATE_PCI_DEVICE(...) {}
#define VMSTATE_END_OF_LIST() {}
typedef struct VMStateField { unsigned dummy; } VMStateField;
@ -635,7 +786,7 @@ typedef struct VMStateDescription
#define assert(cond) do { \
if (!(cond)) { \
q_printf("assertion faied: %s:%d\n", __FILE__, __LINE__); \
qemu_printf("assertion faied: %s:%d\n", __FILE__, __LINE__); \
int *d = (int *)0x0; \
*d = 1; \
}} while (0)
@ -645,55 +796,63 @@ typedef struct VMStateDescription
** traces **
************/
#define trace_usb_xhci_irq_msix_use(v)
#define trace_usb_xhci_irq_msix_unuse(v)
#define trace_usb_xhci_irq_msix(v)
#if 0
#define TRACE_PRINTF(...) qemu_printf(__VA_ARGS__)
#else
#define TRACE_PRINTF(...)
#endif
#define trace_usb_packet_state_change(...) TRACE_PRINTF("%s:%d\n", "trace_usb_packet_state_change", __LINE__)
#define trace_usb_packet_state_fault(...) TRACE_PRINTF("%s:%d\n", "trace_usb_packet_state_fault", __LINE__)
#define trace_usb_port_attach(...) TRACE_PRINTF("%s:%d\n", "trace_usb_port_attach", __LINE__)
#define trace_usb_port_claim(...) TRACE_PRINTF("%s:%d\n", "trace_usb_port_claim", __LINE__)
#define trace_usb_port_detach(...) TRACE_PRINTF("%s:%d\n", "trace_usb_port_detach", __LINE__)
#define trace_usb_port_release(...) TRACE_PRINTF("%s:%d\n", "trace_usb_port_release", __LINE__)
#define trace_usb_xhci_cap_read(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_cap_read", __LINE__)
#define trace_usb_xhci_doorbell_read(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_doorbell_read", __LINE__)
#define trace_usb_xhci_doorbell_write(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_doorbell_write", __LINE__)
#define trace_usb_xhci_enforced_limit(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_enforced_limit", __LINE__)
#define trace_usb_xhci_ep_disable(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_ep_disable", __LINE__)
#define trace_usb_xhci_ep_enable(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_ep_enable", __LINE__)
#define trace_usb_xhci_ep_kick(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_ep_kick", __LINE__)
#define trace_usb_xhci_ep_reset(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_ep_reset", __LINE__)
#define trace_usb_xhci_ep_set_dequeue(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_ep_set_dequeue", __LINE__)
#define trace_usb_xhci_ep_state(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_ep_state", __LINE__)
#define trace_usb_xhci_ep_stop(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_ep_stop", __LINE__)
#define trace_usb_xhci_exit(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_exit", __LINE__)
#define trace_usb_xhci_fetch_trb(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_fetch_trb", __LINE__)
#define trace_usb_xhci_irq_intx(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_irq_intx", __LINE__)
#define trace_usb_xhci_irq_msi(v)
#define trace_usb_xhci_queue_event(...)
#define trace_usb_xhci_fetch_trb(...)
#define trace_usb_xhci_run(...)
#define trace_usb_xhci_stop(...)
#define trace_usb_xhci_ep_state(...)
#define trace_usb_xhci_ep_enable(...)
#define trace_usb_xhci_ep_disable(...)
#define trace_usb_xhci_ep_stop(...)
#define trace_usb_xhci_ep_reset(...)
#define trace_usb_xhci_ep_set_dequeue(...)
#define trace_usb_xhci_xfer_async(...)
#define trace_usb_xhci_xfer_nak(...)
#define trace_usb_xhci_xfer_success(...)
#define trace_usb_xhci_xfer_error(...)
#define trace_usb_xhci_xfer_start(...)
#define trace_usb_xhci_unimplemented(...)
#define trace_usb_xhci_ep_kick(...)
#define trace_usb_xhci_xfer_retry(...)
#define trace_usb_xhci_slot_enable(...)
#define trace_usb_xhci_slot_disable(...)
#define trace_usb_xhci_slot_address(...)
#define trace_usb_xhci_slot_configure(...)
#define trace_usb_xhci_irq_intx(...)
#define trace_usb_xhci_slot_reset(...)
#define trace_usb_xhci_slot_evaluate(...)
#define trace_usb_xhci_port_notify(...)
#define trace_usb_xhci_port_link(...)
#define trace_usb_xhci_port_reset(...)
#define trace_usb_xhci_reset(...)
#define trace_usb_xhci_cap_read(...)
#define trace_usb_xhci_port_read(...)
#define trace_usb_xhci_port_write(...)
#define trace_usb_xhci_oper_read(...)
#define trace_usb_xhci_oper_write(...)
#define trace_usb_xhci_runtime_read(...)
#define trace_usb_xhci_runtime_write(...)
#define trace_usb_xhci_doorbell_read(...)
#define trace_usb_xhci_doorbell_write(...)
#define trace_usb_xhci_exit(...)
#define trace_usb_port_claim(...)
#define trace_usb_port_release(...)
#define trace_usb_port_attach(...)
#define trace_usb_port_detach(...)
#define trace_usb_packet_state_fault(...)
#define trace_usb_packet_state_change(...)
#define trace_usb_xhci_irq_msix(v)
#define trace_usb_xhci_irq_msix_unuse(v)
#define trace_usb_xhci_irq_msix_use(v)
#define trace_usb_xhci_oper_read(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_oper_read", __LINE__)
#define trace_usb_xhci_oper_write(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_oper_write", __LINE__)
#define trace_usb_xhci_port_link(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_port_link", __LINE__)
#define trace_usb_xhci_port_notify(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_port_notify", __LINE__)
#define trace_usb_xhci_port_read(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_port_read", __LINE__)
#define trace_usb_xhci_port_reset(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_port_reset", __LINE__)
#define trace_usb_xhci_port_write(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_port_write", __LINE__)
#define trace_usb_xhci_queue_event(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_queue_event", __LINE__)
#define trace_usb_xhci_reset(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_reset", __LINE__)
#define trace_usb_xhci_run(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_run", __LINE__)
#define trace_usb_xhci_runtime_read(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_runtime_read", __LINE__)
#define trace_usb_xhci_runtime_write(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_runtime_write", __LINE__)
#define trace_usb_xhci_slot_address(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_slot_address", __LINE__)
#define trace_usb_xhci_slot_configure(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_slot_configure", __LINE__)
#define trace_usb_xhci_slot_disable(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_slot_disable", __LINE__)
#define trace_usb_xhci_slot_enable(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_slot_enable", __LINE__)
#define trace_usb_xhci_slot_evaluate(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_slot_evaluate", __LINE__)
#define trace_usb_xhci_slot_reset(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_slot_reset", __LINE__)
#define trace_usb_xhci_stop(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_stop", __LINE__)
#define trace_usb_xhci_unimplemented(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_unimplemented", __LINE__)
#define trace_usb_xhci_xfer_async(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_xfer_async", __LINE__)
#define trace_usb_xhci_xfer_error(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_xfer_error", __LINE__)
#define trace_usb_xhci_xfer_nak(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_xfer_nak", __LINE__)
#define trace_usb_xhci_xfer_retry(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_xfer_retry", __LINE__)
#define trace_usb_xhci_xfer_start(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_xfer_start", __LINE__)
#define trace_usb_xhci_xfer_success(...) TRACE_PRINTF("%s:%d\n", "trace_usb_xhci_xfer_success", __LINE__)
/***********************
** library interface **
@ -723,4 +882,13 @@ void usb_host_update_devices();
void monitor_printf(Monitor *mon, const char *fmt, ...);
/*************
** errno.h **
*************/
enum {
ENOTSUP = 666,
};
#endif /* _INCLUDE__QEMU_EMUL_H_ */

View File

@ -1,18 +1,22 @@
diff --git a/src/lib/qemu/hw/usb/bus.c b/src/lib/qemu/hw/usb/bus.c
index 5f39e1e..b94f3af 100644
--- a/src/lib/qemu/hw/usb/bus.c
+++ b/src/lib/qemu/hw/usb/bus.c
@@ -433,10 +433,10 @@ void usb_claim_port(USBDevice *dev, Error **errp)
@@ -429,13 +429,13 @@
return;
}
} else {
- if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) {
- /* Create a new hub and chain it on */
- usb_try_create_simple(bus, "usb-hub", NULL);
- hub = usb_try_new("usb-hub");
- if (hub) {
- usb_realize_and_unref(hub, bus, NULL);
- }
- }
+ // if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) {
+ // /* Create a new hub and chain it on */
+ // usb_try_create_simple(bus, "usb-hub", NULL);
+ // hub = usb_try_new("usb-hub");
+ // if (hub) {
+ // usb_realize_and_unref(hub, bus, NULL);
+ // }
+ // }
if (bus->nfree == 0) {
error_setg(errp, "tried to attach usb device %s to a bus "

View File

@ -0,0 +1,15 @@
--- a/src/lib/qemu/hw/usb/hcd-xhci-pci.c
+++ b/src/lib/qemu/hw/usb/hcd-xhci-pci.c
@@ -252,10 +252,10 @@
.instance_init = qemu_xhci_instance_init,
};
-static void xhci_register_types(void)
+static void xhci_pci_register_types(void)
{
type_register_static(&xhci_pci_info);
type_register_static(&qemu_xhci_info);
}
-type_init(xhci_register_types)
+type_init(xhci_pci_register_types)

View File

@ -1,42 +0,0 @@
diff --git a/src/lib/qemu/hw/usb/hcd-xhci.c b/src/lib/qemu/hw/usb/hcd-xhci.c
index c673bed..cd930da 100644
--- a/src/lib/qemu/hw/usb/hcd-xhci.c
+++ b/src/lib/qemu/hw/usb/hcd-xhci.c
@@ -486,6 +486,8 @@ struct XHCIState {
#define TYPE_XHCI "nec-usb-xhci"
+#ifndef __cplusplus
+
#define XHCI(obj) \
OBJECT_CHECK(XHCIState, (obj), TYPE_XHCI)
@@ -1349,6 +1351,14 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
static void xhci_ep_kick_timer(void *opaque)
{
XHCIEPContext *epctx = opaque;
+
+ /*
+ * We might have blocked in the entry lock, while the endpoint was stopped
+ * by another thread
+ */
+ if (epctx->state == CC_STOPPED)
+ return;
+
xhci_kick_ep(epctx->xhci, epctx->slotid, epctx->epid, 0);
}
@@ -2361,6 +2371,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
if (bsr) {
slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT;
+ usb_device_reset(dev);
} else {
USBPacket p;
uint8_t buf[1];
@@ -3914,3 +3925,5 @@ static void xhci_register_types(void)
}
type_init(xhci_register_types)
+
+#endif /* __cplusplus */

View File

@ -6,7 +6,7 @@
*/
/*
* Copyright (C) 2015-2017 Genode Labs GmbH
* Copyright (C) 2015-2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
@ -21,7 +21,8 @@
#include <extern_c_begin.h>
#include <qemu_emul.h>
/* XHCIState is defined in this file */
#include <hcd-xhci.c>
#include <hcd-xhci.h>
#include <hcd-xhci-pci.h>
#include <extern_c_end.h>
#include <qemu/usb.h>
@ -34,11 +35,38 @@ static bool const verbose_irq = false;
static bool const verbose_iov = false;
static bool const verbose_mmio = false;
namespace {
/* keep in sync with hcd-xhci.c */
#define OFF_OPER 0x40
#define OFF_RUNTIME 0x1000
#define OFF_PORTS (OFF_OPER + 0x400)
bool port_access(Genode::off_t offset)
{
bool const v = (offset >= OFF_PORTS) && (offset < OFF_RUNTIME);
return v;
}
uint32_t port_index(Genode::off_t offset)
{
return (offset - OFF_PORTS) / 0x10;
}
#undef OFF_OPER
#undef OFF_RUNTIME
#undef OFF_PORTS
} /* anonymous namespace */
extern "C" void _type_init_usb_register_types();
extern "C" void _type_init_usb_host_register_types(Genode::Entrypoint*,
Genode::Allocator*,
Genode::Env *);
extern "C" void _type_init_xhci_register_types();
extern "C" void _type_init_xhci_pci_register_types();
extern Genode::Mutex _mutex;
@ -60,6 +88,7 @@ Qemu::Controller *Qemu::usb_init(Timer_queue &tq, Pci_device &pci,
_type_init_usb_register_types();
_type_init_xhci_register_types();
_type_init_xhci_pci_register_types();
_type_init_usb_host_register_types(&ep, &alloc, &env);
return qemu_controller();
@ -105,7 +134,7 @@ void *memset(void *s, int c, size_t n) {
return Genode::memset(s, c, n); }
void q_printf(char const *fmt, ...)
void qemu_printf(char const *fmt, ...)
{
enum { BUF_SIZE = 128 };
char buf[BUF_SIZE] { };
@ -178,6 +207,7 @@ struct Wrapper
USBDevice _usb_device;
BusState _bus_state;
XHCIState *_xhci_state = nullptr;
XHCIPciState *_xhci_pci_state = nullptr;
USBHostDevice _usb_host_device;
ObjectClass _object_class;
@ -201,6 +231,14 @@ struct Wrapper
&& ptr < ((char*)_xhci_state + sizeof(XHCIState)))
return true;
/*
* XHCIPciState contains XHCIState, so let's play the same game.
*/
if (_xhci_pci_state != nullptr
&& ptr >= _xhci_pci_state
&& ptr < ((char*)_xhci_pci_state + sizeof(XHCIPciState)))
return true;
using addr_t = Genode::addr_t;
addr_t p = (addr_t)ptr;
@ -217,10 +255,11 @@ struct Object_pool
{
enum {
XHCI, /* XHCI controller */
XHCI_PCI, /* XHCI PCI controller */
USB_BUS, /* bus driver */
USB_DEVICE, /* USB device driver */
USB_HOST_DEVICE, /* USB host device driver */
MAX = 8 /* host devices (USB_HOST_DEVICE - MAX) */
MAX = 10 /* host devices (USB_HOST_DEVICE - MAX) */
};
bool used[MAX];
@ -284,6 +323,10 @@ struct XHCIState *cast_XHCIState(void *ptr) {
return Object_pool::p()->find_object(ptr)->_xhci_state; }
struct XHCIPciState *cast_XHCIPciState(void *ptr) {
return Object_pool::p()->find_object(ptr)->_xhci_pci_state; }
struct DeviceState *cast_DeviceState(void *ptr) {
return &Object_pool::p()->find_object(ptr)->_device_state; }
@ -357,7 +400,7 @@ USBHostDevice *create_usbdevice(void *data)
error_free(e);
e = nullptr;
usb_device_class->unrealize(dev_state, &e);
usb_device_class->unrealize(dev_state);
Object_pool::p()->free_object(obj);
return nullptr;
@ -380,7 +423,7 @@ void remove_usbdevice(USBHostDevice *device)
Genode::error("usb_device_state null");
Error *e = nullptr;
usb_device_class->unrealize(usb_device_state, &e);
usb_device_class->unrealize(usb_device_state);
Wrapper *obj = Object_pool::p()->find_object(device);
if (obj)
@ -409,12 +452,43 @@ Type type_register_static(TypeInfo const *t)
{
if (!Genode::strcmp(t->name, TYPE_XHCI)) {
Wrapper *w = &Object_pool::p()->obj[Object_pool::XHCI];
w->_xhci_state = (XHCIState*) g_malloc(sizeof(XHCIState));
Genode::memset(w->_xhci_state, 0, sizeof(XHCIState));
{
Wrapper *p = &Object_pool::p()->obj[Object_pool::XHCI_PCI];
p->_xhci_pci_state = (XHCIPciState*) g_malloc(sizeof(XHCIPciState));
Genode::memset(p->_xhci_pci_state, 0, sizeof(XHCIPciState));
w->_xhci_state = (XHCIState*)&p->_xhci_pci_state->xhci;
}
t->class_init(&w->_object_class, 0);
properties_apply(w->_xhci_state, &w->_device_class);
}
if (!Genode::strcmp(t->name, TYPE_XHCI_PCI)) {
Wrapper *w = &Object_pool::p()->obj[Object_pool::XHCI_PCI];
w->_xhci_state = (XHCIState*)&w->_xhci_pci_state->xhci;
t->class_init(&w->_object_class, 0);
properties_apply(w->_xhci_pci_state, &w->_device_class);
t->instance_init((Object*)w->_xhci_pci_state);
}
if (!Genode::strcmp(t->name, TYPE_QEMU_XHCI)) {
Wrapper *w = &Object_pool::p()->obj[Object_pool::XHCI_PCI];
t->class_init(&w->_object_class, 0);
t->instance_init((Object*)w->_xhci_pci_state);
{
Wrapper *w = &Object_pool::p()->obj[Object_pool::XHCI];
DeviceState *dev = &w->_device_state;
DeviceClass *dev_class = &w->_device_class;
Error *e;
dev_class->realize(dev, &e);
}
PCIDevice *pci = &w->_pci_device;
PCIDeviceClass *pci_class = &w->_pci_device_class;
@ -547,9 +621,21 @@ struct Controller : public Qemu::Controller
}
}
Genode::size_t mmio_size() const { return _mmio_size; }
/**************************
** Controller interface **
**************************/
int mmio_read(Genode::off_t offset, void *buf, Genode::size_t size)
Info info() const override
{
return Info {
.vendor_id = PCI_VENDOR_ID_REDHAT,
.product_id = PCI_DEVICE_ID_REDHAT_XHCI
};
}
Genode::size_t mmio_size() const override { return _mmio_size; }
int mmio_read(Genode::off_t offset, void *buf, Genode::size_t size) override
{
Genode::Mutex::Guard guard(_mutex);
Mmio &mmio = find_region(offset);
@ -560,8 +646,8 @@ struct Controller : public Qemu::Controller
/*
* Handle port access
*/
if (offset >= (OFF_OPER + 0x400) && offset < OFF_RUNTIME) {
uint32_t port = (offset - 0x440) / 0x10;
if (port_access(offset)) {
uint32_t port = port_index(offset);
ptr = (void*)&Object_pool::p()->xhci_state()->ports[port];
}
@ -575,7 +661,7 @@ struct Controller : public Qemu::Controller
return 0;
}
int mmio_write(Genode::off_t offset, void const *buf, Genode::size_t size)
int mmio_write(Genode::off_t offset, void const *buf, Genode::size_t size) override
{
Genode::Mutex::Guard guard(_mutex);
Mmio &mmio = find_region(offset);
@ -588,8 +674,8 @@ struct Controller : public Qemu::Controller
/*
* Handle port access
*/
if (offset >= (OFF_OPER + 0x400) && offset < OFF_RUNTIME) {
uint32_t port = (offset - 0x440) / 0x10;
if (port_access(offset)) {
uint32_t port = port_index(offset);
ptr = (void*)&Object_pool::p()->xhci_state()->ports[port];
}
@ -637,23 +723,16 @@ void memory_region_add_subregion(MemoryRegion *mr, hwaddr offset, MemoryRegion *
** DMA **
*********/
int pci_dma_read(PCIDevice*, dma_addr_t addr, void *buf, dma_addr_t size)
{
return _pci_device->read_dma(addr, buf, size);
}
int pci_dma_write(PCIDevice*, dma_addr_t addr, const void *buf, dma_addr_t size)
{
return _pci_device->write_dma(addr, buf, size);
}
int dma_memory_read(AddressSpace*, dma_addr_t addr, void *buf, dma_addr_t size)
{
return _pci_device->read_dma(addr, buf, size);
}
int dma_memory_write(AddressSpace *, dma_addr_t addr, const void *buf, dma_addr_t len)
{
return _pci_device->write_dma(addr, buf, len);
}
/****************
** Interrupts **
@ -674,19 +753,22 @@ void pci_irq_assert(PCIDevice*)
int msi_init(PCIDevice *pdev, uint8_t offset, unsigned int nr_vectors, bool msi64bit,
bool msi_per_vector_mask)
bool msi_per_vector_mask, Error **)
{
return 0;
}
int msix_init(PCIDevice*, short unsigned int, MemoryRegion*, uint8_t, unsigned int, MemoryRegion*,
uint8_t, unsigned int, uint8_t)
uint8_t, unsigned int, uint8_t, Error **)
{
return 0;
}
void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar) { }
bool msi_enabled(const PCIDevice *pdev)
{
return false;
@ -835,7 +917,7 @@ size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
}
void pci_dma_sglist_init(QEMUSGList *sgl, PCIDevice*, int alloc_hint) {
void qemu_sglist_init(QEMUSGList *sgl, DeviceState *, int alloc_hint, AddressSpace *) {
qemu_iovec_init(sgl, alloc_hint); }
@ -930,3 +1012,28 @@ void error_propagate(Error **dst_errp, Error *local_err) {
void error_free(Error *err) { g_free(err); }
void error_append_hint(Error *const *errp, const char *fmt, ...)
{
}
/*****************
** qdev-core.c **
*****************/
void device_class_set_props(DeviceClass *dc, Property *props)
{
dc->props = props;
}
void device_legacy_reset(DeviceState *dev)
{
DeviceClass *klass = DEVICE_GET_CLASS(dev);
// trace_qdev_reset(dev, object_get_typename(OBJECT(dev)));
if (klass->reset) {
klass->reset(dev);
}
}

View File

@ -488,7 +488,7 @@ static DECLCALLBACK(int) xhciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
int rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, Timer_queue::tm_timer_cb,
pThis, TMTIMER_FLAGS_NO_CRIT_SECT,
"NEC-XHCI Timer", &pThis->controller_timer);
"XHCI Timer", &pThis->controller_timer);
static Timer_queue timer_queue(pThis->controller_timer);
pThis->timer_queue = &timer_queue;
@ -497,6 +497,8 @@ static DECLCALLBACK(int) xhciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
pThis->ctl = Qemu::usb_init(timer_queue, pci_device, *pThis->usb_ep,
vmm_heap(), genode_env());
Qemu::Controller::Info const ctl_info = pThis->ctl->info();
/*
* Init instance data.
*/
@ -504,11 +506,11 @@ static DECLCALLBACK(int) xhciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
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 */
PCIDevSetVendorId (&pThis->PciDev, ctl_info.vendor_id);
PCIDevSetDeviceId (&pThis->PciDev, ctl_info.product_id);
PCIDevSetClassBase (&pThis->PciDev, 0x0c); /* PCI serial */
PCIDevSetClassSub (&pThis->PciDev, 0x03); /* USB */
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