diff --git a/repos/libports/include/qemu/usb.h b/repos/libports/include/qemu/usb.h index 86bc781d7e..6f8092f5c4 100644 --- a/repos/libports/include/qemu/usb.h +++ b/repos/libports/include/qemu/usb.h @@ -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 */ diff --git a/repos/libports/lib/mk/qemu-usb.mk b/repos/libports/lib/mk/qemu-usb.mk index d0f8593c43..c43b8402f9 100644 --- a/repos/libports/lib/mk/qemu-usb.mk +++ b/repos/libports/lib/mk/qemu-usb.mk @@ -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 diff --git a/repos/libports/ports/qemu-usb.hash b/repos/libports/ports/qemu-usb.hash index 4f25d1ffe9..253f1857ba 100644 --- a/repos/libports/ports/qemu-usb.hash +++ b/repos/libports/ports/qemu-usb.hash @@ -1 +1 @@ -2ff18fbfd11a955148cfbdcaa81d4a1162750fcd +d716b4378eb2f243207f868646dfd7e62469228b diff --git a/repos/libports/ports/qemu-usb.port b/repos/libports/ports/qemu-usb.port index 79624af749..06db1a18d3 100644 --- a/repos/libports/ports/qemu-usb.port +++ b/repos/libports/ports/qemu-usb.port @@ -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 diff --git a/repos/libports/src/lib/qemu-usb/dummies.cc b/repos/libports/src/lib/qemu-usb/dummies.cc index bbf608f4c5..f0fb19315b 100644 --- a/repos/libports/src/lib/qemu-usb/dummies.cc +++ b/repos/libports/src/lib/qemu-usb/dummies.cc @@ -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; diff --git a/repos/libports/src/lib/qemu-usb/files.list b/repos/libports/src/lib/qemu-usb/files.list index f501ae6ec4..e108d1c731 100644 --- a/repos/libports/src/lib/qemu-usb/files.list +++ b/repos/libports/src/lib/qemu-usb/files.list @@ -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 diff --git a/repos/libports/src/lib/qemu-usb/include/qemu_emul.h b/repos/libports/src/lib/qemu-usb/include/qemu_emul.h index 7b6e5e38de..2e0037ae5f 100644 --- a/repos/libports/src/lib/qemu-usb/include/qemu_emul.h +++ b/repos/libports/src/lib/qemu-usb/include/qemu_emul.h @@ -18,8 +18,7 @@ #include #include -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_ */ diff --git a/repos/libports/src/lib/qemu-usb/patches/usb_bus_nfree.patch b/repos/libports/src/lib/qemu-usb/patches/usb_bus_nfree.patch index b7677728d0..dd51de524a 100644 --- a/repos/libports/src/lib/qemu-usb/patches/usb_bus_nfree.patch +++ b/repos/libports/src/lib/qemu-usb/patches/usb_bus_nfree.patch @@ -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 " diff --git a/repos/libports/src/lib/qemu-usb/patches/xhci_pci_register.patch b/repos/libports/src/lib/qemu-usb/patches/xhci_pci_register.patch new file mode 100644 index 0000000000..4942d478e7 --- /dev/null +++ b/repos/libports/src/lib/qemu-usb/patches/xhci_pci_register.patch @@ -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) diff --git a/repos/libports/src/lib/qemu-usb/patches/xhci_state.patch b/repos/libports/src/lib/qemu-usb/patches/xhci_state.patch deleted file mode 100644 index 0b054895b1..0000000000 --- a/repos/libports/src/lib/qemu-usb/patches/xhci_state.patch +++ /dev/null @@ -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 */ diff --git a/repos/libports/src/lib/qemu-usb/qemu_emul.cc b/repos/libports/src/lib/qemu-usb/qemu_emul.cc index 926627bc8e..c358f915d7 100644 --- a/repos/libports/src/lib/qemu-usb/qemu_emul.cc +++ b/repos/libports/src/lib/qemu-usb/qemu_emul.cc @@ -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 #include /* XHCIState is defined in this file */ -#include +#include +#include #include #include @@ -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); + } +} diff --git a/repos/ports/src/virtualbox5/devxhci.cc b/repos/ports/src/virtualbox5/devxhci.cc index cd68cab1d2..4b61dca82e 100644 --- a/repos/ports/src/virtualbox5/devxhci.cc +++ b/repos/ports/src/virtualbox5/devxhci.cc @@ -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