Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 47 additions & 11 deletions debug_rom/debug_rom.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@
.global entry
.global exception

// This macro handles mem access with proper management of the MPRVEN
// Usage: MEMORY_ACCESS_WITH_MPRV(<your code>)
#define MEMORY_ACCESS_WITH_MPRV(...) \
csrrci s0, CSR_DCSR, DCSR_MPRVEN; \
andi s0, s0, DCSR_MPRVEN; \
bnez s0, 1f; \
__VA_ARGS__; \
j 2f; \
1: \
__VA_ARGS__; \
csrrsi zero, CSR_DCSR, DCSR_MPRVEN; \
2:

// Entry location on ebreak, Halt, or Breakpoint
// It is the same for all harts. They branch when
// their GO or RESUME bit is set.
Expand All @@ -30,13 +43,22 @@ _entry:
// We keep checking both whether there is something the debugger wants
// us to do, or whether we should resume.
entry_loop:
csrr s0, CSR_MHARTID
sw s0, DEBUG_ROM_HALTED(zero)
lbu s0, DEBUG_ROM_FLAGS(s0) // 1 byte flag per hart. Only one hart advances here.
// 1 byte flag per hart. Only one hart advances here.
MEMORY_ACCESS_WITH_MPRV(
csrr s0, CSR_MHARTID;
sw s0, DEBUG_ROM_HALTED(zero);
lbu s0, DEBUG_ROM_FLAGS(s0);
)

andi s0, s0, (1 << DEBUG_ROM_FLAG_GO)
bnez s0, going
csrr s0, CSR_MHARTID
lbu s0, DEBUG_ROM_FLAGS(s0) // multiple harts can resume here

// multiple harts can resume here
MEMORY_ACCESS_WITH_MPRV(
csrr s0, CSR_MHARTID;
lbu s0, DEBUG_ROM_FLAGS(s0);
)

andi s0, s0, (1 << DEBUG_ROM_FLAG_RESUME)
bnez s0, _resume
wfi
Expand All @@ -46,13 +68,23 @@ _exception:
// Restore S0, which we always save to dscratch.
// We need this in case the user tried an abstract write to a
// non-existent CSR.
csrr s0, CSR_DSCRATCH0
sw zero, DEBUG_ROM_EXCEPTION(zero) // Let debug module know you got an exception.


// Let debug module know you got an exception.
MEMORY_ACCESS_WITH_MPRV(
csrr s0, CSR_DSCRATCH0;
sw zero, DEBUG_ROM_EXCEPTION(zero);
)

ebreak

going:
csrr s0, CSR_MHARTID
sw s0, DEBUG_ROM_GOING(zero) // When debug module sees this write, the GO flag is reset.
// When debug module sees this write, the GO flag is reset.
MEMORY_ACCESS_WITH_MPRV(
csrr s0, CSR_MHARTID;
sw s0, DEBUG_ROM_GOING(zero);
)

csrr s0, CSR_DSCRATCH0 // Restore s0 here
fence
fence.i
Expand All @@ -61,8 +93,12 @@ going:
// because jalr is special there)

_resume:
csrr s0, CSR_MHARTID
sw s0, DEBUG_ROM_RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset.
// When Debug Module sees this write, the RESUME flag is reset.
MEMORY_ACCESS_WITH_MPRV(
csrr s0, CSR_MHARTID;
sw s0, DEBUG_ROM_RESUMING(zero);
)

csrr s0, CSR_DSCRATCH0 // Restore s0
dret

Expand Down
32 changes: 22 additions & 10 deletions debug_rom/debug_rom.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
static const unsigned char debug_rom_raw[] = {
0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x00, 0x06, 0x6f, 0x00, 0x80, 0x03,
0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1,
0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x14, 0x00,
0x63, 0x14, 0x04, 0x02, 0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40,
0x13, 0x74, 0x24, 0x00, 0x63, 0x18, 0x04, 0x02, 0x73, 0x00, 0x50, 0x10,
0x6f, 0xf0, 0x9f, 0xfd, 0x73, 0x24, 0x20, 0x7b, 0x23, 0x26, 0x00, 0x10,
0x73, 0x00, 0x10, 0x00, 0x73, 0x24, 0x40, 0xf1, 0x23, 0x22, 0x80, 0x10,
0x73, 0x24, 0x20, 0x7b, 0x0f, 0x00, 0xf0, 0x0f, 0x0f, 0x10, 0x00, 0x00,
0x67, 0x00, 0x00, 0x30, 0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10,
0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x40, 0x0d, 0x6f, 0x00, 0x40, 0x07,
0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x74, 0x08, 0x7b,
0x13, 0x74, 0x04, 0x01, 0x63, 0x1a, 0x04, 0x00, 0x73, 0x24, 0x40, 0xf1,
0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x6f, 0x00, 0x40, 0x01,
0x73, 0x24, 0x40, 0xf1, 0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40,
0x73, 0x60, 0x08, 0x7b, 0x13, 0x74, 0x14, 0x00, 0x63, 0x10, 0x04, 0x06,
0x73, 0x74, 0x08, 0x7b, 0x13, 0x74, 0x04, 0x01, 0x63, 0x18, 0x04, 0x00,
0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40, 0x6f, 0x00, 0x00, 0x01,
0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40, 0x73, 0x60, 0x08, 0x7b,
0x13, 0x74, 0x24, 0x00, 0x63, 0x14, 0x04, 0x06, 0x73, 0x00, 0x50, 0x10,
0x6f, 0xf0, 0xdf, 0xf9, 0x73, 0x74, 0x08, 0x7b, 0x13, 0x74, 0x04, 0x01,
0x63, 0x18, 0x04, 0x00, 0x73, 0x24, 0x20, 0x7b, 0x23, 0x26, 0x00, 0x10,
0x6f, 0x00, 0x00, 0x01, 0x73, 0x24, 0x20, 0x7b, 0x23, 0x26, 0x00, 0x10,
0x73, 0x60, 0x08, 0x7b, 0x73, 0x00, 0x10, 0x00, 0x73, 0x74, 0x08, 0x7b,
0x13, 0x74, 0x04, 0x01, 0x63, 0x18, 0x04, 0x00, 0x73, 0x24, 0x40, 0xf1,
0x23, 0x22, 0x80, 0x10, 0x6f, 0x00, 0x00, 0x01, 0x73, 0x24, 0x40, 0xf1,
0x23, 0x22, 0x80, 0x10, 0x73, 0x60, 0x08, 0x7b, 0x73, 0x24, 0x20, 0x7b,
0x0f, 0x00, 0xf0, 0x0f, 0x0f, 0x10, 0x00, 0x00, 0x67, 0x00, 0x00, 0x30,
0x73, 0x74, 0x08, 0x7b, 0x13, 0x74, 0x04, 0x01, 0x63, 0x18, 0x04, 0x00,
0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, 0x6f, 0x00, 0x00, 0x01,
0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, 0x73, 0x60, 0x08, 0x7b,
0x73, 0x24, 0x20, 0x7b, 0x73, 0x00, 0x20, 0x7b
};
static const unsigned int debug_rom_raw_len = 116;
static const unsigned int debug_rom_raw_len = 260;
3 changes: 3 additions & 0 deletions riscv/csrs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,7 @@ dcsr_csr_t::dcsr_csr_t(processor_t* const proc, const reg_t addr):
ebreakvs(false),
ebreakvu(false),
v(false),
mprven(false),
cause(0),
ext_cause(0),
cetrig(0),
Expand Down Expand Up @@ -1450,6 +1451,7 @@ reg_t dcsr_csr_t::read() const noexcept {
result = set_field(result, DCSR_STEP, step);
result = set_field(result, DCSR_PRV, prv);
result = set_field(result, CSR_DCSR_V, v);
result = set_field(result, DCSR_MPRVEN, mprven);
result = set_field(result, DCSR_PELP, pelp);
return result;
}
Expand All @@ -1464,6 +1466,7 @@ bool dcsr_csr_t::unlogged_write(const reg_t val) noexcept {
ebreakvs = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_EBREAKVS) : false;
ebreakvu = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_EBREAKVU) : false;
v = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_V) : false;
mprven = get_field(val, CSR_DCSR_MPRVEN);
pelp = proc->extension_enabled(EXT_ZICFILP) ?
static_cast<elp_t>(get_field(val, DCSR_PELP)) : elp_t::NO_LP_EXPECTED;
cetrig = proc->extension_enabled(EXT_SMDBLTRP) ? get_field(val, DCSR_CETRIG) : false;
Expand Down
1 change: 1 addition & 0 deletions riscv/csrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ class dcsr_csr_t: public csr_t {
bool ebreakvs;
bool ebreakvu;
bool v;
bool mprven;
uint8_t cause;
uint8_t ext_cause;
bool cetrig;
Expand Down
2 changes: 1 addition & 1 deletion riscv/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ class mmu_t
{
return proc != nullptr
&& !(proc->state.mnstatus && !get_field(proc->state.mnstatus->read(), MNSTATUS_NMIE))
&& !proc->state.debug_mode
&& (!proc->state.debug_mode || get_field(proc->state.dcsr->read(), DCSR_MPRVEN))
&& get_field(proc->state.mstatus->read(), MSTATUS_MPRV);
}

Expand Down