[PATCH v4] target/riscv: normalize Zcmt jvt.mode on writes

wangyang posted 1 patch 1 week, 1 day ago
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
[PATCH v4] target/riscv: normalize Zcmt jvt.mode on writes
Posted by wangyang 1 week, 1 day ago
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
[PATCH 0/1] tests/tcg/riscv: add Zcmt jvt WARL tests
Posted by wangyang 1 week, 1 day ago
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
[PATCH 1/1] tests/tcg/riscv: test jvt.mode WARL normalization
Posted by wangyang 1 week, 1 day ago
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