Can jump to and execute Debug ROM.
authorTim Newsome <tim@sifive.com>
Sat, 23 Apr 2016 03:11:29 +0000 (20:11 -0700)
committerTim Newsome <tim@sifive.com>
Mon, 23 May 2016 19:12:10 +0000 (12:12 -0700)
Connect with gdb, and the core will jump to Debug ROM and start
executing it. Then it crashes when it jumps to 0x400 because Debug RAM
isn't implemented (and doesn't live there anyway, for now).

13 files changed:
debug_rom/Makefile [deleted file]
debug_rom/debug_rom.S [deleted file]
debug_rom/debug_rom.c [deleted file]
debug_rom/link.ld [deleted file]
riscv/debug_rom.h [new file with mode: 0644]
riscv/debug_rom/Makefile [new file with mode: 0644]
riscv/debug_rom/debug_rom.S [new file with mode: 0755]
riscv/debug_rom/debug_rom.h [new file with mode: 0644]
riscv/debug_rom/link.ld [new file with mode: 0644]
riscv/decode.h
riscv/mmu.cc
riscv/processor.cc
riscv/sim.cc

diff --git a/debug_rom/Makefile b/debug_rom/Makefile
deleted file mode 100644 (file)
index 17cc95e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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.c:   debug_rom.raw
-       xxd -i $^ > $@
-
-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.c
diff --git a/debug_rom/debug_rom.S b/debug_rom/debug_rom.S
deleted file mode 100755 (executable)
index 230f4b4..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-# 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.c b/debug_rom/debug_rom.c
deleted file mode 100644 (file)
index 9d67df5..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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
-};
-unsigned int debug_rom_raw_len = 172;
diff --git a/debug_rom/link.ld b/debug_rom/link.ld
deleted file mode 100644 (file)
index 356099c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-OUTPUT_ARCH( "riscv" )
-ENTRY( entry )
-SECTIONS
-{
-    . = 0xfffff800;     /* TODO: 0x800 */
-    .text :
-    {
-        *(.text)
-    }
-    _end = .;
-}
diff --git a/riscv/debug_rom.h b/riscv/debug_rom.h
new file mode 100644 (file)
index 0000000..d2837ac
--- /dev/null
@@ -0,0 +1,18 @@
+static 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 unsigned int debug_rom_raw_len = 172;
diff --git a/riscv/debug_rom/Makefile b/riscv/debug_rom/Makefile
new file mode 100644 (file)
index 0000000..ff37a29
--- /dev/null
@@ -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.cc:  debug_rom.raw
+       xxd -i $^ > $@
+
+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.c
diff --git a/riscv/debug_rom/debug_rom.S b/riscv/debug_rom/debug_rom.S
new file mode 100755 (executable)
index 0000000..230f4b4
--- /dev/null
@@ -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/riscv/debug_rom/debug_rom.h b/riscv/debug_rom/debug_rom.h
new file mode 100644 (file)
index 0000000..a99534e
--- /dev/null
@@ -0,0 +1,2 @@
+extern unsigned char *debug_rom_raw;
+extern unsigned int debug_rom_raw_len;
diff --git a/riscv/debug_rom/link.ld b/riscv/debug_rom/link.ld
new file mode 100644 (file)
index 0000000..356099c
--- /dev/null
@@ -0,0 +1,11 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY( entry )
+SECTIONS
+{
+    . = 0xfffff800;     /* TODO: 0x800 */
+    .text :
+    {
+        *(.text)
+    }
+    _end = .;
+}
index d1254ee7289579d1b7fdab50d0ddb8c8a05353d0..b59ee781554a8f594ab0d274b4a458f8fc4916ba 100644 (file)
@@ -14,6 +14,7 @@
 #include "config.h"
 #include "common.h"
 #include <cinttypes>
+#include "debug_rom.h"
 
 typedef int64_t sreg_t;
 typedef uint64_t reg_t;
@@ -236,7 +237,9 @@ private:
 #define DCSR_CAUSE_STEPPED      4
 #define DCSR_CAUSE_HALT         5
 
-#define DEBUG_RAM               0xfffffc00       // TODO: 0x400
-#define DEBUG_ROM_ENTRY         0xfffff800       // TODO: 0x800
+#define DEBUG_RAM_START         0xfffffffffffffc00       // TODO: 0x400
+#define DEBUG_RAM_END           (DEBUG_RAM_START + 64)
+#define DEBUG_ROM_START         0xfffffffffffff800       // TODO: 0x800
+#define DEBUG_ROM_END           (DEBUG_ROM_START + debug_rom_raw_len)
 
 #endif
index 0113443cfa4a83d92265ec7e91dccb5404212fd0..5fb72bf64c8a976f5649fe27b58825f2853e22eb 100644 (file)
@@ -54,6 +54,7 @@ reg_t mmu_t::translate(reg_t addr, access_type type)
 const uint16_t* mmu_t::fetch_slow_path(reg_t addr)
 {
   reg_t paddr = translate(addr, FETCH);
+
   if (sim->addr_is_mem(paddr)) {
     refill_tlb(addr, paddr, FETCH);
     return (const uint16_t*)sim->addr_to_mem(paddr);
index 4ef8e0216ce88449d64be63bc45b55282bd53fbf..7c5c0fbfac8c583ff47fa00b0576560295d918bb 100644 (file)
@@ -199,9 +199,13 @@ void processor_t::set_privilege(reg_t prv)
 
 void processor_t::enter_debug_mode(uint8_t cause)
 {
+  fprintf(stderr, "enter_debug_mode(%d)\n", cause);
   state.dcsr.cause = cause;
+  state.dcsr.prv = state.prv;
+  state.prv = PRV_M;
   state.dpc = state.pc;
-  state.pc = DEBUG_ROM_ENTRY;
+  state.pc = DEBUG_ROM_START;
+  debug = true; // TODO
 }
 
 void processor_t::take_trap(trap_t& t, reg_t epc)
@@ -365,6 +369,7 @@ void processor_t::set_csr(int which, reg_t val)
     case CSR_MCAUSE: state.mcause = val; break;
     case CSR_MBADADDR: state.mbadaddr = val; break;
     case DCSR_ADDRESS:
+      // TODO: Use get_field style
       state.dcsr.prv = (val & DCSR_PRV_MASK) >> DCSR_PRV_OFFSET;
       state.dcsr.step = (val & DCSR_STEP_MASK) >> DCSR_STEP_OFFSET;
       // TODO: ndreset and fullreset
index 095c2d9fa6f1a8ead827565863037f3067410988..5cf2646e20ea6cb42134012f803d61b50ae2276a 100644 (file)
@@ -41,11 +41,18 @@ sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, bool halted,
     fprintf(stderr, "warning: only got %lu bytes of target mem (wanted %lu)\n",
             (unsigned long)memsz, (unsigned long)memsz0);
 
+  /* Copy Debug ROM into the end of the allocated block, because we surely
+   * didn't succeed in allocation 0xfffffffff800 bytes. */
+  /* TODO: Once everything uses the new memory map, just put this at the
+   * address that it actually belongs at. */
+  memcpy(mem + memsz - debug_rom_raw_len, debug_rom_raw, debug_rom_raw_len);
+
   debug_mmu = new mmu_t(this, NULL);
 
   for (size_t i = 0; i < procs.size(); i++) {
     procs[i] = new processor_t(isa, this, i);
-    procs[i]->enter_debug_mode(DCSR_CAUSE_HALT);
+    if (halted)
+      procs[i]->enter_debug_mode(DCSR_CAUSE_HALT);
   }
 
   rtc.reset(new rtc_t(procs));