qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 7/9] tests/qtest: Add generic MMIO tests


From: Philippe Mathieu-Daudé
Subject: [RFC PATCH 7/9] tests/qtest: Add generic MMIO tests
Date: Mon, 17 Aug 2020 18:18:51 +0200

Add generic MMIO tests (which don't need any particular knowledge
about the architecture) and can be run without any CPU (using the
'none' machine).

Start testing the interleaved memory accesses.

Cross-endianess is not tested (host and target must have the same
endianess).

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 tests/qtest/mmio-test.c      | 146 +++++++++++++++++++++++++++++++++++
 MAINTAINERS                  |   1 +
 tests/qtest/Makefile.include |   1 +
 3 files changed, 148 insertions(+)
 create mode 100644 tests/qtest/mmio-test.c

diff --git a/tests/qtest/mmio-test.c b/tests/qtest/mmio-test.c
new file mode 100644
index 0000000000..7a31eb8e9d
--- /dev/null
+++ b/tests/qtest/mmio-test.c
@@ -0,0 +1,146 @@
+/*
+ * QTest testcases for generic MMIO accesses
+ *
+ * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqtest.h"
+#include "qemu/bswap.h"
+
+/* Must fit in arch address space */
+static const uint64_t base = 0x20000000ul;
+
+static bool is_cross_endian(QTestState *qts)
+{
+    bool te = qtest_big_endian(qts);
+#ifdef HOST_WORDS_BIGENDIAN
+    te = !te;
+#endif
+    return te;
+}
+
+static QTestState *create_interleaver_qtest(void)
+{
+    QTestState *qts;
+
+    qts = qtest_initf("-M none -device mmio-testdev,address=0x%" PRIx64, base);
+    if (is_cross_endian(qts)) {
+        g_test_skip("Skipping on cross-endian targets");
+        qtest_quit(qts);
+        return NULL;
+    }
+    return qts;
+}
+
+static void test_interleaver_rd32x8a(void)
+{
+    QTestState *qts = create_interleaver_qtest();
+
+    if (!qts) {
+        return;
+    }
+
+    /* write sram directly */
+    qtest_writeb(qts, base + 0x000, 0x10);
+    qtest_writeb(qts, base + 0x100, 0x32);
+    qtest_writeb(qts, base + 0x200, 0x54);
+    qtest_writeb(qts, base + 0x300, 0x76);
+    /* read via interleaver */
+    g_assert_cmphex(qtest_readl(qts, base + 0x13208000 + 0x00), ==, 
0x76543210);
+    qtest_quit(qts);
+}
+
+static void test_interleaver_rd32x8b(void)
+{
+    QTestState *qts = create_interleaver_qtest();
+
+    if (!qts) {
+        return;
+    }
+
+    /* write sram directly */
+    qtest_writeb(qts, base + 0x003, 0x10);
+    qtest_writeb(qts, base + 0x103, 0x32);
+    qtest_writeb(qts, base + 0x203, 0x54);
+    qtest_writeb(qts, base + 0x303, 0x76);
+    /* read via interleaver */
+    g_assert_cmphex(qtest_readl(qts, base + 0x13208000 + 0x0c), ==, 
0x76543210);
+    qtest_quit(qts);
+}
+
+static void test_interleaver_rd32x16(void)
+{
+    QTestState *qts = create_interleaver_qtest();
+
+    if (!qts) {
+        return;
+    }
+
+    /* write sram directly */
+    qtest_writew(qts, base + 0x002, 0x3210);
+    qtest_writew(qts, base + 0x102, 0x7654);
+    /* read via interleaver */
+    g_assert_cmphex(qtest_readl(qts, base + 0x13216000 + 0x04), ==, 
0x76543210);
+    qtest_quit(qts);
+}
+
+static void test_interleaver_wr32x16(void)
+{
+    QTestState *qts = create_interleaver_qtest();
+
+    if (!qts) {
+        return;
+    }
+
+    /* write via interleaver */
+    qtest_writel(qts, base + 0x13216000 + 0x04, 0x76543210);
+    /* read sram directly */
+    g_assert_cmphex(qtest_readw(qts, base + 0x002), ==, 0x3210);
+    g_assert_cmphex(qtest_readw(qts, base + 0x102), ==, 0x7654);
+    qtest_quit(qts);
+}
+
+static void test_interleaver_wr64x8(void)
+{
+    QTestState *qts = create_interleaver_qtest();
+
+    if (!qts) {
+        return;
+    }
+
+    /* write via interleaver */
+    qtest_writeq(qts, base + 0x16408000 + 0x08, 0x9876543210);
+    /* read sram directly */
+    g_assert_cmphex(qtest_readb(qts, base + 0x001), ==, 0x10);
+    g_assert_cmphex(qtest_readb(qts, base + 0x101), ==, 0x32);
+    g_assert_cmphex(qtest_readb(qts, base + 0x401), ==, 0x98);
+    qtest_quit(qts);
+}
+
+static struct {
+    const char *name;
+    void (*test)(void);
+} tests[] = {
+    {"interleaver/rd32x8a", test_interleaver_rd32x8a},
+    {"interleaver/rd32x8b", test_interleaver_rd32x8b},
+    {"interleaver/rd32x16", test_interleaver_rd32x16},
+    {"interleaver/wr32x16", test_interleaver_wr32x16},
+    {"interleaver/wr64x8",  test_interleaver_wr64x8},
+};
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    for (size_t i = 0; i < ARRAY_SIZE(tests); i++) {
+        g_autofree gchar *path = g_strdup_printf("mmio/%s",
+                                                 tests[i].name);
+        qtest_add_func(path, tests[i].test);
+    }
+
+    return g_test_run();
+}
diff --git a/MAINTAINERS b/MAINTAINERS
index f75b8c984a..93efef1b87 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1968,6 +1968,7 @@ F: include/hw/misc/interleaver.h
 F: hw/misc/interleaver.c
 F: hw/misc/mmio-testdev.c
 F: include/hw/misc/testdev.h
+F: tests/qtest/mmio-test.c
 
 Standard VGA
 M: Gerd Hoffmann <kraxel@redhat.com>
diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index b0204e44f2..29dbeb5d05 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -9,6 +9,7 @@ check-qtest-generic-y += qmp-cmd-test
 check-qtest-generic-y += qom-test
 check-qtest-generic-$(CONFIG_MODULES) += modules-test
 check-qtest-generic-y += test-hmp
+check-qtest-generic-$(CONFIG_MMIO_TESTDEV) += mmio-test
 
 check-qtest-pci-$(CONFIG_RTL8139_PCI) += rtl8139-test
 check-qtest-pci-$(CONFIG_VGA) += display-vga-test
-- 
2.26.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]