xref: /openbmc/qemu/hw/xen/xen-bus.c (revision 108f7bba15d6ee4136b543fc22005921e7ce4048)
1 /*
2  * Copyright (c) 2018  Citrix Systems Inc.
3  *
4  * This work is licensed under the terms of the GNU GPL, version 2 or later.
5  * See the COPYING file in the top-level directory.
6  */
7 
8 #include "qemu/osdep.h"
9 #include "hw/hw.h"
10 #include "hw/sysbus.h"
11 #include "hw/xen/xen-bus.h"
12 #include "qapi/error.h"
13 #include "trace.h"
14 
15 static void xen_bus_unrealize(BusState *bus, Error **errp)
16 {
17     trace_xen_bus_unrealize();
18 }
19 
20 static void xen_bus_realize(BusState *bus, Error **errp)
21 {
22     trace_xen_bus_realize();
23 }
24 
25 static void xen_bus_class_init(ObjectClass *class, void *data)
26 {
27     BusClass *bus_class = BUS_CLASS(class);
28 
29     bus_class->realize = xen_bus_realize;
30     bus_class->unrealize = xen_bus_unrealize;
31 }
32 
33 static const TypeInfo xen_bus_type_info = {
34     .name = TYPE_XEN_BUS,
35     .parent = TYPE_BUS,
36     .instance_size = sizeof(XenBus),
37     .class_size = sizeof(XenBusClass),
38     .class_init = xen_bus_class_init,
39     .interfaces = (InterfaceInfo[]) {
40         { TYPE_HOTPLUG_HANDLER },
41         { }
42     },
43 };
44 
45 static void xen_device_unrealize(DeviceState *dev, Error **errp)
46 {
47     XenDevice *xendev = XEN_DEVICE(dev);
48     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
49     const char *type = object_get_typename(OBJECT(xendev));
50 
51     trace_xen_device_unrealize(type);
52 
53     if (xendev_class->unrealize) {
54         xendev_class->unrealize(xendev, errp);
55     }
56 }
57 
58 static void xen_device_realize(DeviceState *dev, Error **errp)
59 {
60     XenDevice *xendev = XEN_DEVICE(dev);
61     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
62     const char *type = object_get_typename(OBJECT(xendev));
63     Error *local_err = NULL;
64 
65     trace_xen_device_realize(type);
66 
67     if (xendev_class->realize) {
68         xendev_class->realize(xendev, &local_err);
69         if (local_err) {
70             error_propagate(errp, local_err);
71             goto unrealize;
72         }
73     }
74 
75     return;
76 
77 unrealize:
78     xen_device_unrealize(dev, &error_abort);
79 }
80 
81 static void xen_device_class_init(ObjectClass *class, void *data)
82 {
83     DeviceClass *dev_class = DEVICE_CLASS(class);
84 
85     dev_class->realize = xen_device_realize;
86     dev_class->unrealize = xen_device_unrealize;
87     dev_class->bus_type = TYPE_XEN_BUS;
88 }
89 
90 static const TypeInfo xen_device_type_info = {
91     .name = TYPE_XEN_DEVICE,
92     .parent = TYPE_DEVICE,
93     .instance_size = sizeof(XenDevice),
94     .abstract = true,
95     .class_size = sizeof(XenDeviceClass),
96     .class_init = xen_device_class_init,
97 };
98 
99 typedef struct XenBridge {
100     SysBusDevice busdev;
101 } XenBridge;
102 
103 #define TYPE_XEN_BRIDGE "xen-bridge"
104 
105 static const TypeInfo xen_bridge_type_info = {
106     .name = TYPE_XEN_BRIDGE,
107     .parent = TYPE_SYS_BUS_DEVICE,
108     .instance_size = sizeof(XenBridge),
109 };
110 
111 static void xen_register_types(void)
112 {
113     type_register_static(&xen_bridge_type_info);
114     type_register_static(&xen_bus_type_info);
115     type_register_static(&xen_device_type_info);
116 }
117 
118 type_init(xen_register_types)
119 
120 void xen_bus_init(void)
121 {
122     DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
123     BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL);
124 
125     qdev_init_nofail(dev);
126     qbus_set_bus_hotplug_handler(bus, &error_abort);
127 }
128