aboutsummaryrefslogtreecommitdiff
path: root/debug_rom
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2016-04-23 10:18:05 -0700
committerTim Newsome <tim@sifive.com>2016-05-23 12:12:11 -0700
commit7facb160390cbd6a1b19d62966fe5140425ee72a (patch)
tree031a5bd46d9933b6c84f11d08a48d8aa906ffad6 /debug_rom
parent6835847f4798cc38f933ba877004eacfc1cbf593 (diff)
downloadriscv-isa-sim-7facb160390cbd6a1b19d62966fe5140425ee72a.zip
riscv-isa-sim-7facb160390cbd6a1b19d62966fe5140425ee72a.tar.gz
riscv-isa-sim-7facb160390cbd6a1b19d62966fe5140425ee72a.tar.bz2
Clean up how Debug ROM is included.
I'm not thrilled about including a static copy in so many cc files, and making the compiler throw it out. But without really grokking the Makefile this is the best it's going to be.
Diffstat (limited to 'debug_rom')
-rw-r--r--debug_rom/Makefile20
-rwxr-xr-xdebug_rom/debug_rom.S105
-rw-r--r--debug_rom/debug_rom.h18
-rw-r--r--debug_rom/link.ld11
4 files changed, 154 insertions, 0 deletions
diff --git a/debug_rom/Makefile b/debug_rom/Makefile
new file mode 100644
index 0000000..d66b84f
--- /dev/null
+++ b/debug_rom/Makefile
@@ -0,0 +1,20 @@
+# Recursive make is bad, but in this case we're cross compiling which is a
+# pretty unusual use case.
+
+CC = $(RISCV)/bin/riscv64-unknown-elf-gcc
+OBJCOPY = $(RISCV)/bin/riscv64-unknown-elf-objcopy
+
+%.o: %.S
+ $(CC) -c $<
+
+debug_rom.h: debug_rom.raw
+ xxd -i $^ | sed "s/^unsigned/static const unsigned/" > $@
+
+debug_rom.raw: debug_rom
+ $(OBJCOPY) -O binary --only-section .text debug_rom debug_rom.raw
+
+debug_rom: debug_rom.o
+ $(CC) -nostdlib -nostartfiles -Tlink.ld -o $@ $^
+
+clean:
+ rm -f debug_rom debug_rom.o debug_rom.raw debug_rom.h
diff --git a/debug_rom/debug_rom.S b/debug_rom/debug_rom.S
new file mode 100755
index 0000000..230f4b4
--- /dev/null
+++ b/debug_rom/debug_rom.S
@@ -0,0 +1,105 @@
+# This code should be functional. Doesn't have to be optimal.
+# I'm writing it to prove that it can be done.
+
+# TODO: Update these constants once they're finalized in the doc.
+
+#define DCSR 0x790
+#define DCSR_CAUSE_DEBINT 3
+#define DCSR_HALT_OFFSET 3
+#define DCSR_DEBUGINT_OFFSET 10
+
+#define DSCRATCH 0x792
+
+#define MCPUID 0xf00
+#define MHARTID 0xf10
+
+#define DEBUG_RAM 0x400
+#define DEBUG_RAM_SIZE 64
+
+#define SETHALTNOT 0x100
+#define CLEARHALTNOT 0x104
+#define CLEARDEBINT 0x108
+
+ .global entry
+ .global resume
+
+ # Automatically called when Debug Mode is first entered.
+entry: j _entry
+ # Should be called by Debug RAM code that has finished execution and
+ # wants to return to Debug Mode.
+resume:
+ # Clear debug interrupt.
+clear_debint:
+ csrr s1, MHARTID
+ sw s1, CLEARDEBINT(zero)
+clear_debint_loop:
+ csrr s1, DCSR
+ andi s1, s1, (1<<DCSR_DEBUGINT_OFFSET)
+ bnez s1, wait_for_interrupt
+
+ # Restore s1.
+ csrr s1, MCPUID
+ bltz s1, restore_not_32
+restore_32:
+ lw s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 4)(zero)
+ j check_halt
+restore_not_32:
+ slli s1, s1, 1
+ bltz s1, restore_128
+restore_64:
+ ld s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 8)(zero)
+ j check_halt
+restore_128:
+ nop #lq s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 16)(zero)
+
+check_halt:
+ csrr s0, DCSR
+ andi s0, s0, (1<<DCSR_HALT_OFFSET)
+ beqz s0, exit
+ j wait_for_interrupt
+
+exit:
+ # Restore s0.
+ csrr s0, DSCRATCH
+ eret
+
+
+_entry:
+ # Save s0 in DSCRATCH
+ csrw DSCRATCH, s0
+
+ # Check why we're here
+ csrr s0, DCSR
+ # cause is in bits 2:0 of dcsr
+ andi s0, s0, 7
+ addi s0, s0, -DCSR_CAUSE_DEBINT
+ bnez s0, spontaneous_halt
+
+jdebugram:
+ # Save s1 so that the debug program can use two registers.
+ csrr s0, MCPUID
+ bltz s0, save_not_32
+save_32:
+ sw s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 4)(zero)
+ jr zero, DEBUG_RAM
+save_not_32:
+ slli s0, s0, 1
+ bltz s0, save_128
+save_64:
+ sd s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 8)(zero)
+ jr zero, DEBUG_RAM
+save_128:
+ nop #sq s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 16)(zero)
+ jr zero, DEBUG_RAM
+
+spontaneous_halt:
+ csrr s0, MHARTID
+ sw s0, SETHALTNOT(zero)
+ csrsi DCSR, DCSR_HALT_OFFSET
+
+wait_for_interrupt:
+ csrr s0, DCSR
+ andi s0, s0, (1<<DCSR_DEBUGINT_OFFSET)
+ beqz s0, wait_for_interrupt
+
+ j jdebugram
diff --git a/debug_rom/debug_rom.h b/debug_rom/debug_rom.h
new file mode 100644
index 0000000..1c53e11
--- /dev/null
+++ b/debug_rom/debug_rom.h
@@ -0,0 +1,18 @@
+static const unsigned char debug_rom_raw[] = {
+ 0x6f, 0x00, 0x40, 0x05, 0xf3, 0x24, 0x00, 0xf1, 0x23, 0x24, 0x90, 0x10,
+ 0xf3, 0x24, 0x00, 0x79, 0x93, 0xf4, 0x04, 0x40, 0x63, 0x94, 0x04, 0x08,
+ 0xf3, 0x24, 0x00, 0xf0, 0x63, 0xc6, 0x04, 0x00, 0x83, 0x24, 0xc0, 0x43,
+ 0x6f, 0x00, 0x80, 0x01, 0x93, 0x94, 0x14, 0x00, 0x63, 0xc6, 0x04, 0x00,
+ 0x83, 0x34, 0x80, 0x43, 0x6f, 0x00, 0x80, 0x00, 0x13, 0x00, 0x00, 0x00,
+ 0x73, 0x24, 0x00, 0x79, 0x13, 0x74, 0x84, 0x00, 0x63, 0x04, 0x04, 0x00,
+ 0x6f, 0x00, 0x40, 0x05, 0x73, 0x24, 0x20, 0x79, 0x73, 0x00, 0x00, 0x10,
+ 0x73, 0x10, 0x24, 0x79, 0x73, 0x24, 0x00, 0x79, 0x13, 0x74, 0x74, 0x00,
+ 0x13, 0x04, 0xd4, 0xff, 0x63, 0x16, 0x04, 0x02, 0x73, 0x24, 0x00, 0xf0,
+ 0x63, 0x46, 0x04, 0x00, 0x23, 0x2e, 0x90, 0x42, 0x67, 0x00, 0x00, 0x40,
+ 0x13, 0x14, 0x14, 0x00, 0x63, 0x46, 0x04, 0x00, 0x23, 0x3c, 0x90, 0x42,
+ 0x67, 0x00, 0x00, 0x40, 0x13, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x40,
+ 0x73, 0x24, 0x00, 0xf1, 0x23, 0x20, 0x80, 0x10, 0x73, 0xe0, 0x01, 0x79,
+ 0x73, 0x24, 0x00, 0x79, 0x13, 0x74, 0x04, 0x40, 0xe3, 0x0c, 0x04, 0xfe,
+ 0x6f, 0xf0, 0x1f, 0xfc
+};
+static const unsigned int debug_rom_raw_len = 172;
diff --git a/debug_rom/link.ld b/debug_rom/link.ld
new file mode 100644
index 0000000..356099c
--- /dev/null
+++ b/debug_rom/link.ld
@@ -0,0 +1,11 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY( entry )
+SECTIONS
+{
+ . = 0xfffff800; /* TODO: 0x800 */
+ .text :
+ {
+ *(.text)
+ }
+ _end = .;
+}