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
);
221 static char *svf_read_line
;
222 static size_t svf_read_line_size
;
223 static char *svf_command_buffer
;
224 static size_t svf_command_buffer_size
;
225 static int svf_line_number
= 1;
226 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
);
228 #define SVF_MAX_BUFFER_SIZE_TO_COMMIT (1024 * 1024)
229 static uint8_t *svf_tdi_buffer
, *svf_tdo_buffer
, *svf_mask_buffer
;
230 static int svf_buffer_index
, svf_buffer_size
;
231 static int svf_quiet
;
233 static int svf_ignore_error
;
235 /* Targetting particular tap */
236 static int svf_tap_is_specified
;
237 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
);
239 /* Progress Indicator */
240 static int svf_progress_enabled
;
241 static long svf_total_lines
;
242 static int svf_percentage
;
243 static int svf_last_printed_percentage
= -1;
246 * macro is used to print the svf hex buffer at desired debug level
247 * DEBUG, INFO, ERROR, USER
249 #define SVF_BUF_LOG(_lvl, _buf, _nbits, _desc) \
250 svf_hexbuf_print(LOG_LVL_##_lvl , __FILE__, __LINE__, __func__, _buf, _nbits, _desc)
252 static void svf_hexbuf_print(int dbg_lvl
, const char *file
, unsigned line
,
253 const char *function
, const uint8_t *buf
,
254 int bit_len
, const char *desc
)
257 int byte_len
= DIV_ROUND_UP(bit_len
, 8);
258 int msbits
= bit_len
% 8;
260 /* allocate 2 bytes per hex digit */
261 char *prbuf
= malloc((byte_len
* 2) + 1);
265 /* print correct number of bytes, mask excess bits where applicable */
266 uint8_t msb
= buf
[byte_len
- 1] & (msbits
? (1 << msbits
) - 1 : 0xff);
267 len
= sprintf(prbuf
, msbits
<= 4 ? "0x%01"PRIx8
: "0x%02"PRIx8
, msb
);
268 for (j
= byte_len
- 2; j
>= 0; j
--)
269 len
+= sprintf(prbuf
+ len
, "%02"PRIx8
, buf
[j
]);
271 log_printf_lf(dbg_lvl
, file
, line
, function
, "%8s = %s", desc
? desc
: " ", prbuf
);
276 static int svf_realloc_buffers(size_t len
)
280 ptr
= realloc(svf_tdi_buffer
, len
);
283 svf_tdi_buffer
= ptr
;
285 ptr
= realloc(svf_tdo_buffer
, len
);
288 svf_tdo_buffer
= ptr
;
290 ptr
= realloc(svf_mask_buffer
, len
);
293 svf_mask_buffer
= ptr
;
295 svf_buffer_size
= len
;
300 static void svf_free_xxd_para(struct svf_xxr_para
*para
)
303 if (para
->tdi
!= NULL
) {
307 if (para
->tdo
!= NULL
) {
311 if (para
->mask
!= NULL
) {
315 if (para
->smask
!= NULL
) {
322 int svf_add_statemove(tap_state_t state_to
)
324 tap_state_t state_from
= cmd_queue_cur_state
;
327 /* when resetting, be paranoid and ignore current state */
328 if (state_to
== TAP_RESET
) {
336 for (index_var
= 0; index_var
< ARRAY_SIZE(svf_statemoves
); index_var
++) {
337 if ((svf_statemoves
[index_var
].from
== state_from
)
338 && (svf_statemoves
[index_var
].to
== state_to
)) {
341 /* recorded path includes current state ... avoid
343 if (svf_statemoves
[index_var
].num_of_moves
> 1)
344 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
- 1,
345 svf_statemoves
[index_var
].paths
+ 1);
347 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
,
348 svf_statemoves
[index_var
].paths
);
352 LOG_ERROR("SVF: can not move to %s", tap_state_name(state_to
));
356 COMMAND_HANDLER(handle_svf_command
)
358 #define SVF_MIN_NUM_OF_OPTIONS 1
359 #define SVF_MAX_NUM_OF_OPTIONS 5
362 long long time_measure_ms
;
363 int time_measure_s
, time_measure_m
;
365 /* use NULL to indicate a "plain" svf file which accounts for
366 * any additional devices in the scan chain, otherwise the device
367 * that should be affected
369 struct jtag_tap
*tap
= NULL
;
371 if ((CMD_ARGC
< SVF_MIN_NUM_OF_OPTIONS
) || (CMD_ARGC
> SVF_MAX_NUM_OF_OPTIONS
))
372 return ERROR_COMMAND_SYNTAX_ERROR
;
374 /* parse command line */
377 svf_ignore_error
= 0;
378 for (unsigned int i
= 0; i
< CMD_ARGC
; i
++) {
379 if (strcmp(CMD_ARGV
[i
], "-tap") == 0) {
380 tap
= jtag_tap_by_string(CMD_ARGV
[i
+1]);
382 command_print(CMD_CTX
, "Tap: %s unknown", CMD_ARGV
[i
+1]);
386 } else if ((strcmp(CMD_ARGV
[i
],
387 "quiet") == 0) || (strcmp(CMD_ARGV
[i
], "-quiet") == 0))
389 else if ((strcmp(CMD_ARGV
[i
], "nil") == 0) || (strcmp(CMD_ARGV
[i
], "-nil") == 0))
391 else if ((strcmp(CMD_ARGV
[i
],
392 "progress") == 0) || (strcmp(CMD_ARGV
[i
], "-progress") == 0))
393 svf_progress_enabled
= 1;
394 else if ((strcmp(CMD_ARGV
[i
],
395 "ignore_error") == 0) || (strcmp(CMD_ARGV
[i
], "-ignore_error") == 0))
396 svf_ignore_error
= 1;
398 svf_fd
= fopen(CMD_ARGV
[i
], "r");
399 if (svf_fd
== NULL
) {
401 command_print(CMD_CTX
, "open(\"%s\"): %s", CMD_ARGV
[i
], strerror(err
));
402 /* no need to free anything now */
403 return ERROR_COMMAND_SYNTAX_ERROR
;
405 LOG_USER("svf processing file: \"%s\"", CMD_ARGV
[i
]);
410 return ERROR_COMMAND_SYNTAX_ERROR
;
413 time_measure_ms
= timeval_ms();
417 svf_command_buffer_size
= 0;
419 svf_check_tdo_para_index
= 0;
420 svf_check_tdo_para
= malloc(sizeof(struct svf_check_tdo_para
) * SVF_CHECK_TDO_PARA_SIZE
);
421 if (NULL
== svf_check_tdo_para
) {
422 LOG_ERROR("not enough memory");
427 svf_buffer_index
= 0;
428 /* double the buffer size */
429 /* in case current command cannot be committed, and next command is a bit scan command */
430 /* here is 32K bits for this big scan command, it should be enough */
431 /* buffer will be reallocated if buffer size is not enough */
432 if (svf_realloc_buffers(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT
) != ERROR_OK
) {
437 memcpy(&svf_para
, &svf_para_init
, sizeof(svf_para
));
445 /* Tap is specified, set header/trailer paddings */
446 int header_ir_len
= 0, header_dr_len
= 0, trailer_ir_len
= 0, trailer_dr_len
= 0;
447 struct jtag_tap
*check_tap
;
449 svf_tap_is_specified
= 1;
451 for (check_tap
= jtag_all_taps(); check_tap
; check_tap
= check_tap
->next_tap
) {
452 if (check_tap
->abs_chain_position
< tap
->abs_chain_position
) {
454 header_ir_len
+= check_tap
->ir_length
;
456 } else if (check_tap
->abs_chain_position
> tap
->abs_chain_position
) {
458 trailer_ir_len
+= check_tap
->ir_length
;
464 if (ERROR_OK
!= svf_set_padding(&svf_para
.hdr_para
, header_dr_len
, 0)) {
465 LOG_ERROR("failed to set data header");
469 /* HIR %d TDI (0xFF) */
470 if (ERROR_OK
!= svf_set_padding(&svf_para
.hir_para
, header_ir_len
, 0xFF)) {
471 LOG_ERROR("failed to set instruction header");
476 if (ERROR_OK
!= svf_set_padding(&svf_para
.tdr_para
, trailer_dr_len
, 0)) {
477 LOG_ERROR("failed to set data trailer");
481 /* TIR %d TDI (0xFF) */
482 if (ERROR_OK
!= svf_set_padding(&svf_para
.tir_para
, trailer_ir_len
, 0xFF)) {
483 LOG_ERROR("failed to set instruction trailer");
488 if (svf_progress_enabled
) {
489 /* Count total lines in file. */
490 while (!feof(svf_fd
)) {
491 svf_getline(&svf_command_buffer
, &svf_command_buffer_size
, svf_fd
);
496 while (ERROR_OK
== svf_read_command_from_file(svf_fd
)) {
499 if (svf_progress_enabled
) {
500 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
501 if (svf_last_printed_percentage
!= svf_percentage
) {
502 LOG_USER_N("\r%d%% ", svf_percentage
);
503 svf_last_printed_percentage
= svf_percentage
;
507 if (svf_progress_enabled
) {
508 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
509 LOG_USER_N("%3d%% %s", svf_percentage
, svf_read_line
);
511 LOG_USER_N("%s", svf_read_line
);
514 if (ERROR_OK
!= svf_run_command(CMD_CTX
, svf_command_buffer
)) {
515 LOG_ERROR("fail to run command at line %d", svf_line_number
);
522 if ((!svf_nil
) && (ERROR_OK
!= jtag_execute_queue()))
524 else if (ERROR_OK
!= svf_check_tdo())
528 time_measure_ms
= timeval_ms() - time_measure_ms
;
529 time_measure_s
= time_measure_ms
/ 1000;
530 time_measure_ms
%= 1000;
531 time_measure_m
= time_measure_s
/ 60;
532 time_measure_s
%= 60;
533 if (time_measure_ms
< 1000)
534 command_print(CMD_CTX
,
535 "\r\nTime used: %dm%ds%lldms ",
546 if (svf_command_buffer
) {
547 free(svf_command_buffer
);
548 svf_command_buffer
= NULL
;
549 svf_command_buffer_size
= 0;
551 if (svf_check_tdo_para
) {
552 free(svf_check_tdo_para
);
553 svf_check_tdo_para
= NULL
;
554 svf_check_tdo_para_index
= 0;
556 if (svf_tdi_buffer
) {
557 free(svf_tdi_buffer
);
558 svf_tdi_buffer
= NULL
;
560 if (svf_tdo_buffer
) {
561 free(svf_tdo_buffer
);
562 svf_tdo_buffer
= NULL
;
564 if (svf_mask_buffer
) {
565 free(svf_mask_buffer
);
566 svf_mask_buffer
= NULL
;
568 svf_buffer_index
= 0;
571 svf_free_xxd_para(&svf_para
.hdr_para
);
572 svf_free_xxd_para(&svf_para
.hir_para
);
573 svf_free_xxd_para(&svf_para
.tdr_para
);
574 svf_free_xxd_para(&svf_para
.tir_para
);
575 svf_free_xxd_para(&svf_para
.sdr_para
);
576 svf_free_xxd_para(&svf_para
.sir_para
);
579 command_print(CMD_CTX
,
580 "svf file programmed %s for %d commands with %d errors",
581 (svf_ignore_error
> 1) ? "unsuccessfully" : "successfully",
583 (svf_ignore_error
> 1) ? (svf_ignore_error
- 1) : 0);
585 command_print(CMD_CTX
, "svf file programmed failed");
587 svf_ignore_error
= 0;
591 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
)
593 #define MIN_CHUNK 16 /* Buffer is increased by this size each time as required */
596 if (*lineptr
== NULL
) {
598 *lineptr
= malloc(*n
);
603 (*lineptr
)[0] = fgetc(stream
);
604 while ((*lineptr
)[i
] != '\n') {
605 (*lineptr
)[++i
] = fgetc(stream
);
612 *lineptr
= realloc(*lineptr
, *n
);
618 return sizeof(*lineptr
);
621 #define SVFP_CMD_INC_CNT 1024
622 static int svf_read_command_from_file(FILE *fd
)
627 int cmd_ok
= 0, slash
= 0;
629 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
632 ch
= svf_read_line
[0];
633 while (!cmd_ok
&& (ch
!= 0)) {
637 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
645 if (svf_getline(&svf_read_line
, &svf_read_line_size
,
658 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
663 /* Don't save '\r' and '\n' if no data is parsed */
667 /* The parsing code currently expects a space
668 * before parentheses -- "TDI (123)". Also a
669 * space afterwards -- "TDI (123) TDO(456)".
670 * But such spaces are optional... instead of
671 * parser updates, cope with that by adding the
674 * Ensure there are 3 bytes available, for:
675 * - current character
677 * - terminating NUL ('\0')
679 if (cmd_pos
+ 3 > svf_command_buffer_size
) {
680 svf_command_buffer
= realloc(svf_command_buffer
, cmd_pos
+ 3);
681 svf_command_buffer_size
= cmd_pos
+ 3;
682 if (svf_command_buffer
== NULL
) {
683 LOG_ERROR("not enough memory");
688 /* insert a space before '(' */
690 svf_command_buffer
[cmd_pos
++] = ' ';
692 svf_command_buffer
[cmd_pos
++] = (char)toupper(ch
);
694 /* insert a space after ')' */
696 svf_command_buffer
[cmd_pos
++] = ' ';
699 ch
= svf_read_line
[++i
];
703 svf_command_buffer
[cmd_pos
] = '\0';
709 static int svf_parse_cmd_string(char *str
, int len
, char **argus
, int *num_of_argu
)
711 int pos
= 0, num
= 0, space_found
= 1, in_bracket
= 0;
717 LOG_ERROR("fail to parse svf command");
727 if (!in_bracket
&& isspace((int) str
[pos
])) {
730 } else if (space_found
) {
731 argus
[num
++] = &str
[pos
];
744 bool svf_tap_state_is_stable(tap_state_t state
)
746 return (TAP_RESET
== state
) || (TAP_IDLE
== state
)
747 || (TAP_DRPAUSE
== state
) || (TAP_IRPAUSE
== state
);
750 static int svf_find_string_in_array(char *str
, char **strs
, int num_of_element
)
754 for (i
= 0; i
< num_of_element
; i
++) {
755 if (!strcmp(str
, strs
[i
]))
761 static int svf_adjust_array_length(uint8_t **arr
, int orig_bit_len
, int new_bit_len
)
763 int new_byte_len
= (new_bit_len
+ 7) >> 3;
765 if ((NULL
== *arr
) || (((orig_bit_len
+ 7) >> 3) < ((new_bit_len
+ 7) >> 3))) {
770 *arr
= malloc(new_byte_len
);
772 LOG_ERROR("not enough memory");
775 memset(*arr
, 0, new_byte_len
);
780 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
)
782 int error
= ERROR_OK
;
783 error
|= svf_adjust_array_length(¶
->tdi
, para
->len
, len
);
784 memset(para
->tdi
, tdi
, (len
+ 7) >> 3);
785 error
|= svf_adjust_array_length(¶
->tdo
, para
->len
, len
);
786 error
|= svf_adjust_array_length(¶
->mask
, para
->len
, len
);
788 para
->data_mask
= XXR_TDI
;
793 static int svf_copy_hexstring_to_binary(char *str
, uint8_t **bin
, int orig_bit_len
, int bit_len
)
795 int i
, str_len
= strlen(str
), str_hbyte_len
= (bit_len
+ 3) >> 2;
798 if (ERROR_OK
!= svf_adjust_array_length(bin
, orig_bit_len
, bit_len
)) {
799 LOG_ERROR("fail to adjust length of array");
803 /* fill from LSB (end of str) to MSB (beginning of str) */
804 for (i
= 0; i
< str_hbyte_len
; i
++) {
806 while (str_len
> 0) {
809 /* Skip whitespace. The SVF specification (rev E) is
810 * deficient in terms of basic lexical issues like
811 * where whitespace is allowed. Long bitstrings may
812 * require line ends for correctness, since there is
813 * a hard limit on line length.
816 if ((ch
>= '0') && (ch
<= '9')) {
819 } else if ((ch
>= 'A') && (ch
<= 'F')) {
823 LOG_ERROR("invalid hex string");
834 (*bin
)[i
/ 2] |= ch
<< 4;
842 /* consume optional leading '0' MSBs or whitespace */
843 while (str_len
> 0 && ((str
[str_len
- 1] == '0')
844 || isspace((int) str
[str_len
- 1])))
847 /* check validity: we must have consumed everything */
848 if (str_len
> 0 || (ch
& ~((2 << ((bit_len
- 1) % 4)) - 1)) != 0) {
849 LOG_ERROR("value execeeds length");
856 static int svf_check_tdo(void)
858 int i
, len
, index_var
;
860 for (i
= 0; i
< svf_check_tdo_para_index
; i
++) {
861 index_var
= svf_check_tdo_para
[i
].buffer_offset
;
862 len
= svf_check_tdo_para
[i
].bit_len
;
863 if ((svf_check_tdo_para
[i
].enabled
)
864 && buf_cmp_mask(&svf_tdi_buffer
[index_var
], &svf_tdo_buffer
[index_var
],
865 &svf_mask_buffer
[index_var
], len
)) {
866 LOG_ERROR("tdo check error at line %d",
867 svf_check_tdo_para
[i
].line_num
);
868 SVF_BUF_LOG(ERROR
, &svf_tdi_buffer
[index_var
], len
, "READ");
869 SVF_BUF_LOG(ERROR
, &svf_tdo_buffer
[index_var
], len
, "WANT");
870 SVF_BUF_LOG(ERROR
, &svf_mask_buffer
[index_var
], len
, "MASK");
872 if (svf_ignore_error
== 0)
878 svf_check_tdo_para_index
= 0;
883 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
)
885 if (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
) {
886 LOG_ERROR("toooooo many operation undone");
890 svf_check_tdo_para
[svf_check_tdo_para_index
].line_num
= svf_line_number
;
891 svf_check_tdo_para
[svf_check_tdo_para_index
].bit_len
= bit_len
;
892 svf_check_tdo_para
[svf_check_tdo_para_index
].enabled
= enabled
;
893 svf_check_tdo_para
[svf_check_tdo_para_index
].buffer_offset
= buffer_offset
;
894 svf_check_tdo_para_index
++;
899 static int svf_execute_tap(void)
901 if ((!svf_nil
) && (ERROR_OK
!= jtag_execute_queue()))
903 else if (ERROR_OK
!= svf_check_tdo())
906 svf_buffer_index
= 0;
911 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
)
913 char *argus
[256], command
;
914 int num_of_argu
= 0, i
;
923 struct svf_xxr_para
*xxr_para_tmp
;
924 uint8_t **pbuffer_tmp
;
925 struct scan_field field
;
927 tap_state_t
*path
= NULL
, state
;
928 /* flag padding commands skipped due to -tap command */
929 int padding_command_skipped
= 0;
931 if (ERROR_OK
!= svf_parse_cmd_string(cmd_str
, strlen(cmd_str
), argus
, &num_of_argu
))
934 /* NOTE: we're a bit loose here, because we ignore case in
935 * TAP state names (instead of insisting on uppercase).
938 command
= svf_find_string_in_array(argus
[0],
939 (char **)svf_command_name
, ARRAY_SIZE(svf_command_name
));
943 if (num_of_argu
!= 2) {
944 LOG_ERROR("invalid parameter of %s", argus
[0]);
948 i_tmp
= tap_state_by_name(argus
[1]);
950 if (svf_tap_state_is_stable(i_tmp
)) {
951 if (command
== ENDIR
) {
952 svf_para
.ir_end_state
= i_tmp
;
953 LOG_DEBUG("\tIR end_state = %s",
954 tap_state_name(i_tmp
));
956 svf_para
.dr_end_state
= i_tmp
;
957 LOG_DEBUG("\tDR end_state = %s",
958 tap_state_name(i_tmp
));
961 LOG_ERROR("%s: %s is not a stable state",
967 if ((num_of_argu
!= 1) && (num_of_argu
!= 3)) {
968 LOG_ERROR("invalid parameter of %s", argus
[0]);
971 if (1 == num_of_argu
) {
972 /* TODO: set jtag speed to full speed */
973 svf_para
.frequency
= 0;
975 if (strcmp(argus
[2], "HZ")) {
976 LOG_ERROR("HZ not found in FREQUENCY command");
979 if (ERROR_OK
!= svf_execute_tap())
981 svf_para
.frequency
= atof(argus
[1]);
982 /* TODO: set jtag speed to */
983 if (svf_para
.frequency
> 0) {
984 command_run_linef(cmd_ctx
,
986 (int)svf_para
.frequency
/ 1000);
987 LOG_DEBUG("\tfrequency = %f", svf_para
.frequency
);
992 if (svf_tap_is_specified
) {
993 padding_command_skipped
= 1;
996 xxr_para_tmp
= &svf_para
.hdr_para
;
999 if (svf_tap_is_specified
) {
1000 padding_command_skipped
= 1;
1003 xxr_para_tmp
= &svf_para
.hir_para
;
1006 if (svf_tap_is_specified
) {
1007 padding_command_skipped
= 1;
1010 xxr_para_tmp
= &svf_para
.tdr_para
;
1013 if (svf_tap_is_specified
) {
1014 padding_command_skipped
= 1;
1017 xxr_para_tmp
= &svf_para
.tir_para
;
1020 xxr_para_tmp
= &svf_para
.sdr_para
;
1023 xxr_para_tmp
= &svf_para
.sir_para
;
1026 /* XXR length [TDI (tdi)] [TDO (tdo)][MASK (mask)] [SMASK (smask)] */
1027 if ((num_of_argu
> 10) || (num_of_argu
% 2)) {
1028 LOG_ERROR("invalid parameter of %s", argus
[0]);
1031 i_tmp
= xxr_para_tmp
->len
;
1032 xxr_para_tmp
->len
= atoi(argus
[1]);
1033 LOG_DEBUG("\tlength = %d", xxr_para_tmp
->len
);
1034 xxr_para_tmp
->data_mask
= 0;
1035 for (i
= 2; i
< num_of_argu
; i
+= 2) {
1036 if ((strlen(argus
[i
+ 1]) < 3) || (argus
[i
+ 1][0] != '(') ||
1037 (argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] != ')')) {
1038 LOG_ERROR("data section error");
1041 argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] = '\0';
1042 /* TDI, TDO, MASK, SMASK */
1043 if (!strcmp(argus
[i
], "TDI")) {
1045 pbuffer_tmp
= &xxr_para_tmp
->tdi
;
1046 xxr_para_tmp
->data_mask
|= XXR_TDI
;
1047 } else if (!strcmp(argus
[i
], "TDO")) {
1049 pbuffer_tmp
= &xxr_para_tmp
->tdo
;
1050 xxr_para_tmp
->data_mask
|= XXR_TDO
;
1051 } else if (!strcmp(argus
[i
], "MASK")) {
1053 pbuffer_tmp
= &xxr_para_tmp
->mask
;
1054 xxr_para_tmp
->data_mask
|= XXR_MASK
;
1055 } else if (!strcmp(argus
[i
], "SMASK")) {
1057 pbuffer_tmp
= &xxr_para_tmp
->smask
;
1058 xxr_para_tmp
->data_mask
|= XXR_SMASK
;
1060 LOG_ERROR("unknow parameter: %s", argus
[i
]);
1064 svf_copy_hexstring_to_binary(&argus
[i
+ 1][1], pbuffer_tmp
, i_tmp
,
1065 xxr_para_tmp
->len
)) {
1066 LOG_ERROR("fail to parse hex value");
1069 SVF_BUF_LOG(DEBUG
, *pbuffer_tmp
, xxr_para_tmp
->len
, argus
[i
]);
1071 /* If a command changes the length of the last scan of the same type and the
1072 * MASK parameter is absent, */
1073 /* the mask pattern used is all cares */
1074 if (!(xxr_para_tmp
->data_mask
& XXR_MASK
) && (i_tmp
!= xxr_para_tmp
->len
)) {
1075 /* MASK not defined and length changed */
1077 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1078 xxr_para_tmp
->len
)) {
1079 LOG_ERROR("fail to adjust length of array");
1082 buf_set_ones(xxr_para_tmp
->mask
, xxr_para_tmp
->len
);
1084 /* If TDO is absent, no comparison is needed, set the mask to 0 */
1085 if (!(xxr_para_tmp
->data_mask
& XXR_TDO
)) {
1086 if (NULL
== xxr_para_tmp
->tdo
) {
1088 svf_adjust_array_length(&xxr_para_tmp
->tdo
, i_tmp
,
1089 xxr_para_tmp
->len
)) {
1090 LOG_ERROR("fail to adjust length of array");
1094 if (NULL
== xxr_para_tmp
->mask
) {
1096 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1097 xxr_para_tmp
->len
)) {
1098 LOG_ERROR("fail to adjust length of array");
1102 memset(xxr_para_tmp
->mask
, 0, (xxr_para_tmp
->len
+ 7) >> 3);
1104 /* do scan if necessary */
1105 if (SDR
== command
) {
1106 /* check buffer size first, reallocate if necessary */
1107 i
= svf_para
.hdr_para
.len
+ svf_para
.sdr_para
.len
+
1108 svf_para
.tdr_para
.len
;
1109 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1110 /* reallocate buffer */
1111 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1112 LOG_ERROR("not enough memory");
1117 /* assemble dr data */
1119 buf_set_buf(svf_para
.hdr_para
.tdi
,
1121 &svf_tdi_buffer
[svf_buffer_index
],
1123 svf_para
.hdr_para
.len
);
1124 i
+= svf_para
.hdr_para
.len
;
1125 buf_set_buf(svf_para
.sdr_para
.tdi
,
1127 &svf_tdi_buffer
[svf_buffer_index
],
1129 svf_para
.sdr_para
.len
);
1130 i
+= svf_para
.sdr_para
.len
;
1131 buf_set_buf(svf_para
.tdr_para
.tdi
,
1133 &svf_tdi_buffer
[svf_buffer_index
],
1135 svf_para
.tdr_para
.len
);
1136 i
+= svf_para
.tdr_para
.len
;
1138 /* add check data */
1139 if (svf_para
.sdr_para
.data_mask
& XXR_TDO
) {
1140 /* assemble dr mask data */
1142 buf_set_buf(svf_para
.hdr_para
.mask
,
1144 &svf_mask_buffer
[svf_buffer_index
],
1146 svf_para
.hdr_para
.len
);
1147 i
+= svf_para
.hdr_para
.len
;
1148 buf_set_buf(svf_para
.sdr_para
.mask
,
1150 &svf_mask_buffer
[svf_buffer_index
],
1152 svf_para
.sdr_para
.len
);
1153 i
+= svf_para
.sdr_para
.len
;
1154 buf_set_buf(svf_para
.tdr_para
.mask
,
1156 &svf_mask_buffer
[svf_buffer_index
],
1158 svf_para
.tdr_para
.len
);
1160 /* assemble dr check data */
1162 buf_set_buf(svf_para
.hdr_para
.tdo
,
1164 &svf_tdo_buffer
[svf_buffer_index
],
1166 svf_para
.hdr_para
.len
);
1167 i
+= svf_para
.hdr_para
.len
;
1168 buf_set_buf(svf_para
.sdr_para
.tdo
,
1170 &svf_tdo_buffer
[svf_buffer_index
],
1172 svf_para
.sdr_para
.len
);
1173 i
+= svf_para
.sdr_para
.len
;
1174 buf_set_buf(svf_para
.tdr_para
.tdo
,
1176 &svf_tdo_buffer
[svf_buffer_index
],
1178 svf_para
.tdr_para
.len
);
1179 i
+= svf_para
.tdr_para
.len
;
1181 svf_add_check_para(1, svf_buffer_index
, i
);
1183 svf_add_check_para(0, svf_buffer_index
, i
);
1185 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1186 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1188 /* NOTE: doesn't use SVF-specified state paths */
1189 jtag_add_plain_dr_scan(field
.num_bits
,
1192 svf_para
.dr_end_state
);
1195 svf_buffer_index
+= (i
+ 7) >> 3;
1196 } else if (SIR
== command
) {
1197 /* check buffer size first, reallocate if necessary */
1198 i
= svf_para
.hir_para
.len
+ svf_para
.sir_para
.len
+
1199 svf_para
.tir_para
.len
;
1200 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1201 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1202 LOG_ERROR("not enough memory");
1207 /* assemble ir data */
1209 buf_set_buf(svf_para
.hir_para
.tdi
,
1211 &svf_tdi_buffer
[svf_buffer_index
],
1213 svf_para
.hir_para
.len
);
1214 i
+= svf_para
.hir_para
.len
;
1215 buf_set_buf(svf_para
.sir_para
.tdi
,
1217 &svf_tdi_buffer
[svf_buffer_index
],
1219 svf_para
.sir_para
.len
);
1220 i
+= svf_para
.sir_para
.len
;
1221 buf_set_buf(svf_para
.tir_para
.tdi
,
1223 &svf_tdi_buffer
[svf_buffer_index
],
1225 svf_para
.tir_para
.len
);
1226 i
+= svf_para
.tir_para
.len
;
1228 /* add check data */
1229 if (svf_para
.sir_para
.data_mask
& XXR_TDO
) {
1230 /* assemble dr mask data */
1232 buf_set_buf(svf_para
.hir_para
.mask
,
1234 &svf_mask_buffer
[svf_buffer_index
],
1236 svf_para
.hir_para
.len
);
1237 i
+= svf_para
.hir_para
.len
;
1238 buf_set_buf(svf_para
.sir_para
.mask
,
1240 &svf_mask_buffer
[svf_buffer_index
],
1242 svf_para
.sir_para
.len
);
1243 i
+= svf_para
.sir_para
.len
;
1244 buf_set_buf(svf_para
.tir_para
.mask
,
1246 &svf_mask_buffer
[svf_buffer_index
],
1248 svf_para
.tir_para
.len
);
1250 /* assemble dr check data */
1252 buf_set_buf(svf_para
.hir_para
.tdo
,
1254 &svf_tdo_buffer
[svf_buffer_index
],
1256 svf_para
.hir_para
.len
);
1257 i
+= svf_para
.hir_para
.len
;
1258 buf_set_buf(svf_para
.sir_para
.tdo
,
1260 &svf_tdo_buffer
[svf_buffer_index
],
1262 svf_para
.sir_para
.len
);
1263 i
+= svf_para
.sir_para
.len
;
1264 buf_set_buf(svf_para
.tir_para
.tdo
,
1266 &svf_tdo_buffer
[svf_buffer_index
],
1268 svf_para
.tir_para
.len
);
1269 i
+= svf_para
.tir_para
.len
;
1271 svf_add_check_para(1, svf_buffer_index
, i
);
1273 svf_add_check_para(0, svf_buffer_index
, i
);
1275 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1276 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1278 /* NOTE: doesn't use SVF-specified state paths */
1279 jtag_add_plain_ir_scan(field
.num_bits
,
1282 svf_para
.ir_end_state
);
1285 svf_buffer_index
+= (i
+ 7) >> 3;
1290 LOG_ERROR("PIO and PIOMAP are not supported");
1294 /* RUNTEST [run_state] run_count run_clk [min_time SEC [MAXIMUM max_time
1295 * SEC]] [ENDSTATE end_state] */
1296 /* RUNTEST [run_state] min_time SEC [MAXIMUM max_time SEC] [ENDSTATE
1298 if ((num_of_argu
< 3) && (num_of_argu
> 11)) {
1299 LOG_ERROR("invalid parameter of %s", argus
[0]);
1308 i_tmp
= tap_state_by_name(argus
[i
]);
1309 if (i_tmp
!= TAP_INVALID
) {
1310 if (svf_tap_state_is_stable(i_tmp
)) {
1311 svf_para
.runtest_run_state
= i_tmp
;
1313 /* When a run_state is specified, the new
1314 * run_state becomes the default end_state.
1316 svf_para
.runtest_end_state
= i_tmp
;
1317 LOG_DEBUG("\trun_state = %s", tap_state_name(i_tmp
));
1320 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1325 /* run_count run_clk */
1326 if (((i
+ 2) <= num_of_argu
) && strcmp(argus
[i
+ 1], "SEC")) {
1327 if (!strcmp(argus
[i
+ 1], "TCK")) {
1328 /* clock source is TCK */
1329 run_count
= atoi(argus
[i
]);
1330 LOG_DEBUG("\trun_count@TCK = %d", run_count
);
1332 LOG_ERROR("%s not supported for clock", argus
[i
+ 1]);
1338 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
+ 1], "SEC")) {
1339 min_time
= atof(argus
[i
]);
1340 LOG_DEBUG("\tmin_time = %fs", min_time
);
1343 /* MAXIMUM max_time SEC */
1344 if (((i
+ 3) <= num_of_argu
) &&
1345 !strcmp(argus
[i
], "MAXIMUM") && !strcmp(argus
[i
+ 2], "SEC")) {
1347 max_time
= atof(argus
[i
+ 1]);
1348 LOG_DEBUG("\tmax_time = %fs", max_time
);
1351 /* ENDSTATE end_state */
1352 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
], "ENDSTATE")) {
1353 i_tmp
= tap_state_by_name(argus
[i
+ 1]);
1355 if (svf_tap_state_is_stable(i_tmp
)) {
1356 svf_para
.runtest_end_state
= i_tmp
;
1357 LOG_DEBUG("\tend_state = %s", tap_state_name(i_tmp
));
1359 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1365 /* all parameter should be parsed */
1366 if (i
== num_of_argu
) {
1368 /* FIXME handle statemove failures */
1369 uint32_t min_usec
= 1000000 * min_time
;
1371 /* enter into run_state if necessary */
1372 if (cmd_queue_cur_state
!= svf_para
.runtest_run_state
)
1373 svf_add_statemove(svf_para
.runtest_run_state
);
1375 /* add clocks and/or min wait */
1376 if (run_count
> 0) {
1378 jtag_add_clocks(run_count
);
1383 jtag_add_sleep(min_usec
);
1386 /* move to end_state if necessary */
1387 if (svf_para
.runtest_end_state
!= svf_para
.runtest_run_state
)
1388 svf_add_statemove(svf_para
.runtest_end_state
);
1391 if (svf_para
.runtest_run_state
!= TAP_IDLE
) {
1392 LOG_ERROR("cannot runtest in %s state",
1393 tap_state_name(svf_para
.runtest_run_state
));
1398 jtag_add_runtest(run_count
, svf_para
.runtest_end_state
);
1401 LOG_ERROR("fail to parse parameter of RUNTEST, %d out of %d is parsed",
1408 /* STATE [pathstate1 [pathstate2 ...[pathstaten]]] stable_state */
1409 if (num_of_argu
< 2) {
1410 LOG_ERROR("invalid parameter of %s", argus
[0]);
1413 if (num_of_argu
> 2) {
1414 /* STATE pathstate1 ... stable_state */
1415 path
= malloc((num_of_argu
- 1) * sizeof(tap_state_t
));
1417 LOG_ERROR("not enough memory");
1420 num_of_argu
--; /* num of path */
1421 i_tmp
= 1; /* path is from parameter 1 */
1422 for (i
= 0; i
< num_of_argu
; i
++, i_tmp
++) {
1423 path
[i
] = tap_state_by_name(argus
[i_tmp
]);
1424 if (path
[i
] == TAP_INVALID
) {
1425 LOG_ERROR("%s: %s is not a valid state", argus
[0], argus
[i_tmp
]);
1429 /* OpenOCD refuses paths containing TAP_RESET */
1430 if (TAP_RESET
== path
[i
]) {
1431 /* FIXME last state MUST be stable! */
1434 jtag_add_pathmove(i
, path
);
1438 num_of_argu
-= i
+ 1;
1442 if (num_of_argu
> 0) {
1443 /* execute last path if necessary */
1444 if (svf_tap_state_is_stable(path
[num_of_argu
- 1])) {
1445 /* last state MUST be stable state */
1447 jtag_add_pathmove(num_of_argu
, path
);
1448 LOG_DEBUG("\tmove to %s by path_move",
1449 tap_state_name(path
[num_of_argu
- 1]));
1451 LOG_ERROR("%s: %s is not a stable state",
1453 tap_state_name(path
[num_of_argu
- 1]));
1462 /* STATE stable_state */
1463 state
= tap_state_by_name(argus
[1]);
1464 if (svf_tap_state_is_stable(state
)) {
1465 LOG_DEBUG("\tmove to %s by svf_add_statemove",
1466 tap_state_name(state
));
1467 /* FIXME handle statemove failures */
1468 svf_add_statemove(state
);
1470 LOG_ERROR("%s: %s is not a stable state",
1471 argus
[0], tap_state_name(state
));
1477 /* TRST trst_mode */
1478 if (num_of_argu
!= 2) {
1479 LOG_ERROR("invalid parameter of %s", argus
[0]);
1482 if (svf_para
.trst_mode
!= TRST_ABSENT
) {
1483 if (ERROR_OK
!= svf_execute_tap())
1485 i_tmp
= svf_find_string_in_array(argus
[1],
1486 (char **)svf_trst_mode_name
,
1487 ARRAY_SIZE(svf_trst_mode_name
));
1491 jtag_add_reset(1, 0);
1496 jtag_add_reset(0, 0);
1501 LOG_ERROR("unknown TRST mode: %s", argus
[1]);
1504 svf_para
.trst_mode
= i_tmp
;
1505 LOG_DEBUG("\ttrst_mode = %s", svf_trst_mode_name
[svf_para
.trst_mode
]);
1507 LOG_ERROR("can not accpet TRST command if trst_mode is ABSENT");
1512 LOG_ERROR("invalid svf command: %s", argus
[0]);
1518 if (padding_command_skipped
)
1519 LOG_USER("(Above Padding command skipped, as per -tap argument)");
1522 if (debug_level
>= LOG_LVL_DEBUG
) {
1523 /* for convenient debugging, execute tap if possible */
1524 if ((svf_buffer_index
> 0) && \
1525 (((command
!= STATE
) && (command
!= RUNTEST
)) || \
1526 ((command
== STATE
) && (num_of_argu
== 2)))) {
1527 if (ERROR_OK
!= svf_execute_tap())
1530 /* output debug info */
1531 if ((SIR
== command
) || (SDR
== command
)) {
1532 SVF_BUF_LOG(DEBUG
, svf_tdi_buffer
, svf_check_tdo_para
[0].bit_len
, "TDO read");
1536 /* for fast executing, execute tap if necessary */
1537 /* half of the buffer is for the next command */
1538 if (((svf_buffer_index
>= SVF_MAX_BUFFER_SIZE_TO_COMMIT
) ||
1539 (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
/ 2)) && \
1540 (((command
!= STATE
) && (command
!= RUNTEST
)) || \
1541 ((command
== STATE
) && (num_of_argu
== 2))))
1542 return svf_execute_tap();
1548 static const struct command_registration svf_command_handlers
[] = {
1551 .handler
= handle_svf_command
,
1552 .mode
= COMMAND_EXEC
,
1553 .help
= "Runs a SVF file.",
1554 .usage
= "svf [-tap device.tap] <file> [quiet] [nil] [progress] [ignore_error]",
1556 COMMAND_REGISTRATION_DONE
1559 int svf_register_commands(struct command_context
*cmd_ctx
)
1561 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)