Merge pull request #738 from riscv/current_hartid
Remove riscv_info_t.current_hartid
This commit is contained in:
commit
6d4ba7cca8
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
Loading…
Reference in New Issue