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