aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2009-06-05 15:53:17 +0100
committerPaul Brook <paul@codesourcery.com>2009-06-05 15:53:17 +0100
commitcae4956e5efcd7898583627ea712923902384c55 (patch)
treef5e68b7d1c6e01236d3c4372a9ca683f3fa3308a /hw
parent1431b6a17e6546569e09bcf8fb7773c925658d8f (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>
Diffstat (limited to 'hw')
-rw-r--r--hw/qdev.c73
-rw-r--r--hw/qdev.h5
-rw-r--r--hw/sysbus.c12
3 files changed, 90 insertions, 0 deletions
diff --git a/hw/qdev.c b/hw/qdev.c
index a7025da9a7..1023c6c37a 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -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);
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 5de0573fdb..7291805b46 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -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);
+ }
+}