From 87bfe9f50587933c0aa3fbf1fc6632f34d77cb54 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 5 Jun 2023 10:43:05 -0700 Subject: [PATCH] target/riscv: Add periodic tick() callback Intended as a place where we can interact with the target without too much concern about preserving state and doing exactly the right thing while poll() is going on. Change-Id: Ic9bd441caae85901a131fd45e742599803df89b5 Signed-off-by: Tim Newsome --- src/target/riscv/riscv.c | 11 +++++++++++ src/target/riscv/riscv.h | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index a5b7dcf75..1aaf50587 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2934,6 +2934,17 @@ int riscv_openocd_poll(struct target *target) } } + /* Call tick() for every hart. What happens in tick() is opaque to this + * layer. The reason it's outside the previous loop is that at this point + * the state of every hart has settled, so any side effects happening in + * tick() won't affect the delicate poll() code. */ + 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) + return ERROR_FAIL; + } + /* Sample memory if any target is running. */ foreach_smp_target(entry, targets) { struct target *t = entry->target; diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 03159cfa2..4cbe00612 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -204,6 +204,10 @@ struct riscv_info { int (*handle_became_unavailable)(struct target *target, enum riscv_hart_state previous_riscv_state); + /* Called periodically (no guarantees about frequency), while there's + * nothing else going on. */ + int (*tick)(struct target *target); + /* Get this target as ready as possible to resume, without actually * resuming. */ int (*resume_prep)(struct target *target);