From 46a67860915391458d7cc8cb93248059df20b8f2 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Tue, 10 Oct 2017 15:53:23 -0700 Subject: Make progbuf a run-time option. Also add an implicit ebreak after the program buffer. This is not part of the spec, but hopefully it will be. --- riscv/debug_module.cc | 20 ++++++++++++++++---- riscv/debug_module.h | 18 ++++++++++++------ riscv/execute.cc | 4 +--- riscv/sim.cc | 6 ++++-- riscv/sim.h | 3 ++- spike_main/spike.cc | 10 +++++++--- 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc index 985cbbd..cbc8c48 100644 --- a/riscv/debug_module.cc +++ b/riscv/debug_module.cc @@ -16,7 +16,12 @@ ///////////////////////// debug_module_t -debug_module_t::debug_module_t(sim_t *sim) : sim(sim) +debug_module_t::debug_module_t(sim_t *sim, unsigned progsize) : + progsize(progsize), + program_buffer_bytes(4 + 4*progsize), + debug_progbuf_start(debug_data_start - program_buffer_bytes), + debug_abstract_start(debug_progbuf_start - debug_abstract_size*4), + sim(sim) { dmcontrol = {0}; @@ -29,17 +34,24 @@ debug_module_t::debug_module_t(sim_t *sim) : sim(sim) abstractauto = {0}; + program_buffer = new uint8_t[program_buffer_bytes]; + 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(program_buffer, 0, program_buffer_bytes); + program_buffer[progsize] = ebreak(); memset(dmdata, 0, sizeof(dmdata)); write32(debug_rom_whereto, 0, jal(ZERO, debug_abstract_start - DEBUG_ROM_WHERETO)); memset(debug_abstract, 0, sizeof(debug_abstract)); +} +debug_module_t::~debug_module_t() +{ + delete[] program_buffer; } void debug_module_t::reset() @@ -97,7 +109,7 @@ bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes) return true; } - if (addr >= debug_progbuf_start && ((addr + len) <= (debug_progbuf_start + sizeof(program_buffer)))) { + if (addr >= debug_progbuf_start && ((addr + len) <= (debug_progbuf_start + program_buffer_bytes))) { memcpy(bytes, program_buffer + addr - debug_progbuf_start, len); return true; } @@ -138,7 +150,7 @@ bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes) return true; } - if (addr >= debug_progbuf_start && ((addr + len) <= (debug_progbuf_start + sizeof(program_buffer)))) { + if (addr >= debug_progbuf_start && ((addr + len) <= (debug_progbuf_start + program_buffer_bytes))) { memcpy(program_buffer + addr - debug_progbuf_start, bytes, len); return true; diff --git a/riscv/debug_module.h b/riscv/debug_module.h index f0d2a47..8b209fb 100644 --- a/riscv/debug_module.h +++ b/riscv/debug_module.h @@ -59,7 +59,8 @@ typedef struct { class debug_module_t : public abstract_device_t { public: - debug_module_t(sim_t *sim); + debug_module_t(sim_t *sim, unsigned progsize); + ~debug_module_t(); void add_device(bus_t *bus); @@ -74,18 +75,23 @@ class debug_module_t : public abstract_device_t private: static const unsigned datasize = 2; - static const unsigned progsize = 16; + // Size of program_buffer in 32-bit words, as exposed to the rest of the + // world. + unsigned progsize; + // Actual size of the program buffer, which is 1 word bigger than we let on + // to implement the implicit ebreak at the end. + unsigned program_buffer_bytes; static const unsigned debug_data_start = 0x380; - static const unsigned debug_progbuf_start = debug_data_start - progsize*4; + unsigned debug_progbuf_start; static const unsigned debug_abstract_size = 2; - static const unsigned debug_abstract_start = debug_progbuf_start - debug_abstract_size*4; - + unsigned debug_abstract_start; + sim_t *sim; uint8_t debug_rom_whereto[4]; uint8_t debug_abstract[debug_abstract_size * 4]; - uint8_t program_buffer[progsize * 4]; + uint8_t *program_buffer; uint8_t dmdata[datasize * 4]; bool halted[1024]; diff --git a/riscv/execute.cc b/riscv/execute.cc index 25e9520..878893c 100644 --- a/riscv/execute.cc +++ b/riscv/execute.cc @@ -147,14 +147,12 @@ void processor_t::step(size_t n) break; } - if (unlikely(state.pc >= DEBUG_START && + if (unlikely(state.pc >= DEBUG_ROM_ENTRY && state.pc < DEBUG_END)) { // We're waiting for the debugger to tell us something. return; } - - } } else while (instret < n) diff --git a/riscv/sim.cc b/riscv/sim.cc index 793a2c8..81d1307 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -25,8 +25,10 @@ static void handle_signal(int sig) sim_t::sim_t(const char* isa, size_t nprocs, bool halted, reg_t start_pc, std::vector> mems, - const std::vector& args, std::vector const hartids) - : htif_t(args), debug_module(this), mems(mems), procs(std::max(nprocs, size_t(1))), + const std::vector& args, + std::vector const hartids, unsigned progsize) + : htif_t(args), debug_module(this, progsize), mems(mems), + procs(std::max(nprocs, size_t(1))), start_pc(start_pc), current_step(0), current_proc(0), debug(false), remote_bitbang(NULL) { diff --git a/riscv/sim.h b/riscv/sim.h index b102a6b..ce5fe19 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -21,7 +21,8 @@ class sim_t : public htif_t public: sim_t(const char* isa, size_t _nprocs, bool halted, reg_t start_pc, std::vector> mems, - const std::vector& args, const std::vector hartids); + const std::vector& args, const std::vector hartids, + unsigned progsize); ~sim_t(); // run the simulation to completion diff --git a/spike_main/spike.cc b/spike_main/spike.cc index 863ee81..1205965 100644 --- a/spike_main/spike.cc +++ b/spike_main/spike.cc @@ -25,7 +25,7 @@ static void help() fprintf(stderr, " -g Track histogram of PCs\n"); fprintf(stderr, " -l Generate a log of execution\n"); fprintf(stderr, " -h Print this help message\n"); - fprintf(stderr, " -H Start halted, allowing a debugger to connect\n"); + fprintf(stderr, " -H Start halted, allowing a debugger to connect\n"); fprintf(stderr, " --isa= RISC-V ISA string [default %s]\n", DEFAULT_ISA); fprintf(stderr, " --pc=
Override ELF entry point\n"); fprintf(stderr, " --hartids= Explicitly specify hartids, default is 0,1,...\n"); @@ -35,7 +35,8 @@ static void help() fprintf(stderr, " --extension= Specify RoCC Extension\n"); fprintf(stderr, " --extlib= Shared library to load\n"); fprintf(stderr, " --rbb-port= Listen on for remote bitbang connection\n"); - fprintf(stderr, " --dump-dts Print device tree string and exit\n"); + fprintf(stderr, " --dump-dts Print device tree string and exit\n"); + fprintf(stderr, " --progsize= progsize for the debug module [default 2]\n"); exit(1); } @@ -85,6 +86,7 @@ int main(int argc, char** argv) const char* isa = DEFAULT_ISA; uint16_t rbb_port = 0; bool use_rbb = false; + unsigned progsize = 2; std::vector hartids; auto const hartids_parser = [&](const char *s) { @@ -125,13 +127,15 @@ int main(int argc, char** argv) exit(-1); } }); + parser.option(0, "progsize", 1, [&](const char* s){progsize = atoi(s);}); auto argv1 = parser.parse(argv); std::vector htif_args(argv1, (const char*const*)argv + argc); if (mems.empty()) mems = make_mems("2048"); - sim_t s(isa, nprocs, halted, start_pc, mems, htif_args, std::move(hartids)); + sim_t s(isa, nprocs, halted, start_pc, mems, htif_args, std::move(hartids), + progsize); std::unique_ptr remote_bitbang((remote_bitbang_t *) NULL); std::unique_ptr jtag_dtm(new jtag_dtm_t(&s.debug_module)); if (use_rbb) { -- cgit v1.1 From fa09d8179f00a731f6a39d039d97188b0ec758d6 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 12 Oct 2017 12:05:26 -0700 Subject: Update to latest debug_defines.h. --- riscv/debug_defines.h | 841 +++++++++++++++++++++++--------------------------- riscv/debug_module.cc | 26 +- riscv/debug_module.h | 9 +- 3 files changed, 411 insertions(+), 465 deletions(-) diff --git a/riscv/debug_defines.h b/riscv/debug_defines.h index cb07ec2..6067dbe 100644 --- a/riscv/debug_defines.h +++ b/riscv/debug_defines.h @@ -4,13 +4,13 @@ */ #define DTM_IDCODE_VERSION_OFFSET 28 #define DTM_IDCODE_VERSION_LENGTH 4 -#define DTM_IDCODE_VERSION (0xf << DTM_IDCODE_VERSION_OFFSET) +#define DTM_IDCODE_VERSION (0xfU << DTM_IDCODE_VERSION_OFFSET) /* * Identifies the designer's part number of this part. */ #define DTM_IDCODE_PARTNUMBER_OFFSET 12 #define DTM_IDCODE_PARTNUMBER_LENGTH 16 -#define DTM_IDCODE_PARTNUMBER (0xffff << DTM_IDCODE_PARTNUMBER_OFFSET) +#define DTM_IDCODE_PARTNUMBER (0xffffU << DTM_IDCODE_PARTNUMBER_OFFSET) /* * Identifies the designer/manufacturer of this part. Bits 6:0 must be * bits 6:0 of the designer/manufacturer's Identification Code as @@ -20,10 +20,10 @@ */ #define DTM_IDCODE_MANUFID_OFFSET 1 #define DTM_IDCODE_MANUFID_LENGTH 11 -#define DTM_IDCODE_MANUFID (0x7ff << DTM_IDCODE_MANUFID_OFFSET) +#define DTM_IDCODE_MANUFID (0x7ffU << DTM_IDCODE_MANUFID_OFFSET) #define DTM_IDCODE_1_OFFSET 0 #define DTM_IDCODE_1_LENGTH 1 -#define DTM_IDCODE_1 (0x1 << DTM_IDCODE_1_OFFSET) +#define DTM_IDCODE_1 (0x1U << DTM_IDCODE_1_OFFSET) #define DTM_DTMCS 0x10 /* * Writing 1 to this bit does a hard reset of the DTM, @@ -35,7 +35,7 @@ */ #define DTM_DTMCS_DMIHARDRESET_OFFSET 17 #define DTM_DTMCS_DMIHARDRESET_LENGTH 1 -#define DTM_DTMCS_DMIHARDRESET (0x1 << DTM_DTMCS_DMIHARDRESET_OFFSET) +#define DTM_DTMCS_DMIHARDRESET (0x1U << DTM_DTMCS_DMIHARDRESET_OFFSET) /* * Writing 1 to this bit clears the sticky error state * and allows the DTM to retry or complete the previous @@ -43,7 +43,7 @@ */ #define DTM_DTMCS_DMIRESET_OFFSET 16 #define DTM_DTMCS_DMIRESET_LENGTH 1 -#define DTM_DTMCS_DMIRESET (0x1 << DTM_DTMCS_DMIRESET_OFFSET) +#define DTM_DTMCS_DMIRESET (0x1U << DTM_DTMCS_DMIRESET_OFFSET) /* * This is a hint to the debugger of the minimum number of * cycles a debugger should spend in @@ -61,7 +61,7 @@ */ #define DTM_DTMCS_IDLE_OFFSET 12 #define DTM_DTMCS_IDLE_LENGTH 3 -#define DTM_DTMCS_IDLE (0x7 << DTM_DTMCS_IDLE_OFFSET) +#define DTM_DTMCS_IDLE (0x7U << DTM_DTMCS_IDLE_OFFSET) /* * 0: No error. * @@ -74,24 +74,24 @@ */ #define DTM_DTMCS_DMISTAT_OFFSET 10 #define DTM_DTMCS_DMISTAT_LENGTH 2 -#define DTM_DTMCS_DMISTAT (0x3 << DTM_DTMCS_DMISTAT_OFFSET) +#define DTM_DTMCS_DMISTAT (0x3U << DTM_DTMCS_DMISTAT_OFFSET) /* * The size of \Faddress in \Rdmi. */ #define DTM_DTMCS_ABITS_OFFSET 4 #define DTM_DTMCS_ABITS_LENGTH 6 -#define DTM_DTMCS_ABITS (0x3f << DTM_DTMCS_ABITS_OFFSET) +#define DTM_DTMCS_ABITS (0x3fU << DTM_DTMCS_ABITS_OFFSET) /* * 0: Version described in spec version 0.11. * -* 1: Version described in spec version 0.12 (and later?), which +* 1: Version described in spec version 0.13 (and later?), which * reduces the DMI data width to 32 bits. * -* Other values are reserved for future use. +* 15: Version not described in any available version of this spec. */ #define DTM_DTMCS_VERSION_OFFSET 0 #define DTM_DTMCS_VERSION_LENGTH 4 -#define DTM_DTMCS_VERSION (0xf << DTM_DTMCS_VERSION_OFFSET) +#define DTM_DTMCS_VERSION (0xfU << DTM_DTMCS_VERSION_OFFSET) #define DTM_DMI 0x11 /* * Address used for DMI access. In Update-DR this value is used @@ -106,11 +106,16 @@ */ #define DTM_DMI_DATA_OFFSET 2 #define DTM_DMI_DATA_LENGTH 32 -#define DTM_DMI_DATA (0xffffffffL << DTM_DMI_DATA_OFFSET) +#define DTM_DMI_DATA (0xffffffffULL << DTM_DMI_DATA_OFFSET) /* * When the debugger writes this field, it has the following meaning: * -* 0: Ignore \Fdata. (nop) +* 0: Ignore \Fdata and \Faddress. (nop) +* +* Don't send anything over the DMI during Update-DR. +* This operation should never result in a busy or error response. +* The address and data reported in the following Capture-DR +* are undefined. * * 1: Read from \Faddress. (read) * @@ -128,8 +133,10 @@ * this access will be ignored. This status is sticky and can be * cleared by writing \Fdmireset in \Rdtmcs. * -* This indicates that the DM itself responded with an error, e.g. -* in the System Bus and Serial Port overflow/underflow cases. +* This indicates that the DM itself responded with an error. +* Note: there are no specified cases in which the DM would +* respond with an error, and DMI is not required to support +* returning errors. * * 3: An operation was attempted while a DMI request is still in * progress. The data scanned into \Rdmi in this access will be @@ -146,49 +153,58 @@ */ #define DTM_DMI_OP_OFFSET 0 #define DTM_DMI_OP_LENGTH 2 -#define DTM_DMI_OP (0x3L << DTM_DMI_OP_OFFSET) +#define DTM_DMI_OP (0x3ULL << DTM_DMI_OP_OFFSET) #define CSR_DCSR 0x7b0 /* * 0: There is no external debug support. * -* 1: External debug support exists as it is described in this document. +* 4: External debug support exists as it is described in this document. * -* Other values are reserved for future standards. +* 15: There is external debug support, but it does not conform to any +* available version of this spec. */ -#define CSR_DCSR_XDEBUGVER_OFFSET 30 -#define CSR_DCSR_XDEBUGVER_LENGTH 2 -#define CSR_DCSR_XDEBUGVER (0x3 << CSR_DCSR_XDEBUGVER_OFFSET) +#define CSR_DCSR_XDEBUGVER_OFFSET 28 +#define CSR_DCSR_XDEBUGVER_LENGTH 4 +#define CSR_DCSR_XDEBUGVER (0xfU << CSR_DCSR_XDEBUGVER_OFFSET) /* * When 1, {\tt ebreak} instructions in Machine Mode enter Debug Mode. */ #define CSR_DCSR_EBREAKM_OFFSET 15 #define CSR_DCSR_EBREAKM_LENGTH 1 -#define CSR_DCSR_EBREAKM (0x1 << CSR_DCSR_EBREAKM_OFFSET) -/* -* When 1, {\tt ebreak} instructions in Hypervisor Mode enter Debug Mode. - */ -#define CSR_DCSR_EBREAKH_OFFSET 14 -#define CSR_DCSR_EBREAKH_LENGTH 1 -#define CSR_DCSR_EBREAKH (0x1 << CSR_DCSR_EBREAKH_OFFSET) +#define CSR_DCSR_EBREAKM (0x1U << CSR_DCSR_EBREAKM_OFFSET) /* * When 1, {\tt ebreak} instructions in Supervisor Mode enter Debug Mode. */ #define CSR_DCSR_EBREAKS_OFFSET 13 #define CSR_DCSR_EBREAKS_LENGTH 1 -#define CSR_DCSR_EBREAKS (0x1 << CSR_DCSR_EBREAKS_OFFSET) +#define CSR_DCSR_EBREAKS (0x1U << CSR_DCSR_EBREAKS_OFFSET) /* * When 1, {\tt ebreak} instructions in User/Application Mode enter * Debug Mode. */ #define CSR_DCSR_EBREAKU_OFFSET 12 #define CSR_DCSR_EBREAKU_LENGTH 1 -#define CSR_DCSR_EBREAKU (0x1 << CSR_DCSR_EBREAKU_OFFSET) +#define CSR_DCSR_EBREAKU (0x1U << CSR_DCSR_EBREAKU_OFFSET) +/* +* 0: Interrupts are disabled during single stepping. +* +* 1: Interrupts are enabled during single stepping. +* +* Implementations may hard wire this bit to 0. +* The debugger must read back the value it +* writes to check whether the feature is supported. If not +* supported, interrupt behavior can be emulated by the debugger. + */ +#define CSR_DCSR_STEPIE_OFFSET 11 +#define CSR_DCSR_STEPIE_LENGTH 1 +#define CSR_DCSR_STEPIE (0x1U << CSR_DCSR_STEPIE_OFFSET) /* * 0: Increment counters as usual. * -* 1: Don't increment any counters while in Debug Mode. This includes -* the {\tt cycle} and {\tt instret} CSRs. This is preferred for most -* debugging scenarios. +* 1: Don't increment any counters while in Debug Mode or on {\tt +* ebreak} instructions that cause entry into Debug Mode. These +* counters include the {\tt cycle} and {\tt instret} CSRs. This is +* preferred for most debugging scenarios. * * An implementation may choose not to support writing to this bit. * The debugger must read back the value it writes to check whether @@ -196,7 +212,7 @@ */ #define CSR_DCSR_STOPCOUNT_OFFSET 10 #define CSR_DCSR_STOPCOUNT_LENGTH 1 -#define CSR_DCSR_STOPCOUNT (0x1 << CSR_DCSR_STOPCOUNT_OFFSET) +#define CSR_DCSR_STOPCOUNT (0x1U << CSR_DCSR_STOPCOUNT_OFFSET) /* * 0: Increment timers as usual. * @@ -208,7 +224,7 @@ */ #define CSR_DCSR_STOPTIME_OFFSET 9 #define CSR_DCSR_STOPTIME_LENGTH 1 -#define CSR_DCSR_STOPTIME (0x1 << CSR_DCSR_STOPTIME_OFFSET) +#define CSR_DCSR_STOPTIME (0x1U << CSR_DCSR_STOPTIME_OFFSET) /* * Explains why Debug Mode was entered. * @@ -217,9 +233,9 @@ * * 1: An {\tt ebreak} instruction was executed. (priority 3) * -* 2: The Trigger Module caused a halt. (priority 4) +* 2: The Trigger Module caused a breakpoint exception. (priority 4) * -* 3: \Fhaltreq was set. (priority 2) +* 3: The debugger requested entry to Debug Mode. (priority 2) * * 4: The hart single stepped because \Fstep was set. (priority 1) * @@ -227,18 +243,17 @@ */ #define CSR_DCSR_CAUSE_OFFSET 6 #define CSR_DCSR_CAUSE_LENGTH 3 -#define CSR_DCSR_CAUSE (0x7 << CSR_DCSR_CAUSE_OFFSET) +#define CSR_DCSR_CAUSE (0x7U << CSR_DCSR_CAUSE_OFFSET) /* * When set and not in Debug Mode, the hart will only execute a single * instruction and then enter Debug Mode. -* Interrupts are disabled when this bit is set. * If the instruction does not complete due to an exception, * the hart will immediately enter Debug Mode before executing * the trap handler, with appropriate exception registers set. */ #define CSR_DCSR_STEP_OFFSET 2 #define CSR_DCSR_STEP_LENGTH 1 -#define CSR_DCSR_STEP (0x1 << CSR_DCSR_STEP_OFFSET) +#define CSR_DCSR_STEP (0x1U << CSR_DCSR_STEP_OFFSET) /* * Contains the privilege level the hart was operating in when Debug * Mode was entered. The encoding is described in Table @@ -251,23 +266,13 @@ */ #define CSR_DCSR_PRV_OFFSET 0 #define CSR_DCSR_PRV_LENGTH 2 -#define CSR_DCSR_PRV (0x3 << CSR_DCSR_PRV_OFFSET) +#define CSR_DCSR_PRV (0x3U << CSR_DCSR_PRV_OFFSET) #define CSR_DPC 0x7b1 #define CSR_DPC_DPC_OFFSET 0 #define CSR_DPC_DPC_LENGTH XLEN #define CSR_DPC_DPC (((1L<> i) & 1)) { perform_abstract_command(); } - } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progsize) { + } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) { unsigned i = address - DMI_PROGBUF0; result = read32(program_buffer, i); if (abstractcs.busy) { @@ -313,15 +313,15 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) result = set_field(result, DMI_DMSTATUS_ANYRESUMEACK, dmstatus.anyresumeack); result = set_field(result, DMI_DMSTATUS_AUTHENTICATED, dmstatus.authenticated); result = set_field(result, DMI_DMSTATUS_AUTHBUSY, dmstatus.authbusy); - result = set_field(result, DMI_DMSTATUS_VERSIONHI, dmstatus.versionhi); - result = set_field(result, DMI_DMSTATUS_VERSIONLO, dmstatus.versionlo); + result = set_field(result, DMI_DMSTATUS_VERSION, dmstatus.version); } break; case DMI_ABSTRACTCS: result = set_field(result, DMI_ABSTRACTCS_CMDERR, abstractcs.cmderr); result = set_field(result, DMI_ABSTRACTCS_BUSY, abstractcs.busy); result = set_field(result, DMI_ABSTRACTCS_DATACOUNT, abstractcs.datacount); - result = set_field(result, DMI_ABSTRACTCS_PROGSIZE, abstractcs.progsize); + result = set_field(result, DMI_ABSTRACTCS_PROGBUFSIZE, + abstractcs.progbufsize); break; case DMI_ABSTRACTAUTO: result = set_field(result, DMI_ABSTRACTAUTO_AUTOEXECPROGBUF, abstractauto.autoexecprogbuf); @@ -440,7 +440,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) } return true; - } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progsize) { + } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) { unsigned i = address - DMI_PROGBUF0; if (!abstractcs.busy) diff --git a/riscv/debug_module.h b/riscv/debug_module.h index 8b209fb..f6f2009 100644 --- a/riscv/debug_module.h +++ b/riscv/debug_module.h @@ -31,8 +31,7 @@ typedef struct { bool authenticated; bool authbusy; bool cfgstrvalid; - unsigned versionhi; - unsigned versionlo; + unsigned version; } dmstatus_t; typedef enum cmderr { @@ -47,7 +46,7 @@ typedef enum cmderr { typedef struct { bool busy; unsigned datacount; - unsigned progsize; + unsigned progbufsize; cmderr_t cmderr; } abstractcs_t; @@ -59,7 +58,7 @@ typedef struct { class debug_module_t : public abstract_device_t { public: - debug_module_t(sim_t *sim, unsigned progsize); + debug_module_t(sim_t *sim, unsigned progbufsize); ~debug_module_t(); void add_device(bus_t *bus); @@ -77,7 +76,7 @@ class debug_module_t : public abstract_device_t static const unsigned datasize = 2; // Size of program_buffer in 32-bit words, as exposed to the rest of the // world. - unsigned progsize; + unsigned progbufsize; // Actual size of the program buffer, which is 1 word bigger than we let on // to implement the implicit ebreak at the end. unsigned program_buffer_bytes; -- cgit v1.1 From 3582bab41908a649c975ae98ad97a0d84b48dcde Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 12 Oct 2017 12:07:11 -0700 Subject: Set impebreak. --- riscv/debug_module.cc | 9 ++++++++- riscv/debug_module.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc index b27fe35..981e991 100644 --- a/riscv/debug_module.cc +++ b/riscv/debug_module.cc @@ -26,6 +26,7 @@ debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize) : dmcontrol = {0}; dmstatus = {0}; + dmstatus.impebreak = true; dmstatus.authenticated = 1; dmstatus.version = 2; @@ -40,7 +41,10 @@ debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize) : memset(debug_rom_flags, 0, sizeof(debug_rom_flags)); memset(resumeack, 0, sizeof(resumeack)); memset(program_buffer, 0, program_buffer_bytes); - program_buffer[progbufsize] = ebreak(); + program_buffer[4*progbufsize] = ebreak(); + program_buffer[4*progbufsize+1] = ebreak() >> 8; + program_buffer[4*progbufsize+2] = ebreak() >> 16; + program_buffer[4*progbufsize+3] = ebreak() >> 24; memset(dmdata, 0, sizeof(dmdata)); write32(debug_rom_whereto, 0, @@ -65,6 +69,7 @@ void debug_module_t::reset() dmcontrol = {0}; dmstatus = {0}; + dmstatus.impebreak = true; dmstatus.authenticated = 1; dmstatus.version = 2; @@ -301,6 +306,8 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) dmstatus.allresumeack = false; } + result = set_field(result, DMI_DMSTATUS_IMPEBREAK, + dmstatus.impebreak); 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); diff --git a/riscv/debug_module.h b/riscv/debug_module.h index f6f2009..00c66cc 100644 --- a/riscv/debug_module.h +++ b/riscv/debug_module.h @@ -18,6 +18,7 @@ typedef struct { } dmcontrol_t; typedef struct { + bool impebreak; bool allnonexistant; bool anynonexistant; bool allunavail; -- cgit v1.1 From e58dffd30decbaf3e813f12cd04a5a798cc76d9d Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 11 Dec 2017 14:28:10 -0800 Subject: Update debug_defines to latest version. --- riscv/debug_defines.h | 70 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/riscv/debug_defines.h b/riscv/debug_defines.h index 6067dbe..1d3e1c0 100644 --- a/riscv/debug_defines.h +++ b/riscv/debug_defines.h @@ -544,6 +544,19 @@ #define CSR_ICOUNT_ACTION (0x3fULL << CSR_ICOUNT_ACTION_OFFSET) #define DMI_DMSTATUS 0x11 /* +* Gets set if the Debug Module was accessed incorrectly. +* +* 0 (none): No error. +* +* 1 (badaddr): There was an access to an unimplemented Debug Module +* address. +* +* 7 (other): An access failed for another reason. + */ +#define DMI_DMSTATUS_DMERR_OFFSET 24 +#define DMI_DMSTATUS_DMERR_LENGTH 3 +#define DMI_DMSTATUS_DMERR (0x7U << DMI_DMSTATUS_DMERR_OFFSET) +/* * If 1, then there is an implicit {\tt ebreak} instruction at the * non-existent word immediately after the Program Buffer. This saves * the debugger from having to write the {\tt ebreak} itself, and @@ -555,26 +568,27 @@ #define DMI_DMSTATUS_IMPEBREAK_LENGTH 1 #define DMI_DMSTATUS_IMPEBREAK (0x1U << DMI_DMSTATUS_IMPEBREAK_OFFSET) /* -* Gets set if the Debug Module was accessed incorrectly. -* -* 0 (none): No error. -* -* 1 (badaddr): There was an access to an unimplemented Debug Module -* address. -* -* 7 (other): An access failed for another reason. +* This field is 1 when all currently selected harts have been reset but the reset has not been acknowledged. */ -#define DMI_DMSTATUS_DMERR_OFFSET 18 -#define DMI_DMSTATUS_DMERR_LENGTH 3 -#define DMI_DMSTATUS_DMERR (0x7U << DMI_DMSTATUS_DMERR_OFFSET) +#define DMI_DMSTATUS_ALLHAVERESET_OFFSET 19 +#define DMI_DMSTATUS_ALLHAVERESET_LENGTH 1 +#define DMI_DMSTATUS_ALLHAVERESET (0x1U << DMI_DMSTATUS_ALLHAVERESET_OFFSET) +/* +* This field is 1 when any currently selected hart has been reset but the reset has not been acknowledged. + */ +#define DMI_DMSTATUS_ANYHAVERESET_OFFSET 18 +#define DMI_DMSTATUS_ANYHAVERESET_LENGTH 1 +#define DMI_DMSTATUS_ANYHAVERESET (0x1U << DMI_DMSTATUS_ANYHAVERESET_OFFSET) /* -* This field is 1 when all currently selected harts have acknowledged the previous \Fresumereq. +* This field is 1 when all currently selected harts have acknowledged +* the previous resume request. */ #define DMI_DMSTATUS_ALLRESUMEACK_OFFSET 17 #define DMI_DMSTATUS_ALLRESUMEACK_LENGTH 1 #define DMI_DMSTATUS_ALLRESUMEACK (0x1U << DMI_DMSTATUS_ALLRESUMEACK_OFFSET) /* -* This field is 1 when any currently selected hart has acknowledged the previous \Fresumereq. +* This field is 1 when any currently selected hart has acknowledged +* the previous resume request. */ #define DMI_DMSTATUS_ANYRESUMEACK_OFFSET 16 #define DMI_DMSTATUS_ANYRESUMEACK_LENGTH 1 @@ -675,11 +689,12 @@ #define DMI_DMSTATUS_VERSION (0xfU << DMI_DMSTATUS_VERSION_OFFSET) #define DMI_DMCONTROL 0x10 /* -* Halt request signal for all currently selected harts. When set to -* 1, each selected hart will halt if it is not currently halted. +* Writes the halt request bit for all currently selected harts. +* When set to 1, each selected hart will halt if it is not currently +* halted. * * Writing 1 or 0 has no effect on a hart which is already halted, but -* the bit should be cleared to 0 before the hart is resumed. +* the bit must be cleared to 0 before the hart is resumed. * * Writes apply to the new value of \Fhartsel and \Fhasel. */ @@ -687,10 +702,12 @@ #define DMI_DMCONTROL_HALTREQ_LENGTH 1 #define DMI_DMCONTROL_HALTREQ (0x1U << DMI_DMCONTROL_HALTREQ_OFFSET) /* -* Resume request signal for all currently selected harts. When set to 1, -* each selected hart will resume if it is currently halted. +* Writes the resume request bit for all currently selected harts. +* When set to 1, each selected hart will resume if it is currently +* halted. * -* This bit is ignored while \Fhaltreq is set. +* The resume request bit is ignored while the halt request bit is +* set. * * Writes apply to the new value of \Fhartsel and \Fhasel. */ @@ -698,9 +715,9 @@ #define DMI_DMCONTROL_RESUMEREQ_LENGTH 1 #define DMI_DMCONTROL_RESUMEREQ (0x1U << DMI_DMCONTROL_RESUMEREQ_OFFSET) /* -* This optional bit controls reset to all the currently selected harts. -* To perform a reset the debugger writes 1, and then writes 0 to -* deassert the reset signal. +* This optional field writes the reset bit for all the currently +* selected harts. To perform a reset the debugger writes 1, and then +* writes 0 to deassert the reset signal. * * If this feature is not implemented, the bit always stays 0, so * after writing 1 the debugger can read the register back to see if @@ -712,6 +729,15 @@ #define DMI_DMCONTROL_HARTRESET_LENGTH 1 #define DMI_DMCONTROL_HARTRESET (0x1U << DMI_DMCONTROL_HARTRESET_OFFSET) /* +* Writing 1 to this bit clears the {\tt havereset} bits for +* any selected harts. +* +* Writes apply to the new value of \Fhartsel and \Fhasel. + */ +#define DMI_DMCONTROL_ACKHAVERESET_OFFSET 28 +#define DMI_DMCONTROL_ACKHAVERESET_LENGTH 1 +#define DMI_DMCONTROL_ACKHAVERESET (0x1U << DMI_DMCONTROL_ACKHAVERESET_OFFSET) +/* * Selects the definition of currently selected harts. * * 0: There is a single currently selected hart, that selected by \Fhartsel. -- cgit v1.1