summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-10-08 11:14:00 -0700
committerDavid Brownell <dbrownell@users.sourceforge.net>2009-10-08 11:14:00 -0700
commita8234af06c16500426a421910886d26a46e6fa53 (patch)
tree557a5d04fb74e34980be1ac433217812ae1ade93 /src
parent40c9668b703389890d30ab5a410e39f6f1e5251e (diff)
downloadopenocd+libswd-a8234af06c16500426a421910886d26a46e6fa53.tar.gz
openocd+libswd-a8234af06c16500426a421910886d26a46e6fa53.tar.bz2
openocd+libswd-a8234af06c16500426a421910886d26a46e6fa53.tar.xz
openocd+libswd-a8234af06c16500426a421910886d26a46e6fa53.zip
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>
Diffstat (limited to 'src')
-rw-r--r--src/jtag/core.c26
-rw-r--r--src/jtag/jtag.h17
-rw-r--r--src/target/target.c17
3 files changed, 51 insertions, 9 deletions
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
{