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: Tomoyuki HIROSE <tomoyuki.hir...@igel.co.jp> --- tests/qtest/memaccess-test.c | 598 +++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 9 + 2 files changed, 607 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..4a6d2089ad --- /dev/null +++ b/tests/qtest/memaccess-test.c @@ -0,0 +1,598 @@ +/* + * QEMU memory region access test + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2024 IGEL Co., Ltd. + * Author: Tomoyuki HIROSE <tomoyuki.hir...@igel.co.jp> + */ + +#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" }, +}; + +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; +} + +static void little_b_valid(QTestState *qts, uint64_t offset) +{ + qtest_writeb(qts, base + offset + 0, 0x00); + qtest_writeb(qts, base + offset + 1, 0x11); + qtest_writeb(qts, base + offset + 2, 0x22); + qtest_writeb(qts, base + offset + 3, 0x33); + qtest_writeb(qts, base + offset + 4, 0x44); + qtest_writeb(qts, base + offset + 5, 0x55); + qtest_writeb(qts, base + offset + 6, 0x66); + qtest_writeb(qts, base + offset + 7, 0x77); + g_assert_cmphex(qtest_readb(qts, base + offset + 0), ==, 0x00); + g_assert_cmphex(qtest_readb(qts, base + offset + 1), ==, 0x11); + g_assert_cmphex(qtest_readb(qts, base + offset + 2), ==, 0x22); + g_assert_cmphex(qtest_readb(qts, base + offset + 3), ==, 0x33); + g_assert_cmphex(qtest_readb(qts, base + offset + 4), ==, 0x44); + g_assert_cmphex(qtest_readb(qts, base + offset + 5), ==, 0x55); + g_assert_cmphex(qtest_readb(qts, base + offset + 6), ==, 0x66); + g_assert_cmphex(qtest_readb(qts, base + offset + 7), ==, 0x77); +} + +static void little_b_invalid(QTestState *qts, uint64_t offset) +{ + qtest_writeb(qts, base + offset + 0, 0x00); + qtest_writeb(qts, base + offset + 1, 0x11); + qtest_writeb(qts, base + offset + 2, 0x22); + qtest_writeb(qts, base + offset + 3, 0x33); + qtest_writeb(qts, base + offset + 4, 0x44); + qtest_writeb(qts, base + offset + 5, 0x55); + qtest_writeb(qts, base + offset + 6, 0x66); + qtest_writeb(qts, base + offset + 7, 0x77); + g_assert_cmphex(qtest_readb(qts, base + offset + 0), ==, 0x00); + g_assert_cmphex(qtest_readb(qts, base + offset + 1), ==, 0x11); + g_assert_cmphex(qtest_readb(qts, base + offset + 2), ==, 0x22); + g_assert_cmphex(qtest_readb(qts, base + offset + 3), ==, 0x33); + g_assert_cmphex(qtest_readb(qts, base + offset + 4), ==, 0x44); + g_assert_cmphex(qtest_readb(qts, base + offset + 5), ==, 0x55); + g_assert_cmphex(qtest_readb(qts, base + offset + 6), ==, 0x66); + g_assert_cmphex(qtest_readb(qts, base + offset + 7), ==, 0x77); +} + +static void little_w_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 1, 0x3322); + qtest_writew(qts, base + offset + 2, 0x5544); + qtest_writew(qts, base + offset + 3, 0x7766); + qtest_writew(qts, base + offset + 4, 0x9988); + qtest_writew(qts, base + offset + 5, 0xbbaa); + qtest_writew(qts, base + offset + 6, 0xddcc); + qtest_writew(qts, base + offset + 7, 0xffee); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1133); + g_assert_cmphex(qtest_readw(qts, base + offset + 1), ==, 0x3355); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x5577); + g_assert_cmphex(qtest_readw(qts, base + offset + 3), ==, 0x7799); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x99bb); + g_assert_cmphex(qtest_readw(qts, base + offset + 5), ==, 0xbbdd); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0xddff); + g_assert_cmphex(qtest_readw(qts, base + offset + 7), ==, 0xffee); + } else { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 1, 0x3322); + qtest_writew(qts, base + offset + 2, 0x5544); + qtest_writew(qts, base + offset + 3, 0x7766); + qtest_writew(qts, base + offset + 4, 0x9988); + qtest_writew(qts, base + offset + 5, 0xbbaa); + qtest_writew(qts, base + offset + 6, 0xddcc); + qtest_writew(qts, base + offset + 7, 0xffee); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x2200); + g_assert_cmphex(qtest_readw(qts, base + offset + 1), ==, 0x4422); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x6644); + g_assert_cmphex(qtest_readw(qts, base + offset + 3), ==, 0x8866); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0xaa88); + g_assert_cmphex(qtest_readw(qts, base + offset + 5), ==, 0xccaa); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0xeecc); + g_assert_cmphex(qtest_readw(qts, base + offset + 7), ==, 0xffee); + } +} + +static void little_w_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 2, 0x3322); + qtest_writew(qts, base + offset + 4, 0x5544); + qtest_writew(qts, base + offset + 6, 0x7766); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1100); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x3322); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x5544); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0x7766); + } else { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 2, 0x3322); + qtest_writew(qts, base + offset + 4, 0x5544); + qtest_writew(qts, base + offset + 6, 0x7766); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1100); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x3322); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x5544); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0x7766); + } +} + +static void little_l_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 1, 0x77665544); + qtest_writel(qts, base + offset + 2, 0xbbaa9988); + qtest_writel(qts, base + offset + 3, 0xffeeddcc); + qtest_writel(qts, base + offset + 4, 0x01234567); + qtest_writel(qts, base + offset + 5, 0x89abcdef); + qtest_writel(qts, base + offset + 6, 0xfedcba98); + qtest_writel(qts, base + offset + 7, 0x76543210); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x3377bbff); + g_assert_cmphex(qtest_readl(qts, base + offset + 1), ==, 0x77bbff01); + g_assert_cmphex(qtest_readl(qts, base + offset + 2), ==, 0xbbff0189); + g_assert_cmphex(qtest_readl(qts, base + offset + 3), ==, 0xff0189fe); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x0189fe76); + g_assert_cmphex(qtest_readl(qts, base + offset + 5), ==, 0x89fe7654); + g_assert_cmphex(qtest_readl(qts, base + offset + 6), ==, 0xfe765432); + g_assert_cmphex(qtest_readl(qts, base + offset + 7), ==, 0x76543210); + } else { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 1, 0x77665544); + qtest_writel(qts, base + offset + 2, 0xbbaa9988); + qtest_writel(qts, base + offset + 3, 0xffeeddcc); + qtest_writel(qts, base + offset + 4, 0x01234567); + qtest_writel(qts, base + offset + 5, 0x89abcdef); + qtest_writel(qts, base + offset + 6, 0xfedcba98); + qtest_writel(qts, base + offset + 7, 0x76543210); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0xcc884400); + g_assert_cmphex(qtest_readl(qts, base + offset + 1), ==, 0x67cc8844); + g_assert_cmphex(qtest_readl(qts, base + offset + 2), ==, 0xef67cc88); + g_assert_cmphex(qtest_readl(qts, base + offset + 3), ==, 0x98ef67cc); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x1098ef67); + g_assert_cmphex(qtest_readl(qts, base + offset + 5), ==, 0x321098ef); + g_assert_cmphex(qtest_readl(qts, base + offset + 6), ==, 0x54321098); + g_assert_cmphex(qtest_readl(qts, base + offset + 7), ==, 0x76543210); + } +} + +static void little_l_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 4, 0x77665544); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x33221100); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x77665544); + } else { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 4, 0x77665544); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x33221100); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x77665544); + } +} + +static void little_q_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + qtest_writeq(qts, base + offset + 1, 0xffeeddccbbaa9988); + qtest_writeq(qts, base + offset + 2, 0xfedcba9876543210); + qtest_writeq(qts, base + offset + 3, 0x0123456789abcdef); + qtest_writeq(qts, base + offset + 4, 0xdeadbeefdeadbeef); + qtest_writeq(qts, base + offset + 5, 0xcafebabecafebabe); + qtest_writeq(qts, base + offset + 6, 0xbeefcafebeefcafe); + qtest_writeq(qts, base + offset + 7, 0xfacefeedfacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x77fffe01decabefa); + g_assert_cmphex(qtest_readq(qts, base + offset + 1), ==, + 0xfffe01decabeface); + g_assert_cmphex(qtest_readq(qts, base + offset + 2), ==, + 0xfe01decabefacefe); + g_assert_cmphex(qtest_readq(qts, base + offset + 3), ==, + 0x01decabefacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 4), ==, + 0xdecabefacefeedfa); + g_assert_cmphex(qtest_readq(qts, base + offset + 5), ==, + 0xcabefacefeedface); + g_assert_cmphex(qtest_readq(qts, base + offset + 6), ==, + 0xbefacefeedfacefe); + g_assert_cmphex(qtest_readq(qts, base + offset + 7), ==, + 0xfacefeedfacefeed); + } else { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + qtest_writeq(qts, base + offset + 1, 0xffeeddccbbaa9988); + qtest_writeq(qts, base + offset + 2, 0xfedcba9876543210); + qtest_writeq(qts, base + offset + 3, 0x0123456789abcdef); + qtest_writeq(qts, base + offset + 4, 0xdeadbeefdeadbeef); + qtest_writeq(qts, base + offset + 5, 0xcafebabecafebabe); + qtest_writeq(qts, base + offset + 6, 0xbeefcafebeefcafe); + qtest_writeq(qts, base + offset + 7, 0xfacefeedfacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0xedfebeefef108800); + g_assert_cmphex(qtest_readq(qts, base + offset + 1), ==, + 0xfeedfebeefef1088); + g_assert_cmphex(qtest_readq(qts, base + offset + 2), ==, + 0xcefeedfebeefef10); + g_assert_cmphex(qtest_readq(qts, base + offset + 3), ==, + 0xfacefeedfebeefef); + g_assert_cmphex(qtest_readq(qts, base + offset + 4), ==, + 0xedfacefeedfebeef); + g_assert_cmphex(qtest_readq(qts, base + offset + 5), ==, + 0xfeedfacefeedfebe); + g_assert_cmphex(qtest_readq(qts, base + offset + 6), ==, + 0xcefeedfacefeedfe); + g_assert_cmphex(qtest_readq(qts, base + offset + 7), ==, + 0xfacefeedfacefeed); + } +} + +static void little_q_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x7766554433221100); + } else { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x7766554433221100); + } +} + +static void big_b_valid(QTestState *qts, uint64_t offset) +{ + qtest_writeb(qts, base + offset + 0, 0x00); + qtest_writeb(qts, base + offset + 1, 0x11); + qtest_writeb(qts, base + offset + 2, 0x22); + qtest_writeb(qts, base + offset + 3, 0x33); + qtest_writeb(qts, base + offset + 4, 0x44); + qtest_writeb(qts, base + offset + 5, 0x55); + qtest_writeb(qts, base + offset + 6, 0x66); + qtest_writeb(qts, base + offset + 7, 0x77); + g_assert_cmphex(qtest_readb(qts, base + offset + 0), ==, 0x00); + g_assert_cmphex(qtest_readb(qts, base + offset + 1), ==, 0x11); + g_assert_cmphex(qtest_readb(qts, base + offset + 2), ==, 0x22); + g_assert_cmphex(qtest_readb(qts, base + offset + 3), ==, 0x33); + g_assert_cmphex(qtest_readb(qts, base + offset + 4), ==, 0x44); + g_assert_cmphex(qtest_readb(qts, base + offset + 5), ==, 0x55); + g_assert_cmphex(qtest_readb(qts, base + offset + 6), ==, 0x66); + g_assert_cmphex(qtest_readb(qts, base + offset + 7), ==, 0x77); +} + +static void big_b_invalid(QTestState *qts, uint64_t offset) +{ + qtest_writeb(qts, base + offset + 0, 0x00); + qtest_writeb(qts, base + offset + 1, 0x11); + qtest_writeb(qts, base + offset + 2, 0x22); + qtest_writeb(qts, base + offset + 3, 0x33); + qtest_writeb(qts, base + offset + 4, 0x44); + qtest_writeb(qts, base + offset + 5, 0x55); + qtest_writeb(qts, base + offset + 6, 0x66); + qtest_writeb(qts, base + offset + 7, 0x77); + g_assert_cmphex(qtest_readb(qts, base + offset + 0), ==, 0x00); + g_assert_cmphex(qtest_readb(qts, base + offset + 1), ==, 0x11); + g_assert_cmphex(qtest_readb(qts, base + offset + 2), ==, 0x22); + g_assert_cmphex(qtest_readb(qts, base + offset + 3), ==, 0x33); + g_assert_cmphex(qtest_readb(qts, base + offset + 4), ==, 0x44); + g_assert_cmphex(qtest_readb(qts, base + offset + 5), ==, 0x55); + g_assert_cmphex(qtest_readb(qts, base + offset + 6), ==, 0x66); + g_assert_cmphex(qtest_readb(qts, base + offset + 7), ==, 0x77); +} + +static void big_w_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 1, 0x3322); + qtest_writew(qts, base + offset + 2, 0x5544); + qtest_writew(qts, base + offset + 3, 0x7766); + qtest_writew(qts, base + offset + 4, 0x9988); + qtest_writew(qts, base + offset + 5, 0xbbaa); + qtest_writew(qts, base + offset + 6, 0xddcc); + qtest_writew(qts, base + offset + 7, 0xffee); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1133); + g_assert_cmphex(qtest_readw(qts, base + offset + 1), ==, 0x3355); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x5577); + g_assert_cmphex(qtest_readw(qts, base + offset + 3), ==, 0x7799); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x99bb); + g_assert_cmphex(qtest_readw(qts, base + offset + 5), ==, 0xbbdd); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0xddff); + g_assert_cmphex(qtest_readw(qts, base + offset + 7), ==, 0xffee); + } else { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 1, 0x3322); + qtest_writew(qts, base + offset + 2, 0x5544); + qtest_writew(qts, base + offset + 3, 0x7766); + qtest_writew(qts, base + offset + 4, 0x9988); + qtest_writew(qts, base + offset + 5, 0xbbaa); + qtest_writew(qts, base + offset + 6, 0xddcc); + qtest_writew(qts, base + offset + 7, 0xffee); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x2200); + g_assert_cmphex(qtest_readw(qts, base + offset + 1), ==, 0x4422); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x6644); + g_assert_cmphex(qtest_readw(qts, base + offset + 3), ==, 0x8866); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0xaa88); + g_assert_cmphex(qtest_readw(qts, base + offset + 5), ==, 0xccaa); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0xeecc); + g_assert_cmphex(qtest_readw(qts, base + offset + 7), ==, 0xffee); + } +} + +static void big_w_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 2, 0x3322); + qtest_writew(qts, base + offset + 4, 0x5544); + qtest_writew(qts, base + offset + 6, 0x7766); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1100); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x3322); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x5544); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0x7766); + } else { + qtest_writew(qts, base + offset + 0, 0x1100); + qtest_writew(qts, base + offset + 2, 0x3322); + qtest_writew(qts, base + offset + 4, 0x5544); + qtest_writew(qts, base + offset + 6, 0x7766); + g_assert_cmphex(qtest_readw(qts, base + offset + 0), ==, 0x1100); + g_assert_cmphex(qtest_readw(qts, base + offset + 2), ==, 0x3322); + g_assert_cmphex(qtest_readw(qts, base + offset + 4), ==, 0x5544); + g_assert_cmphex(qtest_readw(qts, base + offset + 6), ==, 0x7766); + } +} + +static void big_l_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 1, 0x77665544); + qtest_writel(qts, base + offset + 2, 0xbbaa9988); + qtest_writel(qts, base + offset + 3, 0xffeeddcc); + qtest_writel(qts, base + offset + 4, 0x01234567); + qtest_writel(qts, base + offset + 5, 0x89abcdef); + qtest_writel(qts, base + offset + 6, 0xfedcba98); + qtest_writel(qts, base + offset + 7, 0x76543210); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x3377bbff); + g_assert_cmphex(qtest_readl(qts, base + offset + 1), ==, 0x77bbff01); + g_assert_cmphex(qtest_readl(qts, base + offset + 2), ==, 0xbbff0189); + g_assert_cmphex(qtest_readl(qts, base + offset + 3), ==, 0xff0189fe); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x0189fe76); + g_assert_cmphex(qtest_readl(qts, base + offset + 5), ==, 0x89fe7654); + g_assert_cmphex(qtest_readl(qts, base + offset + 6), ==, 0xfe765432); + g_assert_cmphex(qtest_readl(qts, base + offset + 7), ==, 0x76543210); + } else { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 1, 0x77665544); + qtest_writel(qts, base + offset + 2, 0xbbaa9988); + qtest_writel(qts, base + offset + 3, 0xffeeddcc); + qtest_writel(qts, base + offset + 4, 0x01234567); + qtest_writel(qts, base + offset + 5, 0x89abcdef); + qtest_writel(qts, base + offset + 6, 0xfedcba98); + qtest_writel(qts, base + offset + 7, 0x76543210); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0xcc884400); + g_assert_cmphex(qtest_readl(qts, base + offset + 1), ==, 0x67cc8844); + g_assert_cmphex(qtest_readl(qts, base + offset + 2), ==, 0xef67cc88); + g_assert_cmphex(qtest_readl(qts, base + offset + 3), ==, 0x98ef67cc); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x1098ef67); + g_assert_cmphex(qtest_readl(qts, base + offset + 5), ==, 0x321098ef); + g_assert_cmphex(qtest_readl(qts, base + offset + 6), ==, 0x54321098); + g_assert_cmphex(qtest_readl(qts, base + offset + 7), ==, 0x76543210); + } +} + +static void big_l_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 4, 0x77665544); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x33221100); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x77665544); + } else { + qtest_writel(qts, base + offset + 0, 0x33221100); + qtest_writel(qts, base + offset + 4, 0x77665544); + g_assert_cmphex(qtest_readl(qts, base + offset + 0), ==, 0x33221100); + g_assert_cmphex(qtest_readl(qts, base + offset + 4), ==, 0x77665544); + } +} + +static void big_q_valid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + qtest_writeq(qts, base + offset + 1, 0xffeeddccbbaa9988); + qtest_writeq(qts, base + offset + 2, 0xfedcba9876543210); + qtest_writeq(qts, base + offset + 3, 0x0123456789abcdef); + qtest_writeq(qts, base + offset + 4, 0xdeadbeefdeadbeef); + qtest_writeq(qts, base + offset + 5, 0xcafebabecafebabe); + qtest_writeq(qts, base + offset + 6, 0xbeefcafebeefcafe); + qtest_writeq(qts, base + offset + 7, 0xfacefeedfacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x77fffe01decabefa); + g_assert_cmphex(qtest_readq(qts, base + offset + 1), ==, + 0xfffe01decabeface); + g_assert_cmphex(qtest_readq(qts, base + offset + 2), ==, + 0xfe01decabefacefe); + g_assert_cmphex(qtest_readq(qts, base + offset + 3), ==, + 0x01decabefacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 4), ==, + 0xdecabefacefeedfa); + g_assert_cmphex(qtest_readq(qts, base + offset + 5), ==, + 0xcabefacefeedface); + g_assert_cmphex(qtest_readq(qts, base + offset + 6), ==, + 0xbefacefeedfacefe); + g_assert_cmphex(qtest_readq(qts, base + offset + 7), ==, + 0xfacefeedfacefeed); + } else { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + qtest_writeq(qts, base + offset + 1, 0xffeeddccbbaa9988); + qtest_writeq(qts, base + offset + 2, 0xfedcba9876543210); + qtest_writeq(qts, base + offset + 3, 0x0123456789abcdef); + qtest_writeq(qts, base + offset + 4, 0xdeadbeefdeadbeef); + qtest_writeq(qts, base + offset + 5, 0xcafebabecafebabe); + qtest_writeq(qts, base + offset + 6, 0xbeefcafebeefcafe); + qtest_writeq(qts, base + offset + 7, 0xfacefeedfacefeed); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0xedfebeefef108800); + g_assert_cmphex(qtest_readq(qts, base + offset + 1), ==, + 0xfeedfebeefef1088); + g_assert_cmphex(qtest_readq(qts, base + offset + 2), ==, + 0xcefeedfebeefef10); + g_assert_cmphex(qtest_readq(qts, base + offset + 3), ==, + 0xfacefeedfebeefef); + g_assert_cmphex(qtest_readq(qts, base + offset + 4), ==, + 0xedfacefeedfebeef); + g_assert_cmphex(qtest_readq(qts, base + offset + 5), ==, + 0xfeedfacefeedfebe); + g_assert_cmphex(qtest_readq(qts, base + offset + 6), ==, + 0xcefeedfacefeedfe); + g_assert_cmphex(qtest_readq(qts, base + offset + 7), ==, + 0xfacefeedfacefeed); + } +} + +static void big_q_invalid(QTestState *qts, hwaddr offset) +{ + if (qtest_big_endian(qts)) { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x7766554433221100); + } else { + qtest_writeq(qts, base + offset + 0, 0x7766554433221100); + g_assert_cmphex(qtest_readq(qts, base + offset + 0), ==, + 0x7766554433221100); + } +} + +#define DEFINE_test_memaccess(e, e_u, w, w_u, v, v_u) \ + static void \ + test_memaccess_##e##_##w##_##v(void) \ + { \ + QTestState *qts; \ + qts = create_memaccess_qtest(); \ + if (!qts) { \ + return; \ + } \ + \ + for (size_t i = OFF_IDX_OPS_LIST_##e_u##_##w_u##_##v_u; \ + i < OFF_IDX_OPS_LIST_##e_u##_##w_u##_##v_u + \ + N_OPS_LIST_##e_u##_##w_u##_##v_u; \ + i++) { \ + e##_##w##_##v(qts, MEMACCESS_TESTDEV_REGION_SIZE * i); \ + } \ + \ + qtest_quit(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}, +}; + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + arch = qtest_get_arch(); + + for (int i = 0; i < ARRAY_SIZE(tests); i++) { + g_autofree gchar *path = g_strdup_printf("memaccess/%s", tests[i].name); + qtest_add_func(path, tests[i].test); + } + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index aa93e98418..49271cbc3f 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -93,6 +93,7 @@ qtests_i386 = \ (config_all_devices.has_key('CONFIG_SB16') ? ['fuzz-sb16-test'] : []) + \ (config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \ (config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (host_os != 'windows' and \ config_all_devices.has_key('CONFIG_ACPI_ERST') ? ['erst-test'] : []) + \ (config_all_devices.has_key('CONFIG_PCIE_PORT') and \ @@ -136,6 +137,7 @@ qtests_x86_64 = qtests_i386 qtests_alpha = ['boot-serial-test'] + \ qtests_filter + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : []) qtests_avr = [ 'boot-serial-test' ] @@ -158,6 +160,7 @@ qtests_microblazeel = qtests_microblaze qtests_mips = \ qtests_filter + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ (config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : []) @@ -169,6 +172,7 @@ qtests_ppc = \ qtests_filter + \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ (config_all_devices.has_key('CONFIG_M48T59') ? ['m48t59-test'] : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (config_all_accel.has_key('CONFIG_TCG') ? ['prom-env-test'] : []) + \ (config_all_accel.has_key('CONFIG_TCG') ? ['boot-serial-test'] : []) + \ ['boot-order-test'] @@ -195,6 +199,7 @@ qtests_sparc = ['prom-env-test', 'm48t59-test', 'boot-serial-test'] + \ qtests_sparc64 = \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ qtests_filter + \ ['prom-env-test', 'boot-serial-test'] @@ -240,6 +245,7 @@ qtests_arm = \ (config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? ['aspeed_fsi-test'] : []) + \ (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') and config_all_devices.has_key('CONFIG_DM163')? ['dm163-test'] : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ ['arm-cpu-features', 'boot-serial-test'] @@ -254,6 +260,7 @@ qtests_aarch64 = \ (config_all_accel.has_key('CONFIG_TCG') and \ config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \ (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed64 : []) + \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ ['arm-cpu-features', 'numa-test', 'boot-serial-test', @@ -269,9 +276,11 @@ qtests_s390x = \ 'migration-test'] qtests_riscv32 = \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (config_all_devices.has_key('CONFIG_SIFIVE_E_AON') ? ['sifive-e-aon-watchdog-test'] : []) qtests_riscv64 = \ + (config_all_devices.has_key('CONFIG_MEMACCESS_TESTDEV') ? ['memaccess-test'] : []) + \ (unpack_edk2_blobs ? ['bios-tables-test'] : []) qos_test_ss = ss.source_set() -- 2.43.0