1 /***************************************************************************
2 * Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
18 ***************************************************************************/
20 /* Versaloon is a programming tool for multiple MCUs.
21 * It's distributed under GPLv3.
22 * You can find it at http://www.Versaloon.com/.
29 #include <jtag/interface.h>
30 #include <jtag/commands.h>
31 #include "usb_common.h"
33 #include "versaloon/versaloon_include.h"
34 #include "versaloon/versaloon.h"
36 static int vsllink_tms_offset
;
38 struct pending_scan_result
{
41 int length
; /* Number of bits to read */
42 struct scan_command
*command
; /* Corresponding scan command */
45 bool last
; /* indicate the last scan pending */
48 #define MAX_PENDING_SCAN_RESULTS 256
50 static int pending_scan_results_length
;
51 static struct pending_scan_result
52 pending_scan_results_buffer
[MAX_PENDING_SCAN_RESULTS
];
54 /* Queue command functions */
55 static void vsllink_end_state(tap_state_t state
);
56 static void vsllink_state_move(void);
57 static void vsllink_path_move(int num_states
, tap_state_t
*path
);
58 static void vsllink_tms(int num_bits
, const uint8_t *bits
);
59 static void vsllink_runtest(int num_cycles
);
60 static void vsllink_stableclocks(int num_cycles
, int tms
);
61 static void vsllink_scan(bool ir_scan
, enum scan_type type
,
62 uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
63 static void vsllink_reset(int trst
, int srst
);
65 /* VSLLink tap buffer functions */
66 static void vsllink_tap_append_step(int tms
, int tdi
);
67 static void vsllink_tap_init(void);
68 static int vsllink_tap_execute(void);
69 static void vsllink_tap_ensure_pending(int scans
);
70 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
71 struct scan_command
*command
);
73 /* VSLLink lowlevel functions */
75 struct usb_dev_handle
*usb_handle
;
78 static struct vsllink
*vsllink_usb_open(void);
79 static void vsllink_usb_close(struct vsllink
*vsllink
);
81 #if defined _DEBUG_JTAG_IO_
82 static void vsllink_debug_buffer(uint8_t *buffer
, int length
);
85 static int tap_length
;
86 static int tap_buffer_size
;
87 static uint8_t *tms_buffer
;
88 static uint8_t *tdi_buffer
;
89 static uint8_t *tdo_buffer
;
91 struct vsllink
*vsllink_handle
;
93 static int vsllink_execute_queue(void)
95 struct jtag_command
*cmd
= jtag_command_queue
;
100 DEBUG_JTAG_IO("-------------------------------------"
102 "-------------------------------------");
104 while (cmd
!= NULL
) {
107 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
108 cmd
->cmd
.runtest
->num_cycles
,
109 tap_state_name(cmd
->cmd
.runtest
->end_state
));
111 vsllink_end_state(cmd
->cmd
.runtest
->end_state
);
112 vsllink_runtest(cmd
->cmd
.runtest
->num_cycles
);
116 DEBUG_JTAG_IO("statemove end in %s",
117 tap_state_name(cmd
->cmd
.statemove
->end_state
));
119 vsllink_end_state(cmd
->cmd
.statemove
->end_state
);
120 vsllink_state_move();
124 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
125 cmd
->cmd
.pathmove
->num_states
,
126 tap_state_name(cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]));
128 vsllink_path_move(cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
);
132 DEBUG_JTAG_IO("JTAG Scan...");
134 vsllink_end_state(cmd
->cmd
.scan
->end_state
);
136 scan_size
= jtag_build_buffer(
137 cmd
->cmd
.scan
, &buffer
);
139 if (cmd
->cmd
.scan
->ir_scan
)
141 "JTAG Scan write IR(%d bits), "
144 tap_state_name(cmd
->cmd
.scan
->end_state
));
148 "JTAG Scan write DR(%d bits), "
151 tap_state_name(cmd
->cmd
.scan
->end_state
));
153 #ifdef _DEBUG_JTAG_IO_
154 vsllink_debug_buffer(buffer
,
155 DIV_ROUND_UP(scan_size
, 8));
158 type
= jtag_scan_type(cmd
->cmd
.scan
);
160 vsllink_scan(cmd
->cmd
.scan
->ir_scan
,
161 type
, buffer
, scan_size
,
166 DEBUG_JTAG_IO("reset trst: %i srst %i",
167 cmd
->cmd
.reset
->trst
,
168 cmd
->cmd
.reset
->srst
);
170 vsllink_tap_execute();
172 if (cmd
->cmd
.reset
->trst
== 1)
173 tap_set_state(TAP_RESET
);
175 vsllink_reset(cmd
->cmd
.reset
->trst
,
176 cmd
->cmd
.reset
->srst
);
180 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
181 vsllink_tap_execute();
182 jtag_sleep(cmd
->cmd
.sleep
->us
);
185 case JTAG_STABLECLOCKS
:
186 DEBUG_JTAG_IO("add %d clocks",
187 cmd
->cmd
.stableclocks
->num_cycles
);
189 switch (tap_get_state()) {
191 /* tms must be '1' to stay
201 /* else, tms should be '0' */
204 /* above stable states are OK */
206 LOG_ERROR("jtag_add_clocks() "
207 "in non-stable state \"%s\"",
208 tap_state_name(tap_get_state())
212 vsllink_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
, scan_size
);
216 DEBUG_JTAG_IO("add %d jtag tms",
217 cmd
->cmd
.tms
->num_bits
);
219 vsllink_tms(cmd
->cmd
.tms
->num_bits
, cmd
->cmd
.tms
->bits
);
223 LOG_ERROR("BUG: unknown JTAG command type "
224 "encountered: %d", cmd
->type
);
230 return vsllink_tap_execute();
233 static int vsllink_speed(int speed
)
235 versaloon_interface
.adaptors
.jtag_raw
.config(0, (uint16_t)speed
);
236 return versaloon_interface
.adaptors
.peripheral_commit();
239 static int vsllink_khz(int khz
, int *jtag_speed
)
246 static int vsllink_speed_div(int jtag_speed
, int *khz
)
253 static void vsllink_free_buffer(void)
255 if (tdi_buffer
!= NULL
) {
259 if (tdo_buffer
!= NULL
) {
263 if (tms_buffer
!= NULL
) {
269 static int vsllink_quit(void)
271 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
272 0, 0, GPIO_SRST
| GPIO_TRST
);
273 versaloon_interface
.adaptors
.gpio
.fini(0);
274 versaloon_interface
.adaptors
.jtag_raw
.fini(0);
275 versaloon_interface
.adaptors
.peripheral_commit();
276 versaloon_interface
.fini();
278 vsllink_free_buffer();
279 vsllink_usb_close(vsllink_handle
);
284 static int vsllink_init(void)
286 vsllink_handle
= vsllink_usb_open();
287 if (vsllink_handle
== 0) {
288 LOG_ERROR("Can't find USB JTAG Interface!" \
289 "Please check connection and permissions.");
290 return ERROR_JTAG_INIT_FAILED
;
292 LOG_DEBUG("vsllink found on %04X:%04X",
293 versaloon_interface
.usb_setting
.vid
,
294 versaloon_interface
.usb_setting
.pid
);
295 versaloon_usb_device_handle
= vsllink_handle
->usb_handle
;
297 if (ERROR_OK
!= versaloon_interface
.init())
299 if (versaloon_interface
.usb_setting
.buf_size
< 32) {
300 versaloon_interface
.fini();
304 /* malloc buffer size for tap */
305 tap_buffer_size
= versaloon_interface
.usb_setting
.buf_size
/ 2 - 32;
306 vsllink_free_buffer();
307 tdi_buffer
= malloc(tap_buffer_size
);
308 tdo_buffer
= malloc(tap_buffer_size
);
309 tms_buffer
= malloc(tap_buffer_size
);
310 if ((NULL
== tdi_buffer
) || (NULL
== tdo_buffer
) || (NULL
== tms_buffer
)) {
315 versaloon_interface
.adaptors
.jtag_raw
.init(0);
316 versaloon_interface
.adaptors
.jtag_raw
.config(0, jtag_get_speed_khz());
317 versaloon_interface
.adaptors
.gpio
.init(0);
318 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
319 GPIO_TRST
, GPIO_SRST
, GPIO_SRST
);
320 if (ERROR_OK
!= versaloon_interface
.adaptors
.peripheral_commit())
328 /**************************************************************************
329 * Queue command implementations */
331 static void vsllink_end_state(tap_state_t state
)
333 if (tap_is_state_stable(state
))
334 tap_set_end_state(state
);
336 LOG_ERROR("BUG: %i is not a valid end state", state
);
341 /* Goes to the end state. */
342 static void vsllink_state_move(void)
345 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
346 tap_get_end_state());
347 uint8_t tms_scan_bits
= tap_get_tms_path_len(tap_get_state(),
348 tap_get_end_state());
350 for (i
= 0; i
< tms_scan_bits
; i
++)
351 vsllink_tap_append_step((tms_scan
>> i
) & 1, 0);
353 tap_set_state(tap_get_end_state());
356 static void vsllink_path_move(int num_states
, tap_state_t
*path
)
358 for (int i
= 0; i
< num_states
; i
++) {
359 if (path
[i
] == tap_state_transition(tap_get_state(), false))
360 vsllink_tap_append_step(0, 0);
361 else if (path
[i
] == tap_state_transition(tap_get_state(), true))
362 vsllink_tap_append_step(1, 0);
364 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
365 tap_state_name(tap_get_state()),
366 tap_state_name(path
[i
]));
370 tap_set_state(path
[i
]);
373 tap_set_end_state(tap_get_state());
376 static void vsllink_tms(int num_bits
, const uint8_t *bits
)
378 for (int i
= 0; i
< num_bits
; i
++)
379 vsllink_tap_append_step((bits
[i
/ 8] >> (i
% 8)) & 1, 0);
382 static void vsllink_stableclocks(int num_cycles
, int tms
)
384 while (num_cycles
> 0) {
385 vsllink_tap_append_step(tms
, 0);
390 static void vsllink_runtest(int num_cycles
)
392 tap_state_t saved_end_state
= tap_get_end_state();
394 if (tap_get_state() != TAP_IDLE
) {
395 /* enter IDLE state */
396 vsllink_end_state(TAP_IDLE
);
397 vsllink_state_move();
400 vsllink_stableclocks(num_cycles
, 0);
404 vsllink_end_state(saved_end_state
);
405 if (tap_get_end_state() != tap_get_end_state())
406 vsllink_state_move();
409 static void vsllink_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
,
410 int scan_size
, struct scan_command
*command
)
412 tap_state_t saved_end_state
;
414 saved_end_state
= tap_get_end_state();
416 /* Move to appropriate scan state */
417 vsllink_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
419 if (tap_get_state() != tap_get_end_state())
420 vsllink_state_move();
421 vsllink_end_state(saved_end_state
);
424 vsllink_tap_append_scan(scan_size
, buffer
, command
);
426 /* Goto Pause and record position to insert tms:0 */
427 vsllink_tap_append_step(0, 0);
428 vsllink_tms_offset
= tap_length
;
430 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
432 if (tap_get_state() != tap_get_end_state())
433 vsllink_state_move();
436 static void vsllink_reset(int trst
, int srst
)
438 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
441 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
, GPIO_SRST
);
443 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, GPIO_SRST
, 0, 0);
446 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, GPIO_TRST
);
448 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, 0);
449 versaloon_interface
.adaptors
.peripheral_commit();
452 COMMAND_HANDLER(vsllink_handle_usb_vid_command
)
455 return ERROR_COMMAND_SYNTAX_ERROR
;
457 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
458 versaloon_interface
.usb_setting
.vid
);
462 COMMAND_HANDLER(vsllink_handle_usb_pid_command
)
465 return ERROR_COMMAND_SYNTAX_ERROR
;
466 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
467 versaloon_interface
.usb_setting
.pid
);
471 COMMAND_HANDLER(vsllink_handle_usb_serial_command
)
474 return ERROR_COMMAND_SYNTAX_ERROR
;
476 free(versaloon_interface
.usb_setting
.serialstring
);
479 versaloon_interface
.usb_setting
.serialstring
= strdup(CMD_ARGV
[0]);
481 versaloon_interface
.usb_setting
.serialstring
= NULL
;
486 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command
)
489 return ERROR_COMMAND_SYNTAX_ERROR
;
491 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
492 versaloon_interface
.usb_setting
.ep_in
);
494 versaloon_interface
.usb_setting
.ep_in
|= 0x80;
499 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command
)
502 return ERROR_COMMAND_SYNTAX_ERROR
;
504 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
505 versaloon_interface
.usb_setting
.ep_out
);
507 versaloon_interface
.usb_setting
.ep_out
&= ~0x80;
512 COMMAND_HANDLER(vsllink_handle_usb_interface_command
)
515 return ERROR_COMMAND_SYNTAX_ERROR
;
517 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
518 versaloon_interface
.usb_setting
.interface
);
522 /**************************************************************************
523 * VSLLink tap functions */
525 static void vsllink_tap_init(void)
528 pending_scan_results_length
= 0;
529 vsllink_tms_offset
= 0;
532 static void vsllink_tap_ensure_pending(int scans
)
534 int available_scans
=
535 MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
537 if (scans
> available_scans
)
538 vsllink_tap_execute();
541 static void vsllink_tap_append_step(int tms
, int tdi
)
543 int index_var
= tap_length
/ 8;
545 int bit_index
= tap_length
% 8;
546 uint8_t bit
= 1 << bit_index
;
549 tms_buffer
[index_var
] |= bit
;
551 tms_buffer
[index_var
] &= ~bit
;
554 tdi_buffer
[index_var
] |= bit
;
556 tdi_buffer
[index_var
] &= ~bit
;
560 if (tap_buffer_size
* 8 <= tap_length
)
561 vsllink_tap_execute();
564 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
565 struct scan_command
*command
)
567 struct pending_scan_result
*pending_scan_result
;
568 int len_tmp
, len_all
, i
;
571 while (len_all
< length
) {
572 vsllink_tap_ensure_pending(1);
573 pending_scan_result
=
574 &pending_scan_results_buffer
[
575 pending_scan_results_length
];
577 if ((length
- len_all
) > (tap_buffer_size
* 8 - tap_length
)) {
578 /* Use all memory available
579 vsllink_tap_append_step will commit automatically */
580 len_tmp
= tap_buffer_size
* 8 - tap_length
;
581 pending_scan_result
->last
= false;
583 len_tmp
= length
- len_all
;
584 pending_scan_result
->last
= true;
586 pending_scan_result
->src_offset
= tap_length
;
587 pending_scan_result
->dest_offset
= len_all
;
588 pending_scan_result
->length
= len_tmp
;
589 pending_scan_result
->command
= command
;
590 pending_scan_result
->buffer
= buffer
;
591 pending_scan_results_length
++;
593 for (i
= 0; i
< len_tmp
; i
++) {
594 vsllink_tap_append_step(((len_all
+ i
) < length
-1
596 (buffer
[(len_all
+ i
)/8]
597 >> ((len_all
+ i
)%8)) & 1);
604 static int vsllink_jtag_execute(void)
612 versaloon_interface
.adaptors
.jtag_raw
.execute(0, tdi_buffer
, tms_buffer
,
613 tdo_buffer
, tap_length
);
615 result
= versaloon_interface
.adaptors
.peripheral_commit();
617 if (result
== ERROR_OK
) {
618 for (i
= 0; i
< pending_scan_results_length
; i
++) {
619 struct pending_scan_result
*pending_scan_result
=
620 &pending_scan_results_buffer
[i
];
621 uint8_t *buffer
= pending_scan_result
->buffer
;
622 int length
= pending_scan_result
->length
;
623 int src_first
= pending_scan_result
->src_offset
;
624 int dest_first
= pending_scan_result
->dest_offset
;
625 bool last
= pending_scan_result
->last
;
627 struct scan_command
*command
;
629 command
= pending_scan_result
->command
;
630 buf_set_buf(tdo_buffer
, src_first
, buffer
, dest_first
, length
);
632 #ifdef _DEBUG_JTAG_IO_
634 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
635 length
, src_first
, dest_first
);
636 vsllink_debug_buffer(buffer
+ dest_first
/ 8,
637 DIV_ROUND_UP(length
, 7));
641 if (jtag_read_buffer(buffer
, command
)
644 return ERROR_JTAG_QUEUE_FAILED
;
647 if (pending_scan_result
->buffer
!= NULL
)
648 free(pending_scan_result
->buffer
);
652 LOG_ERROR("vsllink_jtag_execute failure");
653 return ERROR_JTAG_QUEUE_FAILED
;
661 static int vsllink_tap_execute(void)
663 return vsllink_jtag_execute();
666 /****************************************************************************
667 * VSLLink USB low-level functions */
669 static uint8_t usb_check_string(usb_dev_handle
*usb
, uint8_t stringidx
,
670 char *string
, char *buff
, uint16_t buf_size
)
678 buff
= malloc(buf_size
);
681 goto free_and_return
;
687 len
= usb_get_string_simple(usb
, stringidx
, buff
, buf_size
);
688 if ((len
< 0) || ((size_t)len
!= strlen(buff
))) {
690 goto free_and_return
;
694 if ((string
!= NULL
) && strcmp(buff
, string
)) {
696 goto free_and_return
;
700 if (alloced
&& (buff
!= NULL
)) {
707 static usb_dev_handle
*find_usb_device(uint16_t VID
, uint16_t PID
, uint8_t interface
,
708 char *serialstring
, char *productstring
)
710 usb_dev_handle
*dev_handle
= NULL
;
711 struct usb_bus
*busses
;
713 struct usb_device
*dev
;
718 busses
= usb_get_busses();
720 for (bus
= busses
; bus
; bus
= bus
->next
) {
721 for (dev
= bus
->devices
; dev
; dev
= dev
->next
) {
722 if ((dev
->descriptor
.idVendor
== VID
)
723 && (dev
->descriptor
.idProduct
== PID
)) {
724 dev_handle
= usb_open(dev
);
725 if (NULL
== dev_handle
) {
726 LOG_ERROR("failed to open %04X:%04X, %s", VID
, PID
,
731 /* check description string */
732 if ((productstring
!= NULL
&& !usb_check_string(dev_handle
,
733 dev
->descriptor
.iProduct
, productstring
, NULL
, 0))
734 || (serialstring
!= NULL
&& !usb_check_string(dev_handle
,
735 dev
->descriptor
.iSerialNumber
, serialstring
, NULL
, 0))) {
736 usb_close(dev_handle
);
741 if (usb_claim_interface(dev_handle
, interface
) != 0) {
742 LOG_ERROR(ERRMSG_FAILURE_OPERATION_MESSAGE
,
743 "claim interface", usb_strerror());
744 usb_close(dev_handle
);
749 if (dev_handle
!= NULL
)
758 static struct vsllink
*vsllink_usb_open(void)
762 struct usb_dev_handle
*dev
;
764 dev
= find_usb_device(versaloon_interface
.usb_setting
.vid
,
765 versaloon_interface
.usb_setting
.pid
,
766 versaloon_interface
.usb_setting
.interface
,
767 versaloon_interface
.usb_setting
.serialstring
, "Versaloon");
771 struct vsllink
*result
= malloc(sizeof(struct vsllink
));
772 result
->usb_handle
= dev
;
776 static void vsllink_usb_close(struct vsllink
*vsllink
)
780 ret
= usb_release_interface(vsllink
->usb_handle
,
781 versaloon_interface
.usb_setting
.interface
);
783 LOG_ERROR("fail to release interface %d, %d returned",
784 versaloon_interface
.usb_setting
.interface
, ret
);
788 ret
= usb_close(vsllink
->usb_handle
);
790 LOG_ERROR("fail to close usb, %d returned", ret
);
797 #define BYTES_PER_LINE 16
799 #if defined _DEBUG_JTAG_IO_
800 static void vsllink_debug_buffer(uint8_t *buffer
, int length
)
807 for (i
= 0; i
< length
; i
+= BYTES_PER_LINE
) {
808 snprintf(line
, 5, "%04x", i
);
809 for (j
= i
; j
< i
+ BYTES_PER_LINE
&& j
< length
; j
++) {
810 snprintf(s
, 4, " %02x", buffer
[j
]);
813 LOG_DEBUG("%s", line
);
816 #endif /* _DEBUG_JTAG_IO_ */
818 static const struct command_registration vsllink_command_handlers
[] = {
820 .name
= "vsllink_usb_vid",
821 .handler
= &vsllink_handle_usb_vid_command
,
822 .mode
= COMMAND_CONFIG
,
825 .name
= "vsllink_usb_pid",
826 .handler
= &vsllink_handle_usb_pid_command
,
827 .mode
= COMMAND_CONFIG
,
830 .name
= "vsllink_usb_serial",
831 .handler
= &vsllink_handle_usb_serial_command
,
832 .mode
= COMMAND_CONFIG
,
835 .name
= "vsllink_usb_bulkin",
836 .handler
= &vsllink_handle_usb_bulkin_command
,
837 .mode
= COMMAND_CONFIG
,
840 .name
= "vsllink_usb_bulkout",
841 .handler
= &vsllink_handle_usb_bulkout_command
,
842 .mode
= COMMAND_CONFIG
,
845 .name
= "vsllink_usb_interface",
846 .handler
= &vsllink_handle_usb_interface_command
,
847 .mode
= COMMAND_CONFIG
,
849 COMMAND_REGISTRATION_DONE
852 static const char *vsllink_transports
[] = {"jtag", "swd", NULL
};
854 struct jtag_interface vsllink_interface
= {
856 .supported
= DEBUG_CAP_TMS_SEQ
,
857 .commands
= vsllink_command_handlers
,
858 .transports
= vsllink_transports
,
860 .init
= vsllink_init
,
861 .quit
= vsllink_quit
,
863 .speed
= vsllink_speed
,
864 .speed_div
= vsllink_speed_div
,
865 .execute_queue
= vsllink_execute_queue
,
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)