aboutsummaryrefslogtreecommitdiff
path: root/src/target/riscv/riscv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/target/riscv/riscv.c')
-rw-r--r--src/target/riscv/riscv.c58
1 files changed, 44 insertions, 14 deletions
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 97de017..bdbb8e4 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -534,6 +534,10 @@ static void riscv_deinit_target(struct target *target)
{
LOG_TARGET_DEBUG(target, "riscv_deinit_target()");
+ /* No need to deinit a target that has not been examined */
+ if (!target_was_examined(target))
+ return;
+
struct riscv_info *info = target->arch_info;
struct target_type *tt = get_target_type(target);
if (!tt)
@@ -1920,28 +1924,31 @@ int riscv_halt(struct target *target)
LOG_TARGET_DEBUG(target, "halting all harts");
+ /* Only halt a hart if it has been examined (was available) */
int result = ERROR_OK;
if (target->smp) {
struct target_list *tlist;
foreach_smp_target(tlist, target->smp_targets) {
struct target *t = tlist->target;
- if (halt_prep(t) != ERROR_OK)
- result = ERROR_FAIL;
+ if (target_was_examined(t))
+ if (halt_prep(t) != ERROR_OK)
+ result = ERROR_FAIL;
}
foreach_smp_target(tlist, target->smp_targets) {
struct target *t = tlist->target;
struct riscv_info *i = riscv_info(t);
- if (i->prepped) {
- if (halt_go(t) != ERROR_OK)
- result = ERROR_FAIL;
- }
+ if (target_was_examined(t))
+ if (i->prepped)
+ if (halt_go(t) != ERROR_OK)
+ result = ERROR_FAIL;
}
foreach_smp_target(tlist, target->smp_targets) {
struct target *t = tlist->target;
- if (halt_finish(t) != ERROR_OK)
- return ERROR_FAIL;
+ if (target_was_examined(t))
+ if (halt_finish(t) != ERROR_OK)
+ return ERROR_FAIL;
}
} else {
@@ -3039,11 +3046,21 @@ static int riscv_poll_hart(struct target *target, enum riscv_next_action *next_a
return ERROR_FAIL;
}
+ /* The hart apparently became unavailable while halted, so we want to resume it */
+ if (state == RISCV_STATE_HALTED && previous_riscv_state == RISCV_STATE_UNAVAILABLE) {
+ if (r->handle_became_available &&
+ r->handle_became_available(target, previous_riscv_state) != ERROR_OK)
+ return ERROR_FAIL;
+ if (riscv_get_hart_state(target, &state) != ERROR_OK)
+ return ERROR_FAIL;
+ }
+
if (target->state == TARGET_UNKNOWN || state != previous_riscv_state) {
switch (state) {
case RISCV_STATE_HALTED:
- if (previous_riscv_state == RISCV_STATE_UNAVAILABLE)
+ if (previous_riscv_state == RISCV_STATE_UNAVAILABLE) {
LOG_TARGET_INFO(target, "became available (halted)");
+ }
LOG_TARGET_DEBUG(target, " triggered a halt; previous_target_state=%d",
previous_target_state);
@@ -3090,8 +3107,9 @@ static int riscv_poll_hart(struct target *target, enum riscv_next_action *next_a
break;
case RISCV_STATE_RUNNING:
- if (previous_riscv_state == RISCV_STATE_UNAVAILABLE)
+ if (previous_riscv_state == RISCV_STATE_UNAVAILABLE) {
LOG_TARGET_INFO(target, "became available (running)");
+ }
LOG_TARGET_DEBUG(target, " triggered running");
target->state = TARGET_RUNNING;
@@ -3102,8 +3120,16 @@ static int riscv_poll_hart(struct target *target, enum riscv_next_action *next_a
break;
case RISCV_STATE_UNAVAILABLE:
- LOG_TARGET_DEBUG(target, " became unavailable");
- LOG_TARGET_INFO(target, "became unavailable.");
+ if (previous_riscv_state == RISCV_STATE_HALTED) {
+ LOG_TARGET_DEBUG(target, " became unavailable (halted)");
+ LOG_TARGET_INFO(target, "became unavailable (halted).");
+ } else if (previous_riscv_state == RISCV_STATE_RUNNING) {
+ LOG_TARGET_DEBUG(target, " became unavailable (running)");
+ LOG_TARGET_INFO(target, "became unavailable (running).");
+ } else {
+ LOG_TARGET_DEBUG(target, " became unavailable");
+ LOG_TARGET_INFO(target, "became unavailable.");
+ }
target->state = TARGET_UNAVAILABLE;
if (r->handle_became_unavailable &&
r->handle_became_unavailable(target, previous_riscv_state) != ERROR_OK)
@@ -3206,8 +3232,10 @@ int riscv_openocd_poll(struct target *target)
continue;
enum riscv_next_action next_action;
- if (riscv_poll_hart(t, &next_action) != ERROR_OK)
+ if (riscv_poll_hart(t, &next_action) != ERROR_OK) {
+ LOG_TARGET_INFO(target, "riscv_poll_hart failed - next_action: %d", next_action);
return ERROR_FAIL;
+ }
switch (next_action) {
case RPH_NONE:
@@ -3264,8 +3292,10 @@ int riscv_openocd_poll(struct target *target)
foreach_smp_target(entry, targets) {
struct target *t = entry->target;
struct riscv_info *info = riscv_info(t);
- if (info->tick && info->tick(t) != ERROR_OK)
+ if (info->tick && info->tick(t) != ERROR_OK) {
+ LOG_TARGET_INFO(target, "info_tick failed - t_coreid: %d", t->coreid);
return ERROR_FAIL;
+ }
}
/* Sample memory if any target is running. */