Jonas Horberg <jhorberg@sauer-danfoss.com>
[openocd.git] / src / jtag / core.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2009 SoftPLC Corporation *
9 * http://softplc.com *
10 * dick@softplc.com *
11 * *
12 * Copyright (C) 2009 Zachary T Welch *
13 * zw@superlucidity.net *
14 * *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
19 * *
20 * This program is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23 * GNU General Public License for more details. *
24 * *
25 * You should have received a copy of the GNU General Public License *
26 * along with this program; if not, write to the *
27 * Free Software Foundation, Inc., *
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 ***************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "jtag.h"
35 #include "minidriver.h"
36 #include "interface.h"
37
38 #ifdef HAVE_STRINGS_H
39 #include <strings.h>
40 #endif
41
42
43 /// The number of JTAG queue flushes (for profiling and debugging purposes).
44 static int jtag_flush_queue_count;
45
46 static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state),
47 int in_num_fields, scan_field_t *in_fields, tap_state_t state);
48
49 /**
50 * The jtag_error variable is set when an error occurs while executing
51 * the queue. Application code may set this using jtag_set_error(),
52 * when an error occurs during processing that should be reported during
53 * jtag_execute_queue().
54 *
55 * Tts value may be checked with jtag_get_error() and cleared with
56 * jtag_error_clear(). This value is returned (and cleared) by
57 * jtag_execute_queue().
58 */
59 static int jtag_error = ERROR_OK;
60
61 static const char *jtag_event_strings[] =
62 {
63 [JTAG_TRST_ASSERTED] = "JTAG controller reset (RESET or TRST)",
64 [JTAG_TAP_EVENT_ENABLE] = "TAP enabled",
65 [JTAG_TAP_EVENT_DISABLE] = "TAP disabled",
66 };
67
68 static int jtag_trst = 0;
69 static int jtag_srst = 0;
70
71 /**
72 * List all TAPs that have been created.
73 */
74 static jtag_tap_t *__jtag_all_taps = NULL;
75 /**
76 * The number of TAPs in the __jtag_all_taps list, used to track the
77 * assigned chain position to new TAPs
78 */
79 static unsigned jtag_num_taps = 0;
80
81 static enum reset_types jtag_reset_config = RESET_NONE;
82 static tap_state_t cmd_queue_end_state = TAP_RESET;
83 tap_state_t cmd_queue_cur_state = TAP_RESET;
84
85 static bool jtag_verify_capture_ir = true;
86 static int jtag_verify = 1;
87
88 /* how long the OpenOCD should wait before attempting JTAG communication after reset lines deasserted (in ms) */
89 static int jtag_nsrst_delay = 0; /* default to no nSRST delay */
90 static int jtag_ntrst_delay = 0; /* default to no nTRST delay */
91
92 typedef struct jtag_event_callback_s
93 {
94 jtag_event_handler_t callback;
95 void* priv;
96 struct jtag_event_callback_s* next;
97 } jtag_event_callback_t;
98
99 /* callbacks to inform high-level handlers about JTAG state changes */
100 static jtag_event_callback_t *jtag_event_callbacks;
101
102 /* speed in kHz*/
103 static int speed_khz = 0;
104 /* speed to fallback to when RCLK is requested but not supported */
105 static int rclk_fallback_speed_khz = 0;
106 static enum {CLOCK_MODE_SPEED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode;
107 static int jtag_speed = 0;
108
109 static struct jtag_interface_s *jtag = NULL;
110
111 /* configuration */
112 jtag_interface_t *jtag_interface = NULL;
113
114 void jtag_set_error(int error)
115 {
116 if ((error == ERROR_OK) || (jtag_error != ERROR_OK))
117 return;
118 jtag_error = error;
119 }
120 int jtag_get_error(void)
121 {
122 return jtag_error;
123 }
124 int jtag_error_clear(void)
125 {
126 int temp = jtag_error;
127 jtag_error = ERROR_OK;
128 return temp;
129 }
130
131
132 jtag_tap_t *jtag_all_taps(void)
133 {
134 return __jtag_all_taps;
135 };
136
137 unsigned jtag_tap_count(void)
138 {
139 return jtag_num_taps;
140 }
141
142 unsigned jtag_tap_count_enabled(void)
143 {
144 jtag_tap_t *t = jtag_all_taps();
145 unsigned n = 0;
146 while (t)
147 {
148 if (t->enabled)
149 n++;
150 t = t->next_tap;
151 }
152 return n;
153 }
154
155 /// Append a new TAP to the chain of all taps.
156 void jtag_tap_add(struct jtag_tap_s *t)
157 {
158 t->abs_chain_position = jtag_num_taps++;
159
160 jtag_tap_t **tap = &__jtag_all_taps;
161 while (*tap != NULL)
162 tap = &(*tap)->next_tap;
163 *tap = t;
164 }
165
166 /* returns a pointer to the n-th device in the scan chain */
167 static inline jtag_tap_t *jtag_tap_by_position(unsigned n)
168 {
169 jtag_tap_t *t = jtag_all_taps();
170
171 while (t && n-- > 0)
172 t = t->next_tap;
173
174 return t;
175 }
176
177 jtag_tap_t *jtag_tap_by_string(const char *s)
178 {
179 /* try by name first */
180 jtag_tap_t *t = jtag_all_taps();
181
182 while (t)
183 {
184 if (0 == strcmp(t->dotted_name, s))
185 return t;
186 t = t->next_tap;
187 }
188
189 /* no tap found by name, so try to parse the name as a number */
190 unsigned n;
191 if (parse_uint(s, &n) != ERROR_OK)
192 return NULL;
193
194 /* FIXME remove this numeric fallback code late June 2010, along
195 * with all info in the User's Guide that TAPs have numeric IDs.
196 * Also update "scan_chain" output to not display the numbers.
197 */
198 t = jtag_tap_by_position(n);
199 if (t)
200 LOG_WARNING("Specify TAP '%s' by name, not number %u",
201 t->dotted_name, n);
202
203 return t;
204 }
205
206 jtag_tap_t *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
207 {
208 const char *cp = Jim_GetString(o, NULL);
209 jtag_tap_t *t = cp ? jtag_tap_by_string(cp) : NULL;
210 if (NULL == cp)
211 cp = "(unknown)";
212 if (NULL == t)
213 Jim_SetResult_sprintf(interp, "Tap '%s' could not be found", cp);
214 return t;
215 }
216
217 jtag_tap_t* jtag_tap_next_enabled(jtag_tap_t* p)
218 {
219 p = p ? p->next_tap : jtag_all_taps();
220 while (p)
221 {
222 if (p->enabled)
223 return p;
224 p = p->next_tap;
225 }
226 return NULL;
227 }
228
229 const char *jtag_tap_name(const jtag_tap_t *tap)
230 {
231 return (tap == NULL) ? "(unknown)" : tap->dotted_name;
232 }
233
234
235 int jtag_register_event_callback(jtag_event_handler_t callback, void *priv)
236 {
237 jtag_event_callback_t **callbacks_p = &jtag_event_callbacks;
238
239 if (callback == NULL)
240 {
241 return ERROR_INVALID_ARGUMENTS;
242 }
243
244 if (*callbacks_p)
245 {
246 while ((*callbacks_p)->next)
247 callbacks_p = &((*callbacks_p)->next);
248 callbacks_p = &((*callbacks_p)->next);
249 }
250
251 (*callbacks_p) = malloc(sizeof(jtag_event_callback_t));
252 (*callbacks_p)->callback = callback;
253 (*callbacks_p)->priv = priv;
254 (*callbacks_p)->next = NULL;
255
256 return ERROR_OK;
257 }
258
259 int jtag_unregister_event_callback(jtag_event_handler_t callback, void *priv)
260 {
261 jtag_event_callback_t **callbacks_p;
262 jtag_event_callback_t **next;
263
264 if (callback == NULL)
265 {
266 return ERROR_INVALID_ARGUMENTS;
267 }
268
269 for (callbacks_p = &jtag_event_callbacks;
270 *callbacks_p != NULL;
271 callbacks_p = next)
272 {
273 next = &((*callbacks_p)->next);
274
275 if ((*callbacks_p)->priv != priv)
276 continue;
277
278 if ((*callbacks_p)->callback == callback)
279 {
280 free(*callbacks_p);
281 *callbacks_p = *next;
282 }
283 }
284
285 return ERROR_OK;
286 }
287
288 int jtag_call_event_callbacks(enum jtag_event event)
289 {
290 jtag_event_callback_t *callback = jtag_event_callbacks;
291
292 LOG_DEBUG("jtag event: %s", jtag_event_strings[event]);
293
294 while (callback)
295 {
296 jtag_event_callback_t *next;
297
298 /* callback may remove itself */
299 next = callback->next;
300 callback->callback(event, callback->priv);
301 callback = next;
302 }
303
304 return ERROR_OK;
305 }
306
307 static void jtag_checks(void)
308 {
309 assert(jtag_trst == 0);
310 }
311
312 static void jtag_prelude(tap_state_t state)
313 {
314 jtag_checks();
315
316 assert(state != TAP_INVALID);
317
318 cmd_queue_cur_state = state;
319 }
320
321 void jtag_alloc_in_value32(scan_field_t *field)
322 {
323 interface_jtag_alloc_in_value32(field);
324 }
325
326 void jtag_add_ir_scan_noverify(int in_count, const scan_field_t *in_fields,
327 tap_state_t state)
328 {
329 jtag_prelude(state);
330
331 int retval = interface_jtag_add_ir_scan(in_count, in_fields, state);
332 jtag_set_error(retval);
333 }
334
335
336 void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
337 {
338 if (jtag_verify && jtag_verify_capture_ir)
339 {
340 /* 8 x 32 bit id's is enough for all invocations */
341
342 for (int j = 0; j < in_num_fields; j++)
343 {
344 /* if we are to run a verification of the ir scan, we need to get the input back.
345 * We may have to allocate space if the caller didn't ask for the input back.
346 */
347 in_fields[j].check_value = in_fields[j].tap->expected;
348 in_fields[j].check_mask = in_fields[j].tap->expected_mask;
349 }
350 jtag_add_scan_check(jtag_add_ir_scan_noverify, in_num_fields, in_fields, state);
351 } else
352 {
353 jtag_add_ir_scan_noverify(in_num_fields, in_fields, state);
354 }
355 }
356
357 void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields,
358 tap_state_t state)
359 {
360 jtag_prelude(state);
361
362 int retval = interface_jtag_add_plain_ir_scan(
363 in_num_fields, in_fields, state);
364 jtag_set_error(retval);
365 }
366
367 void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)
368 {
369 interface_jtag_add_callback(f, data0);
370 }
371
372 void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
373 jtag_callback_data_t data1, jtag_callback_data_t data2,
374 jtag_callback_data_t data3)
375 {
376 interface_jtag_add_callback4(f, data0, data1, data2, data3);
377 }
378
379 int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, uint8_t *in_check_mask, int num_bits);
380
381 static int jtag_check_value_mask_callback(jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
382 {
383 return jtag_check_value_inner((uint8_t *)data0, (uint8_t *)data1, (uint8_t *)data2, (int)data3);
384 }
385
386 static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state),
387 int in_num_fields, scan_field_t *in_fields, tap_state_t state)
388 {
389 for (int i = 0; i < in_num_fields; i++)
390 {
391 struct scan_field_s *field = &in_fields[i];
392 field->allocated = 0;
393 field->modified = 0;
394 if (field->check_value || field->in_value)
395 continue;
396 interface_jtag_add_scan_check_alloc(field);
397 field->modified = 1;
398 }
399
400 jtag_add_scan(in_num_fields, in_fields, state);
401
402 for (int i = 0; i < in_num_fields; i++)
403 {
404 if ((in_fields[i].check_value != NULL) && (in_fields[i].in_value != NULL))
405 {
406 /* this is synchronous for a minidriver */
407 jtag_add_callback4(jtag_check_value_mask_callback, (jtag_callback_data_t)in_fields[i].in_value,
408 (jtag_callback_data_t)in_fields[i].check_value,
409 (jtag_callback_data_t)in_fields[i].check_mask,
410 (jtag_callback_data_t)in_fields[i].num_bits);
411 }
412 if (in_fields[i].allocated)
413 {
414 free(in_fields[i].in_value);
415 }
416 if (in_fields[i].modified)
417 {
418 in_fields[i].in_value = NULL;
419 }
420 }
421 }
422
423 void jtag_add_dr_scan_check(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
424 {
425 if (jtag_verify)
426 {
427 jtag_add_scan_check(jtag_add_dr_scan, in_num_fields, in_fields, state);
428 } else
429 {
430 jtag_add_dr_scan(in_num_fields, in_fields, state);
431 }
432 }
433
434
435 void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields,
436 tap_state_t state)
437 {
438 jtag_prelude(state);
439
440 int retval;
441 retval = interface_jtag_add_dr_scan(in_num_fields, in_fields, state);
442 jtag_set_error(retval);
443 }
444
445 void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields,
446 tap_state_t state)
447 {
448 jtag_prelude(state);
449
450 int retval;
451 retval = interface_jtag_add_plain_dr_scan(in_num_fields, in_fields, state);
452 jtag_set_error(retval);
453 }
454
455 void jtag_add_dr_out(jtag_tap_t* tap,
456 int num_fields, const int* num_bits, const uint32_t* value,
457 tap_state_t end_state)
458 {
459 assert(end_state != TAP_INVALID);
460
461 cmd_queue_cur_state = end_state;
462
463 interface_jtag_add_dr_out(tap,
464 num_fields, num_bits, value,
465 end_state);
466 }
467
468 void jtag_add_tlr(void)
469 {
470 jtag_prelude(TAP_RESET);
471 jtag_set_error(interface_jtag_add_tlr());
472 jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
473 }
474
475 void jtag_add_pathmove(int num_states, const tap_state_t *path)
476 {
477 tap_state_t cur_state = cmd_queue_cur_state;
478
479 /* the last state has to be a stable state */
480 if (!tap_is_state_stable(path[num_states - 1]))
481 {
482 LOG_ERROR("BUG: TAP path doesn't finish in a stable state");
483 jtag_set_error(ERROR_JTAG_NOT_STABLE_STATE);
484 return;
485 }
486
487 for (int i = 0; i < num_states; i++)
488 {
489 if (path[i] == TAP_RESET)
490 {
491 LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences");
492 jtag_set_error(ERROR_JTAG_STATE_INVALID);
493 return;
494 }
495
496 if (tap_state_transition(cur_state, true) != path[i]
497 && tap_state_transition(cur_state, false) != path[i])
498 {
499 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
500 tap_state_name(cur_state), tap_state_name(path[i]));
501 jtag_set_error(ERROR_JTAG_TRANSITION_INVALID);
502 return;
503 }
504 cur_state = path[i];
505 }
506
507 jtag_checks();
508
509 jtag_set_error(interface_jtag_add_pathmove(num_states, path));
510 cmd_queue_cur_state = path[num_states - 1];
511 }
512
513 int jtag_add_statemove(tap_state_t goal_state)
514 {
515 tap_state_t cur_state = cmd_queue_cur_state;
516
517 LOG_DEBUG("cur_state=%s goal_state=%s",
518 tap_state_name(cur_state),
519 tap_state_name(goal_state));
520
521
522 if (goal_state == cur_state)
523 ; /* nothing to do */
524 else if (goal_state == TAP_RESET)
525 {
526 jtag_add_tlr();
527 }
528 else if (tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state))
529 {
530 unsigned tms_bits = tap_get_tms_path(cur_state, goal_state);
531 unsigned tms_count = tap_get_tms_path_len(cur_state, goal_state);
532 tap_state_t moves[8];
533 assert(tms_count < DIM(moves));
534
535 for (unsigned i = 0; i < tms_count; i++, tms_bits >>= 1)
536 {
537 bool bit = tms_bits & 1;
538
539 cur_state = tap_state_transition(cur_state, bit);
540 moves[i] = cur_state;
541 }
542
543 jtag_add_pathmove(tms_count, moves);
544 }
545 else if (tap_state_transition(cur_state, true) == goal_state
546 || tap_state_transition(cur_state, false) == goal_state)
547 {
548 jtag_add_pathmove(1, &goal_state);
549 }
550
551 else
552 return ERROR_FAIL;
553
554 return ERROR_OK;
555 }
556
557 void jtag_add_runtest(int num_cycles, tap_state_t state)
558 {
559 jtag_prelude(state);
560 jtag_set_error(interface_jtag_add_runtest(num_cycles, state));
561 }
562
563
564 void jtag_add_clocks(int num_cycles)
565 {
566 if (!tap_is_state_stable(cmd_queue_cur_state))
567 {
568 LOG_ERROR("jtag_add_clocks() called with TAP in unstable state \"%s\"",
569 tap_state_name(cmd_queue_cur_state));
570 jtag_set_error(ERROR_JTAG_NOT_STABLE_STATE);
571 return;
572 }
573
574 if (num_cycles > 0)
575 {
576 jtag_checks();
577 jtag_set_error(interface_jtag_add_clocks(num_cycles));
578 }
579 }
580
581 void jtag_add_reset(int req_tlr_or_trst, int req_srst)
582 {
583 int trst_with_tlr = 0;
584
585 /* FIX!!! there are *many* different cases here. A better
586 * approach is needed for legal combinations of transitions...
587 */
588 if ((jtag_reset_config & RESET_HAS_SRST)&&
589 (jtag_reset_config & RESET_HAS_TRST)&&
590 ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0))
591 {
592 if (((req_tlr_or_trst&&!jtag_trst)||
593 (!req_tlr_or_trst && jtag_trst))&&
594 ((req_srst&&!jtag_srst)||
595 (!req_srst && jtag_srst)))
596 {
597 /* FIX!!! srst_pulls_trst allows 1,1 => 0,0 transition.... */
598 //LOG_ERROR("BUG: transition of req_tlr_or_trst and req_srst in the same jtag_add_reset() call is undefined");
599 }
600 }
601
602 /* Make sure that jtag_reset_config allows the requested reset */
603 /* if SRST pulls TRST, we can't fulfill srst == 1 with trst == 0 */
604 if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (!req_tlr_or_trst))
605 {
606 LOG_ERROR("BUG: requested reset would assert trst");
607 jtag_set_error(ERROR_FAIL);
608 return;
609 }
610
611 /* if TRST pulls SRST, we reset with TAP T-L-R */
612 if (((jtag_reset_config & RESET_TRST_PULLS_SRST) && (req_tlr_or_trst)) && (req_srst == 0))
613 {
614 trst_with_tlr = 1;
615 }
616
617 if (req_srst && !(jtag_reset_config & RESET_HAS_SRST))
618 {
619 LOG_ERROR("BUG: requested SRST assertion, but the current configuration doesn't support this");
620 jtag_set_error(ERROR_FAIL);
621 return;
622 }
623
624 if (req_tlr_or_trst)
625 {
626 if (!trst_with_tlr && (jtag_reset_config & RESET_HAS_TRST))
627 {
628 jtag_trst = 1;
629 } else
630 {
631 trst_with_tlr = 1;
632 }
633 } else
634 {
635 jtag_trst = 0;
636 }
637
638 jtag_srst = req_srst;
639
640 int retval = interface_jtag_add_reset(jtag_trst, jtag_srst);
641 if (retval != ERROR_OK)
642 {
643 jtag_set_error(retval);
644 return;
645 }
646 jtag_execute_queue();
647
648 if (jtag_srst)
649 {
650 LOG_DEBUG("SRST line asserted");
651 }
652 else
653 {
654 LOG_DEBUG("SRST line released");
655 if (jtag_nsrst_delay)
656 jtag_add_sleep(jtag_nsrst_delay * 1000);
657 }
658
659 if (trst_with_tlr)
660 {
661 LOG_DEBUG("JTAG reset with RESET instead of TRST");
662 jtag_set_end_state(TAP_RESET);
663 jtag_add_tlr();
664 return;
665 }
666
667 if (jtag_trst)
668 {
669 /* we just asserted nTRST, so we're now in Test-Logic-Reset,
670 * and inform possible listeners about this
671 */
672 LOG_DEBUG("TRST line asserted");
673 tap_set_state(TAP_RESET);
674 jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
675 }
676 else
677 {
678 if (jtag_ntrst_delay)
679 jtag_add_sleep(jtag_ntrst_delay * 1000);
680 }
681 }
682
683 tap_state_t jtag_set_end_state(tap_state_t state)
684 {
685 if ((state == TAP_DRSHIFT)||(state == TAP_IRSHIFT))
686 {
687 LOG_ERROR("BUG: TAP_DRSHIFT/IRSHIFT can't be end state. Calling code should use a larger scan field");
688 }
689
690 if (state != TAP_INVALID)
691 cmd_queue_end_state = state;
692 return cmd_queue_end_state;
693 }
694
695 tap_state_t jtag_get_end_state(void)
696 {
697 return cmd_queue_end_state;
698 }
699
700 void jtag_add_sleep(uint32_t us)
701 {
702 /// @todo Here, keep_alive() appears to be a layering violation!!!
703 keep_alive();
704 jtag_set_error(interface_jtag_add_sleep(us));
705 }
706
707 int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, uint8_t *in_check_mask, int num_bits)
708 {
709 int retval = ERROR_OK;
710
711 int compare_failed = 0;
712
713 if (in_check_mask)
714 compare_failed = buf_cmp_mask(captured, in_check_value, in_check_mask, num_bits);
715 else
716 compare_failed = buf_cmp(captured, in_check_value, num_bits);
717
718 if (compare_failed) {
719 /* An error handler could have caught the failing check
720 * only report a problem when there wasn't a handler, or if the handler
721 * acknowledged the error
722 */
723 /*
724 LOG_WARNING("TAP %s:",
725 jtag_tap_name(field->tap));
726 */
727 if (compare_failed)
728 {
729 char *captured_char = buf_to_str(captured, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16);
730 char *in_check_value_char = buf_to_str(in_check_value, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16);
731
732 if (in_check_mask)
733 {
734 char *in_check_mask_char;
735 in_check_mask_char = buf_to_str(in_check_mask, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16);
736 LOG_WARNING("value captured during scan didn't pass the requested check:");
737 LOG_WARNING("captured: 0x%s check_value: 0x%s check_mask: 0x%s",
738 captured_char, in_check_value_char, in_check_mask_char);
739 free(in_check_mask_char);
740 }
741 else
742 {
743 LOG_WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char);
744 }
745
746 free(captured_char);
747 free(in_check_value_char);
748
749 retval = ERROR_JTAG_QUEUE_FAILED;
750 }
751
752 }
753 return retval;
754 }
755
756 void jtag_check_value_mask(scan_field_t *field, uint8_t *value, uint8_t *mask)
757 {
758 assert(field->in_value != NULL);
759
760 if (value == NULL)
761 {
762 /* no checking to do */
763 return;
764 }
765
766 jtag_execute_queue_noclear();
767
768 int retval = jtag_check_value_inner(field->in_value, value, mask, field->num_bits);
769 jtag_set_error(retval);
770 }
771
772
773
774 int default_interface_jtag_execute_queue(void)
775 {
776 if (NULL == jtag)
777 {
778 LOG_ERROR("No JTAG interface configured yet. "
779 "Issue 'init' command in startup scripts "
780 "before communicating with targets.");
781 return ERROR_FAIL;
782 }
783
784 return jtag->execute_queue();
785 }
786
787 void jtag_execute_queue_noclear(void)
788 {
789 jtag_flush_queue_count++;
790 jtag_set_error(interface_jtag_execute_queue());
791 }
792
793 int jtag_get_flush_queue_count(void)
794 {
795 return jtag_flush_queue_count;
796 }
797
798 int jtag_execute_queue(void)
799 {
800 jtag_execute_queue_noclear();
801 return jtag_error_clear();
802 }
803
804 static int jtag_reset_callback(enum jtag_event event, void *priv)
805 {
806 jtag_tap_t *tap = priv;
807
808 LOG_DEBUG("-");
809
810 if (event == JTAG_TRST_ASSERTED)
811 {
812 tap->enabled = !tap->disabled_after_reset;
813
814 buf_set_ones(tap->cur_instr, tap->ir_length);
815 tap->bypass = 1;
816 }
817
818 return ERROR_OK;
819 }
820
821 void jtag_sleep(uint32_t us)
822 {
823 alive_sleep(us/1000);
824 }
825
826 /// maximum number of JTAG devices expected in the chain
827 #define JTAG_MAX_CHAIN_SIZE 20
828
829 #define EXTRACT_MFG(X) (((X) & 0xffe) >> 1)
830 #define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)
831 #define EXTRACT_VER(X) (((X) & 0xf0000000) >> 28)
832
833 static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode)
834 {
835 scan_field_t field = {
836 .tap = NULL,
837 .num_bits = num_idcode * 32,
838 .out_value = idcode_buffer,
839 .in_value = idcode_buffer,
840 };
841
842 // initialize to the end of chain ID value
843 for (unsigned i = 0; i < JTAG_MAX_CHAIN_SIZE; i++)
844 buf_set_u32(idcode_buffer, i * 32, 32, 0x000000FF);
845
846 jtag_add_plain_dr_scan(1, &field, TAP_RESET);
847 return jtag_execute_queue();
848 }
849
850 static bool jtag_examine_chain_check(uint8_t *idcodes, unsigned count)
851 {
852 uint8_t zero_check = 0x0;
853 uint8_t one_check = 0xff;
854
855 for (unsigned i = 0; i < count * 4; i++)
856 {
857 zero_check |= idcodes[i];
858 one_check &= idcodes[i];
859 }
860
861 /* if there wasn't a single non-zero bit or if all bits were one,
862 * the scan is not valid */
863 if (zero_check == 0x00 || one_check == 0xff)
864 {
865 LOG_ERROR("JTAG communication failure: check connection, "
866 "JTAG interface, target power etc.");
867 return false;
868 }
869 return true;
870 }
871
872 static void jtag_examine_chain_display(enum log_levels level, const char *msg,
873 const char *name, uint32_t idcode)
874 {
875 log_printf_lf(level, __FILE__, __LINE__, __FUNCTION__,
876 "JTAG tap: %s %16.16s: 0x%08x "
877 "(mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x)",
878 name, msg,
879 (unsigned int)idcode,
880 (unsigned int)EXTRACT_MFG(idcode),
881 (unsigned int)EXTRACT_PART(idcode),
882 (unsigned int)EXTRACT_VER(idcode));
883 }
884
885 static bool jtag_idcode_is_final(uint32_t idcode)
886 {
887 return idcode == 0x000000FF || idcode == 0xFFFFFFFF;
888 }
889
890 /**
891 * This helper checks that remaining bits in the examined chain data are
892 * all as expected, but a single JTAG device requires only 64 bits to be
893 * read back correctly. This can help identify and diagnose problems
894 * with the JTAG chain earlier, gives more helpful/explicit error messages.
895 */
896 static void jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned max)
897 {
898 bool triggered = false;
899 for (; count < max - 31; count += 32)
900 {
901 uint32_t idcode = buf_get_u32(idcodes, count, 32);
902 // do not trigger the warning if the data looks good
903 if (!triggered && jtag_idcode_is_final(idcode))
904 continue;
905 LOG_WARNING("Unexpected idcode after end of chain: %d 0x%08x",
906 count, (unsigned int)idcode);
907 triggered = true;
908 }
909 }
910
911 static bool jtag_examine_chain_match_tap(const struct jtag_tap_s *tap)
912 {
913 if (0 == tap->expected_ids_cnt)
914 {
915 /// @todo Enable LOG_INFO to ask for reports about unknown TAP IDs.
916 #if 0
917 LOG_INFO("Uknown JTAG TAP ID: 0x%08x", tap->idcode)
918 LOG_INFO("Please report the chip name and reported ID code to the openocd project");
919 #endif
920 return true;
921 }
922
923 /* Loop over the expected identification codes and test for a match */
924 uint8_t ii;
925 for (ii = 0; ii < tap->expected_ids_cnt; ii++)
926 {
927 if (tap->idcode == tap->expected_ids[ii])
928 break;
929 }
930
931 /* If none of the expected ids matched, log an error */
932 if (ii != tap->expected_ids_cnt)
933 {
934 LOG_INFO("JTAG Tap/device matched");
935 return true;
936 }
937 jtag_examine_chain_display(LOG_LVL_ERROR, "got",
938 tap->dotted_name, tap->idcode);
939 for (ii = 0; ii < tap->expected_ids_cnt; ii++)
940 {
941 char msg[32];
942 snprintf(msg, sizeof(msg), "expected %hhu of %hhu",
943 ii + 1, tap->expected_ids_cnt);
944 jtag_examine_chain_display(LOG_LVL_ERROR, msg,
945 tap->dotted_name, tap->expected_ids[ii]);
946 }
947 return false;
948 }
949
950 /* Try to examine chain layout according to IEEE 1149.1 §12
951 */
952 int jtag_examine_chain(void)
953 {
954 uint8_t idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
955 unsigned device_count = 0;
956
957 jtag_examine_chain_execute(idcode_buffer, JTAG_MAX_CHAIN_SIZE);
958
959 if (!jtag_examine_chain_check(idcode_buffer, JTAG_MAX_CHAIN_SIZE))
960 return ERROR_JTAG_INIT_FAILED;
961
962 /* point at the 1st tap */
963 jtag_tap_t *tap = jtag_tap_next_enabled(NULL);
964 if (tap == NULL)
965 {
966 LOG_ERROR("JTAG: No taps enabled?");
967 return ERROR_JTAG_INIT_FAILED;
968 }
969
970 for (unsigned bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;)
971 {
972 uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32);
973 if ((idcode & 1) == 0)
974 {
975 /* LSB must not be 0, this indicates a device in bypass */
976 LOG_WARNING("Tap/Device does not have IDCODE");
977 idcode = 0;
978
979 bit_count += 1;
980 }
981 else
982 {
983 /*
984 * End of chain (invalid manufacturer ID) some devices, such
985 * as AVR will output all 1's instead of TDI input value at
986 * end of chain.
987 */
988 if (jtag_idcode_is_final(idcode))
989 {
990 jtag_examine_chain_end(idcode_buffer,
991 bit_count + 32, JTAG_MAX_CHAIN_SIZE * 32);
992 break;
993 }
994
995 jtag_examine_chain_display(LOG_LVL_INFO, "tap/device found",
996 tap ? tap->dotted_name : "(not-named)",
997 idcode);
998
999 bit_count += 32;
1000 }
1001 device_count++;
1002 if (!tap)
1003 continue;
1004
1005 tap->idcode = idcode;
1006
1007 // ensure the TAP ID does matches what was expected
1008 if (!jtag_examine_chain_match_tap(tap))
1009 return ERROR_JTAG_INIT_FAILED;
1010
1011 tap = jtag_tap_next_enabled(tap);
1012 }
1013
1014 /* see if number of discovered devices matches configuration */
1015 if (device_count != jtag_tap_count_enabled())
1016 {
1017 LOG_ERROR("number of discovered devices in JTAG chain (%i) "
1018 "does not match (enabled) configuration (%i), total taps: %d",
1019 device_count, jtag_tap_count_enabled(), jtag_tap_count());
1020 LOG_ERROR("check the config file and ensure proper JTAG communication"
1021 " (connections, speed, ...)");
1022 return ERROR_JTAG_INIT_FAILED;
1023 }
1024
1025 return ERROR_OK;
1026 }
1027
1028 int jtag_validate_chain(void)
1029 {
1030 jtag_tap_t *tap;
1031 int total_ir_length = 0;
1032 uint8_t *ir_test = NULL;
1033 scan_field_t field;
1034 int chain_pos = 0;
1035
1036 tap = NULL;
1037 total_ir_length = 0;
1038 for (;;) {
1039 tap = jtag_tap_next_enabled(tap);
1040 if (tap == NULL) {
1041 break;
1042 }
1043 total_ir_length += tap->ir_length;
1044 }
1045
1046 total_ir_length += 2;
1047 ir_test = malloc(CEIL(total_ir_length, 8));
1048 buf_set_ones(ir_test, total_ir_length);
1049
1050 field.tap = NULL;
1051 field.num_bits = total_ir_length;
1052 field.out_value = ir_test;
1053 field.in_value = ir_test;
1054
1055
1056 jtag_add_plain_ir_scan(1, &field, TAP_RESET);
1057 jtag_execute_queue();
1058
1059 tap = NULL;
1060 chain_pos = 0;
1061 int val;
1062 for (;;) {
1063 tap = jtag_tap_next_enabled(tap);
1064 if (tap == NULL) {
1065 break;
1066 }
1067
1068 val = buf_get_u32(ir_test, chain_pos, 2);
1069 if (val != 0x1)
1070 {
1071 char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
1072 LOG_ERROR("Could not validate JTAG scan chain, IR mismatch, scan returned 0x%s. tap=%s pos=%d expected 0x1 got %0x", cbuf, jtag_tap_name(tap), chain_pos, val);
1073 free(cbuf);
1074 free(ir_test);
1075 return ERROR_JTAG_INIT_FAILED;
1076 }
1077 chain_pos += tap->ir_length;
1078 }
1079
1080 val = buf_get_u32(ir_test, chain_pos, 2);
1081 if (val != 0x3)
1082 {
1083 char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
1084 LOG_ERROR("Could not validate end of JTAG scan chain, IR mismatch, scan returned 0x%s. pos=%d expected 0x3 got %0x", cbuf, chain_pos, val);
1085 free(cbuf);
1086 free(ir_test);
1087 return ERROR_JTAG_INIT_FAILED;
1088 }
1089
1090 free(ir_test);
1091
1092 return ERROR_OK;
1093 }
1094
1095
1096 void jtag_tap_init(jtag_tap_t *tap)
1097 {
1098 assert(0 != tap->ir_length);
1099
1100 tap->expected = malloc(tap->ir_length);
1101 tap->expected_mask = malloc(tap->ir_length);
1102 tap->cur_instr = malloc(tap->ir_length);
1103
1104 /// @todo cope sanely with ir_length bigger than 32 bits
1105 buf_set_u32(tap->expected, 0, tap->ir_length, tap->ir_capture_value);
1106 buf_set_u32(tap->expected_mask, 0, tap->ir_length, tap->ir_capture_mask);
1107 buf_set_ones(tap->cur_instr, tap->ir_length);
1108
1109 // place TAP in bypass mode
1110 tap->bypass = 1;
1111 // register the reset callback for the TAP
1112 jtag_register_event_callback(&jtag_reset_callback, tap);
1113
1114 LOG_DEBUG("Created Tap: %s @ abs position %d, "
1115 "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name,
1116 tap->abs_chain_position, tap->ir_length,
1117 (unsigned int)(tap->ir_capture_value), (unsigned int)(tap->ir_capture_mask));
1118 jtag_tap_add(tap);
1119 }
1120
1121 void jtag_tap_free(jtag_tap_t *tap)
1122 {
1123 jtag_unregister_event_callback(&jtag_reset_callback, tap);
1124
1125 /// @todo is anything missing? no memory leaks please
1126 free((void *)tap->expected_ids);
1127 free((void *)tap->chip);
1128 free((void *)tap->tapname);
1129 free((void *)tap->dotted_name);
1130 free(tap);
1131 }
1132
1133 int jtag_interface_init(struct command_context_s *cmd_ctx)
1134 {
1135 if (jtag)
1136 return ERROR_OK;
1137
1138 if (!jtag_interface)
1139 {
1140 /* nothing was previously specified by "interface" command */
1141 LOG_ERROR("JTAG interface has to be specified, see \"interface\" command");
1142 return ERROR_JTAG_INVALID_INTERFACE;
1143 }
1144
1145 jtag = jtag_interface;
1146 if (jtag_interface->init() != ERROR_OK)
1147 {
1148 jtag = NULL;
1149 return ERROR_JTAG_INIT_FAILED;
1150 }
1151
1152 int requested_khz = jtag_get_speed_khz();
1153 int actual_khz = requested_khz;
1154 int retval = jtag_get_speed_readable(&actual_khz);
1155 if (ERROR_OK != retval)
1156 LOG_INFO("interface specific clock speed value %d", jtag_get_speed());
1157 else if (actual_khz)
1158 {
1159 if ((CLOCK_MODE_RCLK == clock_mode)
1160 || ((CLOCK_MODE_KHZ == clock_mode) && !requested_khz))
1161 {
1162 LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz"
1163 , actual_khz);
1164 }
1165 else
1166 LOG_INFO("clock speed %d kHz", actual_khz);
1167 }
1168 else
1169 LOG_INFO("RCLK (adaptive clock speed)");
1170
1171 return ERROR_OK;
1172 }
1173
1174 static int jtag_init_inner(struct command_context_s *cmd_ctx)
1175 {
1176 jtag_tap_t *tap;
1177 int retval;
1178
1179 LOG_DEBUG("Init JTAG chain");
1180
1181 tap = jtag_tap_next_enabled(NULL);
1182 if (tap == NULL) {
1183 LOG_ERROR("There are no enabled taps?");
1184 return ERROR_JTAG_INIT_FAILED;
1185 }
1186
1187 jtag_add_tlr();
1188 if ((retval = jtag_execute_queue()) != ERROR_OK)
1189 return retval;
1190
1191 /* examine chain first, as this could discover the real chain layout */
1192 if (jtag_examine_chain() != ERROR_OK)
1193 {
1194 LOG_ERROR("trying to validate configured JTAG chain anyway...");
1195 }
1196
1197 if (jtag_validate_chain() != ERROR_OK)
1198 {
1199 LOG_WARNING("Could not validate JTAG chain, continuing anyway...");
1200 }
1201
1202 return ERROR_OK;
1203 }
1204
1205 int jtag_interface_quit(void)
1206 {
1207 if (!jtag || !jtag->quit)
1208 return ERROR_OK;
1209
1210 // close the JTAG interface
1211 int result = jtag->quit();
1212 if (ERROR_OK != result)
1213 LOG_ERROR("failed: %d", result);
1214
1215 return ERROR_OK;
1216 }
1217
1218
1219 int jtag_init_reset(struct command_context_s *cmd_ctx)
1220 {
1221 int retval;
1222
1223 if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK)
1224 return retval;
1225
1226 LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / RESET");
1227
1228 /* Reset can happen after a power cycle.
1229 *
1230 * Ideally we would only assert TRST or run RESET before the target reset.
1231 *
1232 * However w/srst_pulls_trst, trst is asserted together with the target
1233 * reset whether we want it or not.
1234 *
1235 * NB! Some targets have JTAG circuitry disabled until a
1236 * trst & srst has been asserted.
1237 *
1238 * NB! here we assume nsrst/ntrst delay are sufficient!
1239 *
1240 * NB! order matters!!!! srst *can* disconnect JTAG circuitry
1241 *
1242 */
1243 jtag_add_reset(1, 0); /* RESET or TRST */
1244 if (jtag_reset_config & RESET_HAS_SRST)
1245 {
1246 jtag_add_reset(1, 1);
1247 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)
1248 jtag_add_reset(0, 1);
1249 }
1250 jtag_add_reset(0, 0);
1251 if ((retval = jtag_execute_queue()) != ERROR_OK)
1252 return retval;
1253
1254 /* Check that we can communication on the JTAG chain + eventually we want to
1255 * be able to perform enumeration only after OpenOCD has started
1256 * telnet and GDB server
1257 *
1258 * That would allow users to more easily perform any magic they need to before
1259 * reset happens.
1260 */
1261 return jtag_init_inner(cmd_ctx);
1262 }
1263
1264 int jtag_init(struct command_context_s *cmd_ctx)
1265 {
1266 int retval;
1267 if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK)
1268 return retval;
1269 if (jtag_init_inner(cmd_ctx) == ERROR_OK)
1270 {
1271 return ERROR_OK;
1272 }
1273 return jtag_init_reset(cmd_ctx);
1274 }
1275
1276 unsigned jtag_get_speed_khz(void)
1277 {
1278 return speed_khz;
1279 }
1280
1281 static int jtag_khz_to_speed(unsigned khz, int* speed)
1282 {
1283 LOG_DEBUG("convert khz to interface specific speed value");
1284 speed_khz = khz;
1285 if (jtag != NULL)
1286 {
1287 LOG_DEBUG("have interface set up");
1288 int speed_div1;
1289 int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
1290 if (ERROR_OK != retval)
1291 {
1292 return retval;
1293 }
1294 *speed = speed_div1;
1295 }
1296 return ERROR_OK;
1297 }
1298
1299 static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int* speed)
1300 {
1301 int retval = jtag_khz_to_speed(0, speed);
1302 if ((ERROR_OK != retval) && fallback_speed_khz)
1303 {
1304 LOG_DEBUG("trying fallback speed...");
1305 retval = jtag_khz_to_speed(fallback_speed_khz, speed);
1306 }
1307 return retval;
1308 }
1309
1310 static int jtag_set_speed(int speed)
1311 {
1312 jtag_speed = speed;
1313 /* this command can be called during CONFIG,
1314 * in which case jtag isn't initialized */
1315 return jtag ? jtag->speed(speed) : ERROR_OK;
1316 }
1317
1318 int jtag_config_speed(int speed)
1319 {
1320 LOG_DEBUG("handle jtag speed");
1321 clock_mode = CLOCK_MODE_SPEED;
1322 return jtag_set_speed(speed);
1323 }
1324
1325 int jtag_config_khz(unsigned khz)
1326 {
1327 LOG_DEBUG("handle jtag khz");
1328 clock_mode = CLOCK_MODE_KHZ;
1329 int speed = 0;
1330 int retval = jtag_khz_to_speed(khz, &speed);
1331 return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
1332 }
1333
1334 int jtag_config_rclk(unsigned fallback_speed_khz)
1335 {
1336 LOG_DEBUG("handle jtag rclk");
1337 clock_mode = CLOCK_MODE_RCLK;
1338 rclk_fallback_speed_khz = fallback_speed_khz;
1339 int speed = 0;
1340 int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed);
1341 return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
1342 }
1343
1344 int jtag_get_speed(void)
1345 {
1346 int speed;
1347 switch(clock_mode)
1348 {
1349 case CLOCK_MODE_SPEED:
1350 speed = jtag_speed;
1351 break;
1352 case CLOCK_MODE_KHZ:
1353 jtag_khz_to_speed(jtag_get_speed_khz(), &speed);
1354 break;
1355 case CLOCK_MODE_RCLK:
1356 jtag_rclk_to_speed(rclk_fallback_speed_khz, &speed);
1357 break;
1358 default:
1359 LOG_ERROR("BUG: unknown jtag clock mode");
1360 speed = 0;
1361 break;
1362 }
1363 return speed;
1364 }
1365
1366 int jtag_get_speed_readable(int *khz)
1367 {
1368 return jtag ? jtag->speed_div(jtag_get_speed(), khz) : ERROR_OK;
1369 }
1370
1371 void jtag_set_verify(bool enable)
1372 {
1373 jtag_verify = enable;
1374 }
1375
1376 bool jtag_will_verify()
1377 {
1378 return jtag_verify;
1379 }
1380
1381 void jtag_set_verify_capture_ir(bool enable)
1382 {
1383 jtag_verify_capture_ir = enable;
1384 }
1385
1386 bool jtag_will_verify_capture_ir()
1387 {
1388 return jtag_verify_capture_ir;
1389 }
1390
1391 int jtag_power_dropout(int *dropout)
1392 {
1393 return jtag->power_dropout(dropout);
1394 }
1395
1396 int jtag_srst_asserted(int *srst_asserted)
1397 {
1398 return jtag->srst_asserted(srst_asserted);
1399 }
1400
1401 enum reset_types jtag_get_reset_config(void)
1402 {
1403 return jtag_reset_config;
1404 }
1405 void jtag_set_reset_config(enum reset_types type)
1406 {
1407 jtag_reset_config = type;
1408 }
1409
1410 int jtag_get_trst(void)
1411 {
1412 return jtag_trst;
1413 }
1414 int jtag_get_srst(void)
1415 {
1416 return jtag_srst;
1417 }
1418
1419 void jtag_set_nsrst_delay(unsigned delay)
1420 {
1421 jtag_nsrst_delay = delay;
1422 }
1423 unsigned jtag_get_nsrst_delay(void)
1424 {
1425 return jtag_nsrst_delay;
1426 }
1427 void jtag_set_ntrst_delay(unsigned delay)
1428 {
1429 jtag_ntrst_delay = delay;
1430 }
1431 unsigned jtag_get_ntrst_delay(void)
1432 {
1433 return jtag_ntrst_delay;
1434 }

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)