On 22/8/25 11:24, CJ Chen wrote:
From: Tomoyuki Hirose <hrstmyk8...@gmail.com>
This commit adds a qtest for accessing various memory regions. The
qtest checks the correctness of handling the access to memory regions
by using 'memaccess-testdev'.
Signed-off-by: CJ Chen <cjc...@igel.co.jp>
Co-developed-by: CJ Chen <cjc...@igel.co.jp>
Reported-by: Tomoyuki Hirose <hrstmyk8...@gmail.com>
---
tests/qtest/memaccess-test.c | 597 +++++++++++++++++++++++++++++++++++
tests/qtest/meson.build | 9 +
2 files changed, 606 insertions(+)
create mode 100644 tests/qtest/memaccess-test.c
diff --git a/tests/qtest/memaccess-test.c b/tests/qtest/memaccess-test.c
new file mode 100644
index 0000000000..7e90028ea0
--- /dev/null
+++ b/tests/qtest/memaccess-test.c
@@ -0,0 +1,597 @@
+/*
+ * QEMU memory region access test
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Author: Tomoyuki HIROSE <hrstmyk8...@gmail.com>
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+
+#include "hw/misc/memaccess-testdev.h"
+
+static const char *arch = "";
+static const hwaddr base = 0x200000000;
+
+struct arch2cpu {
+ const char *arch;
+ const char *cpu_model;
+};
+
+static struct arch2cpu cpus_map[] = {
+ /* tested targets list */
+ { "arm", "cortex-a15" },
+ { "aarch64", "cortex-a57" },
+ { "avr", "avr6-avr-cpu" },
+ { "x86_64", "qemu64,apic-id=0" },
+ { "i386", "qemu32,apic-id=0" },
+ { "alpha", "ev67" },
+ { "cris", "crisv32" },
+ { "m68k", "m5206" },
+ { "microblaze", "any" },
+ { "microblazeel", "any" },
+ { "mips", "4Kc" },
+ { "mipsel", "I7200" },
+ { "mips64", "20Kc" },
+ { "mips64el", "I6500" },
+ { "or1k", "or1200" },
+ { "ppc", "604" },
+ { "ppc64", "power8e_v2.1" },
+ { "s390x", "qemu" },
+ { "sh4", "sh7750r" },
+ { "sh4eb", "sh7751r" },
+ { "sparc", "LEON2" },
+ { "sparc64", "Fujitsu Sparc64" },
+ { "tricore", "tc1796" },
+ { "xtensa", "dc233c" },
+ { "xtensaeb", "fsf" },
+ { "hppa", "hppa" },
+ { "riscv64", "rv64" },
+ { "riscv32", "rv32" },
+ { "rx", "rx62n" },
+ { "loongarch64", "la464" },
IIUC CPUs are not involved in the test path. The only difference
is the binary endianness. So we are testing 2 distinct code path
duplicated as ARRAY_SIZE(cpus_map) = 31 times.
Let's run the tests with a pair of common targets and save 29
pointless tests:
... cpus_map[] = {
/* One little endian and one big endian target */
{ "x86_64", "qemu64,apic-id=0" },
{ "s390x", "qemu" }
}
+};
+
+static const char *get_cpu_model_by_arch(const char *arch)
+{
+ for (int i = 0; i < ARRAY_SIZE(cpus_map); i++) {
+ if (!strcmp(arch, cpus_map[i].arch)) {
+ return cpus_map[i].cpu_model;
+ }
+ }
+ return NULL;
+}
+
+static QTestState *create_memaccess_qtest(void)
+{
+ QTestState *qts;
+
+ qts = qtest_initf("-machine none -cpu \"%s\" "
+ "-device memaccess-testdev,address=0x%" PRIx64,
+ get_cpu_model_by_arch(arch), base);
+ return qts;
+}
+DEFINE_test_memaccess(little, LITTLE, b, B, valid, VALID)
+DEFINE_test_memaccess(little, LITTLE, w, W, valid, VALID)
+DEFINE_test_memaccess(little, LITTLE, l, L, valid, VALID)
+DEFINE_test_memaccess(little, LITTLE, q, Q, valid, VALID)
+DEFINE_test_memaccess(little, LITTLE, b, B, invalid, INVALID)
+DEFINE_test_memaccess(little, LITTLE, w, W, invalid, INVALID)
+DEFINE_test_memaccess(little, LITTLE, l, L, invalid, INVALID)
+DEFINE_test_memaccess(little, LITTLE, q, Q, invalid, INVALID)
+DEFINE_test_memaccess(big, BIG, b, B, valid, VALID)
+DEFINE_test_memaccess(big, BIG, w, W, valid, VALID)
+DEFINE_test_memaccess(big, BIG, l, L, valid, VALID)
+DEFINE_test_memaccess(big, BIG, q, Q, valid, VALID)
+DEFINE_test_memaccess(big, BIG, b, B, invalid, INVALID)
+DEFINE_test_memaccess(big, BIG, w, W, invalid, INVALID)
+DEFINE_test_memaccess(big, BIG, l, L, invalid, INVALID)
+DEFINE_test_memaccess(big, BIG, q, Q, invalid, INVALID)
+
+#undef DEFINE_test_memaccess
+
+static struct {
+ const char *name;
+ void (*test)(void);
+} tests[] = {
+ {"little_b_valid", test_memaccess_little_b_valid},
+ {"little_w_valid", test_memaccess_little_w_valid},
+ {"little_l_valid", test_memaccess_little_l_valid},
+ {"little_q_valid", test_memaccess_little_q_valid},
+ {"little_b_invalid", test_memaccess_little_b_invalid},
+ {"little_w_invalid", test_memaccess_little_w_invalid},
+ {"little_l_invalid", test_memaccess_little_l_invalid},
+ {"little_q_invalid", test_memaccess_little_q_invalid},
+ {"big_b_valid", test_memaccess_big_b_valid},
+ {"big_w_valid", test_memaccess_big_w_valid},
+ {"big_l_valid", test_memaccess_big_l_valid},
+ {"big_q_valid", test_memaccess_big_q_valid},
+ {"big_b_invalid", test_memaccess_big_b_invalid},
+ {"big_w_invalid", test_memaccess_big_w_invalid},
+ {"big_l_invalid", test_memaccess_big_l_invalid},
+ {"big_q_invalid", test_memaccess_big_q_invalid},
+};
BTW this reminds me of
https://lore.kernel.org/qemu-devel/20200817161853.593247-8-f4...@amsat.org/
;)