1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2009 by Simon Qian *
5 * SimonQian@SimonQian.com *
6 ***************************************************************************/
8 /* The specification for SVF is available here:
9 * http://www.asset-intertech.com/support/svf.pdf
10 * Below, this document is referred to as the "SVF spec".
12 * The specification for XSVF is available here:
13 * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf
14 * Below, this document is referred to as the "XSVF spec".
21 #include <jtag/jtag.h>
23 #include "helper/system.h"
24 #include <helper/time_support.h>
45 static const char *svf_command_name
[14] = {
69 static const char *svf_trst_mode_name
[4] = {
76 struct svf_statemove
{
79 uint32_t num_of_moves
;
84 * These paths are from the SVF specification for the STATE command, to be
85 * used when the STATE command only includes the final state. The first
86 * element of the path is the "from" (current) state, and the last one is
87 * the "to" (target) state.
89 * All specified paths are the shortest ones in the JTAG spec, and are thus
90 * not (!!) exact matches for the paths used elsewhere in OpenOCD. Note
91 * that PAUSE-to-PAUSE transitions all go through UPDATE and then CAPTURE,
92 * which has specific effects on the various registers; they are not NOPs.
94 * Paths to RESET are disabled here. As elsewhere in OpenOCD, and in XSVF
95 * and many SVF implementations, we don't want to risk missing that state.
96 * To get to RESET, always we ignore the current state.
98 static const struct svf_statemove svf_statemoves
[] = {
99 /* from to num_of_moves, paths[8] */
100 /* {TAP_RESET, TAP_RESET, 1, {TAP_RESET}}, */
101 {TAP_RESET
, TAP_IDLE
, 2, {TAP_RESET
, TAP_IDLE
} },
102 {TAP_RESET
, TAP_DRPAUSE
, 6, {TAP_RESET
, TAP_IDLE
, TAP_DRSELECT
,
103 TAP_DRCAPTURE
, TAP_DREXIT1
, TAP_DRPAUSE
} },
104 {TAP_RESET
, TAP_IRPAUSE
, 7, {TAP_RESET
, TAP_IDLE
, TAP_DRSELECT
,
105 TAP_IRSELECT
, TAP_IRCAPTURE
,
106 TAP_IREXIT1
, TAP_IRPAUSE
} },
108 /* {TAP_IDLE, TAP_RESET, 4, {TAP_IDLE,
109 * TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
110 {TAP_IDLE
, TAP_IDLE
, 1, {TAP_IDLE
} },
111 {TAP_IDLE
, TAP_DRPAUSE
, 5, {TAP_IDLE
, TAP_DRSELECT
, TAP_DRCAPTURE
,
112 TAP_DREXIT1
, TAP_DRPAUSE
} },
113 {TAP_IDLE
, TAP_IRPAUSE
, 6, {TAP_IDLE
, TAP_DRSELECT
, TAP_IRSELECT
,
114 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} },
116 /* {TAP_DRPAUSE, TAP_RESET, 6, {TAP_DRPAUSE,
117 * TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
118 {TAP_DRPAUSE
, TAP_IDLE
, 4, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
120 {TAP_DRPAUSE
, TAP_DRPAUSE
, 7, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
121 TAP_DRSELECT
, TAP_DRCAPTURE
,
122 TAP_DREXIT1
, TAP_DRPAUSE
} },
123 {TAP_DRPAUSE
, TAP_IRPAUSE
, 8, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
124 TAP_DRSELECT
, TAP_IRSELECT
,
125 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} },
127 /* {TAP_IRPAUSE, TAP_RESET, 6, {TAP_IRPAUSE,
128 * TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
129 {TAP_IRPAUSE
, TAP_IDLE
, 4, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
131 {TAP_IRPAUSE
, TAP_DRPAUSE
, 7, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
132 TAP_DRSELECT
, TAP_DRCAPTURE
,
133 TAP_DREXIT1
, TAP_DRPAUSE
} },
134 {TAP_IRPAUSE
, TAP_IRPAUSE
, 8, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
135 TAP_DRSELECT
, TAP_IRSELECT
,
136 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} }
139 #define XXR_TDI (1 << 0)
140 #define XXR_TDO (1 << 1)
141 #define XXR_MASK (1 << 2)
142 #define XXR_SMASK (1 << 3)
144 #define SVF_MAX_ADDCYCLES 255
146 struct svf_xxr_para
{
157 tap_state_t ir_end_state
;
158 tap_state_t dr_end_state
;
159 tap_state_t runtest_run_state
;
160 tap_state_t runtest_end_state
;
161 enum trst_mode trst_mode
;
163 struct svf_xxr_para hir_para
;
164 struct svf_xxr_para hdr_para
;
165 struct svf_xxr_para tir_para
;
166 struct svf_xxr_para tdr_para
;
167 struct svf_xxr_para sir_para
;
168 struct svf_xxr_para sdr_para
;
171 static struct svf_para svf_para
;
172 static const struct svf_para svf_para_init
= {
173 /* frequency, ir_end_state, dr_end_state, runtest_run_state, runtest_end_state, trst_mode */
174 0, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TRST_Z
,
176 /* {len, data_mask, tdi, tdo, mask, smask}, */
177 {0, 0, NULL
, NULL
, NULL
, NULL
},
179 /* {len, data_mask, tdi, tdo, mask, smask}, */
180 {0, 0, NULL
, NULL
, NULL
, NULL
},
182 /* {len, data_mask, tdi, tdo, mask, smask}, */
183 {0, 0, NULL
, NULL
, NULL
, NULL
},
185 /* {len, data_mask, tdi, tdo, mask, smask}, */
186 {0, 0, NULL
, NULL
, NULL
, NULL
},
188 /* {len, data_mask, tdi, tdo, mask, smask}, */
189 {0, 0, NULL
, NULL
, NULL
, NULL
},
191 /* {len, data_mask, tdi, tdo, mask, smask}, */
192 {0, 0, NULL
, NULL
, NULL
, NULL
},
195 struct svf_check_tdo_para
{
196 int line_num
; /* used to record line number of the check operation */
197 /* so more information could be printed */
198 int enabled
; /* check is enabled or not */
199 int buffer_offset
; /* buffer_offset to buffers */
200 int bit_len
; /* bit length to check */
203 #define SVF_CHECK_TDO_PARA_SIZE 1024
204 static struct svf_check_tdo_para
*svf_check_tdo_para
;
205 static int svf_check_tdo_para_index
;
207 static int svf_read_command_from_file(FILE *fd
);
208 static int svf_check_tdo(void);
209 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
);
210 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
);
211 static int svf_execute_tap(void);
214 static char *svf_read_line
;
215 static size_t svf_read_line_size
;
216 static char *svf_command_buffer
;
217 static size_t svf_command_buffer_size
;
218 static int svf_line_number
;
219 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
);
221 #define SVF_MAX_BUFFER_SIZE_TO_COMMIT (1024 * 1024)
222 static uint8_t *svf_tdi_buffer
, *svf_tdo_buffer
, *svf_mask_buffer
;
223 static int svf_buffer_index
, svf_buffer_size
;
224 static int svf_quiet
;
226 static int svf_ignore_error
;
227 static bool svf_noreset
;
228 static int svf_addcycles
;
230 /* Targeting particular tap */
231 static int svf_tap_is_specified
;
232 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
);
234 /* Progress Indicator */
235 static int svf_progress_enabled
;
236 static long svf_total_lines
;
237 static int svf_percentage
;
238 static int svf_last_printed_percentage
= -1;
241 * macro is used to print the svf hex buffer at desired debug level
242 * DEBUG, INFO, ERROR, USER
244 #define SVF_BUF_LOG(_lvl, _buf, _nbits, _desc) \
245 svf_hexbuf_print(LOG_LVL_##_lvl, __FILE__, __LINE__, __func__, _buf, _nbits, _desc)
247 static void svf_hexbuf_print(int dbg_lvl
, const char *file
, unsigned line
,
248 const char *function
, const uint8_t *buf
,
249 int bit_len
, const char *desc
)
252 int byte_len
= DIV_ROUND_UP(bit_len
, 8);
253 int msbits
= bit_len
% 8;
255 /* allocate 2 bytes per hex digit */
256 char *prbuf
= malloc((byte_len
* 2) + 2 + 1);
260 /* print correct number of bytes, mask excess bits where applicable */
261 uint8_t msb
= buf
[byte_len
- 1] & (msbits
? (1 << msbits
) - 1 : 0xff);
262 len
= sprintf(prbuf
, msbits
<= 4 ? "0x%01"PRIx8
: "0x%02"PRIx8
, msb
);
263 for (j
= byte_len
- 2; j
>= 0; j
--)
264 len
+= sprintf(prbuf
+ len
, "%02"PRIx8
, buf
[j
]);
266 log_printf_lf(dbg_lvl
, file
, line
, function
, "%8s = %s", desc
? desc
: " ", prbuf
);
271 static int svf_realloc_buffers(size_t len
)
275 if (svf_execute_tap() != ERROR_OK
)
278 ptr
= realloc(svf_tdi_buffer
, len
);
281 svf_tdi_buffer
= ptr
;
283 ptr
= realloc(svf_tdo_buffer
, len
);
286 svf_tdo_buffer
= ptr
;
288 ptr
= realloc(svf_mask_buffer
, len
);
291 svf_mask_buffer
= ptr
;
293 svf_buffer_size
= len
;
298 static void svf_free_xxd_para(struct svf_xxr_para
*para
)
315 int svf_add_statemove(tap_state_t state_to
)
317 tap_state_t state_from
= cmd_queue_cur_state
;
320 /* when resetting, be paranoid and ignore current state */
321 if (state_to
== TAP_RESET
) {
329 for (index_var
= 0; index_var
< ARRAY_SIZE(svf_statemoves
); index_var
++) {
330 if ((svf_statemoves
[index_var
].from
== state_from
)
331 && (svf_statemoves
[index_var
].to
== state_to
)) {
334 /* recorded path includes current state ... avoid
336 if (svf_statemoves
[index_var
].num_of_moves
> 1)
337 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
- 1,
338 svf_statemoves
[index_var
].paths
+ 1);
340 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
,
341 svf_statemoves
[index_var
].paths
);
345 LOG_ERROR("SVF: can not move to %s", tap_state_name(state_to
));
349 COMMAND_HANDLER(handle_svf_command
)
351 #define SVF_MIN_NUM_OF_OPTIONS 1
352 #define SVF_MAX_NUM_OF_OPTIONS 8
355 int64_t time_measure_ms
;
356 int time_measure_s
, time_measure_m
;
358 /* use NULL to indicate a "plain" svf file which accounts for
359 * any additional devices in the scan chain, otherwise the device
360 * that should be affected
362 struct jtag_tap
*tap
= NULL
;
364 if ((CMD_ARGC
< SVF_MIN_NUM_OF_OPTIONS
) || (CMD_ARGC
> SVF_MAX_NUM_OF_OPTIONS
))
365 return ERROR_COMMAND_SYNTAX_ERROR
;
367 /* parse command line */
370 svf_progress_enabled
= 0;
371 svf_ignore_error
= 0;
375 for (unsigned int i
= 0; i
< CMD_ARGC
; i
++) {
376 if (strcmp(CMD_ARGV
[i
], "-addcycles") == 0) {
377 svf_addcycles
= atoi(CMD_ARGV
[i
+ 1]);
378 if (svf_addcycles
> SVF_MAX_ADDCYCLES
) {
379 command_print(CMD
, "addcycles: %s out of range", CMD_ARGV
[i
+ 1]);
383 } else if (strcmp(CMD_ARGV
[i
], "-tap") == 0) {
384 tap
= jtag_tap_by_string(CMD_ARGV
[i
+1]);
386 command_print(CMD
, "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;
401 else if (strcmp(CMD_ARGV
[i
], "-noreset") == 0)
404 svf_fd
= fopen(CMD_ARGV
[i
], "r");
407 command_print(CMD
, "open(\"%s\"): %s", CMD_ARGV
[i
], strerror(err
));
408 /* no need to free anything now */
409 return ERROR_COMMAND_SYNTAX_ERROR
;
411 LOG_USER("svf processing file: \"%s\"", CMD_ARGV
[i
]);
416 return ERROR_COMMAND_SYNTAX_ERROR
;
419 time_measure_ms
= timeval_ms();
423 svf_command_buffer_size
= 0;
425 svf_check_tdo_para_index
= 0;
426 svf_check_tdo_para
= malloc(sizeof(struct svf_check_tdo_para
) * SVF_CHECK_TDO_PARA_SIZE
);
427 if (!svf_check_tdo_para
) {
428 LOG_ERROR("not enough memory");
433 svf_buffer_index
= 0;
434 /* double the buffer size */
435 /* in case current command cannot be committed, and next command is a bit scan command */
436 /* here is 32K bits for this big scan command, it should be enough */
437 /* buffer will be reallocated if buffer size is not enough */
438 if (svf_realloc_buffers(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT
) != ERROR_OK
) {
443 memcpy(&svf_para
, &svf_para_init
, sizeof(svf_para
));
445 if (!svf_nil
&& !svf_noreset
) {
451 /* Tap is specified, set header/trailer paddings */
452 int header_ir_len
= 0, header_dr_len
= 0, trailer_ir_len
= 0, trailer_dr_len
= 0;
453 struct jtag_tap
*check_tap
;
455 svf_tap_is_specified
= 1;
457 for (check_tap
= jtag_all_taps(); check_tap
; check_tap
= check_tap
->next_tap
) {
458 if (check_tap
->abs_chain_position
< tap
->abs_chain_position
) {
460 header_ir_len
+= check_tap
->ir_length
;
462 } else if (check_tap
->abs_chain_position
> tap
->abs_chain_position
) {
464 trailer_ir_len
+= check_tap
->ir_length
;
470 if (svf_set_padding(&svf_para
.hdr_para
, header_dr_len
, 0) != ERROR_OK
) {
471 LOG_ERROR("failed to set data header");
475 /* HIR %d TDI (0xFF) */
476 if (svf_set_padding(&svf_para
.hir_para
, header_ir_len
, 0xFF) != ERROR_OK
) {
477 LOG_ERROR("failed to set instruction header");
482 if (svf_set_padding(&svf_para
.tdr_para
, trailer_dr_len
, 0) != ERROR_OK
) {
483 LOG_ERROR("failed to set data trailer");
487 /* TIR %d TDI (0xFF) */
488 if (svf_set_padding(&svf_para
.tir_para
, trailer_ir_len
, 0xFF) != ERROR_OK
) {
489 LOG_ERROR("failed to set instruction trailer");
494 if (svf_progress_enabled
) {
495 /* Count total lines in file. */
496 while (!feof(svf_fd
)) {
497 svf_getline(&svf_command_buffer
, &svf_command_buffer_size
, svf_fd
);
502 while (svf_read_command_from_file(svf_fd
) == ERROR_OK
) {
505 if (svf_progress_enabled
) {
506 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
507 if (svf_last_printed_percentage
!= svf_percentage
) {
508 LOG_USER_N("\r%d%% ", svf_percentage
);
509 svf_last_printed_percentage
= svf_percentage
;
513 if (svf_progress_enabled
) {
514 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
515 LOG_USER_N("%3d%% %s", svf_percentage
, svf_read_line
);
517 LOG_USER_N("%s", svf_read_line
);
520 if (svf_run_command(CMD_CTX
, svf_command_buffer
) != ERROR_OK
) {
521 LOG_ERROR("fail to run command at line %d", svf_line_number
);
528 if ((!svf_nil
) && (jtag_execute_queue() != ERROR_OK
))
530 else if (svf_check_tdo() != ERROR_OK
)
534 time_measure_ms
= timeval_ms() - time_measure_ms
;
535 time_measure_s
= time_measure_ms
/ 1000;
536 time_measure_ms
%= 1000;
537 time_measure_m
= time_measure_s
/ 60;
538 time_measure_s
%= 60;
539 if (time_measure_ms
< 1000)
541 "\r\nTime used: %dm%ds%" PRId64
"ms ",
552 free(svf_command_buffer
);
553 svf_command_buffer
= NULL
;
554 svf_command_buffer_size
= 0;
556 free(svf_check_tdo_para
);
557 svf_check_tdo_para
= NULL
;
558 svf_check_tdo_para_index
= 0;
560 free(svf_tdi_buffer
);
561 svf_tdi_buffer
= NULL
;
563 free(svf_tdo_buffer
);
564 svf_tdo_buffer
= NULL
;
566 free(svf_mask_buffer
);
567 svf_mask_buffer
= NULL
;
569 svf_buffer_index
= 0;
572 svf_free_xxd_para(&svf_para
.hdr_para
);
573 svf_free_xxd_para(&svf_para
.hir_para
);
574 svf_free_xxd_para(&svf_para
.tdr_para
);
575 svf_free_xxd_para(&svf_para
.tir_para
);
576 svf_free_xxd_para(&svf_para
.sdr_para
);
577 svf_free_xxd_para(&svf_para
.sir_para
);
581 "svf file programmed %s for %d commands with %d errors",
582 (svf_ignore_error
> 1) ? "unsuccessfully" : "successfully",
584 (svf_ignore_error
> 1) ? (svf_ignore_error
- 1) : 0);
586 command_print(CMD
, "svf file programmed failed");
588 svf_ignore_error
= 0;
592 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
)
594 #define MIN_CHUNK 16 /* Buffer is increased by this size each time as required */
599 *lineptr
= malloc(*n
);
604 (*lineptr
)[0] = fgetc(stream
);
605 while ((*lineptr
)[i
] != '\n') {
606 (*lineptr
)[++i
] = fgetc(stream
);
613 *lineptr
= realloc(*lineptr
, *n
);
619 return sizeof(*lineptr
);
622 #define SVFP_CMD_INC_CNT 1024
623 static int svf_read_command_from_file(FILE *fd
)
628 int cmd_ok
= 0, slash
= 0;
630 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
633 ch
= svf_read_line
[0];
634 while (!cmd_ok
&& (ch
!= 0)) {
638 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
646 if (svf_getline(&svf_read_line
, &svf_read_line_size
,
659 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
665 /* Don't save '\r' and '\n' if no data is parsed */
670 /* The parsing code currently expects a space
671 * before parentheses -- "TDI (123)". Also a
672 * space afterwards -- "TDI (123) TDO(456)".
673 * But such spaces are optional... instead of
674 * parser updates, cope with that by adding the
677 * Ensure there are 3 bytes available, for:
678 * - current character
680 * - terminating NUL ('\0')
682 if (cmd_pos
+ 3 > svf_command_buffer_size
) {
683 svf_command_buffer
= realloc(svf_command_buffer
, cmd_pos
+ 3);
684 svf_command_buffer_size
= cmd_pos
+ 3;
685 if (!svf_command_buffer
) {
686 LOG_ERROR("not enough memory");
691 /* insert a space before '(' */
693 svf_command_buffer
[cmd_pos
++] = ' ';
695 svf_command_buffer
[cmd_pos
++] = (char)toupper(ch
);
697 /* insert a space after ')' */
699 svf_command_buffer
[cmd_pos
++] = ' ';
702 ch
= svf_read_line
[++i
];
706 svf_command_buffer
[cmd_pos
] = '\0';
712 static int svf_parse_cmd_string(char *str
, int len
, char **argus
, int *num_of_argu
)
714 int pos
= 0, num
= 0, space_found
= 1, in_bracket
= 0;
720 LOG_ERROR("fail to parse svf command");
730 if (!in_bracket
&& isspace((int) str
[pos
])) {
733 } else if (space_found
) {
734 argus
[num
++] = &str
[pos
];
750 bool svf_tap_state_is_stable(tap_state_t state
)
752 return (state
== TAP_RESET
) || (state
== TAP_IDLE
)
753 || (state
== TAP_DRPAUSE
) || (state
== TAP_IRPAUSE
);
756 static int svf_find_string_in_array(char *str
, char **strs
, int num_of_element
)
760 for (i
= 0; i
< num_of_element
; i
++) {
761 if (!strcmp(str
, strs
[i
]))
767 static int svf_adjust_array_length(uint8_t **arr
, int orig_bit_len
, int new_bit_len
)
769 int new_byte_len
= (new_bit_len
+ 7) >> 3;
771 if ((!*arr
) || (((orig_bit_len
+ 7) >> 3) < ((new_bit_len
+ 7) >> 3))) {
773 *arr
= calloc(1, new_byte_len
);
775 LOG_ERROR("not enough memory");
782 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
)
784 int error
= ERROR_OK
;
785 error
|= svf_adjust_array_length(¶
->tdi
, para
->len
, len
);
786 memset(para
->tdi
, tdi
, (len
+ 7) >> 3);
787 error
|= svf_adjust_array_length(¶
->tdo
, para
->len
, len
);
788 error
|= svf_adjust_array_length(¶
->mask
, para
->len
, len
);
790 para
->data_mask
= XXR_TDI
;
795 static int svf_copy_hexstring_to_binary(char *str
, uint8_t **bin
, int orig_bit_len
, int bit_len
)
797 int i
, str_len
= strlen(str
), str_hbyte_len
= (bit_len
+ 3) >> 2;
800 if (svf_adjust_array_length(bin
, orig_bit_len
, bit_len
) != ERROR_OK
) {
801 LOG_ERROR("fail to adjust length of array");
805 /* fill from LSB (end of str) to MSB (beginning of str) */
806 for (i
= 0; i
< str_hbyte_len
; i
++) {
808 while (str_len
> 0) {
811 /* Skip whitespace. The SVF specification (rev E) is
812 * deficient in terms of basic lexical issues like
813 * where whitespace is allowed. Long bitstrings may
814 * require line ends for correctness, since there is
815 * a hard limit on line length.
818 if ((ch
>= '0') && (ch
<= '9')) {
821 } else if ((ch
>= 'A') && (ch
<= 'F')) {
825 LOG_ERROR("invalid hex string");
836 (*bin
)[i
/ 2] |= ch
<< 4;
844 /* consume optional leading '0' MSBs or whitespace */
845 while (str_len
> 0 && ((str
[str_len
- 1] == '0')
846 || isspace((int) str
[str_len
- 1])))
849 /* check validity: we must have consumed everything */
850 if (str_len
> 0 || (ch
& ~((2 << ((bit_len
- 1) % 4)) - 1)) != 0) {
851 LOG_ERROR("value exceeds length");
858 static int svf_check_tdo(void)
860 int i
, len
, index_var
;
862 for (i
= 0; i
< svf_check_tdo_para_index
; i
++) {
863 index_var
= svf_check_tdo_para
[i
].buffer_offset
;
864 len
= svf_check_tdo_para
[i
].bit_len
;
865 if ((svf_check_tdo_para
[i
].enabled
)
866 && buf_cmp_mask(&svf_tdi_buffer
[index_var
], &svf_tdo_buffer
[index_var
],
867 &svf_mask_buffer
[index_var
], len
)) {
868 LOG_ERROR("tdo check error at line %d",
869 svf_check_tdo_para
[i
].line_num
);
870 SVF_BUF_LOG(ERROR
, &svf_tdi_buffer
[index_var
], len
, "READ");
871 SVF_BUF_LOG(ERROR
, &svf_tdo_buffer
[index_var
], len
, "WANT");
872 SVF_BUF_LOG(ERROR
, &svf_mask_buffer
[index_var
], len
, "MASK");
874 if (svf_ignore_error
== 0)
880 svf_check_tdo_para_index
= 0;
885 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
)
887 if (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
) {
888 LOG_ERROR("toooooo many operation undone");
892 svf_check_tdo_para
[svf_check_tdo_para_index
].line_num
= svf_line_number
;
893 svf_check_tdo_para
[svf_check_tdo_para_index
].bit_len
= bit_len
;
894 svf_check_tdo_para
[svf_check_tdo_para_index
].enabled
= enabled
;
895 svf_check_tdo_para
[svf_check_tdo_para_index
].buffer_offset
= buffer_offset
;
896 svf_check_tdo_para_index
++;
901 static int svf_execute_tap(void)
903 if ((!svf_nil
) && (jtag_execute_queue() != ERROR_OK
))
905 else if (svf_check_tdo() != ERROR_OK
)
908 svf_buffer_index
= 0;
913 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
)
915 char *argus
[256], command
;
916 int num_of_argu
= 0, i
;
925 struct svf_xxr_para
*xxr_para_tmp
;
926 uint8_t **pbuffer_tmp
;
927 struct scan_field field
;
929 tap_state_t
*path
= NULL
, state
;
930 /* flag padding commands skipped due to -tap command */
931 int padding_command_skipped
= 0;
933 if (svf_parse_cmd_string(cmd_str
, strlen(cmd_str
), argus
, &num_of_argu
) != ERROR_OK
)
936 /* NOTE: we're a bit loose here, because we ignore case in
937 * TAP state names (instead of insisting on uppercase).
940 command
= svf_find_string_in_array(argus
[0],
941 (char **)svf_command_name
, ARRAY_SIZE(svf_command_name
));
945 if (num_of_argu
!= 2) {
946 LOG_ERROR("invalid parameter of %s", argus
[0]);
950 i_tmp
= tap_state_by_name(argus
[1]);
952 if (svf_tap_state_is_stable(i_tmp
)) {
953 if (command
== ENDIR
) {
954 svf_para
.ir_end_state
= i_tmp
;
955 LOG_DEBUG("\tIR end_state = %s",
956 tap_state_name(i_tmp
));
958 svf_para
.dr_end_state
= i_tmp
;
959 LOG_DEBUG("\tDR end_state = %s",
960 tap_state_name(i_tmp
));
963 LOG_ERROR("%s: %s is not a stable state",
969 if ((num_of_argu
!= 1) && (num_of_argu
!= 3)) {
970 LOG_ERROR("invalid parameter of %s", argus
[0]);
973 if (num_of_argu
== 1) {
974 /* TODO: set jtag speed to full speed */
975 svf_para
.frequency
= 0;
977 if (strcmp(argus
[2], "HZ")) {
978 LOG_ERROR("HZ not found in FREQUENCY command");
981 if (svf_execute_tap() != ERROR_OK
)
983 svf_para
.frequency
= atof(argus
[1]);
984 /* TODO: set jtag speed to */
985 if (svf_para
.frequency
> 0) {
986 command_run_linef(cmd_ctx
,
988 (int)svf_para
.frequency
/ 1000);
989 LOG_DEBUG("\tfrequency = %f", svf_para
.frequency
);
994 if (svf_tap_is_specified
) {
995 padding_command_skipped
= 1;
998 xxr_para_tmp
= &svf_para
.hdr_para
;
1001 if (svf_tap_is_specified
) {
1002 padding_command_skipped
= 1;
1005 xxr_para_tmp
= &svf_para
.hir_para
;
1008 if (svf_tap_is_specified
) {
1009 padding_command_skipped
= 1;
1012 xxr_para_tmp
= &svf_para
.tdr_para
;
1015 if (svf_tap_is_specified
) {
1016 padding_command_skipped
= 1;
1019 xxr_para_tmp
= &svf_para
.tir_para
;
1022 xxr_para_tmp
= &svf_para
.sdr_para
;
1025 xxr_para_tmp
= &svf_para
.sir_para
;
1028 /* XXR length [TDI (tdi)] [TDO (tdo)][MASK (mask)] [SMASK (smask)] */
1029 if ((num_of_argu
> 10) || (num_of_argu
% 2)) {
1030 LOG_ERROR("invalid parameter of %s", argus
[0]);
1033 i_tmp
= xxr_para_tmp
->len
;
1034 xxr_para_tmp
->len
= atoi(argus
[1]);
1035 /* If we are to enlarge the buffers, all parts of xxr_para_tmp
1036 * need to be freed */
1037 if (i_tmp
< xxr_para_tmp
->len
) {
1038 free(xxr_para_tmp
->tdi
);
1039 xxr_para_tmp
->tdi
= NULL
;
1040 free(xxr_para_tmp
->tdo
);
1041 xxr_para_tmp
->tdo
= NULL
;
1042 free(xxr_para_tmp
->mask
);
1043 xxr_para_tmp
->mask
= NULL
;
1044 free(xxr_para_tmp
->smask
);
1045 xxr_para_tmp
->smask
= NULL
;
1048 LOG_DEBUG("\tlength = %d", xxr_para_tmp
->len
);
1049 xxr_para_tmp
->data_mask
= 0;
1050 for (i
= 2; i
< num_of_argu
; i
+= 2) {
1051 if ((strlen(argus
[i
+ 1]) < 3) || (argus
[i
+ 1][0] != '(') ||
1052 (argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] != ')')) {
1053 LOG_ERROR("data section error");
1056 argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] = '\0';
1057 /* TDI, TDO, MASK, SMASK */
1058 if (!strcmp(argus
[i
], "TDI")) {
1060 pbuffer_tmp
= &xxr_para_tmp
->tdi
;
1061 xxr_para_tmp
->data_mask
|= XXR_TDI
;
1062 } else if (!strcmp(argus
[i
], "TDO")) {
1064 pbuffer_tmp
= &xxr_para_tmp
->tdo
;
1065 xxr_para_tmp
->data_mask
|= XXR_TDO
;
1066 } else if (!strcmp(argus
[i
], "MASK")) {
1068 pbuffer_tmp
= &xxr_para_tmp
->mask
;
1069 xxr_para_tmp
->data_mask
|= XXR_MASK
;
1070 } else if (!strcmp(argus
[i
], "SMASK")) {
1072 pbuffer_tmp
= &xxr_para_tmp
->smask
;
1073 xxr_para_tmp
->data_mask
|= XXR_SMASK
;
1075 LOG_ERROR("unknown parameter: %s", argus
[i
]);
1079 svf_copy_hexstring_to_binary(&argus
[i
+ 1][1], pbuffer_tmp
, i_tmp
,
1080 xxr_para_tmp
->len
)) {
1081 LOG_ERROR("fail to parse hex value");
1084 SVF_BUF_LOG(DEBUG
, *pbuffer_tmp
, xxr_para_tmp
->len
, argus
[i
]);
1086 /* If a command changes the length of the last scan of the same type and the
1087 * MASK parameter is absent, */
1088 /* the mask pattern used is all cares */
1089 if (!(xxr_para_tmp
->data_mask
& XXR_MASK
) && (i_tmp
!= xxr_para_tmp
->len
)) {
1090 /* MASK not defined and length changed */
1092 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1093 xxr_para_tmp
->len
)) {
1094 LOG_ERROR("fail to adjust length of array");
1097 buf_set_ones(xxr_para_tmp
->mask
, xxr_para_tmp
->len
);
1099 /* If TDO is absent, no comparison is needed, set the mask to 0 */
1100 if (!(xxr_para_tmp
->data_mask
& XXR_TDO
)) {
1101 if (!xxr_para_tmp
->tdo
) {
1103 svf_adjust_array_length(&xxr_para_tmp
->tdo
, i_tmp
,
1104 xxr_para_tmp
->len
)) {
1105 LOG_ERROR("fail to adjust length of array");
1109 if (!xxr_para_tmp
->mask
) {
1111 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1112 xxr_para_tmp
->len
)) {
1113 LOG_ERROR("fail to adjust length of array");
1117 memset(xxr_para_tmp
->mask
, 0, (xxr_para_tmp
->len
+ 7) >> 3);
1119 /* do scan if necessary */
1120 if (command
== SDR
) {
1121 /* check buffer size first, reallocate if necessary */
1122 i
= svf_para
.hdr_para
.len
+ svf_para
.sdr_para
.len
+
1123 svf_para
.tdr_para
.len
;
1124 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1125 /* reallocate buffer */
1126 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1127 LOG_ERROR("not enough memory");
1132 /* assemble dr data */
1134 buf_set_buf(svf_para
.hdr_para
.tdi
,
1136 &svf_tdi_buffer
[svf_buffer_index
],
1138 svf_para
.hdr_para
.len
);
1139 i
+= svf_para
.hdr_para
.len
;
1140 buf_set_buf(svf_para
.sdr_para
.tdi
,
1142 &svf_tdi_buffer
[svf_buffer_index
],
1144 svf_para
.sdr_para
.len
);
1145 i
+= svf_para
.sdr_para
.len
;
1146 buf_set_buf(svf_para
.tdr_para
.tdi
,
1148 &svf_tdi_buffer
[svf_buffer_index
],
1150 svf_para
.tdr_para
.len
);
1151 i
+= svf_para
.tdr_para
.len
;
1153 /* add check data */
1154 if (svf_para
.sdr_para
.data_mask
& XXR_TDO
) {
1155 /* assemble dr mask data */
1157 buf_set_buf(svf_para
.hdr_para
.mask
,
1159 &svf_mask_buffer
[svf_buffer_index
],
1161 svf_para
.hdr_para
.len
);
1162 i
+= svf_para
.hdr_para
.len
;
1163 buf_set_buf(svf_para
.sdr_para
.mask
,
1165 &svf_mask_buffer
[svf_buffer_index
],
1167 svf_para
.sdr_para
.len
);
1168 i
+= svf_para
.sdr_para
.len
;
1169 buf_set_buf(svf_para
.tdr_para
.mask
,
1171 &svf_mask_buffer
[svf_buffer_index
],
1173 svf_para
.tdr_para
.len
);
1175 /* assemble dr check data */
1177 buf_set_buf(svf_para
.hdr_para
.tdo
,
1179 &svf_tdo_buffer
[svf_buffer_index
],
1181 svf_para
.hdr_para
.len
);
1182 i
+= svf_para
.hdr_para
.len
;
1183 buf_set_buf(svf_para
.sdr_para
.tdo
,
1185 &svf_tdo_buffer
[svf_buffer_index
],
1187 svf_para
.sdr_para
.len
);
1188 i
+= svf_para
.sdr_para
.len
;
1189 buf_set_buf(svf_para
.tdr_para
.tdo
,
1191 &svf_tdo_buffer
[svf_buffer_index
],
1193 svf_para
.tdr_para
.len
);
1194 i
+= svf_para
.tdr_para
.len
;
1196 svf_add_check_para(1, svf_buffer_index
, i
);
1198 svf_add_check_para(0, svf_buffer_index
, i
);
1200 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1201 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1203 /* NOTE: doesn't use SVF-specified state paths */
1204 jtag_add_plain_dr_scan(field
.num_bits
,
1207 svf_para
.dr_end_state
);
1211 jtag_add_clocks(svf_addcycles
);
1213 svf_buffer_index
+= (i
+ 7) >> 3;
1214 } else if (command
== SIR
) {
1215 /* check buffer size first, reallocate if necessary */
1216 i
= svf_para
.hir_para
.len
+ svf_para
.sir_para
.len
+
1217 svf_para
.tir_para
.len
;
1218 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1219 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1220 LOG_ERROR("not enough memory");
1225 /* assemble ir data */
1227 buf_set_buf(svf_para
.hir_para
.tdi
,
1229 &svf_tdi_buffer
[svf_buffer_index
],
1231 svf_para
.hir_para
.len
);
1232 i
+= svf_para
.hir_para
.len
;
1233 buf_set_buf(svf_para
.sir_para
.tdi
,
1235 &svf_tdi_buffer
[svf_buffer_index
],
1237 svf_para
.sir_para
.len
);
1238 i
+= svf_para
.sir_para
.len
;
1239 buf_set_buf(svf_para
.tir_para
.tdi
,
1241 &svf_tdi_buffer
[svf_buffer_index
],
1243 svf_para
.tir_para
.len
);
1244 i
+= svf_para
.tir_para
.len
;
1246 /* add check data */
1247 if (svf_para
.sir_para
.data_mask
& XXR_TDO
) {
1248 /* assemble dr mask data */
1250 buf_set_buf(svf_para
.hir_para
.mask
,
1252 &svf_mask_buffer
[svf_buffer_index
],
1254 svf_para
.hir_para
.len
);
1255 i
+= svf_para
.hir_para
.len
;
1256 buf_set_buf(svf_para
.sir_para
.mask
,
1258 &svf_mask_buffer
[svf_buffer_index
],
1260 svf_para
.sir_para
.len
);
1261 i
+= svf_para
.sir_para
.len
;
1262 buf_set_buf(svf_para
.tir_para
.mask
,
1264 &svf_mask_buffer
[svf_buffer_index
],
1266 svf_para
.tir_para
.len
);
1268 /* assemble dr check data */
1270 buf_set_buf(svf_para
.hir_para
.tdo
,
1272 &svf_tdo_buffer
[svf_buffer_index
],
1274 svf_para
.hir_para
.len
);
1275 i
+= svf_para
.hir_para
.len
;
1276 buf_set_buf(svf_para
.sir_para
.tdo
,
1278 &svf_tdo_buffer
[svf_buffer_index
],
1280 svf_para
.sir_para
.len
);
1281 i
+= svf_para
.sir_para
.len
;
1282 buf_set_buf(svf_para
.tir_para
.tdo
,
1284 &svf_tdo_buffer
[svf_buffer_index
],
1286 svf_para
.tir_para
.len
);
1287 i
+= svf_para
.tir_para
.len
;
1289 svf_add_check_para(1, svf_buffer_index
, i
);
1291 svf_add_check_para(0, svf_buffer_index
, i
);
1293 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1294 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1296 /* NOTE: doesn't use SVF-specified state paths */
1297 jtag_add_plain_ir_scan(field
.num_bits
,
1300 svf_para
.ir_end_state
);
1303 svf_buffer_index
+= (i
+ 7) >> 3;
1308 LOG_ERROR("PIO and PIOMAP are not supported");
1311 /* RUNTEST [run_state] run_count run_clk [min_time SEC [MAXIMUM max_time
1312 * SEC]] [ENDSTATE end_state] */
1313 /* RUNTEST [run_state] min_time SEC [MAXIMUM max_time SEC] [ENDSTATE
1315 if ((num_of_argu
< 3) || (num_of_argu
> 11)) {
1316 LOG_ERROR("invalid parameter of %s", argus
[0]);
1325 i_tmp
= tap_state_by_name(argus
[i
]);
1326 if (i_tmp
!= TAP_INVALID
) {
1327 if (svf_tap_state_is_stable(i_tmp
)) {
1328 svf_para
.runtest_run_state
= i_tmp
;
1330 /* When a run_state is specified, the new
1331 * run_state becomes the default end_state.
1333 svf_para
.runtest_end_state
= i_tmp
;
1334 LOG_DEBUG("\trun_state = %s", tap_state_name(i_tmp
));
1337 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1342 /* run_count run_clk */
1343 if (((i
+ 2) <= num_of_argu
) && strcmp(argus
[i
+ 1], "SEC")) {
1344 if (!strcmp(argus
[i
+ 1], "TCK")) {
1345 /* clock source is TCK */
1346 run_count
= atoi(argus
[i
]);
1347 LOG_DEBUG("\trun_count@TCK = %d", run_count
);
1349 LOG_ERROR("%s not supported for clock", argus
[i
+ 1]);
1355 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
+ 1], "SEC")) {
1356 min_time
= atof(argus
[i
]);
1357 LOG_DEBUG("\tmin_time = %fs", min_time
);
1360 /* MAXIMUM max_time SEC */
1361 if (((i
+ 3) <= num_of_argu
) &&
1362 !strcmp(argus
[i
], "MAXIMUM") && !strcmp(argus
[i
+ 2], "SEC")) {
1364 max_time
= atof(argus
[i
+ 1]);
1365 LOG_DEBUG("\tmax_time = %fs", max_time
);
1368 /* ENDSTATE end_state */
1369 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
], "ENDSTATE")) {
1370 i_tmp
= tap_state_by_name(argus
[i
+ 1]);
1372 if (svf_tap_state_is_stable(i_tmp
)) {
1373 svf_para
.runtest_end_state
= i_tmp
;
1374 LOG_DEBUG("\tend_state = %s", tap_state_name(i_tmp
));
1376 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1382 /* all parameter should be parsed */
1383 if (i
== num_of_argu
) {
1385 /* FIXME handle statemove failures */
1386 uint32_t min_usec
= 1000000 * min_time
;
1388 /* enter into run_state if necessary */
1389 if (cmd_queue_cur_state
!= svf_para
.runtest_run_state
)
1390 svf_add_statemove(svf_para
.runtest_run_state
);
1392 /* add clocks and/or min wait */
1393 if (run_count
> 0) {
1395 jtag_add_clocks(run_count
);
1400 jtag_add_sleep(min_usec
);
1403 /* move to end_state if necessary */
1404 if (svf_para
.runtest_end_state
!= svf_para
.runtest_run_state
)
1405 svf_add_statemove(svf_para
.runtest_end_state
);
1408 if (svf_para
.runtest_run_state
!= TAP_IDLE
) {
1409 LOG_ERROR("cannot runtest in %s state",
1410 tap_state_name(svf_para
.runtest_run_state
));
1415 jtag_add_runtest(run_count
, svf_para
.runtest_end_state
);
1418 LOG_ERROR("fail to parse parameter of RUNTEST, %d out of %d is parsed",
1425 /* STATE [pathstate1 [pathstate2 ...[pathstaten]]] stable_state */
1426 if (num_of_argu
< 2) {
1427 LOG_ERROR("invalid parameter of %s", argus
[0]);
1430 if (num_of_argu
> 2) {
1431 /* STATE pathstate1 ... stable_state */
1432 path
= malloc((num_of_argu
- 1) * sizeof(tap_state_t
));
1434 LOG_ERROR("not enough memory");
1437 num_of_argu
--; /* num of path */
1438 i_tmp
= 1; /* path is from parameter 1 */
1439 for (i
= 0; i
< num_of_argu
; i
++, i_tmp
++) {
1440 path
[i
] = tap_state_by_name(argus
[i_tmp
]);
1441 if (path
[i
] == TAP_INVALID
) {
1442 LOG_ERROR("%s: %s is not a valid state", argus
[0], argus
[i_tmp
]);
1446 /* OpenOCD refuses paths containing TAP_RESET */
1447 if (path
[i
] == TAP_RESET
) {
1448 /* FIXME last state MUST be stable! */
1451 jtag_add_pathmove(i
, path
);
1455 num_of_argu
-= i
+ 1;
1459 if (num_of_argu
> 0) {
1460 /* execute last path if necessary */
1461 if (svf_tap_state_is_stable(path
[num_of_argu
- 1])) {
1462 /* last state MUST be stable state */
1464 jtag_add_pathmove(num_of_argu
, path
);
1465 LOG_DEBUG("\tmove to %s by path_move",
1466 tap_state_name(path
[num_of_argu
- 1]));
1468 LOG_ERROR("%s: %s is not a stable state",
1470 tap_state_name(path
[num_of_argu
- 1]));
1479 /* STATE stable_state */
1480 state
= tap_state_by_name(argus
[1]);
1481 if (svf_tap_state_is_stable(state
)) {
1482 LOG_DEBUG("\tmove to %s by svf_add_statemove",
1483 tap_state_name(state
));
1484 /* FIXME handle statemove failures */
1485 svf_add_statemove(state
);
1487 LOG_ERROR("%s: %s is not a stable state",
1488 argus
[0], tap_state_name(state
));
1494 /* TRST trst_mode */
1495 if (num_of_argu
!= 2) {
1496 LOG_ERROR("invalid parameter of %s", argus
[0]);
1499 if (svf_para
.trst_mode
!= TRST_ABSENT
) {
1500 if (svf_execute_tap() != ERROR_OK
)
1502 i_tmp
= svf_find_string_in_array(argus
[1],
1503 (char **)svf_trst_mode_name
,
1504 ARRAY_SIZE(svf_trst_mode_name
));
1508 jtag_add_reset(1, 0);
1513 jtag_add_reset(0, 0);
1518 LOG_ERROR("unknown TRST mode: %s", argus
[1]);
1521 svf_para
.trst_mode
= i_tmp
;
1522 LOG_DEBUG("\ttrst_mode = %s", svf_trst_mode_name
[svf_para
.trst_mode
]);
1524 LOG_ERROR("can not accept TRST command if trst_mode is ABSENT");
1529 LOG_ERROR("invalid svf command: %s", argus
[0]);
1534 if (padding_command_skipped
)
1535 LOG_USER("(Above Padding command skipped, as per -tap argument)");
1538 if (debug_level
>= LOG_LVL_DEBUG
) {
1539 /* for convenient debugging, execute tap if possible */
1540 if ((svf_buffer_index
> 0) &&
1541 (((command
!= STATE
) && (command
!= RUNTEST
)) ||
1542 ((command
== STATE
) && (num_of_argu
== 2)))) {
1543 if (svf_execute_tap() != ERROR_OK
)
1546 /* output debug info */
1547 if ((command
== SIR
) || (command
== SDR
))
1548 SVF_BUF_LOG(DEBUG
, svf_tdi_buffer
, svf_check_tdo_para
[0].bit_len
, "TDO read");
1551 /* for fast executing, execute tap if necessary */
1552 /* half of the buffer is for the next command */
1553 if (((svf_buffer_index
>= SVF_MAX_BUFFER_SIZE_TO_COMMIT
) ||
1554 (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
/ 2)) &&
1555 (((command
!= STATE
) && (command
!= RUNTEST
)) ||
1556 ((command
== STATE
) && (num_of_argu
== 2))))
1557 return svf_execute_tap();
1563 static const struct command_registration svf_command_handlers
[] = {
1566 .handler
= handle_svf_command
,
1567 .mode
= COMMAND_EXEC
,
1568 .help
= "Runs a SVF file.",
1569 .usage
= "[-tap device.tap] <file> [quiet] [nil] [progress] [ignore_error] [-noreset] [-addcycles numcycles]",
1571 COMMAND_REGISTRATION_DONE
1574 int svf_register_commands(struct command_context
*cmd_ctx
)
1576 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)