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>
This commit is contained in:
parent
40c9668b70
commit
a8234af06c
|
@ -137,6 +137,32 @@ int jtag_error_clear(void)
|
||||||
return temp;
|
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)
|
jtag_tap_t *jtag_all_taps(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -737,4 +737,21 @@ int jtag_get_error(void);
|
||||||
*/
|
*/
|
||||||
int jtag_error_clear(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 */
|
#endif /* JTAG_H */
|
||||||
|
|
|
@ -269,8 +269,6 @@ static int new_target_number(void)
|
||||||
return x + 1;
|
return x + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int target_continuous_poll = 1;
|
|
||||||
|
|
||||||
/* read a uint32_t from a buffer in target memory endianness */
|
/* read a uint32_t from a buffer in target memory endianness */
|
||||||
uint32_t target_buffer_get_u32(target_t *target, const uint8_t *buffer)
|
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
|
* more predictable, i.e. dr/irscan & pathmove in events will
|
||||||
* not have JTAG operations injected into the middle of a sequence.
|
* not have JTAG operations injected into the middle of a sequence.
|
||||||
*/
|
*/
|
||||||
int save_poll = target_continuous_poll;
|
bool save_poll = jtag_poll_get_enabled();
|
||||||
target_continuous_poll = 0;
|
|
||||||
|
jtag_poll_set_enabled(false);
|
||||||
|
|
||||||
sprintf(buf, "ocd_process_reset %s", n->name);
|
sprintf(buf, "ocd_process_reset %s", n->name);
|
||||||
retval = Jim_Eval(interp, buf);
|
retval = Jim_Eval(interp, buf);
|
||||||
|
|
||||||
target_continuous_poll = save_poll;
|
jtag_poll_set_enabled(save_poll);
|
||||||
|
|
||||||
if (retval != JIM_OK) {
|
if (retval != JIM_OK) {
|
||||||
Jim_PrintErrorMessage(interp);
|
Jim_PrintErrorMessage(interp);
|
||||||
|
@ -1726,7 +1725,7 @@ int handle_target(void *priv)
|
||||||
* Skip targets that are currently disabled.
|
* Skip targets that are currently disabled.
|
||||||
*/
|
*/
|
||||||
for (target_t *target = all_targets;
|
for (target_t *target = all_targets;
|
||||||
target_continuous_poll && target;
|
is_jtag_poll_safe() && target;
|
||||||
target = target->next)
|
target = target->next)
|
||||||
{
|
{
|
||||||
if (!target->tap->enabled)
|
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)
|
if (argc == 0)
|
||||||
{
|
{
|
||||||
command_print(cmd_ctx, "background polling: %s",
|
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)",
|
command_print(cmd_ctx, "TAP: %s (%s)",
|
||||||
target->tap->dotted_name,
|
target->tap->dotted_name,
|
||||||
target->tap->enabled ? "enabled" : "disabled");
|
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)
|
if (strcmp(args[0], "on") == 0)
|
||||||
{
|
{
|
||||||
target_continuous_poll = 1;
|
jtag_poll_set_enabled(true);
|
||||||
}
|
}
|
||||||
else if (strcmp(args[0], "off") == 0)
|
else if (strcmp(args[0], "off") == 0)
|
||||||
{
|
{
|
||||||
target_continuous_poll = 0;
|
jtag_poll_set_enabled(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue