Fix most of the polling issues relating to disabled targets:
- Disable polling while running TAP event handlers ... the handlers
rely on state machine transitions which polling will break.
- Don't background-poll disabled TAPs ... this was just a bug waiting
to happen. (And then it happened!)
- Don't fail command line polls of disabled taps; that's not any
kind of error, it's just that you can't do much.
- Spell "continuous" correctly in the variable name. ;)
I say "most" issues since (a) there's no interlock between a polling
context and anything else, which may eventually trigger SMP issues;
and (b) this is one of several areas where the jtag and target layers
could stand to interact more cleanly.
---
src/jtag/tcl.c | 12 ++++++++++++
src/target/target.c | 34 +++++++++++++++++++++-------------
src/target/target.h | 2 ++
3 files changed, 35 insertions(+), 13 deletions(-)
Fix most of the polling issues relating to disabled targets:
- Disable polling while running TAP event handlers ... the handlers
rely on state machine transitions which polling will break.
- Don't background-poll disabled TAPs ... this was just a bug waiting
to happen. (And then it happened!)
- Don't fail command line polls of disabled taps; that's not any
kind of error, it's just that you can't do much.
- Spell "continuous" correctly in the variable name. ;)
I say "most" issues since (a) there's no interlock between a polling
context and anything else, which may eventually trigger SMP issues;
and (b) this is one of several areas where the jtag and target layers
could stand to interact more cleanly.
---
src/jtag/tcl.c | 12 ++++++++++++
src/target/target.c | 34 +++++++++++++++++++++-------------
src/target/target.h | 2 ++
3 files changed, 35 insertions(+), 13 deletions(-)
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -35,6 +35,8 @@
#include "minidriver.h"
#include "interface.h"
+#include "target.h"
+
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
@@ -465,9 +467,18 @@ static int jim_newtap_cmd( Jim_GetOptInf
static void jtag_tap_handle_event( jtag_tap_t * tap, enum jtag_tap_event e)
{
+ int saved_pollval = target_continuous_poll;
jtag_tap_event_action_t * jteap;
int done;
+ /* Don't let background polling interfere with TAP enable/disable
+ * logic, which depend on nuances of the JTAG state machine.
+ *
+ * NOTE: we not only want it not to start ... we want any poll
+ * that was currently active to have finished.
+ */
+ target_continuous_poll = 0;
+
jteap = tap->event_action;
done = 0;
@@ -492,6 +503,7 @@ static void jtag_tap_handle_event( jtag_
e,
Jim_Nvp_value2name_simple( nvp_jtag_tap_event, e)->name);
}
+ target_continuous_poll = saved_pollval;
}
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -269,7 +269,7 @@ static int new_target_number(void)
return x+1;
}
-static int target_continous_poll = 1;
+int target_continuous_poll = 1;
/* read a u32 from a buffer in target memory endianness */
u32 target_buffer_get_u32(target_t *target, const u8 *buffer)
@@ -436,13 +436,13 @@ int target_process_reset(struct command_
* 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_continous_poll;
- target_continous_poll = 0;
+ int save_poll = target_continuous_poll;
+ target_continuous_poll = 0;
sprintf( buf, "ocd_process_reset %s", n->name );
retval = Jim_Eval( interp, buf );
- target_continous_poll = save_poll;
+ target_continuous_poll = save_poll;
if(retval != JIM_OK) {
Jim_PrintErrorMessage(interp);
@@ -1650,20 +1650,23 @@ int handle_target(void *priv)
recursive = 0;
}
- target_t *target = all_targets;
-
- while (target)
+ /* Poll targets for state changes unless that's globally disabled.
+ * Skip targets that are currently disabled.
+ */
+ for (target_t *target = all_targets;
+ target_continuous_poll && target;
+ target = target->next)
{
+ if (!target->tap->enabled)
+ continue;
/* only poll target if we've got power and srst isn't asserted */
- if (target_continous_poll&&!powerDropout&&!srstAsserted)
+ if (!powerDropout && !srstAsserted)
{
/* polling may fail silently until the target has been examined */
if((retval = target_poll(target)) != ERROR_OK)
return retval;
}
-
- target = target->next;
}
return retval;
@@ -1791,7 +1794,12 @@ static int handle_poll_command(struct co
if (argc == 0)
{
command_print(cmd_ctx, "background polling: %s",
- target_continous_poll ? "on" : "off");
+ target_continuous_poll ? "on" : "off");
+ command_print(cmd_ctx, "TAP: %s (%s)",
+ target->tap->dotted_name,
+ target->tap->enabled ? "enabled" : "disabled");
+ if (!target->tap->enabled)
+ return ERROR_OK;
if ((retval = target_poll(target)) != ERROR_OK)
return retval;
if ((retval = target_arch_state(target)) != ERROR_OK)
@@ -1802,11 +1810,11 @@ static int handle_poll_command(struct co
{
if (strcmp(args[0], "on") == 0)
{
- target_continous_poll = 1;
+ target_continuous_poll = 1;
}
else if (strcmp(args[0], "off") == 0)
{
- target_continous_poll = 0;
+ target_continuous_poll = 0;
}
else
{
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -244,6 +244,8 @@ extern int target_call_timer_callbacks(v
*/
extern int target_call_timer_callbacks_now(void);
+extern int target_continuous_poll;
+
extern target_t* get_current_target(struct command_context_s *cmd_ctx);
extern int get_num_by_target(target_t *query_target);
extern target_t *get_target(const char *id);
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development