From: Bruno Sa <[email protected]> On RV32, STCE/ADUE/PBMTE/DTE are implemented in henvcfgh. A write to henvcfg should therefore only update the low 32 bits of env->henvcfg.
The current write_henvcfg() path overwrites env->henvcfg with the low-half value and clears any bits previously written via henvcfgh. Preserve the upper 32 bits on RV32 henvcfg writes and keep the existing RV64 behaviour unchanged. Signed-off-by: Bruno Sa <[email protected]> Reviewed-by: Alistair Francis <[email protected]> Message-ID: <[email protected]> Signed-off-by: Alistair Francis <[email protected]> --- target/riscv/csr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index a75281539b..cfd076b368 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -3353,7 +3353,15 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno, } } - env->henvcfg = val & mask; + if (riscv_cpu_mxl(env) == MXL_RV32) { + /* + * RV32 stores STCE/ADUE/PBMTE/DTE in henvcfgh, so a low-half henvcfg + * write must not clobber the upper 32 bits. + */ + env->henvcfg = (env->henvcfg & ~0xFFFFFFFFULL) | (val & mask); + } else { + env->henvcfg = val & mask; + } if ((env->henvcfg & HENVCFG_DTE) == 0) { env->vsstatus &= ~MSTATUS_SDT; } -- 2.53.0
