From: Jamin Lin <[email protected]>

Several boards and SoCs create many unimplemented devices. Each of them
uses its own structure and helper to describe and map these devices.

Add an UnimplementedDeviceConfig structure and a
create_unimplemented_devices() helper. The helper creates an
unimplemented device for each entry of a table, adds it as a QOM child
of the parent object, and maps it in a memory region container with
the given priority. The table is terminated by an empty entry.

Suggested-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Jamin Lin <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Tested-by: Philippe Mathieu-Daudé <[email protected]>
Reviewed-by: Cédric Le Goater <[email protected]>
Link: 
https://lore.kernel.org/qemu-devel/[email protected]
Signed-off-by: Cédric Le Goater <[email protected]>
---
 include/hw/misc/unimp.h | 21 +++++++++++++++++++++
 hw/misc/unimp.c         | 20 ++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h
index 77a5077511f2..073575159d60 100644
--- a/include/hw/misc/unimp.h
+++ b/include/hw/misc/unimp.h
@@ -25,6 +25,27 @@ struct UnimplementedDeviceState {
     uint64_t size;
 };
 
+typedef struct UnimplementedDeviceConfig {
+    const char *qom_name;
+    const char *region_name;
+    uint64_t offset;
+    uint64_t size;
+    int priority;
+} UnimplementedDeviceConfig;
+
+/**
+ * create_unimplemented_devices:
+ * @parentobj: the parent object
+ * @container: a #MemoryRegion within which @addr is a relative address
+ * @devconfigs: NULL terminated array of #UnimplementedDeviceConfig
+ *
+ * For each entries in @devconfigs, create a TYPE_UNIMPLEMENTED_DEVICE
+ * and mmap it in @container at UnimplementedDeviceConfig::offset.
+ * @container is expected to be a QOM child of @parentobj.
+ */
+void create_unimplemented_devices(Object *parentobj, MemoryRegion *container,
+                                  const UnimplementedDeviceConfig *devconfigs);
+
 /**
  * create_unimplemented_device: create and map a dummy device
  * @name: name of the device for debug logging
diff --git a/hw/misc/unimp.c b/hw/misc/unimp.c
index 521b84bf20bf..4c8dcbdff336 100644
--- a/hw/misc/unimp.c
+++ b/hw/misc/unimp.c
@@ -96,3 +96,23 @@ static void unimp_register_types(void)
 }
 
 type_init(unimp_register_types)
+
+void create_unimplemented_devices(Object *parentobj, MemoryRegion *container,
+                                  const UnimplementedDeviceConfig *devconfigs)
+{
+    const UnimplementedDeviceConfig *cfg;
+
+    for (cfg = devconfigs; cfg->qom_name; cfg++) {
+        DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
+        SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+        object_property_add_child(parentobj, cfg->qom_name, OBJECT(dev));
+        qdev_prop_set_string(dev, "name", cfg->region_name);
+        qdev_prop_set_uint64(dev, "size", cfg->size);
+        sysbus_realize_and_unref(sbd, &error_fatal);
+
+        memory_region_add_subregion_overlap(container, cfg->offset,
+                                            sysbus_mmio_get_region(sbd, 0),
+                                            cfg->priority);
+    }
+}
-- 
2.56.0


Reply via email to