From: Tim Newsome Date: Sat, 23 Apr 2016 03:11:29 +0000 (-0700) Subject: Can jump to and execute Debug ROM. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6835847f4798cc38f933ba877004eacfc1cbf593;p=riscv-isa-sim.git Can jump to and execute Debug ROM. 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). --- diff --git a/debug_rom/Makefile b/debug_rom/Makefile deleted file mode 100644 index 17cc95e..0000000 --- a/debug_rom/Makefile +++ /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 index 230f4b4..0000000 --- a/debug_rom/debug_rom.S +++ /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< $@ + +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 index 0000000..230f4b4 --- /dev/null +++ b/riscv/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< +#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 diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 0113443..5fb72bf 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -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); diff --git a/riscv/processor.cc b/riscv/processor.cc index 4ef8e02..7c5c0fb 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -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 diff --git a/riscv/sim.cc b/riscv/sim.cc index 095c2d9..5cf2646 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -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));