X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fxsvf%2Fxsvf.c;h=e7ca5596eaa092cb284b484c9a0ab79f158950cb;hb=503bb08f9993c59a4b3206600555a42fd18459b6;hp=d9b63163037c55a39675e40e82b27bf6c0501425;hpb=d47e1b8f362379d8a2307f49e2b42115a3f40524;p=openocd.git diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c index d9b6316303..e7ca5596ea 100644 --- a/src/xsvf/xsvf.c +++ b/src/xsvf/xsvf.c @@ -2,6 +2,12 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * + * Copyright (C) 2008 Peter Hettkamp * + * peter.hettkamp@htp-tel.de * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -66,6 +72,44 @@ int tap_to_xsvf[] = 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, 0x9, 0xa, 0xb, 0xc, 0xe, 0xf }; + +/* xsvf has it's own definition of a statemove. This needs + * to be handled according to the specs, which has nothing + * to do with the JTAG spec or OpenOCD as such. + * + * Implemented via jtag_add_pathmove(). + */ +void xsvf_add_statemove(enum tap_state state) +{ + enum tap_state moves[7]; /* max # of transitions */ + int i; + enum tap_state curstate = cmd_queue_cur_state; + u8 move = TAP_MOVE(cmd_queue_cur_state, state); + + if ((state != TAP_TLR) && (state == cmd_queue_cur_state)) + return; + + if(state==TAP_TLR) + { + jtag_add_tlr(); + return; + } + for (i=0; i<7; i++) + { + int j = (move >> i) & 1; + if (j) + { + curstate = tap_transitions[curstate].high; + } else + { + curstate = tap_transitions[curstate].low; + } + moves[i] = curstate; + } + + jtag_add_pathmove(7, moves); +} + int xsvf_register_commands(struct command_context_s *cmd_ctx) { register_command(cmd_ctx, NULL, "xsvf", handle_xsvf_command, @@ -125,7 +169,10 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg int runtest_requires_tck = 0; - int device = -1; /* use -1 to indicate a "plain" xsvf file which accounts for additional devices in the scan chain, otherwise the device that should be affected */ + jtag_tap_t *tap = NULL; + /* use NULL to indicate a "plain" xsvf file which accounts for + additional devices in the scan chain, otherwise the device + that should be affected */ if (argc < 2) { @@ -135,7 +182,11 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg if (strcmp(args[0], "plain") != 0) { - device = strtoul(args[0], NULL, 0); + tap = jtag_TapByString( args[0] ); + if( !tap ){ + command_print( cmd_ctx, "Tap: %s unknown", args[0] ); + return ERROR_OK; + } } if ((xsvf_fd = open(args[1], O_RDONLY)) < 0) @@ -178,7 +229,7 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg else { scan_field_t field; - field.device = device; + field.tap = tap; field.num_bits = c; field.out_value = ir_buf; field.out_mask = NULL; @@ -187,7 +238,7 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg field.in_check_mask = NULL; field.in_handler = NULL; field.in_handler_priv = NULL; - if (device == -1) + if (tap == NULL) jtag_add_plain_ir_scan(1, &field, TAP_PI); else jtag_add_ir_scan(1, &field, TAP_PI); @@ -203,13 +254,13 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg jtag_add_runtest(xruntest, xsvf_to_tap[xendir]); else { - jtag_add_statemove(TAP_RTI); + xsvf_add_statemove(TAP_RTI); jtag_add_sleep(xruntest); - jtag_add_statemove(xsvf_to_tap[xendir]); + xsvf_add_statemove(xsvf_to_tap[xendir]); } } else if (xendir != 0xd) /* Pause-IR */ - jtag_add_statemove(xsvf_to_tap[xendir]); + xsvf_add_statemove(xsvf_to_tap[xendir]); } free(ir_buf); } @@ -221,13 +272,13 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg else { scan_field_t field; - field.device = device; + field.tap = tap; field.num_bits = xsdrsize; field.out_value = dr_out_buf; field.out_mask = NULL; field.in_value = NULL; jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL); - if (device == -1) + if (tap == NULL) jtag_add_plain_dr_scan(1, &field, TAP_PD); else jtag_add_dr_scan(1, &field, TAP_PD); @@ -242,13 +293,13 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg jtag_add_runtest(xruntest, xsvf_to_tap[xenddr]); else { - jtag_add_statemove(TAP_RTI); + xsvf_add_statemove(TAP_RTI); jtag_add_sleep(xruntest); - jtag_add_statemove(xsvf_to_tap[xenddr]); + xsvf_add_statemove(xsvf_to_tap[xenddr]); } } else if (xendir != 0x6) /* Pause-DR */ - jtag_add_statemove(xsvf_to_tap[xenddr]); + xsvf_add_statemove(xsvf_to_tap[xenddr]); } break; case 0x04: /* XRUNTEST */ @@ -295,13 +346,13 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg else { scan_field_t field; - field.device = device; + field.tap = tap; field.num_bits = xsdrsize; field.out_value = dr_out_buf; field.out_mask = NULL; field.in_value = NULL; jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL); - if (device == -1) + if (tap == NULL) jtag_add_plain_dr_scan(1, &field, TAP_PD); else jtag_add_dr_scan(1, &field, TAP_PD); @@ -316,13 +367,13 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg jtag_add_runtest(xruntest, xsvf_to_tap[xenddr]); else { - jtag_add_statemove(TAP_RTI); + xsvf_add_statemove(TAP_RTI); jtag_add_sleep(xruntest); - jtag_add_statemove(xsvf_to_tap[xenddr]); + xsvf_add_statemove(xsvf_to_tap[xenddr]); } } else if (xendir != 0x6) /* Pause-DR */ - jtag_add_statemove(xsvf_to_tap[xenddr]); + xsvf_add_statemove(xsvf_to_tap[xenddr]); } } break; @@ -365,7 +416,27 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg do_abort = 1; else { - jtag_add_pathmove(path_len, path); + int i,lasti; + /* here the trick is that jtag_add_pathmove() must end in a stable + state, so we must only invoke jtag_add_tlr() when we absolutely + have to + */ + for(i=0,lasti=0;ilasti) + { + jtag_add_pathmove(i-lasti,path+lasti); + } + lasti=i+1; + jtag_add_tlr(); + } + } + if(i>=lasti) + { + jtag_add_pathmove(i-lasti, path+lasti); + } } free(path); } @@ -418,7 +489,7 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg else { scan_field_t field; - field.device = device; + field.tap = tap; field.num_bits = us; field.out_value = ir_buf; field.out_mask = NULL; @@ -427,7 +498,7 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg field.in_check_mask = NULL; field.in_handler = NULL; field.in_handler_priv = NULL; - if (device == -1) + if (tap == NULL) jtag_add_plain_ir_scan(1, &field, xsvf_to_tap[xendir]); else jtag_add_ir_scan(1, &field, xsvf_to_tap[xendir]); @@ -451,10 +522,10 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg do_abort = 1; else { - jtag_add_statemove(xsvf_to_tap[uc]); + xsvf_add_statemove(xsvf_to_tap[uc]); ui = be_to_h_u32(buf4); jtag_add_sleep(ui); - jtag_add_statemove(xsvf_to_tap[uc2]); + xsvf_add_statemove(xsvf_to_tap[uc2]); } break; default: