diff --git a/debug_rom/debug_rom.S b/debug_rom/debug_rom.S index 2d361397e3..6ed1d21433 100755 --- a/debug_rom/debug_rom.S +++ b/debug_rom/debug_rom.S @@ -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. @@ -47,6 +52,7 @@ _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 @@ -54,6 +60,8 @@ 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, @@ -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. diff --git a/debug_rom/debug_rom.h b/debug_rom/debug_rom.h index 7edd5f68f9..92fa505f82 100644 --- a/debug_rom/debug_rom.h +++ b/debug_rom/debug_rom.h @@ -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; diff --git a/riscv/csrs.cc b/riscv/csrs.cc index ea535f6fe3..a1142d9510 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -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), @@ -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; } @@ -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(get_field(val, DCSR_PELP)) : elp_t::NO_LP_EXPECTED; cetrig = proc->extension_enabled(EXT_SMDBLTRP) ? get_field(val, DCSR_CETRIG) : false; diff --git a/riscv/csrs.h b/riscv/csrs.h index 278bdb3713..cd4f36937d 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -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; diff --git a/riscv/mmu.h b/riscv/mmu.h index 224b8f5954..0eb899419e 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -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); }