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 return retval;
1157
1158 if (actual_khz)
1159 {
1160 if ((CLOCK_MODE_RCLK == clock_mode)
1161 || ((CLOCK_MODE_KHZ == clock_mode) && !requested_khz))
1162 {
1163 LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz"
1164 , actual_khz);
1165 }
1166 else
1167 LOG_INFO("clock speed %d kHz", actual_khz);
1168 }
1169 else
1170 LOG_INFO("RCLK (adaptive clock speed)");
1171
1172 return ERROR_OK;
1173 }
1174
1175 static int jtag_init_inner(struct command_context_s *cmd_ctx)
1176 {
1177 jtag_tap_t *tap;
1178 int retval;
1179
1180 LOG_DEBUG("Init JTAG chain");
1181
1182 tap = jtag_tap_next_enabled(NULL);
1183 if (tap == NULL) {
1184 LOG_ERROR("There are no enabled taps?");
1185 return ERROR_JTAG_INIT_FAILED;
1186 }
1187
1188 jtag_add_tlr();
1189 if ((retval = jtag_execute_queue()) != ERROR_OK)
1190 return retval;
1191
1192 /* examine chain first, as this could discover the real chain layout */
1193 if (jtag_examine_chain() != ERROR_OK)
1194 {
1195 LOG_ERROR("trying to validate configured JTAG chain anyway...");
1196 }
1197
1198 if (jtag_validate_chain() != ERROR_OK)
1199 {
1200 LOG_WARNING("Could not validate JTAG chain, continuing anyway...");
1201 }
1202
1203 return ERROR_OK;
1204 }
1205
1206 int jtag_interface_quit(void)
1207 {
1208 if (!jtag || !jtag->quit)
1209 return ERROR_OK;
1210
1211 // close the JTAG interface
1212 int result = jtag->quit();
1213 if (ERROR_OK != result)
1214 LOG_ERROR("failed: %d", result);
1215
1216 return ERROR_OK;
1217 }
1218
1219
1220 int jtag_init_reset(struct command_context_s *cmd_ctx)
1221 {
1222 int retval;
1223
1224 if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK)
1225 return retval;
1226
1227 LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / RESET");
1228
1229 /* Reset can happen after a power cycle.
1230 *
1231 * Ideally we would only assert TRST or run RESET before the target reset.
1232 *
1233 * However w/srst_pulls_trst, trst is asserted together with the target
1234 * reset whether we want it or not.
1235 *
1236 * NB! Some targets have JTAG circuitry disabled until a
1237 * trst & srst has been asserted.
1238 *
1239 * NB! here we assume nsrst/ntrst delay are sufficient!
1240 *
1241 * NB! order matters!!!! srst *can* disconnect JTAG circuitry
1242 *
1243 */
1244 jtag_add_reset(1, 0); /* RESET or TRST */
1245 if (jtag_reset_config & RESET_HAS_SRST)
1246 {
1247 jtag_add_reset(1, 1);
1248 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)
1249 jtag_add_reset(0, 1);
1250 }
1251 jtag_add_reset(0, 0);
1252 if ((retval = jtag_execute_queue()) != ERROR_OK)
1253 return retval;
1254
1255 /* Check that we can communication on the JTAG chain + eventually we want to
1256 * be able to perform enumeration only after OpenOCD has started
1257 * telnet and GDB server
1258 *
1259 * That would allow users to more easily perform any magic they need to before
1260 * reset happens.
1261 */
1262 return jtag_init_inner(cmd_ctx);
1263 }
1264
1265 int jtag_init(struct command_context_s *cmd_ctx)
1266 {
1267 int retval;
1268 if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK)
1269 return retval;
1270 if (jtag_init_inner(cmd_ctx) == ERROR_OK)
1271 {
1272 return ERROR_OK;
1273 }
1274 return jtag_init_reset(cmd_ctx);
1275 }
1276
1277 unsigned jtag_get_speed_khz(void)
1278 {
1279 return speed_khz;
1280 }
1281
1282 static int jtag_khz_to_speed(unsigned khz, int* speed)
1283 {
1284 LOG_DEBUG("convert khz to interface specific speed value");
1285 speed_khz = khz;
1286 if (jtag != NULL)
1287 {
1288 LOG_DEBUG("have interface set up");
1289 int speed_div1;
1290 int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
1291 if (ERROR_OK != retval)
1292 {
1293 return retval;
1294 }
1295 *speed = speed_div1;
1296 }
1297 return ERROR_OK;
1298 }
1299
1300 static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int* speed)
1301 {
1302 int retval = jtag_khz_to_speed(0, speed);
1303 if ((ERROR_OK != retval) && fallback_speed_khz)
1304 {
1305 LOG_DEBUG("trying fallback speed...");
1306 retval = jtag_khz_to_speed(fallback_speed_khz, speed);
1307 }
1308 return retval;
1309 }
1310
1311 static int jtag_set_speed(int speed)
1312 {
1313 jtag_speed = speed;
1314 /* this command can be called during CONFIG,
1315 * in which case jtag isn't initialized */
1316 return jtag ? jtag->speed(speed) : ERROR_OK;
1317 }
1318
1319 int jtag_config_speed(int speed)
1320 {
1321 LOG_DEBUG("handle jtag speed");
1322 clock_mode = CLOCK_MODE_SPEED;
1323 return jtag_set_speed(speed);
1324 }
1325
1326 int jtag_config_khz(unsigned khz)
1327 {
1328 LOG_DEBUG("handle jtag khz");
1329 clock_mode = CLOCK_MODE_KHZ;
1330 int speed = 0;
1331 int retval = jtag_khz_to_speed(khz, &speed);
1332 return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
1333 }
1334
1335 int jtag_config_rclk(unsigned fallback_speed_khz)
1336 {
1337 LOG_DEBUG("handle jtag rclk");
1338 clock_mode = CLOCK_MODE_RCLK;
1339 rclk_fallback_speed_khz = fallback_speed_khz;
1340 int speed = 0;
1341 int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed);
1342 return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
1343 }
1344
1345 int jtag_get_speed(void)
1346 {
1347 int speed;
1348 switch(clock_mode)
1349 {
1350 case CLOCK_MODE_SPEED:
1351 speed = jtag_speed;
1352 break;
1353 case CLOCK_MODE_KHZ:
1354 jtag_khz_to_speed(jtag_get_speed_khz(), &speed);
1355 break;
1356 case CLOCK_MODE_RCLK:
1357 jtag_rclk_to_speed(rclk_fallback_speed_khz, &speed);
1358 break;
1359 default:
1360 LOG_ERROR("BUG: unknown jtag clock mode");
1361 speed = 0;
1362 break;
1363 }
1364 return speed;
1365 }
1366
1367 int jtag_get_speed_readable(int *khz)
1368 {
1369 return jtag ? jtag->speed_div(jtag_get_speed(), khz) : ERROR_OK;
1370 }
1371
1372 void jtag_set_verify(bool enable)
1373 {
1374 jtag_verify = enable;
1375 }
1376
1377 bool jtag_will_verify()
1378 {
1379 return jtag_verify;
1380 }
1381
1382 void jtag_set_verify_capture_ir(bool enable)
1383 {
1384 jtag_verify_capture_ir = enable;
1385 }
1386
1387 bool jtag_will_verify_capture_ir()
1388 {
1389 return jtag_verify_capture_ir;
1390 }
1391
1392 int jtag_power_dropout(int *dropout)
1393 {
1394 return jtag->power_dropout(dropout);
1395 }
1396
1397 int jtag_srst_asserted(int *srst_asserted)
1398 {
1399 return jtag->srst_asserted(srst_asserted);
1400 }
1401
1402 enum reset_types jtag_get_reset_config(void)
1403 {
1404 return jtag_reset_config;
1405 }
1406 void jtag_set_reset_config(enum reset_types type)
1407 {
1408 jtag_reset_config = type;
1409 }
1410
1411 int jtag_get_trst(void)
1412 {
1413 return jtag_trst;
1414 }
1415 int jtag_get_srst(void)
1416 {
1417 return jtag_srst;
1418 }
1419
1420 void jtag_set_nsrst_delay(unsigned delay)
1421 {
1422 jtag_nsrst_delay = delay;
1423 }
1424 unsigned jtag_get_nsrst_delay(void)
1425 {
1426 return jtag_nsrst_delay;
1427 }
1428 void jtag_set_ntrst_delay(unsigned delay)
1429 {
1430 jtag_ntrst_delay = delay;
1431 }
1432 unsigned jtag_get_ntrst_delay(void)
1433 {
1434 return jtag_ntrst_delay;
1435 }

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)