diff options
author | Andrew Waterman <andrew@sifive.com> | 2019-07-12 12:35:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-12 12:35:14 -0700 |
commit | b1bde2b904cd681c902d7c42c34bc55b4f4922ac (patch) | |
tree | 7ad36c124bae087ccec44db12d078a2f08f4740a | |
parent | 2449351989ada4faae1d8b54fa33f6532ba5ddef (diff) | |
parent | a21e1433ee8223cd4981e0f536bf4fafabe05e3c (diff) | |
download | spike-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.cc | 6 | ||||
-rw-r--r-- | riscv/insns/dret.h | 4 | ||||
-rw-r--r-- | riscv/mmu.cc | 2 | ||||
-rw-r--r-- | riscv/processor.cc | 9 | ||||
-rw-r--r-- | riscv/processor.h | 6 |
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; |