Browse Source

csr: fix double trap state access

In privilege spec sec 3.1.18

" The Ssdbltrp extension adds the double-trap-enable ( DTE ) field in
menvcfg . When  menvcfg.DTE  is zero, the implementation  behaves  as
though  Ssdbltrp  is  not  implemented.  When  Ssdbltrp  is  not  implemented
sstatus.SDT ,  vsstatus.SDT , and  henvcfg.DTE  bits are read-only zero."

The change keep the mstatus.sdt unchangedable and always read-as-zero
when menvcfg.dte is cleared

Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
pull/2163/head
Chih-Min Chao 8 months ago
parent
commit
6d6cc2c525
  1. 10
      riscv/csrs.cc
  2. 4
      riscv/csrs.h

10
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);

4
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;

Loading…
Cancel
Save