1 /***************************************************************************
2 * Copyright (C) 2009 by Simon Qian *
3 * SimonQian@SimonQian.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
21 /* The specification for SVF is available here:
22 * http://www.asset-intertech.com/support/svf.pdf
23 * Below, this document is refered to as the "SVF spec".
25 * The specification for XSVF is available here:
26 * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf
27 * Below, this document is refered to as the "XSVF spec".
34 #include <jtag/jtag.h>
36 #include <helper/time_support.h>
56 static const char *svf_command_name
[14] = {
80 static const char *svf_trst_mode_name
[4] = {
87 struct svf_statemove
{
90 uint32_t num_of_moves
;
95 * These paths are from the SVF specification for the STATE command, to be
96 * used when the STATE command only includes the final state. The first
97 * element of the path is the "from" (current) state, and the last one is
98 * the "to" (target) state.
100 * All specified paths are the shortest ones in the JTAG spec, and are thus
101 * not (!!) exact matches for the paths used elsewhere in OpenOCD. Note
102 * that PAUSE-to-PAUSE transitions all go through UPDATE and then CAPTURE,
103 * which has specific effects on the various registers; they are not NOPs.
105 * Paths to RESET are disabled here. As elsewhere in OpenOCD, and in XSVF
106 * and many SVF implementations, we don't want to risk missing that state.
107 * To get to RESET, always we ignore the current state.
109 static const struct svf_statemove svf_statemoves
[] = {
110 /* from to num_of_moves, paths[8] */
111 /* {TAP_RESET, TAP_RESET, 1, {TAP_RESET}}, */
112 {TAP_RESET
, TAP_IDLE
, 2, {TAP_RESET
, TAP_IDLE
} },
113 {TAP_RESET
, TAP_DRPAUSE
, 6, {TAP_RESET
, TAP_IDLE
, TAP_DRSELECT
,
114 TAP_DRCAPTURE
, TAP_DREXIT1
, TAP_DRPAUSE
} },
115 {TAP_RESET
, TAP_IRPAUSE
, 7, {TAP_RESET
, TAP_IDLE
, TAP_DRSELECT
,
116 TAP_IRSELECT
, TAP_IRCAPTURE
,
117 TAP_IREXIT1
, TAP_IRPAUSE
} },
119 /* {TAP_IDLE, TAP_RESET, 4, {TAP_IDLE,
120 * TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
121 {TAP_IDLE
, TAP_IDLE
, 1, {TAP_IDLE
} },
122 {TAP_IDLE
, TAP_DRPAUSE
, 5, {TAP_IDLE
, TAP_DRSELECT
, TAP_DRCAPTURE
,
123 TAP_DREXIT1
, TAP_DRPAUSE
} },
124 {TAP_IDLE
, TAP_IRPAUSE
, 6, {TAP_IDLE
, TAP_DRSELECT
, TAP_IRSELECT
,
125 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} },
127 /* {TAP_DRPAUSE, TAP_RESET, 6, {TAP_DRPAUSE,
128 * TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
129 {TAP_DRPAUSE
, TAP_IDLE
, 4, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
131 {TAP_DRPAUSE
, TAP_DRPAUSE
, 7, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
132 TAP_DRSELECT
, TAP_DRCAPTURE
,
133 TAP_DREXIT1
, TAP_DRPAUSE
} },
134 {TAP_DRPAUSE
, TAP_IRPAUSE
, 8, {TAP_DRPAUSE
, TAP_DREXIT2
, TAP_DRUPDATE
,
135 TAP_DRSELECT
, TAP_IRSELECT
,
136 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} },
138 /* {TAP_IRPAUSE, TAP_RESET, 6, {TAP_IRPAUSE,
139 * TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */
140 {TAP_IRPAUSE
, TAP_IDLE
, 4, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
142 {TAP_IRPAUSE
, TAP_DRPAUSE
, 7, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
143 TAP_DRSELECT
, TAP_DRCAPTURE
,
144 TAP_DREXIT1
, TAP_DRPAUSE
} },
145 {TAP_IRPAUSE
, TAP_IRPAUSE
, 8, {TAP_IRPAUSE
, TAP_IREXIT2
, TAP_IRUPDATE
,
146 TAP_DRSELECT
, TAP_IRSELECT
,
147 TAP_IRCAPTURE
, TAP_IREXIT1
, TAP_IRPAUSE
} }
150 #define XXR_TDI (1 << 0)
151 #define XXR_TDO (1 << 1)
152 #define XXR_MASK (1 << 2)
153 #define XXR_SMASK (1 << 3)
154 struct svf_xxr_para
{
165 tap_state_t ir_end_state
;
166 tap_state_t dr_end_state
;
167 tap_state_t runtest_run_state
;
168 tap_state_t runtest_end_state
;
169 enum trst_mode trst_mode
;
171 struct svf_xxr_para hir_para
;
172 struct svf_xxr_para hdr_para
;
173 struct svf_xxr_para tir_para
;
174 struct svf_xxr_para tdr_para
;
175 struct svf_xxr_para sir_para
;
176 struct svf_xxr_para sdr_para
;
179 static struct svf_para svf_para
;
180 static const struct svf_para svf_para_init
= {
181 /* frequency, ir_end_state, dr_end_state, runtest_run_state, runtest_end_state, trst_mode */
182 0, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TAP_IDLE
, TRST_Z
,
184 /* {len, data_mask, tdi, tdo, mask, smask}, */
185 {0, 0, NULL
, NULL
, NULL
, NULL
},
187 /* {len, data_mask, tdi, tdo, mask, smask}, */
188 {0, 0, NULL
, NULL
, NULL
, NULL
},
190 /* {len, data_mask, tdi, tdo, mask, smask}, */
191 {0, 0, NULL
, NULL
, NULL
, NULL
},
193 /* {len, data_mask, tdi, tdo, mask, smask}, */
194 {0, 0, NULL
, NULL
, NULL
, NULL
},
196 /* {len, data_mask, tdi, tdo, mask, smask}, */
197 {0, 0, NULL
, NULL
, NULL
, NULL
},
199 /* {len, data_mask, tdi, tdo, mask, smask}, */
200 {0, 0, NULL
, NULL
, NULL
, NULL
},
203 struct svf_check_tdo_para
{
204 int line_num
; /* used to record line number of the check operation */
205 /* so more information could be printed */
206 int enabled
; /* check is enabled or not */
207 int buffer_offset
; /* buffer_offset to buffers */
208 int bit_len
; /* bit length to check */
211 #define SVF_CHECK_TDO_PARA_SIZE 1024
212 static struct svf_check_tdo_para
*svf_check_tdo_para
;
213 static int svf_check_tdo_para_index
;
215 static int svf_read_command_from_file(FILE *fd
);
216 static int svf_check_tdo(void);
217 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
);
218 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
);
219 static int svf_execute_tap(void);
222 static char *svf_read_line
;
223 static size_t svf_read_line_size
;
224 static char *svf_command_buffer
;
225 static size_t svf_command_buffer_size
;
226 static int svf_line_number
;
227 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
);
229 #define SVF_MAX_BUFFER_SIZE_TO_COMMIT (1024 * 1024)
230 static uint8_t *svf_tdi_buffer
, *svf_tdo_buffer
, *svf_mask_buffer
;
231 static int svf_buffer_index
, svf_buffer_size
;
232 static int svf_quiet
;
234 static int svf_ignore_error
;
236 /* Targetting particular tap */
237 static int svf_tap_is_specified
;
238 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
);
240 /* Progress Indicator */
241 static int svf_progress_enabled
;
242 static long svf_total_lines
;
243 static int svf_percentage
;
244 static int svf_last_printed_percentage
= -1;
247 * macro is used to print the svf hex buffer at desired debug level
248 * DEBUG, INFO, ERROR, USER
250 #define SVF_BUF_LOG(_lvl, _buf, _nbits, _desc) \
251 svf_hexbuf_print(LOG_LVL_##_lvl , __FILE__, __LINE__, __func__, _buf, _nbits, _desc)
253 static void svf_hexbuf_print(int dbg_lvl
, const char *file
, unsigned line
,
254 const char *function
, const uint8_t *buf
,
255 int bit_len
, const char *desc
)
258 int byte_len
= DIV_ROUND_UP(bit_len
, 8);
259 int msbits
= bit_len
% 8;
261 /* allocate 2 bytes per hex digit */
262 char *prbuf
= malloc((byte_len
* 2) + 2 + 1);
266 /* print correct number of bytes, mask excess bits where applicable */
267 uint8_t msb
= buf
[byte_len
- 1] & (msbits
? (1 << msbits
) - 1 : 0xff);
268 len
= sprintf(prbuf
, msbits
<= 4 ? "0x%01"PRIx8
: "0x%02"PRIx8
, msb
);
269 for (j
= byte_len
- 2; j
>= 0; j
--)
270 len
+= sprintf(prbuf
+ len
, "%02"PRIx8
, buf
[j
]);
272 log_printf_lf(dbg_lvl
, file
, line
, function
, "%8s = %s", desc
? desc
: " ", prbuf
);
277 static int svf_realloc_buffers(size_t len
)
281 if (svf_execute_tap() != ERROR_OK
)
284 ptr
= realloc(svf_tdi_buffer
, len
);
287 svf_tdi_buffer
= ptr
;
289 ptr
= realloc(svf_tdo_buffer
, len
);
292 svf_tdo_buffer
= ptr
;
294 ptr
= realloc(svf_mask_buffer
, len
);
297 svf_mask_buffer
= ptr
;
299 svf_buffer_size
= len
;
304 static void svf_free_xxd_para(struct svf_xxr_para
*para
)
307 if (para
->tdi
!= NULL
) {
311 if (para
->tdo
!= NULL
) {
315 if (para
->mask
!= NULL
) {
319 if (para
->smask
!= NULL
) {
326 int svf_add_statemove(tap_state_t state_to
)
328 tap_state_t state_from
= cmd_queue_cur_state
;
331 /* when resetting, be paranoid and ignore current state */
332 if (state_to
== TAP_RESET
) {
340 for (index_var
= 0; index_var
< ARRAY_SIZE(svf_statemoves
); index_var
++) {
341 if ((svf_statemoves
[index_var
].from
== state_from
)
342 && (svf_statemoves
[index_var
].to
== state_to
)) {
345 /* recorded path includes current state ... avoid
347 if (svf_statemoves
[index_var
].num_of_moves
> 1)
348 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
- 1,
349 svf_statemoves
[index_var
].paths
+ 1);
351 jtag_add_pathmove(svf_statemoves
[index_var
].num_of_moves
,
352 svf_statemoves
[index_var
].paths
);
356 LOG_ERROR("SVF: can not move to %s", tap_state_name(state_to
));
360 COMMAND_HANDLER(handle_svf_command
)
362 #define SVF_MIN_NUM_OF_OPTIONS 1
363 #define SVF_MAX_NUM_OF_OPTIONS 5
366 long long time_measure_ms
;
367 int time_measure_s
, time_measure_m
;
369 /* use NULL to indicate a "plain" svf file which accounts for
370 * any additional devices in the scan chain, otherwise the device
371 * that should be affected
373 struct jtag_tap
*tap
= NULL
;
375 if ((CMD_ARGC
< SVF_MIN_NUM_OF_OPTIONS
) || (CMD_ARGC
> SVF_MAX_NUM_OF_OPTIONS
))
376 return ERROR_COMMAND_SYNTAX_ERROR
;
378 /* parse command line */
381 svf_progress_enabled
= 0;
382 svf_ignore_error
= 0;
383 for (unsigned int i
= 0; i
< CMD_ARGC
; i
++) {
384 if (strcmp(CMD_ARGV
[i
], "-tap") == 0) {
385 tap
= jtag_tap_by_string(CMD_ARGV
[i
+1]);
387 command_print(CMD_CTX
, "Tap: %s unknown", CMD_ARGV
[i
+1]);
391 } else if ((strcmp(CMD_ARGV
[i
],
392 "quiet") == 0) || (strcmp(CMD_ARGV
[i
], "-quiet") == 0))
394 else if ((strcmp(CMD_ARGV
[i
], "nil") == 0) || (strcmp(CMD_ARGV
[i
], "-nil") == 0))
396 else if ((strcmp(CMD_ARGV
[i
],
397 "progress") == 0) || (strcmp(CMD_ARGV
[i
], "-progress") == 0))
398 svf_progress_enabled
= 1;
399 else if ((strcmp(CMD_ARGV
[i
],
400 "ignore_error") == 0) || (strcmp(CMD_ARGV
[i
], "-ignore_error") == 0))
401 svf_ignore_error
= 1;
403 svf_fd
= fopen(CMD_ARGV
[i
], "r");
404 if (svf_fd
== NULL
) {
406 command_print(CMD_CTX
, "open(\"%s\"): %s", CMD_ARGV
[i
], strerror(err
));
407 /* no need to free anything now */
408 return ERROR_COMMAND_SYNTAX_ERROR
;
410 LOG_USER("svf processing file: \"%s\"", CMD_ARGV
[i
]);
415 return ERROR_COMMAND_SYNTAX_ERROR
;
418 time_measure_ms
= timeval_ms();
422 svf_command_buffer_size
= 0;
424 svf_check_tdo_para_index
= 0;
425 svf_check_tdo_para
= malloc(sizeof(struct svf_check_tdo_para
) * SVF_CHECK_TDO_PARA_SIZE
);
426 if (NULL
== svf_check_tdo_para
) {
427 LOG_ERROR("not enough memory");
432 svf_buffer_index
= 0;
433 /* double the buffer size */
434 /* in case current command cannot be committed, and next command is a bit scan command */
435 /* here is 32K bits for this big scan command, it should be enough */
436 /* buffer will be reallocated if buffer size is not enough */
437 if (svf_realloc_buffers(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT
) != ERROR_OK
) {
442 memcpy(&svf_para
, &svf_para_init
, sizeof(svf_para
));
450 /* Tap is specified, set header/trailer paddings */
451 int header_ir_len
= 0, header_dr_len
= 0, trailer_ir_len
= 0, trailer_dr_len
= 0;
452 struct jtag_tap
*check_tap
;
454 svf_tap_is_specified
= 1;
456 for (check_tap
= jtag_all_taps(); check_tap
; check_tap
= check_tap
->next_tap
) {
457 if (check_tap
->abs_chain_position
< tap
->abs_chain_position
) {
459 header_ir_len
+= check_tap
->ir_length
;
461 } else if (check_tap
->abs_chain_position
> tap
->abs_chain_position
) {
463 trailer_ir_len
+= check_tap
->ir_length
;
469 if (ERROR_OK
!= svf_set_padding(&svf_para
.hdr_para
, header_dr_len
, 0)) {
470 LOG_ERROR("failed to set data header");
474 /* HIR %d TDI (0xFF) */
475 if (ERROR_OK
!= svf_set_padding(&svf_para
.hir_para
, header_ir_len
, 0xFF)) {
476 LOG_ERROR("failed to set instruction header");
481 if (ERROR_OK
!= svf_set_padding(&svf_para
.tdr_para
, trailer_dr_len
, 0)) {
482 LOG_ERROR("failed to set data trailer");
486 /* TIR %d TDI (0xFF) */
487 if (ERROR_OK
!= svf_set_padding(&svf_para
.tir_para
, trailer_ir_len
, 0xFF)) {
488 LOG_ERROR("failed to set instruction trailer");
493 if (svf_progress_enabled
) {
494 /* Count total lines in file. */
495 while (!feof(svf_fd
)) {
496 svf_getline(&svf_command_buffer
, &svf_command_buffer_size
, svf_fd
);
501 while (ERROR_OK
== svf_read_command_from_file(svf_fd
)) {
504 if (svf_progress_enabled
) {
505 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
506 if (svf_last_printed_percentage
!= svf_percentage
) {
507 LOG_USER_N("\r%d%% ", svf_percentage
);
508 svf_last_printed_percentage
= svf_percentage
;
512 if (svf_progress_enabled
) {
513 svf_percentage
= ((svf_line_number
* 20) / svf_total_lines
) * 5;
514 LOG_USER_N("%3d%% %s", svf_percentage
, svf_read_line
);
516 LOG_USER_N("%s", svf_read_line
);
519 if (ERROR_OK
!= svf_run_command(CMD_CTX
, svf_command_buffer
)) {
520 LOG_ERROR("fail to run command at line %d", svf_line_number
);
527 if ((!svf_nil
) && (ERROR_OK
!= jtag_execute_queue()))
529 else if (ERROR_OK
!= svf_check_tdo())
533 time_measure_ms
= timeval_ms() - time_measure_ms
;
534 time_measure_s
= time_measure_ms
/ 1000;
535 time_measure_ms
%= 1000;
536 time_measure_m
= time_measure_s
/ 60;
537 time_measure_s
%= 60;
538 if (time_measure_ms
< 1000)
539 command_print(CMD_CTX
,
540 "\r\nTime used: %dm%ds%lldms ",
551 if (svf_command_buffer
) {
552 free(svf_command_buffer
);
553 svf_command_buffer
= NULL
;
554 svf_command_buffer_size
= 0;
556 if (svf_check_tdo_para
) {
557 free(svf_check_tdo_para
);
558 svf_check_tdo_para
= NULL
;
559 svf_check_tdo_para_index
= 0;
561 if (svf_tdi_buffer
) {
562 free(svf_tdi_buffer
);
563 svf_tdi_buffer
= NULL
;
565 if (svf_tdo_buffer
) {
566 free(svf_tdo_buffer
);
567 svf_tdo_buffer
= NULL
;
569 if (svf_mask_buffer
) {
570 free(svf_mask_buffer
);
571 svf_mask_buffer
= NULL
;
573 svf_buffer_index
= 0;
576 svf_free_xxd_para(&svf_para
.hdr_para
);
577 svf_free_xxd_para(&svf_para
.hir_para
);
578 svf_free_xxd_para(&svf_para
.tdr_para
);
579 svf_free_xxd_para(&svf_para
.tir_para
);
580 svf_free_xxd_para(&svf_para
.sdr_para
);
581 svf_free_xxd_para(&svf_para
.sir_para
);
584 command_print(CMD_CTX
,
585 "svf file programmed %s for %d commands with %d errors",
586 (svf_ignore_error
> 1) ? "unsuccessfully" : "successfully",
588 (svf_ignore_error
> 1) ? (svf_ignore_error
- 1) : 0);
590 command_print(CMD_CTX
, "svf file programmed failed");
592 svf_ignore_error
= 0;
596 static int svf_getline(char **lineptr
, size_t *n
, FILE *stream
)
598 #define MIN_CHUNK 16 /* Buffer is increased by this size each time as required */
601 if (*lineptr
== NULL
) {
603 *lineptr
= malloc(*n
);
608 (*lineptr
)[0] = fgetc(stream
);
609 while ((*lineptr
)[i
] != '\n') {
610 (*lineptr
)[++i
] = fgetc(stream
);
617 *lineptr
= realloc(*lineptr
, *n
);
623 return sizeof(*lineptr
);
626 #define SVFP_CMD_INC_CNT 1024
627 static int svf_read_command_from_file(FILE *fd
)
632 int cmd_ok
= 0, slash
= 0;
634 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
637 ch
= svf_read_line
[0];
638 while (!cmd_ok
&& (ch
!= 0)) {
642 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
650 if (svf_getline(&svf_read_line
, &svf_read_line_size
,
663 if (svf_getline(&svf_read_line
, &svf_read_line_size
, svf_fd
) <= 0)
668 /* Don't save '\r' and '\n' if no data is parsed */
672 /* The parsing code currently expects a space
673 * before parentheses -- "TDI (123)". Also a
674 * space afterwards -- "TDI (123) TDO(456)".
675 * But such spaces are optional... instead of
676 * parser updates, cope with that by adding the
679 * Ensure there are 3 bytes available, for:
680 * - current character
682 * - terminating NUL ('\0')
684 if (cmd_pos
+ 3 > svf_command_buffer_size
) {
685 svf_command_buffer
= realloc(svf_command_buffer
, cmd_pos
+ 3);
686 svf_command_buffer_size
= cmd_pos
+ 3;
687 if (svf_command_buffer
== NULL
) {
688 LOG_ERROR("not enough memory");
693 /* insert a space before '(' */
695 svf_command_buffer
[cmd_pos
++] = ' ';
697 svf_command_buffer
[cmd_pos
++] = (char)toupper(ch
);
699 /* insert a space after ')' */
701 svf_command_buffer
[cmd_pos
++] = ' ';
704 ch
= svf_read_line
[++i
];
708 svf_command_buffer
[cmd_pos
] = '\0';
714 static int svf_parse_cmd_string(char *str
, int len
, char **argus
, int *num_of_argu
)
716 int pos
= 0, num
= 0, space_found
= 1, in_bracket
= 0;
722 LOG_ERROR("fail to parse svf command");
732 if (!in_bracket
&& isspace((int) str
[pos
])) {
735 } else if (space_found
) {
736 argus
[num
++] = &str
[pos
];
749 bool svf_tap_state_is_stable(tap_state_t state
)
751 return (TAP_RESET
== state
) || (TAP_IDLE
== state
)
752 || (TAP_DRPAUSE
== state
) || (TAP_IRPAUSE
== state
);
755 static int svf_find_string_in_array(char *str
, char **strs
, int num_of_element
)
759 for (i
= 0; i
< num_of_element
; i
++) {
760 if (!strcmp(str
, strs
[i
]))
766 static int svf_adjust_array_length(uint8_t **arr
, int orig_bit_len
, int new_bit_len
)
768 int new_byte_len
= (new_bit_len
+ 7) >> 3;
770 if ((NULL
== *arr
) || (((orig_bit_len
+ 7) >> 3) < ((new_bit_len
+ 7) >> 3))) {
775 *arr
= malloc(new_byte_len
);
777 LOG_ERROR("not enough memory");
780 memset(*arr
, 0, new_byte_len
);
785 static int svf_set_padding(struct svf_xxr_para
*para
, int len
, unsigned char tdi
)
787 int error
= ERROR_OK
;
788 error
|= svf_adjust_array_length(¶
->tdi
, para
->len
, len
);
789 memset(para
->tdi
, tdi
, (len
+ 7) >> 3);
790 error
|= svf_adjust_array_length(¶
->tdo
, para
->len
, len
);
791 error
|= svf_adjust_array_length(¶
->mask
, para
->len
, len
);
793 para
->data_mask
= XXR_TDI
;
798 static int svf_copy_hexstring_to_binary(char *str
, uint8_t **bin
, int orig_bit_len
, int bit_len
)
800 int i
, str_len
= strlen(str
), str_hbyte_len
= (bit_len
+ 3) >> 2;
803 if (ERROR_OK
!= svf_adjust_array_length(bin
, orig_bit_len
, bit_len
)) {
804 LOG_ERROR("fail to adjust length of array");
808 /* fill from LSB (end of str) to MSB (beginning of str) */
809 for (i
= 0; i
< str_hbyte_len
; i
++) {
811 while (str_len
> 0) {
814 /* Skip whitespace. The SVF specification (rev E) is
815 * deficient in terms of basic lexical issues like
816 * where whitespace is allowed. Long bitstrings may
817 * require line ends for correctness, since there is
818 * a hard limit on line length.
821 if ((ch
>= '0') && (ch
<= '9')) {
824 } else if ((ch
>= 'A') && (ch
<= 'F')) {
828 LOG_ERROR("invalid hex string");
839 (*bin
)[i
/ 2] |= ch
<< 4;
847 /* consume optional leading '0' MSBs or whitespace */
848 while (str_len
> 0 && ((str
[str_len
- 1] == '0')
849 || isspace((int) str
[str_len
- 1])))
852 /* check validity: we must have consumed everything */
853 if (str_len
> 0 || (ch
& ~((2 << ((bit_len
- 1) % 4)) - 1)) != 0) {
854 LOG_ERROR("value execeeds length");
861 static int svf_check_tdo(void)
863 int i
, len
, index_var
;
865 for (i
= 0; i
< svf_check_tdo_para_index
; i
++) {
866 index_var
= svf_check_tdo_para
[i
].buffer_offset
;
867 len
= svf_check_tdo_para
[i
].bit_len
;
868 if ((svf_check_tdo_para
[i
].enabled
)
869 && buf_cmp_mask(&svf_tdi_buffer
[index_var
], &svf_tdo_buffer
[index_var
],
870 &svf_mask_buffer
[index_var
], len
)) {
871 LOG_ERROR("tdo check error at line %d",
872 svf_check_tdo_para
[i
].line_num
);
873 SVF_BUF_LOG(ERROR
, &svf_tdi_buffer
[index_var
], len
, "READ");
874 SVF_BUF_LOG(ERROR
, &svf_tdo_buffer
[index_var
], len
, "WANT");
875 SVF_BUF_LOG(ERROR
, &svf_mask_buffer
[index_var
], len
, "MASK");
877 if (svf_ignore_error
== 0)
883 svf_check_tdo_para_index
= 0;
888 static int svf_add_check_para(uint8_t enabled
, int buffer_offset
, int bit_len
)
890 if (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
) {
891 LOG_ERROR("toooooo many operation undone");
895 svf_check_tdo_para
[svf_check_tdo_para_index
].line_num
= svf_line_number
;
896 svf_check_tdo_para
[svf_check_tdo_para_index
].bit_len
= bit_len
;
897 svf_check_tdo_para
[svf_check_tdo_para_index
].enabled
= enabled
;
898 svf_check_tdo_para
[svf_check_tdo_para_index
].buffer_offset
= buffer_offset
;
899 svf_check_tdo_para_index
++;
904 static int svf_execute_tap(void)
906 if ((!svf_nil
) && (ERROR_OK
!= jtag_execute_queue()))
908 else if (ERROR_OK
!= svf_check_tdo())
911 svf_buffer_index
= 0;
916 static int svf_run_command(struct command_context
*cmd_ctx
, char *cmd_str
)
918 char *argus
[256], command
;
919 int num_of_argu
= 0, i
;
928 struct svf_xxr_para
*xxr_para_tmp
;
929 uint8_t **pbuffer_tmp
;
930 struct scan_field field
;
932 tap_state_t
*path
= NULL
, state
;
933 /* flag padding commands skipped due to -tap command */
934 int padding_command_skipped
= 0;
936 if (ERROR_OK
!= svf_parse_cmd_string(cmd_str
, strlen(cmd_str
), argus
, &num_of_argu
))
939 /* NOTE: we're a bit loose here, because we ignore case in
940 * TAP state names (instead of insisting on uppercase).
943 command
= svf_find_string_in_array(argus
[0],
944 (char **)svf_command_name
, ARRAY_SIZE(svf_command_name
));
948 if (num_of_argu
!= 2) {
949 LOG_ERROR("invalid parameter of %s", argus
[0]);
953 i_tmp
= tap_state_by_name(argus
[1]);
955 if (svf_tap_state_is_stable(i_tmp
)) {
956 if (command
== ENDIR
) {
957 svf_para
.ir_end_state
= i_tmp
;
958 LOG_DEBUG("\tIR end_state = %s",
959 tap_state_name(i_tmp
));
961 svf_para
.dr_end_state
= i_tmp
;
962 LOG_DEBUG("\tDR end_state = %s",
963 tap_state_name(i_tmp
));
966 LOG_ERROR("%s: %s is not a stable state",
972 if ((num_of_argu
!= 1) && (num_of_argu
!= 3)) {
973 LOG_ERROR("invalid parameter of %s", argus
[0]);
976 if (1 == num_of_argu
) {
977 /* TODO: set jtag speed to full speed */
978 svf_para
.frequency
= 0;
980 if (strcmp(argus
[2], "HZ")) {
981 LOG_ERROR("HZ not found in FREQUENCY command");
984 if (ERROR_OK
!= svf_execute_tap())
986 svf_para
.frequency
= atof(argus
[1]);
987 /* TODO: set jtag speed to */
988 if (svf_para
.frequency
> 0) {
989 command_run_linef(cmd_ctx
,
991 (int)svf_para
.frequency
/ 1000);
992 LOG_DEBUG("\tfrequency = %f", svf_para
.frequency
);
997 if (svf_tap_is_specified
) {
998 padding_command_skipped
= 1;
1001 xxr_para_tmp
= &svf_para
.hdr_para
;
1004 if (svf_tap_is_specified
) {
1005 padding_command_skipped
= 1;
1008 xxr_para_tmp
= &svf_para
.hir_para
;
1011 if (svf_tap_is_specified
) {
1012 padding_command_skipped
= 1;
1015 xxr_para_tmp
= &svf_para
.tdr_para
;
1018 if (svf_tap_is_specified
) {
1019 padding_command_skipped
= 1;
1022 xxr_para_tmp
= &svf_para
.tir_para
;
1025 xxr_para_tmp
= &svf_para
.sdr_para
;
1028 xxr_para_tmp
= &svf_para
.sir_para
;
1031 /* XXR length [TDI (tdi)] [TDO (tdo)][MASK (mask)] [SMASK (smask)] */
1032 if ((num_of_argu
> 10) || (num_of_argu
% 2)) {
1033 LOG_ERROR("invalid parameter of %s", argus
[0]);
1036 i_tmp
= xxr_para_tmp
->len
;
1037 xxr_para_tmp
->len
= atoi(argus
[1]);
1038 /* If we are to enlarge the buffers, all parts of xxr_para_tmp
1039 * need to be freed */
1040 if (i_tmp
< xxr_para_tmp
->len
) {
1041 free(xxr_para_tmp
->tdi
);
1042 xxr_para_tmp
->tdi
= NULL
;
1043 free(xxr_para_tmp
->tdo
);
1044 xxr_para_tmp
->tdo
= NULL
;
1045 free(xxr_para_tmp
->mask
);
1046 xxr_para_tmp
->mask
= NULL
;
1047 free(xxr_para_tmp
->smask
);
1048 xxr_para_tmp
->smask
= NULL
;
1051 LOG_DEBUG("\tlength = %d", xxr_para_tmp
->len
);
1052 xxr_para_tmp
->data_mask
= 0;
1053 for (i
= 2; i
< num_of_argu
; i
+= 2) {
1054 if ((strlen(argus
[i
+ 1]) < 3) || (argus
[i
+ 1][0] != '(') ||
1055 (argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] != ')')) {
1056 LOG_ERROR("data section error");
1059 argus
[i
+ 1][strlen(argus
[i
+ 1]) - 1] = '\0';
1060 /* TDI, TDO, MASK, SMASK */
1061 if (!strcmp(argus
[i
], "TDI")) {
1063 pbuffer_tmp
= &xxr_para_tmp
->tdi
;
1064 xxr_para_tmp
->data_mask
|= XXR_TDI
;
1065 } else if (!strcmp(argus
[i
], "TDO")) {
1067 pbuffer_tmp
= &xxr_para_tmp
->tdo
;
1068 xxr_para_tmp
->data_mask
|= XXR_TDO
;
1069 } else if (!strcmp(argus
[i
], "MASK")) {
1071 pbuffer_tmp
= &xxr_para_tmp
->mask
;
1072 xxr_para_tmp
->data_mask
|= XXR_MASK
;
1073 } else if (!strcmp(argus
[i
], "SMASK")) {
1075 pbuffer_tmp
= &xxr_para_tmp
->smask
;
1076 xxr_para_tmp
->data_mask
|= XXR_SMASK
;
1078 LOG_ERROR("unknow parameter: %s", argus
[i
]);
1082 svf_copy_hexstring_to_binary(&argus
[i
+ 1][1], pbuffer_tmp
, i_tmp
,
1083 xxr_para_tmp
->len
)) {
1084 LOG_ERROR("fail to parse hex value");
1087 SVF_BUF_LOG(DEBUG
, *pbuffer_tmp
, xxr_para_tmp
->len
, argus
[i
]);
1089 /* If a command changes the length of the last scan of the same type and the
1090 * MASK parameter is absent, */
1091 /* the mask pattern used is all cares */
1092 if (!(xxr_para_tmp
->data_mask
& XXR_MASK
) && (i_tmp
!= xxr_para_tmp
->len
)) {
1093 /* MASK not defined and length changed */
1095 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1096 xxr_para_tmp
->len
)) {
1097 LOG_ERROR("fail to adjust length of array");
1100 buf_set_ones(xxr_para_tmp
->mask
, xxr_para_tmp
->len
);
1102 /* If TDO is absent, no comparison is needed, set the mask to 0 */
1103 if (!(xxr_para_tmp
->data_mask
& XXR_TDO
)) {
1104 if (NULL
== xxr_para_tmp
->tdo
) {
1106 svf_adjust_array_length(&xxr_para_tmp
->tdo
, i_tmp
,
1107 xxr_para_tmp
->len
)) {
1108 LOG_ERROR("fail to adjust length of array");
1112 if (NULL
== xxr_para_tmp
->mask
) {
1114 svf_adjust_array_length(&xxr_para_tmp
->mask
, i_tmp
,
1115 xxr_para_tmp
->len
)) {
1116 LOG_ERROR("fail to adjust length of array");
1120 memset(xxr_para_tmp
->mask
, 0, (xxr_para_tmp
->len
+ 7) >> 3);
1122 /* do scan if necessary */
1123 if (SDR
== command
) {
1124 /* check buffer size first, reallocate if necessary */
1125 i
= svf_para
.hdr_para
.len
+ svf_para
.sdr_para
.len
+
1126 svf_para
.tdr_para
.len
;
1127 if ((svf_buffer_size
- svf_buffer_index
) < ((i
+ 7) >> 3)) {
1128 /* reallocate buffer */
1129 if (svf_realloc_buffers(svf_buffer_index
+ ((i
+ 7) >> 3)) != ERROR_OK
) {
1130 LOG_ERROR("not enough memory");
1135 /* assemble dr data */
1137 buf_set_buf(svf_para
.hdr_para
.tdi
,
1139 &svf_tdi_buffer
[svf_buffer_index
],
1141 svf_para
.hdr_para
.len
);
1142 i
+= svf_para
.hdr_para
.len
;
1143 buf_set_buf(svf_para
.sdr_para
.tdi
,
1145 &svf_tdi_buffer
[svf_buffer_index
],
1147 svf_para
.sdr_para
.len
);
1148 i
+= svf_para
.sdr_para
.len
;
1149 buf_set_buf(svf_para
.tdr_para
.tdi
,
1151 &svf_tdi_buffer
[svf_buffer_index
],
1153 svf_para
.tdr_para
.len
);
1154 i
+= svf_para
.tdr_para
.len
;
1156 /* add check data */
1157 if (svf_para
.sdr_para
.data_mask
& XXR_TDO
) {
1158 /* assemble dr mask data */
1160 buf_set_buf(svf_para
.hdr_para
.mask
,
1162 &svf_mask_buffer
[svf_buffer_index
],
1164 svf_para
.hdr_para
.len
);
1165 i
+= svf_para
.hdr_para
.len
;
1166 buf_set_buf(svf_para
.sdr_para
.mask
,
1168 &svf_mask_buffer
[svf_buffer_index
],
1170 svf_para
.sdr_para
.len
);
1171 i
+= svf_para
.sdr_para
.len
;
1172 buf_set_buf(svf_para
.tdr_para
.mask
,
1174 &svf_mask_buffer
[svf_buffer_index
],
1176 svf_para
.tdr_para
.len
);
1178 /* assemble dr check data */
1180 buf_set_buf(svf_para
.hdr_para
.tdo
,
1182 &svf_tdo_buffer
[svf_buffer_index
],
1184 svf_para
.hdr_para
.len
);
1185 i
+= svf_para
.hdr_para
.len
;
1186 buf_set_buf(svf_para
.sdr_para
.tdo
,
1188 &svf_tdo_buffer
[svf_buffer_index
],
1190 svf_para
.sdr_para
.len
);
1191 i
+= svf_para
.sdr_para
.len
;
1192 buf_set_buf(svf_para
.tdr_para
.tdo
,
1194 &svf_tdo_buffer
[svf_buffer_index
],
1196 svf_para
.tdr_para
.len
);
1197 i
+= svf_para
.tdr_para
.len
;
1199 svf_add_check_para(1, svf_buffer_index
, i
);
1201 svf_add_check_para(0, svf_buffer_index
, i
);
1203 field
.out_value
= &svf_tdi_buffer
[svf_buffer_index
];
1204 field
.in_value
= (xxr_para_tmp
->data_mask
& XXR_TDO
) ? &svf_tdi_buffer
[svf_buffer_index
] : NULL
;
1206 /* NOTE: doesn't use SVF-specified state paths */
1207 jtag_add_plain_dr_scan(field
.num_bits
,
1210 svf_para
.dr_end_state
);
1213 svf_buffer_index
+= (i
+ 7) >> 3;
1214 } else if (SIR
== command
) {
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");
1312 /* RUNTEST [run_state] run_count run_clk [min_time SEC [MAXIMUM max_time
1313 * SEC]] [ENDSTATE end_state] */
1314 /* RUNTEST [run_state] min_time SEC [MAXIMUM max_time SEC] [ENDSTATE
1316 if ((num_of_argu
< 3) && (num_of_argu
> 11)) {
1317 LOG_ERROR("invalid parameter of %s", argus
[0]);
1326 i_tmp
= tap_state_by_name(argus
[i
]);
1327 if (i_tmp
!= TAP_INVALID
) {
1328 if (svf_tap_state_is_stable(i_tmp
)) {
1329 svf_para
.runtest_run_state
= i_tmp
;
1331 /* When a run_state is specified, the new
1332 * run_state becomes the default end_state.
1334 svf_para
.runtest_end_state
= i_tmp
;
1335 LOG_DEBUG("\trun_state = %s", tap_state_name(i_tmp
));
1338 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1343 /* run_count run_clk */
1344 if (((i
+ 2) <= num_of_argu
) && strcmp(argus
[i
+ 1], "SEC")) {
1345 if (!strcmp(argus
[i
+ 1], "TCK")) {
1346 /* clock source is TCK */
1347 run_count
= atoi(argus
[i
]);
1348 LOG_DEBUG("\trun_count@TCK = %d", run_count
);
1350 LOG_ERROR("%s not supported for clock", argus
[i
+ 1]);
1356 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
+ 1], "SEC")) {
1357 min_time
= atof(argus
[i
]);
1358 LOG_DEBUG("\tmin_time = %fs", min_time
);
1361 /* MAXIMUM max_time SEC */
1362 if (((i
+ 3) <= num_of_argu
) &&
1363 !strcmp(argus
[i
], "MAXIMUM") && !strcmp(argus
[i
+ 2], "SEC")) {
1365 max_time
= atof(argus
[i
+ 1]);
1366 LOG_DEBUG("\tmax_time = %fs", max_time
);
1369 /* ENDSTATE end_state */
1370 if (((i
+ 2) <= num_of_argu
) && !strcmp(argus
[i
], "ENDSTATE")) {
1371 i_tmp
= tap_state_by_name(argus
[i
+ 1]);
1373 if (svf_tap_state_is_stable(i_tmp
)) {
1374 svf_para
.runtest_end_state
= i_tmp
;
1375 LOG_DEBUG("\tend_state = %s", tap_state_name(i_tmp
));
1377 LOG_ERROR("%s: %s is not a stable state", argus
[0], tap_state_name(i_tmp
));
1383 /* all parameter should be parsed */
1384 if (i
== num_of_argu
) {
1386 /* FIXME handle statemove failures */
1387 uint32_t min_usec
= 1000000 * min_time
;
1389 /* enter into run_state if necessary */
1390 if (cmd_queue_cur_state
!= svf_para
.runtest_run_state
)
1391 svf_add_statemove(svf_para
.runtest_run_state
);
1393 /* add clocks and/or min wait */
1394 if (run_count
> 0) {
1396 jtag_add_clocks(run_count
);
1401 jtag_add_sleep(min_usec
);
1404 /* move to end_state if necessary */
1405 if (svf_para
.runtest_end_state
!= svf_para
.runtest_run_state
)
1406 svf_add_statemove(svf_para
.runtest_end_state
);
1409 if (svf_para
.runtest_run_state
!= TAP_IDLE
) {
1410 LOG_ERROR("cannot runtest in %s state",
1411 tap_state_name(svf_para
.runtest_run_state
));
1416 jtag_add_runtest(run_count
, svf_para
.runtest_end_state
);
1419 LOG_ERROR("fail to parse parameter of RUNTEST, %d out of %d is parsed",
1426 /* STATE [pathstate1 [pathstate2 ...[pathstaten]]] stable_state */
1427 if (num_of_argu
< 2) {
1428 LOG_ERROR("invalid parameter of %s", argus
[0]);
1431 if (num_of_argu
> 2) {
1432 /* STATE pathstate1 ... stable_state */
1433 path
= malloc((num_of_argu
- 1) * sizeof(tap_state_t
));
1435 LOG_ERROR("not enough memory");
1438 num_of_argu
--; /* num of path */
1439 i_tmp
= 1; /* path is from parameter 1 */
1440 for (i
= 0; i
< num_of_argu
; i
++, i_tmp
++) {
1441 path
[i
] = tap_state_by_name(argus
[i_tmp
]);
1442 if (path
[i
] == TAP_INVALID
) {
1443 LOG_ERROR("%s: %s is not a valid state", argus
[0], argus
[i_tmp
]);
1447 /* OpenOCD refuses paths containing TAP_RESET */
1448 if (TAP_RESET
== path
[i
]) {
1449 /* FIXME last state MUST be stable! */
1452 jtag_add_pathmove(i
, path
);
1456 num_of_argu
-= i
+ 1;
1460 if (num_of_argu
> 0) {
1461 /* execute last path if necessary */
1462 if (svf_tap_state_is_stable(path
[num_of_argu
- 1])) {
1463 /* last state MUST be stable state */
1465 jtag_add_pathmove(num_of_argu
, path
);
1466 LOG_DEBUG("\tmove to %s by path_move",
1467 tap_state_name(path
[num_of_argu
- 1]));
1469 LOG_ERROR("%s: %s is not a stable state",
1471 tap_state_name(path
[num_of_argu
- 1]));
1480 /* STATE stable_state */
1481 state
= tap_state_by_name(argus
[1]);
1482 if (svf_tap_state_is_stable(state
)) {
1483 LOG_DEBUG("\tmove to %s by svf_add_statemove",
1484 tap_state_name(state
));
1485 /* FIXME handle statemove failures */
1486 svf_add_statemove(state
);
1488 LOG_ERROR("%s: %s is not a stable state",
1489 argus
[0], tap_state_name(state
));
1495 /* TRST trst_mode */
1496 if (num_of_argu
!= 2) {
1497 LOG_ERROR("invalid parameter of %s", argus
[0]);
1500 if (svf_para
.trst_mode
!= TRST_ABSENT
) {
1501 if (ERROR_OK
!= svf_execute_tap())
1503 i_tmp
= svf_find_string_in_array(argus
[1],
1504 (char **)svf_trst_mode_name
,
1505 ARRAY_SIZE(svf_trst_mode_name
));
1509 jtag_add_reset(1, 0);
1514 jtag_add_reset(0, 0);
1519 LOG_ERROR("unknown TRST mode: %s", argus
[1]);
1522 svf_para
.trst_mode
= i_tmp
;
1523 LOG_DEBUG("\ttrst_mode = %s", svf_trst_mode_name
[svf_para
.trst_mode
]);
1525 LOG_ERROR("can not accpet TRST command if trst_mode is ABSENT");
1530 LOG_ERROR("invalid svf command: %s", argus
[0]);
1536 if (padding_command_skipped
)
1537 LOG_USER("(Above Padding command skipped, as per -tap argument)");
1540 if (debug_level
>= LOG_LVL_DEBUG
) {
1541 /* for convenient debugging, execute tap if possible */
1542 if ((svf_buffer_index
> 0) && \
1543 (((command
!= STATE
) && (command
!= RUNTEST
)) || \
1544 ((command
== STATE
) && (num_of_argu
== 2)))) {
1545 if (ERROR_OK
!= svf_execute_tap())
1548 /* output debug info */
1549 if ((SIR
== command
) || (SDR
== command
)) {
1550 SVF_BUF_LOG(DEBUG
, svf_tdi_buffer
, svf_check_tdo_para
[0].bit_len
, "TDO read");
1554 /* for fast executing, execute tap if necessary */
1555 /* half of the buffer is for the next command */
1556 if (((svf_buffer_index
>= SVF_MAX_BUFFER_SIZE_TO_COMMIT
) ||
1557 (svf_check_tdo_para_index
>= SVF_CHECK_TDO_PARA_SIZE
/ 2)) && \
1558 (((command
!= STATE
) && (command
!= RUNTEST
)) || \
1559 ((command
== STATE
) && (num_of_argu
== 2))))
1560 return svf_execute_tap();
1566 static const struct command_registration svf_command_handlers
[] = {
1569 .handler
= handle_svf_command
,
1570 .mode
= COMMAND_EXEC
,
1571 .help
= "Runs a SVF file.",
1572 .usage
= "svf [-tap device.tap] <file> [quiet] [nil] [progress] [ignore_error]",
1574 COMMAND_REGISTRATION_DONE
1577 int svf_register_commands(struct command_context
*cmd_ctx
)
1579 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)