sysbus: Add dynamic sysbus device search
authorAlexander Graf <agraf@suse.de>
Wed, 24 Sep 2014 11:06:57 +0000 (13:06 +0200)
committerAlexander Graf <agraf@suse.de>
Tue, 4 Nov 2014 22:26:14 +0000 (23:26 +0100)
Sysbus devices can be spawned by C code or dynamically via the command line.
In the latter case, we need to be able to find the dynamically created devices
to do things with them.

This patch adds a search helper that makes it easy to look for dynamically
spawned sysbus devices.

Signed-off-by: Alexander Graf <agraf@suse.de>
hw/core/sysbus.c
include/hw/sysbus.h

index e55c3c1d6d379ded1672b0b076bb6d86588c9b29..19437e65f745339e6fc2e2decf89046f15c0e453 100644 (file)
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 static char *sysbus_get_fw_dev_path(DeviceState *dev);
 
+typedef struct SysBusFind {
+    void *opaque;
+    FindSysbusDeviceFunc *func;
+} SysBusFind;
+
+/* Run func() for every sysbus device, traverse the tree for everything else */
+static int find_sysbus_device(Object *obj, void *opaque)
+{
+    SysBusFind *find = opaque;
+    Object *dev;
+    SysBusDevice *sbdev;
+
+    dev = object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE);
+    sbdev = (SysBusDevice *)dev;
+
+    if (!sbdev) {
+        /* Container, traverse it for children */
+        return object_child_foreach(obj, find_sysbus_device, opaque);
+    }
+
+    find->func(sbdev, find->opaque);
+
+    return 0;
+}
+
+/*
+ * Loop through all dynamically created sysbus devices and call
+ * func() for each instance.
+ */
+void foreach_dynamic_sysbus_device(FindSysbusDeviceFunc *func, void *opaque)
+{
+    Object *container;
+    SysBusFind find = {
+        .func = func,
+        .opaque = opaque,
+    };
+
+    /* Loop through all sysbus devices that were spawened outside the machine */
+    container = container_get(qdev_get_machine(), "/peripheral");
+    find_sysbus_device(container, &find);
+    container = container_get(qdev_get_machine(), "/peripheral-anon");
+    find_sysbus_device(container, &find);
+}
+
+
 static void system_bus_class_init(ObjectClass *klass, void *data)
 {
     BusClass *k = BUS_CLASS(klass);
index 9fb1782d7b9b7cd2a182c0cc657e12489504051c..80529ffed8b5469684526e52ef7e99ce6f4ee2a3 100644 (file)
@@ -57,6 +57,8 @@ struct SysBusDevice {
     pio_addr_t pio[QDEV_MAX_PIO];
 };
 
+typedef int FindSysbusDeviceFunc(SysBusDevice *sbdev, void *opaque);
+
 void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory);
 MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
@@ -72,6 +74,9 @@ void sysbus_add_io(SysBusDevice *dev, hwaddr addr,
                    MemoryRegion *mem);
 MemoryRegion *sysbus_address_space(SysBusDevice *dev);
 
+/* Call func for every dynamically created sysbus device in the system */
+void foreach_dynamic_sysbus_device(FindSysbusDeviceFunc *func, void *opaque);
+
 /* Legacy helper function for creating devices.  */
 DeviceState *sysbus_create_varargs(const char *name,
                                  hwaddr addr, ...);