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 | 29 | #include "net.h" |
| 30 | 30 | #include "qdev.h" |
| 31 | 31 | #include "sysemu.h" |
| 32 | +#include "monitor.h" | |
| 32 | 33 | |
| 33 | 34 | struct DeviceProperty { |
| 34 | 35 | const char *name; |
| ... | ... | @@ -337,3 +338,75 @@ BusState *qbus_create(BusType type, size_t size, |
| 337 | 338 | } |
| 338 | 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 | 117 | |
| 118 | 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 | 125 | #endif | ... | ... |
hw/sysbus.c
| ... | ... | @@ -20,6 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | #include "sysbus.h" |
| 22 | 22 | #include "sysemu.h" |
| 23 | +#include "monitor.h" | |
| 23 | 24 | |
| 24 | 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 | 151 | } |
| 151 | 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 | 23 | */ |
| 24 | 24 | #include <dirent.h> |
| 25 | 25 | #include "hw/hw.h" |
| 26 | +#include "hw/qdev.h" | |
| 26 | 27 | #include "hw/usb.h" |
| 27 | 28 | #include "hw/pcmcia.h" |
| 28 | 29 | #include "hw/pc.h" |
| ... | ... | @@ -1854,6 +1855,8 @@ static const mon_cmd_t info_cmds[] = { |
| 1854 | 1855 | { "migrate", "", do_info_migrate, "", "show migration status" }, |
| 1855 | 1856 | { "balloon", "", do_info_balloon, |
| 1856 | 1857 | "", "show balloon information" }, |
| 1858 | + { "qtree", "", do_info_qtree, | |
| 1859 | + "", "show device tree" }, | |
| 1857 | 1860 | { NULL, NULL, }, |
| 1858 | 1861 | }; |
| 1859 | 1862 | ... | ... |