MAINTAINERS | 2 ++ target/riscv/tcg/csr.c | 6 +++- tests/tcg/meson.build | 1 + tests/tcg/riscv32/meson.build | 5 +++ tests/tcg/riscv32/system/meson.build | 38 +++++++++++++++++++++ tests/tcg/riscv32/test-jvt-warl.S | 49 ++++++++++++++++++++++++++++ tests/tcg/riscv64/system/meson.build | 7 ++++ tests/tcg/riscv64/test-jvt-warl.S | 49 ++++++++++++++++++++++++++++ 8 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/riscv32/meson.build create mode 100644 tests/tcg/riscv32/system/meson.build create mode 100644 tests/tcg/riscv32/test-jvt-warl.S create mode 100644 tests/tcg/riscv64/test-jvt-warl.S
Only jvt.mode=0 is implemented, and jvt.mode is a WARL field, so a
software write of a reserved mode encoding must read back with the
implemented mode. write_jvt() currently stores the raw value, so a
subsequent cm.jt traps. Mask the written value with JVT_BASE.
Add TCG system tests for normalized readback and cm.jt dispatch on
RV32 and RV64.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4408
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: wangyang <wangyang25@otcaix.iscas.ac.cn>
---
Changes since v3:
- Add actual cm.jt dispatch coverage after the WARL readback check.
- Add RV32 system-mode tests alongside the RV64 test.
MAINTAINERS | 2 ++
target/riscv/tcg/csr.c | 6 +++-
tests/tcg/meson.build | 1 +
tests/tcg/riscv32/meson.build | 5 +++
tests/tcg/riscv32/system/meson.build | 38 +++++++++++++++++++++
tests/tcg/riscv32/test-jvt-warl.S | 49 ++++++++++++++++++++++++++++
tests/tcg/riscv64/system/meson.build | 7 ++++
tests/tcg/riscv64/test-jvt-warl.S | 49 ++++++++++++++++++++++++++++
8 files changed, 156 insertions(+), 1 deletion(-)
create mode 100644 tests/tcg/riscv32/meson.build
create mode 100644 tests/tcg/riscv32/system/meson.build
create mode 100644 tests/tcg/riscv32/test-jvt-warl.S
create mode 100644 tests/tcg/riscv64/test-jvt-warl.S
diff --git a/MAINTAINERS b/MAINTAINERS
index 1ee661cc23..4f2b6e882d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -377,6 +377,7 @@ F: include/hw/riscv/
F: common-user/host/riscv*
F: tests/functional/riscv32
F: tests/functional/riscv64
+F: tests/tcg/riscv32/
F: tests/tcg/riscv64/
F: tests/qtest/iommu-riscv-test.c
@@ -1786,6 +1787,7 @@ F: include/hw/riscv/opentitan.h
F: include/hw/*/ibex_*.h
F: target/riscv/insn_trans/trans_xthead.c.inc
F: target/riscv/xlrbr.decode
+F: tests/tcg/riscv32/
F: tests/tcg/riscv64/test-crc32.S
Microchip PolarFire SoC Icicle Kit
diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
index 061bc9db77..d16c9cd3c7 100644
--- a/target/riscv/tcg/csr.c
+++ b/target/riscv/tcg/csr.c
@@ -5904,7 +5904,11 @@ static RISCVException read_jvt(CPURISCVState *env, int csrno,
static RISCVException write_jvt(CPURISCVState *env, int csrno,
target_ulong val, uintptr_t ra)
{
- env->jvt = val;
+ /*
+ * jvt.mode is WARL and only mode 0 is implemented, so drop the
+ * reserved mode encodings instead of storing them.
+ */
+ env->jvt = val & JVT_BASE;
return RISCV_EXCP_NONE;
}
diff --git a/tests/tcg/meson.build b/tests/tcg/meson.build
index 4c0e30756d..184edcdbbc 100644
--- a/tests/tcg/meson.build
+++ b/tests/tcg/meson.build
@@ -186,6 +186,7 @@ subdir('mips64el')
subdir('or1k')
subdir('ppc64')
subdir('ppc64le')
+subdir('riscv32')
subdir('riscv64')
subdir('s390x')
subdir('sh4')
diff --git a/tests/tcg/riscv32/meson.build b/tests/tcg/riscv32/meson.build
new file mode 100644
index 0000000000..5557157c34
--- /dev/null
+++ b/tests/tcg/riscv32/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+cc = 'riscv64-linux-gnu-gcc'
+cc_dockerfile = 'debian-all-test-cross'
+subdir('system')
diff --git a/tests/tcg/riscv32/system/meson.build b/tests/tcg/riscv32/system/meson.build
new file mode 100644
index 0000000000..2ea397b3a2
--- /dev/null
+++ b/tests/tcg/riscv32/system/meson.build
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests = []
+
+link_script = files('../../riscv64/semihost.ld')[0]
+cflags = ['-march=rv32i_zicsr',
+ '-mabi=ilp32',
+ '-nostdlib',
+ '-ffreestanding',
+ '-Wa,--noexecstack',
+ '-Wl,-T', link_script]
+qemu_args = ['-M', 'virt',
+ '-display', 'none',
+ '-serial', 'stdio',
+ '-semihosting',
+ '-bios']
+
+tests += {
+ 'test-jvt-warl.S': {
+ 'cflags': cflags,
+ 'qemu_args': [
+ '-cpu', 'rv32i,h=false,zcd=false,zca=true,zcmt=true,zicsr=true', qemu_args,
+ ],
+ },
+}
+
+if 'qemu-system-riscv32' in emulators
+ tcg_tests += {
+ 'riscv32-softmmu': {
+ 'cc': cc,
+ 'cc_dockerfile': cc_dockerfile,
+ 'folder': 'riscv32',
+ 'gdb_arch': 'riscv32',
+ 'qemu': emulators['qemu-system-riscv32'],
+ 'tests': tests,
+ }
+ }
+endif
diff --git a/tests/tcg/riscv32/test-jvt-warl.S b/tests/tcg/riscv32/test-jvt-warl.S
new file mode 100644
index 0000000000..b9e42bc7a0
--- /dev/null
+++ b/tests/tcg/riscv32/test-jvt-warl.S
@@ -0,0 +1,49 @@
+/*
+ * Verify jvt.mode WARL normalization and cm.jt dispatch.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+ .option norvc
+ .text
+ .global _start
+_start:
+ lla t0, trap
+ csrw mtvec, t0
+ lla t0, jvt_table
+ ori t1, t0, 0x3f
+ csrw 0x017, t1
+ csrr t2, 0x017
+ bne t0, t2, fail
+ .2byte 0xa002 /* cm.jt index 0 */
+
+fail:
+ li a0, 1
+ j _exit
+
+target:
+ li a0, 0
+
+_exit:
+ lla a1, semiargs
+ li t0, 0x20026 /* ADP_Stopped_ApplicationExit */
+ sw t0, 0(a1)
+ sw a0, 4(a1)
+ li a0, 0x20 /* TARGET_SYS_EXIT_EXTENDED */
+ .balign 16
+ slli zero, zero, 0x1f
+ ebreak
+ srai zero, zero, 0x7
+ j .
+
+trap:
+ li a0, 1
+ j _exit
+
+ .balign 64
+jvt_table:
+ .word target
+
+ .data
+ .balign 8
+semiargs:
+ .space 8
diff --git a/tests/tcg/riscv64/system/meson.build b/tests/tcg/riscv64/system/meson.build
index c2d7d09887..62f0ffe1ea 100644
--- a/tests/tcg/riscv64/system/meson.build
+++ b/tests/tcg/riscv64/system/meson.build
@@ -26,6 +26,13 @@ tests += {
'test-misa-w.S': setup + {'qemu_args': ['-cpu', 'rv64,x-misa-w=true,c=true,v=true', qemu_args]},
}
+tests += {
+ 'test-jvt-warl.S': {
+ 'cflags': cflags + ['-march=rv64gc_zicsr'],
+ 'qemu_args': ['-cpu', 'rv64,zcmt=true,zcd=false', qemu_args],
+ }
+}
+
tests += {
'test-rv128-mstatus.S': {
'cflags': cflags,
diff --git a/tests/tcg/riscv64/test-jvt-warl.S b/tests/tcg/riscv64/test-jvt-warl.S
new file mode 100644
index 0000000000..2ac28e6951
--- /dev/null
+++ b/tests/tcg/riscv64/test-jvt-warl.S
@@ -0,0 +1,49 @@
+/*
+ * Verify jvt.mode WARL normalization and cm.jt dispatch.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+ .option norvc
+ .text
+ .global _start
+_start:
+ lla t0, trap
+ csrw mtvec, t0
+ lla t0, jvt_table
+ ori t1, t0, 0x3f
+ csrw 0x017, t1
+ csrr t2, 0x017
+ bne t0, t2, fail
+ .2byte 0xa002 /* cm.jt index 0 */
+
+fail:
+ li a0, 1
+ j _exit
+
+target:
+ li a0, 0
+
+_exit:
+ lla a1, semiargs
+ li t0, 0x20026 /* ADP_Stopped_ApplicationExit */
+ sd t0, 0(a1)
+ sd a0, 8(a1)
+ li a0, 0x20 /* TARGET_SYS_EXIT_EXTENDED */
+ .balign 16
+ slli zero, zero, 0x1f
+ ebreak
+ srai zero, zero, 0x7
+ j .
+
+trap:
+ li a0, 1
+ j _exit
+
+ .balign 64
+jvt_table:
+ .dword target
+
+ .data
+ .balign 16
+semiargs:
+ .space 16
base-commit: 7e8d3c7fc460fe7cd28a3e423d7466fa292bc269
--
2.55.0.windows.2
The CSR fix for #4408 is already queued in Alistair's riscv-to-apply.next branch at bfdd4f6a918ffad4f013d4f53a9adca1adc0aa3b. This follow-up contains only the RV32/RV64 TCG system tests. Sorry for repeating the CSR hunk in v4 after it had been queued. The tests check normalized jvt readback and cm.jt dispatch. The same two tests passed in the Docker TCG build (2/2). wangyang (1): tests/tcg/riscv: test jvt.mode WARL normalization tests/tcg/riscv32/system/meson.build | 9 +++++ tests/tcg/riscv32/test-jvt-warl.S | 49 ++++++++++++++++++++++++++++ tests/tcg/riscv64/system/meson.build | 7 ++++ tests/tcg/riscv64/test-jvt-warl.S | 49 ++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 tests/tcg/riscv32/test-jvt-warl.S create mode 100644 tests/tcg/riscv64/test-jvt-warl.S -- 2.55.0.windows.2
Check that RV32 and RV64 read back the implemented mode after
writing reserved mode bits, then execute cm.jt through the table.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4408
Signed-off-by: wangyang <wangyang25@otcaix.iscas.ac.cn>
---
tests/tcg/riscv32/system/meson.build | 9 +++++
tests/tcg/riscv32/test-jvt-warl.S | 49 ++++++++++++++++++++++++++++
tests/tcg/riscv64/system/meson.build | 7 ++++
tests/tcg/riscv64/test-jvt-warl.S | 49 ++++++++++++++++++++++++++++
4 files changed, 114 insertions(+)
create mode 100644 tests/tcg/riscv32/test-jvt-warl.S
create mode 100644 tests/tcg/riscv64/test-jvt-warl.S
diff --git a/tests/tcg/riscv32/system/meson.build b/tests/tcg/riscv32/system/meson.build
index f8e55ad3d4..31c285c6f6 100644
--- a/tests/tcg/riscv32/system/meson.build
+++ b/tests/tcg/riscv32/system/meson.build
@@ -22,6 +22,15 @@ tests += {
},
}
+tests += {
+ 'test-jvt-warl.S': {
+ 'cflags': cflags,
+ 'qemu_args': [
+ '-cpu', 'rv32i,h=false,zcd=false,zca=true,zcmt=true,zicsr=true', qemu_args,
+ ],
+ },
+}
+
if 'qemu-system-riscv32' in emulators
tcg_tests += {
'riscv32-softmmu': {
diff --git a/tests/tcg/riscv32/test-jvt-warl.S b/tests/tcg/riscv32/test-jvt-warl.S
new file mode 100644
index 0000000000..b9e42bc7a0
--- /dev/null
+++ b/tests/tcg/riscv32/test-jvt-warl.S
@@ -0,0 +1,49 @@
+/*
+ * Verify jvt.mode WARL normalization and cm.jt dispatch.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+ .option norvc
+ .text
+ .global _start
+_start:
+ lla t0, trap
+ csrw mtvec, t0
+ lla t0, jvt_table
+ ori t1, t0, 0x3f
+ csrw 0x017, t1
+ csrr t2, 0x017
+ bne t0, t2, fail
+ .2byte 0xa002 /* cm.jt index 0 */
+
+fail:
+ li a0, 1
+ j _exit
+
+target:
+ li a0, 0
+
+_exit:
+ lla a1, semiargs
+ li t0, 0x20026 /* ADP_Stopped_ApplicationExit */
+ sw t0, 0(a1)
+ sw a0, 4(a1)
+ li a0, 0x20 /* TARGET_SYS_EXIT_EXTENDED */
+ .balign 16
+ slli zero, zero, 0x1f
+ ebreak
+ srai zero, zero, 0x7
+ j .
+
+trap:
+ li a0, 1
+ j _exit
+
+ .balign 64
+jvt_table:
+ .word target
+
+ .data
+ .balign 8
+semiargs:
+ .space 8
diff --git a/tests/tcg/riscv64/system/meson.build b/tests/tcg/riscv64/system/meson.build
index 3e1c970382..ce5e710288 100644
--- a/tests/tcg/riscv64/system/meson.build
+++ b/tests/tcg/riscv64/system/meson.build
@@ -77,6 +77,13 @@ tests += {
}
}
+tests += {
+ 'test-jvt-warl.S': {
+ 'cflags': cflags + ['-march=rv64gc_zicsr'],
+ 'qemu_args': ['-cpu', 'rv64,zcmt=true,zcd=false', qemu_args],
+ }
+}
+
if 'qemu-system-riscv64' in emulators
tcg_tests += {
'riscv64-softmmu': {
diff --git a/tests/tcg/riscv64/test-jvt-warl.S b/tests/tcg/riscv64/test-jvt-warl.S
new file mode 100644
index 0000000000..2ac28e6951
--- /dev/null
+++ b/tests/tcg/riscv64/test-jvt-warl.S
@@ -0,0 +1,49 @@
+/*
+ * Verify jvt.mode WARL normalization and cm.jt dispatch.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+ .option norvc
+ .text
+ .global _start
+_start:
+ lla t0, trap
+ csrw mtvec, t0
+ lla t0, jvt_table
+ ori t1, t0, 0x3f
+ csrw 0x017, t1
+ csrr t2, 0x017
+ bne t0, t2, fail
+ .2byte 0xa002 /* cm.jt index 0 */
+
+fail:
+ li a0, 1
+ j _exit
+
+target:
+ li a0, 0
+
+_exit:
+ lla a1, semiargs
+ li t0, 0x20026 /* ADP_Stopped_ApplicationExit */
+ sd t0, 0(a1)
+ sd a0, 8(a1)
+ li a0, 0x20 /* TARGET_SYS_EXIT_EXTENDED */
+ .balign 16
+ slli zero, zero, 0x1f
+ ebreak
+ srai zero, zero, 0x7
+ j .
+
+trap:
+ li a0, 1
+ j _exit
+
+ .balign 64
+jvt_table:
+ .dword target
+
+ .data
+ .balign 16
+semiargs:
+ .space 16
--
2.55.0.windows.2
© 2016 - 2026 Red Hat, Inc.