Doc update:  say "jtag newtap ... -disable" records the
state after exiting the RESET state, matching the only
implementation we're working with so far (TI ICEpick-C).

Matching code updates, including a few minor cleanups
mostly related to the JTAG event callback mechanism:

 - a memory leak in jtag_tap_free()
 - fix conceptual bug in unregistering JTAG event callbacks
 - remove hidden assumption about JTAG event numbering
 - move function declarations to the header where they belong
 - some end'o'line whitespace

Now we're sure the "enable" flag value is correct after resets.
---
 doc/openocd.texi |    7 ++++---
 src/jtag/core.c  |   24 +++++++++++++++++-------
 src/jtag/jtag.h  |   25 +++++++++++++++----------
 src/jtag/tcl.c   |   21 +++++++++------------
 4 files changed, 45 insertions(+), 32 deletions(-)

Doc update:  say "jtag newtap ... -disable" records the
state after exiting the RESET state, matching the only
implementation we're working with so far (TI ICEpick-C).

Matching code updates, including a few minor cleanups
mostly related to the JTAG event callback mechanism:

 - a memory leak in jtag_tap_free()
 - fix conceptual bug in unregistering JTAG event callbacks
 - remove hidden assumption about JTAG event numbering
 - move function declarations to the header where they belong
 - some end'o'line whitespace

Now, we're sure that flag's value is correct after resets.
---
 doc/openocd.texi |    7 ++++---
 src/jtag/core.c  |   24 +++++++++++++++++-------
 src/jtag/jtag.h  |   25 +++++++++++++++----------
 src/jtag/tcl.c   |   21 +++++++++------------
 4 files changed, 45 insertions(+), 32 deletions(-)

--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -2302,8 +2302,9 @@ A TAP may also provide optional @var{con
 
 @itemize @bullet
 @item @code{-disable} (or @code{-enable})
-...@*use the @code{-disable} paramater to flag a TAP which is not
-linked in to the scan chain when it is declared.
+...@*use the @code{-disable} parameter to flag a TAP which is not
+linked in to the scan chain after a reset using either TRST
+or the JTAG state machine's @sc{reset} state.
 You may use @code{-enable} to highlight the default state
 (the TAP is linked in).
 @xref{Enabling and Disabling TAPs}.
@@ -5067,7 +5068,7 @@ and @command{irscan} commands are:
 @end itemize
 
 Note that only six of those states are fully ``stable'' in the
-face of TMS fixed (usually low)
+face of TMS fixed (low except for @sc{reset})
 and a free-running JTAG clock.  For all the
 others, the next TCK transition changes to a new state.
 
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -58,9 +58,9 @@ static void jtag_add_scan_check(void (*j
  */
 static int jtag_error = ERROR_OK;
 
-static char* jtag_event_strings[] =
+static const char *jtag_event_strings[] =
 {
-	"JTAG controller reset (RESET or TRST)"
+	[JTAG_TRST_ASSERTED] = "JTAG controller reset (RESET or TRST)",
 };
 
 static int jtag_trst = 0;
@@ -243,24 +243,30 @@ int jtag_register_event_callback(jtag_ev
 	return ERROR_OK;
 }
 
-int jtag_unregister_event_callback(jtag_event_handler_t callback)
+int jtag_unregister_event_callback(jtag_event_handler_t callback, void *priv)
 {
-	jtag_event_callback_t **callbacks_p = &jtag_event_callbacks;
+	jtag_event_callback_t **callbacks_p;
+	jtag_event_callback_t **next;
 
 	if (callback == NULL)
 	{
 		return ERROR_INVALID_ARGUMENTS;
 	}
 
-	while (*callbacks_p)
+	for (callbacks_p = &jtag_event_callbacks;
+			*callbacks_p != NULL;
+			callbacks_p = next)
 	{
-		jtag_event_callback_t **next = &((*callbacks_p)->next);
+		next = &((*callbacks_p)->next);
+
+		if ((*callbacks_p)->priv != priv)
+			continue;
+
 		if ((*callbacks_p)->callback == callback)
 		{
 			free(*callbacks_p);
 			*callbacks_p = *next;
 		}
-		callbacks_p = next;
 	}
 
 	return ERROR_OK;
@@ -786,6 +792,8 @@ static int jtag_reset_callback(enum jtag
 
 	if (event == JTAG_TRST_ASSERTED)
 	{
+		tap->enabled = !tap->disabled_after_reset;
+
 		buf_set_ones(tap->cur_instr, tap->ir_length);
 		tap->bypass = 1;
 	}
@@ -1092,6 +1100,8 @@ void jtag_tap_init(jtag_tap_t *tap)
 
 void jtag_tap_free(jtag_tap_t *tap)
 {
+	jtag_unregister_event_callback(&jtag_reset_callback, tap);
+
 	/// @todo is anything missing? no memory leaks please 
 	free((void *)tap->expected_ids);
 	free((void *)tap->chip);
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -151,8 +151,10 @@ struct jtag_tap_s
 	const char* tapname;
 	const char* dotted_name;
 	int abs_chain_position;
-	/// Is this TAP enabled?
-	int enabled;
+	/// Is this TAP disabled after JTAG reset?
+	bool disabled_after_reset;
+	/// Is this TAP currently enabled?
+	bool enabled;
 	int ir_length; /**< size of instruction register */
 	u32 ir_capture_value;
 	u8* expected; /**< Capture-IR expected value */
@@ -185,16 +187,16 @@ extern unsigned jtag_tap_count_enabled(v
 extern unsigned jtag_tap_count(void);
 
 
-/* 
+/*
  * There are three cases when JTAG_TRST_ASSERTED callback is invoked. The
- * event is invoked *after* TRST is asserted(or queued rather). It is illegal 
- * to communicate with the JTAG interface during the callback(as there is 
+ * event is invoked *after* TRST is asserted(or queued rather). It is illegal
+ * to communicate with the JTAG interface during the callback(as there is
  * currently a queue being built).
- * 
+ *
  * - TMS reset
  * - SRST pulls TRST
  * - TRST asserted
- * 
+ *
  **/
 enum jtag_event {
 	JTAG_TRST_ASSERTED
@@ -226,7 +228,7 @@ struct jtag_tap_event_action_s
 typedef int (*jtag_event_handler_t)(enum jtag_event event, void* priv);
 
 extern int jtag_register_event_callback(jtag_event_handler_t f, void *x);
-extern int jtag_unregister_event_callback(jtag_event_handler_t f);
+extern int jtag_unregister_event_callback(jtag_event_handler_t f, void *x);
 
 extern int jtag_call_event_callbacks(enum jtag_event event);
 
@@ -235,7 +237,7 @@ extern int jtag_call_event_callbacks(enu
 int jtag_get_speed(void);
 /**
  * Given a @a speed setting, use the interface @c speed_div callback to
- * adjust the setting.  
+ * adjust the setting.
  * @param speed The speed setting to convert back to readable KHz.
  * @returns ERROR_OK if the interface has not been initialized or on success;
  * 	otherwise, the error code produced by the @c speed_div callback.
@@ -507,7 +509,7 @@ extern void jtag_add_pathmove(int num_st
  * @param goal_state The final TAP state.
  * @return ERROR_OK on success, or an error code on failure.
  *
- * Moves from the current state to the goal \a state. 
+ * Moves from the current state to the goal \a state.
  *
  * This needs to be handled according to the xsvf spec, see the XSTATE
  * command description.  From the XSVF spec, pertaining to XSTATE:
@@ -705,4 +707,7 @@ int jtag_get_error(void);
  */
 int jtag_error_clear(void);
 
+void jtag_tap_init(jtag_tap_t *tap);
+void jtag_tap_free(jtag_tap_t *tap);
+
 #endif /* JTAG_H */
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -308,9 +308,6 @@ static int is_bad_irval(int ir_length, j
 	return (w & v) != 0;
 }
 
-extern void jtag_tap_init(jtag_tap_t *tap);
-extern void jtag_tap_free(jtag_tap_t *tap);
-
 static int jim_newtap_cmd( Jim_GetOptInfo *goi )
 {
 	jtag_tap_t *pTap;
@@ -336,12 +333,12 @@ static int jim_newtap_cmd( Jim_GetOptInf
 		{ .name = NULL				,	.value = -1 },
 	};
 
-	pTap = malloc( sizeof(jtag_tap_t) );
-	memset( pTap, 0, sizeof(*pTap) );
-	if( !pTap ){
-		Jim_SetResult_sprintf( goi->interp, "no memory");
+	pTap = calloc(1, sizeof(jtag_tap_t));
+	if (!pTap) {
+		Jim_SetResult_sprintf(goi->interp, "no memory");
 		return JIM_ERR;
 	}
+
 	/*
 	 * we expect CHIP + TAP + OPTIONS
 	 * */
@@ -364,9 +361,6 @@ static int jim_newtap_cmd( Jim_GetOptInf
 	LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
 			  pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
 
-	/* default is enabled */
-	pTap->enabled = 1;
-
 	/* deal with options */
 #define NTREQ_IRLEN      1
 #define NTREQ_IRCAPTURE  2
@@ -384,10 +378,10 @@ static int jim_newtap_cmd( Jim_GetOptInf
 		LOG_DEBUG("Processing option: %s", n->name );
 		switch( n->value ){
 		case NTAP_OPT_ENABLED:
-			pTap->enabled = 1;
+			pTap->disabled_after_reset = false;
 			break;
 		case NTAP_OPT_DISABLED:
-			pTap->enabled = 0;
+			pTap->disabled_after_reset = true;
 			break;
 		case NTAP_OPT_EXPECTED_ID:
 		{
@@ -451,6 +445,9 @@ static int jim_newtap_cmd( Jim_GetOptInf
 		} /* switch(n->value) */
 	} /* while( goi->argc ) */
 
+	/* default is enabled-after-reset */
+	pTap->enabled = !pTap->disabled_after_reset;
+
 	/* Did all the required option bits get cleared? */
 	if (0 == reqbits)
 	{
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to