mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 11:27:29 +00:00
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:
parent
a6f0b05834
commit
9918a8f88d
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
||||
|
@ -1 +1 @@
|
||||
2ff18fbfd11a955148cfbdcaa81d4a1162750fcd
|
||||
d716b4378eb2f243207f868646dfd7e62469228b
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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 "
|
||||
|
@ -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)
|
@ -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 */
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user