From 0b0ac1bd9adaf86bb3c556ab94494d7746316aaf Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 9 Jun 2026 02:10:22 -0700 Subject: [PATCH] Fix Ssccfg implementation Fib about the address of the counter-config CSRs so that permission checks will succeed in S-mode and so the correct mcounteren bit is checked for the cycle config CSR. Fixes #2312 Signed-off-by: Andrew Waterman --- riscv/csr_init.cc | 39 ++++++++++++++++++++------------------- riscv/processor.h | 6 ------ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/riscv/csr_init.cc b/riscv/csr_init.cc index a4e00a38..877993e2 100644 --- a/riscv/csr_init.cc +++ b/riscv/csr_init.cc @@ -88,17 +88,6 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) add_csr(CSR_MCYCLECFG, mcyclecfg); add_csr(CSR_MINSTRETCFG, minstretcfg); } - if (proc->extension_enabled_const(EXT_SMCDELEG)) { - if (xlen == 32) { - cyclecfg = std::make_shared(proc, CSR_MCYCLECFG, csrmap[CSR_MCYCLECFG]); - cyclecfgh = std::make_shared(proc, CSR_MCYCLECFGH, csrmap[CSR_MCYCLECFGH]); - instretcfg = std::make_shared(proc, CSR_MINSTRETCFG, csrmap[CSR_MINSTRETCFG]); - instretcfgh = std::make_shared(proc, CSR_MINSTRETCFGH, csrmap[CSR_MINSTRETCFGH]); - } else { - instretcfg = std::make_shared(proc, CSR_MINSTRETCFG, csrmap[CSR_MINSTRETCFG]); - cyclecfg = std::make_shared(proc, CSR_MCYCLECFG, csrmap[CSR_MCYCLECFG]); - } - } } for (reg_t i = 0; i < N_HPMCOUNTERS; ++i) { const reg_t which_mevent = CSR_MHPMEVENT3 + i; @@ -502,25 +491,37 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) break; case CSR_SIREG2: if (proc->extension_enabled_const(EXT_ZICNTR)) { - sireg->add_ireg_proxy(SISELECT_SMCDELEG_START, cyclecfg); - sireg->add_ireg_proxy(SISELECT_SMCDELEG_INSTRETCFG, instretcfg); + // describe address as that of CYCLE rather than MCYCLECFG, + // so that perm checks and mcounteren checks do the right thing + auto cyclecfg_proxy = std::make_shared(proc, CSR_CYCLE, csrmap[CSR_MCYCLECFG]); + sireg->add_ireg_proxy(SISELECT_SMCDELEG_START, cyclecfg_proxy); + + auto instretcfg_proxy = std::make_shared(proc, CSR_INSTRET, csrmap[CSR_MINSTRETCFG]); + sireg->add_ireg_proxy(SISELECT_SMCDELEG_INSTRETCFG, instretcfg_proxy); } if (proc->extension_enabled_const(EXT_ZIHPM)) { - for (size_t j = 0; j < (SISELECT_SMCDELEG_END - SISELECT_SMCDELEG_HPMEVENT_3 + 1); j++) - sireg->add_ireg_proxy(SISELECT_SMCDELEG_HPMEVENT_3 + j, csrmap[CSR_MHPMEVENT3 + j]); + for (size_t j = 0; j < (SISELECT_SMCDELEG_END - SISELECT_SMCDELEG_HPMEVENT_3 + 1); j++) { + auto proxy = std::make_shared(proc, CSR_HPMCOUNTER3 + j, csrmap[CSR_MHPMEVENT3 + j]); + sireg->add_ireg_proxy(SISELECT_SMCDELEG_HPMEVENT_3 + j, proxy); + } } break; case CSR_SIREG5: if (xlen == 32) { // cyclecfgh/instretcfgh if (proc->extension_enabled_const(EXT_ZICNTR) && proc->extension_enabled_const(EXT_SMCNTRPMF)) { - sireg->add_ireg_proxy(SISELECT_SMCDELEG_START, cyclecfgh); - sireg->add_ireg_proxy(SISELECT_SMCDELEG_INSTRET, instretcfgh); + auto cyclecfgh_proxy = std::make_shared(proc, CSR_CYCLEH, csrmap[CSR_MCYCLECFGH]); + sireg->add_ireg_proxy(SISELECT_SMCDELEG_START, cyclecfgh_proxy); + + auto instretcfgh_proxy = std::make_shared(proc, CSR_INSTRETH, csrmap[CSR_MINSTRETCFGH]); + sireg->add_ireg_proxy(SISELECT_SMCDELEG_INSTRET, instretcfgh_proxy); } // hpmevent3h-hpmevent31h if (proc->extension_enabled_const(EXT_ZIHPM) && proc->extension_enabled_const(EXT_SSCOFPMF)) { - for (size_t j = 0; j < (SISELECT_SMCDELEG_END - SISELECT_SMCDELEG_HPMEVENT_3); j++) - sireg->add_ireg_proxy(SISELECT_SMCDELEG_HPMEVENT_3 + j, csrmap[CSR_MHPMEVENT3H + j]); + for (size_t j = 0; j < (SISELECT_SMCDELEG_END - SISELECT_SMCDELEG_HPMEVENT_3); j++) { + auto proxy = std::make_shared(proc, CSR_HPMCOUNTER3H + j, csrmap[CSR_MHPMEVENT3H + j]); + sireg->add_ireg_proxy(SISELECT_SMCDELEG_HPMEVENT_3 + j, proxy); + } } } case CSR_SIREG3: diff --git a/riscv/processor.h b/riscv/processor.h index 92324361..7e79c9fa 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -185,12 +185,6 @@ struct state_t time_counter_csr_t_p time; csr_t_p time_proxy; - csr_t_p instretcfg; - csr_t_p instretcfgh; - - csr_t_p cyclecfg; - csr_t_p cyclecfgh; - csr_t_p stimecmp; csr_t_p vstimecmp;