diff options
-rw-r--r-- | riscv/csrs.cc | 44 | ||||
-rw-r--r-- | riscv/csrs.h | 14 | ||||
-rw-r--r-- | riscv/execute.cc | 2 | ||||
-rw-r--r-- | riscv/insns/dret.h | 4 | ||||
-rw-r--r-- | riscv/processor.cc | 41 | ||||
-rw-r--r-- | riscv/processor.h | 2 |
6 files changed, 65 insertions, 42 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index abd1580..4ff2b99 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1057,3 +1057,47 @@ void dpc_csr_t::verify_permissions(insn_t insn, bool write) const { if (!state->debug_mode) throw trap_illegal_instruction(insn.bits()); } + + +dcsr_csr_t::dcsr_csr_t(processor_t* const proc, const reg_t addr): + csr_t(proc, addr) { +} + +void dcsr_csr_t::verify_permissions(insn_t insn, bool write) const { + csr_t::verify_permissions(insn, write); + if (!state->debug_mode) + throw trap_illegal_instruction(insn.bits()); +} + +reg_t dcsr_csr_t::read() const noexcept { + uint32_t v = 0; + v = set_field(v, DCSR_XDEBUGVER, 1); + v = set_field(v, DCSR_EBREAKM, ebreakm); + v = set_field(v, DCSR_EBREAKH, ebreakh); + v = set_field(v, DCSR_EBREAKS, ebreaks); + v = set_field(v, DCSR_EBREAKU, ebreaku); + v = set_field(v, DCSR_STOPCYCLE, 0); + v = set_field(v, DCSR_STOPTIME, 0); + v = set_field(v, DCSR_CAUSE, cause); + v = set_field(v, DCSR_STEP, step); + v = set_field(v, DCSR_PRV, prv); + return v; +} + +bool dcsr_csr_t::unlogged_write(const reg_t val) noexcept { + prv = get_field(val, DCSR_PRV); + step = get_field(val, DCSR_STEP); + // TODO: ndreset and fullreset + ebreakm = get_field(val, DCSR_EBREAKM); + ebreakh = get_field(val, DCSR_EBREAKH); + ebreaks = get_field(val, DCSR_EBREAKS); + ebreaku = get_field(val, DCSR_EBREAKU); + halt = get_field(val, DCSR_HALT); + return true; +} + +void dcsr_csr_t::write_cause_and_prv(uint8_t cause, reg_t prv) noexcept { + this->cause = cause; + this->prv = prv; + log_write(); +} diff --git a/riscv/csrs.h b/riscv/csrs.h index 9cae5c6..1fe7ddf 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -543,8 +543,15 @@ class dpc_csr_t: public epc_csr_t { virtual void verify_permissions(insn_t insn, bool write) const override; }; -typedef struct -{ +class dcsr_csr_t: public csr_t { + public: + 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; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; + public: uint8_t prv; bool step; bool ebreakm; @@ -553,7 +560,8 @@ typedef struct bool ebreaku; bool halt; uint8_t cause; -} dcsr_t; +}; +typedef std::shared_ptr<dcsr_csr_t> dcsr_csr_t_p; #endif diff --git a/riscv/execute.cc b/riscv/execute.cc index ed64277..95471a9 100644 --- a/riscv/execute.cc +++ b/riscv/execute.cc @@ -227,7 +227,7 @@ void processor_t::step(size_t n) } else if (halt_request == HR_GROUP) { enter_debug_mode(DCSR_CAUSE_GROUP); } // !!!The halt bit in DCSR is deprecated. - else if (state.dcsr.halt) { + else if (state.dcsr->halt) { enter_debug_mode(DCSR_CAUSE_HALT); } } diff --git a/riscv/insns/dret.h b/riscv/insns/dret.h index 2b4c9cd..01a3992 100644 --- a/riscv/insns/dret.h +++ b/riscv/insns/dret.h @@ -1,9 +1,9 @@ require(STATE.debug_mode); set_pc_and_serialize(STATE.dpc->read()); -p->set_privilege(STATE.dcsr.prv); +p->set_privilege(STATE.dcsr->prv); /* We're not in Debug Mode anymore. */ STATE.debug_mode = false; -if (STATE.dcsr.step) +if (STATE.dcsr->step) STATE.single_step = STATE.STEP_STEPPING; diff --git a/riscv/processor.cc b/riscv/processor.cc index 7003d1c..cf57c82 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -499,7 +499,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_DPC] = dpc = std::make_shared<dpc_csr_t>(proc, CSR_DPC); csrmap[CSR_DSCRATCH0] = std::make_shared<debug_mode_csr_t>(proc, CSR_DSCRATCH0); csrmap[CSR_DSCRATCH1] = std::make_shared<debug_mode_csr_t>(proc, CSR_DSCRATCH1); - memset(&this->dcsr, 0, sizeof(this->dcsr)); + csrmap[CSR_DCSR] = dcsr = std::make_shared<dcsr_csr_t>(proc, CSR_DCSR); csrmap[CSR_TSELECT] = tselect = std::make_shared<tselect_csr_t>(proc, CSR_TSELECT); memset(this->mcontrol, 0, sizeof(this->mcontrol)); @@ -612,7 +612,7 @@ void processor_t::reset() { xlen = max_xlen; state.reset(this, max_isa); - state.dcsr.halt = halt_on_reset; + state.dcsr->halt = halt_on_reset; halt_on_reset = false; VU.reset(); @@ -792,8 +792,7 @@ void processor_t::set_virt(bool virt) void processor_t::enter_debug_mode(uint8_t cause) { state.debug_mode = true; - state.dcsr.cause = cause; - state.dcsr.prv = state.prv; + state.dcsr->write_cause_and_prv(cause, state.prv); set_privilege(PRV_M); state.dpc->write(state.pc); state.pc = DEBUG_ROM_ENTRY; @@ -833,9 +832,9 @@ void processor_t::take_trap(trap_t& t, reg_t epc) } if (t.cause() == CAUSE_BREAKPOINT && ( - (state.prv == PRV_M && state.dcsr.ebreakm) || - (state.prv == PRV_S && state.dcsr.ebreaks) || - (state.prv == PRV_U && state.dcsr.ebreaku))) { + (state.prv == PRV_M && state.dcsr->ebreakm) || + (state.prv == PRV_S && state.dcsr->ebreaks) || + (state.prv == PRV_U && state.dcsr->ebreaku))) { enter_debug_mode(DCSR_CAUSE_SWBP); return; } @@ -994,16 +993,6 @@ void processor_t::set_csr(int which, reg_t val) VU.vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT; VU.vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT; break; - case CSR_DCSR: - state.dcsr.prv = get_field(val, DCSR_PRV); - state.dcsr.step = get_field(val, DCSR_STEP); - // TODO: ndreset and fullreset - state.dcsr.ebreakm = get_field(val, DCSR_EBREAKM); - state.dcsr.ebreakh = get_field(val, DCSR_EBREAKH); - state.dcsr.ebreaks = get_field(val, DCSR_EBREAKS); - state.dcsr.ebreaku = get_field(val, DCSR_EBREAKU); - state.dcsr.halt = get_field(val, DCSR_HALT); - break; case CSR_VSTART: dirty_vs_state; VU.vstart = val & (VU.get_vlen() - 1); @@ -1047,7 +1036,6 @@ void processor_t::set_csr(int which, reg_t val) LOG_CSR(CSR_VXRM); break; - case CSR_DCSR: case CSR_SENTROPY: LOG_CSR(which); break; @@ -1111,23 +1099,6 @@ reg_t processor_t::get_csr(int which, insn_t insn, bool write, bool peek) case CSR_MVENDORID: ret(0); case CSR_MHARTID: ret(id); case CSR_TDATA3: ret(0); - case CSR_DCSR: - { - if (!state.debug_mode) - break; - uint32_t v = 0; - v = set_field(v, DCSR_XDEBUGVER, 1); - v = set_field(v, DCSR_EBREAKM, state.dcsr.ebreakm); - v = set_field(v, DCSR_EBREAKH, state.dcsr.ebreakh); - v = set_field(v, DCSR_EBREAKS, state.dcsr.ebreaks); - v = set_field(v, DCSR_EBREAKU, state.dcsr.ebreaku); - v = set_field(v, DCSR_STOPCYCLE, 0); - v = set_field(v, DCSR_STOPTIME, 0); - v = set_field(v, DCSR_CAUSE, state.dcsr.cause); - v = set_field(v, DCSR_STEP, state.dcsr.step); - v = set_field(v, DCSR_PRV, state.dcsr.prv); - ret(v); - } case CSR_VSTART: require_vector_vs; if (!extension_enabled('V')) diff --git a/riscv/processor.h b/riscv/processor.h index a594f6b..a9b75fd 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -190,7 +190,7 @@ struct state_t csr_t_p vsatp; csr_t_p dpc; - dcsr_t dcsr; + dcsr_csr_t_p dcsr; csr_t_p tselect; mcontrol_t mcontrol[num_triggers]; tdata2_csr_t_p tdata2; |