diff options
author | David Brownell <dbrownell@users.sourceforge.net> | 2009-10-08 11:14:00 -0700 |
---|---|---|
committer | David Brownell <dbrownell@users.sourceforge.net> | 2009-10-08 11:14:00 -0700 |
commit | a8234af06c16500426a421910886d26a46e6fa53 (patch) | |
tree | 557a5d04fb74e34980be1ac433217812ae1ade93 | |
parent | 40c9668b703389890d30ab5a410e39f6f1e5251e (diff) | |
download | riscv-openocd-a8234af06c16500426a421910886d26a46e6fa53.zip riscv-openocd-a8234af06c16500426a421910886d26a46e6fa53.tar.gz riscv-openocd-a8234af06c16500426a421910886d26a46e6fa53.tar.bz2 |
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 <dbrownell@users.sourceforge.net>
-rw-r--r-- | src/jtag/core.c | 26 | ||||
-rw-r--r-- | src/jtag/jtag.h | 17 | ||||
-rw-r--r-- | src/target/target.c | 17 |
3 files changed, 51 insertions, 9 deletions
diff --git a/src/jtag/core.c b/src/jtag/core.c index b8235eb..bdfd6e5 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 0126b33..5085445 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 253a7e4..ced09e9 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 { |