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 <[email protected]>
Signed-off-by: wangyang <[email protected]>
---
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


Reply via email to