From b2672e5d5271b346a71ec33ab42c88437b9b60d1 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 1 Feb 2018 14:32:00 -0800 Subject: Add --debug-sba option This lets the user control whether the system bus access implements bus mastering. --- riscv/debug_module.cc | 85 +++++++++++++++++++++++---------------------------- riscv/debug_module.h | 3 +- riscv/sim.cc | 5 +-- riscv/sim.h | 2 +- spike_main/spike.cc | 7 ++++- 5 files changed, 50 insertions(+), 52 deletions(-) diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc index 1d18478..12956a5 100644 --- a/riscv/debug_module.cc +++ b/riscv/debug_module.cc @@ -16,9 +16,10 @@ ///////////////////////// debug_module_t -debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize) : +debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits) : progbufsize(progbufsize), program_buffer_bytes(4 + 4*progbufsize), + max_bus_master_bits(max_bus_master_bits), debug_progbuf_start(debug_data_start - program_buffer_bytes), debug_abstract_start(debug_progbuf_start - debug_abstract_size*4), sim(sim) @@ -70,12 +71,18 @@ void debug_module_t::reset() abstractauto = {0}; sbcs = {0}; - sbcs.version = 1; - sbcs.access64 = true; - sbcs.access32 = true; - sbcs.access16 = true; - sbcs.access8 = true; - sbcs.asize = sizeof(reg_t) * 8; + if (max_bus_master_bits > 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) { @@ -233,7 +240,7 @@ unsigned debug_module_t::sb_access_bits() void debug_module_t::sb_autoincrement() { - if (!sbcs.autoincrement) + if (!sbcs.autoincrement || !max_bus_master_bits) return; uint64_t value = sbaddress[0] + sb_access_bits() / 8; @@ -254,29 +261,19 @@ void debug_module_t::sb_autoincrement() void debug_module_t::sb_read() { reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0]; - D(fprintf(stderr, "sb_read() @ 0x%lx\n", address)); try { - switch (sbcs.sbaccess) { - case 0: - sbdata[0] = sim->debug_mmu->load_uint8(address); - break; - case 1: - sbdata[0] = sim->debug_mmu->load_uint16(address); - break; - case 2: - sbdata[0] = sim->debug_mmu->load_uint32(address); - D(fprintf(stderr, " -> 0x%x\n", sbdata[0])); - break; - case 3: - { - uint64_t value = sim->debug_mmu->load_uint32(address); - sbdata[0] = value; - sbdata[1] = value >> 32; - break; - } - default: - sbcs.error = 3; - break; + 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; @@ -287,23 +284,17 @@ 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)); - switch (sbcs.sbaccess) { - case 0: - sim->debug_mmu->store_uint8(address, sbdata[0]); - break; - case 1: - sim->debug_mmu->store_uint16(address, sbdata[0]); - break; - case 2: - sim->debug_mmu->store_uint32(address, sbdata[0]); - break; - case 3: - sim->debug_mmu->store_uint64(address, - (((uint64_t) sbdata[1]) << 32) | sbdata[0]); - break; - default: - sbcs.error = 3; - break; + 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; } } diff --git a/riscv/debug_module.h b/riscv/debug_module.h index d581be8..36037b4 100644 --- a/riscv/debug_module.h +++ b/riscv/debug_module.h @@ -74,7 +74,7 @@ typedef struct { class debug_module_t : public abstract_device_t { public: - debug_module_t(sim_t *sim, unsigned progbufsize); + debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits); ~debug_module_t(); void add_device(bus_t *bus); @@ -96,6 +96,7 @@ class debug_module_t : public abstract_device_t // 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; + unsigned max_bus_master_bits ; static const unsigned debug_data_start = 0x380; unsigned debug_progbuf_start; diff --git a/riscv/sim.cc b/riscv/sim.cc index 97697e4..009bb98 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -26,10 +26,11 @@ 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, unsigned progsize) + 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) + 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 e29cca4..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 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) { -- cgit v1.1