Skip to content

Commit 1fa4c72

Browse files
nattgrispaulfertser
authored andcommitted
jtag: Rewrite TAP verification/auto-probe logic
Enable auto-creating additional discovered TAPs even if some TAPs are predefined, avoiding initialization failure when it's not necessary. Also, drop the arbitrary limit on the number of predefined TAPs. Still, don't auto-create any if there are more than 20 TAPs already, to stop a noisy connection from creating unlimited TAPs. Create auto-probed TAPs with less noise. Reduce code duplication between verification and auto-probing. Change-Id: I82a504d92dbcc0060206e71f10c5158256b5f561 Signed-off-by: Andreas Fritiofson <[email protected]> Reviewed-on: http://openocd.zylin.com/2236 Tested-by: jenkins Reviewed-by: Paul Fertser <[email protected]>
1 parent 24fb042 commit 1fa4c72

File tree

1 file changed

+76
-106
lines changed

1 file changed

+76
-106
lines changed

src/jtag/core.c

Lines changed: 76 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -886,11 +886,7 @@ void jtag_sleep(uint32_t us)
886886
alive_sleep((us+999)/1000);
887887
}
888888

889-
/* Maximum number of enabled JTAG devices we expect in the scan chain,
890-
* plus one (to detect garbage at the end). Devices that don't support
891-
* IDCODE take up fewer bits, possibly allowing a few more devices.
892-
*/
893-
#define JTAG_MAX_CHAIN_SIZE 20
889+
#define JTAG_MAX_AUTO_TAPS 20
894890

895891
#define EXTRACT_MFG(X) (((X) & 0xffe) >> 1)
896892
#define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)
@@ -913,7 +909,7 @@ static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcod
913909
};
914910

915911
/* initialize to the end of chain ID value */
916-
for (unsigned i = 0; i < JTAG_MAX_CHAIN_SIZE; i++)
912+
for (unsigned i = 0; i < num_idcode; i++)
917913
buf_set_u32(idcode_buffer, i * 32, 32, END_OF_CHAIN_FLAG);
918914

919915
jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value, TAP_DRPAUSE);
@@ -998,21 +994,16 @@ static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned ma
998994

999995
static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
1000996
{
1001-
uint32_t idcode = tap->idcode;
1002997

1003-
/* ignore expected BYPASS codes; warn otherwise */
1004-
if (0 == tap->expected_ids_cnt && !idcode)
998+
if (tap->expected_ids_cnt == 0 || !tap->hasidcode)
1005999
return true;
10061000

10071001
/* optionally ignore the JTAG version field - bits 28-31 of IDCODE */
10081002
uint32_t mask = tap->ignore_version ? ~(0xf << 28) : ~0;
1009-
1010-
idcode &= mask;
1003+
uint32_t idcode = tap->idcode & mask;
10111004

10121005
/* Loop over the expected identification codes and test for a match */
1013-
unsigned ii, limit = tap->expected_ids_cnt;
1014-
1015-
for (ii = 0; ii < limit; ii++) {
1006+
for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {
10161007
uint32_t expected = tap->expected_ids[ii] & mask;
10171008

10181009
if (idcode == expected)
@@ -1026,10 +1017,10 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
10261017
/* If none of the expected ids matched, warn */
10271018
jtag_examine_chain_display(LOG_LVL_WARNING, "UNEXPECTED",
10281019
tap->dotted_name, tap->idcode);
1029-
for (ii = 0; ii < limit; ii++) {
1020+
for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {
10301021
char msg[32];
10311022

1032-
snprintf(msg, sizeof(msg), "expected %u of %u", ii + 1, limit);
1023+
snprintf(msg, sizeof(msg), "expected %u of %u", ii + 1, tap->expected_ids_cnt);
10331024
jtag_examine_chain_display(LOG_LVL_ERROR, msg,
10341025
tap->dotted_name, tap->expected_ids[ii]);
10351026
}
@@ -1041,130 +1032,108 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
10411032
*/
10421033
static int jtag_examine_chain(void)
10431034
{
1044-
uint8_t idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
1045-
unsigned bit_count;
10461035
int retval;
1047-
int tapcount = 0;
1048-
bool autoprobe = false;
1036+
unsigned max_taps = jtag_tap_count();
1037+
1038+
/* Autoprobe up to this many. */
1039+
if (max_taps < JTAG_MAX_AUTO_TAPS)
1040+
max_taps = JTAG_MAX_AUTO_TAPS;
1041+
1042+
/* Add room for end-of-chain marker. */
1043+
max_taps++;
1044+
1045+
uint8_t *idcode_buffer = malloc(max_taps * 4);
1046+
if (idcode_buffer == NULL)
1047+
return ERROR_JTAG_INIT_FAILED;
10491048

10501049
/* DR scan to collect BYPASS or IDCODE register contents.
10511050
* Then make sure the scan data has both ones and zeroes.
10521051
*/
10531052
LOG_DEBUG("DR scan interrogation for IDCODE/BYPASS");
1054-
retval = jtag_examine_chain_execute(idcode_buffer, JTAG_MAX_CHAIN_SIZE);
1053+
retval = jtag_examine_chain_execute(idcode_buffer, max_taps);
10551054
if (retval != ERROR_OK)
1056-
return retval;
1057-
if (!jtag_examine_chain_check(idcode_buffer, JTAG_MAX_CHAIN_SIZE))
1058-
return ERROR_JTAG_INIT_FAILED;
1055+
goto out;
1056+
if (!jtag_examine_chain_check(idcode_buffer, max_taps)) {
1057+
retval = ERROR_JTAG_INIT_FAILED;
1058+
goto out;
1059+
}
10591060

1060-
/* point at the 1st tap */
1061+
/* Point at the 1st predefined tap, if any */
10611062
struct jtag_tap *tap = jtag_tap_next_enabled(NULL);
10621063

1063-
if (!tap)
1064-
autoprobe = true;
1065-
1066-
for (bit_count = 0;
1067-
tap && bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;
1068-
tap = jtag_tap_next_enabled(tap)) {
1064+
unsigned bit_count = 0;
1065+
unsigned autocount = 0;
1066+
for (unsigned i = 0; i < max_taps; i++) {
1067+
assert(bit_count < max_taps * 32);
10691068
uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32);
10701069

1070+
/* No predefined TAP? Auto-probe. */
1071+
if (tap == NULL) {
1072+
/* Is there another TAP? */
1073+
if (jtag_idcode_is_final(idcode))
1074+
break;
1075+
1076+
/* Default everything in this TAP except IR length.
1077+
*
1078+
* REVISIT create a jtag_alloc(chip, tap) routine, and
1079+
* share it with jim_newtap_cmd().
1080+
*/
1081+
tap = calloc(1, sizeof *tap);
1082+
if (!tap) {
1083+
retval = ERROR_FAIL;
1084+
goto out;
1085+
}
1086+
1087+
tap->chip = alloc_printf("auto%u", autocount++);
1088+
tap->tapname = strdup("tap");
1089+
tap->dotted_name = alloc_printf("%s.%s", tap->chip, tap->tapname);
1090+
1091+
tap->ir_length = 0; /* ... signifying irlen autoprobe */
1092+
tap->ir_capture_mask = 0x03;
1093+
tap->ir_capture_value = 0x01;
1094+
1095+
tap->enabled = true;
1096+
1097+
jtag_tap_init(tap);
1098+
}
1099+
10711100
if ((idcode & 1) == 0) {
10721101
/* Zero for LSB indicates a device in bypass */
1073-
LOG_INFO("TAP %s does not have IDCODE",
1074-
tap->dotted_name);
1075-
idcode = 0;
1102+
LOG_INFO("TAP %s does not have IDCODE", tap->dotted_name);
10761103
tap->hasidcode = false;
1104+
tap->idcode = 0;
10771105

10781106
bit_count += 1;
10791107
} else {
10801108
/* Friendly devices support IDCODE */
10811109
tap->hasidcode = true;
1082-
jtag_examine_chain_display(LOG_LVL_INFO,
1083-
"tap/device found",
1084-
tap->dotted_name, idcode);
1110+
tap->idcode = idcode;
1111+
jtag_examine_chain_display(LOG_LVL_INFO, "tap/device found", tap->dotted_name, idcode);
10851112

10861113
bit_count += 32;
10871114
}
1088-
tap->idcode = idcode;
10891115

10901116
/* ensure the TAP ID matches what was expected */
10911117
if (!jtag_examine_chain_match_tap(tap))
10921118
retval = ERROR_JTAG_INIT_SOFT_FAIL;
1093-
}
1094-
1095-
/* Fail if too many TAPs were enabled for us to verify them all. */
1096-
if (tap) {
1097-
LOG_ERROR("Too many TAPs enabled; '%s' ignored.",
1098-
tap->dotted_name);
1099-
return ERROR_JTAG_INIT_FAILED;
1100-
}
11011119

1102-
/* if autoprobing, the tap list is still empty ... populate it! */
1103-
while (autoprobe && bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31) {
1104-
uint32_t idcode;
1105-
char buf[12];
1106-
1107-
/* Is there another TAP? */
1108-
idcode = buf_get_u32(idcode_buffer, bit_count, 32);
1109-
if (jtag_idcode_is_final(idcode))
1110-
break;
1111-
1112-
/* Default everything in this TAP except IR length.
1113-
*
1114-
* REVISIT create a jtag_alloc(chip, tap) routine, and
1115-
* share it with jim_newtap_cmd().
1116-
*/
1117-
tap = calloc(1, sizeof *tap);
1118-
if (!tap)
1119-
return ERROR_FAIL;
1120-
1121-
sprintf(buf, "auto%d", tapcount++);
1122-
tap->chip = strdup(buf);
1123-
tap->tapname = strdup("tap");
1124-
1125-
sprintf(buf, "%s.%s", tap->chip, tap->tapname);
1126-
tap->dotted_name = strdup(buf);
1127-
1128-
/* tap->ir_length == 0 ... signifying irlen autoprobe */
1129-
tap->ir_capture_mask = 0x03;
1130-
tap->ir_capture_value = 0x01;
1131-
1132-
tap->enabled = true;
1133-
1134-
if ((idcode & 1) == 0) {
1135-
bit_count += 1;
1136-
tap->hasidcode = false;
1137-
} else {
1138-
bit_count += 32;
1139-
tap->hasidcode = true;
1140-
tap->idcode = idcode;
1141-
1142-
tap->expected_ids_cnt = 1;
1143-
tap->expected_ids = malloc(sizeof(uint32_t));
1144-
tap->expected_ids[0] = idcode;
1145-
}
1146-
1147-
LOG_WARNING("AUTO %s - use \"jtag newtap "
1148-
"%s %s -expected-id 0x%8.8" PRIx32 " ...\"",
1149-
tap->dotted_name, tap->chip, tap->tapname,
1150-
tap->idcode);
1151-
1152-
jtag_tap_init(tap);
1120+
tap = jtag_tap_next_enabled(tap);
11531121
}
11541122

11551123
/* After those IDCODE or BYPASS register values should be
11561124
* only the data we fed into the scan chain.
11571125
*/
1158-
if (jtag_examine_chain_end(idcode_buffer, bit_count,
1159-
8 * sizeof(idcode_buffer))) {
1160-
LOG_ERROR("double-check your JTAG setup (interface, "
1161-
"speed, missing TAPs, ...)");
1162-
return ERROR_JTAG_INIT_FAILED;
1126+
if (jtag_examine_chain_end(idcode_buffer, bit_count, max_taps * 32)) {
1127+
LOG_ERROR("double-check your JTAG setup (interface, speed, ...)");
1128+
retval = ERROR_JTAG_INIT_FAILED;
1129+
goto out;
11631130
}
11641131

11651132
/* Return success or, for backwards compatibility if only
11661133
* some IDCODE values mismatched, a soft/continuable fault.
11671134
*/
1135+
out:
1136+
free(idcode_buffer);
11681137
return retval;
11691138
}
11701139

@@ -1227,7 +1196,7 @@ static int jtag_validate_ircapture(void)
12271196
* least two bits. Guessing will fail if (a) any TAP does
12281197
* not conform to the JTAG spec; or (b) when the upper bits
12291198
* captured from some conforming TAP are nonzero. Or if
1230-
* (c) an IR length is longer than 32 bits -- which is only
1199+
* (c) an IR length is longer than JTAG_IRLEN_MAX bits,
12311200
* an implementation limit, which could someday be raised.
12321201
*
12331202
* REVISIT optimization: if there's a *single* TAP we can
@@ -1242,11 +1211,12 @@ static int jtag_validate_ircapture(void)
12421211
if (tap->ir_length == 0) {
12431212
tap->ir_length = 2;
12441213
while ((val = buf_get_u64(ir_test, chain_pos, tap->ir_length + 1)) == 1
1245-
&& tap->ir_length <= 64) {
1214+
&& tap->ir_length < JTAG_IRLEN_MAX) {
12461215
tap->ir_length++;
12471216
}
1248-
LOG_WARNING("AUTO %s - use \"... -irlen %d\"",
1249-
jtag_tap_name(tap), tap->ir_length);
1217+
LOG_WARNING("AUTO %s - use \"jtag newtap " "%s %s -irlen %d "
1218+
"-expected-id 0x%08" PRIx32 "\"",
1219+
tap->dotted_name, tap->chip, tap->tapname, tap->ir_length, tap->idcode);
12501220
}
12511221

12521222
/* Validate the two LSBs, which must be 01 per JTAG spec.

0 commit comments

Comments
 (0)