tap_transition_t tap_transitions[16] =
{
- {TAP_TLR, TAP_RTI}, /* TLR */
- {TAP_SIS, TAP_CD}, /* SDS */
- {TAP_E1D, TAP_SD}, /* CD */
- {TAP_E1D, TAP_SD}, /* SD */
- {TAP_UD, TAP_PD}, /* E1D */
- {TAP_E2D, TAP_PD}, /* PD */
- {TAP_UD, TAP_SD}, /* E2D */
- {TAP_SDS, TAP_RTI}, /* UD */
- {TAP_SDS, TAP_RTI}, /* RTI */
- {TAP_TLR, TAP_CI}, /* SIS */
- {TAP_E1I, TAP_SI}, /* CI */
- {TAP_E1I, TAP_SI}, /* SI */
- {TAP_UI, TAP_PI}, /* E1I */
- {TAP_E2I, TAP_PI}, /* PI */
- {TAP_UI, TAP_SI}, /* E2I */
- {TAP_SDS, TAP_RTI} /* UI */
+ {TAP_RESET, TAP_IDLE}, /* TLR */
+ {TAP_IRSELECT, TAP_DRCAPTURE}, /* SDS */
+ {TAP_DREXIT1, TAP_DRSHIFT}, /* CD */
+ {TAP_DREXIT1, TAP_DRSHIFT}, /* SD */
+ {TAP_DRUPDATE, TAP_DRPAUSE}, /* E1D */
+ {TAP_DREXIT2, TAP_DRPAUSE}, /* PD */
+ {TAP_DRUPDATE, TAP_DRSHIFT}, /* E2D */
+ {TAP_DRSELECT, TAP_IDLE}, /* UD */
+ {TAP_DRSELECT, TAP_IDLE}, /* RTI */
+ {TAP_RESET, TAP_IRCAPTURE}, /* SIS */
+ {TAP_IREXIT1, TAP_IRSHIFT}, /* CI */
+ {TAP_IREXIT1, TAP_IRSHIFT}, /* SI */
+ {TAP_IRUPDATE, TAP_IRPAUSE}, /* E1I */
+ {TAP_IREXIT2, TAP_IRPAUSE}, /* PI */
+ {TAP_IRUPDATE, TAP_IRSHIFT}, /* E2I */
+ {TAP_DRSELECT, TAP_IDLE} /* UI */
};
char* jtag_event_strings[] =
* inside the drivers, but we don't want to break
* linking the drivers!!!!
*/
-enum tap_state end_state = TAP_TLR;
-enum tap_state cur_state = TAP_TLR;
+enum tap_state end_state = TAP_RESET;
+enum tap_state cur_state = TAP_RESET;
int jtag_trst = 0;
int jtag_srst = 0;
static jtag_tap_t *jtag_all_taps = NULL;
enum reset_types jtag_reset_config = RESET_NONE;
-enum tap_state cmd_queue_end_state = TAP_TLR;
-enum tap_state cmd_queue_cur_state = TAP_TLR;
+enum tap_state cmd_queue_end_state = TAP_RESET;
+enum tap_state cmd_queue_cur_state = TAP_RESET;
int jtag_verify_capture_ir = 1;
int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-jtag_tap_t *jtag_AllTaps(void)
-{
- return jtag_all_taps;
+jtag_tap_t *jtag_AllTaps(void)
+{
+ return jtag_all_taps;
};
-int
+int
jtag_NumTotalTaps(void)
{
jtag_tap_t *t;
return n;
}
-jtag_tap_t *
-jtag_NextEnabledTap( jtag_tap_t *p )
-{
- if( p == NULL ){
- // start at the head of list
- p = jtag_AllTaps();
- } else {
- // start *after* this one
- p = p->next_tap;
- }
- while( p ){
- if( p->enabled ){
- break;
- } else {
- p = p->next_tap;
- }
- }
- return p;
-}
jtag_tap_t *jtag_TapByString( const char *s )
{
t = NULL;
} else {
t = jtag_TapByString( cp );
- }
+ }
if( t == NULL ){
Jim_SetResult_sprintf(interp,"Tap: %s is unknown", cp );
}
orig_n = n;
t = jtag_AllTaps();
-
+
while( t && (n > 0)) {
n--;
t = t->next_tap;
int offset;
u8 *t;
+ /*
+ * WARNING:
+ * We align/round the *SIZE* per below
+ * so that all pointers returned by
+ * this function are reasonably well
+ * aligned.
+ *
+ * If we did not, then an "odd-length" request would cause the
+ * *next* allocation to be at an *odd* address, and because
+ * this function has the same type of api as malloc() - we
+ * must also return pointers that have the same type of
+ * alignment.
+ *
+ * What I do not/have is a reasonable portable means
+ * to align by...
+ *
+ * The solution here, is based on these suggestions.
+ * http://gcc.gnu.org/ml/gcc-help/2008-12/msg00041.html
+ *
+ */
+ union worse_case_align {
+ int i;
+ long l;
+ float f;
+ void *v;
+ };
+#define ALIGN_SIZE (sizeof(union worse_case_align))
+
+ // The alignment process.
+ size = (size + ALIGN_SIZE -1) & (~(ALIGN_SIZE-1));
+ // Done...
+
+
if (*p_page)
{
while ((*p_page)->next)
return;
}
- if (cmd_queue_end_state == TAP_TLR)
+ if (cmd_queue_end_state == TAP_RESET)
jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
}
void jtag_add_tlr(void)
{
- jtag_prelude(TAP_TLR);
+ jtag_prelude(TAP_RESET);
int retval;
retval=interface_jtag_add_tlr();
int MINIDRIVER(interface_jtag_add_tlr)()
{
- enum tap_state state = TAP_TLR;
+ enum tap_state state = TAP_RESET;
jtag_command_t **last_cmd = jtag_get_last_command_p();
/* allocate memory for a new list member */
for (i=0; i<num_states; i++)
{
- if (path[i] == TAP_TLR)
+ if (path[i] == TAP_RESET)
{
- LOG_ERROR("BUG: TAP_TLR is not a valid state for pathmove sequences");
+ LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences");
exit(-1);
}
if ((tap_transitions[cur_state].low != path[i])&&
if (trst_with_tlr)
{
LOG_DEBUG("JTAG reset with TLR instead of TRST");
- jtag_add_end_state(TAP_TLR);
+ jtag_add_end_state(TAP_RESET);
jtag_add_tlr();
jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
return;
* and inform possible listeners about this
*/
LOG_DEBUG("TRST line asserted");
- cmd_queue_cur_state = TAP_TLR;
+ cmd_queue_cur_state = TAP_RESET;
jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
}
else
void jtag_add_end_state(enum tap_state state)
{
cmd_queue_end_state = state;
- if ((cmd_queue_end_state == TAP_SD)||(cmd_queue_end_state == TAP_SI))
+ if ((cmd_queue_end_state == TAP_DRSHIFT)||(cmd_queue_end_state == TAP_IRSHIFT))
{
- LOG_ERROR("BUG: TAP_SD/SI can't be end state. Calling code should use a larger scan field");
+ LOG_ERROR("BUG: TAP_DRSHIFT/SI can't be end state. Calling code should use a larger scan field");
}
}
char *in_check_mask_char;
in_check_mask_char = buf_to_str(field->in_check_mask, (num_bits > 64) ? 64 : num_bits, 16);
LOG_WARNING("value captured during scan didn't pass the requested check:");
- LOG_WARNING("captured: 0x%s check_value: 0x%s check_mask: 0x%s",
+ LOG_WARNING("captured: 0x%s check_value: 0x%s check_mask: 0x%s",
captured_char, in_check_value_char, in_check_mask_char);
free(in_check_mask_char);
}
buf_set_u32(idcode_buffer, i * 32, 32, 0x000000FF);
}
- jtag_add_plain_dr_scan(1, &field, TAP_TLR);
+ jtag_add_plain_dr_scan(1, &field, TAP_RESET);
jtag_execute_queue();
for (i = 0; i < JTAG_MAX_CHAIN_SIZE * 4; i++)
LOG_ERROR("JTAG: No taps enabled?");
return ERROR_JTAG_INIT_FAILED;
}
-
+
for (bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;)
{
u32 idcode = buf_get_u32(idcode_buffer, bit_count, 32);
if (tap)
{
tap->idcode = idcode;
- if( tap->expected_id ){
- if( tap->idcode != tap->expected_id ){
- LOG_ERROR("ERROR: Tap: %s - Expected id: 0x%08x, Got: 0x%08x",
+
+ if (tap->expected_ids_cnt > 0) {
+ /* 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_ERROR("JTAG tap: %s got: 0x%08x (mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x)",
tap->dotted_name,
- tap->expected_id,
- idcode );
- LOG_ERROR("ERROR: expected: mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x",
- EXTRACT_MFG( tap->expected_id ),
- EXTRACT_PART( tap->expected_id ),
- EXTRACT_VER( tap->expected_id ) );
- LOG_ERROR("ERROR: got: mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x",
+ idcode,
EXTRACT_MFG( tap->idcode ),
EXTRACT_PART( tap->idcode ),
EXTRACT_VER( tap->idcode ) );
+ for (ii = 0; ii < tap->expected_ids_cnt; ii++) {
+ LOG_ERROR("JTAG tap: %s expected %hhu of %hhu: 0x%08x (mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x)",
+ tap->dotted_name,
+ ii + 1,
+ tap->expected_ids_cnt,
+ tap->expected_ids[ii],
+ EXTRACT_MFG( tap->expected_ids[ii] ),
+ EXTRACT_PART( tap->expected_ids[ii] ),
+ EXTRACT_VER( tap->expected_ids[ii] ) );
+ }
+
+ return ERROR_JTAG_INIT_FAILED;
} else {
LOG_INFO("JTAG Tap/device matched");
}
} else {
#if 0
- LOG_INFO("JTAG TAP ID: 0x%08x - Unknown - please report (A) chipname and (B) idcode to the openocd project",
+ LOG_INFO("JTAG TAP ID: 0x%08x - Unknown - please report (A) chipname and (B) idcode to the openocd project",
tap->idcode);
#endif
}
field.in_handler = NULL;
field.in_handler_priv = NULL;
- jtag_add_plain_ir_scan(1, &field, TAP_TLR);
+ jtag_add_plain_ir_scan(1, &field, TAP_RESET);
jtag_execute_queue();
tap = NULL;
if( tap == NULL ){
break;
}
-
+
if (buf_get_u32(ir_test, chain_pos, 2) != 0x1)
{
{ .name = NULL , .value = -1 },
};
-
+
pTap = malloc( sizeof(jtag_tap_t) );
memset( pTap, 0, sizeof(*pTap) );
if( !pTap ){
}
//
// we expect CHIP + TAP + OPTIONS
- //
+ //
if( goi->argc < 3 ){
Jim_SetResult_sprintf(goi->interp, "Missing CHIP TAP OPTIONS ....");
return JIM_ERR;
Jim_GetOpt_String( goi, &cp, NULL );
pTap->tapname = strdup(cp);
-
+
// name + dot + name + null
x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
cp = malloc( x );
sprintf( cp, "%s.%s", pTap->chip, pTap->tapname );
pTap->dotted_name = cp;
- LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
+ 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;
// clear them as we find them
reqbits = (NTREQ_IRLEN | NTREQ_IRCAPTURE | NTREQ_IRMASK);
-
+
while( goi->argc ){
e = Jim_GetOpt_Nvp( goi, opts, &n );
if( e != JIM_OK ){
pTap->enabled = 0;
break;
case NTAP_OPT_EXPECTED_ID:
+ {
+ u32 *new_expected_ids;
+
e = Jim_GetOpt_Wide( goi, &w );
- pTap->expected_id = w;
+ if( e != JIM_OK) {
+ Jim_SetResult_sprintf(goi->interp, "option: %s bad parameter", n->name);
+ return e;
+ }
+
+ new_expected_ids = malloc(sizeof(u32) * (pTap->expected_ids_cnt + 1));
+ if (new_expected_ids == NULL) {
+ Jim_SetResult_sprintf( goi->interp, "no memory");
+ return JIM_ERR;
+ }
+
+ memcpy(new_expected_ids, pTap->expected_ids, sizeof(u32) * pTap->expected_ids_cnt);
+
+ new_expected_ids[pTap->expected_ids_cnt] = w;
+
+ free(pTap->expected_ids);
+ pTap->expected_ids = new_expected_ids;
+ pTap->expected_ids_cnt++;
break;
+ }
case NTAP_OPT_IRLEN:
case NTAP_OPT_IRMASK:
case NTAP_OPT_IRCAPTURE:
}
if( (w < 0) || (w > 0xffff) ){
// wacky value
- Jim_SetResult_sprintf( goi->interp, "option: %s - wacky value: %d (0x%x)",
+ Jim_SetResult_sprintf( goi->interp, "option: %s - wacky value: %d (0x%x)",
n->name, (int)(w), (int)(w));
return JIM_ERR;
}
// Did we get all the options?
if( reqbits ){
- // no
+ // no
Jim_SetResult_sprintf( goi->interp,
- "newtap: %s missing required parameters",
+ "newtap: %s missing required parameters",
pTap->dotted_name);
// fixme: Tell user what is missing :-(
// no memory leaks pelase
+ free(((void *)(pTap->expected_ids)));
free(((void *)(pTap->chip)));
free(((void *)(pTap->tapname)));
free(((void *)(pTap->dotted_name)));
pTap->ir_length,
pTap->ir_capture_value );
buf_set_u32( pTap->expected_mask,
- 0,
+ 0,
pTap->ir_length,
pTap->ir_capture_mask );
- buf_set_ones( pTap->cur_instr,
+ buf_set_ones( pTap->cur_instr,
pTap->ir_length );
pTap->bypass = 1;
jtag_register_event_callback(jtag_reset_callback, pTap );
-
+
ppTap = &(jtag_all_taps);
while( (*ppTap) != NULL ){
ppTap = &((*ppTap)->next_tap);
}
*ppTap = pTap;
- {
+ {
static int n_taps = 0;
pTap->abs_chain_position = n_taps++;
}
Jim_SetResultString( goi.interp, "Too many parameters",-1 );
return JIM_ERR;
}
-
- {
+
+ {
jtag_tap_t *t;
t = jtag_TapByJimObj( goi.interp, goi.argv[0] );
if( t == NULL ){
// argv[ 1] = ir capture
// argv[ 2] = ir mask
// argv[ 3] = not actually used by anything but in the docs
-
+
if( argc < 4 ){
command_print( cmd_ctx, "OLD DEPRECATED SYNTAX: Please use the NEW syntax");
return ERROR_OK;
command_print( cmd_ctx, "jtag newtap stm32 cortexm3 ....., thus creating the tap: \"stm32.cortexm3\"");
command_print( cmd_ctx, "jtag newtap stm32 boundry ....., and the tap: \"stm32.boundery\"");
command_print( cmd_ctx, "And then refer to the taps by the dotted name.");
-
+
newargs[0] = Jim_NewStringObj( interp, "jtag", -1 );
Jim_GetString( newargs[8], NULL ),
Jim_GetString( newargs[9], NULL ) );
-
+
e = jim_jtag_command( interp, 10, newargs );
if( e != JIM_OK ){
command_print(cmd_ctx, "---|--------------------|---------|------------|------------|------|------|------|---------");
while( tap ){
- u32 expected, expected_mask, cur_instr;
+ u32 expected, expected_mask, cur_instr, ii;
expected = buf_get_u32(tap->expected, 0, tap->ir_length);
expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
cur_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length);
+
command_print(cmd_ctx,
"%2d | %-18s | %c | 0x%08x | 0x%08x | 0x%02x | 0x%02x | 0x%02x | 0x%02x",
tap->abs_chain_position,
tap->dotted_name,
tap->enabled ? 'Y' : 'n',
- tap->idcode,
- tap->expected_id,
- tap->ir_length,
- expected,
- expected_mask,
+ tap->idcode,
+ (tap->expected_ids_cnt > 0 ? tap->expected_ids[0] : 0),
+ tap->ir_length,
+ expected,
+ expected_mask,
cur_instr);
+
+ for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
+ command_print(cmd_ctx, " | | | | 0x%08x | | | | ",
+ tap->expected_ids[ii]);
+ }
+
tap = tap->next_tap;
}