diff options
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/csrs.cc | 10 | ||||
-rw-r--r-- | riscv/csrs.h | 6 | ||||
-rw-r--r-- | riscv/insns/dret.h | 2 | ||||
-rw-r--r-- | riscv/processor.cc | 12 | ||||
-rw-r--r-- | riscv/processor.h | 2 |
5 files changed, 20 insertions, 12 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 0badeaa..abd1580 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1047,3 +1047,13 @@ void debug_mode_csr_t::verify_permissions(insn_t insn, bool write) const { if (!state->debug_mode) throw trap_illegal_instruction(insn.bits()); } + +dpc_csr_t::dpc_csr_t(processor_t* const proc, const reg_t addr): + epc_csr_t(proc, addr) { +} + +void dpc_csr_t::verify_permissions(insn_t insn, bool write) const { + epc_csr_t::verify_permissions(insn, write); + if (!state->debug_mode) + throw trap_illegal_instruction(insn.bits()); +} diff --git a/riscv/csrs.h b/riscv/csrs.h index c293554..c9c5584 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -537,4 +537,10 @@ class debug_mode_csr_t: public basic_csr_t { typedef std::shared_ptr<tdata2_csr_t> tdata2_csr_t_p; +class dpc_csr_t: public epc_csr_t { + public: + dpc_csr_t(processor_t* const proc, const reg_t addr); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; + #endif diff --git a/riscv/insns/dret.h b/riscv/insns/dret.h index ba503a0..2b4c9cd 100644 --- a/riscv/insns/dret.h +++ b/riscv/insns/dret.h @@ -1,5 +1,5 @@ require(STATE.debug_mode); -set_pc_and_serialize(STATE.dpc); +set_pc_and_serialize(STATE.dpc->read()); p->set_privilege(STATE.dcsr.prv); /* We're not in Debug Mode anymore. */ diff --git a/riscv/processor.cc b/riscv/processor.cc index 2fa9118..7003d1c 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -496,7 +496,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_VSSTATUS] = vsstatus = std::make_shared<vsstatus_csr_t>(proc, CSR_VSSTATUS); csrmap[CSR_SSTATUS] = sstatus = std::make_shared<sstatus_csr_t>(proc, nonvirtual_sstatus, vsstatus); - dpc = 0; + 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)); @@ -795,7 +795,7 @@ void processor_t::enter_debug_mode(uint8_t cause) state.dcsr.cause = cause; state.dcsr.prv = state.prv; set_privilege(PRV_M); - state.dpc = state.pc; + state.dpc->write(state.pc); state.pc = DEBUG_ROM_ENTRY; } @@ -1004,9 +1004,6 @@ void processor_t::set_csr(int which, reg_t val) state.dcsr.ebreaku = get_field(val, DCSR_EBREAKU); state.dcsr.halt = get_field(val, DCSR_HALT); break; - case CSR_DPC: - state.dpc = val & ~(reg_t)1; - break; case CSR_VSTART: dirty_vs_state; VU.vstart = val & (VU.get_vlen() - 1); @@ -1051,7 +1048,6 @@ void processor_t::set_csr(int which, reg_t val) break; case CSR_DCSR: - case CSR_DPC: case CSR_SENTROPY: LOG_CSR(which); break; @@ -1132,10 +1128,6 @@ reg_t processor_t::get_csr(int which, insn_t insn, bool write, bool peek) v = set_field(v, DCSR_PRV, state.dcsr.prv); ret(v); } - case CSR_DPC: - if (!state.debug_mode) - break; - ret(state.dpc & pc_alignment_mask()); case CSR_VSTART: require_vector_vs; if (!extension_enabled('V')) diff --git a/riscv/processor.h b/riscv/processor.h index bd1c85b..36422b3 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -201,7 +201,7 @@ struct state_t csr_t_p vstval; csr_t_p vsatp; - reg_t dpc; + csr_t_p dpc; dcsr_t dcsr; csr_t_p tselect; mcontrol_t mcontrol[num_triggers]; |