On 15/2/24 15:10, Alex Bennée wrote:
This is an experimental patch to allow the creation of unimp regions
from the command line. I'm not sure we would ever merge it as
generally unimp regions are created by the machine definition and
adding your own regions into existing device spaces is likely to break
things pretty badly.

However what I was looking for was a simple way to test that a Xen XFT
test was accessing and trapping where I thought it was without hacking
up the machine models themselves. It allows the addition of unimp
regions to specific address spaces as in the future we shouldn't rely
on sysbus being the default but it's pretty clunky as you need to
intuit the full QOM path of the region, e.g.:

   /qemu-system-aarch64 -machine fby35 --display none \
     -serial mon:stdio -d unimp \
     --device 
dummy-device,name=dummy1,offset=0x10001000,size=0x1000,x-address-space="/machine/unattached/fsi.opb[0]"

Then running info mtree -f shows:

   ...
   FlatView #15
    AS "fsi.opb", root: fsi.opb
    Root memory region: fsi.opb
     0000000010001000-0000000010001fff (prio 0, i/o): dummy1
     0000000080000000-000000008fffffff (prio 0, i/o): fsi.master
     00000000a0000000-00000000a00003ff (prio 0, i/o): cfam.config
     00000000a0000400-00000000a00007ff (prio 0, i/o): cfam @0000000000000400
     00000000a0000800-00000000a0000bff (prio 0, i/o): fsi.slave
     00000000a0000c00-00000000a0000fff (prio 0, i/o): fsi.scratchpad
     00000000a0001000-00000000a01fffff (prio 0, i/o): cfam @0000000000001000

No need to review this RFC unless you particularly think this would be
useful to develop further.

Some devices are only useful for QEMU hardness test suite,
but still are very useful in-tree.

https://lore.kernel.org/qemu-devel/20200817161853.593247-6-f4...@amsat.org/

Signed-off-by: Alex Bennée <alex.ben...@linaro.org>
Cc: Manos Pitsidianakis <manos.pitsidiana...@linaro.org>
Cc: Philippe Mathieu-Daudé <phi...@linaro.org>
---
  hw/misc/dummy.c     | 97 +++++++++++++++++++++++++++++++++++++++++++++
  hw/misc/meson.build |  2 +-
  2 files changed, 98 insertions(+), 1 deletion(-)
  create mode 100644 hw/misc/dummy.c

diff --git a/hw/misc/dummy.c b/hw/misc/dummy.c
new file mode 100644
index 00000000000..701c3468951
--- /dev/null
+++ b/hw/misc/dummy.c
@@ -0,0 +1,97 @@
+/*
+ * user creatable dummy device wrapper
+ *
+ * This is a simple wrapper around the unimp device
+ *
+ * Copyright (c) 2024 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "exec/address-spaces.h"
+#include "hw/misc/unimp.h"
+
+#define TYPE_DUMMY_DEVICE "dummy-device"
+
+OBJECT_DECLARE_SIMPLE_TYPE(DummyDeviceState, DUMMY_DEVICE)
+
+struct DummyDeviceState {
+    DeviceState parent_obj;
+
+    DeviceState *unimp;
+
+    MemoryRegion *mr;
+
+    char *name;
+    char *as_name;
+    uint64_t offset;
+    uint64_t size;
+};
+
+static void dummy_realize(DeviceState *dev, Error **errp)
+{
+    DummyDeviceState *s = DUMMY_DEVICE(dev);
+
+    if (s->size == 0) {
+        error_setg(errp, "property 'size' not specified or zero");
+        return;
+    }
+
+    if (s->name == NULL) {
+        error_setg(errp, "property 'name' not specified");
+        return;
+    }
+
+    if (s->as_name == NULL) {
+        s->mr = get_system_memory();
+    } else {
+        bool ambiguous = false;
+        /* this needs to be a full path. e.g. /machine/unattached/foo[0] */
+        Object *obj = object_resolve_path_type(s->as_name, TYPE_MEMORY_REGION, 
&ambiguous);

OMG yet another attempt of device which automatically map itself in
its REALIZE()...

+        if (!obj || ambiguous) {
+            error_setg(errp, "Unable to find %s to locate region", s->as_name);
+            return;
+        }
+        s->mr = MEMORY_REGION(obj);
+    }
+
+    /*
+     * While this is a test device we don't want to make it too easy
+     * to shoot yourself in the foot.
+     */
+    s->unimp = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
+    qdev_prop_set_string(s->unimp, "name", s->name);
+    qdev_prop_set_uint64(s->unimp, "size", s->size);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(s->unimp), &error_fatal);
+
+    /* Now lets map it to memory */
+    memory_region_add_subregion_overlap(s->mr, s->offset, 
&UNIMPLEMENTED_DEVICE(s->unimp)->iomem, 0);

... here!

+}
+
+static Property dummy_properties[] = {
+    DEFINE_PROP_UINT64("offset", DummyDeviceState, offset, 0),
+    DEFINE_PROP_UINT64("size", DummyDeviceState, size, 0),
+    DEFINE_PROP_STRING("name", DummyDeviceState, name),
+    DEFINE_PROP_STRING("x-address-space", DummyDeviceState, as_name),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void dummy_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = dummy_realize;
+    device_class_set_props(dc, dummy_properties);
+}
+
+static const TypeInfo dummy_devices[]  = {
+    {
+        .name = TYPE_DUMMY_DEVICE,
+        .parent = TYPE_DEVICE,
+        .instance_size = sizeof(DummyDeviceState),
+        .class_init = dummy_class_init,
+    }
+};
+
+DEFINE_TYPES(dummy_devices)
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index e4ef1da5a53..309314e2398 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -5,7 +5,7 @@ system_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: 
files('debugexit.c'))
  system_ss.add(when: 'CONFIG_ISA_TESTDEV', if_true: files('pc-testdev.c'))
  system_ss.add(when: 'CONFIG_PCA9552', if_true: files('pca9552.c'))
  system_ss.add(when: 'CONFIG_PCI_TESTDEV', if_true: files('pci-testdev.c'))
-system_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c'))
+system_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c', 'dummy.c'))
  system_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c'))
  system_ss.add(when: 'CONFIG_LED', if_true: files('led.c'))
  system_ss.add(when: 'CONFIG_PVPANIC_COMMON', if_true: files('pvpanic.c'))


Reply via email to