1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "arm7_9_common.h"
28 static char* etb_reg_list
[] =
35 "ETB_ram_read_pointer",
36 "ETB_ram_write_pointer",
37 "ETB_trigger_counter",
41 static int etb_reg_arch_type
= -1;
43 static int etb_get_reg(reg_t
*reg
);
45 static int handle_etb_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
47 static int etb_set_instr(etb_t
*etb
, u32 new_instr
)
55 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
60 field
.num_bits
= tap
->ir_length
;
61 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
62 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
64 field
.in_value
= NULL
;
66 jtag_add_ir_scan(1, &field
, TAP_INVALID
);
68 free(field
.out_value
);
74 static int etb_scann(etb_t
*etb
, u32 new_scan_chain
)
76 if (etb
->cur_scan_chain
!= new_scan_chain
)
82 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
83 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_scan_chain
);
85 field
.in_value
= NULL
;
87 /* select INTEST instruction */
88 etb_set_instr(etb
, 0x2);
89 jtag_add_dr_scan(1, &field
, TAP_INVALID
);
91 etb
->cur_scan_chain
= new_scan_chain
;
93 free(field
.out_value
);
99 reg_cache_t
* etb_build_reg_cache(etb_t
*etb
)
101 reg_cache_t
*reg_cache
= malloc(sizeof(reg_cache_t
));
102 reg_t
*reg_list
= NULL
;
103 etb_reg_t
*arch_info
= NULL
;
107 /* register a register arch-type for etm registers only once */
108 if (etb_reg_arch_type
== -1)
109 etb_reg_arch_type
= register_reg_arch_type(etb_get_reg
, etb_set_reg_w_exec
);
111 /* the actual registers are kept in two arrays */
112 reg_list
= calloc(num_regs
, sizeof(reg_t
));
113 arch_info
= calloc(num_regs
, sizeof(etb_reg_t
));
115 /* fill in values for the reg cache */
116 reg_cache
->name
= "etb registers";
117 reg_cache
->next
= NULL
;
118 reg_cache
->reg_list
= reg_list
;
119 reg_cache
->num_regs
= num_regs
;
121 /* set up registers */
122 for (i
= 0; i
< num_regs
; i
++)
124 reg_list
[i
].name
= etb_reg_list
[i
];
125 reg_list
[i
].size
= 32;
126 reg_list
[i
].dirty
= 0;
127 reg_list
[i
].valid
= 0;
128 reg_list
[i
].bitfield_desc
= NULL
;
129 reg_list
[i
].num_bitfields
= 0;
130 reg_list
[i
].value
= calloc(1, 4);
131 reg_list
[i
].arch_info
= &arch_info
[i
];
132 reg_list
[i
].arch_type
= etb_reg_arch_type
;
133 reg_list
[i
].size
= 32;
134 arch_info
[i
].addr
= i
;
135 arch_info
[i
].etb
= etb
;
141 static int etb_get_reg(reg_t
*reg
)
145 if ((retval
= etb_read_reg(reg
)) != ERROR_OK
)
147 LOG_ERROR("BUG: error scheduling etm register read");
151 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
153 LOG_ERROR("register read failed");
160 static int etb_read_ram(etb_t
*etb
, u32
*data
, int num_frames
)
162 scan_field_t fields
[3];
165 jtag_add_end_state(TAP_IDLE
);
167 etb_set_instr(etb
, 0xc);
169 fields
[0].tap
= etb
->tap
;
170 fields
[0].num_bits
= 32;
171 fields
[0].out_value
= NULL
;
173 fields
[0].in_value
= tmp
;
175 fields
[1].tap
= etb
->tap
;
176 fields
[1].num_bits
= 7;
177 fields
[1].out_value
= malloc(1);
178 buf_set_u32(fields
[1].out_value
, 0, 7, 4);
179 fields
[1].in_value
= NULL
;
181 fields
[2].tap
= etb
->tap
;
182 fields
[2].num_bits
= 1;
183 fields
[2].out_value
= malloc(1);
184 buf_set_u32(fields
[2].out_value
, 0, 1, 0);
185 fields
[2].in_value
= NULL
;
187 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
189 for (i
= 0; i
< num_frames
; i
++)
191 /* ensure nR/W reamins set to read */
192 buf_set_u32(fields
[2].out_value
, 0, 1, 0);
194 /* address remains set to 0x4 (RAM data) until we read the last frame */
195 if (i
< num_frames
- 1)
196 buf_set_u32(fields
[1].out_value
, 0, 7, 4);
198 buf_set_u32(fields
[1].out_value
, 0, 7, 0);
200 jtag_add_dr_scan_now(3, fields
, TAP_INVALID
);
202 data
[i
]=buf_get_u32(tmp
, 0, 32);
205 jtag_execute_queue();
207 free(fields
[1].out_value
);
208 free(fields
[2].out_value
);
213 int etb_read_reg_w_check(reg_t
*reg
, u8
* check_value
, u8
* check_mask
)
215 etb_reg_t
*etb_reg
= reg
->arch_info
;
216 u8 reg_addr
= etb_reg
->addr
& 0x7f;
217 scan_field_t fields
[3];
219 LOG_DEBUG("%i", etb_reg
->addr
);
221 jtag_add_end_state(TAP_IDLE
);
222 etb_scann(etb_reg
->etb
, 0x0);
223 etb_set_instr(etb_reg
->etb
, 0xc);
225 fields
[0].tap
= etb_reg
->etb
->tap
;
226 fields
[0].num_bits
= 32;
227 fields
[0].out_value
= reg
->value
;
228 fields
[0].in_value
= NULL
;
230 fields
[1].tap
= etb_reg
->etb
->tap
;
231 fields
[1].num_bits
= 7;
232 fields
[1].out_value
= malloc(1);
233 buf_set_u32(fields
[1].out_value
, 0, 7, reg_addr
);
234 fields
[1].in_value
= NULL
;
236 fields
[2].tap
= etb_reg
->etb
->tap
;
237 fields
[2].num_bits
= 1;
238 fields
[2].out_value
= malloc(1);
239 buf_set_u32(fields
[2].out_value
, 0, 1, 0);
240 fields
[2].in_value
= NULL
;
242 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
244 /* read the identification register in the second run, to make sure we
245 * don't read the ETB data register twice, skipping every second entry
247 buf_set_u32(fields
[1].out_value
, 0, 7, 0x0);
248 fields
[0].in_value
= reg
->value
;
250 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
252 jtag_check_value_mask(fields
+0, check_value
, check_mask
);
254 free(fields
[1].out_value
);
255 free(fields
[2].out_value
);
260 int etb_read_reg(reg_t
*reg
)
262 return etb_read_reg_w_check(reg
, NULL
, NULL
);
265 int etb_set_reg(reg_t
*reg
, u32 value
)
269 if ((retval
= etb_write_reg(reg
, value
)) != ERROR_OK
)
271 LOG_ERROR("BUG: error scheduling etm register write");
275 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
282 int etb_set_reg_w_exec(reg_t
*reg
, u8
*buf
)
286 etb_set_reg(reg
, buf_get_u32(buf
, 0, reg
->size
));
288 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
290 LOG_ERROR("register write failed");
296 int etb_write_reg(reg_t
*reg
, u32 value
)
298 etb_reg_t
*etb_reg
= reg
->arch_info
;
299 u8 reg_addr
= etb_reg
->addr
& 0x7f;
300 scan_field_t fields
[3];
302 LOG_DEBUG("%i: 0x%8.8x", etb_reg
->addr
, value
);
304 jtag_add_end_state(TAP_IDLE
);
305 etb_scann(etb_reg
->etb
, 0x0);
306 etb_set_instr(etb_reg
->etb
, 0xc);
308 fields
[0].tap
= etb_reg
->etb
->tap
;
309 fields
[0].num_bits
= 32;
310 fields
[0].out_value
= malloc(4);
311 buf_set_u32(fields
[0].out_value
, 0, 32, value
);
312 fields
[0].in_value
= NULL
;
314 fields
[1].tap
= etb_reg
->etb
->tap
;
315 fields
[1].num_bits
= 7;
316 fields
[1].out_value
= malloc(1);
317 buf_set_u32(fields
[1].out_value
, 0, 7, reg_addr
);
318 fields
[1].in_value
= NULL
;
320 fields
[2].tap
= etb_reg
->etb
->tap
;
321 fields
[2].num_bits
= 1;
322 fields
[2].out_value
= malloc(1);
323 buf_set_u32(fields
[2].out_value
, 0, 1, 1);
325 fields
[2].in_value
= NULL
;
327 free(fields
[0].out_value
);
328 free(fields
[1].out_value
);
329 free(fields
[2].out_value
);
334 int etb_store_reg(reg_t
*reg
)
336 return etb_write_reg(reg
, buf_get_u32(reg
->value
, 0, reg
->size
));
339 static int etb_register_commands(struct command_context_s
*cmd_ctx
)
343 etb_cmd
= register_command(cmd_ctx
, NULL
, "etb", NULL
, COMMAND_ANY
, "Embedded Trace Buffer");
345 register_command(cmd_ctx
, etb_cmd
, "config", handle_etb_config_command
, COMMAND_CONFIG
, NULL
);
350 static int handle_etb_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
354 armv4_5_common_t
*armv4_5
;
355 arm7_9_common_t
*arm7_9
;
359 return ERROR_COMMAND_SYNTAX_ERROR
;
362 target
= get_target_by_num(strtoul(args
[0], NULL
, 0));
366 LOG_ERROR("target number '%s' not defined", args
[0]);
370 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
372 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
376 tap
= jtag_TapByString( args
[1] );
379 command_print(cmd_ctx
, "Tap: %s does not exist", args
[1] );
385 etb_t
*etb
= malloc(sizeof(etb_t
));
387 arm7_9
->etm_ctx
->capture_driver_priv
= etb
;
390 etb
->cur_scan_chain
= 0xffffffff;
391 etb
->reg_cache
= NULL
;
397 LOG_ERROR("target has no ETM defined, ETB left unconfigured");
404 static int etb_init(etm_context_t
*etm_ctx
)
406 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
408 etb
->etm_ctx
= etm_ctx
;
410 /* identify ETB RAM depth and width */
411 etb_read_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_DEPTH
]);
412 etb_read_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_WIDTH
]);
413 jtag_execute_queue();
415 etb
->ram_depth
= buf_get_u32(etb
->reg_cache
->reg_list
[ETB_RAM_DEPTH
].value
, 0, 32);
416 etb
->ram_width
= buf_get_u32(etb
->reg_cache
->reg_list
[ETB_RAM_WIDTH
].value
, 0, 32);
421 static trace_status_t
etb_status(etm_context_t
*etm_ctx
)
423 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
425 etb
->etm_ctx
= etm_ctx
;
427 /* if tracing is currently idle, return this information */
428 if (etm_ctx
->capture_status
== TRACE_IDLE
)
430 return etm_ctx
->capture_status
;
432 else if (etm_ctx
->capture_status
& TRACE_RUNNING
)
434 reg_t
*etb_status_reg
= &etb
->reg_cache
->reg_list
[ETB_STATUS
];
435 int etb_timeout
= 100;
437 /* trace is running, check the ETB status flags */
438 etb_get_reg(etb_status_reg
);
440 /* check Full bit to identify an overflow */
441 if (buf_get_u32(etb_status_reg
->value
, 0, 1) == 1)
442 etm_ctx
->capture_status
|= TRACE_OVERFLOWED
;
444 /* check Triggered bit to identify trigger condition */
445 if (buf_get_u32(etb_status_reg
->value
, 1, 1) == 1)
446 etm_ctx
->capture_status
|= TRACE_TRIGGERED
;
448 /* check AcqComp to identify trace completion */
449 if (buf_get_u32(etb_status_reg
->value
, 2, 1) == 1)
451 while (etb_timeout
-- && (buf_get_u32(etb_status_reg
->value
, 3, 1) == 0))
453 /* wait for data formatter idle */
454 etb_get_reg(etb_status_reg
);
457 if (etb_timeout
== 0)
459 LOG_ERROR("AcqComp set but DFEmpty won't go high, ETB status: 0x%x",
460 buf_get_u32(etb_status_reg
->value
, 0, etb_status_reg
->size
));
463 if (!(etm_ctx
->capture_status
&& TRACE_TRIGGERED
))
465 LOG_ERROR("trace completed, but no trigger condition detected");
468 etm_ctx
->capture_status
&= ~TRACE_RUNNING
;
469 etm_ctx
->capture_status
|= TRACE_COMPLETED
;
473 return etm_ctx
->capture_status
;
476 static int etb_read_trace(etm_context_t
*etm_ctx
)
478 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
480 int num_frames
= etb
->ram_depth
;
481 u32
*trace_data
= NULL
;
484 etb_read_reg(&etb
->reg_cache
->reg_list
[ETB_STATUS
]);
485 etb_read_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_WRITE_POINTER
]);
486 jtag_execute_queue();
488 /* check if we overflowed, and adjust first frame of the trace accordingly
489 * if we didn't overflow, read only up to the frame that would be written next,
490 * i.e. don't read invalid entries
492 if (buf_get_u32(etb
->reg_cache
->reg_list
[ETB_STATUS
].value
, 0, 1))
494 first_frame
= buf_get_u32(etb
->reg_cache
->reg_list
[ETB_RAM_WRITE_POINTER
].value
, 0, 32);
498 num_frames
= buf_get_u32(etb
->reg_cache
->reg_list
[ETB_RAM_WRITE_POINTER
].value
, 0, 32);
501 etb_write_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_READ_POINTER
], first_frame
);
503 /* read data into temporary array for unpacking */
504 trace_data
= malloc(sizeof(u32
) * num_frames
);
505 etb_read_ram(etb
, trace_data
, num_frames
);
507 if (etm_ctx
->trace_depth
> 0)
509 free(etm_ctx
->trace_data
);
512 if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_4BIT
)
513 etm_ctx
->trace_depth
= num_frames
* 3;
514 else if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_8BIT
)
515 etm_ctx
->trace_depth
= num_frames
* 2;
517 etm_ctx
->trace_depth
= num_frames
;
519 etm_ctx
->trace_data
= malloc(sizeof(etmv1_trace_data_t
) * etm_ctx
->trace_depth
);
521 for (i
= 0, j
= 0; i
< num_frames
; i
++)
523 if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_4BIT
)
526 etm_ctx
->trace_data
[j
].pipestat
= trace_data
[i
] & 0x7;
527 etm_ctx
->trace_data
[j
].packet
= (trace_data
[i
] & 0x78) >> 3;
528 etm_ctx
->trace_data
[j
].flags
= 0;
529 if ((trace_data
[i
] & 0x80) >> 7)
531 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRACESYNC_CYCLE
;
533 if (etm_ctx
->trace_data
[j
].pipestat
== STAT_TR
)
535 etm_ctx
->trace_data
[j
].pipestat
= etm_ctx
->trace_data
[j
].packet
& 0x7;
536 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRIGGER_CYCLE
;
540 etm_ctx
->trace_data
[j
+1].pipestat
= (trace_data
[i
] & 0x100) >> 8;
541 etm_ctx
->trace_data
[j
+1].packet
= (trace_data
[i
] & 0x7800) >> 11;
542 etm_ctx
->trace_data
[j
+1].flags
= 0;
543 if ((trace_data
[i
] & 0x8000) >> 15)
545 etm_ctx
->trace_data
[j
+1].flags
|= ETMV1_TRACESYNC_CYCLE
;
547 if (etm_ctx
->trace_data
[j
+1].pipestat
== STAT_TR
)
549 etm_ctx
->trace_data
[j
+1].pipestat
= etm_ctx
->trace_data
[j
+1].packet
& 0x7;
550 etm_ctx
->trace_data
[j
+1].flags
|= ETMV1_TRIGGER_CYCLE
;
554 etm_ctx
->trace_data
[j
+2].pipestat
= (trace_data
[i
] & 0x10000) >> 16;
555 etm_ctx
->trace_data
[j
+2].packet
= (trace_data
[i
] & 0x780000) >> 19;
556 etm_ctx
->trace_data
[j
+2].flags
= 0;
557 if ((trace_data
[i
] & 0x800000) >> 23)
559 etm_ctx
->trace_data
[j
+2].flags
|= ETMV1_TRACESYNC_CYCLE
;
561 if (etm_ctx
->trace_data
[j
+2].pipestat
== STAT_TR
)
563 etm_ctx
->trace_data
[j
+2].pipestat
= etm_ctx
->trace_data
[j
+2].packet
& 0x7;
564 etm_ctx
->trace_data
[j
+2].flags
|= ETMV1_TRIGGER_CYCLE
;
569 else if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_8BIT
)
572 etm_ctx
->trace_data
[j
].pipestat
= trace_data
[i
] & 0x7;
573 etm_ctx
->trace_data
[j
].packet
= (trace_data
[i
] & 0x7f8) >> 3;
574 etm_ctx
->trace_data
[j
].flags
= 0;
575 if ((trace_data
[i
] & 0x800) >> 11)
577 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRACESYNC_CYCLE
;
579 if (etm_ctx
->trace_data
[j
].pipestat
== STAT_TR
)
581 etm_ctx
->trace_data
[j
].pipestat
= etm_ctx
->trace_data
[j
].packet
& 0x7;
582 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRIGGER_CYCLE
;
586 etm_ctx
->trace_data
[j
+1].pipestat
= (trace_data
[i
] & 0x7000) >> 12;
587 etm_ctx
->trace_data
[j
+1].packet
= (trace_data
[i
] & 0x7f8000) >> 15;
588 etm_ctx
->trace_data
[j
+1].flags
= 0;
589 if ((trace_data
[i
] & 0x800000) >> 23)
591 etm_ctx
->trace_data
[j
+1].flags
|= ETMV1_TRACESYNC_CYCLE
;
593 if (etm_ctx
->trace_data
[j
+1].pipestat
== STAT_TR
)
595 etm_ctx
->trace_data
[j
+1].pipestat
= etm_ctx
->trace_data
[j
+1].packet
& 0x7;
596 etm_ctx
->trace_data
[j
+1].flags
|= ETMV1_TRIGGER_CYCLE
;
604 etm_ctx
->trace_data
[j
].pipestat
= trace_data
[i
] & 0x7;
605 etm_ctx
->trace_data
[j
].packet
= (trace_data
[i
] & 0x7fff8) >> 3;
606 etm_ctx
->trace_data
[j
].flags
= 0;
607 if ((trace_data
[i
] & 0x80000) >> 19)
609 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRACESYNC_CYCLE
;
611 if (etm_ctx
->trace_data
[j
].pipestat
== STAT_TR
)
613 etm_ctx
->trace_data
[j
].pipestat
= etm_ctx
->trace_data
[j
].packet
& 0x7;
614 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRIGGER_CYCLE
;
626 static int etb_start_capture(etm_context_t
*etm_ctx
)
628 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
629 u32 etb_ctrl_value
= 0x1;
632 if ((etm_ctx
->portmode
& ETM_PORT_MODE_MASK
) == ETM_PORT_DEMUXED
)
634 if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) != ETM_PORT_8BIT
)
636 LOG_ERROR("ETB can't run in demultiplexed mode with a 4 or 16 bit port");
637 return ERROR_ETM_PORTMODE_NOT_SUPPORTED
;
639 etb_ctrl_value
|= 0x2;
642 if ((etm_ctx
->portmode
& ETM_PORT_MODE_MASK
) == ETM_PORT_MUXED
)
643 return ERROR_ETM_PORTMODE_NOT_SUPPORTED
;
645 trigger_count
= (etb
->ram_depth
* etm_ctx
->trigger_percent
) / 100;
647 etb_write_reg(&etb
->reg_cache
->reg_list
[ETB_TRIGGER_COUNTER
], trigger_count
);
648 etb_write_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_WRITE_POINTER
], 0x0);
649 etb_write_reg(&etb
->reg_cache
->reg_list
[ETB_CTRL
], etb_ctrl_value
);
650 jtag_execute_queue();
652 /* we're starting a new trace, initialize capture status */
653 etm_ctx
->capture_status
= TRACE_RUNNING
;
658 static int etb_stop_capture(etm_context_t
*etm_ctx
)
660 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
661 reg_t
*etb_ctrl_reg
= &etb
->reg_cache
->reg_list
[ETB_CTRL
];
663 etb_write_reg(etb_ctrl_reg
, 0x0);
664 jtag_execute_queue();
666 /* trace stopped, just clear running flag, but preserve others */
667 etm_ctx
->capture_status
&= ~TRACE_RUNNING
;
672 etm_capture_driver_t etb_capture_driver
=
675 .register_commands
= etb_register_commands
,
677 .status
= etb_status
,
678 .start_capture
= etb_start_capture
,
679 .stop_capture
= etb_stop_capture
,
680 .read_trace
= etb_read_trace
,
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)