From 3efaf6979b4b2e01dbe299c77a1231b089d025e2 Mon Sep 17 00:00:00 2001 From: 124107157-KV <124107157@umail.ucc.ie> Date: Wed, 16 Sep 2026 11:28:34 +0100 Subject: [PATCH] Fix mtvec WARL readback and trap dispatch coherence --- core/csr_regfile.sv | 4 ++ verif/tests/custom/issues/mtvec-warl-rv64.S | 61 +++++++++++++++++++++ verif/tests/testlist_issues.yaml | 21 +++++++ 3 files changed, 86 insertions(+) create mode 100644 verif/tests/custom/issues/mtvec-warl-rv64.S diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index f6ed1ecf5ae..79cec826db4 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -1745,6 +1745,10 @@ module csr_regfile // we are in vector mode, this implementation requires the additional // alignment constraint of 64 * 4 bytes if (DirVecOnly) mtvec_d = {csr_wdata[CVA6Cfg.XLEN-1:8], 7'b0, DirVecOnly}; + // Machine-mode instruction fetches use physical addresses. Legalize + // mtvec to the implemented physical address width so its CSR-visible + // value matches the address that can actually be fetched. + mtvec_d = CVA6Cfg.XLEN'(CVA6Cfg.PLEN'(mtvec_d)); end riscv::CSR_MCOUNTEREN: begin if (CVA6Cfg.RVU) mcounteren_d = {{CVA6Cfg.XLEN - 32{1'b0}}, csr_wdata[31:0]}; diff --git a/verif/tests/custom/issues/mtvec-warl-rv64.S b/verif/tests/custom/issues/mtvec-warl-rv64.S new file mode 100644 index 00000000000..d1b93bec7d2 --- /dev/null +++ b/verif/tests/custom/issues/mtvec-warl-rv64.S @@ -0,0 +1,61 @@ +# Copyright 2026 Keerthivasan +# +# Licensed under the Solderpad Hardware Licence, Version 2.0. +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +# +# Regression test for CVA6 issue #3458. +# +# mtvec is WARL. If an mtvec value contains address bits that the +# implementation cannot use for instruction fetch, the implementation may +# legalize the value on write. If the value is instead retained on readback, +# trap dispatch must consume the same architectural base. +# +# The current bug retains a high-tagged value in mtvec, while the instruction +# fetch path ultimately uses the low physical-address alias. + + .section .text + .align 2 + + .equ HIGH_TAG, 0x1000000000000000 + + .globl main + +main: + # Construct an mtvec value whose low portion names a real executable + # trap handler while bit 60 is outside the implemented physical-address + # width of cv64a6_imafdc_sv39. + la t0, low_trap_entry + li t1, HIGH_TAG + or s0, t0, t1 + + # Write and immediately read back mtvec. + csrw mtvec, s0 + csrr s1, mtvec + + # Legalization is a valid WARL implementation choice. + # If the unsupported tag was removed, the CSR and fetch behavior are + # coherent and this test passes. + bne s1, s0, pass_mtvec_legalized + + # If the tagged value was retained, trap dispatch must not silently + # consume the low alias. +ecall_site: + ecall + + # ECALL must trap and must never retire here. + li a0, 41 + j finish + + .align 2 +low_trap_entry: + # Reaching this handler while mtvec readback retained HIGH_TAG reproduces + # issue #3458: software sees the tagged base but hardware dispatched to + # its low physical alias. + li a0, 42 + j finish + +pass_mtvec_legalized: + li a0, 0 + +finish: + jal exit diff --git a/verif/tests/testlist_issues.yaml b/verif/tests/testlist_issues.yaml index 1538b41fe67..91e20fab49e 100644 --- a/verif/tests/testlist_issues.yaml +++ b/verif/tests/testlist_issues.yaml @@ -238,3 +238,24 @@ testlist: when MRET or SRET returns below M-mode. iterations: 1 asm_tests: /custom/issues/xret-mprv-clear-rv64.S + + - test: mtvec-warl-rv64 + <<: *common_test_config + description: > + Check that mtvec CSR readback and machine-mode trap dispatch remain + coherent when software writes address bits outside the implemented + physical-address width. + iterations: 1 + asm_tests: /custom/issues/mtvec-warl-rv64.S + gcc_opts: >- + -static + -misa-spec=2.2 + -mcmodel=medany + -fvisibility=hidden + -nostdlib + -nostartfiles + ../tests/custom/common/crt.S + -I../tests/custom/env + -I../tests/custom/common + -T ../../config/gen_from_riscv_config/linker/link.ld + -lgcc