4 changed files with 83 additions and 161 deletions
@ -1,152 +1,81 @@ |
|||||
# This code should be functional. Doesn't have to be optimal. |
// See LICENSE.SiFive for license details. |
||||
# I'm writing it to prove that it can be done. |
|
||||
|
|
||||
#include "riscv/encoding.h" |
#include "spike/encoding.h" |
||||
|
|
||||
# TODO: Update these constants once they're finalized in the doc. |
// These are implementation-specific addresses in the Debug Module |
||||
|
#define HALTED 0x100 |
||||
|
#define GOING 0x104 |
||||
|
#define RESUMING 0x108 |
||||
|
#define EXCEPTION 0x10C |
||||
|
|
||||
#define DEBUG_RAM 0x400 |
// Region of memory where each hart has 1 |
||||
#ifndef DEBUG_RAM_SIZE |
// byte to read. |
||||
# define DEBUG_RAM_SIZE 64 |
#define FLAGS 0x400 |
||||
#endif |
#define FLAG_GO 0 |
||||
|
#define FLAG_RESUME 1 |
||||
#define CLEARDEBINT 0x100 |
|
||||
#define SETHALTNOT 0x10c |
|
||||
|
|
||||
#if (defined(RV32) + defined(RV64) + defined(RV128)) > 1 |
|
||||
# define MULTI_XLEN |
|
||||
#elif (defined(RV32) + defined(RV64) + defined(RV128)) == 0 |
|
||||
# error define one or more of RV32, RV64, RV128 |
|
||||
#endif |
|
||||
|
|
||||
|
.option norvc |
||||
.global entry |
.global entry |
||||
.global resume |
|
||||
.global exception |
.global exception |
||||
|
|
||||
# Automatically called when Debug Mode is first entered. |
// Entry location on ebreak, Halt, or Breakpoint |
||||
entry: j _entry |
// It is the same for all harts. They branch when |
||||
# Should be called by Debug RAM code that has finished execution and |
// their GO or RESUME bit is set. |
||||
# wants to return to Debug Mode. |
|
||||
|
entry: |
||||
|
jal zero, _entry |
||||
resume: |
resume: |
||||
j _resume |
jal zero, _resume |
||||
exception: |
exception: |
||||
# Set the last word of Debug RAM to all ones, to indicate that we hit |
jal zero, _exception |
||||
# an exception. |
|
||||
li s0, ~0 |
|
||||
j _resume2 |
|
||||
|
|
||||
_resume: |
_entry: |
||||
li s0, 0 |
// This fence is required because the execution may have written something |
||||
_resume2: |
// into the Abstract Data or Program Buffer registers. |
||||
fence |
fence |
||||
|
csrw CSR_DSCRATCH, s0 // Save s0 to allow signaling MHARTID |
||||
# Restore s1. |
|
||||
#ifdef MULTI_XLEN |
// We continue to let the hart know that we are halted in order that |
||||
csrr s1, CSR_MISA |
// a DM which was reset is still made aware that a hart is halted. |
||||
#endif |
// We keep checking both whether there is something the debugger wants |
||||
|
// us to do, or whether we should resume. |
||||
#ifdef RV32 |
entry_loop: |
||||
# ifdef MULTI_XLEN |
csrr s0, CSR_MHARTID |
||||
bltz s1, restore_not_32 |
sw s0, HALTED(zero) |
||||
# endif |
lbu s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here. |
||||
|
andi s0, s0, (1 << FLAG_GO) |
||||
restore_32: |
bnez s0, going |
||||
lw s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 4)(zero) |
csrr s0, CSR_MHARTID |
||||
# if defined(RV64) || defined(RV128) |
lbu s0, FLAGS(s0) // multiple harts can resume here |
||||
j finish_restore |
andi s0, s0, (1 << FLAG_RESUME) |
||||
# endif |
bnez s0, resume |
||||
#endif |
jal zero, entry_loop |
||||
|
|
||||
restore_not_32: |
_exception: |
||||
#if defined(RV64) && defined(RV128) |
sw zero, EXCEPTION(zero) // Let debug module know you got an exception. |
||||
slli s1, s1, 1 |
ebreak |
||||
bltz s1, restore_128 |
|
||||
#endif |
going: |
||||
|
csrr s0, CSR_DSCRATCH // Restore s0 here |
||||
#ifdef RV64 |
sw zero, GOING(zero) // When debug module sees this write, the GO flag is reset. |
||||
restore_64: |
jalr zero, zero, %lo(whereto) // Rocket-Chip has a specific hack which is that jalr in |
||||
ld s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 8)(zero) |
// Debug Mode will flush the I-Cache. We need that so that the |
||||
#endif |
// remainder of the variable instructions will be what Debug Module |
||||
#if defined(RV64) && defined(RV128) |
// intends. |
||||
j finish_restore |
_resume: |
||||
#endif |
csrr s0, CSR_MHARTID |
||||
#ifdef RV128 |
sw s0, RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset. |
||||
restore_128: |
csrr s0, CSR_DSCRATCH // Restore s0 |
||||
lq s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 16)(zero) |
|
||||
#endif |
|
||||
|
|
||||
finish_restore: |
|
||||
# s0 contains ~0 if we got here through an exception, and 0 otherwise. |
|
||||
# Store this to the last word in Debug RAM so the debugger can tell if |
|
||||
# an exception occurred. |
|
||||
sw s0, (DEBUG_RAM + DEBUG_RAM_SIZE - 4)(zero) |
|
||||
|
|
||||
# Clear debug interrupt. |
|
||||
csrr s0, CSR_MHARTID |
|
||||
sw s0, CLEARDEBINT(zero) |
|
||||
|
|
||||
check_halt: |
|
||||
csrr s0, CSR_DCSR |
|
||||
andi s0, s0, DCSR_HALT |
|
||||
bnez s0, wait_for_interrupt |
|
||||
|
|
||||
exit: |
|
||||
# Restore s0. |
|
||||
csrr s0, CSR_DSCRATCH |
|
||||
dret |
dret |
||||
|
|
||||
_entry: |
// END OF ACTUAL "ROM" CONTENTS. BELOW IS JUST FOR LINKER SCRIPT. |
||||
# Save s0 in DSCRATCH |
|
||||
csrw CSR_DSCRATCH, s0 |
.section .whereto |
||||
|
whereto: |
||||
# Check why we're here |
nop |
||||
csrr s0, CSR_DCSR |
// Variable "ROM" This is : jal x0 abstract, jal x0 program_buffer, |
||||
# cause is in bits 8:6 of dcsr |
// or jal x0 resume, as desired. |
||||
andi s0, s0, DCSR_CAUSE |
// Debug Module state machine tracks what is 'desired'. |
||||
addi s0, s0, -(DCSR_CAUSE_DEBUGINT<<6) |
// We don't need/want to use jalr here because all of the |
||||
bnez s0, spontaneous_halt |
// Variable ROM contents are set by |
||||
|
// Debug Module before setting the OK_GO byte. |
||||
jdebugram: |
|
||||
# Save s1 so that the debug program can use two registers. |
|
||||
#ifdef MULTI_XLEN |
|
||||
csrr s0, CSR_MISA |
|
||||
#endif |
|
||||
|
|
||||
#ifdef RV32 |
|
||||
# ifdef MULTI_XLEN |
|
||||
bltz s0, save_not_32 |
|
||||
# endif |
|
||||
save_32: |
|
||||
sw s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 4)(zero) |
|
||||
jr zero, DEBUG_RAM |
|
||||
#endif |
|
||||
|
|
||||
save_not_32: |
|
||||
#if defined(RV64) && defined(RV128) |
|
||||
slli s0, s0, 1 |
|
||||
bltz s0, save_128 |
|
||||
#endif |
|
||||
|
|
||||
#ifdef RV64 |
|
||||
save_64: |
|
||||
sd s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 8)(zero) |
|
||||
jr zero, DEBUG_RAM |
|
||||
#endif |
|
||||
|
|
||||
#ifdef RV128 |
|
||||
save_128: |
|
||||
sq s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 16)(zero) |
|
||||
jr zero, DEBUG_RAM |
|
||||
#endif |
|
||||
|
|
||||
spontaneous_halt: |
|
||||
csrr s0, CSR_MHARTID |
|
||||
sw s0, SETHALTNOT(zero) |
|
||||
csrsi CSR_DCSR, DCSR_HALT |
|
||||
|
|
||||
wait_for_interrupt: |
|
||||
csrr s0, CSR_DCSR |
|
||||
andi s0, s0, DCSR_DEBUGINT |
|
||||
beqz s0, wait_for_interrupt |
|
||||
|
|
||||
j jdebugram |
|
||||
|
|||||
@ -1,16 +1,11 @@ |
|||||
static const unsigned char debug_rom_raw[] = { |
static const unsigned char debug_rom_raw[] = { |
||||
0x6f, 0x00, 0xc0, 0x04, 0x6f, 0x00, 0xc0, 0x00, 0x13, 0x04, 0xf0, 0xff, |
0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0xc0, 0x04, 0x6f, 0x00, 0x40, 0x03, |
||||
0x6f, 0x00, 0x80, 0x00, 0x13, 0x04, 0x00, 0x00, 0x0f, 0x00, 0xf0, 0x0f, |
0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1, |
||||
0xf3, 0x24, 0x10, 0x30, 0x63, 0xc6, 0x04, 0x00, 0x83, 0x24, 0xc0, 0x43, |
0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x14, 0x00, |
||||
0x6f, 0x00, 0x80, 0x00, 0x83, 0x34, 0x80, 0x43, 0x23, 0x2e, 0x80, 0x42, |
0x63, 0x10, 0x04, 0x02, 0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40, |
||||
0x73, 0x24, 0x40, 0xf1, 0x23, 0x20, 0x80, 0x10, 0x73, 0x24, 0x00, 0x7b, |
0x13, 0x74, 0x24, 0x00, 0xe3, 0x18, 0x04, 0xfc, 0x6f, 0xf0, 0xdf, 0xfd, |
||||
0x13, 0x74, 0x84, 0x00, 0x63, 0x12, 0x04, 0x04, 0x73, 0x24, 0x20, 0x7b, |
0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00, 0x73, 0x24, 0x20, 0x7b, |
||||
0x73, 0x00, 0x20, 0x7b, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x00, 0x7b, |
0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30, 0x73, 0x24, 0x40, 0xf1, |
||||
0x13, 0x74, 0x04, 0x1c, 0x13, 0x04, 0x04, 0xf4, 0x63, 0x1e, 0x04, 0x00, |
0x23, 0x24, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b, 0x73, 0x00, 0x20, 0x7b |
||||
0x73, 0x24, 0x10, 0x30, 0x63, 0x46, 0x04, 0x00, 0x23, 0x2e, 0x90, 0x42, |
|
||||
0x67, 0x00, 0x00, 0x40, 0x23, 0x3c, 0x90, 0x42, 0x67, 0x00, 0x00, 0x40, |
|
||||
0x73, 0x24, 0x40, 0xf1, 0x23, 0x26, 0x80, 0x10, 0x73, 0x60, 0x04, 0x7b, |
|
||||
0x73, 0x24, 0x00, 0x7b, 0x13, 0x74, 0x04, 0x02, 0xe3, 0x0c, 0x04, 0xfe, |
|
||||
0x6f, 0xf0, 0x1f, 0xfd |
|
||||
}; |
}; |
||||
static const unsigned int debug_rom_raw_len = 148; |
static const unsigned int debug_rom_raw_len = 96; |
||||
|
|||||
Loading…
Reference in new issue