[RFC PATCH 3/3] tests/qtest: add K230 SRAM qtest
Jian Cai <[email protected]> Mon, 20 Jul 2026 15:45:45 +0800
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Add qtest coverage for the K230 SRAM device model. Six test cases verify the MMIO region: - address_mapped: write/read at SRAM base address - read_write_consistency: 4-offset write-read verification - byte_access: byte-level R/W and 32-bit LE composition - initial_zeroed: SRAM is zero-initialized on startup - unmapped_beyond_range: out-of-range access does not crash QEMU - write_and_verify_range: 64 KiB step full-range verification Signed-off-by: Jian Cai <[email protected]> --- MAINTAINERS | 2 + tests/qtest/k230-sram-test.c | 161 +++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 3 +- 3 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 tests/qtest/k230-sram-test.c diff --git a/MAINTAINERS b/MAINTAINERS index 3567563ba6..eebe8b3def 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1827,9 +1827,11 @@ F: docs/system/riscv/k230.rst F: hw/riscv/k230.c F: hw/riscv/k230_sram.c F: include/hw/riscv/k230_sram.h +F: tests/qtest/k230-sram-test.c F: hw/riscv/k230_sram.c F: include/hw/riscv/k230_sram.h F: tests/qtest/k230-sram-test.c +F: tests/qtest/k230-sram-test.c F: hw/watchdog/k230_wdt.c F: include/hw/riscv/k230.h F: include/hw/watchdog/k230_wdt.h diff --git a/tests/qtest/k230-sram-test.c b/tests/qtest/k230-sram-test.c new file mode 100644 index 0000000000..b00e1173c5 --- /dev/null +++ b/tests/qtest/k230-sram-test.c @@ -0,0 +1,161 @@ +/* + * QTest testcase for K230 SRAM + * + * K230 Technical Reference Manual V0.3.1 (2024-11-18): + * https://github.com/revyos/external-docs/blob/master/K230/en-us/K230_Technical_Reference_Manual_V0.3.1_20241118.pdf + * + * The K230 shared SRAM is 2 MB at 0x80200000, accessed directly via the + * AXI bus. It has no software-visible controller registers, so the tests + * focus on MMIO read/write consistency across the full range. + * + * Copyright (c) 2026 Jian Cai <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "libqtest.h" + +/* K230 SRAM MMIO base address and size */ +#define K230_SRAM_BASE 0x80200000 +#define K230_SRAM_SIZE (2 * 1024 * 1024) /* 2 MiB */ + +static void test_address_mapped(void) +{ + QTestState *qts = qtest_init("-machine k230"); + + /* Write a known pattern at the start of SRAM */ + const uint32_t pattern = 0xDEADBEEF; + qtest_writel(qts, K230_SRAM_BASE, pattern); + + /* Read back and verify */ + uint32_t value = qtest_readl(qts, K230_SRAM_BASE); + g_assert_cmphex(value, ==, pattern); + + qtest_quit(qts); +} + +static void test_read_write_consistency(void) +{ + QTestState *qts = qtest_init("-machine k230"); + + /* Write and read back a sequence of patterns at different offsets */ + static const struct { + const char *desc; + uint32_t offset; + uint32_t pattern; + } test_cases[] = { + { "start", 0x000000, 0x12345678 }, + { "mid", 0x100000, 0x9ABCDEF0 }, /* 1 MiB */ + { "end-4", K230_SRAM_SIZE - 4, 0xCAFEBABE }, + { "aligned-256", 0x000100, 0x55AA55AA }, + }; + + for (size_t i = 0; i < G_N_ELEMENTS(test_cases); i++) { + uint32_t addr = K230_SRAM_BASE + test_cases[i].offset; + qtest_writel(qts, addr, test_cases[i].pattern); + + uint32_t value = qtest_readl(qts, addr); + g_assert_cmphex(value, ==, test_cases[i].pattern); + } + + qtest_quit(qts); +} + +static void test_byte_access(void) +{ + QTestState *qts = qtest_init("-machine k230"); + + /* Verify byte-level access */ + uint32_t base = K230_SRAM_BASE; + + qtest_writeb(qts, base + 0, 0xAA); + qtest_writeb(qts, base + 1, 0xBB); + qtest_writeb(qts, base + 2, 0xCC); + qtest_writeb(qts, base + 3, 0xDD); + + uint8_t b0 = qtest_readb(qts, base + 0); + uint8_t b1 = qtest_readb(qts, base + 1); + uint8_t b2 = qtest_readb(qts, base + 2); + uint8_t b3 = qtest_readb(qts, base + 3); + + g_assert_cmphex(b0, ==, 0xAA); + g_assert_cmphex(b1, ==, 0xBB); + g_assert_cmphex(b2, ==, 0xCC); + g_assert_cmphex(b3, ==, 0xDD); + + /* Verify 32-bit read sees the combined value (LE) */ + uint32_t word = qtest_readl(qts, base); + g_assert_cmphex(word, ==, 0xDDCCBBAA); + + qtest_quit(qts); +} + +static void test_initial_zeroed(void) +{ + QTestState *qts = qtest_init("-machine k230"); + + /* SRAM should be zero-initialized by memory_region_init_ram */ + uint32_t value = qtest_readl(qts, K230_SRAM_BASE); + g_assert_cmphex(value, ==, 0); + + value = qtest_readl(qts, K230_SRAM_BASE + K230_SRAM_SIZE - 4); + g_assert_cmphex(value, ==, 0); + + qtest_quit(qts); +} + +static void test_unmapped_beyond_range(void) +{ + QTestState *qts = qtest_init("-machine k230"); + + /* + * Writes beyond the SRAM region should not crash QEMU. + * The exact behaviour (unassigned access / abort) is platform-specific; + * we just verify the write does not take the process down. + */ + qtest_writel(qts, K230_SRAM_BASE + K230_SRAM_SIZE, 0xBADF00D); + qtest_readl(qts, K230_SRAM_BASE + K230_SRAM_SIZE); + + qtest_quit(qts); +} + +static void test_write_and_verify_range(void) +{ + QTestState *qts = qtest_init("-machine k230"); + + /* + * Write a walking-bit pattern across the full 2 MiB range in + * 64 KiB steps, verifying each word writes correctly. + */ + for (uint32_t offset = 0; offset < K230_SRAM_SIZE; offset += 0x10000) { + uint32_t addr = K230_SRAM_BASE + offset; + uint32_t pattern = offset | 0x3; /* keep bottom bits set */ + + qtest_writel(qts, addr, pattern); + uint32_t value = qtest_readl(qts, addr); + g_assert_cmphex(value, ==, pattern); + } + + qtest_quit(qts); +} + +int main(int argc, char *argv[]) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/k230-sram/address_mapped", + test_address_mapped); + qtest_add_func("/k230-sram/read_write_consistency", + test_read_write_consistency); + qtest_add_func("/k230-sram/byte_access", + test_byte_access); + qtest_add_func("/k230-sram/initial_zeroed", + test_initial_zeroed); + qtest_add_func("/k230-sram/unmapped_beyond_range", + test_unmapped_beyond_range); + qtest_add_func("/k230-sram/write_and_verify_range", + test_write_and_verify_range); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 56ff860e21..cf64539acb 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -297,7 +297,8 @@ qtests_riscv64 = ['riscv-csr-test'] + \ (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and config_all_devices.has_key('CONFIG_RISCV_IOMMU') ? ['iommu-riscv-test'] : []) + \ - (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test'] : []) + (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test', + 'k230-sram-test'] : []) qtests_hexagon = ['boot-serial-test'] -- 2.43.0