aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2019-05-14 11:02:15 -0700
committerGitHub <noreply@github.com>2019-05-14 11:02:15 -0700
commit8ac902f6ff877e976af434bfe8fa8445930174a1 (patch)
treec140d3661f447fc2e61f15ebeaa1956b1a358774 /riscv
parent8925aec9dc03d590e7cf8c45314a37e50ebfba02 (diff)
downloadspike-8ac902f6ff877e976af434bfe8fa8445930174a1.zip
spike-8ac902f6ff877e976af434bfe8fa8445930174a1.tar.gz
spike-8ac902f6ff877e976af434bfe8fa8445930174a1.tar.bz2
Clean up debug module options. (#299)
* Clean up debug module options. 1. Instead of passing each one a few levels deep, create debug_module_config_t which contains them all. 2. Rename all those command line options so they start with --dm for debug module. 3. Add --dm-no-halt-groups to disable halt group support. * Update changelog.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/debug_module.cc69
-rw-r--r--riscv/debug_module.h26
-rw-r--r--riscv/sim.cc10
-rw-r--r--riscv/sim.h4
4 files changed, 49 insertions, 60 deletions
diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc
index 20419b1..c4fb45c 100644
--- a/riscv/debug_module.cc
+++ b/riscv/debug_module.cc
@@ -31,16 +31,10 @@ static unsigned field_width(unsigned n)
///////////////////////// debug_module_t
-debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits,
- bool require_authentication, unsigned abstract_rti, bool support_hasel,
- bool support_abstract_csr_access) :
+debug_module_t::debug_module_t(sim_t *sim, const debug_module_config_t &config) :
nprocs(sim->nprocs()),
- progbufsize(progbufsize),
- program_buffer_bytes(4 + 4*progbufsize),
- max_bus_master_bits(max_bus_master_bits),
- require_authentication(require_authentication),
- abstract_rti(abstract_rti),
- support_abstract_csr_access(support_abstract_csr_access),
+ config(config),
+ program_buffer_bytes(4 + 4*config.progbufsize),
debug_progbuf_start(debug_data_start - program_buffer_bytes),
debug_abstract_start(debug_progbuf_start - debug_abstract_size*4),
custom_base(0),
@@ -49,8 +43,7 @@ debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bu
// The spec lets a debugger select nonexistent harts. Create hart_state for
// them because I'm too lazy to add the code to just ignore accesses.
hart_state(1 << field_width(sim->nprocs())),
- hart_array_mask(sim->nprocs()),
- support_hasel(support_hasel)
+ hart_array_mask(sim->nprocs())
{
D(fprintf(stderr, "debug_data_start=0x%x\n", debug_data_start));
D(fprintf(stderr, "debug_progbuf_start=0x%x\n", debug_progbuf_start));
@@ -62,10 +55,10 @@ debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bu
memset(debug_rom_flags, 0, sizeof(debug_rom_flags));
memset(program_buffer, 0, program_buffer_bytes);
- 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;
+ program_buffer[4*config.progbufsize] = ebreak();
+ program_buffer[4*config.progbufsize+1] = ebreak() >> 8;
+ program_buffer[4*config.progbufsize+2] = ebreak() >> 16;
+ program_buffer[4*config.progbufsize+3] = ebreak() >> 24;
memset(dmdata, 0, sizeof(dmdata));
write32(debug_rom_whereto, 0,
@@ -93,27 +86,27 @@ void debug_module_t::reset()
dmstatus = {0};
dmstatus.impebreak = true;
- dmstatus.authenticated = !require_authentication;
+ dmstatus.authenticated = !config.require_authentication;
dmstatus.version = 2;
abstractcs = {0};
abstractcs.datacount = sizeof(dmdata) / 4;
- abstractcs.progbufsize = progbufsize;
+ abstractcs.progbufsize = config.progbufsize;
abstractauto = {0};
sbcs = {0};
- if (max_bus_master_bits > 0) {
+ if (config.max_bus_master_bits > 0) {
sbcs.version = 1;
sbcs.asize = sizeof(reg_t) * 8;
}
- if (max_bus_master_bits >= 64)
+ if (config.max_bus_master_bits >= 64)
sbcs.access64 = true;
- if (max_bus_master_bits >= 32)
+ if (config.max_bus_master_bits >= 32)
sbcs.access32 = true;
- if (max_bus_master_bits >= 16)
+ if (config.max_bus_master_bits >= 16)
sbcs.access16 = true;
- if (max_bus_master_bits >= 8)
+ if (config.max_bus_master_bits >= 8)
sbcs.access8 = true;
challenge = random();
@@ -297,7 +290,7 @@ unsigned debug_module_t::sb_access_bits()
void debug_module_t::sb_autoincrement()
{
- if (!sbcs.autoincrement || !max_bus_master_bits)
+ if (!sbcs.autoincrement || !config.max_bus_master_bits)
return;
uint64_t value = sbaddress[0] + sb_access_bits() / 8;
@@ -319,13 +312,13 @@ 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) {
+ if (sbcs.sbaccess == 0 && config.max_bus_master_bits >= 8) {
sbdata[0] = sim->debug_mmu->load_uint8(address);
- } else if (sbcs.sbaccess == 1 && max_bus_master_bits >= 16) {
+ } else if (sbcs.sbaccess == 1 && config.max_bus_master_bits >= 16) {
sbdata[0] = sim->debug_mmu->load_uint16(address);
- } else if (sbcs.sbaccess == 2 && max_bus_master_bits >= 32) {
+ } else if (sbcs.sbaccess == 2 && config.max_bus_master_bits >= 32) {
sbdata[0] = sim->debug_mmu->load_uint32(address);
- } else if (sbcs.sbaccess == 3 && max_bus_master_bits >= 64) {
+ } else if (sbcs.sbaccess == 3 && config.max_bus_master_bits >= 64) {
uint64_t value = sim->debug_mmu->load_uint64(address);
sbdata[0] = value;
sbdata[1] = value >> 32;
@@ -341,13 +334,13 @@ 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) {
+ if (sbcs.sbaccess == 0 && config.max_bus_master_bits >= 8) {
sim->debug_mmu->store_uint8(address, sbdata[0]);
- } else if (sbcs.sbaccess == 1 && max_bus_master_bits >= 16) {
+ } else if (sbcs.sbaccess == 1 && config.max_bus_master_bits >= 16) {
sim->debug_mmu->store_uint16(address, sbdata[0]);
- } else if (sbcs.sbaccess == 2 && max_bus_master_bits >= 32) {
+ } else if (sbcs.sbaccess == 2 && config.max_bus_master_bits >= 32) {
sim->debug_mmu->store_uint32(address, sbdata[0]);
- } else if (sbcs.sbaccess == 3 && max_bus_master_bits >= 64) {
+ } else if (sbcs.sbaccess == 3 && config.max_bus_master_bits >= 64) {
sim->debug_mmu->store_uint64(address,
(((uint64_t) sbdata[1]) << 32) | sbdata[0]);
} else {
@@ -374,7 +367,7 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
if (!abstractcs.busy && ((abstractauto.autoexecdata >> i) & 1)) {
perform_abstract_command();
}
- } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) {
+ } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + config.progbufsize) {
unsigned i = address - DMI_PROGBUF0;
result = read32(program_buffer, i);
if (abstractcs.busy) {
@@ -587,7 +580,7 @@ bool debug_module_t::perform_abstract_command()
unsigned i = 0;
if (get_field(command, AC_ACCESS_REGISTER_TRANSFER)) {
- if (regno < 0x1000 && support_abstract_csr_access) {
+ if (regno < 0x1000 && config.support_abstract_csr_access) {
write32(debug_abstract, i++, csrw(S0, CSR_DSCRATCH));
if (write) {
@@ -700,7 +693,7 @@ bool debug_module_t::perform_abstract_command()
}
debug_rom_flags[dmcontrol.hartsel] |= 1 << DEBUG_ROM_FLAG_GO;
- rti_remaining = abstract_rti;
+ rti_remaining = config.abstract_rti;
abstract_command_completed = false;
abstractcs.busy = true;
@@ -732,7 +725,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
}
return true;
- } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) {
+ } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + config.progbufsize) {
unsigned i = address - DMI_PROGBUF0;
if (!abstractcs.busy)
@@ -757,7 +750,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
dmcontrol.resumereq = get_field(value, DMI_DMCONTROL_RESUMEREQ);
dmcontrol.hartreset = get_field(value, DMI_DMCONTROL_HARTRESET);
dmcontrol.ndmreset = get_field(value, DMI_DMCONTROL_NDMRESET);
- if (support_hasel)
+ if (config.support_hasel)
dmcontrol.hasel = get_field(value, DMI_DMCONTROL_HASEL);
else
dmcontrol.hasel = 0;
@@ -871,7 +864,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
case DMI_AUTHDATA:
D(fprintf(stderr, "debug authentication: got 0x%x; 0x%x unlocks\n", value,
challenge + secret));
- if (require_authentication) {
+ if (config.require_authentication) {
if (value == challenge + secret) {
dmstatus.authenticated = true;
} else {
@@ -881,7 +874,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
}
return true;
case DMI_DMCS2:
- if (get_field(value, DMI_DMCS2_HGWRITE)) {
+ if (config.support_haltgroups && get_field(value, DMI_DMCS2_HGWRITE)) {
hart_state[dmcontrol.hartsel].haltgroup = get_field(value,
DMI_DMCS2_HALTGROUP);
}
diff --git a/riscv/debug_module.h b/riscv/debug_module.h
index f24a097..8fd6f67 100644
--- a/riscv/debug_module.h
+++ b/riscv/debug_module.h
@@ -9,6 +9,18 @@
class sim_t;
typedef struct {
+ // Size of program_buffer in 32-bit words, as exposed to the rest of the
+ // world.
+ unsigned progbufsize;
+ unsigned max_bus_master_bits;
+ bool require_authentication;
+ unsigned abstract_rti;
+ bool support_hasel;
+ bool support_abstract_csr_access;
+ bool support_haltgroups;
+} debug_module_config_t;
+
+typedef struct {
bool haltreq;
bool resumereq;
bool hasel;
@@ -93,10 +105,7 @@ class debug_module_t : public abstract_device_t
* abstract_rti is extra run-test/idle cycles that each abstract command
* takes to execute. Useful for testing OpenOCD.
*/
- debug_module_t(sim_t *sim, unsigned progbufsize,
- unsigned max_bus_master_bits, bool require_authentication,
- unsigned abstract_rti, bool support_hasel,
- bool support_abstract_csr_access);
+ debug_module_t(sim_t *sim, const debug_module_config_t &config);
~debug_module_t();
void add_device(bus_t *bus);
@@ -119,16 +128,10 @@ class debug_module_t : public abstract_device_t
private:
static const unsigned datasize = 2;
unsigned nprocs;
- // Size of program_buffer in 32-bit words, as exposed to the rest of the
- // world.
- unsigned progbufsize;
+ debug_module_config_t config;
// 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;
- bool require_authentication;
- unsigned abstract_rti;
- bool support_abstract_csr_access;
static const unsigned debug_data_start = 0x380;
unsigned debug_progbuf_start;
@@ -182,7 +185,6 @@ class debug_module_t : public abstract_device_t
bool abstract_command_completed;
unsigned rti_remaining;
- bool support_hasel;
};
#endif
diff --git a/riscv/sim.cc b/riscv/sim.cc
index 3cd29af..0bfdc8b 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -27,16 +27,12 @@ static void handle_signal(int sig)
sim_t::sim_t(const char* isa, size_t nprocs, bool halted, reg_t start_pc,
std::vector<std::pair<reg_t, mem_t*>> mems,
const std::vector<std::string>& args,
- std::vector<int> const hartids, unsigned progsize,
- unsigned max_bus_master_bits, bool require_authentication,
- suseconds_t abstract_delay_usec, bool support_hasel,
- bool support_abstract_csr_access)
+ std::vector<int> const hartids,
+ const debug_module_config_t &dm_config)
: htif_t(args), mems(mems), procs(std::max(nprocs, size_t(1))),
start_pc(start_pc), current_step(0), current_proc(0), debug(false),
histogram_enabled(false), dtb_enabled(true), remote_bitbang(NULL),
- debug_module(this, progsize, max_bus_master_bits, require_authentication,
- abstract_delay_usec, support_hasel,
- support_abstract_csr_access)
+ debug_module(this, dm_config)
{
signal(SIGINT, &handle_signal);
diff --git a/riscv/sim.h b/riscv/sim.h
index d1c7a37..6b9fad5 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -24,9 +24,7 @@ public:
sim_t(const char* isa, size_t _nprocs, bool halted, reg_t start_pc,
std::vector<std::pair<reg_t, mem_t*>> mems,
const std::vector<std::string>& args, const std::vector<int> hartids,
- unsigned progsize, unsigned max_bus_master_bits,
- bool require_authentication, suseconds_t abstract_delay_usec,
- bool support_hasel, bool support_abstract_csr_access);
+ const debug_module_config_t &dm_config);
~sim_t();
// run the simulation to completion