#include "hw/i386/apic-msidef.h"
#include "hw/xen/xen_common.h"
#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen_bus.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-misc.h"
#include "qemu/error-report.h"
state->device_listener = xen_device_listener;
device_listener_register(&state->device_listener);
+ xen_bus_init(xen_domid);
+
/* Initialize backend core & drivers */
if (xen_be_init() != 0) {
error_report("xen backend core setup failed");
# xen backend driver support
-common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o xen_pvdev.o xen-common.o
+common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o xen_pvdev.o xen-common.o xen_bus.o xen_foo.o
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
xen_map_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u bdf: %02x.%02x.%02x"
xen_unmap_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u bdf: %02x.%02x.%02x"
xen_domid_restrict(int err) "err: %u"
+
+# include/hw/xen/xen_bus.c
+xen_backend_realize(const char *type, char *name, uint16_t domid) "type: %s name: %s domid: %u"
+xen_backend_unrealize(const char *type, char *name, uint16_t domid) "type: %s name: %s domid: %u"
--- /dev/null
+#include "qemu/osdep.h"
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/boards.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/xen/xen_bus.h"
+#include "monitor/monitor.h"
+#include "trace.h"
+
+static void xen_bus_dev_print(Monitor *mon, DeviceState *dev, int indent)
+{
+ XenBackend *d = XEN_BACKEND(dev);
+ XenBackendClass *dc = XEN_BACKEND_GET_CLASS(d);
+ XenBus *b = XEN_BUS(qdev_get_parent_bus(dev));
+
+ monitor_printf(mon, "%*stype = '%s' name = '%s' domid = %u\n",
+ indent, "", dc->type, d->name, b->domid);
+}
+
+static void xen_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->print_dev = xen_bus_dev_print;
+}
+
+static void xen_backend_realize(DeviceState *dev, Error **errp)
+{
+ XenBackend *d = XEN_BACKEND(dev);
+ XenBackendClass *dc = XEN_BACKEND_GET_CLASS(d);
+ XenBus *b = XEN_BUS(qdev_get_parent_bus(dev));
+ Error *local_err = NULL;
+
+ if (!d->name) {
+ error_setg(errp, "invalid name");
+ return;
+ }
+
+ trace_xen_backend_realize(dc->type, d->name, b->domid);
+
+ if (dc->realize) {
+ dc->realize(d, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+}
+
+static void xen_backend_unrealize(DeviceState *dev, Error **errp)
+{
+ XenBackend *d = XEN_BACKEND(dev);
+ XenBackendClass *dc = XEN_BACKEND_GET_CLASS(d);
+ XenBus *b = XEN_BUS(qdev_get_parent_bus(dev));
+ Error *local_err = NULL;
+
+ trace_xen_backend_realize(dc->type, d->name, b->domid);
+
+ if (dc->unrealize) {
+ dc->unrealize(d, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+}
+
+static Property xen_backend_props[] = {
+ DEFINE_PROP_STRING("name", XenBackend, name),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void xen_backend_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *k = DEVICE_CLASS(klass);
+
+ k->realize = xen_backend_realize;
+ k->unrealize = xen_backend_unrealize;
+ k->props = xen_backend_props;
+
+ k->bus_type = TYPE_XEN_BUS;
+}
+
+void xen_bus_init(domid_t domid)
+{
+ DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
+ XenBus *b;
+
+ qdev_init_nofail(dev);
+
+ b = XEN_BUS(qbus_create(TYPE_XEN_BUS, dev, NULL));
+ qbus_set_bus_hotplug_handler(BUS(b), &error_abort);
+
+ b->domid = domid;
+}
+
+static const TypeInfo xen_bridge_type_info = {
+ .name = TYPE_XEN_BRIDGE,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(XenBridge),
+};
+
+static const TypeInfo xen_bus_type_info = {
+ .name = TYPE_XEN_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(XenBus),
+ .class_size = sizeof(XenBusClass),
+ .class_init = xen_bus_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
+};
+
+static const TypeInfo xen_backend_type_info = {
+ .name = TYPE_XEN_BACKEND,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(XenBackend),
+ .abstract = true,
+ .class_size = sizeof(XenBackendClass),
+ .class_init = xen_backend_class_init,
+};
+
+static void xen_register_types(void)
+{
+ type_register_static(&xen_bridge_type_info);
+ type_register_static(&xen_bus_type_info);
+ type_register_static(&xen_backend_type_info);
+}
+
+type_init(xen_register_types)
--- /dev/null
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/xen/xen_bus.h"
+#include "trace.h"
+
+#define TYPE_XEN_FOO_BACKEND "xen-foo"
+
+#define XEN_FOO_BACKEND(obj) \
+ OBJECT_CHECK(XenBackend, (obj), TYPE_XEN_FOO_BACKEND)
+
+typedef struct XenFooBackend {
+ /*< private >*/
+ XenBackend parent_obj;
+ /*< public >*/
+ unsigned int data;
+} XenFooBackend;
+
+static void xen_foo_realize(XenBackend *dev, Error **errp)
+{
+}
+
+static void xen_foo_unrealize(XenBackend *dev, Error **errp)
+{
+}
+
+static Property xen_foo_props[] = {
+ DEFINE_PROP_UINT32("data", XenFooBackend, data, 0xfeedface),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void xen_foo_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ XenBackendClass *k = XEN_BACKEND_CLASS(klass);
+
+ k->type = "foo";
+ k->realize = xen_foo_realize;
+ k->unrealize = xen_foo_unrealize;
+ dc->desc = "Xen Foo Backend";
+ dc->props = xen_foo_props;
+}
+
+static const TypeInfo xen_foo_type_info = {
+ .name = TYPE_XEN_FOO_BACKEND,
+ .parent = TYPE_XEN_BACKEND,
+ .instance_size = sizeof(XenFooBackend),
+ .class_init = xen_foo_class_init,
+};
+
+static void xen_foo_register_types(void)
+{
+ type_register_static(&xen_foo_type_info);
+}
+
+type_init(xen_foo_register_types)
--- /dev/null
+#ifndef QEMU_XEN_BUS_H
+#define QEMU_XEN_BUS_H
+
+#include <xen/xen.h>
+
+#include "hw/sysbus.h"
+
+typedef struct XenBridge {
+ SysBusDevice busdev;
+} XenBridge;
+
+typedef struct XenBusClass {
+ /*< private >*/
+ BusClass parent_class;
+ /*< public >*/
+
+} XenBusClass;
+
+typedef struct XenBus {
+ BusState qbus;
+ domid_t domid;
+} XenBus;
+
+typedef struct XenBackend {
+ DeviceState qdev;
+ char *name;
+} XenBackend;
+
+typedef void (*XenBackendRealize)(XenBackend *dev, Error **errp);
+typedef void (*XenBackendUnrealize)(XenBackend *dev, Error **errp);
+
+typedef struct XenBackendClass {
+ /*< private >*/
+ DeviceClass parent_class;
+ /*< public >*/
+ const char *type;
+ XenBackendRealize realize;
+ XenBackendUnrealize unrealize;
+} XenBackendClass;
+
+#define TYPE_XEN_BACKEND "xen-backend"
+#define XEN_BACKEND(obj) \
+ OBJECT_CHECK(XenBackend, (obj), TYPE_XEN_BACKEND)
+#define XEN_BACKEND_CLASS(klass) \
+ OBJECT_CLASS_CHECK(XenBackendClass, (klass), TYPE_XEN_BACKEND)
+#define XEN_BACKEND_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(XenBackendClass, (obj), TYPE_XEN_BACKEND)
+
+
+#define TYPE_XEN_BUS "xen-bus"
+#define XEN_BUS(obj) OBJECT_CHECK(XenBus, (obj), TYPE_XEN_BUS)
+#define XEN_BUS_CLASS(klass) OBJECT_CLASS_CHECK(XenBusClass, (klass), TYPE_XEN_BUS)
+#define XEN_BUS_GET_CLASS(obj) OBJECT_GET_CLASS(XenBusClass, (obj), TYPE_XEN_BUS)
+
+#define TYPE_XEN_BRIDGE "xen-bridge"
+
+void xen_bus_init(domid_t);
+
+#endif