X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Finterface.c;h=1ed45123f30bc70cdcb079019177bca5dc4c5a3f;hb=ca32f25638408df8a9c18522da43f6e8adcdb5cb;hp=fee1255769ddabcd9900cf7076c1e227f20eb76a;hpb=8b994145b849c40b0a195c3fb332b9770b2f9097;p=openocd.git diff --git a/src/jtag/interface.c b/src/jtag/interface.c index fee1255769..1ed45123f3 100644 --- a/src/jtag/interface.c +++ b/src/jtag/interface.c @@ -73,20 +73,23 @@ tap_state_t tap_get_end_state() int tap_move_ndx(tap_state_t astate) { - /* given a stable state, return the index into the tms_seqs[] array within tap_get_tms_path() */ + /* given a stable state, return the index into the tms_seqs[] + * array within tap_get_tms_path() + */ int ndx; switch (astate) { case TAP_RESET: ndx = 0; break; + case TAP_IDLE: ndx = 1; break; case TAP_DRSHIFT: ndx = 2; break; case TAP_DRPAUSE: ndx = 3; break; - case TAP_IDLE: ndx = 1; break; case TAP_IRSHIFT: ndx = 4; break; case TAP_IRPAUSE: ndx = 5; break; default: - LOG_ERROR("fatal: unstable state \"%s\" used in tap_move_ndx()", tap_state_name(astate)); + LOG_ERROR("FATAL: unstable state \"%s\" in tap_move_ndx()", + tap_state_name(astate)); exit(1); } @@ -95,12 +98,7 @@ int tap_move_ndx(tap_state_t astate) /* tap_move[i][j]: tap movement command to go from state i to state j - * 0: Test-Logic-Reset - * 1: Run-Test/Idle - * 2: Shift-DR - * 3: Pause-DR - * 4: Shift-IR - * 5: Pause-IR + * encodings of i and j are what tap_move_ndx() reports. * * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code */ @@ -108,7 +106,6 @@ struct tms_sequences { uint8_t bits; uint8_t bit_count; - }; /* @@ -133,13 +130,10 @@ static const struct tms_sequences old_tms_seqs[6][6] = /* [from_state_ndx][to_ { /* value clocked to TMS to move from one of six stable states to another. * N.B. OOCD clocks TMS from LSB first, so read these right-to-left. - * N.B. These values are tightly bound to the table in tap_get_tms_path_len(). * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable. * These extra ones cause no TAP state problem, because we go into reset and stay in reset. */ - - /* to state: */ /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ @@ -168,24 +162,33 @@ static const struct tms_sequences short_tms_seqs[6][6] = /* [from_state_ndx][t state specific comments: ------------------------ - *->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to + *->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to work better on ARM9 with ft2232 driver. (Dick) RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing. needed on ARM9 with ft2232 driver. (Dick) + (For a total of *THREE* extra clocks in RESET; NOP.) RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing. needed on ARM9 with ft2232 driver. (Dick) + (For a total of *TWO* extra clocks in RESET; NOP.) + + RESET->* always adds one or more clocks in the target state, + which should be NOPS; except shift states which (as + noted above) add those clocks in RESET. + + The X-to-X transitions always add clocks; from *SHIFT, they go + via IDLE and thus *DO HAVE SIDE EFFECTS* (capture and update). */ /* to state: */ - /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ - { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ - { B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */ - { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */ - { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */ - { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */ - { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1) } /* IRPAUSE */ + /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ + { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */ + { B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */ + { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */ + { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */ + { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */ + { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1)} /* IRPAUSE */ }; @@ -327,43 +330,54 @@ tap_state_t tap_state_transition(tap_state_t cur_state, bool tms) return new_state; } -const char* tap_state_name(tap_state_t state) + +/* NOTE: do not change these state names. They're documented, + * and we rely on them to match SVF input (except for "RUN/IDLE"). + */ +static const struct name_mapping { + enum tap_state symbol; + const char *name; +} tap_name_mapping[] = { + { TAP_RESET, "RESET", }, + { TAP_IDLE, "RUN/IDLE", }, + { TAP_DRSELECT, "DRSELECT", }, + { TAP_DRCAPTURE,"DRCAPTURE", }, + { TAP_DRSHIFT, "DRSHIFT", }, + { TAP_DREXIT1, "DREXIT1", }, + { TAP_DRPAUSE, "DRPAUSE", }, + { TAP_DREXIT2, "DREXIT2", }, + { TAP_DRUPDATE, "DRUPDATE", }, + { TAP_IRSELECT, "IRSELECT", }, + { TAP_IRCAPTURE,"IRCAPTURE", }, + { TAP_IRSHIFT, "IRSHIFT", }, + { TAP_IREXIT1, "IREXIT1", }, + { TAP_IRPAUSE, "IRPAUSE", }, + { TAP_IREXIT2, "IREXIT2", }, + { TAP_IRUPDATE, "IRUPDATE", }, + + /* only for input: accept standard SVF name */ + { TAP_IDLE, "IDLE", }, +}; + +const char *tap_state_name(tap_state_t state) { - const char* ret; + unsigned i; - switch (state) - { - case TAP_RESET: ret = "RESET"; break; - case TAP_IDLE: ret = "RUN/IDLE"; break; - case TAP_DRSELECT: ret = "DRSELECT"; break; - case TAP_DRCAPTURE: ret = "DRCAPTURE"; break; - case TAP_DRSHIFT: ret = "DRSHIFT"; break; - case TAP_DREXIT1: ret = "DREXIT1"; break; - case TAP_DRPAUSE: ret = "DRPAUSE"; break; - case TAP_DREXIT2: ret = "DREXIT2"; break; - case TAP_DRUPDATE: ret = "DRUPDATE"; break; - case TAP_IRSELECT: ret = "IRSELECT"; break; - case TAP_IRCAPTURE: ret = "IRCAPTURE"; break; - case TAP_IRSHIFT: ret = "IRSHIFT"; break; - case TAP_IREXIT1: ret = "IREXIT1"; break; - case TAP_IRPAUSE: ret = "IRPAUSE"; break; - case TAP_IREXIT2: ret = "IREXIT2"; break; - case TAP_IRUPDATE: ret = "IRUPDATE"; break; - default: ret = "???"; + for (i = 0; i < ARRAY_SIZE(tap_name_mapping); i++) { + if (tap_name_mapping[i].symbol == state) + return tap_name_mapping[i].name; } - - return ret; + return "???"; } tap_state_t tap_state_by_name(const char *name) { - tap_state_t x; + unsigned i; - for (x = 0 ; x < TAP_NUM_STATES ; x++) { + for (i = 0; i < ARRAY_SIZE(tap_name_mapping); i++) { /* be nice to the human */ - if (0 == strcasecmp(name, tap_state_name(x))) { - return x; - } + if (strcasecmp(name, tap_name_mapping[i].name) == 0) + return tap_name_mapping[i].symbol; } /* not found */ return TAP_INVALID; @@ -399,7 +413,7 @@ tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, tms_buffer = (const uint8_t *)tms_buf; tdi_buffer = (const uint8_t *)tdi_buf; - tap_bytes = TAP_SCAN_BYTES(tap_bits); + tap_bytes = DIV_ROUND_UP(tap_bits, 8); DEBUG_JTAG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes); tap_out_bits = 0;