Merge pull request #738 from riscv/current_hartid

Remove riscv_info_t.current_hartid
This commit is contained in:
Tim Newsome 2022-10-04 13:17:59 -07:00 committed by GitHub
commit 6d4ba7cca8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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. */