From 34f9ff0d0d86b9616fb620a07f3d5bafeaf75338 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 5 Jun 2023 10:39:12 -0700 Subject: [PATCH] target/riscv: Add some event callbacks. Specifically, call into the RISC-V version when target becomes halted, running, or unavailable. I'll be using unavailable shortly. Change-Id: I9ffffdccbf22e053fe6390d656b362bf9ab9559a Signed-off-by: Tim Newsome --- src/target/riscv/riscv.c | 10 ++++++++++ src/target/riscv/riscv.h | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 8927ac136..a5b7dcf75 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2752,6 +2752,10 @@ static int riscv_poll_hart(struct target *target, enum riscv_next_action *next_a } } + if (r->handle_became_halted && + r->handle_became_halted(target, previous_riscv_state) != ERROR_OK) + return ERROR_FAIL; + /* We shouldn't do the callbacks yet. What if * there are multiple harts that halted at the * same time? We need to set debug reason on each @@ -2769,12 +2773,18 @@ static int riscv_poll_hart(struct target *target, enum riscv_next_action *next_a LOG_TARGET_DEBUG(target, " triggered running"); target->state = TARGET_RUNNING; target->debug_reason = DBG_REASON_NOTHALTED; + if (r->handle_became_running && + r->handle_became_running(target, previous_riscv_state) != ERROR_OK) + return ERROR_FAIL; break; case RISCV_STATE_UNAVAILABLE: 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) + return ERROR_FAIL; break; case RISCV_STATE_NON_EXISTENT: diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index a695cc349..03159cfa2 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -193,6 +193,17 @@ struct riscv_info { * was resumed. */ int (*resume_go)(struct target *target); int (*step_current_hart)(struct target *target); + + /* These get called from riscv_poll_hart(), which is a house of cards + * together with openocd_poll(), so be careful not to upset things too + * much. */ + int (*handle_became_halted)(struct target *target, + enum riscv_hart_state previous_riscv_state); + int (*handle_became_running)(struct target *target, + enum riscv_hart_state previous_riscv_state); + int (*handle_became_unavailable)(struct target *target, + enum riscv_hart_state previous_riscv_state); + /* Get this target as ready as possible to resume, without actually * resuming. */ int (*resume_prep)(struct target *target);