Browse Source

Merge pull request #309 from riscv/dret

Fix DRET in M-mode, and change how D-mode is represented
pull/311/head
Andrew Waterman 7 years ago
committed by GitHub
parent
commit
b1bde2b904
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      riscv/execute.cc
  2. 4
      riscv/insns/dret.h
  3. 2
      riscv/mmu.cc
  4. 9
      riscv/processor.cc
  5. 6
      riscv/processor.h

6
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;

4
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;

2
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);
}

9
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) {

6
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;

Loading…
Cancel
Save