Remove riscv_info_t.current_hartid

This was used to track which hart a given operation must apply to. But
we already have a target associated with each operation, and from there
we can find the desired hart id. dm013_info_t already tracks
current_hartid (meaning which hart ID is currently selected by the DM).

This makes the code simpler to understand. Also it turns out we don't
need to make sure the correct hart ID is currently selected because
there are only a few real entry points.

Change-Id: Ibe8d5e156523397f245edd6ec0a5df3239b717bf
Signed-off-by: Tim Newsome <tim@sifive.com>
This commit is contained in:
Tim Newsome 2022-09-23 11:32:42 -07:00
parent 550a66e720
commit 84365e65e5
4 changed files with 79 additions and 121 deletions

View File

@ -1590,7 +1590,6 @@ static int examine(struct target *target)
return result; return result;
target_set_examined(target); target_set_examined(target);
riscv_set_current_hartid(target, 0);
for (size_t i = 0; i < 32; ++i) for (size_t i = 0; i < 32; ++i)
reg_cache_set(target, i, -1); reg_cache_set(target, i, -1);
LOG_INFO("Examined RISCV core; XLEN=%d, misa=0x%" PRIx64, LOG_INFO("Examined RISCV core; XLEN=%d, misa=0x%" PRIx64,

View File

@ -38,7 +38,7 @@ static void riscv013_clear_abstract_error(struct target *target);
static int riscv013_get_register(struct target *target, static int riscv013_get_register(struct target *target,
riscv_reg_t *value, int rid); riscv_reg_t *value, int rid);
static int riscv013_set_register(struct target *target, int regid, uint64_t value); static int riscv013_set_register(struct target *target, int regid, uint64_t value);
static int riscv013_select_current_hart(struct target *target); static int dm013_select_hart(struct target *target, int hart_index);
static int riscv013_halt_prep(struct target *target); static int riscv013_halt_prep(struct target *target);
static int riscv013_halt_go(struct target *target); static int riscv013_halt_go(struct target *target);
static int riscv013_resume_go(struct target *target); static int riscv013_resume_go(struct target *target);
@ -139,8 +139,12 @@ typedef struct {
bool was_reset; bool was_reset;
/* Targets that are connected to this DM. */ /* Targets that are connected to this DM. */
struct list_head target_list; struct list_head target_list;
/* The currently selected hartid on this DM. */ /* Contains the ID of the hart that is currently selected by this DM.
* (If multiple harts are selected this is meaningless, and that corner case
* is not currently handled well.)
*/
int current_hartid; int current_hartid;
bool hasel_supported; bool hasel_supported;
/* The program buffer stores executable code. 0 is an illegal instruction, /* The program buffer stores executable code. 0 is an illegal instruction,
@ -758,6 +762,12 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
} }
} }
static int dm013_select_target(struct target *target)
{
riscv013_info_t *info = get_info(target);
return dm013_select_hart(target, info->index);
}
static int execute_abstract_command(struct target *target, uint32_t command) static int execute_abstract_command(struct target *target, uint32_t command)
{ {
RISCV013_INFO(info); RISCV013_INFO(info);
@ -1384,6 +1394,9 @@ static int register_write_direct(struct target *target, unsigned number,
/** Actually read registers from the target right now. */ /** Actually read registers from the target right now. */
static int register_read_direct(struct target *target, uint64_t *value, uint32_t number) static int register_read_direct(struct target *target, uint64_t *value, uint32_t number)
{ {
if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL;
int result = register_read_abstract(target, value, number, int result = register_read_abstract(target, value, number,
register_size(target, number)); register_size(target, number));
@ -1659,8 +1672,7 @@ static int examine(struct target *target)
/* Before doing anything else we must first enumerate the harts. */ /* Before doing anything else we must first enumerate the harts. */
if (dm->hart_count < 0) { if (dm->hart_count < 0) {
for (int i = 0; i < MIN(RISCV_MAX_HARTS, 1 << info->hartsellen); ++i) { for (int i = 0; i < MIN(RISCV_MAX_HARTS, 1 << info->hartsellen); ++i) {
r->current_hartid = i; if (dm013_select_hart(target, i) != ERROR_OK)
if (riscv013_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
uint32_t s; uint32_t s;
@ -1678,8 +1690,6 @@ static int examine(struct target *target)
LOG_DEBUG("Detected %d harts.", dm->hart_count); LOG_DEBUG("Detected %d harts.", dm->hart_count);
} }
r->current_hartid = target->coreid;
if (dm->hart_count == 0) { if (dm->hart_count == 0) {
LOG_ERROR("No harts found!"); LOG_ERROR("No harts found!");
return ERROR_FAIL; return ERROR_FAIL;
@ -1688,7 +1698,7 @@ static int examine(struct target *target)
/* Don't call any riscv_* functions until after we've counted the number of /* Don't call any riscv_* functions until after we've counted the number of
* cores and initialized registers. */ * cores and initialized registers. */
if (riscv013_select_current_hart(target) != ERROR_OK) if (dm013_select_hart(target, info->index) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
bool halted = riscv_is_halted(target); bool halted = riscv_is_halted(target);
@ -1948,7 +1958,7 @@ static int riscv013_get_register_buf(struct target *target,
{ {
assert(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31); assert(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31);
if (riscv_select_current_hart(target) != ERROR_OK) if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
if (riscv_save_register(target, GDB_REGNO_S0) != ERROR_OK) if (riscv_save_register(target, GDB_REGNO_S0) != ERROR_OK)
@ -2004,7 +2014,7 @@ static int riscv013_set_register_buf(struct target *target,
{ {
assert(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31); assert(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31);
if (riscv_select_current_hart(target) != ERROR_OK) if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
if (riscv_save_register(target, GDB_REGNO_S0) != ERROR_OK) if (riscv_save_register(target, GDB_REGNO_S0) != ERROR_OK)
@ -2270,7 +2280,7 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->set_register = &riscv013_set_register; generic_info->set_register = &riscv013_set_register;
generic_info->get_register_buf = &riscv013_get_register_buf; generic_info->get_register_buf = &riscv013_get_register_buf;
generic_info->set_register_buf = &riscv013_set_register_buf; generic_info->set_register_buf = &riscv013_set_register_buf;
generic_info->select_current_hart = &riscv013_select_current_hart; generic_info->select_target = &dm013_select_target;
generic_info->is_halted = &riscv013_is_halted; generic_info->is_halted = &riscv013_is_halted;
generic_info->resume_go = &riscv013_resume_go; generic_info->resume_go = &riscv013_resume_go;
generic_info->step_current_hart = &riscv013_step_current_hart; generic_info->step_current_hart = &riscv013_step_current_hart;
@ -2329,7 +2339,7 @@ static int init_target(struct command_context *cmd_ctx,
static int assert_reset(struct target *target) static int assert_reset(struct target *target)
{ {
RISCV_INFO(r); RISCV013_INFO(info);
select_dmi(target); select_dmi(target);
@ -2347,7 +2357,7 @@ static int assert_reset(struct target *target)
/* Set haltreq for each hart. */ /* Set haltreq for each hart. */
uint32_t control = control_base; uint32_t control = control_base;
control = set_hartsel(control_base, target->coreid); control = set_hartsel(control_base, info->index);
control = set_field(control, DM_DMCONTROL_HALTREQ, control = set_field(control, DM_DMCONTROL_HALTREQ,
target->reset_halt ? 1 : 0); target->reset_halt ? 1 : 0);
dmi_write(target, DM_DMCONTROL, control); dmi_write(target, DM_DMCONTROL, control);
@ -2358,7 +2368,7 @@ static int assert_reset(struct target *target)
} else { } else {
/* Reset just this hart. */ /* Reset just this hart. */
uint32_t control = set_hartsel(control_base, r->current_hartid); uint32_t control = set_hartsel(control_base, info->index);
control = set_field(control, DM_DMCONTROL_HALTREQ, control = set_field(control, DM_DMCONTROL_HALTREQ,
target->reset_halt ? 1 : 0); target->reset_halt ? 1 : 0);
control = set_field(control, DM_DMCONTROL_NDMRESET, 1); control = set_field(control, DM_DMCONTROL_NDMRESET, 1);
@ -2381,7 +2391,6 @@ static int assert_reset(struct target *target)
static int deassert_reset(struct target *target) static int deassert_reset(struct target *target)
{ {
RISCV_INFO(r);
RISCV013_INFO(info); RISCV013_INFO(info);
select_dmi(target); select_dmi(target);
@ -2389,22 +2398,21 @@ static int deassert_reset(struct target *target)
uint32_t control = 0; uint32_t control = 0;
control = set_field(control, DM_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0); control = set_field(control, DM_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0);
control = set_field(control, DM_DMCONTROL_DMACTIVE, 1); control = set_field(control, DM_DMCONTROL_DMACTIVE, 1);
dmi_write(target, DM_DMCONTROL, dmi_write(target, DM_DMCONTROL, set_hartsel(control, info->index));
set_hartsel(control, r->current_hartid));
uint32_t dmstatus; uint32_t dmstatus;
int dmi_busy_delay = info->dmi_busy_delay; int dmi_busy_delay = info->dmi_busy_delay;
time_t start = time(NULL); time_t start = time(NULL);
for (int i = 0; i < riscv_count_harts(target); ++i) { for (unsigned int i = 0; i < riscv_count_harts(target); ++i) {
int index = i; unsigned int index = i;
if (target->rtos) { if (target->rtos) {
if (index != target->coreid) if (index != info->index)
continue; continue;
dmi_write(target, DM_DMCONTROL, dmi_write(target, DM_DMCONTROL,
set_hartsel(control, index)); set_hartsel(control, index));
} else { } else {
index = r->current_hartid; index = info->index;
} }
LOG_DEBUG("Waiting for hart %d to come out of reset.", index); LOG_DEBUG("Waiting for hart %d to come out of reset.", index);
@ -2454,6 +2462,9 @@ static int deassert_reset(struct target *target)
static int execute_fence(struct target *target) static int execute_fence(struct target *target)
{ {
if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL;
/* FIXME: For non-coherent systems we need to flush the caches right /* FIXME: For non-coherent systems we need to flush the caches right
* here, but there's no ISA-defined way of doing that. */ * here, but there's no ISA-defined way of doing that. */
{ {
@ -3416,6 +3427,9 @@ static int read_memory_progbuf(struct target *target, target_addr_t address,
LOG_DEBUG("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR, count, LOG_DEBUG("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR, count,
size, address); size, address);
if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL;
select_dmi(target); select_dmi(target);
memset(buffer, 0, count*size); memset(buffer, 0, count*size);
@ -4045,7 +4059,7 @@ static int riscv013_get_register(struct target *target,
LOG_DEBUG("[%s] reading register %s", target_name(target), LOG_DEBUG("[%s] reading register %s", target_name(target),
gdb_regno_name(rid)); gdb_regno_name(rid));
if (riscv_select_current_hart(target) != ERROR_OK) if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
int result = ERROR_OK; int result = ERROR_OK;
@ -4070,7 +4084,8 @@ static int riscv013_get_register(struct target *target,
static int riscv013_set_register(struct target *target, int rid, uint64_t value) static int riscv013_set_register(struct target *target, int rid, uint64_t value)
{ {
riscv013_select_current_hart(target); if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL;
LOG_TARGET_DEBUG(target, "writing 0x%" PRIx64 " to register %s", LOG_TARGET_DEBUG(target, "writing 0x%" PRIx64 " to register %s",
value, gdb_regno_name(rid)); value, gdb_regno_name(rid));
@ -4100,21 +4115,23 @@ static int riscv013_set_register(struct target *target, int rid, uint64_t value)
return ERROR_OK; return ERROR_OK;
} }
static int riscv013_select_current_hart(struct target *target) static int dm013_select_hart(struct target *target, int hart_index)
{ {
RISCV_INFO(r);
dm013_info_t *dm = get_dm(target); dm013_info_t *dm = get_dm(target);
if (!dm) if (!dm)
return ERROR_FAIL; return ERROR_FAIL;
if (r->current_hartid == dm->current_hartid) if (hart_index == dm->current_hartid)
return ERROR_OK; return ERROR_OK;
uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE; uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE;
dmcontrol = set_hartsel(dmcontrol, r->current_hartid); dmcontrol = set_hartsel(dmcontrol, hart_index);
int result = dmi_write(target, DM_DMCONTROL, dmcontrol); if (dmi_write(target, DM_DMCONTROL, dmcontrol) != ERROR_OK) {
dm->current_hartid = r->current_hartid; /* Who knows what the state is? */
return result; dm->current_hartid = -2;
return ERROR_FAIL;
}
dm->current_hartid = hart_index;
return ERROR_OK;
} }
/* Select all harts that were prepped and that are selectable, clearing the /* Select all harts that were prepped and that are selectable, clearing the
@ -4128,6 +4145,7 @@ static int select_prepped_harts(struct target *target, bool *use_hasel)
RISCV_INFO(r); RISCV_INFO(r);
r->prepped = false; r->prepped = false;
*use_hasel = false; *use_hasel = false;
dm013_select_target(target);
return ERROR_OK; return ERROR_OK;
} }
@ -4178,18 +4196,19 @@ static int riscv013_halt_prep(struct target *target)
static int riscv013_halt_go(struct target *target) static int riscv013_halt_go(struct target *target)
{ {
RISCV013_INFO(info);
bool use_hasel = false; bool use_hasel = false;
if (select_prepped_harts(target, &use_hasel) != ERROR_OK) if (select_prepped_harts(target, &use_hasel) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
RISCV_INFO(r); LOG_TARGET_DEBUG(target, "halting hart");
LOG_DEBUG("halting hart %d", r->current_hartid);
/* Issue the halt command, and then wait for the current hart to halt. */ /* Issue the halt command, and then wait for the current hart to halt. */
uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE | DM_DMCONTROL_HALTREQ; uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE | DM_DMCONTROL_HALTREQ;
if (use_hasel) if (use_hasel)
dmcontrol |= DM_DMCONTROL_HASEL; dmcontrol |= DM_DMCONTROL_HASEL;
dmcontrol = set_hartsel(dmcontrol, r->current_hartid); dmcontrol = set_hartsel(dmcontrol, info->index);
dmi_write(target, DM_DMCONTROL, dmcontrol); dmi_write(target, DM_DMCONTROL, dmcontrol);
for (size_t i = 0; i < 256; ++i) for (size_t i = 0; i < 256; ++i)
if (riscv_is_halted(target)) if (riscv_is_halted(target))
@ -4258,20 +4277,23 @@ static int riscv013_on_halt(struct target *target)
static bool riscv013_is_halted(struct target *target) static bool riscv013_is_halted(struct target *target)
{ {
RISCV013_INFO(info);
uint32_t dmstatus; uint32_t dmstatus;
if (dm013_select_target(target) != ERROR_OK)
return false;
if (dmstatus_read(target, &dmstatus, true) != ERROR_OK) if (dmstatus_read(target, &dmstatus, true) != ERROR_OK)
return false; return false;
if (get_field(dmstatus, DM_DMSTATUS_ANYUNAVAIL)) if (get_field(dmstatus, DM_DMSTATUS_ANYUNAVAIL))
LOG_ERROR("Hart %d is unavailable.", riscv_current_hartid(target)); LOG_TARGET_ERROR(target, "Hart is unavailable.");
if (get_field(dmstatus, DM_DMSTATUS_ANYNONEXISTENT)) if (get_field(dmstatus, DM_DMSTATUS_ANYNONEXISTENT))
LOG_ERROR("Hart %d doesn't exist.", riscv_current_hartid(target)); LOG_TARGET_ERROR(target, "Hart doesn't exist.");
if (get_field(dmstatus, DM_DMSTATUS_ANYHAVERESET)) { if (get_field(dmstatus, DM_DMSTATUS_ANYHAVERESET)) {
int hartid = riscv_current_hartid(target); LOG_TARGET_INFO(target, "Hart unexpectedly reset!");
LOG_INFO("Hart %d unexpectedly reset!", hartid);
/* TODO: Can we make this more obvious to eg. a gdb user? */ /* TODO: Can we make this more obvious to eg. a gdb user? */
uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE | uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE |
DM_DMCONTROL_ACKHAVERESET; DM_DMCONTROL_ACKHAVERESET;
dmcontrol = set_hartsel(dmcontrol, hartid); dmcontrol = set_hartsel(dmcontrol, info->index);
/* If we had been halted when we reset, request another halt. If we /* If we had been halted when we reset, request another halt. If we
* ended up running out of reset, then the user will (hopefully) get a * ended up running out of reset, then the user will (hopefully) get a
* message that a reset happened, that the target is running, and then * message that a reset happened, that the target is running, and then
@ -4776,9 +4798,8 @@ static int riscv013_on_step_or_resume(struct target *target, bool step)
static int riscv013_step_or_resume_current_hart(struct target *target, static int riscv013_step_or_resume_current_hart(struct target *target,
bool step, bool use_hasel) bool step, bool use_hasel)
{ {
RISCV_INFO(r);
if (!riscv_is_halted(target)) { if (!riscv_is_halted(target)) {
LOG_ERROR("Hart %d is not halted!", r->current_hartid); LOG_TARGET_ERROR(target, "Hart is not halted!");
return ERROR_FAIL; return ERROR_FAIL;
} }
LOG_TARGET_DEBUG(target, "resuming (for step?=%d)", step); LOG_TARGET_DEBUG(target, "resuming (for step?=%d)", step);
@ -4786,11 +4807,12 @@ static int riscv013_step_or_resume_current_hart(struct target *target,
if (riscv_flush_registers(target) != ERROR_OK) if (riscv_flush_registers(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
dm013_info_t *dm = get_dm(target);
/* Issue the resume command, and then wait for the current hart to resume. */ /* Issue the resume command, and then wait for the current hart to resume. */
uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE | DM_DMCONTROL_RESUMEREQ; uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE | DM_DMCONTROL_RESUMEREQ;
if (use_hasel) if (use_hasel)
dmcontrol |= DM_DMCONTROL_HASEL; dmcontrol |= DM_DMCONTROL_HASEL;
dmcontrol = set_hartsel(dmcontrol, r->current_hartid); dmcontrol = set_hartsel(dmcontrol, dm->current_hartid);
dmi_write(target, DM_DMCONTROL, dmcontrol); dmi_write(target, DM_DMCONTROL, dmcontrol);
dmcontrol = set_field(dmcontrol, DM_DMCONTROL_HASEL, 0); dmcontrol = set_field(dmcontrol, DM_DMCONTROL_HASEL, 0);

View File

@ -1155,11 +1155,6 @@ static int old_or_new_riscv_poll(struct target *target)
return riscv_openocd_poll(target); return riscv_openocd_poll(target);
} }
int riscv_select_current_hart(struct target *target)
{
return riscv_set_current_hartid(target, target->coreid);
}
int riscv_flush_registers(struct target *target) int riscv_flush_registers(struct target *target)
{ {
RISCV_INFO(r); RISCV_INFO(r);
@ -1228,14 +1223,11 @@ int halt_prep(struct target *target)
LOG_DEBUG("[%s] prep hart, debug_reason=%d", target_name(target), LOG_DEBUG("[%s] prep hart, debug_reason=%d", target_name(target),
target->debug_reason); target->debug_reason);
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
if (riscv_is_halted(target)) { if (riscv_is_halted(target)) {
LOG_DEBUG("[%s] Hart is already halted (debug_reason=%d).", LOG_DEBUG("[%s] Hart is already halted (debug_reason=%d).",
target_name(target), target->debug_reason); target_name(target), target->debug_reason);
if (target->debug_reason == DBG_REASON_NOTHALTED) { if (target->debug_reason == DBG_REASON_NOTHALTED) {
enum riscv_halt_reason halt_reason = enum riscv_halt_reason halt_reason = riscv_halt_reason(target);
riscv_halt_reason(target, r->current_hartid);
if (set_debug_reason(target, halt_reason) != ERROR_OK) if (set_debug_reason(target, halt_reason) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -1252,8 +1244,6 @@ int riscv_halt_go_all_harts(struct target *target)
{ {
RISCV_INFO(r); RISCV_INFO(r);
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
if (riscv_is_halted(target)) { if (riscv_is_halted(target)) {
LOG_DEBUG("[%s] Hart is already halted.", target_name(target)); LOG_DEBUG("[%s] Hart is already halted.", target_name(target));
} else { } else {
@ -1464,8 +1454,6 @@ static int resume_prep(struct target *target, int current,
} }
if (r->is_halted) { if (r->is_halted) {
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
if (r->resume_prep(target) != ERROR_OK) if (r->resume_prep(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -1738,8 +1726,6 @@ static int riscv_read_phys_memory(struct target *target, target_addr_t phys_addr
uint32_t size, uint32_t count, uint8_t *buffer) uint32_t size, uint32_t count, uint8_t *buffer)
{ {
RISCV_INFO(r); RISCV_INFO(r);
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
return r->read_memory(target, phys_address, size, count, buffer, size); return r->read_memory(target, phys_address, size, count, buffer, size);
} }
@ -1751,9 +1737,6 @@ static int riscv_read_memory(struct target *target, target_addr_t address,
return ERROR_OK; return ERROR_OK;
} }
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
target_addr_t physical_addr; target_addr_t physical_addr;
if (target->type->virt2phys(target, address, &physical_addr) == ERROR_OK) if (target->type->virt2phys(target, address, &physical_addr) == ERROR_OK)
address = physical_addr; address = physical_addr;
@ -1765,8 +1748,6 @@ static int riscv_read_memory(struct target *target, target_addr_t address,
static int riscv_write_phys_memory(struct target *target, target_addr_t phys_address, static int riscv_write_phys_memory(struct target *target, target_addr_t phys_address,
uint32_t size, uint32_t count, const uint8_t *buffer) uint32_t size, uint32_t count, const uint8_t *buffer)
{ {
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
struct target_type *tt = get_target_type(target); struct target_type *tt = get_target_type(target);
return tt->write_memory(target, phys_address, size, count, buffer); return tt->write_memory(target, phys_address, size, count, buffer);
} }
@ -1779,9 +1760,6 @@ static int riscv_write_memory(struct target *target, target_addr_t address,
return ERROR_OK; return ERROR_OK;
} }
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
target_addr_t physical_addr; target_addr_t physical_addr;
if (target->type->virt2phys(target, address, &physical_addr) == ERROR_OK) if (target->type->virt2phys(target, address, &physical_addr) == ERROR_OK)
address = physical_addr; address = physical_addr;
@ -1813,9 +1791,6 @@ static int riscv_get_gdb_reg_list_internal(struct target *target,
return ERROR_FAIL; return ERROR_FAIL;
} }
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
switch (reg_class) { switch (reg_class) {
case REG_CLASS_GENERAL: case REG_CLASS_GENERAL:
*reg_list_size = 33; *reg_list_size = 33;
@ -1971,9 +1946,9 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
return result; return result;
} }
/* The current hart id might have been changed in poll(). */ /* TODO: The current hart id might have been changed in poll(). */
if (riscv_select_current_hart(target) != ERROR_OK) /* if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL; */
if (reg_pc->type->get(reg_pc) != ERROR_OK) if (reg_pc->type->get(reg_pc) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
@ -2113,8 +2088,6 @@ enum riscv_poll_hart {
static enum riscv_poll_hart riscv_poll_hart(struct target *target, int hartid) static enum riscv_poll_hart riscv_poll_hart(struct target *target, int hartid)
{ {
RISCV_INFO(r); RISCV_INFO(r);
if (riscv_set_current_hartid(target, hartid) != ERROR_OK)
return RPH_ERROR;
LOG_TARGET_DEBUG(target, "polling, target->state=%d", target->state); LOG_TARGET_DEBUG(target, "polling, target->state=%d", target->state);
@ -2194,7 +2167,6 @@ exit:
int riscv_openocd_poll(struct target *target) int riscv_openocd_poll(struct target *target)
{ {
LOG_DEBUG("polling all harts"); LOG_DEBUG("polling all harts");
int halted_hart = -1;
enum target_state old_state = target->state; enum target_state old_state = target->state;
if (target->smp) { if (target->smp) {
@ -2205,8 +2177,7 @@ int riscv_openocd_poll(struct target *target)
struct target *t = list->target; struct target *t = list->target;
if (!target_was_examined(t)) if (!target_was_examined(t))
continue; continue;
riscv_info_t *r = riscv_info(t); enum riscv_poll_hart out = riscv_poll_hart(t, t->coreid);
enum riscv_poll_hart out = riscv_poll_hart(t, r->current_hartid);
switch (out) { switch (out) {
case RPH_NO_CHANGE: case RPH_NO_CHANGE:
break; break;
@ -2217,7 +2188,7 @@ int riscv_openocd_poll(struct target *target)
case RPH_DISCOVERED_HALTED: case RPH_DISCOVERED_HALTED:
t->state = TARGET_HALTED; t->state = TARGET_HALTED;
enum riscv_halt_reason halt_reason = enum riscv_halt_reason halt_reason =
riscv_halt_reason(t, r->current_hartid); riscv_halt_reason(t);
if (set_debug_reason(t, halt_reason) != ERROR_OK) if (set_debug_reason(t, halt_reason) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
@ -2273,8 +2244,7 @@ int riscv_openocd_poll(struct target *target)
return ERROR_OK; return ERROR_OK;
} else { } else {
enum riscv_poll_hart out = riscv_poll_hart(target, enum riscv_poll_hart out = riscv_poll_hart(target, target->coreid);
riscv_current_hartid(target));
if (out == RPH_NO_CHANGE || out == RPH_DISCOVERED_RUNNING) { if (out == RPH_NO_CHANGE || out == RPH_DISCOVERED_RUNNING) {
if (target->state == TARGET_RUNNING) if (target->state == TARGET_RUNNING)
sample_memory(target); sample_memory(target);
@ -2283,10 +2253,10 @@ int riscv_openocd_poll(struct target *target)
return ERROR_FAIL; return ERROR_FAIL;
} }
halted_hart = riscv_current_hartid(target); LOG_TARGET_DEBUG(target, "hart halted");
LOG_DEBUG(" hart %d halted", halted_hart);
enum riscv_halt_reason halt_reason = riscv_halt_reason(target, halted_hart); target->state = TARGET_HALTED;
enum riscv_halt_reason halt_reason = riscv_halt_reason(target);
if (set_debug_reason(target, halt_reason) != ERROR_OK) if (set_debug_reason(target, halt_reason) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
target->state = TARGET_HALTED; target->state = TARGET_HALTED;
@ -3516,7 +3486,6 @@ void riscv_info_init(struct target *target, riscv_info_t *r)
{ {
memset(r, 0, sizeof(*r)); memset(r, 0, sizeof(*r));
r->dtm_version = 1; r->dtm_version = 1;
r->current_hartid = target->coreid;
r->version_specific = NULL; r->version_specific = NULL;
memset(r->trigger_unique_id, 0xff, sizeof(r->trigger_unique_id)); memset(r->trigger_unique_id, 0xff, sizeof(r->trigger_unique_id));
@ -3542,8 +3511,6 @@ static int riscv_resume_go_all_harts(struct target *target)
RISCV_INFO(r); RISCV_INFO(r);
LOG_TARGET_DEBUG(target, "resuming hart, state=%d", target->state); LOG_TARGET_DEBUG(target, "resuming hart, state=%d", target->state);
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
if (riscv_is_halted(target)) { if (riscv_is_halted(target)) {
if (r->resume_go(target) != ERROR_OK) if (r->resume_go(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
@ -3605,8 +3572,6 @@ int riscv_interrupts_restore(struct target *target, uint64_t old_mstatus)
int riscv_step_rtos_hart(struct target *target) int riscv_step_rtos_hart(struct target *target)
{ {
RISCV_INFO(r); RISCV_INFO(r);
if (riscv_select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
LOG_DEBUG("[%s] stepping", target_name(target)); LOG_DEBUG("[%s] stepping", target_name(target));
if (!riscv_is_halted(target)) { if (!riscv_is_halted(target)) {
@ -3643,21 +3608,6 @@ unsigned riscv_xlen(const struct target *target)
return r->xlen; return r->xlen;
} }
int riscv_set_current_hartid(struct target *target, int hartid)
{
RISCV_INFO(r);
if (!r->select_current_hart)
return ERROR_OK;
int previous_hartid = riscv_current_hartid(target);
r->current_hartid = hartid;
LOG_DEBUG("setting hartid to %d, was %d", hartid, previous_hartid);
if (r->select_current_hart(target) != ERROR_OK)
return ERROR_FAIL;
return ERROR_OK;
}
void riscv_invalidate_register_cache(struct target *target) void riscv_invalidate_register_cache(struct target *target)
{ {
/* Do not invalidate the register cache if it is not yet set up /* Do not invalidate the register cache if it is not yet set up
@ -3673,13 +3623,8 @@ void riscv_invalidate_register_cache(struct target *target)
} }
} }
int riscv_current_hartid(const struct target *target)
{
RISCV_INFO(r);
return r->current_hartid;
}
int riscv_count_harts(struct target *target) unsigned int riscv_count_harts(struct target *target)
{ {
if (!target) if (!target)
return 1; return 1;
@ -3846,12 +3791,10 @@ bool riscv_is_halted(struct target *target)
return r->is_halted(target); return r->is_halted(target);
} }
enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid) enum riscv_halt_reason riscv_halt_reason(struct target *target)
{ {
RISCV_INFO(r); RISCV_INFO(r);
if (riscv_set_current_hartid(target, hartid) != ERROR_OK) if (target->state != TARGET_HALTED) {
return RISCV_HALT_ERROR;
if (!riscv_is_halted(target)) {
LOG_ERROR("Hart is not halted!"); LOG_ERROR("Hart is not halted!");
return RISCV_HALT_UNKNOWN; return RISCV_HALT_UNKNOWN;
} }

View File

@ -99,12 +99,6 @@ typedef struct {
struct command_context *cmd_ctx; struct command_context *cmd_ctx;
void *version_specific; void *version_specific;
/* The hart that is currently being debugged. Note that this is
* different than the hartid that the RTOS is expected to use. This
* one will change all the time, it's more of a global argument to
* every function than an actual */
int current_hartid;
/* Single buffer that contains all register names, instead of calling /* Single buffer that contains all register names, instead of calling
* malloc for each register. Needs to be freed when reg_list is freed. */ * malloc for each register. Needs to be freed when reg_list is freed. */
char *reg_names; char *reg_names;
@ -154,7 +148,7 @@ typedef struct {
int (*get_register_buf)(struct target *target, uint8_t *buf, int regno); int (*get_register_buf)(struct target *target, uint8_t *buf, int regno);
int (*set_register_buf)(struct target *target, int regno, int (*set_register_buf)(struct target *target, int regno,
const uint8_t *buf); const uint8_t *buf);
int (*select_current_hart)(struct target *target); int (*select_target)(struct target *target);
bool (*is_halted)(struct target *target); bool (*is_halted)(struct target *target);
/* Resume this target, as well as every other prepped target that can be /* Resume this target, as well as every other prepped target that can be
* resumed near-simultaneously. Clear the prepped flag on any target that * resumed near-simultaneously. Clear the prepped flag on any target that
@ -354,7 +348,7 @@ int riscv_current_hartid(const struct target *target);
/* Lists the number of harts in the system, which are assumed to be /* Lists the number of harts in the system, which are assumed to be
* consecutive and start with mhartid=0. */ * consecutive and start with mhartid=0. */
int riscv_count_harts(struct target *target); unsigned int riscv_count_harts(struct target *target);
/** Set register, updating the cache. */ /** Set register, updating the cache. */
int riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v); int riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);
@ -370,7 +364,7 @@ int riscv_flush_registers(struct target *target);
/* Checks the state of the current hart -- "is_halted" checks the actual /* Checks the state of the current hart -- "is_halted" checks the actual
* on-device register. */ * on-device register. */
bool riscv_is_halted(struct target *target); bool riscv_is_halted(struct target *target);
enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid); enum riscv_halt_reason riscv_halt_reason(struct target *target);
/* These helper functions let the generic program interface get target-specific /* These helper functions let the generic program interface get target-specific
* information. */ * information. */