diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2009-06-05 15:53:17 +0100 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2009-06-05 15:53:17 +0100 |
commit | cae4956e5efcd7898583627ea712923902384c55 (patch) | |
tree | f5e68b7d1c6e01236d3c4372a9ca683f3fa3308a | |
parent | 1431b6a17e6546569e09bcf8fb7773c925658d8f (diff) |
qdev: add monitor command to dump the tree.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Paul Brook <paul@codesourcery.com>
-rw-r--r-- | hw/qdev.c | 73 | ||||
-rw-r--r-- | hw/qdev.h | 5 | ||||
-rw-r--r-- | hw/sysbus.c | 12 | ||||
-rw-r--r-- | monitor.c | 3 |
4 files changed, 93 insertions, 0 deletions
@@ -29,6 +29,7 @@ #include "net.h" #include "qdev.h" #include "sysemu.h" +#include "monitor.h" struct DeviceProperty { const char *name; @@ -337,3 +338,75 @@ BusState *qbus_create(BusType type, size_t size, } return bus; } + +static const char *bus_type_names[] = { + "System", + "PCI", + "SCSI", + "I2C", + "SSI" +}; + +#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__) +static void qbus_print(Monitor *mon, BusState *bus, int indent); + +static void qdev_print(Monitor *mon, DeviceState *dev, int indent) +{ + DeviceProperty *prop; + BusState *child; + qdev_printf("dev: %s\n", dev->type->name); + indent += 2; + if (dev->num_gpio_in) { + qdev_printf("gpio-in %d\n", dev->num_gpio_in); + } + if (dev->num_gpio_out) { + qdev_printf("gpio-out %d\n", dev->num_gpio_out); + } + for (prop = dev->props; prop; prop = prop->next) { + switch (prop->type) { + case PROP_TYPE_INT: + qdev_printf("prop-int %s 0x%" PRIx64 "\n", prop->name, + prop->value.i); + break; + case PROP_TYPE_PTR: + qdev_printf("prop-ptr %s\n", prop->name); + break; + case PROP_TYPE_DEV: + qdev_printf("prop-dev %s %s\n", prop->name, + ((DeviceState *)prop->value.ptr)->type->name); + break; + default: + qdev_printf("prop-unknown%d %s\n", prop->type, prop->name); + break; + } + } + switch (dev->parent_bus->type) { + case BUS_TYPE_SYSTEM: + sysbus_dev_print(mon, dev, indent); + break; + default: + break; + } + LIST_FOREACH(child, &dev->child_bus, sibling) { + qbus_print(mon, child, indent); + } +} + +static void qbus_print(Monitor *mon, BusState *bus, int indent) +{ + struct DeviceState *dev; + + qdev_printf("bus: %s\n", bus->name); + indent += 2; + qdev_printf("type %s\n", bus_type_names[bus->type]); + LIST_FOREACH(dev, &bus->children, sibling) { + qdev_print(mon, dev, indent); + } +} +#undef qdev_printf + +void do_info_qtree(Monitor *mon) +{ + if (main_system_bus) + qbus_print(mon, main_system_bus, 0); +} @@ -117,4 +117,9 @@ BusState *qbus_create(BusType type, size_t size, #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev) +/*** monitor commands ***/ + +void do_info_qtree(Monitor *mon); +void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); + #endif diff --git a/hw/sysbus.c b/hw/sysbus.c index a1843088e3..fbd2ddf394 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -20,6 +20,7 @@ #include "sysbus.h" #include "sysemu.h" +#include "monitor.h" void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) { @@ -150,3 +151,14 @@ DeviceState *sysbus_create_varargs(const char *name, } return dev; } + +void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) +{ + SysBusDevice *s = sysbus_from_qdev(dev); + int i; + + for (i = 0; i < s->num_mmio; i++) { + monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n", + indent, "", s->mmio[i].addr, s->mmio[i].size); + } +} @@ -23,6 +23,7 @@ */ #include <dirent.h> #include "hw/hw.h" +#include "hw/qdev.h" #include "hw/usb.h" #include "hw/pcmcia.h" #include "hw/pc.h" @@ -1854,6 +1855,8 @@ static const mon_cmd_t info_cmds[] = { { "migrate", "", do_info_migrate, "", "show migration status" }, { "balloon", "", do_info_balloon, "", "show balloon information" }, + { "qtree", "", do_info_qtree, + "", "show device tree" }, { NULL, NULL, }, }; |