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
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to