X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=riscv%2Fdebug_module.cc;h=53df8a47d1a7415f20ac8ad88d11cb74b8b29022;hb=b5bbd05923f11ae2c593da006abf6cda7ce214b2;hp=5d885927fcb45c2c3b41b97dba605afbedf010b9;hpb=8fda4e00ea7326d6f2a2867c7482559bf5b0b401;p=riscv-isa-sim.git diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc index 5d88592..53df8a4 100644 --- a/riscv/debug_module.cc +++ b/riscv/debug_module.cc @@ -8,7 +8,7 @@ #include "debug_rom/debug_rom.h" #include "debug_rom/debug_rom_defines.h" -#if 1 +#if 0 # define D(x) x #else # define D(x) @@ -36,10 +36,10 @@ debug_module_t::debug_module_t(sim_t *sim) : sim(sim) memset(dmdata, 0, sizeof(dmdata)); write32(debug_rom_whereto, 0, - jal(ZERO, DEBUG_ABSTRACT_START - DEBUG_ROM_WHERETO)); + jal(ZERO, debug_abstract_start - DEBUG_ROM_WHERETO)); + + memset(debug_abstract, 0, sizeof(debug_abstract)); - memset(debug_rom_abstract, 0, sizeof(debug_rom_abstract)); - } void debug_module_t::reset() @@ -72,33 +72,33 @@ 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_raw_len) { + (addr + len) <= (DEBUG_ROM_ENTRY + debug_rom_raw_len)) { memcpy(bytes, debug_rom_raw + addr - DEBUG_ROM_ENTRY, len); return true; } - if (addr >= DEBUG_ROM_WHERETO && addr < DEBUG_ROM_WHERETO + 4) { + if (addr >= DEBUG_ROM_WHERETO && (addr + len) <= (DEBUG_ROM_WHERETO + 4)) { memcpy(bytes, debug_rom_whereto + addr - DEBUG_ROM_WHERETO, len); return true; } - if (addr >= DEBUG_ROM_FLAGS && addr < DEBUG_ROM_FLAGS + 1024) { + if (addr >= DEBUG_ROM_FLAGS && ((addr + len) <= DEBUG_ROM_FLAGS + 1024)) { memcpy(bytes, debug_rom_flags + addr - DEBUG_ROM_FLAGS, len); return true; } - if (addr >= DEBUG_ABSTRACT_START && addr < DEBUG_ABSTRACT_END) { - memcpy(bytes, debug_rom_abstract + addr - DEBUG_ABSTRACT_START, len); + if (addr >= debug_abstract_start && ((addr + len) <= (debug_abstract_start + sizeof(debug_abstract)))) { + memcpy(bytes, debug_abstract + addr - debug_abstract_start, len); return true; } - if (addr >= DEBUG_DATA_START && addr < DEBUG_DATA_END) { - memcpy(bytes, dmdata + addr - DEBUG_DATA_START, len); + if (addr >= debug_data_start && (addr + len) <= (debug_data_start + sizeof(dmdata))) { + memcpy(bytes, dmdata + addr - debug_data_start, len); return true; } - - if (addr >= DEBUG_PROGBUF_START && addr < DEBUG_PROGBUF_END) { - memcpy(bytes, program_buffer + addr - DEBUG_PROGBUF_START, len); + + if (addr >= debug_progbuf_start && ((addr + len) <= (debug_progbuf_start + sizeof(program_buffer)))) { + memcpy(bytes, program_buffer + addr - debug_progbuf_start, len); return true; } @@ -110,6 +110,19 @@ 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) { + D( + switch (len) { + case 4: + fprintf(stderr, "store(addr=0x%lx, len=%d, bytes=0x%08x); " + "hartsel=0x%x\n", addr, (unsigned) len, *(uint32_t *) bytes, + dmcontrol.hartsel); + break; + default: + fprintf(stderr, "store(addr=0x%lx, len=%d, bytes=...); " + "hartsel=0x%x\n", addr, (unsigned) len, dmcontrol.hartsel); + break; + } + ); uint8_t id_bytes[4]; uint32_t id = 0; @@ -119,14 +132,15 @@ bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes) } addr = DEBUG_START + addr; - - if (addr >= DEBUG_DATA_START && addr < DEBUG_DATA_END) { - memcpy(dmdata + addr - DEBUG_DATA_START, bytes, len); + + if (addr >= debug_data_start && (addr + len) <= (debug_data_start + sizeof(dmdata))) { + memcpy(dmdata + addr - debug_data_start, bytes, len); return true; } - - if (addr >= DEBUG_PROGBUF_START && addr < DEBUG_PROGBUF_END) { - memcpy(program_buffer + addr - DEBUG_PROGBUF_START, bytes, len); + + if (addr >= debug_progbuf_start && ((addr + len) <= (debug_progbuf_start + sizeof(program_buffer)))) { + memcpy(program_buffer + addr - debug_progbuf_start, bytes, len); + return true; } @@ -204,18 +218,26 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) { unsigned i = address - DMI_DATA0; result = read32(dmdata, i); + if (abstractcs.busy) { + result = -1; + fprintf(stderr, "\ndmi_read(0x%02x (data[%d]) -> -1 because abstractcs.busy==true\n", address, i); + } if (abstractcs.busy && abstractcs.cmderr == CMDERR_NONE) { abstractcs.cmderr = CMDERR_BUSY; } - if ((abstractauto.autoexecdata >> i) & 1){ + if (!abstractcs.busy && ((abstractauto.autoexecdata >> i) & 1)) { perform_abstract_command(); } } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progsize) { - unsigned i = address = DMI_PROGBUF0; + unsigned i = address - DMI_PROGBUF0; result = read32(program_buffer, i); - if ((abstractauto.autoexecprogbuf >> i) & 1) { + if (abstractcs.busy) { + result = -1; + fprintf(stderr, "\ndmi_read(0x%02x (progbuf[%d]) -> -1 because abstractcs.busy==true\n", address, i); + } + if (!abstractcs.busy && ((abstractauto.autoexecprogbuf >> i) & 1)) { perform_abstract_command(); } @@ -266,7 +288,7 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) } else { dmstatus.allresumeack = false; } - + result = set_field(result, DMI_DMSTATUS_ALLNONEXISTENT, dmstatus.allnonexistant); result = set_field(result, DMI_DMSTATUS_ALLUNAVAIL, dmstatus.allunavail); result = set_field(result, DMI_DMSTATUS_ALLRUNNING, dmstatus.allrunning); @@ -300,7 +322,7 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) result = set_field(result, DMI_HARTINFO_NSCRATCH, 1); result = set_field(result, DMI_HARTINFO_DATAACCESS, 1); result = set_field(result, DMI_HARTINFO_DATASIZE, abstractcs.datacount); - result = set_field(result, DMI_HARTINFO_DATAADDR, DEBUG_DATA_START); + result = set_field(result, DMI_HARTINFO_DATAADDR, debug_data_start); break; default: result = 0; @@ -345,22 +367,22 @@ bool debug_module_t::perform_abstract_command() switch (size) { case 2: if (write) - write32(debug_rom_abstract, 0, lw(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_abstract, 0, lw(regnum, ZERO, debug_data_start)); else - write32(debug_rom_abstract, 0, sw(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_abstract, 0, sw(regnum, ZERO, debug_data_start)); break; case 3: if (write) - write32(debug_rom_abstract, 0, ld(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_abstract, 0, ld(regnum, ZERO, debug_data_start)); else - write32(debug_rom_abstract, 0, sd(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_abstract, 0, sd(regnum, ZERO, debug_data_start)); break; /* case 4: if (write) - write32(debug_rom_code, 0, lq(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_rom_code, 0, lq(regnum, ZERO, debug_data_start)); else - write32(debug_rom_code, 0, sq(regnum, ZERO, DEBUG_DATA_START)); + write32(debug_rom_code, 0, sq(regnum, ZERO, debug_data_start)); break; */ default: @@ -368,18 +390,20 @@ bool debug_module_t::perform_abstract_command() return true; } } else { - // Should be a NOP. Store DEBUG_DATA to x0. - write32(debug_rom_abstract, 0, sw(ZERO, ZERO, DEBUG_DATA_START)); + //NOP + write32(debug_abstract, 0, addi(ZERO, ZERO, 0)); } - + if (get_field(command, AC_ACCESS_REGISTER_POSTEXEC)) { - write32(debug_rom_abstract, 1, jal(ZERO, DEBUG_PROGBUF_START - DEBUG_ABSTRACT_START)); + // Since the next instruction is what we will use, just use nother NOP + // to get there. + write32(debug_abstract, 1, addi(ZERO, ZERO, 0)); } else { - write32(debug_rom_abstract, 1, ebreak()); + write32(debug_abstract, 1, ebreak()); } debug_rom_flags[dmcontrol.hartsel] |= 1 << DEBUG_ROM_FLAG_GO; - + abstractcs.busy = true; } else { abstractcs.cmderr = CMDERR_NOTSUP; @@ -392,19 +416,29 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) D(fprintf(stderr, "dmi_write(0x%x, 0x%x)\n", address, value)); if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) { unsigned i = address - DMI_DATA0; - write32(dmdata, address - DMI_DATA0, value); + if (!abstractcs.busy) + write32(dmdata, address - DMI_DATA0, value); if (abstractcs.busy && abstractcs.cmderr == CMDERR_NONE) { abstractcs.cmderr = CMDERR_BUSY; } - if ((abstractauto.autoexecdata >> i) & 1) + if (!abstractcs.busy && ((abstractauto.autoexecdata >> i) & 1)) { perform_abstract_command(); + } return true; } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progsize) { - write32(program_buffer, address - DMI_PROGBUF0, value); + unsigned i = address - DMI_PROGBUF0; + + if (!abstractcs.busy) + write32(program_buffer, i, value); + + if (!abstractcs.busy && ((abstractauto.autoexecprogbuf >> i) & 1)) { + perform_abstract_command(); + } return true; + } else { switch (address) { case DMI_DMCONTROL: @@ -425,6 +459,9 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) debug_rom_flags[dmcontrol.hartsel] |= (1 << DEBUG_ROM_FLAG_RESUME); resumeack[dmcontrol.hartsel] = false; } + if (dmcontrol.ndmreset) { + proc->reset(); + } } } return true; @@ -438,9 +475,11 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) return true; case DMI_ABSTRACTAUTO: - abstractauto.autoexecprogbuf = get_field(value, DMI_ABSTRACTAUTO_AUTOEXECPROGBUF); - abstractauto.autoexecdata = get_field(value, DMI_ABSTRACTAUTO_AUTOEXECDATA); - break; + abstractauto.autoexecprogbuf = get_field(value, + DMI_ABSTRACTAUTO_AUTOEXECPROGBUF); + abstractauto.autoexecdata = get_field(value, + DMI_ABSTRACTAUTO_AUTOEXECDATA); + return true; } } return false;