#define SSTATUS32_SD 0x80000000
#define SSTATUS64_SD 0x8000000000000000
+#define DCSR_XDEBUGVER (3<<29)
+#define DCSR_HWBPCOUNT (0xfff<<17)
#define DCSR_PRV (3<<14)
+#define DCSR_NDRESET (1<<13)
+#define DCSR_FULLRESET (1<<12)
+#define DCSR_STEP (1<<11)
+#define DCSR_DEBUGINT (1<<10)
+#define DCSR_STOPCYCLE (1<<9)
+#define DCSR_STOPTIME (1<<8)
+#define DCSR_EBREAKM (1<<7)
+#define DCSR_EBREAKH (1<<6)
+#define DCSR_EBREAKS (1<<5)
+#define DCSR_EBREAKU (1<<4)
+#define DCSR_HALT (1<<3)
#define DCSR_CAUSE 7
#define DCSR_CAUSE_NONE 0
switch (step) {
case 0:
// TODO: For now we just assume the target is 64-bit.
- gs.write_debug_ram(0, csrsi(DCSR_ADDRESS, DCSR_HALT_MASK));
- gs.write_debug_ram(1, csrr(S0, DPC_ADDRESS));
+ gs.write_debug_ram(0, csrsi(CSR_DCSR, DCSR_HALT));
+ gs.write_debug_ram(1, csrr(S0, CSR_DPC));
gs.write_debug_ram(2, sd(S0, 0, (uint16_t) DEBUG_RAM_START));
gs.write_debug_ram(3, csrr(S0, CSR_MBADADDR));
gs.write_debug_ram(4, sd(S0, 0, (uint16_t) DEBUG_RAM_START + 8));
switch (step) {
case 0:
gs.write_debug_ram(0, ld(S0, 0, (uint16_t) DEBUG_RAM_START+16));
- gs.write_debug_ram(1, csrw(S0, DPC_ADDRESS));
+ gs.write_debug_ram(1, csrw(S0, CSR_DPC));
if (gs.fence_i_required) {
gs.write_debug_ram(2, fence_i());
gs.write_debug_ram(3, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*3))));
gs.write_debug_ram(3, csrw(S0, CSR_DCSR));
gs.write_debug_ram(4, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*4))));
- reg_t dcsr = gs.dcsr & ~DCSR_HALT_MASK;
- if (single_step)
- dcsr |= DCSR_STEP_MASK;
- else
- dcsr &= ~DCSR_STEP_MASK;
+ reg_t dcsr = set_field(gs.dcsr, DCSR_HALT, 0);
+ dcsr = set_field(dcsr, DCSR_STEP, single_step);
gs.write_debug_ram(5, dcsr);
gs.write_debug_ram(6, gs.saved_mcause);
} else {
if (state.dcsr.cause) {
state.pc = DEBUG_ROM_EXCEPTION;
+ state.dpc = epc;
} else {
state.pc = state.mtvec;
+ state.mepc = epc;
}
state.mcause = t.cause();
- state.mepc = epc;
if (t.has_badaddr())
state.mbadaddr = t.get_badaddr();
case CSR_MSCRATCH: state.mscratch = val; break;
case CSR_MCAUSE: state.mcause = val; break;
case CSR_MBADADDR: state.mbadaddr = val; break;
- case DCSR_ADDRESS:
+ case CSR_DCSR:
// TODO: Use get_field style
- state.dcsr.prv = (val & DCSR_PRV_MASK) >> DCSR_PRV_OFFSET;
- state.dcsr.step = (val & DCSR_STEP_MASK) >> DCSR_STEP_OFFSET;
+ state.dcsr.prv = get_field(val, DCSR_PRV);
+ state.dcsr.step = get_field(val, DCSR_STEP);
// TODO: ndreset and fullreset
- state.dcsr.ebreakm = (val & DCSR_EBREAKM_MASK) >> DCSR_EBREAKM_OFFSET;
- state.dcsr.ebreakh = (val & DCSR_EBREAKH_MASK) >> DCSR_EBREAKH_OFFSET;
- state.dcsr.ebreaks = (val & DCSR_EBREAKS_MASK) >> DCSR_EBREAKS_OFFSET;
- state.dcsr.ebreaku = (val & DCSR_EBREAKU_MASK) >> DCSR_EBREAKU_OFFSET;
- state.dcsr.halt = (val & DCSR_HALT_MASK) >> DCSR_HALT_OFFSET;
+ 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 DPC_ADDRESS:
+ case CSR_DPC:
state.dpc = val;
break;
- case DSCRATCH_ADDRESS:
+ case CSR_DSCRATCH:
state.dscratch = val;
break;
}
case CSR_MTVEC: return state.mtvec;
case CSR_MEDELEG: return state.medeleg;
case CSR_MIDELEG: return state.mideleg;
- case DCSR_ADDRESS:
+ case CSR_DCSR:
{
- uint32_t value =
- (1 << DCSR_XDEBUGVER_OFFSET) |
- (0 << DCSR_HWBPCOUNT_OFFSET) |
- (0 << DCSR_NDRESET_OFFSET) |
- (0 << DCSR_FULLRESET_OFFSET) |
- (state.dcsr.prv << DCSR_PRV_OFFSET) |
- (state.dcsr.step << DCSR_STEP_OFFSET) |
- (sim->debug_module.get_interrupt(id) << DCSR_DEBUGINT_OFFSET) |
- (0 << DCSR_STOPCYCLE_OFFSET) |
- (0 << DCSR_STOPTIME_OFFSET) |
- (state.dcsr.ebreakm << DCSR_EBREAKM_OFFSET) |
- (state.dcsr.ebreakh << DCSR_EBREAKH_OFFSET) |
- (state.dcsr.ebreaks << DCSR_EBREAKS_OFFSET) |
- (state.dcsr.ebreaku << DCSR_EBREAKU_OFFSET) |
- (state.dcsr.halt << DCSR_HALT_OFFSET) |
- (state.dcsr.cause << DCSR_CAUSE_OFFSET);
- return value;
+ uint32_t v = 0;
+ v = set_field(v, DCSR_XDEBUGVER, 1);
+ v = set_field(v, DCSR_HWBPCOUNT, 0);
+ v = set_field(v, DCSR_NDRESET, 0);
+ v = set_field(v, DCSR_FULLRESET, 0);
+ v = set_field(v, DCSR_PRV, state.dcsr.prv);
+ v = set_field(v, DCSR_STEP, state.dcsr.step);
+ v = set_field(v, DCSR_DEBUGINT, sim->debug_module.get_interrupt(id));
+ v = set_field(v, DCSR_STOPCYCLE, 0);
+ v = set_field(v, DCSR_STOPTIME, 0);
+ 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_HALT, state.dcsr.halt);
+ v = set_field(v, DCSR_CAUSE, state.dcsr.cause);
+ return v;
}
- case DPC_ADDRESS:
+ case CSR_DPC:
return state.dpc;
- case DSCRATCH_ADDRESS:
+ case CSR_DSCRATCH:
return state.dscratch;
}
throw trap_illegal_instruction();