diff --git a/riscv/csr_init.cc b/riscv/csr_init.cc index 26f5b67d..307eab7b 100644 --- a/riscv/csr_init.cc +++ b/riscv/csr_init.cc @@ -476,13 +476,17 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) add_const_ext_csr(EXT_SSQOSID, CSR_SRMCFG, std::make_shared(proc, CSR_SRMCFG, srmcfg_mask, 0)); mvien = std::make_shared(proc, CSR_MVIEN, 0); + mvip = std::make_shared(proc, CSR_MVIP, 0); if (proc->extension_enabled_const(EXT_SMAIA)) { add_csr(CSR_MTOPI, std::make_shared(proc, CSR_MTOPI)); if (xlen == 32) { add_supervisor_csr(CSR_MVIEN, std::make_shared(proc, CSR_MVIEN, mvien)); add_supervisor_csr(CSR_MVIENH, std::make_shared(proc, CSR_MVIENH, mvien)); + add_supervisor_csr(CSR_MVIP, std::make_shared(proc, CSR_MVIP, mvip)); + add_supervisor_csr(CSR_MVIPH, std::make_shared(proc, CSR_MVIPH, mvip)); } else { add_supervisor_csr(CSR_MVIEN, mvien); + add_supervisor_csr(CSR_MVIEN, mvip); } } } diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 7aa52056..e7f3a102 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1993,3 +1993,26 @@ reg_t mtopi_csr_t::read() const noexcept { bool mtopi_csr_t::unlogged_write(const reg_t UNUSED val) noexcept { return false; } + +mvip_csr_t::mvip_csr_t(processor_t* const proc, const reg_t addr, const reg_t init): + basic_csr_t(proc, addr, init) { +} + +reg_t mvip_csr_t::read() const noexcept { + const reg_t mip = state->mip->read(); + const reg_t menvcfg = state->menvcfg->read(); + return 0 + | (mip & MIP_SEIP) + | ((menvcfg & MENVCFG_STCE) ? 0 : (mip & MIP_STIP)) + | (mip & MIP_SSIP) + ; +} + +bool mvip_csr_t::unlogged_write(const reg_t val) noexcept { + state->mip->write_with_mask(MIP_SEIP, val); + if (!(state->menvcfg->read() & MENVCFG_STCE)) + state->mip->write_with_mask(MIP_STIP, val); // mvip.STIP is an alias of mip.STIP when mip.STIP is writable + state->mip->write_with_mask(MIP_SSIP, val); + + return false; +} diff --git a/riscv/csrs.h b/riscv/csrs.h index 506393fe..5c583a47 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -916,4 +916,14 @@ class mtopi_csr_t: public csr_t { protected: bool unlogged_write(const reg_t val) noexcept override; }; + +class mvip_csr_t : public basic_csr_t { + public: + mvip_csr_t(processor_t* const proc, const reg_t addr, const reg_t init); + reg_t read() const noexcept override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; + +typedef std::shared_ptr mvip_csr_t_p; #endif diff --git a/riscv/processor.h b/riscv/processor.h index d6e69eab..32247230 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -175,6 +175,7 @@ struct state_t csr_t_p ssp; csr_t_p mvien; + mvip_csr_t_p mvip; bool serialized; // whether timer CSRs are in a well-defined state