Commit cae4956e5efcd7898583627ea712923902384c55
Committed by
Paul Brook
1 parent
1431b6a1
qdev: add monitor command to dump the tree.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Paul Brook <paul@codesourcery.com>
Showing
4 changed files
with
93 additions
and
0 deletions
hw/qdev.c
@@ -29,6 +29,7 @@ | @@ -29,6 +29,7 @@ | ||
29 | #include "net.h" | 29 | #include "net.h" |
30 | #include "qdev.h" | 30 | #include "qdev.h" |
31 | #include "sysemu.h" | 31 | #include "sysemu.h" |
32 | +#include "monitor.h" | ||
32 | 33 | ||
33 | struct DeviceProperty { | 34 | struct DeviceProperty { |
34 | const char *name; | 35 | const char *name; |
@@ -337,3 +338,75 @@ BusState *qbus_create(BusType type, size_t size, | @@ -337,3 +338,75 @@ BusState *qbus_create(BusType type, size_t size, | ||
337 | } | 338 | } |
338 | return bus; | 339 | return bus; |
339 | } | 340 | } |
341 | + | ||
342 | +static const char *bus_type_names[] = { | ||
343 | + "System", | ||
344 | + "PCI", | ||
345 | + "SCSI", | ||
346 | + "I2C", | ||
347 | + "SSI" | ||
348 | +}; | ||
349 | + | ||
350 | +#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__) | ||
351 | +static void qbus_print(Monitor *mon, BusState *bus, int indent); | ||
352 | + | ||
353 | +static void qdev_print(Monitor *mon, DeviceState *dev, int indent) | ||
354 | +{ | ||
355 | + DeviceProperty *prop; | ||
356 | + BusState *child; | ||
357 | + qdev_printf("dev: %s\n", dev->type->name); | ||
358 | + indent += 2; | ||
359 | + if (dev->num_gpio_in) { | ||
360 | + qdev_printf("gpio-in %d\n", dev->num_gpio_in); | ||
361 | + } | ||
362 | + if (dev->num_gpio_out) { | ||
363 | + qdev_printf("gpio-out %d\n", dev->num_gpio_out); | ||
364 | + } | ||
365 | + for (prop = dev->props; prop; prop = prop->next) { | ||
366 | + switch (prop->type) { | ||
367 | + case PROP_TYPE_INT: | ||
368 | + qdev_printf("prop-int %s 0x%" PRIx64 "\n", prop->name, | ||
369 | + prop->value.i); | ||
370 | + break; | ||
371 | + case PROP_TYPE_PTR: | ||
372 | + qdev_printf("prop-ptr %s\n", prop->name); | ||
373 | + break; | ||
374 | + case PROP_TYPE_DEV: | ||
375 | + qdev_printf("prop-dev %s %s\n", prop->name, | ||
376 | + ((DeviceState *)prop->value.ptr)->type->name); | ||
377 | + break; | ||
378 | + default: | ||
379 | + qdev_printf("prop-unknown%d %s\n", prop->type, prop->name); | ||
380 | + break; | ||
381 | + } | ||
382 | + } | ||
383 | + switch (dev->parent_bus->type) { | ||
384 | + case BUS_TYPE_SYSTEM: | ||
385 | + sysbus_dev_print(mon, dev, indent); | ||
386 | + break; | ||
387 | + default: | ||
388 | + break; | ||
389 | + } | ||
390 | + LIST_FOREACH(child, &dev->child_bus, sibling) { | ||
391 | + qbus_print(mon, child, indent); | ||
392 | + } | ||
393 | +} | ||
394 | + | ||
395 | +static void qbus_print(Monitor *mon, BusState *bus, int indent) | ||
396 | +{ | ||
397 | + struct DeviceState *dev; | ||
398 | + | ||
399 | + qdev_printf("bus: %s\n", bus->name); | ||
400 | + indent += 2; | ||
401 | + qdev_printf("type %s\n", bus_type_names[bus->type]); | ||
402 | + LIST_FOREACH(dev, &bus->children, sibling) { | ||
403 | + qdev_print(mon, dev, indent); | ||
404 | + } | ||
405 | +} | ||
406 | +#undef qdev_printf | ||
407 | + | ||
408 | +void do_info_qtree(Monitor *mon) | ||
409 | +{ | ||
410 | + if (main_system_bus) | ||
411 | + qbus_print(mon, main_system_bus, 0); | ||
412 | +} |
hw/qdev.h
@@ -117,4 +117,9 @@ BusState *qbus_create(BusType type, size_t size, | @@ -117,4 +117,9 @@ BusState *qbus_create(BusType type, size_t size, | ||
117 | 117 | ||
118 | #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev) | 118 | #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev) |
119 | 119 | ||
120 | +/*** monitor commands ***/ | ||
121 | + | ||
122 | +void do_info_qtree(Monitor *mon); | ||
123 | +void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); | ||
124 | + | ||
120 | #endif | 125 | #endif |
hw/sysbus.c
@@ -20,6 +20,7 @@ | @@ -20,6 +20,7 @@ | ||
20 | 20 | ||
21 | #include "sysbus.h" | 21 | #include "sysbus.h" |
22 | #include "sysemu.h" | 22 | #include "sysemu.h" |
23 | +#include "monitor.h" | ||
23 | 24 | ||
24 | void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) | 25 | void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) |
25 | { | 26 | { |
@@ -150,3 +151,14 @@ DeviceState *sysbus_create_varargs(const char *name, | @@ -150,3 +151,14 @@ DeviceState *sysbus_create_varargs(const char *name, | ||
150 | } | 151 | } |
151 | return dev; | 152 | return dev; |
152 | } | 153 | } |
154 | + | ||
155 | +void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) | ||
156 | +{ | ||
157 | + SysBusDevice *s = sysbus_from_qdev(dev); | ||
158 | + int i; | ||
159 | + | ||
160 | + for (i = 0; i < s->num_mmio; i++) { | ||
161 | + monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n", | ||
162 | + indent, "", s->mmio[i].addr, s->mmio[i].size); | ||
163 | + } | ||
164 | +} |
monitor.c
@@ -23,6 +23,7 @@ | @@ -23,6 +23,7 @@ | ||
23 | */ | 23 | */ |
24 | #include <dirent.h> | 24 | #include <dirent.h> |
25 | #include "hw/hw.h" | 25 | #include "hw/hw.h" |
26 | +#include "hw/qdev.h" | ||
26 | #include "hw/usb.h" | 27 | #include "hw/usb.h" |
27 | #include "hw/pcmcia.h" | 28 | #include "hw/pcmcia.h" |
28 | #include "hw/pc.h" | 29 | #include "hw/pc.h" |
@@ -1854,6 +1855,8 @@ static const mon_cmd_t info_cmds[] = { | @@ -1854,6 +1855,8 @@ static const mon_cmd_t info_cmds[] = { | ||
1854 | { "migrate", "", do_info_migrate, "", "show migration status" }, | 1855 | { "migrate", "", do_info_migrate, "", "show migration status" }, |
1855 | { "balloon", "", do_info_balloon, | 1856 | { "balloon", "", do_info_balloon, |
1856 | "", "show balloon information" }, | 1857 | "", "show balloon information" }, |
1858 | + { "qtree", "", do_info_qtree, | ||
1859 | + "", "show device tree" }, | ||
1857 | { NULL, NULL, }, | 1860 | { NULL, NULL, }, |
1858 | }; | 1861 | }; |
1859 | 1862 |