aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Johnson <scott.johnson@arilinc.com>2021-09-22 18:40:04 -0700
committerScott Johnson <scott.johnson@arilinc.com>2021-09-26 17:17:53 -0700
commit1fe77945de9bacaf1e10f05b1dad4d115c552216 (patch)
tree52c911002f7371a5569385eb6d2e39387050eb34
parentbfcf4707b301230542816fd7bd71f89d57d3ef16 (diff)
downloadriscv-isa-sim-1fe77945de9bacaf1e10f05b1dad4d115c552216.zip
riscv-isa-sim-1fe77945de9bacaf1e10f05b1dad4d115c552216.tar.gz
riscv-isa-sim-1fe77945de9bacaf1e10f05b1dad4d115c552216.tar.bz2
Convert dcsr to csr_t
-rw-r--r--riscv/csrs.cc44
-rw-r--r--riscv/csrs.h14
-rw-r--r--riscv/execute.cc2
-rw-r--r--riscv/insns/dret.h4
-rw-r--r--riscv/processor.cc41
-rw-r--r--riscv/processor.h2
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;