From f3ed0ab608639dd50c48124fc22e3dc7f6d8f0ec Mon Sep 17 00:00:00 2001 From: Evgeniy Naydanov Date: Thu, 10 Oct 2024 14:18:59 +0300 Subject: [PATCH] target/riscv: check other TAPs in `select_dmi()` If some other TAP is not in BYPASS, an IR scan is needed to select BYPASS on that TAP. Change-Id: Iae425a415109b1a853db3718762661877eea56e8 Signed-off-by: Evgeniy Naydanov --- src/jtag/jtag.h | 1 + src/target/riscv/riscv-013.c | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index b9d37b32a..6ba118f7a 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -151,6 +151,7 @@ const char *jtag_tap_name(const struct jtag_tap *tap); struct jtag_tap *jtag_tap_by_string(const char *dotted_name); struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *obj); struct jtag_tap *jtag_tap_by_position(unsigned int abs_position); +/* FIXME: "jtag_tap_next_enabled()" should accept a const pointer. */ struct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p); unsigned int jtag_tap_count_enabled(void); unsigned int jtag_tap_count(void); diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index f3dda0287..a8a823860 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -357,10 +357,31 @@ static void select_dmi(struct target *target) select_dmi_via_bscan(target); return; } - if (buf_eq(target->tap->cur_instr, select_dbus.out_value, - target->tap->ir_length)) - return; - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); + if (!target->tap->enabled) + LOG_TARGET_ERROR(target, "BUG: Target's TAP '%s' is disabled!", + jtag_tap_name(target->tap)); + + bool need_ir_scan = false; + /* FIXME: make "tap" a const pointer. */ + for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); + tap; tap = jtag_tap_next_enabled(tap)) { + if (tap != target->tap) { + /* Different TAP than ours - check if it is in bypass */ + if (!tap->bypass) { + need_ir_scan = true; + break; + } + } else { + /* Our TAP - check if the correct instruction is already loaded */ + if (!buf_eq(target->tap->cur_instr, select_dbus.out_value, target->tap->ir_length)) { + need_ir_scan = true; + break; + } + } + } + + if (need_ir_scan) + jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); } static int increase_dmi_busy_delay(struct target *target)