From 8fda4e00ea7326d6f2a2867c7482559bf5b0b401 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Tue, 18 Apr 2017 11:34:31 -0700 Subject: [PATCH] debug: Checkpoint which somewhat works with OpenOCD v13, but still has some bugs. --- debug_rom/debug_rom_defines.h | 1 + riscv/debug_module.cc | 160 +++++++++++++++++++--------------- riscv/debug_module.h | 11 +-- riscv/decode.h | 13 ++- riscv/execute.cc | 13 +-- riscv/processor.cc | 4 +- riscv/processor.h | 1 + 7 files changed, 108 insertions(+), 95 deletions(-) diff --git a/debug_rom/debug_rom_defines.h b/debug_rom/debug_rom_defines.h index 074107c..616cf59 100644 --- a/debug_rom/debug_rom_defines.h +++ b/debug_rom/debug_rom_defines.h @@ -18,5 +18,6 @@ // These needs to match the link.ld #define DEBUG_ROM_WHERETO 0x300 #define DEBUG_ROM_ENTRY 0x800 +#define DEBUG_ROM_TVEC 0x808 #endif diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc index 0f51f7b..5d88592 100644 --- a/riscv/debug_module.cc +++ b/riscv/debug_module.cc @@ -6,6 +6,7 @@ #include "mmu.h" #include "debug_rom/debug_rom.h" +#include "debug_rom/debug_rom_defines.h" #if 1 # define D(x) x @@ -15,9 +16,7 @@ ///////////////////////// debug_module_t -debug_module_t::debug_module_t(sim_t *sim) : sim(sim), - next_action(jal(ZERO, 0)), - action_executed(false) +debug_module_t::debug_module_t(sim_t *sim) : sim(sim) { dmcontrol = {0}; @@ -30,12 +29,17 @@ debug_module_t::debug_module_t(sim_t *sim) : sim(sim), abstractauto = {0}; - for (unsigned i = 0; i < DEBUG_ROM_ENTRY_SIZE / 4; i++) { - write32(debug_rom_entry, i, jal(ZERO, 0)); - halted[i] = false; - } - + memset(halted, 0, sizeof(halted)); + memset(debug_rom_flags, 0, sizeof(debug_rom_flags)); + memset(resumeack, 0, sizeof(resumeack)); memset(program_buffer, 0, sizeof(program_buffer)); + memset(dmdata, 0, sizeof(dmdata)); + + write32(debug_rom_whereto, 0, + jal(ZERO, DEBUG_ABSTRACT_START - DEBUG_ROM_WHERETO)); + + memset(debug_rom_abstract, 0, sizeof(debug_rom_abstract)); + } void debug_module_t::reset() @@ -68,39 +72,23 @@ bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes) addr = DEBUG_START + addr; if (addr >= DEBUG_ROM_ENTRY && - addr < DEBUG_ROM_ENTRY + DEBUG_ROM_ENTRY_SIZE) { - - if (read32(debug_rom_entry, dmcontrol.hartsel) == jal(ZERO, 0)) { - // We're here in an infinite loop. That means that whatever abstract - // command has complete. - abstractcs.busy = false; - } - - action_executed = true; - - halted[(addr - DEBUG_ROM_ENTRY) / 4] = true; - memcpy(bytes, debug_rom_entry + addr - DEBUG_ROM_ENTRY, len); + addr < DEBUG_ROM_ENTRY + debug_rom_raw_len) { + memcpy(bytes, debug_rom_raw + addr - DEBUG_ROM_ENTRY, len); return true; } - if (action_executed) { - // Restore the jump-to-self loop. - write32(debug_rom_entry, dmcontrol.hartsel, next_action); - next_action = jal(ZERO, 0); - action_executed = false; + if (addr >= DEBUG_ROM_WHERETO && addr < DEBUG_ROM_WHERETO + 4) { + memcpy(bytes, debug_rom_whereto + addr - DEBUG_ROM_WHERETO, len); + return true; } - if (addr >= DEBUG_ROM_CODE && - addr < DEBUG_ROM_CODE + DEBUG_ROM_CODE_SIZE) { - - if (read32(debug_rom_code, 0) == dret()) { - abstractcs.busy = false; - halted[dmcontrol.hartsel] = false; - resumeack[dmcontrol.hartsel] = true; - } + if (addr >= DEBUG_ROM_FLAGS && addr < DEBUG_ROM_FLAGS + 1024) { + memcpy(bytes, debug_rom_flags + addr - DEBUG_ROM_FLAGS, len); + return true; + } - fprintf(stderr, "returning the debug rom code.\n"); - memcpy(bytes, debug_rom_code + addr - DEBUG_ROM_CODE, len); + if (addr >= DEBUG_ABSTRACT_START && addr < DEBUG_ABSTRACT_END) { + memcpy(bytes, debug_rom_abstract + addr - DEBUG_ABSTRACT_START, len); return true; } @@ -114,15 +102,6 @@ bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes) return true; } - if (addr >= DEBUG_ROM_EXCEPTION && - addr < DEBUG_ROM_EXCEPTION + DEBUG_ROM_EXCEPTION_SIZE) { - memcpy(bytes, debug_rom_exception + addr - DEBUG_ROM_EXCEPTION, len); - if (abstractcs.cmderr == CMDERR_NONE) { - abstractcs.cmderr = CMDERR_EXCEPTION; - } - return true; - } - fprintf(stderr, "ERROR: invalid load from debug module: %zd bytes at 0x%016" PRIx64 "\n", len, addr); @@ -132,6 +111,13 @@ bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes) bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes) { + uint8_t id_bytes[4]; + uint32_t id = 0; + if (len == 4) { + memcpy(id_bytes, bytes, 4); + id = read32(id_bytes, 0); + } + addr = DEBUG_START + addr; if (addr >= DEBUG_DATA_START && addr < DEBUG_DATA_END) { @@ -144,6 +130,39 @@ bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes) return true; } + if (addr == DEBUG_ROM_HALTED) { + assert (len == 4); + halted[id] = true; + if (dmcontrol.hartsel == id) { + if (0 == (debug_rom_flags[id] & (1 << DEBUG_ROM_FLAG_GO))){ + if (dmcontrol.hartsel == id) { + abstractcs.busy = false; + } + } + } + return true; + } + + if (addr == DEBUG_ROM_GOING) { + debug_rom_flags[dmcontrol.hartsel] &= ~(1 << DEBUG_ROM_FLAG_GO); + return true; + } + + if (addr == DEBUG_ROM_RESUMING) { + assert (len == 4); + halted[id] = false; + resumeack[id] = true; + debug_rom_flags[id] &= ~(1 << DEBUG_ROM_FLAG_RESUME); + return true; + } + + if (addr == DEBUG_ROM_EXCEPTION) { + if (abstractcs.cmderr == CMDERR_NONE) { + abstractcs.cmderr = CMDERR_EXCEPTION; + } + return true; + } + fprintf(stderr, "ERROR: invalid store to debug module: %zd bytes at 0x%016" PRIx64 "\n", len, addr); return false; @@ -184,17 +203,22 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) D(fprintf(stderr, "dmi_read(0x%x) -> ", address)); if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) { unsigned i = address - DMI_DATA0; - result = read32(dmdata, address - DMI_DATA0); + result = read32(dmdata, i); if (abstractcs.busy && abstractcs.cmderr == CMDERR_NONE) { abstractcs.cmderr = CMDERR_BUSY; } - if ((abstractauto.autoexecdata >> i) & 1) + if ((abstractauto.autoexecdata >> i) & 1){ perform_abstract_command(); + } } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progsize) { - // TODO : Autoexec progbuf. - result = read32(program_buffer, address - DMI_PROGBUF0); + unsigned i = address = DMI_PROGBUF0; + result = read32(program_buffer, i); + if ((abstractauto.autoexecprogbuf >> i) & 1) { + perform_abstract_command(); + } + } else { switch (address) { case DMI_DMCONTROL: @@ -304,31 +328,32 @@ bool debug_module_t::perform_abstract_command() bool write = get_field(command, AC_ACCESS_REGISTER_WRITE); unsigned regno = get_field(command, AC_ACCESS_REGISTER_REGNO); - if (regno < 0x1000 || regno >= 0x1020) { - abstractcs.cmderr = CMDERR_NOTSUP; - return true; - } - - unsigned regnum = regno - 0x1000; - if (!halted[dmcontrol.hartsel]) { abstractcs.cmderr = CMDERR_HALTRESUME; return true; } if (get_field(command, AC_ACCESS_REGISTER_TRANSFER)) { + + if (regno < 0x1000 || regno >= 0x1020) { + abstractcs.cmderr = CMDERR_NOTSUP; + return true; + } + + unsigned regnum = regno - 0x1000; + switch (size) { case 2: if (write) - write32(debug_rom_code, 0, lw(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_rom_abstract, 0, lw(regnum, ZERO, DEBUG_DATA_START)); else - write32(debug_rom_code, 0, sw(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_rom_abstract, 0, sw(regnum, ZERO, DEBUG_DATA_START)); break; case 3: if (write) - write32(debug_rom_code, 0, ld(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_rom_abstract, 0, ld(regnum, ZERO, DEBUG_DATA_START)); else - write32(debug_rom_code, 0, sd(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_rom_abstract, 0, sd(regnum, ZERO, DEBUG_DATA_START)); break; /* case 4: @@ -344,21 +369,17 @@ bool debug_module_t::perform_abstract_command() } } else { // Should be a NOP. Store DEBUG_DATA to x0. - write32(debug_rom_code, 0, sw(ZERO, ZERO, DEBUG_DATA_START)); + write32(debug_rom_abstract, 0, sw(ZERO, ZERO, DEBUG_DATA_START)); } if (get_field(command, AC_ACCESS_REGISTER_POSTEXEC)) { - write32(debug_rom_code, 1, jal(ZERO, DEBUG_PROGBUF_START - DEBUG_ROM_CODE - 4)); + write32(debug_rom_abstract, 1, jal(ZERO, DEBUG_PROGBUF_START - DEBUG_ABSTRACT_START)); } else { - write32(debug_rom_code, 1, ebreak()); + write32(debug_rom_abstract, 1, ebreak()); } + debug_rom_flags[dmcontrol.hartsel] |= 1 << DEBUG_ROM_FLAG_GO; - write32(debug_rom_entry, dmcontrol.hartsel, - jal(ZERO, DEBUG_ROM_CODE - (DEBUG_ROM_ENTRY + 4 * dmcontrol.hartsel))); - - write32(debug_rom_exception, dmcontrol.hartsel, - jal(ZERO, (DEBUG_ROM_ENTRY + 4 * dmcontrol.hartsel) - DEBUG_ROM_EXCEPTION)); abstractcs.busy = true; } else { abstractcs.cmderr = CMDERR_NOTSUP; @@ -401,10 +422,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) if (proc) { proc->halt_request = dmcontrol.haltreq; if (dmcontrol.resumereq) { - write32(debug_rom_code, 0, dret()); - write32(debug_rom_entry, dmcontrol.hartsel, - jal(ZERO, DEBUG_ROM_CODE - (DEBUG_ROM_ENTRY + 4 * dmcontrol.hartsel))); - abstractcs.busy = true; + debug_rom_flags[dmcontrol.hartsel] |= (1 << DEBUG_ROM_FLAG_RESUME); resumeack[dmcontrol.hartsel] = false; } } diff --git a/riscv/debug_module.h b/riscv/debug_module.h index 8daf03b..d3398ea 100644 --- a/riscv/debug_module.h +++ b/riscv/debug_module.h @@ -77,19 +77,14 @@ class debug_module_t : public abstract_device_t sim_t *sim; - uint8_t debug_rom_entry[DEBUG_ROM_ENTRY_SIZE]; - uint8_t debug_rom_code[DEBUG_ROM_CODE_SIZE]; - uint8_t debug_rom_exception[DEBUG_ROM_EXCEPTION_SIZE]; + uint8_t debug_rom_whereto[4]; + uint8_t debug_rom_abstract[4*2]; uint8_t program_buffer[progsize * 4]; uint8_t dmdata[DEBUG_DATA_SIZE]; bool halted[1024]; bool resumeack[1024]; - - // Instruction that will be placed at the current hart's ROM entry address - // after the current action has completed. - uint32_t next_action; - bool action_executed; + uint8_t debug_rom_flags[1024]; void write32(uint8_t *rom, unsigned int index, uint32_t value); uint32_t read32(uint8_t *rom, unsigned int index); diff --git a/riscv/decode.h b/riscv/decode.h index 551f451..45d1c58 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -249,13 +249,6 @@ inline freg_t freg(freg_t f) { return f; } // Seems that 0x0 doesn't work. #define DEBUG_START 0x100 -#define DEBUG_ROM_ENTRY 0x400 -#define DEBUG_ROM_ENTRY_SIZE (1024 * 4) -#define DEBUG_ROM_CODE (DEBUG_ROM_ENTRY + DEBUG_ROM_ENTRY_SIZE) -#define DEBUG_ROM_CODE_SIZE 256 -#define DEBUG_ROM_EXCEPTION (DEBUG_ROM_CODE + DEBUG_ROM_CODE_SIZE) -#define DEBUG_ROM_EXCEPTION_SIZE 4 - #define DEBUG_DATA_START 0x380 #define DEBUG_DATA_SIZE 0x20 #define DEBUG_DATA_END DEBUG_DATA_START + DEBUG_DATA_SIZE @@ -264,6 +257,10 @@ inline freg_t freg(freg_t f) { return f; } #define DEBUG_PROGBUF_START DEBUG_DATA_START - DEBUG_PROGBUF_SIZE #define DEBUG_PROGBUF_END DEBUG_PROGBUF_START + DEBUG_PROGBUF_SIZE -#define DEBUG_END 0x2000 - 1 +#define DEBUG_ABSTRACT_SIZE 2*4 +#define DEBUG_ABSTRACT_START (DEBUG_PROGBUF_START - DEBUG_ABSTRACT_SIZE) +#define DEBUG_ABSTRACT_END (DEBUG_ABSTRACT_START + DEBUG_ABSTRACT_SIZE) + +#define DEBUG_END (0x1000 - 1) #endif diff --git a/riscv/execute.cc b/riscv/execute.cc index 7734ca2..303effe 100644 --- a/riscv/execute.cc +++ b/riscv/execute.cc @@ -65,7 +65,8 @@ void processor_t::step(size_t n) if (state.dcsr.cause == DCSR_CAUSE_NONE) { if (halt_request) { enter_debug_mode(DCSR_CAUSE_DEBUGINT); - } else if (state.dcsr.halt) { + } // !!!The halt bit in DCSR is deprecated. + else if (state.dcsr.halt) { enter_debug_mode(DCSR_CAUSE_HALT); } } @@ -116,12 +117,14 @@ void processor_t::step(size_t n) break; } - if (unlikely(state.pc >= DEBUG_ROM_ENTRY && - state.pc < DEBUG_ROM_ENTRY + DEBUG_ROM_ENTRY_SIZE)) { - // We're spinning waiting for the debugger to tell us something. - // Let's go talk to the debugger. + if (unlikely(state.pc >= DEBUG_START && + state.pc < DEBUG_END)) { + // We're waiting for the debugger to tell us something. return; } + + + } } else while (instret < n) diff --git a/riscv/processor.cc b/riscv/processor.cc index d6da193..b2c2d34 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -210,10 +210,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc) if (state.dcsr.cause) { if (t.cause() == CAUSE_BREAKPOINT) { state.pc = debug_rom_entry(); - fprintf(stderr, "Breakpoint."); } else { - fprintf(stderr, "WE ARE IN DEBUG MODE, DEBUG_ROM_EXCEPTION\n"); - state.pc = DEBUG_ROM_EXCEPTION; + state.pc = DEBUG_ROM_TVEC; } return; } diff --git a/riscv/processor.h b/riscv/processor.h index ea9cb7b..071f458 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -8,6 +8,7 @@ #include #include #include +#include "debug_rom/debug_rom_defines.h" class processor_t; class mmu_t; -- 2.30.2