* The number of TAPs in the __jtag_all_taps list, used to track the
* assigned chain position to new TAPs
*/
-static int jtag_num_taps = 0;
+static unsigned jtag_num_taps = 0;
enum reset_types jtag_reset_config = RESET_NONE;
tap_state_t cmd_queue_end_state = TAP_RESET;
#if BUILD_ECOSBOARD == 1
extern jtag_interface_t zy1000_interface;
-#endif
-
+#elif defined(BUILD_MINIDRIVER_DUMMY)
+ extern jtag_interface_t minidummy_interface;
+#else // standard drivers
#if BUILD_PARPORT == 1
extern jtag_interface_t parport_interface;
#endif
#if BUILD_ARMJTAGEW == 1
extern jtag_interface_t armjtagew_interface;
#endif
+#endif // standard drivers
+/**
+ * The list of built-in JTAG interfaces, containing entries for those
+ * drivers that were enabled by the @c configure script.
+ *
+ * The list should be defined to contain either one minidriver interface
+ * or some number of standard driver interfaces, never both.
+ */
jtag_interface_t *jtag_interfaces[] = {
#if BUILD_ECOSBOARD == 1
&zy1000_interface,
-#endif
+#elif defined(BUILD_MINIDRIVER_DUMMY)
+ &minidummy_interface,
+#else // standard drivers
#if BUILD_PARPORT == 1
&parport_interface,
#endif
#if BUILD_ARMJTAGEW == 1
&armjtagew_interface,
#endif
+#endif // standard drivers
NULL,
};
int jtag_speed = 0;
/* jtag commands */
+static int handle_interface_list_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc);
static int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_scan_chain_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-static int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
return __jtag_all_taps;
};
-int jtag_tap_count(void)
+unsigned jtag_tap_count(void)
{
return jtag_num_taps;
}
-int jtag_tap_count_enabled(void)
+unsigned jtag_tap_count_enabled(void)
{
- jtag_tap_t *t;
- int n;
-
- n = 0;
- t = jtag_all_taps();
- while(t){
- if( t->enabled ){
+ jtag_tap_t *t = jtag_all_taps();
+ unsigned n = 0;
+ while(t)
+ {
+ if (t->enabled)
n++;
- }
t = t->next_tap;
}
return n;
}
/// Append a new TAP to the chain of all taps.
-static void jtag_tap_add(struct jtag_tap_s *t)
+void jtag_tap_add(struct jtag_tap_s *t)
{
t->abs_chain_position = jtag_num_taps++;
*tap = t;
}
-jtag_tap_t *jtag_tap_by_string( const char *s )
+jtag_tap_t *jtag_tap_by_string(const char *s)
{
- jtag_tap_t *t;
+ /* try by name first */
+ jtag_tap_t *t = jtag_all_taps();
+ while (t)
+ {
+ if (0 == strcmp(t->dotted_name, s))
+ return t;
+ t = t->next_tap;
+ }
+
+ /* no tap found by name, so try to parse the name as a number */
char *cp;
+ unsigned n = strtoul(s, &cp, 0);
+ if ((s == cp) || (*cp != 0))
+ return NULL;
- t = jtag_all_taps();
- /* try name first */
- while(t){
- if( 0 == strcmp( t->dotted_name, s ) ){
- break;
- } else {
- t = t->next_tap;
- }
- }
- /* backup plan is by number */
- if( t == NULL ){
- /* ok - is "s" a number? */
- int n;
- n = strtol( s, &cp, 0 );
- if( (s != cp) && (*cp == 0) ){
- /* Then it is... */
- t = jtag_tap_by_abs_position(n);
- }
- }
- return t;
+ return jtag_tap_by_position(n);
}
-jtag_tap_t * jtag_tap_by_jim_obj( Jim_Interp *interp, Jim_Obj *o )
+jtag_tap_t *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
{
- jtag_tap_t *t;
- const char *cp;
-
- cp = Jim_GetString( o, NULL );
- if(cp == NULL){
+ const char *cp = Jim_GetString(o, NULL);
+ jtag_tap_t *t = cp ? jtag_tap_by_string(cp) : NULL;
+ if (NULL == cp)
cp = "(unknown)";
- t = NULL;
- } else {
- t = jtag_tap_by_string( cp );
- }
- if( t == NULL ){
- Jim_SetResult_sprintf(interp,"Tap: %s is unknown", cp );
- }
+ if (NULL == t)
+ Jim_SetResult_sprintf(interp, "Tap '%s' could not be found", cp);
return t;
}
/* returns a pointer to the n-th device in the scan chain */
-jtag_tap_t * jtag_tap_by_abs_position( int n )
+jtag_tap_t *jtag_tap_by_position(unsigned n)
{
- int orig_n;
- jtag_tap_t *t;
+ jtag_tap_t *t = jtag_all_taps();
- orig_n = n;
- t = jtag_all_taps();
-
- while( t && (n > 0)) {
- n--;
+ while (t && n-- > 0)
t = t->next_tap;
- }
+
return t;
}
interface_jtag_alloc_in_value32(field);
}
-void jtag_add_ir_scan_noverify(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
+void jtag_add_ir_scan_noverify(int in_count, const scan_field_t *in_fields,
+ tap_state_t state)
{
- int retval;
jtag_prelude(state);
- retval=interface_jtag_add_ir_scan(in_num_fields, in_fields, state);
- if (retval!=ERROR_OK)
- jtag_error=retval;
-
+ int retval = interface_jtag_add_ir_scan(in_count, in_fields, state);
+ jtag_set_error(retval);
}
-/**
- * Generate an IR SCAN with a list of scan fields with one entry for each enabled TAP.
- *
- * If the input field list contains an instruction value for a TAP then that is used
- * otherwise the TAP is set to bypass.
- *
- * TAPs for which no fields are passed are marked as bypassed for subsequent DR SCANs.
- *
- */
void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
{
if (jtag_verify&&jtag_verify_capture_ir)
}
}
-/**
- * Duplicate the scan fields passed into the function into an IR SCAN command
- *
- * This function assumes that the caller handles extra fields for bypassed TAPs
- *
- */
-void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
+void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields,
+ tap_state_t state)
{
- int retval;
-
jtag_prelude(state);
- retval=interface_jtag_add_plain_ir_scan(in_num_fields, in_fields, state);
- if (retval!=ERROR_OK)
- jtag_error=retval;
+ int retval = interface_jtag_add_plain_ir_scan(
+ in_num_fields, in_fields, state);
+ jtag_set_error(retval);
}
void jtag_add_callback(jtag_callback1_t f, u8 *in)
}
-/**
- * Generate a DR SCAN using the fields passed to the function
- *
- * For not bypassed TAPs the function checks in_fields and uses fields specified there.
- * For bypassed TAPs the function generates a dummy 1bit field.
- *
- * The bypass status of TAPs is set by jtag_add_ir_scan().
- *
- */
-void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
+void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields,
+ tap_state_t state)
{
- int retval;
-
jtag_prelude(state);
- retval=interface_jtag_add_dr_scan(in_num_fields, in_fields, state);
- if (retval!=ERROR_OK)
- jtag_error=retval;
+ int retval;
+ retval = interface_jtag_add_dr_scan(in_num_fields, in_fields, state);
+ jtag_set_error(retval);
}
-
-
-/**
- * Duplicate the scan fields passed into the function into a DR SCAN command
- *
- * This function assumes that the caller handles extra fields for bypassed TAPs
- *
- */
-void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
+void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields,
+ tap_state_t state)
{
- int retval;
-
jtag_prelude(state);
- retval=interface_jtag_add_plain_dr_scan(in_num_fields, in_fields, state);
- if (retval!=ERROR_OK)
- jtag_error=retval;
+ int retval;
+ retval = interface_jtag_add_plain_dr_scan(in_num_fields, in_fields, state);
+ jtag_set_error(retval);
}
void jtag_add_dr_out(jtag_tap_t* tap,
void jtag_add_tlr(void)
{
jtag_prelude(TAP_RESET);
-
- int retval;
- retval=interface_jtag_add_tlr();
- if (retval!=ERROR_OK)
- jtag_error=retval;
-
+ jtag_set_error(interface_jtag_add_tlr());
jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
}
void jtag_add_pathmove(int num_states, const tap_state_t *path)
{
tap_state_t cur_state = cmd_queue_cur_state;
- int i;
- int retval;
/* the last state has to be a stable state */
if (!tap_is_state_stable(path[num_states - 1]))
{
LOG_ERROR("BUG: TAP path doesn't finish in a stable state");
- exit(-1);
+ jtag_set_error(ERROR_JTAG_NOT_STABLE_STATE);
+ return;
}
- for (i=0; i<num_states; i++)
+ for (int i = 0; i < num_states; i++)
{
if (path[i] == TAP_RESET)
{
LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences");
- exit(-1);
+ jtag_set_error(ERROR_JTAG_STATE_INVALID);
+ return;
}
if ( tap_state_transition(cur_state, true) != path[i]
&& tap_state_transition(cur_state, false) != path[i])
{
- LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[i]));
- exit(-1);
+ LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
+ tap_state_name(cur_state), tap_state_name(path[i]));
+ jtag_set_error(ERROR_JTAG_TRANSITION_INVALID);
+ return;
}
cur_state = path[i];
}
jtag_checks();
- retval = interface_jtag_add_pathmove(num_states, path);
+ jtag_set_error(interface_jtag_add_pathmove(num_states, path));
cmd_queue_cur_state = path[num_states - 1];
- if (retval!=ERROR_OK)
- jtag_error=retval;
}
void jtag_add_runtest(int num_cycles, tap_state_t state)
{
- int retval;
-
jtag_prelude(state);
-
- /* executed by sw or hw fifo */
- retval=interface_jtag_add_runtest(num_cycles, state);
- if (retval!=ERROR_OK)
- jtag_error=retval;
+ jtag_set_error(interface_jtag_add_runtest(num_cycles, state));
}
-void jtag_add_clocks( int num_cycles )
+void jtag_add_clocks(int num_cycles)
{
- int retval;
-
- if( !tap_is_state_stable(cmd_queue_cur_state) )
+ if (!tap_is_state_stable(cmd_queue_cur_state))
{
- LOG_ERROR( "jtag_add_clocks() was called with TAP in non-stable state \"%s\"",
- tap_state_name(cmd_queue_cur_state) );
- jtag_error = ERROR_JTAG_NOT_STABLE_STATE;
+ LOG_ERROR("jtag_add_clocks() called with TAP in unstable state \"%s\"",
+ tap_state_name(cmd_queue_cur_state));
+ jtag_set_error(ERROR_JTAG_NOT_STABLE_STATE);
return;
}
- if( num_cycles > 0 )
+ if (num_cycles > 0)
{
jtag_checks();
-
- retval = interface_jtag_add_clocks(num_cycles);
- if (retval != ERROR_OK)
- jtag_error=retval;
+ jtag_set_error(interface_jtag_add_clocks(num_cycles));
}
}
void jtag_add_reset(int req_tlr_or_trst, int req_srst)
{
int trst_with_tlr = 0;
- int retval;
/* FIX!!! there are *many* different cases here. A better
* approach is needed for legal combinations of transitions...
if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (!req_tlr_or_trst))
{
LOG_ERROR("BUG: requested reset would assert trst");
- jtag_error=ERROR_FAIL;
+ jtag_set_error(ERROR_FAIL);
return;
}
if (req_srst && !(jtag_reset_config & RESET_HAS_SRST))
{
LOG_ERROR("BUG: requested SRST assertion, but the current configuration doesn't support this");
- jtag_error=ERROR_FAIL;
+ jtag_set_error(ERROR_FAIL);
return;
}
jtag_srst = req_srst;
- retval = interface_jtag_add_reset(jtag_trst, jtag_srst);
- if (retval!=ERROR_OK)
+ int retval = interface_jtag_add_reset(jtag_trst, jtag_srst);
+ if (retval != ERROR_OK)
{
- jtag_error=retval;
+ jtag_set_error(retval);
return;
}
jtag_execute_queue();
void jtag_add_sleep(u32 us)
{
- keep_alive(); /* we might be running on a very slow JTAG clk */
- int retval=interface_jtag_add_sleep(us);
- if (retval!=ERROR_OK)
- jtag_error=retval;
- return;
+ /// @todo Here, keep_alive() appears to be a layering violation!!!
+ keep_alive();
+ jtag_set_error(interface_jtag_add_sleep(us));
}
int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits)
void jtag_execute_queue_noclear(void)
{
- /* each flush can take as much as 1-2ms on high bandwidth low latency interfaces.
- * E.g. a JTAG over TCP/IP or USB....
- */
jtag_flush_queue_count++;
-
- int retval=interface_jtag_execute_queue();
- /* we keep the first error */
- if ((jtag_error==ERROR_OK)&&(retval!=ERROR_OK))
- {
- jtag_error=retval;
- }
+ jtag_set_error(interface_jtag_execute_queue());
}
int jtag_get_flush_queue_count(void)
int jtag_execute_queue(void)
{
- int retval;
jtag_execute_queue_noclear();
- retval=jtag_error;
- jtag_error=ERROR_OK;
- return retval;
+ return jtag_error_clear();
}
static int jtag_reset_callback(enum jtag_event event, void *priv)
EXTRACT_MFG(idcode), EXTRACT_PART(idcode), EXTRACT_VER(idcode) );
}
+static bool jtag_idcode_is_final(u32 idcode)
+{
+ return idcode == 0x000000FF || idcode == 0xFFFFFFFF;
+}
+
/**
* This helper checks that remaining bits in the examined chain data are
* all as expected, but a single JTAG device requires only 64 bits to be
{
u32 idcode = buf_get_u32(idcodes, count, 32);
// do not trigger the warning if the data looks good
- if (!triggered && (idcode == 0x000000FF || idcode == 0xFFFFFFFF))
+ if (!triggered && jtag_idcode_is_final(idcode))
continue;
LOG_WARNING("Unexpected idcode after end of chain: %d 0x%08x",
count, idcode);
}
}
+static bool jtag_examine_chain_match_tap(const struct jtag_tap_s *tap)
+{
+ if (0 == tap->expected_ids_cnt)
+ {
+ /// @todo Enable LOG_INFO to ask for reports about unknown TAP IDs.
+#if 0
+ LOG_INFO("Uknown JTAG TAP ID: 0x%08x", tap->idcode)
+ LOG_INFO("Please report the chip name and reported ID code to the openocd project");
+#endif
+ return true;
+ }
+
+ /* Loop over the expected identification codes and test for a match */
+ u8 ii;
+ for (ii = 0; ii < tap->expected_ids_cnt; ii++)
+ {
+ if (tap->idcode == tap->expected_ids[ii])
+ break;
+ }
+
+ /* If none of the expected ids matched, log an error */
+ if (ii != tap->expected_ids_cnt)
+ {
+ LOG_INFO("JTAG Tap/device matched");
+ return true;
+ }
+ jtag_examine_chain_display(LOG_LVL_ERROR, "got",
+ tap->dotted_name, tap->idcode);
+ for (ii = 0; ii < tap->expected_ids_cnt; ii++)
+ {
+ char msg[32];
+ snprintf(msg, sizeof(msg), "expected %hhu of %hhu",
+ ii + 1, tap->expected_ids_cnt);
+ jtag_examine_chain_display(LOG_LVL_ERROR, msg,
+ tap->dotted_name, tap->expected_ids[ii]);
+ }
+ return false;
+}
+
/* Try to examine chain layout according to IEEE 1149.1 §12
*/
static int jtag_examine_chain(void)
{
- jtag_tap_t *tap;
u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
- int bit_count;
- int device_count = 0;
+ unsigned device_count = 0;
jtag_examine_chain_execute(idcode_buffer, JTAG_MAX_CHAIN_SIZE);
return ERROR_JTAG_INIT_FAILED;
/* point at the 1st tap */
- tap = jtag_tap_next_enabled(NULL);
- if( tap == NULL ){
+ jtag_tap_t *tap = jtag_tap_next_enabled(NULL);
+ if (tap == NULL)
+ {
LOG_ERROR("JTAG: No taps enabled?");
return ERROR_JTAG_INIT_FAILED;
}
- for (bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;)
+ for (unsigned bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;)
{
u32 idcode = buf_get_u32(idcode_buffer, bit_count, 32);
if ((idcode & 1) == 0)
{
/* LSB must not be 0, this indicates a device in bypass */
LOG_WARNING("Tap/Device does not have IDCODE");
- idcode=0;
+ idcode = 0;
bit_count += 1;
}
* as AVR will output all 1's instead of TDI input value at
* end of chain.
*/
- if ((idcode == 0x000000FF)||(idcode == 0xFFFFFFFF))
+ if (jtag_idcode_is_final(idcode))
{
jtag_examine_chain_end(idcode_buffer,
bit_count + 32, JTAG_MAX_CHAIN_SIZE * 32);
tap->idcode = idcode;
- if (0 == tap->expected_ids_cnt)
- {
- // @todo Enable LOG_INFO to ask for reports about unknown TAP IDs.
-#if 0
- LOG_INFO("Uknown JTAG TAP ID: 0x%08x", tap->idcode)
- LOG_INFO("Please report the chip name and reported ID code to the openocd project");
-#endif
- tap = jtag_tap_next_enabled(tap);
- continue;
- }
- /* Loop over the expected identification codes and test for a match */
- u8 ii;
- for (ii = 0; ii < tap->expected_ids_cnt; ii++) {
- if (tap->idcode == tap->expected_ids[ii]) {
- break;
- }
- }
+ // ensure the TAP ID does matches what was expected
+ if (!jtag_examine_chain_match_tap(tap))
+ return ERROR_JTAG_INIT_FAILED;
- /* If none of the expected ids matched, log an error */
- if (ii != tap->expected_ids_cnt)
- {
- LOG_INFO("JTAG Tap/device matched");
- tap = jtag_tap_next_enabled(tap);
- continue;
- }
- jtag_examine_chain_display(LOG_LVL_ERROR, "got",
- tap->dotted_name, tap->idcode);
- for (ii = 0; ii < tap->expected_ids_cnt; ii++) {
- char msg[20];
- snprintf(msg, 20, "expected %hhu of %hhu",
- ii + 1, tap->expected_ids_cnt);
- jtag_examine_chain_display(LOG_LVL_ERROR, msg,
- tap->dotted_name, tap->expected_ids[ii]);
- }
- return ERROR_JTAG_INIT_FAILED;
+ tap = jtag_tap_next_enabled(tap);
}
/* see if number of discovered devices matches configuration */
if (device_count != jtag_tap_count_enabled())
{
- LOG_ERROR("number of discovered devices in JTAG chain (%i) doesn't match (enabled) configuration (%i), total taps: %d",
- device_count, jtag_tap_count_enabled(), jtag_tap_count());
- LOG_ERROR("check the config file and ensure proper JTAG communication (connections, speed, ...)");
+ LOG_ERROR("number of discovered devices in JTAG chain (%i) "
+ "does not match (enabled) configuration (%i), total taps: %d",
+ device_count, jtag_tap_count_enabled(), jtag_tap_count());
+ LOG_ERROR("check the config file and ensure proper JTAG communication"
+ " (connections, speed, ...)");
return ERROR_JTAG_INIT_FAILED;
}
register_command(cmd_ctx, NULL, "interface", handle_interface_command,
COMMAND_CONFIG, "try to configure interface");
+ register_command(cmd_ctx, NULL,
+ "interface_list", &handle_interface_list_command,
+ COMMAND_ANY, "list all built-in interfaces");
register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command,
COMMAND_ANY, "(DEPRECATED) set jtag speed (if supported)");
register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command,
register_command(cmd_ctx, NULL, "scan_chain", handle_scan_chain_command,
COMMAND_EXEC, "print current scan chain configuration");
- register_command(cmd_ctx, NULL, "endstate", handle_endstate_command,
- COMMAND_EXEC, "finish JTAG operations in <tap_state>");
register_command(cmd_ctx, NULL, "jtag_reset", handle_jtag_reset_command,
COMMAND_EXEC, "toggle reset lines <trst> <srst>");
register_command(cmd_ctx, NULL, "runtest", handle_runtest_command,
return ERROR_OK;
}
-static int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_interface_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc)
{
- int i;
- int retval;
-
/* check whether the interface is already configured */
if (jtag_interface)
{
}
/* interface name is a mandatory argument */
- if (argc < 1 || args[0][0] == '\0')
- {
+ if (argc != 1 || args[0][0] == '\0')
return ERROR_COMMAND_SYNTAX_ERROR;
- }
- for (i=0; jtag_interfaces[i]; i++)
+ for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
{
- if (strcmp(args[0], jtag_interfaces[i]->name) == 0)
- {
- if ((retval = jtag_interfaces[i]->register_commands(cmd_ctx)) != ERROR_OK)
- {
+ if (strcmp(args[0], jtag_interfaces[i]->name) != 0)
+ continue;
+
+ int retval = jtag_interfaces[i]->register_commands(cmd_ctx);
+ if (ERROR_OK != retval)
return retval;
- }
- jtag_interface = jtag_interfaces[i];
+ jtag_interface = jtag_interfaces[i];
- if (jtag_interface->khz == NULL)
- {
- jtag_interface->khz = default_khz;
- }
- if (jtag_interface->speed_div == NULL)
- {
- jtag_interface->speed_div = default_speed_div;
- }
- if (jtag_interface->power_dropout == NULL)
- {
- jtag_interface->power_dropout = default_power_dropout;
- }
- if (jtag_interface->srst_asserted == NULL)
- {
- jtag_interface->srst_asserted = default_srst_asserted;
- }
+ if (jtag_interface->khz == NULL)
+ jtag_interface->khz = default_khz;
+ if (jtag_interface->speed_div == NULL)
+ jtag_interface->speed_div = default_speed_div;
+ if (jtag_interface->power_dropout == NULL)
+ jtag_interface->power_dropout = default_power_dropout;
+ if (jtag_interface->srst_asserted == NULL)
+ jtag_interface->srst_asserted = default_srst_asserted;
- return ERROR_OK;
- }
+ return ERROR_OK;
}
/* no valid interface was found (i.e. the configuration option,
* didn't match one of the compiled-in interfaces
*/
- LOG_ERROR("No valid jtag interface found (%s)", args[0]);
- LOG_ERROR("compiled-in jtag interfaces:");
- for (i = 0; jtag_interfaces[i]; i++)
+ LOG_ERROR("The specified JTAG interface was not found (%s)", args[0]);
+ handle_interface_list_command(cmd_ctx, cmd, args, argc);
+ return ERROR_JTAG_INVALID_INTERFACE;
+}
+
+static int handle_interface_list_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc)
+{
+ if (strcmp(cmd, "interface_list") == 0 && argc > 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ command_print(cmd_ctx, "The following JTAG interfaces are available:");
+ for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
{
- LOG_ERROR("%i: %s", i, jtag_interfaces[i]->name);
+ const char *name = jtag_interfaces[i]->name;
+ command_print(cmd_ctx, "%u: %s", i + 1, name);
}
- return ERROR_JTAG_INVALID_INTERFACE;
+ return ERROR_OK;
}
static int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
return ERROR_OK;
}
-static int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc)
{
- if (argc < 1)
- {
- LOG_ERROR("jtag_nsrst_delay <ms> command takes one required argument");
- exit(-1);
- }
- else
- {
+ if (argc > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ if (argc == 1)
jtag_set_nsrst_delay(strtoul(args[0], NULL, 0));
- }
-
+ command_print(cmd_ctx, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay());
return ERROR_OK;
}
-static int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc)
{
- if (argc < 1)
- {
- LOG_ERROR("jtag_ntrst_delay <ms> command takes one required argument");
- exit(-1);
- }
- else
- {
+ if (argc > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ if (argc == 1)
jtag_set_ntrst_delay(strtoul(args[0], NULL, 0));
- }
-
+ command_print(cmd_ctx, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
return ERROR_OK;
}
-
static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
- int retval=ERROR_OK;
+ int retval = ERROR_OK;
+ if (argc > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
if (argc == 1)
{
LOG_DEBUG("handle jtag speed");
/* this command can be called during CONFIG,
* in which case jtag isn't initialized */
if (jtag)
- {
- retval=jtag->speed(cur_speed);
- }
- } else if (argc == 0)
- {
- } else
- {
- return ERROR_COMMAND_SYNTAX_ERROR;
+ retval = jtag->speed(cur_speed);
}
command_print(cmd_ctx, "jtag_speed: %d", jtag_speed);
static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
- int retval=ERROR_OK;
- LOG_DEBUG("handle jtag khz");
+ if (argc > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ int retval = ERROR_OK;
int cur_speed = 0;
- if(argc == 1)
+ if (argc == 1)
{
+ LOG_DEBUG("handle jtag khz");
+
jtag_set_speed_khz(strtoul(args[0], NULL, 0));
if (jtag != NULL)
{
LOG_DEBUG("have interface set up");
int speed_div1;
- if ((retval=jtag->khz(jtag_get_speed_khz(), &speed_div1))!=ERROR_OK)
+ retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
+ if (ERROR_OK != retval)
{
jtag_set_speed_khz(0);
return retval;
}
-
cur_speed = jtag_speed = speed_div1;
- retval=jtag->speed(cur_speed);
- } else
- {
- hasKHz = true;
+ retval = jtag->speed(cur_speed);
}
- } else if (argc==0)
- {
- } else
- {
- return ERROR_COMMAND_SYNTAX_ERROR;
+ else
+ hasKHz = true;
}
- cur_speed = jtag_get_speed_khz();
- if (jtag!=NULL)
+ cur_speed = jtag_get_speed_khz();
+ if (jtag != NULL)
{
- if ((retval=jtag->speed_div(jtag_speed, &cur_speed))!=ERROR_OK)
+ retval = jtag->speed_div(jtag_speed, &cur_speed);
+ if (ERROR_OK != retval)
return retval;
}
}
-static int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_jtag_reset_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc)
{
- if (argc < 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- tap_state_t state = tap_state_by_name(args[0]);
- if (state < 0)
- {
- command_print( cmd_ctx, "Invalid state name: %s\n", args[0] );
+ if (argc != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- }
- jtag_set_end_state(state);
- jtag_execute_queue();
-
- command_print(cmd_ctx, "current endstate: %s",
- tap_state_name(cmd_queue_end_state));
- return ERROR_OK;
-}
-
-static int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
int trst = -1;
- int srst = -1;
-
- if (argc < 2)
- {
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
if (args[0][0] == '1')
trst = 1;
else if (args[0][0] == '0')
trst = 0;
else
- {
return ERROR_COMMAND_SYNTAX_ERROR;
- }
+ int srst = -1;
if (args[1][0] == '1')
srst = 1;
else if (args[1][0] == '0')
srst = 0;
else
- {
return ERROR_COMMAND_SYNTAX_ERROR;
- }
if (jtag_interface_init(cmd_ctx) != ERROR_OK)
return ERROR_JTAG_INIT_FAILED;
return ERROR_OK;
}
-static int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_runtest_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc)
{
- if (argc < 1)
- {
+ if (argc != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- }
jtag_add_runtest(strtol(args[0], NULL, 0), jtag_get_end_state());
jtag_execute_queue();
return ERROR_OK;
-
}
/*
}
/**
- * Function jtag_add_statemove
- * moves from the current state to the goal \a state. This needs
+ * 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:
+ *
+ * For special states known as stable states (Test-Logic-Reset,
+ * Run-Test/Idle, Pause-DR, Pause- IR), an XSVF interpreter follows
+ * predefined TAP state paths when the starting state is a stable state
+ * and when the XSTATE specifies a new stable state. See the STATE
+ * command in the [Ref 5] for the TAP state paths between stable
+ * states.
+ *
+ * For non-stable states, XSTATE should specify a state that is only one
+ * TAP state transition distance from the current TAP state to avoid
+ * undefined TAP state paths. A sequence of multiple XSTATE commands can
+ * be issued to transition the TAP through a specific state path.
+ *
+ * @note Unless @a tms_bits holds a path that agrees with [Ref 5] in *
+ * above spec, then this code is not fully conformant to the xsvf spec.
+ * This puts a burden on tap_get_tms_path() function from the xsvf spec.
+ * If in doubt, you should confirm that that burden is being met.
+ *
+ * Otherwise, state must be immediately reachable in one clock cycle,
+ * and does not need to be a stable state.
*/
int jtag_add_statemove(tap_state_t goal_state)
{
- int retval = ERROR_OK;
-
- tap_state_t moves[8];
tap_state_t cur_state = cmd_queue_cur_state;
- int i;
- int tms_bits;
- int tms_count;
LOG_DEBUG( "cur_state=%s goal_state=%s",
tap_state_name(cur_state),
tap_state_name(goal_state) );
- /* From the XSVF spec, pertaining to XSTATE:
-
- For special states known as stable states (Test-Logic-Reset,
- Run-Test/Idle, Pause-DR, Pause- IR), an XSVF interpreter follows
- predefined TAP state paths when the starting state is a stable state and
- when the XSTATE specifies a new stable state (see the STATE command in
- the [Ref 5] for the TAP state paths between stable states). For
- non-stable states, XSTATE should specify a state that is only one TAP
- state transition distance from the current TAP state to avoid undefined
- TAP state paths. A sequence of multiple XSTATE commands can be issued to
- transition the TAP through a specific state path.
- */
-
if (goal_state==cur_state )
; /* nothing to do */
-
else if( goal_state==TAP_RESET )
{
jtag_add_tlr();
}
-
else if( tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state) )
{
- /* note: unless tms_bits holds a path that agrees with [Ref 5] in above
- spec, then this code is not fully conformant to the xsvf spec. This
- puts a burden on tap_get_tms_path() function from the xsvf spec.
- If in doubt, you should confirm that that burden is being met.
- */
-
- tms_bits = tap_get_tms_path(cur_state, goal_state);
- tms_count = tap_get_tms_path_len(cur_state, goal_state);
+ unsigned tms_bits = tap_get_tms_path(cur_state, goal_state);
+ unsigned tms_count = tap_get_tms_path_len(cur_state, goal_state);
+ tap_state_t moves[8];
+ assert(tms_count < DIM(moves));
- assert( (unsigned) tms_count < DIM(moves) );
-
- for (i=0; i<tms_count; i++, tms_bits>>=1)
+ for (unsigned i = 0; i < tms_count; i++, tms_bits >>= 1)
{
bool bit = tms_bits & 1;
jtag_add_pathmove(tms_count, moves);
}
-
- /* else state must be immediately reachable in one clock cycle, and does not
- need to be a stable state.
- */
else if( tap_state_transition(cur_state, true) == goal_state
|| tap_state_transition(cur_state, false) == goal_state )
{
- /* move a single state */
- moves[0] = goal_state;
- jtag_add_pathmove( 1, moves );
+ jtag_add_pathmove(1, &goal_state);
}
else
- {
- retval = ERROR_FAIL;
- }
+ return ERROR_FAIL;
- return retval;
+ return ERROR_OK;
}
void jtag_set_nsrst_delay(unsigned delay)
{
jtag_nsrst_delay = delay;
}
+unsigned jtag_get_nsrst_delay(void)
+{
+ return jtag_nsrst_delay;
+}
void jtag_set_ntrst_delay(unsigned delay)
{
jtag_ntrst_delay = delay;
}
-
-
+unsigned jtag_get_ntrst_delay(void)
+{
+ return jtag_ntrst_delay;
+}