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");
161 static void etb_getbuf(u8
*in
)
163 *((u32
*)in
)=buf_get_u32(in
, 0, 32);
167 static int etb_read_ram(etb_t
*etb
, u32
*data
, int num_frames
)
169 scan_field_t fields
[3];
172 jtag_add_end_state(TAP_IDLE
);
174 etb_set_instr(etb
, 0xc);
176 fields
[0].tap
= etb
->tap
;
177 fields
[0].num_bits
= 32;
178 fields
[0].out_value
= NULL
;
179 fields
[0].in_value
= NULL
;
181 fields
[1].tap
= etb
->tap
;
182 fields
[1].num_bits
= 7;
183 fields
[1].out_value
= malloc(1);
184 buf_set_u32(fields
[1].out_value
, 0, 7, 4);
185 fields
[1].in_value
= NULL
;
187 fields
[2].tap
= etb
->tap
;
188 fields
[2].num_bits
= 1;
189 fields
[2].out_value
= malloc(1);
190 buf_set_u32(fields
[2].out_value
, 0, 1, 0);
191 fields
[2].in_value
= NULL
;
193 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
195 for (i
= 0; i
< num_frames
; i
++)
197 /* ensure nR/W reamins set to read */
198 buf_set_u32(fields
[2].out_value
, 0, 1, 0);
200 /* address remains set to 0x4 (RAM data) until we read the last frame */
201 if (i
< num_frames
- 1)
202 buf_set_u32(fields
[1].out_value
, 0, 7, 4);
204 buf_set_u32(fields
[1].out_value
, 0, 7, 0);
206 fields
[0].in_value
= (u8
*)(data
+i
);
207 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
209 jtag_add_callback(etb_getbuf
, (u8
*)(data
+i
));
212 jtag_execute_queue();
214 free(fields
[1].out_value
);
215 free(fields
[2].out_value
);
220 int etb_read_reg_w_check(reg_t
*reg
, u8
* check_value
, u8
* check_mask
)
222 etb_reg_t
*etb_reg
= reg
->arch_info
;
223 u8 reg_addr
= etb_reg
->addr
& 0x7f;
224 scan_field_t fields
[3];
226 LOG_DEBUG("%i", etb_reg
->addr
);
228 jtag_add_end_state(TAP_IDLE
);
229 etb_scann(etb_reg
->etb
, 0x0);
230 etb_set_instr(etb_reg
->etb
, 0xc);
232 fields
[0].tap
= etb_reg
->etb
->tap
;
233 fields
[0].num_bits
= 32;
234 fields
[0].out_value
= reg
->value
;
235 fields
[0].in_value
= NULL
;
237 fields
[1].tap
= etb_reg
->etb
->tap
;
238 fields
[1].num_bits
= 7;
239 fields
[1].out_value
= malloc(1);
240 buf_set_u32(fields
[1].out_value
, 0, 7, reg_addr
);
241 fields
[1].in_value
= NULL
;
243 fields
[2].tap
= etb_reg
->etb
->tap
;
244 fields
[2].num_bits
= 1;
245 fields
[2].out_value
= malloc(1);
246 buf_set_u32(fields
[2].out_value
, 0, 1, 0);
247 fields
[2].in_value
= NULL
;
249 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
251 /* read the identification register in the second run, to make sure we
252 * don't read the ETB data register twice, skipping every second entry
254 buf_set_u32(fields
[1].out_value
, 0, 7, 0x0);
255 fields
[0].in_value
= reg
->value
;
257 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
259 jtag_check_value_mask(fields
+0, check_value
, check_mask
);
261 free(fields
[1].out_value
);
262 free(fields
[2].out_value
);
267 int etb_read_reg(reg_t
*reg
)
269 return etb_read_reg_w_check(reg
, NULL
, NULL
);
272 int etb_set_reg(reg_t
*reg
, u32 value
)
276 if ((retval
= etb_write_reg(reg
, value
)) != ERROR_OK
)
278 LOG_ERROR("BUG: error scheduling etm register write");
282 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
289 int etb_set_reg_w_exec(reg_t
*reg
, u8
*buf
)
293 etb_set_reg(reg
, buf_get_u32(buf
, 0, reg
->size
));
295 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
297 LOG_ERROR("register write failed");
303 int etb_write_reg(reg_t
*reg
, u32 value
)
305 etb_reg_t
*etb_reg
= reg
->arch_info
;
306 u8 reg_addr
= etb_reg
->addr
& 0x7f;
307 scan_field_t fields
[3];
309 LOG_DEBUG("%i: 0x%8.8x", etb_reg
->addr
, value
);
311 jtag_add_end_state(TAP_IDLE
);
312 etb_scann(etb_reg
->etb
, 0x0);
313 etb_set_instr(etb_reg
->etb
, 0xc);
315 fields
[0].tap
= etb_reg
->etb
->tap
;
316 fields
[0].num_bits
= 32;
317 fields
[0].out_value
= malloc(4);
318 buf_set_u32(fields
[0].out_value
, 0, 32, value
);
319 fields
[0].in_value
= NULL
;
321 fields
[1].tap
= etb_reg
->etb
->tap
;
322 fields
[1].num_bits
= 7;
323 fields
[1].out_value
= malloc(1);
324 buf_set_u32(fields
[1].out_value
, 0, 7, reg_addr
);
325 fields
[1].in_value
= NULL
;
327 fields
[2].tap
= etb_reg
->etb
->tap
;
328 fields
[2].num_bits
= 1;
329 fields
[2].out_value
= malloc(1);
330 buf_set_u32(fields
[2].out_value
, 0, 1, 1);
332 fields
[2].in_value
= NULL
;
334 free(fields
[0].out_value
);
335 free(fields
[1].out_value
);
336 free(fields
[2].out_value
);
341 int etb_store_reg(reg_t
*reg
)
343 return etb_write_reg(reg
, buf_get_u32(reg
->value
, 0, reg
->size
));
346 static int etb_register_commands(struct command_context_s
*cmd_ctx
)
350 etb_cmd
= register_command(cmd_ctx
, NULL
, "etb", NULL
, COMMAND_ANY
, "Embedded Trace Buffer");
352 register_command(cmd_ctx
, etb_cmd
, "config", handle_etb_config_command
, COMMAND_CONFIG
, NULL
);
357 static int handle_etb_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
361 armv4_5_common_t
*armv4_5
;
362 arm7_9_common_t
*arm7_9
;
366 return ERROR_COMMAND_SYNTAX_ERROR
;
369 target
= get_target_by_num(strtoul(args
[0], NULL
, 0));
373 LOG_ERROR("target number '%s' not defined", args
[0]);
377 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
379 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
383 tap
= jtag_TapByString( args
[1] );
386 command_print(cmd_ctx
, "Tap: %s does not exist", args
[1] );
392 etb_t
*etb
= malloc(sizeof(etb_t
));
394 arm7_9
->etm_ctx
->capture_driver_priv
= etb
;
397 etb
->cur_scan_chain
= 0xffffffff;
398 etb
->reg_cache
= NULL
;
404 LOG_ERROR("target has no ETM defined, ETB left unconfigured");
411 static int etb_init(etm_context_t
*etm_ctx
)
413 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
415 etb
->etm_ctx
= etm_ctx
;
417 /* identify ETB RAM depth and width */
418 etb_read_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_DEPTH
]);
419 etb_read_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_WIDTH
]);
420 jtag_execute_queue();
422 etb
->ram_depth
= buf_get_u32(etb
->reg_cache
->reg_list
[ETB_RAM_DEPTH
].value
, 0, 32);
423 etb
->ram_width
= buf_get_u32(etb
->reg_cache
->reg_list
[ETB_RAM_WIDTH
].value
, 0, 32);
428 static trace_status_t
etb_status(etm_context_t
*etm_ctx
)
430 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
432 etb
->etm_ctx
= etm_ctx
;
434 /* if tracing is currently idle, return this information */
435 if (etm_ctx
->capture_status
== TRACE_IDLE
)
437 return etm_ctx
->capture_status
;
439 else if (etm_ctx
->capture_status
& TRACE_RUNNING
)
441 reg_t
*etb_status_reg
= &etb
->reg_cache
->reg_list
[ETB_STATUS
];
442 int etb_timeout
= 100;
444 /* trace is running, check the ETB status flags */
445 etb_get_reg(etb_status_reg
);
447 /* check Full bit to identify an overflow */
448 if (buf_get_u32(etb_status_reg
->value
, 0, 1) == 1)
449 etm_ctx
->capture_status
|= TRACE_OVERFLOWED
;
451 /* check Triggered bit to identify trigger condition */
452 if (buf_get_u32(etb_status_reg
->value
, 1, 1) == 1)
453 etm_ctx
->capture_status
|= TRACE_TRIGGERED
;
455 /* check AcqComp to identify trace completion */
456 if (buf_get_u32(etb_status_reg
->value
, 2, 1) == 1)
458 while (etb_timeout
-- && (buf_get_u32(etb_status_reg
->value
, 3, 1) == 0))
460 /* wait for data formatter idle */
461 etb_get_reg(etb_status_reg
);
464 if (etb_timeout
== 0)
466 LOG_ERROR("AcqComp set but DFEmpty won't go high, ETB status: 0x%x",
467 buf_get_u32(etb_status_reg
->value
, 0, etb_status_reg
->size
));
470 if (!(etm_ctx
->capture_status
&& TRACE_TRIGGERED
))
472 LOG_ERROR("trace completed, but no trigger condition detected");
475 etm_ctx
->capture_status
&= ~TRACE_RUNNING
;
476 etm_ctx
->capture_status
|= TRACE_COMPLETED
;
480 return etm_ctx
->capture_status
;
483 static int etb_read_trace(etm_context_t
*etm_ctx
)
485 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
487 int num_frames
= etb
->ram_depth
;
488 u32
*trace_data
= NULL
;
491 etb_read_reg(&etb
->reg_cache
->reg_list
[ETB_STATUS
]);
492 etb_read_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_WRITE_POINTER
]);
493 jtag_execute_queue();
495 /* check if we overflowed, and adjust first frame of the trace accordingly
496 * if we didn't overflow, read only up to the frame that would be written next,
497 * i.e. don't read invalid entries
499 if (buf_get_u32(etb
->reg_cache
->reg_list
[ETB_STATUS
].value
, 0, 1))
501 first_frame
= buf_get_u32(etb
->reg_cache
->reg_list
[ETB_RAM_WRITE_POINTER
].value
, 0, 32);
505 num_frames
= buf_get_u32(etb
->reg_cache
->reg_list
[ETB_RAM_WRITE_POINTER
].value
, 0, 32);
508 etb_write_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_READ_POINTER
], first_frame
);
510 /* read data into temporary array for unpacking */
511 trace_data
= malloc(sizeof(u32
) * num_frames
);
512 etb_read_ram(etb
, trace_data
, num_frames
);
514 if (etm_ctx
->trace_depth
> 0)
516 free(etm_ctx
->trace_data
);
519 if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_4BIT
)
520 etm_ctx
->trace_depth
= num_frames
* 3;
521 else if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_8BIT
)
522 etm_ctx
->trace_depth
= num_frames
* 2;
524 etm_ctx
->trace_depth
= num_frames
;
526 etm_ctx
->trace_data
= malloc(sizeof(etmv1_trace_data_t
) * etm_ctx
->trace_depth
);
528 for (i
= 0, j
= 0; i
< num_frames
; i
++)
530 if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_4BIT
)
533 etm_ctx
->trace_data
[j
].pipestat
= trace_data
[i
] & 0x7;
534 etm_ctx
->trace_data
[j
].packet
= (trace_data
[i
] & 0x78) >> 3;
535 etm_ctx
->trace_data
[j
].flags
= 0;
536 if ((trace_data
[i
] & 0x80) >> 7)
538 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRACESYNC_CYCLE
;
540 if (etm_ctx
->trace_data
[j
].pipestat
== STAT_TR
)
542 etm_ctx
->trace_data
[j
].pipestat
= etm_ctx
->trace_data
[j
].packet
& 0x7;
543 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRIGGER_CYCLE
;
547 etm_ctx
->trace_data
[j
+1].pipestat
= (trace_data
[i
] & 0x100) >> 8;
548 etm_ctx
->trace_data
[j
+1].packet
= (trace_data
[i
] & 0x7800) >> 11;
549 etm_ctx
->trace_data
[j
+1].flags
= 0;
550 if ((trace_data
[i
] & 0x8000) >> 15)
552 etm_ctx
->trace_data
[j
+1].flags
|= ETMV1_TRACESYNC_CYCLE
;
554 if (etm_ctx
->trace_data
[j
+1].pipestat
== STAT_TR
)
556 etm_ctx
->trace_data
[j
+1].pipestat
= etm_ctx
->trace_data
[j
+1].packet
& 0x7;
557 etm_ctx
->trace_data
[j
+1].flags
|= ETMV1_TRIGGER_CYCLE
;
561 etm_ctx
->trace_data
[j
+2].pipestat
= (trace_data
[i
] & 0x10000) >> 16;
562 etm_ctx
->trace_data
[j
+2].packet
= (trace_data
[i
] & 0x780000) >> 19;
563 etm_ctx
->trace_data
[j
+2].flags
= 0;
564 if ((trace_data
[i
] & 0x800000) >> 23)
566 etm_ctx
->trace_data
[j
+2].flags
|= ETMV1_TRACESYNC_CYCLE
;
568 if (etm_ctx
->trace_data
[j
+2].pipestat
== STAT_TR
)
570 etm_ctx
->trace_data
[j
+2].pipestat
= etm_ctx
->trace_data
[j
+2].packet
& 0x7;
571 etm_ctx
->trace_data
[j
+2].flags
|= ETMV1_TRIGGER_CYCLE
;
576 else if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_8BIT
)
579 etm_ctx
->trace_data
[j
].pipestat
= trace_data
[i
] & 0x7;
580 etm_ctx
->trace_data
[j
].packet
= (trace_data
[i
] & 0x7f8) >> 3;
581 etm_ctx
->trace_data
[j
].flags
= 0;
582 if ((trace_data
[i
] & 0x800) >> 11)
584 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRACESYNC_CYCLE
;
586 if (etm_ctx
->trace_data
[j
].pipestat
== STAT_TR
)
588 etm_ctx
->trace_data
[j
].pipestat
= etm_ctx
->trace_data
[j
].packet
& 0x7;
589 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRIGGER_CYCLE
;
593 etm_ctx
->trace_data
[j
+1].pipestat
= (trace_data
[i
] & 0x7000) >> 12;
594 etm_ctx
->trace_data
[j
+1].packet
= (trace_data
[i
] & 0x7f8000) >> 15;
595 etm_ctx
->trace_data
[j
+1].flags
= 0;
596 if ((trace_data
[i
] & 0x800000) >> 23)
598 etm_ctx
->trace_data
[j
+1].flags
|= ETMV1_TRACESYNC_CYCLE
;
600 if (etm_ctx
->trace_data
[j
+1].pipestat
== STAT_TR
)
602 etm_ctx
->trace_data
[j
+1].pipestat
= etm_ctx
->trace_data
[j
+1].packet
& 0x7;
603 etm_ctx
->trace_data
[j
+1].flags
|= ETMV1_TRIGGER_CYCLE
;
611 etm_ctx
->trace_data
[j
].pipestat
= trace_data
[i
] & 0x7;
612 etm_ctx
->trace_data
[j
].packet
= (trace_data
[i
] & 0x7fff8) >> 3;
613 etm_ctx
->trace_data
[j
].flags
= 0;
614 if ((trace_data
[i
] & 0x80000) >> 19)
616 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRACESYNC_CYCLE
;
618 if (etm_ctx
->trace_data
[j
].pipestat
== STAT_TR
)
620 etm_ctx
->trace_data
[j
].pipestat
= etm_ctx
->trace_data
[j
].packet
& 0x7;
621 etm_ctx
->trace_data
[j
].flags
|= ETMV1_TRIGGER_CYCLE
;
633 static int etb_start_capture(etm_context_t
*etm_ctx
)
635 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
636 u32 etb_ctrl_value
= 0x1;
639 if ((etm_ctx
->portmode
& ETM_PORT_MODE_MASK
) == ETM_PORT_DEMUXED
)
641 if ((etm_ctx
->portmode
& ETM_PORT_WIDTH_MASK
) != ETM_PORT_8BIT
)
643 LOG_ERROR("ETB can't run in demultiplexed mode with a 4 or 16 bit port");
644 return ERROR_ETM_PORTMODE_NOT_SUPPORTED
;
646 etb_ctrl_value
|= 0x2;
649 if ((etm_ctx
->portmode
& ETM_PORT_MODE_MASK
) == ETM_PORT_MUXED
)
650 return ERROR_ETM_PORTMODE_NOT_SUPPORTED
;
652 trigger_count
= (etb
->ram_depth
* etm_ctx
->trigger_percent
) / 100;
654 etb_write_reg(&etb
->reg_cache
->reg_list
[ETB_TRIGGER_COUNTER
], trigger_count
);
655 etb_write_reg(&etb
->reg_cache
->reg_list
[ETB_RAM_WRITE_POINTER
], 0x0);
656 etb_write_reg(&etb
->reg_cache
->reg_list
[ETB_CTRL
], etb_ctrl_value
);
657 jtag_execute_queue();
659 /* we're starting a new trace, initialize capture status */
660 etm_ctx
->capture_status
= TRACE_RUNNING
;
665 static int etb_stop_capture(etm_context_t
*etm_ctx
)
667 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
668 reg_t
*etb_ctrl_reg
= &etb
->reg_cache
->reg_list
[ETB_CTRL
];
670 etb_write_reg(etb_ctrl_reg
, 0x0);
671 jtag_execute_queue();
673 /* trace stopped, just clear running flag, but preserve others */
674 etm_ctx
->capture_status
&= ~TRACE_RUNNING
;
679 etm_capture_driver_t etb_capture_driver
=
682 .register_commands
= etb_register_commands
,
684 .status
= etb_status
,
685 .start_capture
= etb_start_capture
,
686 .stop_capture
= etb_stop_capture
,
687 .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)