[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 5/9] hw/misc: Add MMIO test device
From: |
Philippe Mathieu-Daudé |
Subject: |
[RFC PATCH 5/9] hw/misc: Add MMIO test device |
Date: |
Mon, 17 Aug 2020 18:18:49 +0200 |
Add a MMIO test device handy to test QEMU internal devices via MMIO
accesses.
This device is meant to be run by the 'none' machine, thus no CPU
is required.
So far it is only useful to test the interleaver device.
A SRAM region is split into 256B subregions, and these subregions
are mapped at different addresses in an interleaved setup.
All the following (INPUT x OUTPUT) configurations can be tested:
16x8, 32x8, 32x16, 64x8, 64x16 and 64x32.
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
include/hw/misc/testdev.h | 15 ++++
hw/misc/mmio-testdev.c | 146 ++++++++++++++++++++++++++++++++++++++
MAINTAINERS | 2 +
hw/misc/Kconfig | 5 ++
hw/misc/Makefile.objs | 1 +
5 files changed, 169 insertions(+)
create mode 100644 include/hw/misc/testdev.h
create mode 100644 hw/misc/mmio-testdev.c
diff --git a/include/hw/misc/testdev.h b/include/hw/misc/testdev.h
new file mode 100644
index 0000000000..2ff47d2766
--- /dev/null
+++ b/include/hw/misc/testdev.h
@@ -0,0 +1,15 @@
+/*
+ * QEMU MMIO test device
+ *
+ * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MISC_TESTDEV_H
+#define HW_MISC_TESTDEV_H
+
+#define TYPE_MMIO_TESTDEV "mmio-testdev"
+
+#endif
+
diff --git a/hw/misc/mmio-testdev.c b/hw/misc/mmio-testdev.c
new file mode 100644
index 0000000000..3b7a8057b2
--- /dev/null
+++ b/hw/misc/mmio-testdev.c
@@ -0,0 +1,146 @@
+/*
+ * QEMU MMIO test device
+ *
+ * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * This device is mostly used to test QEMU internal MMIO devices.
+ * Accesses using CPU core are not allowed.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "hw/misc/testdev.h"
+#include "hw/misc/interleaver.h"
+
+/*
+ * Device Memory Map:
+ *
+ * offset size description
+ * ---------- ---------- --------------------
+ * 0x00000000 [ 2 KiB] SRAM (8 banks of 256B)
+ * 0x10000000 [ 128 MiB] interleaved-container
+ * 0x11608000 [ 4 KiB] interleaved-16x8 (each device interleaves the sram)
+ * 0x13208000 [ 8 KiB] interleaved-32x8 "
+ * 0x13216000 [ 4 KiB] interleaved-32x16 "
+ * 0x16408000 [ 16 KiB] interleaved-64x8 "
+ * 0x16416000 [ 8 KiB] interleaved-64x16 "
+ * 0x16432000 [ 4 KiB] interleaved-64x32 "
+ * 0x20000000 [ 256 MiB] container
+ *
+ * All gap regions are reserved.
+ */
+
+typedef struct MmioTestDevice {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ MemoryRegion container;
+ MemoryRegion sram;
+ MemoryRegion sram_alias[8];
+ MemoryRegion interleaver_container;
+ MemoryRegion iomem;
+
+ uint64_t base;
+} MmioTestDevice;
+
+#define TESTDEV(obj) \
+ OBJECT_CHECK(MmioTestDevice, (obj), TYPE_MMIO_TESTDEV)
+
+static void mmio_testdev_realize(DeviceState *dev, Error **errp)
+{
+ static const unsigned bhexs[] = {
+ [8] = 0x8, [16] = 0x16, [32] = 0x32, [64] = 0x64,
+ };
+ static const struct {
+ unsigned in, out;
+ const char *typename;
+ } cfg[] = {
+ {16, 8, TYPE_INTERLEAVER_16X8_DEVICE},
+ {32, 8, TYPE_INTERLEAVER_32X8_DEVICE},
+ {32, 16, TYPE_INTERLEAVER_32X16_DEVICE},
+ {64, 8, TYPE_INTERLEAVER_64X8_DEVICE},
+ {64, 16, TYPE_INTERLEAVER_64X16_DEVICE},
+ {64, 32, TYPE_INTERLEAVER_64X32_DEVICE},
+ };
+ MmioTestDevice *s = TESTDEV(dev);
+ DeviceState *interleaver;
+
+ if (s->base == UINT64_MAX) {
+ error_setg(errp, "property 'address' not specified or zero");
+ return;
+ }
+
+ memory_region_init(&s->container, OBJECT(s), "testdev", 0x20000000);
+
+ memory_region_init_ram(&s->sram, OBJECT(s), "testdev-sram",
+ 0x800, &error_fatal);
+ memory_region_add_subregion(&s->container, 0x000000, &s->sram);
+
+ /* interleaved memory */
+ memory_region_init(&s->interleaver_container, OBJECT(s),
+ "interleaver-container", 0x8000000);
+ memory_region_add_subregion(&s->container, 0x10000000,
+ &s->interleaver_container);
+ for (unsigned i = 0; i < 8; i++) {
+ g_autofree char *name = g_strdup_printf("sram-p%u", i);
+ /* Each alias access a 256B region of the SRAM */
+ memory_region_init_alias(&s->sram_alias[i], OBJECT(s), name,
+ &s->sram, i * 0x100, 0x100);
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(cfg); i++) {
+ unsigned count = cfg[i].in / cfg[i].out;
+
+ interleaver = qdev_new(cfg[i].typename);
+ qdev_prop_set_uint64(interleaver, "size", count * 0x100);
+ /* Map 256B SRAM regions on interleaver banks */
+ for (unsigned c = 0; c < count; c++) {
+ g_autofree char *prop_name = g_strdup_printf("mr%u", c);
+ object_property_set_link(OBJECT(interleaver), prop_name,
+ OBJECT(&s->sram_alias[c]), &error_abort);
+ }
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(interleaver), &error_fatal);
+ memory_region_add_subregion(&s->interleaver_container,
+ (bhexs[cfg[i].in] << 20) | (bhexs[cfg[i].out] << 12),
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(interleaver), 0));
+ }
+
+ memory_region_add_subregion(get_system_memory(), s->base, &s->container);
+}
+
+static Property mmio_testdev_properties[] = {
+ DEFINE_PROP_UINT64("address", MmioTestDevice, base, UINT64_MAX),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void mmio_testdev_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = mmio_testdev_realize;
+ dc->user_creatable = true;
+ device_class_set_props(dc, mmio_testdev_properties);
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static const TypeInfo mmio_testdev_info = {
+ .name = TYPE_MMIO_TESTDEV,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(MmioTestDevice),
+ .class_init = mmio_testdev_class_init,
+};
+
+static void mmio_testdev_register_types(void)
+{
+ type_register_static(&mmio_testdev_info);
+}
+
+type_init(mmio_testdev_register_types)
diff --git a/MAINTAINERS b/MAINTAINERS
index 1efce3dd27..f75b8c984a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1966,6 +1966,8 @@ M: Philippe Mathieu-Daudé <f4bug@amsat.org>
S: Maintained
F: include/hw/misc/interleaver.h
F: hw/misc/interleaver.c
+F: hw/misc/mmio-testdev.c
+F: include/hw/misc/testdev.h
Standard VGA
M: Gerd Hoffmann <kraxel@redhat.com>
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 7ed0f4ccc7..5b101abeea 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -30,6 +30,11 @@ config ISA_TESTDEV
default y if TEST_DEVICES
depends on ISA_BUS
+config MMIO_TESTDEV
+ bool
+ default y if TEST_DEVICES
+ depends on INTERLEAVER
+
config PCI_TESTDEV
bool
default y if TEST_DEVICES
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index aa753a847f..b3e7da7177 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -5,6 +5,7 @@ common-obj-$(CONFIG_TMP421) += tmp421.o
common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o
common-obj-$(CONFIG_SGA) += sga.o
common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
+common-obj-$(CONFIG_MMIO_TESTDEV) += mmio-testdev.o
common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
common-obj-$(CONFIG_EDU) += edu.o
common-obj-$(CONFIG_PCA9552) += pca9552.o
--
2.26.2
- [RFC PATCH 0/9] hw/misc: Add support for interleaved memory accesses, Philippe Mathieu-Daudé, 2020/08/17
- [RFC PATCH 2/9] qtest: Add local qtest_mem_as() getter, Philippe Mathieu-Daudé, 2020/08/17
- [RFC PATCH 3/9] qtest: Directly use global address_space_memory when no CPU available, Philippe Mathieu-Daudé, 2020/08/17
- [RFC PATCH 4/9] hw/misc: Add interleaver device to make interleaved memory accesses, Philippe Mathieu-Daudé, 2020/08/17
- [RFC PATCH 1/9] memory: Initialize MemoryRegionOps for RAM memory regions, Philippe Mathieu-Daudé, 2020/08/17
- [RFC PATCH 5/9] hw/misc: Add MMIO test device,
Philippe Mathieu-Daudé <=
- [RFC PATCH 9/9] hw/misc/interleaver: Display subregions in 'info mtree', Philippe Mathieu-Daudé, 2020/08/17
- [RFC PATCH 6/9] hw/core/null-machine: Allow to use the MMIO 'test' device, Philippe Mathieu-Daudé, 2020/08/17
- [RFC PATCH 7/9] tests/qtest: Add generic MMIO tests, Philippe Mathieu-Daudé, 2020/08/17
- [RFC PATCH 8/9] memory: Allow memory region to display its subregions own descriptions, Philippe Mathieu-Daudé, 2020/08/17
- Re: [RFC PATCH 0/9] hw/misc: Add support for interleaved memory accesses, no-reply, 2020/08/17
- Re: [RFC PATCH 0/9] hw/misc: Add support for interleaved memory accesses, Philippe Mathieu-Daudé, 2020/08/22
- Re: [RFC PATCH 0/9] hw/misc: Add support for interleaved memory accesses, Philippe Mathieu-Daudé, 2020/08/22