diff options
-rw-r--r-- | src/jtag/bitbang.c | 16 | ||||
-rw-r--r-- | src/jtag/ft2232.c | 27 | ||||
-rw-r--r-- | src/jtag/jtag.c | 41 | ||||
-rw-r--r-- | src/jtag/jtag.h | 11 | ||||
-rw-r--r-- | src/xsvf/xsvf.c | 74 |
5 files changed, 122 insertions, 47 deletions
diff --git a/src/jtag/bitbang.c b/src/jtag/bitbang.c index e4191d1..0541600 100644 --- a/src/jtag/bitbang.c +++ b/src/jtag/bitbang.c @@ -38,6 +38,14 @@ #include <unistd.h> +/** + * Function bitbang_stableclocks + * issues a number of clock cycles while staying in a stable state. + * Because the TMS value required to stay in the RESET state is a 1, whereas + * the TMS value required to stay in any of the other stable states is a 0, + * this function checks the current stable state to decide on the value of TMS + * to use. + */ static void bitbang_stableclocks(int num_cycles); @@ -162,13 +170,14 @@ void bitbang_runtest(int num_cycles) static void bitbang_stableclocks(int num_cycles) { + int tms = (cur_state == TAP_RESET ? 1 : 0); int i; /* send num_cycles clocks onto the cable */ for (i = 0; i < num_cycles; i++) { - bitbang_interface->write(1, 0, 0); - bitbang_interface->write(0, 0, 0); + bitbang_interface->write(1, tms, 0); + bitbang_interface->write(0, tms, 0); } } @@ -293,6 +302,9 @@ int bitbang_execute_queue(void) break; case JTAG_STABLECLOCKS: + /* this is only allowed while in a stable state. A check for a stable + * state was done in jtag_add_clocks() + */ bitbang_stableclocks(cmd->cmd.stableclocks->num_cycles); break; diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c index c612502..e63b293 100644 --- a/src/jtag/ft2232.c +++ b/src/jtag/ft2232.c @@ -1415,22 +1415,9 @@ int ft2232_execute_queue() break; case JTAG_STABLECLOCKS: - /* "if (tap_move_map[cur_state] != -1)" is of no help when cur_state==TAP_IDLE */ - switch(cur_state) - { - case TAP_DRSHIFT: - case TAP_IDLE: - case TAP_RESET: - case TAP_DRPAUSE: - case TAP_IRSHIFT: - case TAP_IRPAUSE: - break; /* above stable states are OK */ - default: - LOG_ERROR( "jtag_add_clocks() was called with TAP in non-stable state \"%s\"", - jtag_state_name(cur_state) ); - retval = ERROR_JTAG_QUEUE_FAILED; - } - + /* this is only allowed while in a stable state. A check for a stable + * state was done in jtag_add_clocks() + */ if (ft2232_stableclocks(cmd->cmd.stableclocks->num_cycles, cmd) != ERROR_OK) retval = ERROR_JTAG_QUEUE_FAILED; #ifdef _DEBUG_JTAG_IO_ @@ -2336,11 +2323,15 @@ static int ft2232_stableclocks(int num_cycles, jtag_command_t *cmd) { int retval = 0; + /* 7 bits of either ones or zeros. */ + u8 tms = (cur_state == TAP_RESET ? 0x7F : 0x00); + while (num_cycles > 0) { /* the command 0x4b, "Clock Data to TMS/CS Pin (no Read)" handles * at most 7 bits per invocation. Here we invoke it potentially * several times. + * see: http://www.ftdichip.com/Documents/AppNotes/AN2232C-01_MPSSE_Cmnd.pdf */ int bitcount_per_command = (num_cycles > 7) ? 7 : num_cycles; @@ -2358,8 +2349,8 @@ static int ft2232_stableclocks(int num_cycles, jtag_command_t *cmd) /* scan 7 bit */ BUFFER_ADD = bitcount_per_command - 1; - /* TMS data bits are all zeros to stay in the current stable state */ - BUFFER_ADD = 0x0; + /* TMS data bits are either all zeros or ones to stay in the current stable state */ + BUFFER_ADD = tms; require_send = 1; diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index bbf90e0..4db9961 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -1093,11 +1093,31 @@ void jtag_add_clocks( int num_cycles ) { int retval; - jtag_prelude1(); + /* "if (tap_move_map[cm_queue_cur_state] != -1)" is of no help when cur_state==TAP_IDLE */ + switch(cmd_queue_cur_state) + { + case TAP_DRSHIFT: + case TAP_IDLE: + case TAP_RESET: + case TAP_DRPAUSE: + case TAP_IRSHIFT: + case TAP_IRPAUSE: + break; /* above stable states are OK */ + default: + LOG_ERROR( "jtag_add_clocks() was called with TAP in non-stable state \"%s\"", + jtag_state_name(cmd_queue_cur_state) ); + jtag_error = ERROR_JTAG_NOT_STABLE_STATE; + return; + } - retval=interface_jtag_add_clocks(num_cycles); - if (retval!=ERROR_OK) - jtag_error=retval; + if( num_cycles > 0 ) + { + jtag_prelude1(); + + retval=interface_jtag_add_clocks(num_cycles); + if (retval!=ERROR_OK) + jtag_error=retval; + } } void jtag_add_reset(int req_tlr_or_trst, int req_srst) @@ -1287,7 +1307,7 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer) if (cmd->fields[i].out_value) { #ifdef _DEBUG_JTAG_IO_ - char* char_buf = buf_to_str(cmd->fields[i].out_value, (cmd->fields[i].num_bits > 64) ? 64 : cmd->fields[i].num_bits, 16); + char* char_buf = buf_to_str(cmd->fields[i].out_value, (cmd->fields[i].num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : cmd->fields[i].num_bits, 16); #endif buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits); #ifdef _DEBUG_JTAG_IO_ @@ -1297,9 +1317,6 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer) } bit_count += cmd->fields[i].num_bits; -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("bit_count totalling: %i", bit_count ); -#endif } return bit_count; @@ -1325,7 +1342,7 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits); #ifdef _DEBUG_JTAG_IO_ - char *char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); + char *char_buf = buf_to_str(captured, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16); LOG_DEBUG("fields[%i].in_value[%i]: 0x%s", i, num_bits, char_buf); free(char_buf); #endif @@ -1391,13 +1408,13 @@ int jtag_check_value(u8 *captured, void *priv, scan_field_t *field) jtag_tap_name(field->tap)); if (compare_failed) { - char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); - char *in_check_value_char = buf_to_str(field->in_check_value, (num_bits > 64) ? 64 : num_bits, 16); + 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(field->in_check_value, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16); if (field->in_check_mask) { char *in_check_mask_char; - in_check_mask_char = buf_to_str(field->in_check_mask, (num_bits > 64) ? 64 : num_bits, 16); + in_check_mask_char = buf_to_str(field->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); diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index cc3c9f0..815035a 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -34,6 +34,11 @@ #define _DEBUG_JTAG_IO_ #endif +#ifndef DEBUG_JTAG_IOZ +#define DEBUG_JTAG_IOZ 64 +#endif + + /* 16 Tap States, from page 21 of ASSET InterTech, Inc.'s svf.pdf */ typedef enum tap_state @@ -499,12 +504,14 @@ void jtag_tap_handle_event( jtag_tap_t * tap, enum jtag_tap_event e); * JTAG subsystem uses codes between -100 and -199 */ #define ERROR_JTAG_INIT_FAILED (-100) -#define ERROR_JTAG_INVALID_INTERFACE (-101) +#define ERROR_JTAG_INVALID_INTERFACE (-101) #define ERROR_JTAG_NOT_IMPLEMENTED (-102) -#define ERROR_JTAG_TRST_ASSERTED (-103) +#define ERROR_JTAG_TRST_ASSERTED (-103) #define ERROR_JTAG_QUEUE_FAILED (-104) +#define ERROR_JTAG_NOT_STABLE_STATE (-105) #define ERROR_JTAG_DEVICE_ERROR (-107) + /* this allows JTAG devices to implement the entire jtag_xxx() layer in hw/sw */ #ifdef HAVE_JTAG_MINIDRIVER_H /* Here a #define MINIDRIVER() and an inline version of hw fifo interface_jtag_add_dr_out can be defined */ diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c index 1bcc5d0..d69c1a9 100644 --- a/src/xsvf/xsvf.c +++ b/src/xsvf/xsvf.c @@ -107,6 +107,7 @@ LSDR 1 TDI (0) #define LCOUNT 0x19 #define LDELAY 0x1A #define LSDR 0x1B +#define XTRST 0x1C /* XSVF valid state values for the XSTATE command, from appendix B of xapp503.pdf */ @@ -127,6 +128,11 @@ LSDR 1 TDI (0) #define XSV_IREXIT2 0x0E #define XSV_IRUPDATE 0x0F +/* arguments to XTRST */ +#define XTRST_ON 0 +#define XTRST_OFF 1 +#define XTRST_Z 2 +#define XTRST_ABSENT 3 #define XSTATE_MAX_PATH 12 @@ -210,7 +216,7 @@ static void xsvf_add_statemove(tap_state_t state) int xsvf_register_commands(struct command_context_s *cmd_ctx) { register_command(cmd_ctx, NULL, "xsvf", handle_xsvf_command, - COMMAND_EXEC, "run xsvf <file> [virt2]"); + COMMAND_EXEC, "run xsvf <file> [virt2] [quiet]"); return ERROR_OK; } @@ -288,6 +294,8 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha int unsupported = 0; int tdo_mismatch = 0; int result; + int verbose = 1; + char* filename; int runtest_requires_tck = 0; /* a flag telling whether to clock TCK during waits, or simply sleep, controled by virt2 */ @@ -300,10 +308,12 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha if (argc < 2) { - command_print(cmd_ctx, "usage: xsvf <device#|plain> <file> <variant>"); + command_print(cmd_ctx, "usage: xsvf <device#|plain> <file> [<variant>] [quiet]"); return ERROR_FAIL; } + filename = args[1]; /* we mess with args starting point below, snapshot filename here */ + if (strcmp(args[0], "plain") != 0) { tap = jtag_TapByString( args[0] ); @@ -314,9 +324,9 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha } } - if ((xsvf_fd = open(args[1], O_RDONLY)) < 0) + if ((xsvf_fd = open(filename, O_RDONLY)) < 0) { - command_print(cmd_ctx, "file \"%s\" not found", args[1]); + command_print(cmd_ctx, "file \"%s\" not found", filename); return ERROR_FAIL; } @@ -324,9 +334,16 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha if ((argc > 2) && (strcmp(args[2], "virt2") == 0)) { runtest_requires_tck = 1; + --argc; + ++args; + } + + if ((argc > 2) && (strcmp(args[2], "quiet") == 0)) + { + verbose = 0; } - LOG_USER("xsvf processing file: \"%s\"", args[1]); + LOG_USER("xsvf processing file: \"%s\"", filename); while( read(xsvf_fd, &opcode, 1) > 0 ) { @@ -462,7 +479,8 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha jtag_add_pathmove( sizeof(exception_path)/sizeof(exception_path[0]), exception_path); - LOG_USER("%s %d retry %d", op_name, xsdrsize, attempt); + if (verbose) + LOG_USER("%s %d retry %d", op_name, xsdrsize, attempt); } field.tap = tap; @@ -749,7 +767,8 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha } while (uc != 0); comment[sizeof(comment)-1] = 0; /* regardless, terminate */ - LOG_USER(comment); + if (verbose) + LOG_USER(comment); } break; @@ -918,20 +937,24 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha { scan_field_t field; + xsvf_add_statemove( loop_state ); + jtag_add_clocks(loop_clocks); + jtag_add_sleep(loop_usecs); + field.tap = tap; field.num_bits = xsdrsize; field.out_value = dr_out_buf; field.out_mask = NULL; field.in_value = NULL; - if (attempt > 0) + if (attempt > 0 && verbose) LOG_USER("LSDR retry %d", attempt); jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL); if (tap == NULL) - jtag_add_plain_dr_scan(1, &field, loop_state); + jtag_add_plain_dr_scan(1, &field, TAP_DRPAUSE); else - jtag_add_dr_scan(1, &field, loop_state); + jtag_add_dr_scan(1, &field, TAP_DRPAUSE); /* LOG_DEBUG("FLUSHING QUEUE"); */ result = jtag_execute_queue(); @@ -940,9 +963,6 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha matched = 1; break; } - - jtag_add_clocks(loop_clocks); - jtag_add_sleep(loop_usecs); } if (!matched ) @@ -954,6 +974,34 @@ static int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, cha } break; + case XTRST: + { + u8 trst_mode; + + if (read(xsvf_fd, &trst_mode, 1) < 0) + { + do_abort = 1; + break; + } + + switch( trst_mode ) + { + case XTRST_ON: + jtag_add_reset(1, 0); + break; + case XTRST_OFF: + case XTRST_Z: + jtag_add_reset(0, 0); + break; + case XTRST_ABSENT: + break; + default: + LOG_ERROR( "XTRST mode argument (0x%02X) out of range", trst_mode ); + do_abort = 1; + } + } + break; + default: LOG_ERROR("unknown xsvf command (0x%02X)\n", uc); unsupported = 1; |