diff options
author | Andrew Waterman <andrew@sifive.com> | 2023-05-24 13:51:34 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2023-05-25 14:35:42 -0700 |
commit | d99efb545cca366a159dc1dedcbbd08fa2b3b8cf (patch) | |
tree | 56933e75e6963c14080a179315b48ac0ca6895e4 | |
parent | e910707051c4e10889f58229443bf9d41652ed7b (diff) | |
download | riscv-isa-sim-d99efb545cca366a159dc1dedcbbd08fa2b3b8cf.zip riscv-isa-sim-d99efb545cca366a159dc1dedcbbd08fa2b3b8cf.tar.gz riscv-isa-sim-d99efb545cca366a159dc1dedcbbd08fa2b3b8cf.tar.bz2 |
Implement dcsr.v and make DRET use it
Resolves #1365
-rw-r--r-- | riscv/csrs.cc | 8 | ||||
-rw-r--r-- | riscv/csrs.h | 3 | ||||
-rw-r--r-- | riscv/insns/dret.h | 1 | ||||
-rw-r--r-- | riscv/processor.cc | 2 |
4 files changed, 11 insertions, 3 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 9a165eb..95b5e22 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -13,6 +13,8 @@ #include "trap.h" // For require(): #include "insn_macros.h" +// For CSR_DCSR_V: +#include "debug_defines.h" // STATE macro used by require_privilege() macro: #undef STATE @@ -1234,6 +1236,7 @@ dcsr_csr_t::dcsr_csr_t(processor_t* const proc, const reg_t addr): ebreaks(false), ebreaku(false), halt(false), + v(false), cause(0) { } @@ -1255,6 +1258,7 @@ reg_t dcsr_csr_t::read() const noexcept { result = set_field(result, DCSR_CAUSE, cause); result = set_field(result, DCSR_STEP, step); result = set_field(result, DCSR_PRV, prv); + result = set_field(result, CSR_DCSR_V, v); return result; } @@ -1267,12 +1271,14 @@ bool dcsr_csr_t::unlogged_write(const reg_t val) noexcept { ebreaks = get_field(val, DCSR_EBREAKS); ebreaku = get_field(val, DCSR_EBREAKU); halt = get_field(val, DCSR_HALT); + v = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_V) : false; return true; } -void dcsr_csr_t::write_cause_and_prv(uint8_t cause, reg_t prv) noexcept { +void dcsr_csr_t::write_cause_and_prv(uint8_t cause, reg_t prv, bool v) noexcept { this->cause = cause; this->prv = prv; + this->v = v; log_write(); } diff --git a/riscv/csrs.h b/riscv/csrs.h index 65be799..19aefca 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -656,7 +656,7 @@ class dcsr_csr_t: public csr_t { dcsr_csr_t(processor_t* const proc, const reg_t addr); virtual void verify_permissions(insn_t insn, bool write) const override; virtual reg_t read() const noexcept override; - void write_cause_and_prv(uint8_t cause, reg_t prv) noexcept; + void write_cause_and_prv(uint8_t cause, reg_t prv, bool v) noexcept; protected: virtual bool unlogged_write(const reg_t val) noexcept override; public: @@ -667,6 +667,7 @@ class dcsr_csr_t: public csr_t { bool ebreaks; bool ebreaku; bool halt; + bool v; uint8_t cause; }; diff --git a/riscv/insns/dret.h b/riscv/insns/dret.h index 56ce25b..0540c51 100644 --- a/riscv/insns/dret.h +++ b/riscv/insns/dret.h @@ -1,6 +1,7 @@ require(STATE.debug_mode); set_pc_and_serialize(STATE.dpc->read()); p->set_privilege(STATE.dcsr->prv); +p->set_virt(STATE.dcsr->v); if (STATE.prv < PRV_M) STATE.mstatus->write(STATE.mstatus->read() & ~MSTATUS_MPRV); diff --git a/riscv/processor.cc b/riscv/processor.cc index 23284b8..3d13f4e 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -763,7 +763,7 @@ void processor_t::set_virt(bool virt) void processor_t::enter_debug_mode(uint8_t cause) { state.debug_mode = true; - state.dcsr->write_cause_and_prv(cause, state.prv); + state.dcsr->write_cause_and_prv(cause, state.prv, state.v); set_privilege(PRV_M); state.dpc->write(state.pc); state.pc = DEBUG_ROM_ENTRY; |