From: Tim Newsome Date: Mon, 19 Feb 2018 19:55:19 +0000 (-0800) Subject: Merge pull request #171 from riscv/sysbusbits X-Git-Url: https://git.libre-soc.org/?p=riscv-isa-sim.git;a=commitdiff_plain;h=c746388b542eacd2586acfbc0a742b08a5c0bd6f;hp=4c1c92f59f7b021eb2fa3b373b60f0e8b7c08a17 Merge pull request #171 from riscv/sysbusbits Add support for debug bus mastering --- diff --git a/riscv/debug_defines.h b/riscv/debug_defines.h index 1d3e1c0..04500e5 100644 --- a/riscv/debug_defines.h +++ b/riscv/debug_defines.h @@ -295,7 +295,7 @@ * * Other values are reserved for future use. */ -#define CSR_TDATA1_TYPE_OFFSET XLEN-4 +#define CSR_TDATA1_TYPE_OFFSET (XLEN-4) #define CSR_TDATA1_TYPE_LENGTH 4 #define CSR_TDATA1_TYPE (0xfULL << CSR_TDATA1_TYPE_OFFSET) /* @@ -307,14 +307,14 @@ * * This bit is only writable from Debug Mode. */ -#define CSR_TDATA1_DMODE_OFFSET XLEN-5 +#define CSR_TDATA1_DMODE_OFFSET (XLEN-5) #define CSR_TDATA1_DMODE_LENGTH 1 #define CSR_TDATA1_DMODE (0x1ULL << CSR_TDATA1_DMODE_OFFSET) /* * Trigger-specific data. */ #define CSR_TDATA1_DATA_OFFSET 0 -#define CSR_TDATA1_DATA_LENGTH XLEN - 5 +#define CSR_TDATA1_DATA_LENGTH (XLEN - 5) #define CSR_TDATA1_DATA (((1L< 0) { + sbcs.version = 1; + sbcs.asize = sizeof(reg_t) * 8; + } + if (max_bus_master_bits >= 64) + sbcs.access64 = true; + if (max_bus_master_bits >= 32) + sbcs.access32 = true; + if (max_bus_master_bits >= 16) + sbcs.access16 = true; + if (max_bus_master_bits >= 8) + sbcs.access8 = true; } void debug_module_t::add_device(bus_t *bus) { @@ -228,6 +233,71 @@ processor_t *debug_module_t::current_proc() const return proc; } +unsigned debug_module_t::sb_access_bits() +{ + return 8 << sbcs.sbaccess; +} + +void debug_module_t::sb_autoincrement() +{ + if (!sbcs.autoincrement || !max_bus_master_bits) + return; + + uint64_t value = sbaddress[0] + sb_access_bits() / 8; + sbaddress[0] = value; + uint32_t carry = value >> 32; + + value = sbaddress[1] + carry; + sbaddress[1] = value; + carry = value >> 32; + + value = sbaddress[2] + carry; + sbaddress[2] = value; + carry = value >> 32; + + sbaddress[3] += carry; +} + +void debug_module_t::sb_read() +{ + reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0]; + try { + if (sbcs.sbaccess == 0 && max_bus_master_bits >= 8) { + sbdata[0] = sim->debug_mmu->load_uint8(address); + } else if (sbcs.sbaccess == 1 && max_bus_master_bits >= 16) { + sbdata[0] = sim->debug_mmu->load_uint16(address); + } else if (sbcs.sbaccess == 2 && max_bus_master_bits >= 32) { + sbdata[0] = sim->debug_mmu->load_uint32(address); + } else if (sbcs.sbaccess == 3 && max_bus_master_bits >= 64) { + uint64_t value = sim->debug_mmu->load_uint32(address); + sbdata[0] = value; + sbdata[1] = value >> 32; + } else { + sbcs.error = 3; + } + } catch (trap_load_access_fault& t) { + sbcs.error = 2; + } +} + +void debug_module_t::sb_write() +{ + reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0]; + D(fprintf(stderr, "sb_write() 0x%x @ 0x%lx\n", sbdata[0], address)); + if (sbcs.sbaccess == 0 && max_bus_master_bits >= 8) { + sim->debug_mmu->store_uint8(address, sbdata[0]); + } else if (sbcs.sbaccess == 1 && max_bus_master_bits >= 16) { + sim->debug_mmu->store_uint16(address, sbdata[0]); + } else if (sbcs.sbaccess == 2 && max_bus_master_bits >= 32) { + sim->debug_mmu->store_uint32(address, sbdata[0]); + } else if (sbcs.sbaccess == 3 && max_bus_master_bits >= 64) { + sim->debug_mmu->store_uint64(address, + (((uint64_t) sbdata[1]) << 32) | sbdata[0]); + } else { + sbcs.error = 3; + } +} + bool debug_module_t::dmi_read(unsigned address, uint32_t *value) { uint32_t result = 0; @@ -268,7 +338,8 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) result = set_field(result, DMI_DMCONTROL_HALTREQ, dmcontrol.haltreq); result = set_field(result, DMI_DMCONTROL_RESUMEREQ, dmcontrol.resumereq); - result = set_field(result, DMI_DMCONTROL_HARTSEL, dmcontrol.hartsel); + result = set_field(result, ((1L<> mems, 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) + std::vector const hartids, unsigned progsize, + unsigned max_bus_master_bits) + : htif_t(args), mems(mems), procs(std::max(nprocs, size_t(1))), + start_pc(start_pc), current_step(0), current_proc(0), debug(false), + remote_bitbang(NULL), debug_module(this, progsize, max_bus_master_bits) { signal(SIGINT, &handle_signal); diff --git a/riscv/sim.h b/riscv/sim.h index ce5fe19..47f3a45 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -22,7 +22,7 @@ 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, - unsigned progsize); + unsigned progsize, unsigned max_bus_master_bits); ~sim_t(); // run the simulation to completion @@ -38,8 +38,6 @@ public: processor_t* get_core(size_t i) { return procs.at(i); } unsigned nprocs() const { return procs.size(); } - debug_module_t debug_module; - private: std::vector> mems; mmu_t* debug_mmu; // debug port into main memory @@ -92,6 +90,7 @@ private: friend class processor_t; friend class mmu_t; + friend class debug_module_t; // htif friend void sim_thread_main(void*); @@ -105,6 +104,12 @@ private: void write_chunk(addr_t taddr, size_t len, const void* src); size_t chunk_align() { return 8; } size_t chunk_max_size() { return 8; } + +public: + // Initialize this after procs, because in debug_module_t::reset() we + // enumerate processors, which segfaults if procs hasn't been initialized + // yet. + debug_module_t debug_module; }; extern volatile bool ctrlc_pressed; diff --git a/spike_main/spike.cc b/spike_main/spike.cc index d3caa22..f77d488 100644 --- a/spike_main/spike.cc +++ b/spike_main/spike.cc @@ -37,6 +37,8 @@ static void help() fprintf(stderr, " --rbb-port= Listen on for remote bitbang connection\n"); fprintf(stderr, " --dump-dts Print device tree string and exit\n"); fprintf(stderr, " --progsize= progsize for the debug module [default 2]\n"); + fprintf(stderr, " --debug-sba= debug bus master supports up to " + " wide accesses [default 0]\n"); exit(1); } @@ -89,6 +91,7 @@ int main(int argc, char** argv) uint16_t rbb_port = 0; bool use_rbb = false; unsigned progsize = 2; + unsigned max_bus_master_bits = 0; std::vector hartids; auto const hartids_parser = [&](const char *s) { @@ -130,6 +133,8 @@ int main(int argc, char** argv) } }); parser.option(0, "progsize", 1, [&](const char* s){progsize = atoi(s);}); + parser.option(0, "debug-sba", 1, + [&](const char* s){max_bus_master_bits = atoi(s);}); auto argv1 = parser.parse(argv); std::vector htif_args(argv1, (const char*const*)argv + argc); @@ -137,7 +142,7 @@ int main(int argc, char** argv) mems = make_mems("2048"); sim_t s(isa, nprocs, halted, start_pc, mems, htif_args, std::move(hartids), - progsize); + progsize, max_bus_master_bits); std::unique_ptr remote_bitbang((remote_bitbang_t *) NULL); std::unique_ptr jtag_dtm(new jtag_dtm_t(&s.debug_module)); if (use_rbb) {