This device can be used to create a memory wrapped into a sysbus device. This device has one property 'readonly' which allows to choose between a ram or a rom.
The purpose for this device is to be used with qapi command device_add. Signed-off-by: Damien Hedde <damien.he...@greensocs.com> --- include/hw/mem/sysbus-memory.h | 28 ++++++++++++ hw/mem/sysbus-memory.c | 80 ++++++++++++++++++++++++++++++++++ hw/mem/meson.build | 2 + 3 files changed, 110 insertions(+) create mode 100644 include/hw/mem/sysbus-memory.h create mode 100644 hw/mem/sysbus-memory.c diff --git a/include/hw/mem/sysbus-memory.h b/include/hw/mem/sysbus-memory.h new file mode 100644 index 0000000000..5c596f8b4f --- /dev/null +++ b/include/hw/mem/sysbus-memory.h @@ -0,0 +1,28 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * SysBusDevice Memory + * + * Copyright (c) 2021 Greensocs + */ + +#ifndef HW_SYSBUS_MEMORY_H +#define HW_SYSBUS_MEMORY_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_SYSBUS_MEMORY "sysbus-memory" +OBJECT_DECLARE_SIMPLE_TYPE(SysBusMemoryState, SYSBUS_MEMORY) + +struct SysBusMemoryState { + /* <private> */ + SysBusDevice parent_obj; + uint64_t size; + bool readonly; + + /* <public> */ + MemoryRegion mem; +}; + +#endif /* HW_SYSBUS_MEMORY_H */ diff --git a/hw/mem/sysbus-memory.c b/hw/mem/sysbus-memory.c new file mode 100644 index 0000000000..f1ad7ba7ec --- /dev/null +++ b/hw/mem/sysbus-memory.c @@ -0,0 +1,80 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * SysBusDevice Memory + * + * Copyright (c) 2021 Greensocs + */ + +#include "qemu/osdep.h" +#include "hw/mem/sysbus-memory.h" +#include "hw/qdev-properties.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qapi/error.h" + +static Property sysbus_memory_properties[] = { + DEFINE_PROP_UINT64("size", SysBusMemoryState, size, 0), + DEFINE_PROP_BOOL("readonly", SysBusMemoryState, readonly, false), + DEFINE_PROP_END_OF_LIST(), +}; + +static void sysbus_memory_realize(DeviceState *dev, Error **errp) +{ + SysBusMemoryState *s = SYSBUS_MEMORY(dev); + gchar *name; + + if (!s->size) { + error_setg(errp, "'size' must be non-zero."); + return; + } + + /* + * We impose having an id (which is unique) because we need to generate + * a unique name for the memory region. + * memory_region_init_ram/rom() will abort() (in qemu_ram_set_idstr() + * function if 2 system-memory devices are created with the same name + * for the memory region). + */ + if (!dev->id) { + error_setg(errp, "system-memory device must have an id."); + return; + } + name = g_strdup_printf("%s.region", dev->id); + + if (s->readonly) { + memory_region_init_rom(&s->mem, OBJECT(dev), name, s->size, errp); + } else { + memory_region_init_ram(&s->mem, OBJECT(dev), name, s->size, errp); + } + + g_free(name); + if (*errp) { + return; + } + + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mem); +} + +static void sysbus_memory_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->user_creatable = true; + dc->realize = sysbus_memory_realize; + device_class_set_props(dc, sysbus_memory_properties); +} + +static const TypeInfo sysbus_memory_info = { + .name = TYPE_SYSBUS_MEMORY, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(SysBusMemoryState), + .class_init = sysbus_memory_class_init, +}; + +static void sysbus_memory_register_types(void) +{ + type_register_static(&sysbus_memory_info); +} + +type_init(sysbus_memory_register_types) diff --git a/hw/mem/meson.build b/hw/mem/meson.build index 82f86d117e..04c74e12f2 100644 --- a/hw/mem/meson.build +++ b/hw/mem/meson.build @@ -7,3 +7,5 @@ mem_ss.add(when: 'CONFIG_NVDIMM', if_true: files('nvdimm.c')) softmmu_ss.add_all(when: 'CONFIG_MEM_DEVICE', if_true: mem_ss) softmmu_ss.add(when: 'CONFIG_SPARSE_MEM', if_true: files('sparse-mem.c')) + +softmmu_ss.add(files('sysbus-memory.c')) -- 2.35.1