Browse Source

debug: Use a more practical debug ROM

pull/94/head
Megan Wachs 9 years ago
parent
commit
d46f694d85
  1. 10
      debug_rom/Makefile
  2. 207
      debug_rom/debug_rom.S
  3. 23
      debug_rom/debug_rom.h
  4. 4
      debug_rom/link.ld

10
debug_rom/Makefile

@ -6,7 +6,7 @@ OBJCOPY = $(RISCV)/bin/riscv64-unknown-elf-objcopy
COMPILE = $(CC) -nostdlib -nostartfiles -I.. -Tlink.ld COMPILE = $(CC) -nostdlib -nostartfiles -I.. -Tlink.ld
ELFS = debug_rom debug_rom32 debug_rom64 ELFS = debug_rom
DEPS = debug_rom.S link.ld DEPS = debug_rom.S link.ld
all: $(patsubst %,%.h,$(ELFS)) all: $(patsubst %,%.h,$(ELFS))
@ -18,13 +18,7 @@ all: $(patsubst %,%.h,$(ELFS))
$(OBJCOPY) -O binary --only-section .text $^ $@ $(OBJCOPY) -O binary --only-section .text $^ $@
debug_rom: $(DEPS) debug_rom: $(DEPS)
$(COMPILE) -DRV32 -DRV64 -o $@ $^ $(COMPILE) -o $@ $^
debug_rom32: $(DEPS)
$(COMPILE) -DRV32 -DDEBUG_RAM_SIZE=28 -o $@ $^
debug_rom64: $(DEPS)
$(COMPILE) -DRV64 -o $@ $^
clean: clean:
rm -f $(ELFS) debug_rom*.raw debug_rom*.h rm -f $(ELFS) debug_rom*.raw debug_rom*.h

207
debug_rom/debug_rom.S

@ -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

23
debug_rom/debug_rom.h

@ -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;

4
debug_rom/link.ld

@ -2,6 +2,10 @@ OUTPUT_ARCH( "riscv" )
ENTRY( entry ) ENTRY( entry )
SECTIONS SECTIONS
{ {
.whereto 0x300 :
{
*(.whereto)
}
. = 0x800; . = 0x800;
.text : .text :
{ {

Loading…
Cancel
Save