{
[JTAG_TRST_ASSERTED] = "JTAG controller reset (TLR or TRST)",
[JTAG_TAP_EVENT_ENABLE] = "TAP enabled",
+ [JTAG_TAP_EVENT_POST_RESET] = "post reset",
[JTAG_TAP_EVENT_DISABLE] = "TAP disabled",
};
void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
{
+ assert(state != TAP_RESET);
+
if (jtag_verify && jtag_verify_capture_ir)
{
/* 8 x 32 bit id's is enough for all invocations */
void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields,
tap_state_t state)
{
+ assert(state != TAP_RESET);
+
jtag_prelude(state);
int retval = interface_jtag_add_plain_ir_scan(
interface_jtag_add_callback4(f, data0, data1, data2, data3);
}
-int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, uint8_t *in_check_mask, int num_bits);
+static int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value,
+ uint8_t *in_check_mask, int num_bits);
static int jtag_check_value_mask_callback(jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
{
void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields,
tap_state_t state)
{
+ assert(state != TAP_RESET);
+
jtag_prelude(state);
int retval;
void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields,
tap_state_t state)
{
+ assert(state != TAP_RESET);
+
jtag_prelude(state);
int retval;
int num_fields, const int* num_bits, const uint32_t* value,
tap_state_t end_state)
{
+ assert(end_state != TAP_RESET);
assert(end_state != TAP_INVALID);
cmd_queue_cur_state = end_state;
{
jtag_prelude(TAP_RESET);
jtag_set_error(interface_jtag_add_tlr());
+
+ /* NOTE: order here matches TRST path in jtag_add_reset() */
jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
+ jtag_notify_reset();
}
void jtag_add_pathmove(int num_states, const tap_state_t *path)
} else if (jtag_trst != new_trst) {
jtag_trst = new_trst;
if (jtag_trst) {
- /* we just asserted nTRST, so we're now in TAP_RESET;
- * inform possible listeners about this
- *
- * REVISIT asserting TRST is less significant than
- * being in TAP_RESET ... both entries (TRST, TLR)
- * should trigger a callback.
- */
LOG_DEBUG("TRST line asserted");
tap_set_state(TAP_RESET);
- jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
} else {
LOG_DEBUG("TRST line released");
if (jtag_ntrst_delay)
jtag_add_sleep(jtag_ntrst_delay * 1000);
+
+ /* We just asserted nTRST, so we're now in TAP_RESET.
+ * Inform possible listeners about this, now that
+ * JTAG instructions and data can be shifted. This
+ * sequence must match jtag_add_tlr().
+ */
+ jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
+ jtag_notify_reset();
}
}
}
jtag_set_error(interface_jtag_add_sleep(us));
}
-int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, uint8_t *in_check_mask, int num_bits)
+static int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value,
+ uint8_t *in_check_mask, int num_bits)
{
int retval = ERROR_OK;
compare_failed = buf_cmp(captured, in_check_value, num_bits);
if (compare_failed) {
- /* An error handler could have caught the failing check
- * only report a problem when there wasn't a handler, or if the handler
- * acknowledged the error
- */
- /*
- LOG_WARNING("TAP %s:",
- jtag_tap_name(field->tap));
- */
- if (compare_failed)
- {
- char *captured_char = buf_to_str(captured, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16);
- char *in_check_value_char = buf_to_str(in_check_value, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16);
+ char *captured_str, *in_check_value_str;
+ int bits = (num_bits > DEBUG_JTAG_IOZ)
+ ? DEBUG_JTAG_IOZ
+ : num_bits;
- if (in_check_mask)
- {
- char *in_check_mask_char;
- in_check_mask_char = buf_to_str(in_check_mask, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : 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",
- captured_char, in_check_value_char, in_check_mask_char);
- free(in_check_mask_char);
- }
- else
- {
- LOG_WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char);
- }
+ /* NOTE: we've lost diagnostic context here -- 'which tap' */
+
+ captured_str = buf_to_str(captured, bits, 16);
+ in_check_value_str = buf_to_str(in_check_value, bits, 16);
+
+ LOG_WARNING("Bad value '%s' captured during DR or IR scan:",
+ captured_str);
+ LOG_WARNING(" check_value: 0x%s", in_check_value_str);
+
+ free(captured_str);
+ free(in_check_value_str);
- free(captured_char);
- free(in_check_value_char);
+ if (in_check_mask) {
+ char *in_check_mask_str;
- retval = ERROR_JTAG_QUEUE_FAILED;
+ in_check_mask_str = buf_to_str(in_check_mask, bits, 16);
+ LOG_WARNING(" check_mask: 0x%s", in_check_mask_str);
+ free(in_check_mask_str);
}
+ retval = ERROR_JTAG_QUEUE_FAILED;
}
return retval;
}
{
jtag_tap_t *tap = priv;
- LOG_DEBUG("-");
+ LOG_DEBUG("TAP %s event %s", tap->dotted_name,
+ jtag_event_strings[event]);
if (event == JTAG_TRST_ASSERTED)
{
for (unsigned i = 0; i < JTAG_MAX_CHAIN_SIZE; i++)
buf_set_u32(idcode_buffer, i * 32, 32, 0x000000FF);
- jtag_add_plain_dr_scan(1, &field, TAP_RESET);
+ jtag_add_plain_dr_scan(1, &field, TAP_DRPAUSE);
+ jtag_add_tlr();
return jtag_execute_queue();
}
/* If none of the expected ids matched, log an error */
if (ii != tap->expected_ids_cnt)
{
- LOG_INFO("JTAG Tap/device matched");
+ LOG_DEBUG("JTAG Tap/device matched");
return true;
}
jtag_examine_chain_display(LOG_LVL_ERROR, "got",
/* Try to examine chain layout according to IEEE 1149.1 ยง12
*/
-int jtag_examine_chain(void)
+static int jtag_examine_chain(void)
{
uint8_t idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
unsigned device_count = 0;
return ERROR_JTAG_INIT_FAILED;
}
- for (unsigned bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;)
+ for (unsigned bit_count = 0;
+ tap && bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;
+ tap = jtag_tap_next_enabled(tap))
{
uint32_t 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;
+ tap->hasidcode = false;
bit_count += 1;
}
else
{
- /*
+ tap->hasidcode = true;
+
+ /*
* End of chain (invalid manufacturer ID) some devices, such
* as AVR will output all 1's instead of TDI input value at
* end of chain.
tap->idcode = idcode;
// ensure the TAP ID does matches what was expected
- if (!jtag_examine_chain_match_tap(tap))
+ if (!jtag_examine_chain_match_tap(tap))
return ERROR_JTAG_INIT_FAILED;
-
- tap = jtag_tap_next_enabled(tap);
}
/* see if number of discovered devices matches configuration */
field.in_value = ir_test;
- jtag_add_plain_ir_scan(1, &field, TAP_RESET);
- jtag_execute_queue();
+ jtag_add_plain_ir_scan(1, &field, TAP_IRPAUSE);
+ jtag_add_tlr();
+
+ int retval;
+ retval = jtag_execute_queue();
+ if (retval != ERROR_OK)
+ return retval;
tap = NULL;
chain_pos = 0;
}
val = buf_get_u32(ir_test, chain_pos, 2);
- if (val != 0x1)
+ /* Only fail this check if we have IDCODE for this device */
+ if ((val != 0x1)&&(tap->hasidcode))
{
char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
LOG_ERROR("Could not validate JTAG scan chain, IR mismatch, scan returned 0x%s. tap=%s pos=%d expected 0x1 got %0x", cbuf, jtag_tap_name(tap), chain_pos, val);