Skip to content

Commit

Permalink
Add DCSR.MPRVEN support
Browse files Browse the repository at this point in the history
Adds DCSR.MPRVEN bit support, as specified in RISC-V External Debug Support Version 1.0.0-rc4
(https://github.com/riscv/riscv-debug-spec/releases/tag/1.0.0-rc4, see 4.9.1 Debug Control and Status).

This bit allows to enable hardware virtual address translation when memory access
is initiated by the debugger (see 4.1 Debug Mode, clause 2).

This change:
* Increases debug specification coverage, allows more detailed testing of external debuggers with Spike.
* Decreases the number of required abstract commands to read virtual memory thus improving the user experience.

Commit's changes:
* Added MPRVEN field to DCSR register
* Updated debug_rom.S to turn off MPRVEN while executing ROM

To avoid unwanted address translation in while debug_rom.S executed
DCSR.MPRVEN bit has to be cleared on entry and restored on exit.

Updated version of debug_rom.S does the following:
* On _entry: clears DCSR.MPRVEN bit, stores previous DCSR value to S1
  and stores previous S1 value to DSCRATCH01
* On _exception: restores S1 value from DSCRATCH01
* On _resume/going: restores S1 and DCSR values

Signed-off-by: Farid Khaydari <[email protected]>
  • Loading branch information
fk-sc committed Dec 20, 2024
1 parent 88fc84d commit 372448d
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 12 deletions.
12 changes: 11 additions & 1 deletion debug_rom/debug_rom.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ _entry:
// This fence is required because the execution may have written something
// into the Abstract Data or Program Buffer registers.
fence
csrw CSR_DSCRATCH0, s0 // Save s0 to allow signaling MHARTID
csrw CSR_DSCRATCH0, s0 // Save s0 to allow signaling MHARTID

// We need to disable privilege modification to avoid
// address translation in debug_rom memory accesses
csrw CSR_DSCRATCH1, s1 // Save s1
csrrci s1, CSR_DCSR, DCSR_MPRVEN // Save DCSR and clear MPRVEN

// We continue to let the hart know that we are halted in order that
// a DM which was reset is still made aware that a hart is halted.
Expand All @@ -47,13 +52,16 @@ _exception:
// We need this in case the user tried an abstract write to a
// non-existent CSR.
csrr s0, CSR_DSCRATCH0
csrr s1, CSR_DSCRATCH1 // Restore s1
sw zero, DEBUG_ROM_EXCEPTION(zero) // Let debug module know you got an exception.
ebreak

going:
csrr s0, CSR_MHARTID
sw s0, DEBUG_ROM_GOING(zero) // When debug module sees this write, the GO flag is reset.
csrr s0, CSR_DSCRATCH0 // Restore s0 here
csrw CSR_DCSR, s1 // Restore DSCR
csrr s1, CSR_DSCRATCH1 // Restore s1
fence
fence.i
jalr zero, zero, %lo(whereto) // Debug module will put different instructions and data in the RAM,
Expand All @@ -64,6 +72,8 @@ _resume:
csrr s0, CSR_MHARTID
sw s0, DEBUG_ROM_RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset.
csrr s0, CSR_DSCRATCH0 // Restore s0
csrw CSR_DCSR, s1 // Restore DSCR
csrr s1, CSR_DSCRATCH1 // Restore s1
dret

// END OF ACTUAL "ROM" CONTENTS. BELOW IS JUST FOR LINKER SCRIPT.
Expand Down
22 changes: 12 additions & 10 deletions debug_rom/debug_rom.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
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,
0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x40, 0x07, 0x6f, 0x00, 0x00, 0x04,
0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x90, 0x34, 0x7b,
0xf3, 0x74, 0x08, 0x7b, 0x73, 0x24, 0x40, 0xf1, 0x23, 0x20, 0x80, 0x10,
0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x14, 0x00, 0x63, 0x16, 0x04, 0x02,
0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x24, 0x00,
0x63, 0x1e, 0x04, 0x02, 0x73, 0x00, 0x50, 0x10, 0x6f, 0xf0, 0x9f, 0xfd,
0x73, 0x24, 0x20, 0x7b, 0xf3, 0x24, 0x30, 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,
0x73, 0x24, 0x20, 0x7b, 0x73, 0x00, 0x20, 0x7b
0x73, 0x24, 0x20, 0x7b, 0x73, 0x90, 0x04, 0x7b, 0xf3, 0x24, 0x30, 0x7b,
0x0f, 0x00, 0xf0, 0x0f, 0x0f, 0x10, 0x00, 0x00, 0x67, 0x00, 0x00, 0x30,
0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b,
0x73, 0x90, 0x04, 0x7b, 0xf3, 0x24, 0x30, 0x7b, 0x73, 0x00, 0x20, 0x7b
};
static const unsigned int debug_rom_raw_len = 116;
static const unsigned int debug_rom_raw_len = 144;
3 changes: 3 additions & 0 deletions riscv/csrs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,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 @@ -1374,6 +1375,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 @@ -1388,6 +1390,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 @@ -697,6 +697,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 @@ -486,7 +486,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

0 comments on commit 372448d

Please sign in to comment.