diff --git a/riscv/csr_init.cc b/riscv/csr_init.cc index 2fb9a90eef..4a05a9c712 100644 --- a/riscv/csr_init.cc +++ b/riscv/csr_init.cc @@ -224,6 +224,25 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) } else { add_hypervisor_csr(CSR_HIDELEG, hideleg); } + + const reg_t menvcfg_mask = (proc->extension_enabled(EXT_ZICBOM) ? MENVCFG_CBCFE | MENVCFG_CBIE : 0) | + (proc->extension_enabled(EXT_ZICBOZ) ? MENVCFG_CBZE : 0) | + (proc->extension_enabled(EXT_SMNPM) ? MENVCFG_PMM : 0) | + (proc->extension_enabled(EXT_SVADU) ? MENVCFG_ADUE: 0) | + (proc->extension_enabled(EXT_SVPBMT) ? MENVCFG_PBMTE : 0) | + (proc->extension_enabled(EXT_SSTC) ? MENVCFG_STCE : 0) | + (proc->extension_enabled(EXT_ZICFILP) ? MENVCFG_LPE : 0) | + (proc->extension_enabled(EXT_ZICFISS) ? MENVCFG_SSE : 0) | + (proc->extension_enabled(EXT_SSDBLTRP) ? MENVCFG_DTE : 0)| + (proc->extension_enabled(EXT_SMCDELEG) ? MENVCFG_CDE : 0); + menvcfg = std::make_shared(proc, CSR_MENVCFG, menvcfg_mask, 0); + if (xlen == 32) { + add_user_csr(CSR_MENVCFG, std::make_shared(proc, CSR_MENVCFG, menvcfg)); + add_user_csr(CSR_MENVCFGH, std::make_shared(proc, CSR_MENVCFGH, menvcfg)); + } else { + add_user_csr(CSR_MENVCFG, menvcfg); + } + const reg_t hedeleg_mask = (1 << CAUSE_MISALIGNED_FETCH) | (1 << CAUSE_FETCH_ACCESS) | @@ -310,23 +329,6 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) add_csr(CSR_MVENDORID, std::make_shared(proc, CSR_MVENDORID, 0)); add_csr(CSR_MHARTID, std::make_shared(proc, CSR_MHARTID, proc->get_id())); add_csr(CSR_MCONFIGPTR, std::make_shared(proc, CSR_MCONFIGPTR, 0)); - const reg_t menvcfg_mask = (proc->extension_enabled(EXT_ZICBOM) ? MENVCFG_CBCFE | MENVCFG_CBIE : 0) | - (proc->extension_enabled(EXT_ZICBOZ) ? MENVCFG_CBZE : 0) | - (proc->extension_enabled(EXT_SMNPM) ? MENVCFG_PMM : 0) | - (proc->extension_enabled(EXT_SVADU) ? MENVCFG_ADUE: 0) | - (proc->extension_enabled(EXT_SVPBMT) ? MENVCFG_PBMTE : 0) | - (proc->extension_enabled(EXT_SSTC) ? MENVCFG_STCE : 0) | - (proc->extension_enabled(EXT_ZICFILP) ? MENVCFG_LPE : 0) | - (proc->extension_enabled(EXT_ZICFISS) ? MENVCFG_SSE : 0) | - (proc->extension_enabled(EXT_SSDBLTRP) ? MENVCFG_DTE : 0)| - (proc->extension_enabled(EXT_SMCDELEG) ? MENVCFG_CDE : 0); - menvcfg = std::make_shared(proc, CSR_MENVCFG, menvcfg_mask, 0); - if (xlen == 32) { - add_user_csr(CSR_MENVCFG, std::make_shared(proc, CSR_MENVCFG, menvcfg)); - add_user_csr(CSR_MENVCFGH, std::make_shared(proc, CSR_MENVCFGH, menvcfg)); - } else { - add_user_csr(CSR_MENVCFG, menvcfg); - } const reg_t senvcfg_mask = (proc->extension_enabled(EXT_ZICBOM) ? SENVCFG_CBCFE | SENVCFG_CBIE : 0) | (proc->extension_enabled(EXT_ZICBOZ) ? SENVCFG_CBZE : 0) | (proc->extension_enabled(EXT_SVUKTE) ? SENVCFG_UKTE : 0) | diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 3b8933f621..fbd914fe83 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -544,11 +544,16 @@ mstatus_csr_t::mstatus_csr_t(processor_t* const proc, const reg_t addr): val(compute_mstatus_initial_value()) { } +reg_t mstatus_csr_t::read() const noexcept { + return val & ~reg_t(state->menvcfg->read() & MENVCFG_DTE ? 0 : MSTATUS_SDT); +} + bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept { const bool has_mpv = proc->extension_enabled('H'); const bool has_gva = has_mpv; + const reg_t adj_write_mask = sstatus_write_mask & ~reg_t(state->menvcfg->read() & MENVCFG_DTE ? 0 : SSTATUS_SDT); - const reg_t mask = sstatus_write_mask + const reg_t mask = adj_write_mask | MSTATUS_MIE | MSTATUS_MPIE | (proc->extension_enabled('U') ? MSTATUS_MPRV : 0) | MSTATUS_MPP | MSTATUS_TW @@ -558,12 +563,11 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept { | (has_mpv ? MSTATUS_MPV : 0) | (proc->extension_enabled(EXT_SMDBLTRP) ? MSTATUS_MDT : 0) | (proc->extension_enabled(EXT_ZICFILP) ? (MSTATUS_SPELP | MSTATUS_MPELP) : 0) - | (proc->extension_enabled(EXT_SSDBLTRP) ? SSTATUS_SDT : 0) ; const reg_t requested_mpp = proc->legalize_privilege(get_field(val, MSTATUS_MPP)); const reg_t adjusted_val = set_field(val, MSTATUS_MPP, requested_mpp); - reg_t new_mstatus = (read() & ~mask) | (adjusted_val & mask); + reg_t new_mstatus = (this->val & ~mask) | (adjusted_val & mask); new_mstatus = (new_mstatus & MSTATUS_MDT) ? (new_mstatus & ~MSTATUS_MIE) : new_mstatus; new_mstatus = (new_mstatus & MSTATUS_SDT) ? (new_mstatus & ~MSTATUS_SIE) : new_mstatus; maybe_flush_tlb(new_mstatus); diff --git a/riscv/csrs.h b/riscv/csrs.h index 11e1c2bcfd..b1d5a3ba43 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -255,9 +255,7 @@ class mstatus_csr_t final: public base_status_csr_t { public: mstatus_csr_t(processor_t* const proc, const reg_t addr); - reg_t read() const noexcept override { - return val; - } + reg_t read() const noexcept override; protected: virtual bool unlogged_write(const reg_t val) noexcept override;