Skip to content

Commit 6d6cc2c

Browse files
committed
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>
1 parent 47c1a95 commit 6d6cc2c

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

riscv/csrs.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,11 +544,16 @@ mstatus_csr_t::mstatus_csr_t(processor_t* const proc, const reg_t addr):
544544
val(compute_mstatus_initial_value()) {
545545
}
546546

547+
reg_t mstatus_csr_t::read() const noexcept {
548+
return val & ~reg_t(state->menvcfg->read() & MENVCFG_DTE ? 0 : MSTATUS_SDT);
549+
}
550+
547551
bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept {
548552
const bool has_mpv = proc->extension_enabled('H');
549553
const bool has_gva = has_mpv;
554+
const reg_t adj_write_mask = sstatus_write_mask & ~reg_t(state->menvcfg->read() & MENVCFG_DTE ? 0 : SSTATUS_SDT);
550555

551-
const reg_t mask = sstatus_write_mask
556+
const reg_t mask = adj_write_mask
552557
| MSTATUS_MIE | MSTATUS_MPIE
553558
| (proc->extension_enabled('U') ? MSTATUS_MPRV : 0)
554559
| MSTATUS_MPP | MSTATUS_TW
@@ -558,12 +563,11 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept {
558563
| (has_mpv ? MSTATUS_MPV : 0)
559564
| (proc->extension_enabled(EXT_SMDBLTRP) ? MSTATUS_MDT : 0)
560565
| (proc->extension_enabled(EXT_ZICFILP) ? (MSTATUS_SPELP | MSTATUS_MPELP) : 0)
561-
| (proc->extension_enabled(EXT_SSDBLTRP) ? SSTATUS_SDT : 0)
562566
;
563567

564568
const reg_t requested_mpp = proc->legalize_privilege(get_field(val, MSTATUS_MPP));
565569
const reg_t adjusted_val = set_field(val, MSTATUS_MPP, requested_mpp);
566-
reg_t new_mstatus = (read() & ~mask) | (adjusted_val & mask);
570+
reg_t new_mstatus = (this->val & ~mask) | (adjusted_val & mask);
567571
new_mstatus = (new_mstatus & MSTATUS_MDT) ? (new_mstatus & ~MSTATUS_MIE) : new_mstatus;
568572
new_mstatus = (new_mstatus & MSTATUS_SDT) ? (new_mstatus & ~MSTATUS_SIE) : new_mstatus;
569573
maybe_flush_tlb(new_mstatus);

riscv/csrs.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,7 @@ class mstatus_csr_t final: public base_status_csr_t {
255255
public:
256256
mstatus_csr_t(processor_t* const proc, const reg_t addr);
257257

258-
reg_t read() const noexcept override {
259-
return val;
260-
}
258+
reg_t read() const noexcept override;
261259

262260
protected:
263261
virtual bool unlogged_write(const reg_t val) noexcept override;

0 commit comments

Comments
 (0)