aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2019-07-12 12:35:14 -0700
committerGitHub <noreply@github.com>2019-07-12 12:35:14 -0700
commitb1bde2b904cd681c902d7c42c34bc55b4f4922ac (patch)
tree7ad36c124bae087ccec44db12d078a2f08f4740a
parent2449351989ada4faae1d8b54fa33f6532ba5ddef (diff)
parenta21e1433ee8223cd4981e0f536bf4fafabe05e3c (diff)
downloadspike-b1bde2b904cd681c902d7c42c34bc55b4f4922ac.zip
spike-b1bde2b904cd681c902d7c42c34bc55b4f4922ac.tar.gz
spike-b1bde2b904cd681c902d7c42c34bc55b4f4922ac.tar.bz2
Merge pull request #309 from riscv/dret
Fix DRET in M-mode, and change how D-mode is represented
-rw-r--r--riscv/execute.cc6
-rw-r--r--riscv/insns/dret.h4
-rw-r--r--riscv/mmu.cc2
-rw-r--r--riscv/processor.cc9
-rw-r--r--riscv/processor.h6
5 files changed, 15 insertions, 12 deletions
diff --git a/riscv/execute.cc b/riscv/execute.cc
index 54e293d..822d934 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -85,13 +85,13 @@ static reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch)
bool processor_t::slow_path()
{
- return debug || state.single_step != state.STEP_NONE || state.dcsr.cause;
+ return debug || state.single_step != state.STEP_NONE || state.debug_mode;
}
// fetch/decode/execute loop
void processor_t::step(size_t n)
{
- if (state.dcsr.cause == DCSR_CAUSE_NONE) {
+ if (!state.debug_mode) {
if (halt_request) {
enter_debug_mode(DCSR_CAUSE_DEBUGINT);
} // !!!The halt bit in DCSR is deprecated.
@@ -130,7 +130,7 @@ void processor_t::step(size_t n)
{
if (unlikely(!state.serialized && state.single_step == state.STEP_STEPPED)) {
state.single_step = state.STEP_NONE;
- if (state.dcsr.cause == DCSR_CAUSE_NONE) {
+ if (!state.debug_mode) {
enter_debug_mode(DCSR_CAUSE_STEP);
// enter_debug_mode changed state.pc, so we can't just continue.
break;
diff --git a/riscv/insns/dret.h b/riscv/insns/dret.h
index 35c19cb..ba503a0 100644
--- a/riscv/insns/dret.h
+++ b/riscv/insns/dret.h
@@ -1,9 +1,9 @@
-require_privilege(PRV_M);
+require(STATE.debug_mode);
set_pc_and_serialize(STATE.dpc);
p->set_privilege(STATE.dcsr.prv);
/* We're not in Debug Mode anymore. */
-STATE.dcsr.cause = 0;
+STATE.debug_mode = false;
if (STATE.dcsr.step)
STATE.single_step = STATE.STEP_STEPPING;
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 506b99f..a0e500b 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -51,7 +51,7 @@ reg_t mmu_t::translate(reg_t addr, reg_t len, access_type type)
reg_t mode = proc->state.prv;
if (type != FETCH) {
- if (!proc->state.dcsr.cause && get_field(proc->state.mstatus, MSTATUS_MPRV))
+ if (!proc->state.debug_mode && get_field(proc->state.mstatus, MSTATUS_MPRV))
mode = get_field(proc->state.mstatus, MSTATUS_MPP);
}
diff --git a/riscv/processor.cc b/riscv/processor.cc
index ca49b41..f97e9b8 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -277,7 +277,7 @@ void processor_t::take_interrupt(reg_t pending_interrupts)
if (enabled_interrupts == 0)
enabled_interrupts = pending_interrupts & state.mideleg & -s_enabled;
- if (state.dcsr.cause == 0 && enabled_interrupts) {
+ if (!state.debug_mode && enabled_interrupts) {
// nonstandard interrupts have highest priority
if (enabled_interrupts >> IRQ_M_EXT)
enabled_interrupts = enabled_interrupts >> IRQ_M_EXT << IRQ_M_EXT;
@@ -331,6 +331,7 @@ void processor_t::set_privilege(reg_t prv)
void processor_t::enter_debug_mode(uint8_t cause)
{
+ state.debug_mode = true;
state.dcsr.cause = cause;
state.dcsr.prv = state.prv;
set_privilege(PRV_M);
@@ -348,7 +349,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
t.get_tval());
}
- if (state.dcsr.cause) {
+ if (state.debug_mode) {
if (t.cause() == CAUSE_BREAKPOINT) {
state.pc = DEBUG_ROM_ENTRY;
} else {
@@ -606,7 +607,7 @@ void processor_t::set_csr(int which, reg_t val)
case CSR_TDATA1:
{
mcontrol_t *mc = &state.mcontrol[state.tselect];
- if (mc->dmode && !state.dcsr.cause) {
+ if (mc->dmode && !state.debug_mode) {
break;
}
mc->dmode = get_field(val, MCONTROL_DMODE(xlen));
@@ -629,7 +630,7 @@ void processor_t::set_csr(int which, reg_t val)
}
break;
case CSR_TDATA2:
- if (state.mcontrol[state.tselect].dmode && !state.dcsr.cause) {
+ if (state.mcontrol[state.tselect].dmode && !state.debug_mode) {
break;
}
if (state.tselect < state.num_triggers) {
diff --git a/riscv/processor.h b/riscv/processor.h
index 8e68fb3..0477c3e 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -232,12 +232,14 @@ struct state_t
reg_t stvec;
reg_t satp;
reg_t scause;
+
reg_t dpc;
reg_t dscratch;
dcsr_t dcsr;
reg_t tselect;
mcontrol_t mcontrol[num_triggers];
reg_t tdata2[num_triggers];
+ bool debug_mode;
static const int n_pmp = 16;
uint8_t pmpcfg[n_pmp];
@@ -330,13 +332,13 @@ public:
bool debug;
// When true, take the slow simulation path.
bool slow_path();
- bool halted() { return state.dcsr.cause ? true : false; }
+ bool halted() { return state.debug_mode; }
bool halt_request;
// Return the index of a trigger that matched, or -1.
inline int trigger_match(trigger_operation_t operation, reg_t address, reg_t data)
{
- if (state.dcsr.cause)
+ if (state.debug_mode)
return -1;
bool chain_ok = true;