Statistics
| Branch: | Revision:

root / hw / qdev.c @ 042f84d0

History | View | Annotate | Download (10.1 kB)

1 aae9460e Paul Brook
/*
2 aae9460e Paul Brook
 *  Dynamic device configuration and creation.
3 aae9460e Paul Brook
 *
4 aae9460e Paul Brook
 *  Copyright (c) 2009 CodeSourcery
5 aae9460e Paul Brook
 *
6 aae9460e Paul Brook
 * This library is free software; you can redistribute it and/or
7 aae9460e Paul Brook
 * modify it under the terms of the GNU Lesser General Public
8 aae9460e Paul Brook
 * License as published by the Free Software Foundation; either
9 aae9460e Paul Brook
 * version 2 of the License, or (at your option) any later version.
10 aae9460e Paul Brook
 *
11 aae9460e Paul Brook
 * This library is distributed in the hope that it will be useful,
12 aae9460e Paul Brook
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 aae9460e Paul Brook
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 aae9460e Paul Brook
 * Lesser General Public License for more details.
15 aae9460e Paul Brook
 *
16 aae9460e Paul Brook
 * You should have received a copy of the GNU Lesser General Public
17 aae9460e Paul Brook
 * License along with this library; if not, write to the Free Software
18 aae9460e Paul Brook
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19 aae9460e Paul Brook
 */
20 aae9460e Paul Brook
21 aae9460e Paul Brook
/* The theory here is that it should be possible to create a machine without
22 aae9460e Paul Brook
   knowledge of specific devices.  Historically board init routines have
23 aae9460e Paul Brook
   passed a bunch of arguments to each device, requiring the board know
24 aae9460e Paul Brook
   exactly which device it is dealing with.  This file provides an abstract
25 aae9460e Paul Brook
   API for device configuration and initialization.  Devices will generally
26 aae9460e Paul Brook
   inherit from a particular bus (e.g. PCI or I2C) rather than
27 aae9460e Paul Brook
   this API directly.  */
28 aae9460e Paul Brook
29 9d07d757 Paul Brook
#include "net.h"
30 aae9460e Paul Brook
#include "qdev.h"
31 aae9460e Paul Brook
#include "sysemu.h"
32 cae4956e Gerd Hoffmann
#include "monitor.h"
33 aae9460e Paul Brook
34 aae9460e Paul Brook
struct DeviceProperty {
35 aae9460e Paul Brook
    const char *name;
36 1431b6a1 Paul Brook
    DevicePropType type;
37 aae9460e Paul Brook
    union {
38 89a740e1 Paul Brook
        uint64_t i;
39 aae9460e Paul Brook
        void *ptr;
40 aae9460e Paul Brook
    } value;
41 aae9460e Paul Brook
    DeviceProperty *next;
42 aae9460e Paul Brook
};
43 aae9460e Paul Brook
44 02e2da45 Paul Brook
/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
45 b9aaf7f8 Blue Swirl
static BusState *main_system_bus;
46 10c4c98a Gerd Hoffmann
extern struct BusInfo system_bus_info;
47 4d6ae674 Paul Brook
48 042f84d0 Gerd Hoffmann
static DeviceInfo *device_info_list;
49 aae9460e Paul Brook
50 aae9460e Paul Brook
/* Register a new device type.  */
51 074f2fff Gerd Hoffmann
void qdev_register(DeviceInfo *info)
52 aae9460e Paul Brook
{
53 074f2fff Gerd Hoffmann
    assert(info->size >= sizeof(DeviceState));
54 042f84d0 Gerd Hoffmann
    assert(!info->next);
55 aae9460e Paul Brook
56 042f84d0 Gerd Hoffmann
    info->next = device_info_list;
57 042f84d0 Gerd Hoffmann
    device_info_list = info;
58 aae9460e Paul Brook
}
59 aae9460e Paul Brook
60 aae9460e Paul Brook
/* Create a new device.  This only initializes the device state structure
61 aae9460e Paul Brook
   and allows properties to be set.  qdev_init should be called to
62 aae9460e Paul Brook
   initialize the actual device emulation.  */
63 02e2da45 Paul Brook
DeviceState *qdev_create(BusState *bus, const char *name)
64 aae9460e Paul Brook
{
65 042f84d0 Gerd Hoffmann
    DeviceInfo *info;
66 aae9460e Paul Brook
    DeviceState *dev;
67 aae9460e Paul Brook
68 10c4c98a Gerd Hoffmann
    if (!bus) {
69 10c4c98a Gerd Hoffmann
        if (!main_system_bus) {
70 10c4c98a Gerd Hoffmann
            main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
71 aae9460e Paul Brook
        }
72 10c4c98a Gerd Hoffmann
        bus = main_system_bus;
73 10c4c98a Gerd Hoffmann
    }
74 10c4c98a Gerd Hoffmann
75 042f84d0 Gerd Hoffmann
    for (info = device_info_list; info != NULL; info = info->next) {
76 042f84d0 Gerd Hoffmann
        if (info->bus_info != bus->info)
77 10c4c98a Gerd Hoffmann
            continue;
78 042f84d0 Gerd Hoffmann
        if (strcmp(info->name, name) != 0)
79 10c4c98a Gerd Hoffmann
            continue;
80 10c4c98a Gerd Hoffmann
        break;
81 aae9460e Paul Brook
    }
82 042f84d0 Gerd Hoffmann
    if (!info) {
83 10c4c98a Gerd Hoffmann
        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
84 aae9460e Paul Brook
    }
85 aae9460e Paul Brook
86 042f84d0 Gerd Hoffmann
    dev = qemu_mallocz(info->size);
87 042f84d0 Gerd Hoffmann
    dev->info = info;
88 02e2da45 Paul Brook
    dev->parent_bus = bus;
89 02e2da45 Paul Brook
    LIST_INSERT_HEAD(&bus->children, dev, sibling);
90 aae9460e Paul Brook
    return dev;
91 aae9460e Paul Brook
}
92 aae9460e Paul Brook
93 aae9460e Paul Brook
/* Initialize a device.  Device properties should be set before calling
94 aae9460e Paul Brook
   this function.  IRQs and MMIO regions should be connected/mapped after
95 aae9460e Paul Brook
   calling this function.  */
96 aae9460e Paul Brook
void qdev_init(DeviceState *dev)
97 aae9460e Paul Brook
{
98 042f84d0 Gerd Hoffmann
    dev->info->init(dev, dev->info);
99 02e2da45 Paul Brook
}
100 02e2da45 Paul Brook
101 02e2da45 Paul Brook
/* Unlink device from bus and free the structure.  */
102 02e2da45 Paul Brook
void qdev_free(DeviceState *dev)
103 02e2da45 Paul Brook
{
104 02e2da45 Paul Brook
    LIST_REMOVE(dev, sibling);
105 02e2da45 Paul Brook
    free(dev);
106 aae9460e Paul Brook
}
107 aae9460e Paul Brook
108 1431b6a1 Paul Brook
static DeviceProperty *create_prop(DeviceState *dev, const char *name,
109 1431b6a1 Paul Brook
                                   DevicePropType type)
110 aae9460e Paul Brook
{
111 aae9460e Paul Brook
    DeviceProperty *prop;
112 aae9460e Paul Brook
113 aae9460e Paul Brook
    /* TODO: Check for duplicate properties.  */
114 aae9460e Paul Brook
    prop = qemu_mallocz(sizeof(*prop));
115 aae9460e Paul Brook
    prop->name = qemu_strdup(name);
116 1431b6a1 Paul Brook
    prop->type = type;
117 aae9460e Paul Brook
    prop->next = dev->props;
118 aae9460e Paul Brook
    dev->props = prop;
119 aae9460e Paul Brook
120 aae9460e Paul Brook
    return prop;
121 aae9460e Paul Brook
}
122 aae9460e Paul Brook
123 89a740e1 Paul Brook
void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value)
124 aae9460e Paul Brook
{
125 aae9460e Paul Brook
    DeviceProperty *prop;
126 aae9460e Paul Brook
127 1431b6a1 Paul Brook
    prop = create_prop(dev, name, PROP_TYPE_INT);
128 aae9460e Paul Brook
    prop->value.i = value;
129 aae9460e Paul Brook
}
130 aae9460e Paul Brook
131 1431b6a1 Paul Brook
void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value)
132 1431b6a1 Paul Brook
{
133 1431b6a1 Paul Brook
    DeviceProperty *prop;
134 1431b6a1 Paul Brook
135 1431b6a1 Paul Brook
    prop = create_prop(dev, name, PROP_TYPE_DEV);
136 1431b6a1 Paul Brook
    prop->value.ptr = value;
137 1431b6a1 Paul Brook
}
138 1431b6a1 Paul Brook
139 aae9460e Paul Brook
void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value)
140 aae9460e Paul Brook
{
141 aae9460e Paul Brook
    DeviceProperty *prop;
142 aae9460e Paul Brook
143 db241f40 Paul Brook
    prop = create_prop(dev, name, PROP_TYPE_PTR);
144 aae9460e Paul Brook
    prop->value.ptr = value;
145 aae9460e Paul Brook
}
146 aae9460e Paul Brook
147 9d07d757 Paul Brook
void qdev_set_netdev(DeviceState *dev, NICInfo *nd)
148 9d07d757 Paul Brook
{
149 9d07d757 Paul Brook
    assert(!dev->nd);
150 9d07d757 Paul Brook
    dev->nd = nd;
151 9d07d757 Paul Brook
}
152 9d07d757 Paul Brook
153 aae9460e Paul Brook
154 aae9460e Paul Brook
/* Get a character (serial) device interface.  */
155 aae9460e Paul Brook
CharDriverState *qdev_init_chardev(DeviceState *dev)
156 aae9460e Paul Brook
{
157 aae9460e Paul Brook
    static int next_serial;
158 aae9460e Paul Brook
    static int next_virtconsole;
159 aae9460e Paul Brook
    /* FIXME: This is a nasty hack that needs to go away.  */
160 042f84d0 Gerd Hoffmann
    if (strncmp(dev->info->name, "virtio", 6) == 0) {
161 aae9460e Paul Brook
        return virtcon_hds[next_virtconsole++];
162 aae9460e Paul Brook
    } else {
163 aae9460e Paul Brook
        return serial_hds[next_serial++];
164 aae9460e Paul Brook
    }
165 aae9460e Paul Brook
}
166 aae9460e Paul Brook
167 02e2da45 Paul Brook
BusState *qdev_get_parent_bus(DeviceState *dev)
168 aae9460e Paul Brook
{
169 02e2da45 Paul Brook
    return dev->parent_bus;
170 aae9460e Paul Brook
}
171 aae9460e Paul Brook
172 1431b6a1 Paul Brook
static DeviceProperty *find_prop(DeviceState *dev, const char *name,
173 1431b6a1 Paul Brook
                                 DevicePropType type)
174 aae9460e Paul Brook
{
175 aae9460e Paul Brook
    DeviceProperty *prop;
176 aae9460e Paul Brook
177 aae9460e Paul Brook
    for (prop = dev->props; prop; prop = prop->next) {
178 aae9460e Paul Brook
        if (strcmp(prop->name, name) == 0) {
179 1431b6a1 Paul Brook
            assert (prop->type == type);
180 aae9460e Paul Brook
            return prop;
181 aae9460e Paul Brook
        }
182 aae9460e Paul Brook
    }
183 aae9460e Paul Brook
    return NULL;
184 aae9460e Paul Brook
}
185 aae9460e Paul Brook
186 aae9460e Paul Brook
uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def)
187 aae9460e Paul Brook
{
188 aae9460e Paul Brook
    DeviceProperty *prop;
189 aae9460e Paul Brook
190 1431b6a1 Paul Brook
    prop = find_prop(dev, name, PROP_TYPE_INT);
191 1431b6a1 Paul Brook
    if (!prop) {
192 aae9460e Paul Brook
        return def;
193 1431b6a1 Paul Brook
    }
194 aae9460e Paul Brook
195 aae9460e Paul Brook
    return prop->value.i;
196 aae9460e Paul Brook
}
197 aae9460e Paul Brook
198 aae9460e Paul Brook
void *qdev_get_prop_ptr(DeviceState *dev, const char *name)
199 aae9460e Paul Brook
{
200 aae9460e Paul Brook
    DeviceProperty *prop;
201 aae9460e Paul Brook
202 1431b6a1 Paul Brook
    prop = find_prop(dev, name, PROP_TYPE_PTR);
203 aae9460e Paul Brook
    assert(prop);
204 aae9460e Paul Brook
    return prop->value.ptr;
205 aae9460e Paul Brook
}
206 aae9460e Paul Brook
207 1431b6a1 Paul Brook
DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name)
208 1431b6a1 Paul Brook
{
209 1431b6a1 Paul Brook
    DeviceProperty *prop;
210 1431b6a1 Paul Brook
211 1431b6a1 Paul Brook
    prop = find_prop(dev, name, PROP_TYPE_DEV);
212 1431b6a1 Paul Brook
    if (!prop) {
213 1431b6a1 Paul Brook
        return NULL;
214 1431b6a1 Paul Brook
    }
215 1431b6a1 Paul Brook
    return prop->value.ptr;
216 1431b6a1 Paul Brook
}
217 1431b6a1 Paul Brook
218 aae9460e Paul Brook
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
219 aae9460e Paul Brook
{
220 aae9460e Paul Brook
    assert(dev->num_gpio_in == 0);
221 aae9460e Paul Brook
    dev->num_gpio_in = n;
222 aae9460e Paul Brook
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
223 aae9460e Paul Brook
}
224 aae9460e Paul Brook
225 aae9460e Paul Brook
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
226 aae9460e Paul Brook
{
227 aae9460e Paul Brook
    assert(dev->num_gpio_out == 0);
228 aae9460e Paul Brook
    dev->num_gpio_out = n;
229 aae9460e Paul Brook
    dev->gpio_out = pins;
230 aae9460e Paul Brook
}
231 aae9460e Paul Brook
232 aae9460e Paul Brook
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
233 aae9460e Paul Brook
{
234 aae9460e Paul Brook
    assert(n >= 0 && n < dev->num_gpio_in);
235 aae9460e Paul Brook
    return dev->gpio_in[n];
236 aae9460e Paul Brook
}
237 aae9460e Paul Brook
238 aae9460e Paul Brook
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
239 aae9460e Paul Brook
{
240 aae9460e Paul Brook
    assert(n >= 0 && n < dev->num_gpio_out);
241 aae9460e Paul Brook
    dev->gpio_out[n] = pin;
242 aae9460e Paul Brook
}
243 aae9460e Paul Brook
244 9d07d757 Paul Brook
VLANClientState *qdev_get_vlan_client(DeviceState *dev,
245 cda9046b Mark McLoughlin
                                      NetCanReceive *can_receive,
246 cda9046b Mark McLoughlin
                                      NetReceive *receive,
247 cda9046b Mark McLoughlin
                                      NetReceiveIOV *receive_iov,
248 9d07d757 Paul Brook
                                      NetCleanup *cleanup,
249 9d07d757 Paul Brook
                                      void *opaque)
250 9d07d757 Paul Brook
{
251 9d07d757 Paul Brook
    NICInfo *nd = dev->nd;
252 9d07d757 Paul Brook
    assert(nd);
253 cda9046b Mark McLoughlin
    return qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
254 cda9046b Mark McLoughlin
                                receive, receive_iov, cleanup, opaque);
255 9d07d757 Paul Brook
}
256 9d07d757 Paul Brook
257 9d07d757 Paul Brook
258 9d07d757 Paul Brook
void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
259 9d07d757 Paul Brook
{
260 9d07d757 Paul Brook
    memcpy(macaddr, dev->nd->macaddr, 6);
261 9d07d757 Paul Brook
}
262 9d07d757 Paul Brook
263 aae9460e Paul Brook
static int next_block_unit[IF_COUNT];
264 aae9460e Paul Brook
265 aae9460e Paul Brook
/* Get a block device.  This should only be used for single-drive devices
266 aae9460e Paul Brook
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
267 aae9460e Paul Brook
   appropriate bus.  */
268 aae9460e Paul Brook
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
269 aae9460e Paul Brook
{
270 aae9460e Paul Brook
    int unit = next_block_unit[type]++;
271 aae9460e Paul Brook
    int index;
272 aae9460e Paul Brook
273 aae9460e Paul Brook
    index = drive_get_index(type, 0, unit);
274 aae9460e Paul Brook
    if (index == -1) {
275 aae9460e Paul Brook
        return NULL;
276 aae9460e Paul Brook
    }
277 aae9460e Paul Brook
    return drives_table[index].bdrv;
278 aae9460e Paul Brook
}
279 4d6ae674 Paul Brook
280 02e2da45 Paul Brook
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
281 4d6ae674 Paul Brook
{
282 02e2da45 Paul Brook
    BusState *bus;
283 4d6ae674 Paul Brook
284 02e2da45 Paul Brook
    LIST_FOREACH(bus, &dev->child_bus, sibling) {
285 4d6ae674 Paul Brook
        if (strcmp(name, bus->name) == 0) {
286 02e2da45 Paul Brook
            return bus;
287 4d6ae674 Paul Brook
        }
288 4d6ae674 Paul Brook
    }
289 4d6ae674 Paul Brook
    return NULL;
290 4d6ae674 Paul Brook
}
291 4d6ae674 Paul Brook
292 6f68ecb2 Paul Brook
static int next_scsi_bus;
293 6f68ecb2 Paul Brook
294 6f68ecb2 Paul Brook
/* Create a scsi bus, and attach devices to it.  */
295 6f68ecb2 Paul Brook
/* TODO: Actually create a scsi bus for hotplug to use.  */
296 6f68ecb2 Paul Brook
void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
297 6f68ecb2 Paul Brook
{
298 6f68ecb2 Paul Brook
   int bus = next_scsi_bus++;
299 6f68ecb2 Paul Brook
   int unit;
300 6f68ecb2 Paul Brook
   int index;
301 6f68ecb2 Paul Brook
302 6f68ecb2 Paul Brook
   for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
303 6f68ecb2 Paul Brook
       index = drive_get_index(IF_SCSI, bus, unit);
304 6f68ecb2 Paul Brook
       if (index == -1) {
305 6f68ecb2 Paul Brook
           continue;
306 6f68ecb2 Paul Brook
       }
307 6f68ecb2 Paul Brook
       attach(host, drives_table[index].bdrv, unit);
308 6f68ecb2 Paul Brook
   }
309 6f68ecb2 Paul Brook
}
310 02e2da45 Paul Brook
311 10c4c98a Gerd Hoffmann
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
312 02e2da45 Paul Brook
{
313 02e2da45 Paul Brook
    BusState *bus;
314 02e2da45 Paul Brook
315 10c4c98a Gerd Hoffmann
    bus = qemu_mallocz(info->size);
316 10c4c98a Gerd Hoffmann
    bus->info = info;
317 02e2da45 Paul Brook
    bus->parent = parent;
318 02e2da45 Paul Brook
    bus->name = qemu_strdup(name);
319 02e2da45 Paul Brook
    LIST_INIT(&bus->children);
320 02e2da45 Paul Brook
    if (parent) {
321 02e2da45 Paul Brook
        LIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
322 02e2da45 Paul Brook
    }
323 02e2da45 Paul Brook
    return bus;
324 02e2da45 Paul Brook
}
325 cae4956e Gerd Hoffmann
326 cae4956e Gerd Hoffmann
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
327 cae4956e Gerd Hoffmann
static void qbus_print(Monitor *mon, BusState *bus, int indent);
328 cae4956e Gerd Hoffmann
329 cae4956e Gerd Hoffmann
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
330 cae4956e Gerd Hoffmann
{
331 cae4956e Gerd Hoffmann
    DeviceProperty *prop;
332 cae4956e Gerd Hoffmann
    BusState *child;
333 042f84d0 Gerd Hoffmann
    qdev_printf("dev: %s\n", dev->info->name);
334 cae4956e Gerd Hoffmann
    indent += 2;
335 cae4956e Gerd Hoffmann
    if (dev->num_gpio_in) {
336 cae4956e Gerd Hoffmann
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
337 cae4956e Gerd Hoffmann
    }
338 cae4956e Gerd Hoffmann
    if (dev->num_gpio_out) {
339 cae4956e Gerd Hoffmann
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
340 cae4956e Gerd Hoffmann
    }
341 cae4956e Gerd Hoffmann
    for (prop = dev->props; prop; prop = prop->next) {
342 cae4956e Gerd Hoffmann
        switch (prop->type) {
343 cae4956e Gerd Hoffmann
        case PROP_TYPE_INT:
344 cae4956e Gerd Hoffmann
            qdev_printf("prop-int %s 0x%" PRIx64 "\n", prop->name,
345 cae4956e Gerd Hoffmann
                        prop->value.i);
346 cae4956e Gerd Hoffmann
            break;
347 cae4956e Gerd Hoffmann
        case PROP_TYPE_PTR:
348 cae4956e Gerd Hoffmann
            qdev_printf("prop-ptr %s\n", prop->name);
349 cae4956e Gerd Hoffmann
            break;
350 cae4956e Gerd Hoffmann
        case PROP_TYPE_DEV:
351 cae4956e Gerd Hoffmann
            qdev_printf("prop-dev %s %s\n", prop->name,
352 042f84d0 Gerd Hoffmann
                        ((DeviceState *)prop->value.ptr)->info->name);
353 cae4956e Gerd Hoffmann
            break;
354 cae4956e Gerd Hoffmann
        default:
355 cae4956e Gerd Hoffmann
            qdev_printf("prop-unknown%d %s\n", prop->type, prop->name);
356 cae4956e Gerd Hoffmann
            break;
357 cae4956e Gerd Hoffmann
        }
358 cae4956e Gerd Hoffmann
    }
359 10c4c98a Gerd Hoffmann
    if (dev->parent_bus->info->print_dev)
360 10c4c98a Gerd Hoffmann
        dev->parent_bus->info->print_dev(mon, dev, indent);
361 cae4956e Gerd Hoffmann
    LIST_FOREACH(child, &dev->child_bus, sibling) {
362 cae4956e Gerd Hoffmann
        qbus_print(mon, child, indent);
363 cae4956e Gerd Hoffmann
    }
364 cae4956e Gerd Hoffmann
}
365 cae4956e Gerd Hoffmann
366 cae4956e Gerd Hoffmann
static void qbus_print(Monitor *mon, BusState *bus, int indent)
367 cae4956e Gerd Hoffmann
{
368 cae4956e Gerd Hoffmann
    struct DeviceState *dev;
369 cae4956e Gerd Hoffmann
370 cae4956e Gerd Hoffmann
    qdev_printf("bus: %s\n", bus->name);
371 cae4956e Gerd Hoffmann
    indent += 2;
372 10c4c98a Gerd Hoffmann
    qdev_printf("type %s\n", bus->info->name);
373 cae4956e Gerd Hoffmann
    LIST_FOREACH(dev, &bus->children, sibling) {
374 cae4956e Gerd Hoffmann
        qdev_print(mon, dev, indent);
375 cae4956e Gerd Hoffmann
    }
376 cae4956e Gerd Hoffmann
}
377 cae4956e Gerd Hoffmann
#undef qdev_printf
378 cae4956e Gerd Hoffmann
379 cae4956e Gerd Hoffmann
void do_info_qtree(Monitor *mon)
380 cae4956e Gerd Hoffmann
{
381 cae4956e Gerd Hoffmann
    if (main_system_bus)
382 cae4956e Gerd Hoffmann
        qbus_print(mon, main_system_bus, 0);
383 cae4956e Gerd Hoffmann
}