diff --git a/riscv/csr_init.cc b/riscv/csr_init.cc index 22f20ff86..cb4ead329 100644 --- a/riscv/csr_init.cc +++ b/riscv/csr_init.cc @@ -33,6 +33,26 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) add_csr(CSR_MTVEC, mtvec = std::make_shared(proc, CSR_MTVEC)); add_csr(CSR_MCAUSE, mcause = std::make_shared(proc, CSR_MCAUSE)); + 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); + const reg_t menvcfg_init = (proc->extension_enabled(EXT_ZICBOM) ? MENVCFG_CBCFE | MENVCFG_CBIE : 0) | + (proc->extension_enabled(EXT_ZICBOZ) ? MENVCFG_CBZE : 0) | + (proc->extension_enabled(EXT_SSTC) ? MENVCFG_STCE : 0); + menvcfg = std::make_shared(proc, CSR_MENVCFG, menvcfg_mask, menvcfg_init); + 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 minstretcfg_mask = !proc->extension_enabled_const(EXT_SMCNTRPMF) ? 0 : MHPMEVENT_MINH | MHPMEVENT_SINH | MHPMEVENT_UINH | MHPMEVENT_VSINH | MHPMEVENT_VUINH; auto minstretcfg = std::make_shared(proc, CSR_MINSTRETCFG, minstretcfg_mask, 0); @@ -261,25 +281,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); - const reg_t menvcfg_init = (proc->extension_enabled(EXT_ZICBOM) ? MENVCFG_CBCFE | MENVCFG_CBIE : 0) | - (proc->extension_enabled(EXT_ZICBOZ) ? MENVCFG_CBZE : 0) | - (proc->extension_enabled(EXT_SSTC) ? MENVCFG_STCE : 0); - menvcfg = std::make_shared(proc, CSR_MENVCFG, menvcfg_mask, menvcfg_init); - 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_SSNPM) ? SENVCFG_PMM : 0) | diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 78f4ec49c..4974c9bb2 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -501,10 +501,21 @@ vsstatus_csr_t::vsstatus_csr_t(processor_t* const proc, const reg_t addr): bool vsstatus_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t hDTE = (state->henvcfg->read() & HENVCFG_DTE); - const reg_t adj_write_mask = sstatus_write_mask & ~(hDTE ? 0 : SSTATUS_SDT); + const reg_t adj_write_mask = +#if defined(DIFFTEST) && defined(CPU_XIANGSHAN) + sstatus_write_mask; +#else + sstatus_write_mask & ~(hDTE ? 0 : SSTATUS_SDT); +#endif reg_t newval = (this->val & ~adj_write_mask) | (val & adj_write_mask); + bool write_sdt = +#if defined(DIFFTEST) && defined(CPU_XIANGSHAN) + newval & SSTATUS_SDT && hDTE; +#else + (newval & SSTATUS_SDT); +#endif - newval = (newval & SSTATUS_SDT) ? (newval & ~SSTATUS_SIE) : newval; + newval = (write_sdt) ? (newval & ~SSTATUS_SIE) : newval; if (state->v) maybe_flush_tlb(newval); this->val = adjust_sd(newval); @@ -525,10 +536,20 @@ sstatus_proxy_csr_t::sstatus_proxy_csr_t(processor_t* const proc, const reg_t ad bool sstatus_proxy_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t mDTE = (state->menvcfg->read() & MENVCFG_DTE); - const reg_t adj_write_mask = sstatus_write_mask & ~(mDTE ? 0 : SSTATUS_SDT); + const reg_t adj_write_mask = +#if defined(DIFFTEST) && defined(CPU_XIANGSHAN) + sstatus_write_mask; +#else + sstatus_write_mask & ~(mDTE ? 0 : SSTATUS_SDT); +#endif reg_t new_mstatus = (mstatus->read() & ~adj_write_mask) | (val & adj_write_mask); - - new_mstatus = (new_mstatus & SSTATUS_SDT) ? (new_mstatus & ~SSTATUS_SIE) : new_mstatus; + bool write_sdt = +#if defined(DIFFTEST) && defined(CPU_XIANGSHAN) + new_mstatus & SSTATUS_SDT && mDTE; +#else + (new_mstatus & SSTATUS_SDT); +#endif + new_mstatus = (write_sdt) ? (new_mstatus & ~SSTATUS_SIE) : new_mstatus; // On RV32 this will only log the low 32 bits, so make sure we're // not modifying anything in the upper 32 bits. @@ -579,16 +600,35 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept { reg_t new_mstatus = (read() & ~mask) | (adjusted_val & mask); new_mstatus ^= new_mstatus & (0x3 << 13); // FS is always zero #else - reg_t new_mstatus = (read() & ~mask) | (adjusted_val & mask); - if (new_mstatus & MSTATUS_MDT) { - new_mstatus = new_mstatus & ~MSTATUS_MIE; - } + const reg_t mDTE = (state->menvcfg->read() & MENVCFG_DTE); + const reg_t adj_write_mask = +#if defined(DIFFTEST) && defined(CPU_XIANGSHAN) + mask; +#else + mask & ~(mDTE ? 0 : MSTATUS_SDT); +#endif + reg_t new_mstatus = (read() & ~adj_write_mask) | (adjusted_val & adj_write_mask); + bool write_sdt = +#if defined(DIFFTEST) && defined(CPU_XIANGSHAN) + new_mstatus & MSTATUS_SDT && mDTE; +#else + (new_mstatus & MSTATUS_SDT); +#endif + new_mstatus = (new_mstatus & MSTATUS_MDT) ? (new_mstatus & ~MSTATUS_MIE) : new_mstatus; + new_mstatus = (write_sdt) ? (new_mstatus & ~MSTATUS_SIE) : new_mstatus; #endif maybe_flush_tlb(new_mstatus); this->val = adjust_sd(new_mstatus); return true; } +reg_t mstatus_csr_t::read() const noexcept { + const reg_t mDTE = state->menvcfg->read() & MENVCFG_DTE; + const reg_t adj_read_mask = ~(mDTE ? 0 : MSTATUS_SDT); + + return this->val & adj_read_mask; +} + reg_t mstatus_csr_t::compute_mstatus_initial_value() const noexcept { const reg_t big_endian_bits = (proc->extension_enabled_const('U') ? MSTATUS_UBE : 0) | (proc->extension_enabled_const('S') ? MSTATUS_SBE : 0) diff --git a/riscv/csrs.h b/riscv/csrs.h index b46a52cfa..50db8d44d 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -255,10 +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; - } - + virtual reg_t read() const noexcept override; protected: virtual bool unlogged_write(const reg_t val) noexcept override; private: