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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
19 /* The specification for SVF is available here:
20 * http://www.asset-intertech.com/support/svf.pdf
21 * Below, this document is referred to as the "SVF spec".
23 * The specification for XSVF is available here:
24 * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf
25 * Below, this document is referred to as the "XSVF spec".
32 #include <jtag/jtag.h>
34 #include "helper/system.h"
35 #include <helper/time_support.h>
55 static const char *svf_command_name
[14] = {
79 static const char *svf_trst_mode_name
[4] = {
86 struct svf_statemove
{
89 uint32_t num_of_moves
;
94 * These paths are from the SVF specification for the STATE command, to be
95 * used when the STATE command only includes the final state. The first
96 * element of the path is the "from" (current) state, and the last one is
97 * the "to" (target) state.
99 * All specified paths are the shortest ones in the JTAG spec, and are thus
100 * not (!!) exact matches for the paths used elsewhere in OpenOCD. Note
101 * that PAUSE-to-PAUSE transitions all go through UPDATE and then CAPTURE,
102 * which has specific effects on the various registers; they are not NOPs.
104 * Paths to RESET are disabled here. As elsewhere in OpenOCD, and in XSVF
105 * and many SVF implementations, we don't want to risk missing that state.
106 * To get to RESET, always we ignore the current state.
108 static const struct svf_statemove svf_statemoves
[] = {
109 /* from to num_of_moves, paths[8] */
110 /* {TAP_RESET, TAP_RESET, 1, {TAP_RESET}}, */
111 {TAP_RESET
, TAP_IDLE
, 2, {TAP_RESET
, TAP_IDLE
} },
112 {TAP_RESET
, TAP_DRPAUSE
, 6, {TAP_RESET
, TAP_IDLE
, TAP_DRSELECT
,
113 TAP_DRCAPTURE
, TAP_DREXIT1
, TAP_DRPAUSE
} },
114 {TAP_RESET
, TAP_IRPAUSE
, 7, {TAP_RESET
, TAP_IDLE
, TAP_DRSELECT
,
115 TAP_IRSELECT
, TAP_IRCAPTURE
,
116 TAP_IREXIT1
, TAP_IRPAUSE
} },
118 /* {TAP_IDLE, TAP_RESET, 4, {TAP_IDLE,
119 * TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
120 {TAP_IDLE
, TAP_IDLE
, 1, {TAP_IDLE
} },
121 {TAP_IDLE
, TAP_DRPAUSE
, 5, {TAP_IDLE
, TAP_DRSELECT
, TAP_DRCAPTURE
,
122 TAP_DREXIT1
, TAP_DRPAUSE
} },
123 {TAP_IDLE
, TAP_IRPAUSE
, 6, {TAP_IDLE
, TAP_DRSELECT
, TAP_IRSELECT
,
124 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} },
126 /* {TAP_DRPAUSE, TAP_RESET, 6, {TAP_DRPAUSE,
127 * TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
128 {TAP_DRPAUSE
, TAP_IDLE
, 4, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
130 {TAP_DRPAUSE
, TAP_DRPAUSE
, 7, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
131 TAP_DRSELECT
, TAP_DRCAPTURE
,
132 TAP_DREXIT1
, TAP_DRPAUSE
} },
133 {TAP_DRPAUSE
, TAP_IRPAUSE
, 8, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
134 TAP_DRSELECT
, TAP_IRSELECT
,
135 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} },
137 /* {TAP_IRPAUSE, TAP_RESET, 6, {TAP_IRPAUSE,
138 * TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
139 {TAP_IRPAUSE
, TAP_IDLE
, 4, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
141 {TAP_IRPAUSE
, TAP_DRPAUSE
, 7, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
142 TAP_DRSELECT
, TAP_DRCAPTURE
,
143 TAP_DREXIT1
, TAP_DRPAUSE
} },
144 {TAP_IRPAUSE
, TAP_IRPAUSE
, 8, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
145 TAP_DRSELECT
, TAP_IRSELECT
,
146 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} }
149 #define XXR_TDI (1 << 0)
150 #define XXR_TDO (1 << 1)
151 #define XXR_MASK (1 << 2)
152 #define XXR_SMASK (1 << 3)
153 struct svf_xxr_para
{
164 tap_state_t ir_end_state
;
165 tap_state_t dr_end_state
;
166 tap_state_t runtest_run_state
;
167 tap_state_t runtest_end_state
;
168 enum trst_mode trst_mode
;
170 struct svf_xxr_para hir_para
;
171 struct svf_xxr_para hdr_para
;
172 struct svf_xxr_para tir_para
;
173 struct svf_xxr_para tdr_para
;
174 struct svf_xxr_para sir_para
;
175 struct svf_xxr_para sdr_para
;
178 static struct svf_para svf_para
;
179 static const struct svf_para svf_para_init
= {
180 /* frequency, ir_end_state, dr_end_state, runtest_run_state, runtest_end_state, trst_mode */
181 0, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TRST_Z
,
183 /* {len, data_mask, tdi, tdo, mask, smask}, */
184 {0, 0, NULL
, NULL
, NULL
, NULL
},
186 /* {len, data_mask, tdi, tdo, mask, smask}, */
187 {0, 0, NULL
, NULL
, NULL
, NULL
},
189 /* {len, data_mask, tdi, tdo, mask, smask}, */
190 {0, 0, NULL
, NULL
, NULL
, NULL
},
192 /* {len, data_mask, tdi, tdo, mask, smask}, */
193 {0, 0, NULL
, NULL
, NULL
, NULL
},
195 /* {len, data_mask, tdi, tdo, mask, smask}, */
196 {0, 0, NULL
, NULL
, NULL
, NULL
},
198 /* {len, data_mask, tdi, tdo, mask, smask}, */
199 {0, 0, NULL
, NULL
, NULL
, NULL
},
202 struct svf_check_tdo_para
{
203 int line_num
; /* used to record line number of the check operation */
204 /* so more information could be printed */
205 int enabled
; /* check is enabled or not */
206 int buffer_offset
; /* buffer_offset to buffers */
207 int bit_len
; /* bit length to check */
210 #define SVF_CHECK_TDO_PARA_SIZE 1024
211 static struct svf_check_tdo_para
*svf_check_tdo_para
;
212 static int svf_check_tdo_para_index
;
214 static int svf_read_command_from_file(FILE *fd
);
215 static int svf_check_tdo(void);
216 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
);
217 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
);
218 static int svf_execute_tap(void);
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
;
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 /* Targeting 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) + 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 if (svf_execute_tap() != ERROR_OK
)
283 ptr
= realloc(svf_tdi_buffer
, len
);
286 svf_tdi_buffer
= ptr
;
288 ptr
= realloc(svf_tdo_buffer
, len
);
291 svf_tdo_buffer
= ptr
;
293 ptr
= realloc(svf_mask_buffer
, len
);
296 svf_mask_buffer
= ptr
;
298 svf_buffer_size
= len
;
303 static void svf_free_xxd_para(struct svf_xxr_para
*para
)
320 int svf_add_statemove(tap_state_t state_to
)
322 tap_state_t state_from
= cmd_queue_cur_state
;
325 /* when resetting, be paranoid and ignore current state */
326 if (state_to
== TAP_RESET
) {
334 for (index_var
= 0; index_var
< ARRAY_SIZE(svf_statemoves
); index_var
++) {
335 if ((svf_statemoves
[index_var
].from
== state_from
)
336 && (svf_statemoves
[index_var
].to
== state_to
)) {
339 /* recorded path includes current state ... avoid
341 if (svf_statemoves
[index_var
].num_of_moves
> 1)
342 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
- 1,
343 svf_statemoves
[index_var
].paths
+ 1);
345 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
,
346 svf_statemoves
[index_var
].paths
);
350 LOG_ERROR("SVF: can not move to %s", tap_state_name(state_to
));
354 COMMAND_HANDLER(handle_svf_command
)
356 #define SVF_MIN_NUM_OF_OPTIONS 1
357 #define SVF_MAX_NUM_OF_OPTIONS 5
360 int64_t time_measure_ms
;
361 int time_measure_s
, time_measure_m
;
363 /* use NULL to indicate a "plain" svf file which accounts for
364 * any additional devices in the scan chain, otherwise the device
365 * that should be affected
367 struct jtag_tap
*tap
= NULL
;
369 if ((CMD_ARGC
< SVF_MIN_NUM_OF_OPTIONS
) || (CMD_ARGC
> SVF_MAX_NUM_OF_OPTIONS
))
370 return ERROR_COMMAND_SYNTAX_ERROR
;
372 /* parse command line */
375 svf_progress_enabled
= 0;
376 svf_ignore_error
= 0;
377 for (unsigned int i
= 0; i
< CMD_ARGC
; i
++) {
378 if (strcmp(CMD_ARGV
[i
], "-tap") == 0) {
379 tap
= jtag_tap_by_string(CMD_ARGV
[i
+1]);
381 command_print(CMD
, "Tap: %s unknown", CMD_ARGV
[i
+1]);
385 } else if ((strcmp(CMD_ARGV
[i
],
386 "quiet") == 0) || (strcmp(CMD_ARGV
[i
], "-quiet") == 0))
388 else if ((strcmp(CMD_ARGV
[i
], "nil") == 0) || (strcmp(CMD_ARGV
[i
], "-nil") == 0))
390 else if ((strcmp(CMD_ARGV
[i
],
391 "progress") == 0) || (strcmp(CMD_ARGV
[i
], "-progress") == 0))
392 svf_progress_enabled
= 1;
393 else if ((strcmp(CMD_ARGV
[i
],
394 "ignore_error") == 0) || (strcmp(CMD_ARGV
[i
], "-ignore_error") == 0))
395 svf_ignore_error
= 1;
397 svf_fd
= fopen(CMD_ARGV
[i
], "r");
398 if (svf_fd
== NULL
) {
400 command_print(CMD
, "open(\"%s\"): %s", CMD_ARGV
[i
], strerror(err
));
401 /* no need to free anything now */
402 return ERROR_COMMAND_SYNTAX_ERROR
;
404 LOG_USER("svf processing file: \"%s\"", CMD_ARGV
[i
]);
409 return ERROR_COMMAND_SYNTAX_ERROR
;
412 time_measure_ms
= timeval_ms();
416 svf_command_buffer_size
= 0;
418 svf_check_tdo_para_index
= 0;
419 svf_check_tdo_para
= malloc(sizeof(struct svf_check_tdo_para
) * SVF_CHECK_TDO_PARA_SIZE
);
420 if (NULL
== svf_check_tdo_para
) {
421 LOG_ERROR("not enough memory");
426 svf_buffer_index
= 0;
427 /* double the buffer size */
428 /* in case current command cannot be committed, and next command is a bit scan command */
429 /* here is 32K bits for this big scan command, it should be enough */
430 /* buffer will be reallocated if buffer size is not enough */
431 if (svf_realloc_buffers(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT
) != ERROR_OK
) {
436 memcpy(&svf_para
, &svf_para_init
, sizeof(svf_para
));
444 /* Tap is specified, set header/trailer paddings */
445 int header_ir_len
= 0, header_dr_len
= 0, trailer_ir_len
= 0, trailer_dr_len
= 0;
446 struct jtag_tap
*check_tap
;
448 svf_tap_is_specified
= 1;
450 for (check_tap
= jtag_all_taps(); check_tap
; check_tap
= check_tap
->next_tap
) {
451 if (check_tap
->abs_chain_position
< tap
->abs_chain_position
) {
453 header_ir_len
+= check_tap
->ir_length
;
455 } else if (check_tap
->abs_chain_position
> tap
->abs_chain_position
) {
457 trailer_ir_len
+= check_tap
->ir_length
;
463 if (ERROR_OK
!= svf_set_padding(&svf_para
.hdr_para
, header_dr_len
, 0)) {
464 LOG_ERROR("failed to set data header");
468 /* HIR %d TDI (0xFF) */
469 if (ERROR_OK
!= svf_set_padding(&svf_para
.hir_para
, header_ir_len
, 0xFF)) {
470 LOG_ERROR("failed to set instruction header");
475 if (ERROR_OK
!= svf_set_padding(&svf_para
.tdr_para
, trailer_dr_len
, 0)) {
476 LOG_ERROR("failed to set data trailer");
480 /* TIR %d TDI (0xFF) */
481 if (ERROR_OK
!= svf_set_padding(&svf_para
.tir_para
, trailer_ir_len
, 0xFF)) {
482 LOG_ERROR("failed to set instruction trailer");
487 if (svf_progress_enabled
) {
488 /* Count total lines in file. */
489 while (!feof(svf_fd
)) {
490 svf_getline(&svf_command_buffer
, &svf_command_buffer_size
, svf_fd
);
495 while (ERROR_OK
== svf_read_command_from_file(svf_fd
)) {
498 if (svf_progress_enabled
) {
499 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
500 if (svf_last_printed_percentage
!= svf_percentage
) {
501 LOG_USER_N("\r%d%% ", svf_percentage
);
502 svf_last_printed_percentage
= svf_percentage
;
506 if (svf_progress_enabled
) {
507 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
508 LOG_USER_N("%3d%% %s", svf_percentage
, svf_read_line
);
510 LOG_USER_N("%s", svf_read_line
);
513 if (ERROR_OK
!= svf_run_command(CMD_CTX
, svf_command_buffer
)) {
514 LOG_ERROR("fail to run command at line %d", svf_line_number
);
521 if ((!svf_nil
) && (ERROR_OK
!= jtag_execute_queue()))
523 else if (ERROR_OK
!= svf_check_tdo())
527 time_measure_ms
= timeval_ms() - time_measure_ms
;
528 time_measure_s
= time_measure_ms
/ 1000;
529 time_measure_ms
%= 1000;
530 time_measure_m
= time_measure_s
/ 60;
531 time_measure_s
%= 60;
532 if (time_measure_ms
< 1000)
534 "\r\nTime used: %dm%ds%" PRId64
"ms ",
545 free(svf_command_buffer
);
546 svf_command_buffer
= NULL
;
547 svf_command_buffer_size
= 0;
549 free(svf_check_tdo_para
);
550 svf_check_tdo_para
= NULL
;
551 svf_check_tdo_para_index
= 0;
553 free(svf_tdi_buffer
);
554 svf_tdi_buffer
= NULL
;
556 free(svf_tdo_buffer
);
557 svf_tdo_buffer
= NULL
;
559 free(svf_mask_buffer
);
560 svf_mask_buffer
= NULL
;
562 svf_buffer_index
= 0;
565 svf_free_xxd_para(&svf_para
.hdr_para
);
566 svf_free_xxd_para(&svf_para
.hir_para
);
567 svf_free_xxd_para(&svf_para
.tdr_para
);
568 svf_free_xxd_para(&svf_para
.tir_para
);
569 svf_free_xxd_para(&svf_para
.sdr_para
);
570 svf_free_xxd_para(&svf_para
.sir_para
);
574 "svf file programmed %s for %d commands with %d errors",
575 (svf_ignore_error
> 1) ? "unsuccessfully" : "successfully",
577 (svf_ignore_error
> 1) ? (svf_ignore_error
- 1) : 0);
579 command_print(CMD
, "svf file programmed failed");
581 svf_ignore_error
= 0;
585 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
)
587 #define MIN_CHUNK 16 /* Buffer is increased by this size each time as required */
590 if (*lineptr
== NULL
) {
592 *lineptr
= malloc(*n
);
597 (*lineptr
)[0] = fgetc(stream
);
598 while ((*lineptr
)[i
] != '\n') {
599 (*lineptr
)[++i
] = fgetc(stream
);
606 *lineptr
= realloc(*lineptr
, *n
);
612 return sizeof(*lineptr
);
615 #define SVFP_CMD_INC_CNT 1024
616 static int svf_read_command_from_file(FILE *fd
)
621 int cmd_ok
= 0, slash
= 0;
623 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
626 ch
= svf_read_line
[0];
627 while (!cmd_ok
&& (ch
!= 0)) {
631 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
639 if (svf_getline(&svf_read_line
, &svf_read_line_size
,
652 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
658 /* Don't save '\r' and '\n' if no data is parsed */
663 /* The parsing code currently expects a space
664 * before parentheses -- "TDI (123)". Also a
665 * space afterwards -- "TDI (123) TDO(456)".
666 * But such spaces are optional... instead of
667 * parser updates, cope with that by adding the
670 * Ensure there are 3 bytes available, for:
671 * - current character
673 * - terminating NUL ('\0')
675 if (cmd_pos
+ 3 > svf_command_buffer_size
) {
676 svf_command_buffer
= realloc(svf_command_buffer
, cmd_pos
+ 3);
677 svf_command_buffer_size
= cmd_pos
+ 3;
678 if (svf_command_buffer
== NULL
) {
679 LOG_ERROR("not enough memory");
684 /* insert a space before '(' */
686 svf_command_buffer
[cmd_pos
++] = ' ';
688 svf_command_buffer
[cmd_pos
++] = (char)toupper(ch
);
690 /* insert a space after ')' */
692 svf_command_buffer
[cmd_pos
++] = ' ';
695 ch
= svf_read_line
[++i
];
699 svf_command_buffer
[cmd_pos
] = '\0';
705 static int svf_parse_cmd_string(char *str
, int len
, char **argus
, int *num_of_argu
)
707 int pos
= 0, num
= 0, space_found
= 1, in_bracket
= 0;
713 LOG_ERROR("fail to parse svf command");
723 if (!in_bracket
&& isspace((int) str
[pos
])) {
726 } else if (space_found
) {
727 argus
[num
++] = &str
[pos
];
743 bool svf_tap_state_is_stable(tap_state_t state
)
745 return (TAP_RESET
== state
) || (TAP_IDLE
== state
)
746 || (TAP_DRPAUSE
== state
) || (TAP_IRPAUSE
== state
);
749 static int svf_find_string_in_array(char *str
, char **strs
, int num_of_element
)
753 for (i
= 0; i
< num_of_element
; i
++) {
754 if (!strcmp(str
, strs
[i
]))
760 static int svf_adjust_array_length(uint8_t **arr
, int orig_bit_len
, int new_bit_len
)
762 int new_byte_len
= (new_bit_len
+ 7) >> 3;
764 if ((NULL
== *arr
) || (((orig_bit_len
+ 7) >> 3) < ((new_bit_len
+ 7) >> 3))) {
766 *arr
= calloc(1, new_byte_len
);
768 LOG_ERROR("not enough memory");
775 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
)
777 int error
= ERROR_OK
;
778 error
|= svf_adjust_array_length(¶
->tdi
, para
->len
, len
);
779 memset(para
->tdi
, tdi
, (len
+ 7) >> 3);
780 error
|= svf_adjust_array_length(¶
->tdo
, para
->len
, len
);
781 error
|= svf_adjust_array_length(¶
->mask
, para
->len
, len
);
783 para
->data_mask
= XXR_TDI
;
788 static int svf_copy_hexstring_to_binary(char *str
, uint8_t **bin
, int orig_bit_len
, int bit_len
)
790 int i
, str_len
= strlen(str
), str_hbyte_len
= (bit_len
+ 3) >> 2;
793 if (ERROR_OK
!= svf_adjust_array_length(bin
, orig_bit_len
, bit_len
)) {
794 LOG_ERROR("fail to adjust length of array");
798 /* fill from LSB (end of str) to MSB (beginning of str) */
799 for (i
= 0; i
< str_hbyte_len
; i
++) {
801 while (str_len
> 0) {
804 /* Skip whitespace. The SVF specification (rev E) is
805 * deficient in terms of basic lexical issues like
806 * where whitespace is allowed. Long bitstrings may
807 * require line ends for correctness, since there is
808 * a hard limit on line length.
811 if ((ch
>= '0') && (ch
<= '9')) {
814 } else if ((ch
>= 'A') && (ch
<= 'F')) {
818 LOG_ERROR("invalid hex string");
829 (*bin
)[i
/ 2] |= ch
<< 4;
837 /* consume optional leading '0' MSBs or whitespace */
838 while (str_len
> 0 && ((str
[str_len
- 1] == '0')
839 || isspace((int) str
[str_len
- 1])))
842 /* check validity: we must have consumed everything */
843 if (str_len
> 0 || (ch
& ~((2 << ((bit_len
- 1) % 4)) - 1)) != 0) {
844 LOG_ERROR("value exceeds length");
851 static int svf_check_tdo(void)
853 int i
, len
, index_var
;
855 for (i
= 0; i
< svf_check_tdo_para_index
; i
++) {
856 index_var
= svf_check_tdo_para
[i
].buffer_offset
;
857 len
= svf_check_tdo_para
[i
].bit_len
;
858 if ((svf_check_tdo_para
[i
].enabled
)
859 && buf_cmp_mask(&svf_tdi_buffer
[index_var
], &svf_tdo_buffer
[index_var
],
860 &svf_mask_buffer
[index_var
], len
)) {
861 LOG_ERROR("tdo check error at line %d",
862 svf_check_tdo_para
[i
].line_num
);
863 SVF_BUF_LOG(ERROR
, &svf_tdi_buffer
[index_var
], len
, "READ");
864 SVF_BUF_LOG(ERROR
, &svf_tdo_buffer
[index_var
], len
, "WANT");
865 SVF_BUF_LOG(ERROR
, &svf_mask_buffer
[index_var
], len
, "MASK");
867 if (svf_ignore_error
== 0)
873 svf_check_tdo_para_index
= 0;
878 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
)
880 if (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
) {
881 LOG_ERROR("toooooo many operation undone");
885 svf_check_tdo_para
[svf_check_tdo_para_index
].line_num
= svf_line_number
;
886 svf_check_tdo_para
[svf_check_tdo_para_index
].bit_len
= bit_len
;
887 svf_check_tdo_para
[svf_check_tdo_para_index
].enabled
= enabled
;
888 svf_check_tdo_para
[svf_check_tdo_para_index
].buffer_offset
= buffer_offset
;
889 svf_check_tdo_para_index
++;
894 static int svf_execute_tap(void)
896 if ((!svf_nil
) && (ERROR_OK
!= jtag_execute_queue()))
898 else if (ERROR_OK
!= svf_check_tdo())
901 svf_buffer_index
= 0;
906 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
)
908 char *argus
[256], command
;
909 int num_of_argu
= 0, i
;
918 struct svf_xxr_para
*xxr_para_tmp
;
919 uint8_t **pbuffer_tmp
;
920 struct scan_field field
;
922 tap_state_t
*path
= NULL
, state
;
923 /* flag padding commands skipped due to -tap command */
924 int padding_command_skipped
= 0;
926 if (ERROR_OK
!= svf_parse_cmd_string(cmd_str
, strlen(cmd_str
), argus
, &num_of_argu
))
929 /* NOTE: we're a bit loose here, because we ignore case in
930 * TAP state names (instead of insisting on uppercase).
933 command
= svf_find_string_in_array(argus
[0],
934 (char **)svf_command_name
, ARRAY_SIZE(svf_command_name
));
938 if (num_of_argu
!= 2) {
939 LOG_ERROR("invalid parameter of %s", argus
[0]);
943 i_tmp
= tap_state_by_name(argus
[1]);
945 if (svf_tap_state_is_stable(i_tmp
)) {
946 if (command
== ENDIR
) {
947 svf_para
.ir_end_state
= i_tmp
;
948 LOG_DEBUG("\tIR end_state = %s",
949 tap_state_name(i_tmp
));
951 svf_para
.dr_end_state
= i_tmp
;
952 LOG_DEBUG("\tDR end_state = %s",
953 tap_state_name(i_tmp
));
956 LOG_ERROR("%s: %s is not a stable state",
962 if ((num_of_argu
!= 1) && (num_of_argu
!= 3)) {
963 LOG_ERROR("invalid parameter of %s", argus
[0]);
966 if (1 == num_of_argu
) {
967 /* TODO: set jtag speed to full speed */
968 svf_para
.frequency
= 0;
970 if (strcmp(argus
[2], "HZ")) {
971 LOG_ERROR("HZ not found in FREQUENCY command");
974 if (ERROR_OK
!= svf_execute_tap())
976 svf_para
.frequency
= atof(argus
[1]);
977 /* TODO: set jtag speed to */
978 if (svf_para
.frequency
> 0) {
979 command_run_linef(cmd_ctx
,
981 (int)svf_para
.frequency
/ 1000);
982 LOG_DEBUG("\tfrequency = %f", svf_para
.frequency
);
987 if (svf_tap_is_specified
) {
988 padding_command_skipped
= 1;
991 xxr_para_tmp
= &svf_para
.hdr_para
;
994 if (svf_tap_is_specified
) {
995 padding_command_skipped
= 1;
998 xxr_para_tmp
= &svf_para
.hir_para
;
1001 if (svf_tap_is_specified
) {
1002 padding_command_skipped
= 1;
1005 xxr_para_tmp
= &svf_para
.tdr_para
;
1008 if (svf_tap_is_specified
) {
1009 padding_command_skipped
= 1;
1012 xxr_para_tmp
= &svf_para
.tir_para
;
1015 xxr_para_tmp
= &svf_para
.sdr_para
;
1018 xxr_para_tmp
= &svf_para
.sir_para
;
1021 /* XXR length [TDI (tdi)] [TDO (tdo)][MASK (mask)] [SMASK (smask)] */
1022 if ((num_of_argu
> 10) || (num_of_argu
% 2)) {
1023 LOG_ERROR("invalid parameter of %s", argus
[0]);
1026 i_tmp
= xxr_para_tmp
->len
;
1027 xxr_para_tmp
->len
= atoi(argus
[1]);
1028 /* If we are to enlarge the buffers, all parts of xxr_para_tmp
1029 * need to be freed */
1030 if (i_tmp
< xxr_para_tmp
->len
) {
1031 free(xxr_para_tmp
->tdi
);
1032 xxr_para_tmp
->tdi
= NULL
;
1033 free(xxr_para_tmp
->tdo
);
1034 xxr_para_tmp
->tdo
= NULL
;
1035 free(xxr_para_tmp
->mask
);
1036 xxr_para_tmp
->mask
= NULL
;
1037 free(xxr_para_tmp
->smask
);
1038 xxr_para_tmp
->smask
= NULL
;
1041 LOG_DEBUG("\tlength = %d", xxr_para_tmp
->len
);
1042 xxr_para_tmp
->data_mask
= 0;
1043 for (i
= 2; i
< num_of_argu
; i
+= 2) {
1044 if ((strlen(argus
[i
+ 1]) < 3) || (argus
[i
+ 1][0] != '(') ||
1045 (argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] != ')')) {
1046 LOG_ERROR("data section error");
1049 argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] = '\0';
1050 /* TDI, TDO, MASK, SMASK */
1051 if (!strcmp(argus
[i
], "TDI")) {
1053 pbuffer_tmp
= &xxr_para_tmp
->tdi
;
1054 xxr_para_tmp
->data_mask
|= XXR_TDI
;
1055 } else if (!strcmp(argus
[i
], "TDO")) {
1057 pbuffer_tmp
= &xxr_para_tmp
->tdo
;
1058 xxr_para_tmp
->data_mask
|= XXR_TDO
;
1059 } else if (!strcmp(argus
[i
], "MASK")) {
1061 pbuffer_tmp
= &xxr_para_tmp
->mask
;
1062 xxr_para_tmp
->data_mask
|= XXR_MASK
;
1063 } else if (!strcmp(argus
[i
], "SMASK")) {
1065 pbuffer_tmp
= &xxr_para_tmp
->smask
;
1066 xxr_para_tmp
->data_mask
|= XXR_SMASK
;
1068 LOG_ERROR("unknown parameter: %s", argus
[i
]);
1072 svf_copy_hexstring_to_binary(&argus
[i
+ 1][1], pbuffer_tmp
, i_tmp
,
1073 xxr_para_tmp
->len
)) {
1074 LOG_ERROR("fail to parse hex value");
1077 SVF_BUF_LOG(DEBUG
, *pbuffer_tmp
, xxr_para_tmp
->len
, argus
[i
]);
1079 /* If a command changes the length of the last scan of the same type and the
1080 * MASK parameter is absent, */
1081 /* the mask pattern used is all cares */
1082 if (!(xxr_para_tmp
->data_mask
& XXR_MASK
) && (i_tmp
!= xxr_para_tmp
->len
)) {
1083 /* MASK not defined and length changed */
1085 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1086 xxr_para_tmp
->len
)) {
1087 LOG_ERROR("fail to adjust length of array");
1090 buf_set_ones(xxr_para_tmp
->mask
, xxr_para_tmp
->len
);
1092 /* If TDO is absent, no comparison is needed, set the mask to 0 */
1093 if (!(xxr_para_tmp
->data_mask
& XXR_TDO
)) {
1094 if (NULL
== xxr_para_tmp
->tdo
) {
1096 svf_adjust_array_length(&xxr_para_tmp
->tdo
, i_tmp
,
1097 xxr_para_tmp
->len
)) {
1098 LOG_ERROR("fail to adjust length of array");
1102 if (NULL
== xxr_para_tmp
->mask
) {
1104 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1105 xxr_para_tmp
->len
)) {
1106 LOG_ERROR("fail to adjust length of array");
1110 memset(xxr_para_tmp
->mask
, 0, (xxr_para_tmp
->len
+ 7) >> 3);
1112 /* do scan if necessary */
1113 if (SDR
== command
) {
1114 /* check buffer size first, reallocate if necessary */
1115 i
= svf_para
.hdr_para
.len
+ svf_para
.sdr_para
.len
+
1116 svf_para
.tdr_para
.len
;
1117 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1118 /* reallocate buffer */
1119 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1120 LOG_ERROR("not enough memory");
1125 /* assemble dr data */
1127 buf_set_buf(svf_para
.hdr_para
.tdi
,
1129 &svf_tdi_buffer
[svf_buffer_index
],
1131 svf_para
.hdr_para
.len
);
1132 i
+= svf_para
.hdr_para
.len
;
1133 buf_set_buf(svf_para
.sdr_para
.tdi
,
1135 &svf_tdi_buffer
[svf_buffer_index
],
1137 svf_para
.sdr_para
.len
);
1138 i
+= svf_para
.sdr_para
.len
;
1139 buf_set_buf(svf_para
.tdr_para
.tdi
,
1141 &svf_tdi_buffer
[svf_buffer_index
],
1143 svf_para
.tdr_para
.len
);
1144 i
+= svf_para
.tdr_para
.len
;
1146 /* add check data */
1147 if (svf_para
.sdr_para
.data_mask
& XXR_TDO
) {
1148 /* assemble dr mask data */
1150 buf_set_buf(svf_para
.hdr_para
.mask
,
1152 &svf_mask_buffer
[svf_buffer_index
],
1154 svf_para
.hdr_para
.len
);
1155 i
+= svf_para
.hdr_para
.len
;
1156 buf_set_buf(svf_para
.sdr_para
.mask
,
1158 &svf_mask_buffer
[svf_buffer_index
],
1160 svf_para
.sdr_para
.len
);
1161 i
+= svf_para
.sdr_para
.len
;
1162 buf_set_buf(svf_para
.tdr_para
.mask
,
1164 &svf_mask_buffer
[svf_buffer_index
],
1166 svf_para
.tdr_para
.len
);
1168 /* assemble dr check data */
1170 buf_set_buf(svf_para
.hdr_para
.tdo
,
1172 &svf_tdo_buffer
[svf_buffer_index
],
1174 svf_para
.hdr_para
.len
);
1175 i
+= svf_para
.hdr_para
.len
;
1176 buf_set_buf(svf_para
.sdr_para
.tdo
,
1178 &svf_tdo_buffer
[svf_buffer_index
],
1180 svf_para
.sdr_para
.len
);
1181 i
+= svf_para
.sdr_para
.len
;
1182 buf_set_buf(svf_para
.tdr_para
.tdo
,
1184 &svf_tdo_buffer
[svf_buffer_index
],
1186 svf_para
.tdr_para
.len
);
1187 i
+= svf_para
.tdr_para
.len
;
1189 svf_add_check_para(1, svf_buffer_index
, i
);
1191 svf_add_check_para(0, svf_buffer_index
, i
);
1193 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1194 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1196 /* NOTE: doesn't use SVF-specified state paths */
1197 jtag_add_plain_dr_scan(field
.num_bits
,
1200 svf_para
.dr_end_state
);
1203 svf_buffer_index
+= (i
+ 7) >> 3;
1204 } else if (SIR
== command
) {
1205 /* check buffer size first, reallocate if necessary */
1206 i
= svf_para
.hir_para
.len
+ svf_para
.sir_para
.len
+
1207 svf_para
.tir_para
.len
;
1208 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1209 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1210 LOG_ERROR("not enough memory");
1215 /* assemble ir data */
1217 buf_set_buf(svf_para
.hir_para
.tdi
,
1219 &svf_tdi_buffer
[svf_buffer_index
],
1221 svf_para
.hir_para
.len
);
1222 i
+= svf_para
.hir_para
.len
;
1223 buf_set_buf(svf_para
.sir_para
.tdi
,
1225 &svf_tdi_buffer
[svf_buffer_index
],
1227 svf_para
.sir_para
.len
);
1228 i
+= svf_para
.sir_para
.len
;
1229 buf_set_buf(svf_para
.tir_para
.tdi
,
1231 &svf_tdi_buffer
[svf_buffer_index
],
1233 svf_para
.tir_para
.len
);
1234 i
+= svf_para
.tir_para
.len
;
1236 /* add check data */
1237 if (svf_para
.sir_para
.data_mask
& XXR_TDO
) {
1238 /* assemble dr mask data */
1240 buf_set_buf(svf_para
.hir_para
.mask
,
1242 &svf_mask_buffer
[svf_buffer_index
],
1244 svf_para
.hir_para
.len
);
1245 i
+= svf_para
.hir_para
.len
;
1246 buf_set_buf(svf_para
.sir_para
.mask
,
1248 &svf_mask_buffer
[svf_buffer_index
],
1250 svf_para
.sir_para
.len
);
1251 i
+= svf_para
.sir_para
.len
;
1252 buf_set_buf(svf_para
.tir_para
.mask
,
1254 &svf_mask_buffer
[svf_buffer_index
],
1256 svf_para
.tir_para
.len
);
1258 /* assemble dr check data */
1260 buf_set_buf(svf_para
.hir_para
.tdo
,
1262 &svf_tdo_buffer
[svf_buffer_index
],
1264 svf_para
.hir_para
.len
);
1265 i
+= svf_para
.hir_para
.len
;
1266 buf_set_buf(svf_para
.sir_para
.tdo
,
1268 &svf_tdo_buffer
[svf_buffer_index
],
1270 svf_para
.sir_para
.len
);
1271 i
+= svf_para
.sir_para
.len
;
1272 buf_set_buf(svf_para
.tir_para
.tdo
,
1274 &svf_tdo_buffer
[svf_buffer_index
],
1276 svf_para
.tir_para
.len
);
1277 i
+= svf_para
.tir_para
.len
;
1279 svf_add_check_para(1, svf_buffer_index
, i
);
1281 svf_add_check_para(0, svf_buffer_index
, i
);
1283 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1284 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1286 /* NOTE: doesn't use SVF-specified state paths */
1287 jtag_add_plain_ir_scan(field
.num_bits
,
1290 svf_para
.ir_end_state
);
1293 svf_buffer_index
+= (i
+ 7) >> 3;
1298 LOG_ERROR("PIO and PIOMAP are not supported");
1301 /* RUNTEST [run_state] run_count run_clk [min_time SEC [MAXIMUM max_time
1302 * SEC]] [ENDSTATE end_state] */
1303 /* RUNTEST [run_state] min_time SEC [MAXIMUM max_time SEC] [ENDSTATE
1305 if ((num_of_argu
< 3) || (num_of_argu
> 11)) {
1306 LOG_ERROR("invalid parameter of %s", argus
[0]);
1315 i_tmp
= tap_state_by_name(argus
[i
]);
1316 if (i_tmp
!= TAP_INVALID
) {
1317 if (svf_tap_state_is_stable(i_tmp
)) {
1318 svf_para
.runtest_run_state
= i_tmp
;
1320 /* When a run_state is specified, the new
1321 * run_state becomes the default end_state.
1323 svf_para
.runtest_end_state
= i_tmp
;
1324 LOG_DEBUG("\trun_state = %s", tap_state_name(i_tmp
));
1327 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1332 /* run_count run_clk */
1333 if (((i
+ 2) <= num_of_argu
) && strcmp(argus
[i
+ 1], "SEC")) {
1334 if (!strcmp(argus
[i
+ 1], "TCK")) {
1335 /* clock source is TCK */
1336 run_count
= atoi(argus
[i
]);
1337 LOG_DEBUG("\trun_count@TCK = %d", run_count
);
1339 LOG_ERROR("%s not supported for clock", argus
[i
+ 1]);
1345 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
+ 1], "SEC")) {
1346 min_time
= atof(argus
[i
]);
1347 LOG_DEBUG("\tmin_time = %fs", min_time
);
1350 /* MAXIMUM max_time SEC */
1351 if (((i
+ 3) <= num_of_argu
) &&
1352 !strcmp(argus
[i
], "MAXIMUM") && !strcmp(argus
[i
+ 2], "SEC")) {
1354 max_time
= atof(argus
[i
+ 1]);
1355 LOG_DEBUG("\tmax_time = %fs", max_time
);
1358 /* ENDSTATE end_state */
1359 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
], "ENDSTATE")) {
1360 i_tmp
= tap_state_by_name(argus
[i
+ 1]);
1362 if (svf_tap_state_is_stable(i_tmp
)) {
1363 svf_para
.runtest_end_state
= i_tmp
;
1364 LOG_DEBUG("\tend_state = %s", tap_state_name(i_tmp
));
1366 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1372 /* all parameter should be parsed */
1373 if (i
== num_of_argu
) {
1375 /* FIXME handle statemove failures */
1376 uint32_t min_usec
= 1000000 * min_time
;
1378 /* enter into run_state if necessary */
1379 if (cmd_queue_cur_state
!= svf_para
.runtest_run_state
)
1380 svf_add_statemove(svf_para
.runtest_run_state
);
1382 /* add clocks and/or min wait */
1383 if (run_count
> 0) {
1385 jtag_add_clocks(run_count
);
1390 jtag_add_sleep(min_usec
);
1393 /* move to end_state if necessary */
1394 if (svf_para
.runtest_end_state
!= svf_para
.runtest_run_state
)
1395 svf_add_statemove(svf_para
.runtest_end_state
);
1398 if (svf_para
.runtest_run_state
!= TAP_IDLE
) {
1399 LOG_ERROR("cannot runtest in %s state",
1400 tap_state_name(svf_para
.runtest_run_state
));
1405 jtag_add_runtest(run_count
, svf_para
.runtest_end_state
);
1408 LOG_ERROR("fail to parse parameter of RUNTEST, %d out of %d is parsed",
1415 /* STATE [pathstate1 [pathstate2 ...[pathstaten]]] stable_state */
1416 if (num_of_argu
< 2) {
1417 LOG_ERROR("invalid parameter of %s", argus
[0]);
1420 if (num_of_argu
> 2) {
1421 /* STATE pathstate1 ... stable_state */
1422 path
= malloc((num_of_argu
- 1) * sizeof(tap_state_t
));
1424 LOG_ERROR("not enough memory");
1427 num_of_argu
--; /* num of path */
1428 i_tmp
= 1; /* path is from parameter 1 */
1429 for (i
= 0; i
< num_of_argu
; i
++, i_tmp
++) {
1430 path
[i
] = tap_state_by_name(argus
[i_tmp
]);
1431 if (path
[i
] == TAP_INVALID
) {
1432 LOG_ERROR("%s: %s is not a valid state", argus
[0], argus
[i_tmp
]);
1436 /* OpenOCD refuses paths containing TAP_RESET */
1437 if (TAP_RESET
== path
[i
]) {
1438 /* FIXME last state MUST be stable! */
1441 jtag_add_pathmove(i
, path
);
1445 num_of_argu
-= i
+ 1;
1449 if (num_of_argu
> 0) {
1450 /* execute last path if necessary */
1451 if (svf_tap_state_is_stable(path
[num_of_argu
- 1])) {
1452 /* last state MUST be stable state */
1454 jtag_add_pathmove(num_of_argu
, path
);
1455 LOG_DEBUG("\tmove to %s by path_move",
1456 tap_state_name(path
[num_of_argu
- 1]));
1458 LOG_ERROR("%s: %s is not a stable state",
1460 tap_state_name(path
[num_of_argu
- 1]));
1469 /* STATE stable_state */
1470 state
= tap_state_by_name(argus
[1]);
1471 if (svf_tap_state_is_stable(state
)) {
1472 LOG_DEBUG("\tmove to %s by svf_add_statemove",
1473 tap_state_name(state
));
1474 /* FIXME handle statemove failures */
1475 svf_add_statemove(state
);
1477 LOG_ERROR("%s: %s is not a stable state",
1478 argus
[0], tap_state_name(state
));
1484 /* TRST trst_mode */
1485 if (num_of_argu
!= 2) {
1486 LOG_ERROR("invalid parameter of %s", argus
[0]);
1489 if (svf_para
.trst_mode
!= TRST_ABSENT
) {
1490 if (ERROR_OK
!= svf_execute_tap())
1492 i_tmp
= svf_find_string_in_array(argus
[1],
1493 (char **)svf_trst_mode_name
,
1494 ARRAY_SIZE(svf_trst_mode_name
));
1498 jtag_add_reset(1, 0);
1503 jtag_add_reset(0, 0);
1508 LOG_ERROR("unknown TRST mode: %s", argus
[1]);
1511 svf_para
.trst_mode
= i_tmp
;
1512 LOG_DEBUG("\ttrst_mode = %s", svf_trst_mode_name
[svf_para
.trst_mode
]);
1514 LOG_ERROR("can not accept TRST command if trst_mode is ABSENT");
1519 LOG_ERROR("invalid svf command: %s", argus
[0]);
1524 if (padding_command_skipped
)
1525 LOG_USER("(Above Padding command skipped, as per -tap argument)");
1528 if (debug_level
>= LOG_LVL_DEBUG
) {
1529 /* for convenient debugging, execute tap if possible */
1530 if ((svf_buffer_index
> 0) &&
1531 (((command
!= STATE
) && (command
!= RUNTEST
)) ||
1532 ((command
== STATE
) && (num_of_argu
== 2)))) {
1533 if (ERROR_OK
!= svf_execute_tap())
1536 /* output debug info */
1537 if ((SIR
== command
) || (SDR
== command
)) {
1538 SVF_BUF_LOG(DEBUG
, svf_tdi_buffer
, svf_check_tdo_para
[0].bit_len
, "TDO read");
1542 /* for fast executing, execute tap if necessary */
1543 /* half of the buffer is for the next command */
1544 if (((svf_buffer_index
>= SVF_MAX_BUFFER_SIZE_TO_COMMIT
) ||
1545 (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
/ 2)) &&
1546 (((command
!= STATE
) && (command
!= RUNTEST
)) ||
1547 ((command
== STATE
) && (num_of_argu
== 2))))
1548 return svf_execute_tap();
1554 static const struct command_registration svf_command_handlers
[] = {
1557 .handler
= handle_svf_command
,
1558 .mode
= COMMAND_EXEC
,
1559 .help
= "Runs a SVF file.",
1560 .usage
= "[-tap device.tap] <file> [quiet] [nil] [progress] [ignore_error]",
1562 COMMAND_REGISTRATION_DONE
1565 int svf_register_commands(struct command_context
*cmd_ctx
)
1567 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)