From: David Brownell Date: Thu, 8 Oct 2009 18:14:00 +0000 (-0700) Subject: prevent abort via polling during jtag_reset X-Git-Tag: v0.3.0-rc0~120 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=a8234af06c16500426a421910886d26a46e6fa53;p=openocd prevent abort via polling during jtag_reset Observed: openocd: core.c:318: jtag_checks: Assertion `jtag_trst == 0' failed. The issue was that nothing disabled background polling during calls from the TCL shell to "jtag_reset 1 1". Fix by moving the existing poll-disable mechanism to the JTAG layer where it belongs, and then augmenting it to always pay attention to TRST and SRST. Signed-off-by: David Brownell --- diff --git a/src/jtag/core.c b/src/jtag/core.c index b8235eb1..bdfd6e5b 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -137,6 +137,32 @@ int jtag_error_clear(void) return temp; } +/************/ + +static bool jtag_poll = 1; + +bool is_jtag_poll_safe(void) +{ + /* Polling can be disabled explicitly with set_enabled(false). + * It is also implicitly disabled while TRST is active and + * while SRST is gating the JTAG clock. + */ + if (!jtag_poll || jtag_trst != 0) + return false; + return jtag_srst == 0 || (jtag_reset_config & RESET_SRST_NO_GATING); +} + +bool jtag_poll_get_enabled(void) +{ + return jtag_poll; +} + +void jtag_poll_set_enabled(bool value) +{ + jtag_poll = value; +} + +/************/ jtag_tap_t *jtag_all_taps(void) { diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 0126b331..5085445f 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -737,4 +737,21 @@ int jtag_get_error(void); */ int jtag_error_clear(void); +/** + * Return true if it's safe for a background polling task to access the + * JTAG scan chain. Polling may be explicitly disallowed, and is also + * unsafe while nTRST is active or the JTAG clock is gated off., + */ +bool is_jtag_poll_safe(void); + +/** + * Return flag reporting whether JTAG polling is disallowed. + */ +bool jtag_poll_get_enabled(void); + +/** + * Assign flag reporting whether JTAG polling is disallowed. + */ +void jtag_poll_set_enabled(bool value); + #endif /* JTAG_H */ diff --git a/src/target/target.c b/src/target/target.c index 253a7e46..ced09e90 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -269,8 +269,6 @@ static int new_target_number(void) return x + 1; } -static int target_continuous_poll = 1; - /* read a uint32_t from a buffer in target memory endianness */ uint32_t target_buffer_get_u32(target_t *target, const uint8_t *buffer) { @@ -436,13 +434,14 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo * more predictable, i.e. dr/irscan & pathmove in events will * not have JTAG operations injected into the middle of a sequence. */ - int save_poll = target_continuous_poll; - target_continuous_poll = 0; + bool save_poll = jtag_poll_get_enabled(); + + jtag_poll_set_enabled(false); sprintf(buf, "ocd_process_reset %s", n->name); retval = Jim_Eval(interp, buf); - target_continuous_poll = save_poll; + jtag_poll_set_enabled(save_poll); if (retval != JIM_OK) { Jim_PrintErrorMessage(interp); @@ -1726,7 +1725,7 @@ int handle_target(void *priv) * Skip targets that are currently disabled. */ for (target_t *target = all_targets; - target_continuous_poll && target; + is_jtag_poll_safe() && target; target = target->next) { if (!target->tap->enabled) @@ -1886,7 +1885,7 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha if (argc == 0) { command_print(cmd_ctx, "background polling: %s", - target_continuous_poll ? "on" : "off"); + jtag_poll_get_enabled() ? "on" : "off"); command_print(cmd_ctx, "TAP: %s (%s)", target->tap->dotted_name, target->tap->enabled ? "enabled" : "disabled"); @@ -1902,11 +1901,11 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha { if (strcmp(args[0], "on") == 0) { - target_continuous_poll = 1; + jtag_poll_set_enabled(true); } else if (strcmp(args[0], "off") == 0) { - target_continuous_poll = 0; + jtag_poll_set_enabled(false); } else {