1 /***************************************************************************
2 * Copyright (C) 2009 by Simon Qian *
3 * SimonQian@SimonQian.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
21 /* The specification for SVF is available here:
22 * http://www.asset-intertech.com/support/svf.pdf
23 * Below, this document is refered to as the "SVF spec".
25 * The specification for XSVF is available here:
26 * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf
27 * Below, this document is refered to as the "XSVF spec".
34 #include <jtag/jtag.h>
36 #include <helper/time_support.h>
56 static const char *svf_command_name
[14] = {
80 static const char *svf_trst_mode_name
[4] = {
87 struct svf_statemove
{
90 uint32_t num_of_moves
;
95 * These paths are from the SVF specification for the STATE command, to be
96 * used when the STATE command only includes the final state. The first
97 * element of the path is the "from" (current) state, and the last one is
98 * the "to" (target) state.
100 * All specified paths are the shortest ones in the JTAG spec, and are thus
101 * not (!!) exact matches for the paths used elsewhere in OpenOCD. Note
102 * that PAUSE-to-PAUSE transitions all go through UPDATE and then CAPTURE,
103 * which has specific effects on the various registers; they are not NOPs.
105 * Paths to RESET are disabled here. As elsewhere in OpenOCD, and in XSVF
106 * and many SVF implementations, we don't want to risk missing that state.
107 * To get to RESET, always we ignore the current state.
109 static const struct svf_statemove svf_statemoves
[] = {
110 /* from to num_of_moves, paths[8] */
111 /* {TAP_RESET, TAP_RESET, 1, {TAP_RESET}}, */
112 {TAP_RESET
, TAP_IDLE
, 2, {TAP_RESET
, TAP_IDLE
} },
113 {TAP_RESET
, TAP_DRPAUSE
, 6, {TAP_RESET
, TAP_IDLE
, TAP_DRSELECT
,
114 TAP_DRCAPTURE
, TAP_DREXIT1
, TAP_DRPAUSE
} },
115 {TAP_RESET
, TAP_IRPAUSE
, 7, {TAP_RESET
, TAP_IDLE
, TAP_DRSELECT
,
116 TAP_IRSELECT
, TAP_IRCAPTURE
,
117 TAP_IREXIT1
, TAP_IRPAUSE
} },
119 /* {TAP_IDLE, TAP_RESET, 4, {TAP_IDLE,
120 * TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
121 {TAP_IDLE
, TAP_IDLE
, 1, {TAP_IDLE
} },
122 {TAP_IDLE
, TAP_DRPAUSE
, 5, {TAP_IDLE
, TAP_DRSELECT
, TAP_DRCAPTURE
,
123 TAP_DREXIT1
, TAP_DRPAUSE
} },
124 {TAP_IDLE
, TAP_IRPAUSE
, 6, {TAP_IDLE
, TAP_DRSELECT
, TAP_IRSELECT
,
125 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} },
127 /* {TAP_DRPAUSE, TAP_RESET, 6, {TAP_DRPAUSE,
128 * TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
129 {TAP_DRPAUSE
, TAP_IDLE
, 4, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
131 {TAP_DRPAUSE
, TAP_DRPAUSE
, 7, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
132 TAP_DRSELECT
, TAP_DRCAPTURE
,
133 TAP_DREXIT1
, TAP_DRPAUSE
} },
134 {TAP_DRPAUSE
, TAP_IRPAUSE
, 8, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
135 TAP_DRSELECT
, TAP_IRSELECT
,
136 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} },
138 /* {TAP_IRPAUSE, TAP_RESET, 6, {TAP_IRPAUSE,
139 * TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
140 {TAP_IRPAUSE
, TAP_IDLE
, 4, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
142 {TAP_IRPAUSE
, TAP_DRPAUSE
, 7, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
143 TAP_DRSELECT
, TAP_DRCAPTURE
,
144 TAP_DREXIT1
, TAP_DRPAUSE
} },
145 {TAP_IRPAUSE
, TAP_IRPAUSE
, 8, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
146 TAP_DRSELECT
, TAP_IRSELECT
,
147 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} }
150 #define XXR_TDI (1 << 0)
151 #define XXR_TDO (1 << 1)
152 #define XXR_MASK (1 << 2)
153 #define XXR_SMASK (1 << 3)
154 struct svf_xxr_para
{
165 tap_state_t ir_end_state
;
166 tap_state_t dr_end_state
;
167 tap_state_t runtest_run_state
;
168 tap_state_t runtest_end_state
;
169 enum trst_mode trst_mode
;
171 struct svf_xxr_para hir_para
;
172 struct svf_xxr_para hdr_para
;
173 struct svf_xxr_para tir_para
;
174 struct svf_xxr_para tdr_para
;
175 struct svf_xxr_para sir_para
;
176 struct svf_xxr_para sdr_para
;
179 static struct svf_para svf_para
;
180 static const struct svf_para svf_para_init
= {
181 /* frequency, ir_end_state, dr_end_state, runtest_run_state, runtest_end_state, trst_mode */
182 0, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TRST_Z
,
184 /* {len, data_mask, tdi, tdo, mask, smask}, */
185 {0, 0, NULL
, NULL
, NULL
, NULL
},
187 /* {len, data_mask, tdi, tdo, mask, smask}, */
188 {0, 0, NULL
, NULL
, NULL
, NULL
},
190 /* {len, data_mask, tdi, tdo, mask, smask}, */
191 {0, 0, NULL
, NULL
, NULL
, NULL
},
193 /* {len, data_mask, tdi, tdo, mask, smask}, */
194 {0, 0, NULL
, NULL
, NULL
, NULL
},
196 /* {len, data_mask, tdi, tdo, mask, smask}, */
197 {0, 0, NULL
, NULL
, NULL
, NULL
},
199 /* {len, data_mask, tdi, tdo, mask, smask}, */
200 {0, 0, NULL
, NULL
, NULL
, NULL
},
203 struct svf_check_tdo_para
{
204 int line_num
; /* used to record line number of the check operation */
205 /* so more information could be printed */
206 int enabled
; /* check is enabled or not */
207 int buffer_offset
; /* buffer_offset to buffers */
208 int bit_len
; /* bit length to check */
211 #define SVF_CHECK_TDO_PARA_SIZE 1024
212 static struct svf_check_tdo_para
*svf_check_tdo_para
;
213 static int svf_check_tdo_para_index
;
215 static int svf_read_command_from_file(FILE *fd
);
216 static int svf_check_tdo(void);
217 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
);
218 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
);
219 static int svf_execute_tap(void);
222 static char *svf_read_line
;
223 static size_t svf_read_line_size
;
224 static char *svf_command_buffer
;
225 static size_t svf_command_buffer_size
;
226 static int svf_line_number
= 1;
227 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
);
229 #define SVF_MAX_BUFFER_SIZE_TO_COMMIT (1024 * 1024)
230 static uint8_t *svf_tdi_buffer
, *svf_tdo_buffer
, *svf_mask_buffer
;
231 static int svf_buffer_index
, svf_buffer_size
;
232 static int svf_quiet
;
234 static int svf_ignore_error
;
236 /* Targetting particular tap */
237 static int svf_tap_is_specified
;
238 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
);
240 /* Progress Indicator */
241 static int svf_progress_enabled
;
242 static long svf_total_lines
;
243 static int svf_percentage
;
244 static int svf_last_printed_percentage
= -1;
247 * macro is used to print the svf hex buffer at desired debug level
248 * DEBUG, INFO, ERROR, USER
250 #define SVF_BUF_LOG(_lvl, _buf, _nbits, _desc) \
251 svf_hexbuf_print(LOG_LVL_##_lvl , __FILE__, __LINE__, __func__, _buf, _nbits, _desc)
253 static void svf_hexbuf_print(int dbg_lvl
, const char *file
, unsigned line
,
254 const char *function
, const uint8_t *buf
,
255 int bit_len
, const char *desc
)
258 int byte_len
= DIV_ROUND_UP(bit_len
, 8);
259 int msbits
= bit_len
% 8;
261 /* allocate 2 bytes per hex digit */
262 char *prbuf
= malloc((byte_len
* 2) + 1);
266 /* print correct number of bytes, mask excess bits where applicable */
267 uint8_t msb
= buf
[byte_len
- 1] & (msbits
? (1 << msbits
) - 1 : 0xff);
268 len
= sprintf(prbuf
, msbits
<= 4 ? "0x%01"PRIx8
: "0x%02"PRIx8
, msb
);
269 for (j
= byte_len
- 2; j
>= 0; j
--)
270 len
+= sprintf(prbuf
+ len
, "%02"PRIx8
, buf
[j
]);
272 log_printf_lf(dbg_lvl
, file
, line
, function
, "%8s = %s", desc
? desc
: " ", prbuf
);
277 static int svf_realloc_buffers(size_t len
)
281 if (svf_execute_tap() != ERROR_OK
)
284 ptr
= realloc(svf_tdi_buffer
, len
);
287 svf_tdi_buffer
= ptr
;
289 ptr
= realloc(svf_tdo_buffer
, len
);
292 svf_tdo_buffer
= ptr
;
294 ptr
= realloc(svf_mask_buffer
, len
);
297 svf_mask_buffer
= ptr
;
299 svf_buffer_size
= len
;
304 static void svf_free_xxd_para(struct svf_xxr_para
*para
)
307 if (para
->tdi
!= NULL
) {
311 if (para
->tdo
!= NULL
) {
315 if (para
->mask
!= NULL
) {
319 if (para
->smask
!= NULL
) {
326 int svf_add_statemove(tap_state_t state_to
)
328 tap_state_t state_from
= cmd_queue_cur_state
;
331 /* when resetting, be paranoid and ignore current state */
332 if (state_to
== TAP_RESET
) {
340 for (index_var
= 0; index_var
< ARRAY_SIZE(svf_statemoves
); index_var
++) {
341 if ((svf_statemoves
[index_var
].from
== state_from
)
342 && (svf_statemoves
[index_var
].to
== state_to
)) {
345 /* recorded path includes current state ... avoid
347 if (svf_statemoves
[index_var
].num_of_moves
> 1)
348 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
- 1,
349 svf_statemoves
[index_var
].paths
+ 1);
351 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
,
352 svf_statemoves
[index_var
].paths
);
356 LOG_ERROR("SVF: can not move to %s", tap_state_name(state_to
));
360 COMMAND_HANDLER(handle_svf_command
)
362 #define SVF_MIN_NUM_OF_OPTIONS 1
363 #define SVF_MAX_NUM_OF_OPTIONS 5
366 long long time_measure_ms
;
367 int time_measure_s
, time_measure_m
;
369 /* use NULL to indicate a "plain" svf file which accounts for
370 * any additional devices in the scan chain, otherwise the device
371 * that should be affected
373 struct jtag_tap
*tap
= NULL
;
375 if ((CMD_ARGC
< SVF_MIN_NUM_OF_OPTIONS
) || (CMD_ARGC
> SVF_MAX_NUM_OF_OPTIONS
))
376 return ERROR_COMMAND_SYNTAX_ERROR
;
378 /* parse command line */
381 svf_ignore_error
= 0;
382 for (unsigned int i
= 0; i
< CMD_ARGC
; i
++) {
383 if (strcmp(CMD_ARGV
[i
], "-tap") == 0) {
384 tap
= jtag_tap_by_string(CMD_ARGV
[i
+1]);
386 command_print(CMD_CTX
, "Tap: %s unknown", CMD_ARGV
[i
+1]);
390 } else if ((strcmp(CMD_ARGV
[i
],
391 "quiet") == 0) || (strcmp(CMD_ARGV
[i
], "-quiet") == 0))
393 else if ((strcmp(CMD_ARGV
[i
], "nil") == 0) || (strcmp(CMD_ARGV
[i
], "-nil") == 0))
395 else if ((strcmp(CMD_ARGV
[i
],
396 "progress") == 0) || (strcmp(CMD_ARGV
[i
], "-progress") == 0))
397 svf_progress_enabled
= 1;
398 else if ((strcmp(CMD_ARGV
[i
],
399 "ignore_error") == 0) || (strcmp(CMD_ARGV
[i
], "-ignore_error") == 0))
400 svf_ignore_error
= 1;
402 svf_fd
= fopen(CMD_ARGV
[i
], "r");
403 if (svf_fd
== NULL
) {
405 command_print(CMD_CTX
, "open(\"%s\"): %s", CMD_ARGV
[i
], strerror(err
));
406 /* no need to free anything now */
407 return ERROR_COMMAND_SYNTAX_ERROR
;
409 LOG_USER("svf processing file: \"%s\"", CMD_ARGV
[i
]);
414 return ERROR_COMMAND_SYNTAX_ERROR
;
417 time_measure_ms
= timeval_ms();
421 svf_command_buffer_size
= 0;
423 svf_check_tdo_para_index
= 0;
424 svf_check_tdo_para
= malloc(sizeof(struct svf_check_tdo_para
) * SVF_CHECK_TDO_PARA_SIZE
);
425 if (NULL
== svf_check_tdo_para
) {
426 LOG_ERROR("not enough memory");
431 svf_buffer_index
= 0;
432 /* double the buffer size */
433 /* in case current command cannot be committed, and next command is a bit scan command */
434 /* here is 32K bits for this big scan command, it should be enough */
435 /* buffer will be reallocated if buffer size is not enough */
436 if (svf_realloc_buffers(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT
) != ERROR_OK
) {
441 memcpy(&svf_para
, &svf_para_init
, sizeof(svf_para
));
449 /* Tap is specified, set header/trailer paddings */
450 int header_ir_len
= 0, header_dr_len
= 0, trailer_ir_len
= 0, trailer_dr_len
= 0;
451 struct jtag_tap
*check_tap
;
453 svf_tap_is_specified
= 1;
455 for (check_tap
= jtag_all_taps(); check_tap
; check_tap
= check_tap
->next_tap
) {
456 if (check_tap
->abs_chain_position
< tap
->abs_chain_position
) {
458 header_ir_len
+= check_tap
->ir_length
;
460 } else if (check_tap
->abs_chain_position
> tap
->abs_chain_position
) {
462 trailer_ir_len
+= check_tap
->ir_length
;
468 if (ERROR_OK
!= svf_set_padding(&svf_para
.hdr_para
, header_dr_len
, 0)) {
469 LOG_ERROR("failed to set data header");
473 /* HIR %d TDI (0xFF) */
474 if (ERROR_OK
!= svf_set_padding(&svf_para
.hir_para
, header_ir_len
, 0xFF)) {
475 LOG_ERROR("failed to set instruction header");
480 if (ERROR_OK
!= svf_set_padding(&svf_para
.tdr_para
, trailer_dr_len
, 0)) {
481 LOG_ERROR("failed to set data trailer");
485 /* TIR %d TDI (0xFF) */
486 if (ERROR_OK
!= svf_set_padding(&svf_para
.tir_para
, trailer_ir_len
, 0xFF)) {
487 LOG_ERROR("failed to set instruction trailer");
492 if (svf_progress_enabled
) {
493 /* Count total lines in file. */
494 while (!feof(svf_fd
)) {
495 svf_getline(&svf_command_buffer
, &svf_command_buffer_size
, svf_fd
);
500 while (ERROR_OK
== svf_read_command_from_file(svf_fd
)) {
503 if (svf_progress_enabled
) {
504 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
505 if (svf_last_printed_percentage
!= svf_percentage
) {
506 LOG_USER_N("\r%d%% ", svf_percentage
);
507 svf_last_printed_percentage
= svf_percentage
;
511 if (svf_progress_enabled
) {
512 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
513 LOG_USER_N("%3d%% %s", svf_percentage
, svf_read_line
);
515 LOG_USER_N("%s", svf_read_line
);
518 if (ERROR_OK
!= svf_run_command(CMD_CTX
, svf_command_buffer
)) {
519 LOG_ERROR("fail to run command at line %d", svf_line_number
);
526 if ((!svf_nil
) && (ERROR_OK
!= jtag_execute_queue()))
528 else if (ERROR_OK
!= svf_check_tdo())
532 time_measure_ms
= timeval_ms() - time_measure_ms
;
533 time_measure_s
= time_measure_ms
/ 1000;
534 time_measure_ms
%= 1000;
535 time_measure_m
= time_measure_s
/ 60;
536 time_measure_s
%= 60;
537 if (time_measure_ms
< 1000)
538 command_print(CMD_CTX
,
539 "\r\nTime used: %dm%ds%lldms ",
550 if (svf_command_buffer
) {
551 free(svf_command_buffer
);
552 svf_command_buffer
= NULL
;
553 svf_command_buffer_size
= 0;
555 if (svf_check_tdo_para
) {
556 free(svf_check_tdo_para
);
557 svf_check_tdo_para
= NULL
;
558 svf_check_tdo_para_index
= 0;
560 if (svf_tdi_buffer
) {
561 free(svf_tdi_buffer
);
562 svf_tdi_buffer
= NULL
;
564 if (svf_tdo_buffer
) {
565 free(svf_tdo_buffer
);
566 svf_tdo_buffer
= NULL
;
568 if (svf_mask_buffer
) {
569 free(svf_mask_buffer
);
570 svf_mask_buffer
= NULL
;
572 svf_buffer_index
= 0;
575 svf_free_xxd_para(&svf_para
.hdr_para
);
576 svf_free_xxd_para(&svf_para
.hir_para
);
577 svf_free_xxd_para(&svf_para
.tdr_para
);
578 svf_free_xxd_para(&svf_para
.tir_para
);
579 svf_free_xxd_para(&svf_para
.sdr_para
);
580 svf_free_xxd_para(&svf_para
.sir_para
);
583 command_print(CMD_CTX
,
584 "svf file programmed %s for %d commands with %d errors",
585 (svf_ignore_error
> 1) ? "unsuccessfully" : "successfully",
587 (svf_ignore_error
> 1) ? (svf_ignore_error
- 1) : 0);
589 command_print(CMD_CTX
, "svf file programmed failed");
591 svf_ignore_error
= 0;
595 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
)
597 #define MIN_CHUNK 16 /* Buffer is increased by this size each time as required */
600 if (*lineptr
== NULL
) {
602 *lineptr
= malloc(*n
);
607 (*lineptr
)[0] = fgetc(stream
);
608 while ((*lineptr
)[i
] != '\n') {
609 (*lineptr
)[++i
] = fgetc(stream
);
616 *lineptr
= realloc(*lineptr
, *n
);
622 return sizeof(*lineptr
);
625 #define SVFP_CMD_INC_CNT 1024
626 static int svf_read_command_from_file(FILE *fd
)
631 int cmd_ok
= 0, slash
= 0;
633 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
636 ch
= svf_read_line
[0];
637 while (!cmd_ok
&& (ch
!= 0)) {
641 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
649 if (svf_getline(&svf_read_line
, &svf_read_line_size
,
662 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
667 /* Don't save '\r' and '\n' if no data is parsed */
671 /* The parsing code currently expects a space
672 * before parentheses -- "TDI (123)". Also a
673 * space afterwards -- "TDI (123) TDO(456)".
674 * But such spaces are optional... instead of
675 * parser updates, cope with that by adding the
678 * Ensure there are 3 bytes available, for:
679 * - current character
681 * - terminating NUL ('\0')
683 if (cmd_pos
+ 3 > svf_command_buffer_size
) {
684 svf_command_buffer
= realloc(svf_command_buffer
, cmd_pos
+ 3);
685 svf_command_buffer_size
= cmd_pos
+ 3;
686 if (svf_command_buffer
== NULL
) {
687 LOG_ERROR("not enough memory");
692 /* insert a space before '(' */
694 svf_command_buffer
[cmd_pos
++] = ' ';
696 svf_command_buffer
[cmd_pos
++] = (char)toupper(ch
);
698 /* insert a space after ')' */
700 svf_command_buffer
[cmd_pos
++] = ' ';
703 ch
= svf_read_line
[++i
];
707 svf_command_buffer
[cmd_pos
] = '\0';
713 static int svf_parse_cmd_string(char *str
, int len
, char **argus
, int *num_of_argu
)
715 int pos
= 0, num
= 0, space_found
= 1, in_bracket
= 0;
721 LOG_ERROR("fail to parse svf command");
731 if (!in_bracket
&& isspace((int) str
[pos
])) {
734 } else if (space_found
) {
735 argus
[num
++] = &str
[pos
];
748 bool svf_tap_state_is_stable(tap_state_t state
)
750 return (TAP_RESET
== state
) || (TAP_IDLE
== state
)
751 || (TAP_DRPAUSE
== state
) || (TAP_IRPAUSE
== state
);
754 static int svf_find_string_in_array(char *str
, char **strs
, int num_of_element
)
758 for (i
= 0; i
< num_of_element
; i
++) {
759 if (!strcmp(str
, strs
[i
]))
765 static int svf_adjust_array_length(uint8_t **arr
, int orig_bit_len
, int new_bit_len
)
767 int new_byte_len
= (new_bit_len
+ 7) >> 3;
769 if ((NULL
== *arr
) || (((orig_bit_len
+ 7) >> 3) < ((new_bit_len
+ 7) >> 3))) {
774 *arr
= malloc(new_byte_len
);
776 LOG_ERROR("not enough memory");
779 memset(*arr
, 0, new_byte_len
);
784 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
)
786 int error
= ERROR_OK
;
787 error
|= svf_adjust_array_length(¶
->tdi
, para
->len
, len
);
788 memset(para
->tdi
, tdi
, (len
+ 7) >> 3);
789 error
|= svf_adjust_array_length(¶
->tdo
, para
->len
, len
);
790 error
|= svf_adjust_array_length(¶
->mask
, para
->len
, len
);
792 para
->data_mask
= XXR_TDI
;
797 static int svf_copy_hexstring_to_binary(char *str
, uint8_t **bin
, int orig_bit_len
, int bit_len
)
799 int i
, str_len
= strlen(str
), str_hbyte_len
= (bit_len
+ 3) >> 2;
802 if (ERROR_OK
!= svf_adjust_array_length(bin
, orig_bit_len
, bit_len
)) {
803 LOG_ERROR("fail to adjust length of array");
807 /* fill from LSB (end of str) to MSB (beginning of str) */
808 for (i
= 0; i
< str_hbyte_len
; i
++) {
810 while (str_len
> 0) {
813 /* Skip whitespace. The SVF specification (rev E) is
814 * deficient in terms of basic lexical issues like
815 * where whitespace is allowed. Long bitstrings may
816 * require line ends for correctness, since there is
817 * a hard limit on line length.
820 if ((ch
>= '0') && (ch
<= '9')) {
823 } else if ((ch
>= 'A') && (ch
<= 'F')) {
827 LOG_ERROR("invalid hex string");
838 (*bin
)[i
/ 2] |= ch
<< 4;
846 /* consume optional leading '0' MSBs or whitespace */
847 while (str_len
> 0 && ((str
[str_len
- 1] == '0')
848 || isspace((int) str
[str_len
- 1])))
851 /* check validity: we must have consumed everything */
852 if (str_len
> 0 || (ch
& ~((2 << ((bit_len
- 1) % 4)) - 1)) != 0) {
853 LOG_ERROR("value execeeds length");
860 static int svf_check_tdo(void)
862 int i
, len
, index_var
;
864 for (i
= 0; i
< svf_check_tdo_para_index
; i
++) {
865 index_var
= svf_check_tdo_para
[i
].buffer_offset
;
866 len
= svf_check_tdo_para
[i
].bit_len
;
867 if ((svf_check_tdo_para
[i
].enabled
)
868 && buf_cmp_mask(&svf_tdi_buffer
[index_var
], &svf_tdo_buffer
[index_var
],
869 &svf_mask_buffer
[index_var
], len
)) {
870 LOG_ERROR("tdo check error at line %d",
871 svf_check_tdo_para
[i
].line_num
);
872 SVF_BUF_LOG(ERROR
, &svf_tdi_buffer
[index_var
], len
, "READ");
873 SVF_BUF_LOG(ERROR
, &svf_tdo_buffer
[index_var
], len
, "WANT");
874 SVF_BUF_LOG(ERROR
, &svf_mask_buffer
[index_var
], len
, "MASK");
876 if (svf_ignore_error
== 0)
882 svf_check_tdo_para_index
= 0;
887 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
)
889 if (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
) {
890 LOG_ERROR("toooooo many operation undone");
894 svf_check_tdo_para
[svf_check_tdo_para_index
].line_num
= svf_line_number
;
895 svf_check_tdo_para
[svf_check_tdo_para_index
].bit_len
= bit_len
;
896 svf_check_tdo_para
[svf_check_tdo_para_index
].enabled
= enabled
;
897 svf_check_tdo_para
[svf_check_tdo_para_index
].buffer_offset
= buffer_offset
;
898 svf_check_tdo_para_index
++;
903 static int svf_execute_tap(void)
905 if ((!svf_nil
) && (ERROR_OK
!= jtag_execute_queue()))
907 else if (ERROR_OK
!= svf_check_tdo())
910 svf_buffer_index
= 0;
915 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
)
917 char *argus
[256], command
;
918 int num_of_argu
= 0, i
;
927 struct svf_xxr_para
*xxr_para_tmp
;
928 uint8_t **pbuffer_tmp
;
929 struct scan_field field
;
931 tap_state_t
*path
= NULL
, state
;
932 /* flag padding commands skipped due to -tap command */
933 int padding_command_skipped
= 0;
935 if (ERROR_OK
!= svf_parse_cmd_string(cmd_str
, strlen(cmd_str
), argus
, &num_of_argu
))
938 /* NOTE: we're a bit loose here, because we ignore case in
939 * TAP state names (instead of insisting on uppercase).
942 command
= svf_find_string_in_array(argus
[0],
943 (char **)svf_command_name
, ARRAY_SIZE(svf_command_name
));
947 if (num_of_argu
!= 2) {
948 LOG_ERROR("invalid parameter of %s", argus
[0]);
952 i_tmp
= tap_state_by_name(argus
[1]);
954 if (svf_tap_state_is_stable(i_tmp
)) {
955 if (command
== ENDIR
) {
956 svf_para
.ir_end_state
= i_tmp
;
957 LOG_DEBUG("\tIR end_state = %s",
958 tap_state_name(i_tmp
));
960 svf_para
.dr_end_state
= i_tmp
;
961 LOG_DEBUG("\tDR end_state = %s",
962 tap_state_name(i_tmp
));
965 LOG_ERROR("%s: %s is not a stable state",
971 if ((num_of_argu
!= 1) && (num_of_argu
!= 3)) {
972 LOG_ERROR("invalid parameter of %s", argus
[0]);
975 if (1 == num_of_argu
) {
976 /* TODO: set jtag speed to full speed */
977 svf_para
.frequency
= 0;
979 if (strcmp(argus
[2], "HZ")) {
980 LOG_ERROR("HZ not found in FREQUENCY command");
983 if (ERROR_OK
!= svf_execute_tap())
985 svf_para
.frequency
= atof(argus
[1]);
986 /* TODO: set jtag speed to */
987 if (svf_para
.frequency
> 0) {
988 command_run_linef(cmd_ctx
,
990 (int)svf_para
.frequency
/ 1000);
991 LOG_DEBUG("\tfrequency = %f", svf_para
.frequency
);
996 if (svf_tap_is_specified
) {
997 padding_command_skipped
= 1;
1000 xxr_para_tmp
= &svf_para
.hdr_para
;
1003 if (svf_tap_is_specified
) {
1004 padding_command_skipped
= 1;
1007 xxr_para_tmp
= &svf_para
.hir_para
;
1010 if (svf_tap_is_specified
) {
1011 padding_command_skipped
= 1;
1014 xxr_para_tmp
= &svf_para
.tdr_para
;
1017 if (svf_tap_is_specified
) {
1018 padding_command_skipped
= 1;
1021 xxr_para_tmp
= &svf_para
.tir_para
;
1024 xxr_para_tmp
= &svf_para
.sdr_para
;
1027 xxr_para_tmp
= &svf_para
.sir_para
;
1030 /* XXR length [TDI (tdi)] [TDO (tdo)][MASK (mask)] [SMASK (smask)] */
1031 if ((num_of_argu
> 10) || (num_of_argu
% 2)) {
1032 LOG_ERROR("invalid parameter of %s", argus
[0]);
1035 i_tmp
= xxr_para_tmp
->len
;
1036 xxr_para_tmp
->len
= atoi(argus
[1]);
1037 LOG_DEBUG("\tlength = %d", xxr_para_tmp
->len
);
1038 xxr_para_tmp
->data_mask
= 0;
1039 for (i
= 2; i
< num_of_argu
; i
+= 2) {
1040 if ((strlen(argus
[i
+ 1]) < 3) || (argus
[i
+ 1][0] != '(') ||
1041 (argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] != ')')) {
1042 LOG_ERROR("data section error");
1045 argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] = '\0';
1046 /* TDI, TDO, MASK, SMASK */
1047 if (!strcmp(argus
[i
], "TDI")) {
1049 pbuffer_tmp
= &xxr_para_tmp
->tdi
;
1050 xxr_para_tmp
->data_mask
|= XXR_TDI
;
1051 } else if (!strcmp(argus
[i
], "TDO")) {
1053 pbuffer_tmp
= &xxr_para_tmp
->tdo
;
1054 xxr_para_tmp
->data_mask
|= XXR_TDO
;
1055 } else if (!strcmp(argus
[i
], "MASK")) {
1057 pbuffer_tmp
= &xxr_para_tmp
->mask
;
1058 xxr_para_tmp
->data_mask
|= XXR_MASK
;
1059 } else if (!strcmp(argus
[i
], "SMASK")) {
1061 pbuffer_tmp
= &xxr_para_tmp
->smask
;
1062 xxr_para_tmp
->data_mask
|= XXR_SMASK
;
1064 LOG_ERROR("unknow parameter: %s", argus
[i
]);
1068 svf_copy_hexstring_to_binary(&argus
[i
+ 1][1], pbuffer_tmp
, i_tmp
,
1069 xxr_para_tmp
->len
)) {
1070 LOG_ERROR("fail to parse hex value");
1073 SVF_BUF_LOG(DEBUG
, *pbuffer_tmp
, xxr_para_tmp
->len
, argus
[i
]);
1075 /* If a command changes the length of the last scan of the same type and the
1076 * MASK parameter is absent, */
1077 /* the mask pattern used is all cares */
1078 if (!(xxr_para_tmp
->data_mask
& XXR_MASK
) && (i_tmp
!= xxr_para_tmp
->len
)) {
1079 /* MASK not defined and length changed */
1081 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1082 xxr_para_tmp
->len
)) {
1083 LOG_ERROR("fail to adjust length of array");
1086 buf_set_ones(xxr_para_tmp
->mask
, xxr_para_tmp
->len
);
1088 /* If TDO is absent, no comparison is needed, set the mask to 0 */
1089 if (!(xxr_para_tmp
->data_mask
& XXR_TDO
)) {
1090 if (NULL
== xxr_para_tmp
->tdo
) {
1092 svf_adjust_array_length(&xxr_para_tmp
->tdo
, i_tmp
,
1093 xxr_para_tmp
->len
)) {
1094 LOG_ERROR("fail to adjust length of array");
1098 if (NULL
== xxr_para_tmp
->mask
) {
1100 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1101 xxr_para_tmp
->len
)) {
1102 LOG_ERROR("fail to adjust length of array");
1106 memset(xxr_para_tmp
->mask
, 0, (xxr_para_tmp
->len
+ 7) >> 3);
1108 /* do scan if necessary */
1109 if (SDR
== command
) {
1110 /* check buffer size first, reallocate if necessary */
1111 i
= svf_para
.hdr_para
.len
+ svf_para
.sdr_para
.len
+
1112 svf_para
.tdr_para
.len
;
1113 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1114 /* reallocate buffer */
1115 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1116 LOG_ERROR("not enough memory");
1121 /* assemble dr data */
1123 buf_set_buf(svf_para
.hdr_para
.tdi
,
1125 &svf_tdi_buffer
[svf_buffer_index
],
1127 svf_para
.hdr_para
.len
);
1128 i
+= svf_para
.hdr_para
.len
;
1129 buf_set_buf(svf_para
.sdr_para
.tdi
,
1131 &svf_tdi_buffer
[svf_buffer_index
],
1133 svf_para
.sdr_para
.len
);
1134 i
+= svf_para
.sdr_para
.len
;
1135 buf_set_buf(svf_para
.tdr_para
.tdi
,
1137 &svf_tdi_buffer
[svf_buffer_index
],
1139 svf_para
.tdr_para
.len
);
1140 i
+= svf_para
.tdr_para
.len
;
1142 /* add check data */
1143 if (svf_para
.sdr_para
.data_mask
& XXR_TDO
) {
1144 /* assemble dr mask data */
1146 buf_set_buf(svf_para
.hdr_para
.mask
,
1148 &svf_mask_buffer
[svf_buffer_index
],
1150 svf_para
.hdr_para
.len
);
1151 i
+= svf_para
.hdr_para
.len
;
1152 buf_set_buf(svf_para
.sdr_para
.mask
,
1154 &svf_mask_buffer
[svf_buffer_index
],
1156 svf_para
.sdr_para
.len
);
1157 i
+= svf_para
.sdr_para
.len
;
1158 buf_set_buf(svf_para
.tdr_para
.mask
,
1160 &svf_mask_buffer
[svf_buffer_index
],
1162 svf_para
.tdr_para
.len
);
1164 /* assemble dr check data */
1166 buf_set_buf(svf_para
.hdr_para
.tdo
,
1168 &svf_tdo_buffer
[svf_buffer_index
],
1170 svf_para
.hdr_para
.len
);
1171 i
+= svf_para
.hdr_para
.len
;
1172 buf_set_buf(svf_para
.sdr_para
.tdo
,
1174 &svf_tdo_buffer
[svf_buffer_index
],
1176 svf_para
.sdr_para
.len
);
1177 i
+= svf_para
.sdr_para
.len
;
1178 buf_set_buf(svf_para
.tdr_para
.tdo
,
1180 &svf_tdo_buffer
[svf_buffer_index
],
1182 svf_para
.tdr_para
.len
);
1183 i
+= svf_para
.tdr_para
.len
;
1185 svf_add_check_para(1, svf_buffer_index
, i
);
1187 svf_add_check_para(0, svf_buffer_index
, i
);
1189 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1190 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1192 /* NOTE: doesn't use SVF-specified state paths */
1193 jtag_add_plain_dr_scan(field
.num_bits
,
1196 svf_para
.dr_end_state
);
1199 svf_buffer_index
+= (i
+ 7) >> 3;
1200 } else if (SIR
== command
) {
1201 /* check buffer size first, reallocate if necessary */
1202 i
= svf_para
.hir_para
.len
+ svf_para
.sir_para
.len
+
1203 svf_para
.tir_para
.len
;
1204 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1205 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1206 LOG_ERROR("not enough memory");
1211 /* assemble ir data */
1213 buf_set_buf(svf_para
.hir_para
.tdi
,
1215 &svf_tdi_buffer
[svf_buffer_index
],
1217 svf_para
.hir_para
.len
);
1218 i
+= svf_para
.hir_para
.len
;
1219 buf_set_buf(svf_para
.sir_para
.tdi
,
1221 &svf_tdi_buffer
[svf_buffer_index
],
1223 svf_para
.sir_para
.len
);
1224 i
+= svf_para
.sir_para
.len
;
1225 buf_set_buf(svf_para
.tir_para
.tdi
,
1227 &svf_tdi_buffer
[svf_buffer_index
],
1229 svf_para
.tir_para
.len
);
1230 i
+= svf_para
.tir_para
.len
;
1232 /* add check data */
1233 if (svf_para
.sir_para
.data_mask
& XXR_TDO
) {
1234 /* assemble dr mask data */
1236 buf_set_buf(svf_para
.hir_para
.mask
,
1238 &svf_mask_buffer
[svf_buffer_index
],
1240 svf_para
.hir_para
.len
);
1241 i
+= svf_para
.hir_para
.len
;
1242 buf_set_buf(svf_para
.sir_para
.mask
,
1244 &svf_mask_buffer
[svf_buffer_index
],
1246 svf_para
.sir_para
.len
);
1247 i
+= svf_para
.sir_para
.len
;
1248 buf_set_buf(svf_para
.tir_para
.mask
,
1250 &svf_mask_buffer
[svf_buffer_index
],
1252 svf_para
.tir_para
.len
);
1254 /* assemble dr check data */
1256 buf_set_buf(svf_para
.hir_para
.tdo
,
1258 &svf_tdo_buffer
[svf_buffer_index
],
1260 svf_para
.hir_para
.len
);
1261 i
+= svf_para
.hir_para
.len
;
1262 buf_set_buf(svf_para
.sir_para
.tdo
,
1264 &svf_tdo_buffer
[svf_buffer_index
],
1266 svf_para
.sir_para
.len
);
1267 i
+= svf_para
.sir_para
.len
;
1268 buf_set_buf(svf_para
.tir_para
.tdo
,
1270 &svf_tdo_buffer
[svf_buffer_index
],
1272 svf_para
.tir_para
.len
);
1273 i
+= svf_para
.tir_para
.len
;
1275 svf_add_check_para(1, svf_buffer_index
, i
);
1277 svf_add_check_para(0, svf_buffer_index
, i
);
1279 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1280 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1282 /* NOTE: doesn't use SVF-specified state paths */
1283 jtag_add_plain_ir_scan(field
.num_bits
,
1286 svf_para
.ir_end_state
);
1289 svf_buffer_index
+= (i
+ 7) >> 3;
1294 LOG_ERROR("PIO and PIOMAP are not supported");
1298 /* RUNTEST [run_state] run_count run_clk [min_time SEC [MAXIMUM max_time
1299 * SEC]] [ENDSTATE end_state] */
1300 /* RUNTEST [run_state] min_time SEC [MAXIMUM max_time SEC] [ENDSTATE
1302 if ((num_of_argu
< 3) && (num_of_argu
> 11)) {
1303 LOG_ERROR("invalid parameter of %s", argus
[0]);
1312 i_tmp
= tap_state_by_name(argus
[i
]);
1313 if (i_tmp
!= TAP_INVALID
) {
1314 if (svf_tap_state_is_stable(i_tmp
)) {
1315 svf_para
.runtest_run_state
= i_tmp
;
1317 /* When a run_state is specified, the new
1318 * run_state becomes the default end_state.
1320 svf_para
.runtest_end_state
= i_tmp
;
1321 LOG_DEBUG("\trun_state = %s", tap_state_name(i_tmp
));
1324 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1329 /* run_count run_clk */
1330 if (((i
+ 2) <= num_of_argu
) && strcmp(argus
[i
+ 1], "SEC")) {
1331 if (!strcmp(argus
[i
+ 1], "TCK")) {
1332 /* clock source is TCK */
1333 run_count
= atoi(argus
[i
]);
1334 LOG_DEBUG("\trun_count@TCK = %d", run_count
);
1336 LOG_ERROR("%s not supported for clock", argus
[i
+ 1]);
1342 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
+ 1], "SEC")) {
1343 min_time
= atof(argus
[i
]);
1344 LOG_DEBUG("\tmin_time = %fs", min_time
);
1347 /* MAXIMUM max_time SEC */
1348 if (((i
+ 3) <= num_of_argu
) &&
1349 !strcmp(argus
[i
], "MAXIMUM") && !strcmp(argus
[i
+ 2], "SEC")) {
1351 max_time
= atof(argus
[i
+ 1]);
1352 LOG_DEBUG("\tmax_time = %fs", max_time
);
1355 /* ENDSTATE end_state */
1356 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
], "ENDSTATE")) {
1357 i_tmp
= tap_state_by_name(argus
[i
+ 1]);
1359 if (svf_tap_state_is_stable(i_tmp
)) {
1360 svf_para
.runtest_end_state
= i_tmp
;
1361 LOG_DEBUG("\tend_state = %s", tap_state_name(i_tmp
));
1363 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1369 /* all parameter should be parsed */
1370 if (i
== num_of_argu
) {
1372 /* FIXME handle statemove failures */
1373 uint32_t min_usec
= 1000000 * min_time
;
1375 /* enter into run_state if necessary */
1376 if (cmd_queue_cur_state
!= svf_para
.runtest_run_state
)
1377 svf_add_statemove(svf_para
.runtest_run_state
);
1379 /* add clocks and/or min wait */
1380 if (run_count
> 0) {
1382 jtag_add_clocks(run_count
);
1387 jtag_add_sleep(min_usec
);
1390 /* move to end_state if necessary */
1391 if (svf_para
.runtest_end_state
!= svf_para
.runtest_run_state
)
1392 svf_add_statemove(svf_para
.runtest_end_state
);
1395 if (svf_para
.runtest_run_state
!= TAP_IDLE
) {
1396 LOG_ERROR("cannot runtest in %s state",
1397 tap_state_name(svf_para
.runtest_run_state
));
1402 jtag_add_runtest(run_count
, svf_para
.runtest_end_state
);
1405 LOG_ERROR("fail to parse parameter of RUNTEST, %d out of %d is parsed",
1412 /* STATE [pathstate1 [pathstate2 ...[pathstaten]]] stable_state */
1413 if (num_of_argu
< 2) {
1414 LOG_ERROR("invalid parameter of %s", argus
[0]);
1417 if (num_of_argu
> 2) {
1418 /* STATE pathstate1 ... stable_state */
1419 path
= malloc((num_of_argu
- 1) * sizeof(tap_state_t
));
1421 LOG_ERROR("not enough memory");
1424 num_of_argu
--; /* num of path */
1425 i_tmp
= 1; /* path is from parameter 1 */
1426 for (i
= 0; i
< num_of_argu
; i
++, i_tmp
++) {
1427 path
[i
] = tap_state_by_name(argus
[i_tmp
]);
1428 if (path
[i
] == TAP_INVALID
) {
1429 LOG_ERROR("%s: %s is not a valid state", argus
[0], argus
[i_tmp
]);
1433 /* OpenOCD refuses paths containing TAP_RESET */
1434 if (TAP_RESET
== path
[i
]) {
1435 /* FIXME last state MUST be stable! */
1438 jtag_add_pathmove(i
, path
);
1442 num_of_argu
-= i
+ 1;
1446 if (num_of_argu
> 0) {
1447 /* execute last path if necessary */
1448 if (svf_tap_state_is_stable(path
[num_of_argu
- 1])) {
1449 /* last state MUST be stable state */
1451 jtag_add_pathmove(num_of_argu
, path
);
1452 LOG_DEBUG("\tmove to %s by path_move",
1453 tap_state_name(path
[num_of_argu
- 1]));
1455 LOG_ERROR("%s: %s is not a stable state",
1457 tap_state_name(path
[num_of_argu
- 1]));
1466 /* STATE stable_state */
1467 state
= tap_state_by_name(argus
[1]);
1468 if (svf_tap_state_is_stable(state
)) {
1469 LOG_DEBUG("\tmove to %s by svf_add_statemove",
1470 tap_state_name(state
));
1471 /* FIXME handle statemove failures */
1472 svf_add_statemove(state
);
1474 LOG_ERROR("%s: %s is not a stable state",
1475 argus
[0], tap_state_name(state
));
1481 /* TRST trst_mode */
1482 if (num_of_argu
!= 2) {
1483 LOG_ERROR("invalid parameter of %s", argus
[0]);
1486 if (svf_para
.trst_mode
!= TRST_ABSENT
) {
1487 if (ERROR_OK
!= svf_execute_tap())
1489 i_tmp
= svf_find_string_in_array(argus
[1],
1490 (char **)svf_trst_mode_name
,
1491 ARRAY_SIZE(svf_trst_mode_name
));
1495 jtag_add_reset(1, 0);
1500 jtag_add_reset(0, 0);
1505 LOG_ERROR("unknown TRST mode: %s", argus
[1]);
1508 svf_para
.trst_mode
= i_tmp
;
1509 LOG_DEBUG("\ttrst_mode = %s", svf_trst_mode_name
[svf_para
.trst_mode
]);
1511 LOG_ERROR("can not accpet TRST command if trst_mode is ABSENT");
1516 LOG_ERROR("invalid svf command: %s", argus
[0]);
1522 if (padding_command_skipped
)
1523 LOG_USER("(Above Padding command skipped, as per -tap argument)");
1526 if (debug_level
>= LOG_LVL_DEBUG
) {
1527 /* for convenient debugging, execute tap if possible */
1528 if ((svf_buffer_index
> 0) && \
1529 (((command
!= STATE
) && (command
!= RUNTEST
)) || \
1530 ((command
== STATE
) && (num_of_argu
== 2)))) {
1531 if (ERROR_OK
!= svf_execute_tap())
1534 /* output debug info */
1535 if ((SIR
== command
) || (SDR
== command
)) {
1536 SVF_BUF_LOG(DEBUG
, svf_tdi_buffer
, svf_check_tdo_para
[0].bit_len
, "TDO read");
1540 /* for fast executing, execute tap if necessary */
1541 /* half of the buffer is for the next command */
1542 if (((svf_buffer_index
>= SVF_MAX_BUFFER_SIZE_TO_COMMIT
) ||
1543 (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
/ 2)) && \
1544 (((command
!= STATE
) && (command
!= RUNTEST
)) || \
1545 ((command
== STATE
) && (num_of_argu
== 2))))
1546 return svf_execute_tap();
1552 static const struct command_registration svf_command_handlers
[] = {
1555 .handler
= handle_svf_command
,
1556 .mode
= COMMAND_EXEC
,
1557 .help
= "Runs a SVF file.",
1558 .usage
= "svf [-tap device.tap] <file> [quiet] [nil] [progress] [ignore_error]",
1560 COMMAND_REGISTRATION_DONE
1563 int svf_register_commands(struct command_context
*cmd_ctx
)
1565 return register_commands(cmd_ctx
, NULL
, svf_command_handlers
);
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)