Skip to content

Commit

Permalink
Merge pull request #1394 from riscv-software-src/unavailable
Browse files Browse the repository at this point in the history
Let debugger control hart availability
  • Loading branch information
aswaterman authored Jul 5, 2023
2 parents 09a3c64 + ea67403 commit e9848ed
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
45 changes: 37 additions & 8 deletions riscv/debug_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ debug_module_t::debug_module_t(simif_t *sim, const debug_module_config_t &config
jal(ZERO, debug_abstract_start - DEBUG_ROM_WHERETO));

memset(debug_abstract, 0, sizeof(debug_abstract));
for (unsigned i = 0; i < sizeof(hart_available_state) / sizeof(*hart_available_state); i++) {
hart_available_state[i] = true;
}

reset();
}
Expand Down Expand Up @@ -202,7 +205,8 @@ bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes)
if (hart_state[id].haltgroup) {
for (const auto& [hart_id, hart] : sim->get_harts()) {
if (!hart_state[hart_id].halted &&
hart_state[hart_id].haltgroup == hart_state[id].haltgroup) {
hart_state[hart_id].haltgroup == hart_state[id].haltgroup &&
hart_available(hart_id)) {
hart->halt_request = hart->HR_GROUP;
// TODO: What if the debugger comes and writes dmcontrol before the
// halt occurs?
Expand Down Expand Up @@ -337,6 +341,13 @@ void debug_module_t::sb_write()
}
}

bool debug_module_t::hart_available(unsigned hart_id) const
{
if (hart_id < sizeof(hart_available_state) / sizeof(*hart_available_state))
return hart_available_state[hart_id];
return true;
}

bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
{
uint32_t result = 0;
Expand Down Expand Up @@ -391,6 +402,8 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
dmstatus.allnonexistant = true;
dmstatus.allresumeack = true;
dmstatus.anyresumeack = false;
dmstatus.allunavail = true;
dmstatus.anyunavail = false;
for (const auto& [hart_id, hart] : sim->get_harts()) {
if (hart_selected(hart_id)) {
dmstatus.allnonexistant = false;
Expand All @@ -399,12 +412,19 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
} else {
dmstatus.allresumeack = false;
}
auto hart = sim->get_harts().at(hart_id);
if (hart_state[hart_id].halted) {
dmstatus.allrunning = false;
dmstatus.anyhalted = true;
dmstatus.allunavail = false;
} else if (!hart_available(hart_id)) {
dmstatus.allrunning = false;
dmstatus.allhalted = false;
dmstatus.anyunavail = true;
} else {
dmstatus.allhalted = false;
dmstatus.anyrunning = true;
dmstatus.allunavail = false;
}
}
}
Expand All @@ -414,9 +434,6 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
// non-existant hartsel.
dmstatus.anynonexistant = dmcontrol.hartsel >= sim->get_cfg().nprocs();

dmstatus.allunavail = false;
dmstatus.anyunavail = false;

result = set_field(result, DM_DMSTATUS_IMPEBREAK,
dmstatus.impebreak);
result = set_field(result, DM_DMSTATUS_ALLHAVERESET, selected_hart_state().havereset);
Expand Down Expand Up @@ -522,6 +539,11 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
case DM_DMCS2:
result = set_field(result, DM_DMCS2_GROUP, selected_hart_state().haltgroup);
break;
case DM_CUSTOM:
for (unsigned i = 0; i < sizeof(hart_available_state) / sizeof(*hart_available_state); i++) {
result |= hart_available_state[i] << i;
}
break;
default:
result = 0;
D(fprintf(stderr, "Unexpected. Returning Error."));
Expand Down Expand Up @@ -790,16 +812,18 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
if (get_field(value, DM_DMCONTROL_ACKHAVERESET)) {
hart_state[hart_id].havereset = false;
}
hart->halt_request = dmcontrol.haltreq ? hart->HR_REGULAR : hart->HR_NONE;
if (dmcontrol.haltreq) {
if (dmcontrol.haltreq && hart_available(hart_id)) {
hart->halt_request = hart->HR_REGULAR;
D(fprintf(stderr, "halt hart %d\n", hart_id));
} else {
hart->halt_request = hart->HR_NONE;
}
if (dmcontrol.resumereq) {
if (dmcontrol.resumereq && hart_available(hart_id)) {
D(fprintf(stderr, "resume hart %d\n", hart_id));
debug_rom_flags[hart_id] |= (1 << DEBUG_ROM_FLAG_RESUME);
hart_state[hart_id].resumeack = false;
}
if (dmcontrol.hartreset) {
if (dmcontrol.hartreset && hart_available(hart_id)) {
hart->reset();
}
}
Expand Down Expand Up @@ -903,6 +927,11 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
selected_hart_state().haltgroup = get_field(value, DM_DMCS2_GROUP);
}
return true;
case DM_CUSTOM:
for (unsigned i = 0; i < sizeof(hart_available_state) / sizeof(*hart_available_state); i++) {
hart_available_state[i] = get_field(value, 1<<i);
}
return true;
}
}
return false;
Expand Down
6 changes: 6 additions & 0 deletions riscv/debug_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ class debug_module_t : public abstract_device_t

size_t selected_hart_id() const;
hart_debug_state_t& selected_hart_state();

/* Whether the first 2 harts are available is controllable through DMCUSTOM,
* where bit 0 corresponds to hart 0, etc. When a bit is one the hart
* available. Otherwise it is unavailable. */
bool hart_available_state[2];
bool hart_available(unsigned hart_id) const;
};

#endif

0 comments on commit e9848ed

Please sign in to comment.