From a4c6ab62f0121857856aca0496e921253c95405a Mon Sep 17 00:00:00 2001 From: Guanghui Cheng Date: Mon, 2 Mar 2026 10:53:19 +0800 Subject: [PATCH] fix(debug_rom): support DCSR.mprven * Updated debug_rom.S to turn off MPRVEN on memory access --- scripts/debug_rom/debug_rom.S | 38 +++++++++++--- scripts/debug_rom/debug_rom_nonzero.S | 51 ++++++++++++------- .../devices/debug/DebugRomContents.scala | 24 ++++++--- .../debug/DebugRomNonzeroContents.scala | 29 +++++++---- 4 files changed, 100 insertions(+), 42 deletions(-) diff --git a/scripts/debug_rom/debug_rom.S b/scripts/debug_rom/debug_rom.S index 138c81b7a2f..c417c64535f 100755 --- a/scripts/debug_rom/debug_rom.S +++ b/scripts/debug_rom/debug_rom.S @@ -18,6 +18,19 @@ .global entry .global exception +// This macro handles mem access with proper management of the MPRVEN +// Usage: MEMORY_ACCESS_WITH_MPRV() +#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. @@ -40,29 +53,38 @@ _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, HALTED(zero) - lbu s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here. + MEMORY_ACCESS_WITH_MPRV( + csrr s0, CSR_MHARTID; + sw s0, HALTED(zero); + lbu s0, FLAGS(s0); // 1 byte flag per hart. Only one hart advances here. + ) andi s0, s0, (1 << FLAG_GO) | (1 << FLAG_RESUME) beqz s0, entry_loop // Loop until either GO or RESUME is set. andi s0, s0, (1 << FLAG_GO) beqz s0, _resume // If GO is clear at this point, RESUME must be set. - csrr s0, CSR_DSCRATCH0 // Restore s0 here - sw zero, GOING(zero) // When debug module sees this write, the GO flag is reset. + MEMORY_ACCESS_WITH_MPRV( + csrr s0, CSR_DSCRATCH0; // Restore s0 here + sw zero, GOING(zero); // When debug module sees this write, the GO flag is reset. + ) jalr zero, zero, %lo(whereto) // Rocket-Chip has a specific hack which is that jalr in // Debug Mode will flush the I-Cache. We need that so that the // remainder of the variable instructions will be what Debug Module // intends. _resume: - csrr s0, CSR_MHARTID - sw s0, RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset. + MEMORY_ACCESS_WITH_MPRV( + csrr s0, CSR_MHARTID; + sw s0, RESUMING(zero); // When Debug Module sees this write, the RESUME flag is reset. + ) csrr s0, CSR_DSCRATCH0 // Restore s0 dret _exception: - sw zero, EXCEPTION(zero) // Let debug module know you got an exception. + MEMORY_ACCESS_WITH_MPRV( + csrr s0, CSR_DSCRATCH0; + sw zero, EXCEPTION(zero); // Let debug module know you got an exception. + ) ebreak // END OF ACTUAL "ROM" CONTENTS. BELOW IS JUST FOR LINKER SCRIPT. diff --git a/scripts/debug_rom/debug_rom_nonzero.S b/scripts/debug_rom/debug_rom_nonzero.S index 8c529ed0e0d..3286d36de2e 100644 --- a/scripts/debug_rom/debug_rom_nonzero.S +++ b/scripts/debug_rom/debug_rom_nonzero.S @@ -21,6 +21,19 @@ .global entry .global exception +// This macro handles mem access with proper management of the MPRVEN +// Usage: MEMORY_ACCESS_WITH_MPRV() +#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. @@ -33,7 +46,10 @@ entry: // 0x808 exception: csrrw s1, CSR_DSCRATCH1, s1 // s1=base, ds1=s1 - sw zero, EXCEPTION(s1) // Let debug module know you got an exception. + MEMORY_ACCESS_WITH_MPRV( + csrr s0, CSR_DSCRATCH0; + sw zero, EXCEPTION(s1); // Let debug module know you got an exception. + ) _entry: // This fence is required because the execution may have written something @@ -47,31 +63,30 @@ _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, HALTED(s1) - add s0, s0, s1 // s0=base + hartid - lbu s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here. + MEMORY_ACCESS_WITH_MPRV( + csrr s0, CSR_MHARTID; + sw s0, HALTED(s1); + add s0, s0, s1; // s0=base + hartid + lbu s0, FLAGS(s0); // 1 byte flag per hart. Only one hart advances here. + ) andi s0, s0, (1 << FLAG_GO) | (1 << FLAG_RESUME) beqz s0, entry_loop // Loop until either GO or RESUME is set. andi s0, s0, (1 << FLAG_GO) beqz s0, _resume // If GO is clear at this point, RESUME must be set. - csrr s0, CSR_DSCRATCH0 // Restore s0 here - -//TODO: 0x48 is a hack for (icache-entry) constant - jalr zero, 0x48(s1) // Rocket-Chip has a specific hack which is that jalr in - // Debug Mode will flush the I-Cache. We need that so that the - // remainder of the variable instructions will be what Debug Module - // intends. -icache: - sw zero, GOING(s1) // When debug module sees this write, the GO flag is reset. - csrrw s1, CSR_DSCRATCH1, s1 // s1=s1, ds1=base - j whereto + MEMORY_ACCESS_WITH_MPRV( + csrr s0, CSR_DSCRATCH0; // Restore s0 here + sw zero, GOING(s1); // When debug module sees this write, the GO flag is reset. + csrrw s1, CSR_DSCRATCH1, s1; // s1=s1, ds1=base + j whereto; + ) _resume: - csrr s0, CSR_MHARTID - sw s0, RESUMING(s1) // When Debug Module sees this write, the RESUME flag is reset. + MEMORY_ACCESS_WITH_MPRV( + csrr s0, CSR_MHARTID; + sw s0, RESUMING(s1); // When Debug Module sees this write, the RESUME flag is reset. + ) csrr s0, CSR_DSCRATCH0 // Restore s0 csrr s1, CSR_DSCRATCH1 // Restore s1 dret diff --git a/src/main/scala/devices/debug/DebugRomContents.scala b/src/main/scala/devices/debug/DebugRomContents.scala index dc919de78e7..73ed92e479b 100644 --- a/src/main/scala/devices/debug/DebugRomContents.scala +++ b/src/main/scala/devices/debug/DebugRomContents.scala @@ -5,13 +5,23 @@ package freechips.rocketchip.devices.debug object DebugRomContents { def apply() : Array[Byte] = { Array ( - 0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x80, 0x03, 0x6f, 0x00, 0x40, 0x04, - 0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1, - 0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x34, 0x00, - 0xe3, 0x08, 0x04, 0xfe, 0x13, 0x74, 0x14, 0x00, 0x63, 0x08, 0x04, 0x00, - 0x73, 0x24, 0x20, 0x7b, 0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30, - 0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b, - 0x73, 0x00, 0x20, 0x7b, 0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00 + 0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x40, 0x07, 0x6f, 0x00, 0xc0, 0x09, + 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, 0x34, 0x00, 0xe3, 0x08, 0x04, 0xfc, + 0x13, 0x74, 0x14, 0x00, 0x63, 0x06, 0x04, 0x02, 0x73, 0x74, 0x08, 0x7b, + 0x13, 0x74, 0x04, 0x01, 0x63, 0x18, 0x04, 0x00, 0x73, 0x24, 0x20, 0x7b, + 0x23, 0x22, 0x00, 0x10, 0x6f, 0x00, 0x00, 0x01, 0x73, 0x24, 0x20, 0x7b, + 0x23, 0x22, 0x00, 0x10, 0x73, 0x60, 0x08, 0x7b, 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, 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 ).map(_.toByte) } } diff --git a/src/main/scala/devices/debug/DebugRomNonzeroContents.scala b/src/main/scala/devices/debug/DebugRomNonzeroContents.scala index 65be23ca1cc..75ab802b9c8 100644 --- a/src/main/scala/devices/debug/DebugRomNonzeroContents.scala +++ b/src/main/scala/devices/debug/DebugRomNonzeroContents.scala @@ -5,15 +5,26 @@ package freechips.rocketchip.devices.debug object DebugRomNonzeroContents { def apply() : Array[Byte] = { Array ( - 0x73, 0x90, 0x34, 0x7b, 0x6f, 0x00, 0xc0, 0x00, 0xf3, 0x94, 0x34, 0x7b, - 0x23, 0xa6, 0x04, 0x90, 0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, - 0x97, 0x04, 0x00, 0x00, 0x93, 0x84, 0x84, 0xfe, 0x73, 0x24, 0x40, 0xf1, - 0x23, 0xa0, 0x84, 0x90, 0x33, 0x04, 0x94, 0x00, 0x03, 0x44, 0x04, 0xc0, - 0x13, 0x74, 0x34, 0x00, 0xe3, 0x06, 0x04, 0xfe, 0x13, 0x74, 0x14, 0x00, - 0x63, 0x0c, 0x04, 0x00, 0x73, 0x24, 0x20, 0x7b, 0x67, 0x80, 0x84, 0x04, - 0x23, 0xa2, 0x04, 0x90, 0xf3, 0x94, 0x34, 0x7b, 0x6f, 0xf0, 0x1f, 0xab, - 0x73, 0x24, 0x40, 0xf1, 0x23, 0xa4, 0x84, 0x90, 0x73, 0x24, 0x20, 0x7b, - 0xf3, 0x24, 0x30, 0x7b, 0x73, 0x00, 0x20, 0x7b + 0x73, 0x90, 0x34, 0x7b, 0x6f, 0x00, 0xc0, 0x02, 0xf3, 0x94, 0x34, 0x7b, + 0x73, 0x74, 0x08, 0x7b, 0x13, 0x74, 0x04, 0x01, 0x63, 0x18, 0x04, 0x00, + 0x73, 0x24, 0x20, 0x7b, 0x23, 0xa6, 0x04, 0x90, 0x6f, 0x00, 0x00, 0x01, + 0x73, 0x24, 0x20, 0x7b, 0x23, 0xa6, 0x04, 0x90, 0x73, 0x60, 0x08, 0x7b, + 0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x97, 0x04, 0x00, 0x00, + 0x93, 0x84, 0x84, 0xfc, 0x73, 0x74, 0x08, 0x7b, 0x13, 0x74, 0x04, 0x01, + 0x63, 0x1c, 0x04, 0x00, 0x73, 0x24, 0x40, 0xf1, 0x23, 0xa0, 0x84, 0x90, + 0x33, 0x04, 0x94, 0x00, 0x03, 0x44, 0x04, 0xc0, 0x6f, 0x00, 0x80, 0x01, + 0x73, 0x24, 0x40, 0xf1, 0x23, 0xa0, 0x84, 0x90, 0x33, 0x04, 0x94, 0x00, + 0x03, 0x44, 0x04, 0xc0, 0x73, 0x60, 0x08, 0x7b, 0x13, 0x74, 0x34, 0x00, + 0xe3, 0x04, 0x04, 0xfc, 0x13, 0x74, 0x14, 0x00, 0x63, 0x0c, 0x04, 0x02, + 0x73, 0x74, 0x08, 0x7b, 0x13, 0x74, 0x04, 0x01, 0x63, 0x1c, 0x04, 0x00, + 0x73, 0x24, 0x20, 0x7b, 0x23, 0xa2, 0x04, 0x90, 0xf3, 0x94, 0x34, 0x7b, + 0x6f, 0xf0, 0x5f, 0xa6, 0x6f, 0x00, 0x80, 0x01, 0x73, 0x24, 0x20, 0x7b, + 0x23, 0xa2, 0x04, 0x90, 0xf3, 0x94, 0x34, 0x7b, 0x6f, 0xf0, 0x1f, 0xa5, + 0x73, 0x60, 0x08, 0x7b, 0x73, 0x74, 0x08, 0x7b, 0x13, 0x74, 0x04, 0x01, + 0x63, 0x18, 0x04, 0x00, 0x73, 0x24, 0x40, 0xf1, 0x23, 0xa4, 0x84, 0x90, + 0x6f, 0x00, 0x00, 0x01, 0x73, 0x24, 0x40, 0xf1, 0x23, 0xa4, 0x84, 0x90, + 0x73, 0x60, 0x08, 0x7b, 0x73, 0x24, 0x20, 0x7b, 0xf3, 0x24, 0x30, 0x7b, + 0x73, 0x00, 0x20, 0x7b ).map(_.toByte) } }