remove unecessary setting of deprecated fields to NULL
[openocd.git] / src / target / etm.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <string.h>
25
26 #include "etm.h"
27 #include "etb.h"
28
29 #include "armv4_5.h"
30 #include "arm7_9_common.h"
31 #include "arm_disassembler.h"
32 #include "arm_simulator.h"
33
34 #include "log.h"
35 #include "arm_jtag.h"
36 #include "types.h"
37 #include "binarybuffer.h"
38 #include "target.h"
39 #include "register.h"
40 #include "jtag.h"
41 #include "fileio.h"
42
43 #include <stdlib.h>
44
45 /* ETM register access functionality
46 *
47 */
48
49 #if 0
50 static bitfield_desc_t etm_comms_ctrl_bitfield_desc[] =
51 {
52 {"R", 1},
53 {"W", 1},
54 {"reserved", 26},
55 {"version", 4}
56 };
57 #endif
58
59 static int etm_reg_arch_info[] =
60 {
61 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
62 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
63 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
64 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
65 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
66 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
67 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
68 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
69 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
70 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
71 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
72 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
73 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67,
74 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
75 };
76
77 static int etm_reg_arch_size_info[] =
78 {
79 32, 32, 17, 8, 3, 9, 32, 16,
80 17, 26, 25, 8, 17, 32, 32, 17,
81 32, 32, 32, 32, 32, 32, 32, 32,
82 32, 32, 32, 32, 32, 32, 32, 32,
83 7, 7, 7, 7, 7, 7, 7, 7,
84 7, 7, 7, 7, 7, 7, 7, 7,
85 32, 32, 32, 32, 32, 32, 32, 32,
86 32, 32, 32, 32, 32, 32, 32, 32,
87 32, 32, 32, 32, 32, 32, 32, 32,
88 32, 32, 32, 32, 32, 32, 32, 32,
89 16, 16, 16, 16, 18, 18, 18, 18,
90 17, 17, 17, 17, 16, 16, 16, 16,
91 17, 17, 17, 17, 17, 17, 2,
92 17, 17, 17, 17, 32, 32, 32, 32
93 };
94
95 static char* etm_reg_list[] =
96 {
97 "ETM_CTRL",
98 "ETM_CONFIG",
99 "ETM_TRIG_EVENT",
100 "ETM_MMD_CTRL",
101 "ETM_STATUS",
102 "ETM_SYS_CONFIG",
103 "ETM_TRACE_RESOURCE_CTRL",
104 "ETM_TRACE_EN_CTRL2",
105 "ETM_TRACE_EN_EVENT",
106 "ETM_TRACE_EN_CTRL1",
107 "ETM_FIFOFULL_REGION",
108 "ETM_FIFOFULL_LEVEL",
109 "ETM_VIEWDATA_EVENT",
110 "ETM_VIEWDATA_CTRL1",
111 "ETM_VIEWDATA_CTRL2",
112 "ETM_VIEWDATA_CTRL3",
113 "ETM_ADDR_COMPARATOR_VALUE1",
114 "ETM_ADDR_COMPARATOR_VALUE2",
115 "ETM_ADDR_COMPARATOR_VALUE3",
116 "ETM_ADDR_COMPARATOR_VALUE4",
117 "ETM_ADDR_COMPARATOR_VALUE5",
118 "ETM_ADDR_COMPARATOR_VALUE6",
119 "ETM_ADDR_COMPARATOR_VALUE7",
120 "ETM_ADDR_COMPARATOR_VALUE8",
121 "ETM_ADDR_COMPARATOR_VALUE9",
122 "ETM_ADDR_COMPARATOR_VALUE10",
123 "ETM_ADDR_COMPARATOR_VALUE11",
124 "ETM_ADDR_COMPARATOR_VALUE12",
125 "ETM_ADDR_COMPARATOR_VALUE13",
126 "ETM_ADDR_COMPARATOR_VALUE14",
127 "ETM_ADDR_COMPARATOR_VALUE15",
128 "ETM_ADDR_COMPARATOR_VALUE16",
129 "ETM_ADDR_ACCESS_TYPE1",
130 "ETM_ADDR_ACCESS_TYPE2",
131 "ETM_ADDR_ACCESS_TYPE3",
132 "ETM_ADDR_ACCESS_TYPE4",
133 "ETM_ADDR_ACCESS_TYPE5",
134 "ETM_ADDR_ACCESS_TYPE6",
135 "ETM_ADDR_ACCESS_TYPE7",
136 "ETM_ADDR_ACCESS_TYPE8",
137 "ETM_ADDR_ACCESS_TYPE9",
138 "ETM_ADDR_ACCESS_TYPE10",
139 "ETM_ADDR_ACCESS_TYPE11",
140 "ETM_ADDR_ACCESS_TYPE12",
141 "ETM_ADDR_ACCESS_TYPE13",
142 "ETM_ADDR_ACCESS_TYPE14",
143 "ETM_ADDR_ACCESS_TYPE15",
144 "ETM_ADDR_ACCESS_TYPE16",
145 "ETM_DATA_COMPARATOR_VALUE1",
146 "ETM_DATA_COMPARATOR_VALUE2",
147 "ETM_DATA_COMPARATOR_VALUE3",
148 "ETM_DATA_COMPARATOR_VALUE4",
149 "ETM_DATA_COMPARATOR_VALUE5",
150 "ETM_DATA_COMPARATOR_VALUE6",
151 "ETM_DATA_COMPARATOR_VALUE7",
152 "ETM_DATA_COMPARATOR_VALUE8",
153 "ETM_DATA_COMPARATOR_VALUE9",
154 "ETM_DATA_COMPARATOR_VALUE10",
155 "ETM_DATA_COMPARATOR_VALUE11",
156 "ETM_DATA_COMPARATOR_VALUE12",
157 "ETM_DATA_COMPARATOR_VALUE13",
158 "ETM_DATA_COMPARATOR_VALUE14",
159 "ETM_DATA_COMPARATOR_VALUE15",
160 "ETM_DATA_COMPARATOR_VALUE16",
161 "ETM_DATA_COMPARATOR_MASK1",
162 "ETM_DATA_COMPARATOR_MASK2",
163 "ETM_DATA_COMPARATOR_MASK3",
164 "ETM_DATA_COMPARATOR_MASK4",
165 "ETM_DATA_COMPARATOR_MASK5",
166 "ETM_DATA_COMPARATOR_MASK6",
167 "ETM_DATA_COMPARATOR_MASK7",
168 "ETM_DATA_COMPARATOR_MASK8",
169 "ETM_DATA_COMPARATOR_MASK9",
170 "ETM_DATA_COMPARATOR_MASK10",
171 "ETM_DATA_COMPARATOR_MASK11",
172 "ETM_DATA_COMPARATOR_MASK12",
173 "ETM_DATA_COMPARATOR_MASK13",
174 "ETM_DATA_COMPARATOR_MASK14",
175 "ETM_DATA_COMPARATOR_MASK15",
176 "ETM_DATA_COMPARATOR_MASK16",
177 "ETM_COUNTER_INITAL_VALUE1",
178 "ETM_COUNTER_INITAL_VALUE2",
179 "ETM_COUNTER_INITAL_VALUE3",
180 "ETM_COUNTER_INITAL_VALUE4",
181 "ETM_COUNTER_ENABLE1",
182 "ETM_COUNTER_ENABLE2",
183 "ETM_COUNTER_ENABLE3",
184 "ETM_COUNTER_ENABLE4",
185 "ETM_COUNTER_RELOAD_VALUE1",
186 "ETM_COUNTER_RELOAD_VALUE2",
187 "ETM_COUNTER_RELOAD_VALUE3",
188 "ETM_COUNTER_RELOAD_VALUE4",
189 "ETM_COUNTER_VALUE1",
190 "ETM_COUNTER_VALUE2",
191 "ETM_COUNTER_VALUE3",
192 "ETM_COUNTER_VALUE4",
193 "ETM_SEQUENCER_CTRL1",
194 "ETM_SEQUENCER_CTRL2",
195 "ETM_SEQUENCER_CTRL3",
196 "ETM_SEQUENCER_CTRL4",
197 "ETM_SEQUENCER_CTRL5",
198 "ETM_SEQUENCER_CTRL6",
199 "ETM_SEQUENCER_STATE",
200 "ETM_EXTERNAL_OUTPUT1",
201 "ETM_EXTERNAL_OUTPUT2",
202 "ETM_EXTERNAL_OUTPUT3",
203 "ETM_EXTERNAL_OUTPUT4",
204 "ETM_CONTEXTID_COMPARATOR_VALUE1",
205 "ETM_CONTEXTID_COMPARATOR_VALUE2",
206 "ETM_CONTEXTID_COMPARATOR_VALUE3",
207 "ETM_CONTEXTID_COMPARATOR_MASK"
208 };
209
210 static int etm_reg_arch_type = -1;
211
212 static int etm_get_reg(reg_t *reg);
213
214 static command_t *etm_cmd = NULL;
215
216 reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_context_t *etm_ctx)
217 {
218 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
219 reg_t *reg_list = NULL;
220 etm_reg_t *arch_info = NULL;
221 int num_regs = sizeof(etm_reg_arch_info)/sizeof(int);
222 int i;
223
224 /* register a register arch-type for etm registers only once */
225 if (etm_reg_arch_type == -1)
226 etm_reg_arch_type = register_reg_arch_type(etm_get_reg, etm_set_reg_w_exec);
227
228 /* the actual registers are kept in two arrays */
229 reg_list = calloc(num_regs, sizeof(reg_t));
230 arch_info = calloc(num_regs, sizeof(etm_reg_t));
231
232 /* fill in values for the reg cache */
233 reg_cache->name = "etm registers";
234 reg_cache->next = NULL;
235 reg_cache->reg_list = reg_list;
236 reg_cache->num_regs = num_regs;
237
238 /* set up registers */
239 for (i = 0; i < num_regs; i++)
240 {
241 reg_list[i].name = etm_reg_list[i];
242 reg_list[i].size = 32;
243 reg_list[i].dirty = 0;
244 reg_list[i].valid = 0;
245 reg_list[i].bitfield_desc = NULL;
246 reg_list[i].num_bitfields = 0;
247 reg_list[i].value = calloc(1, 4);
248 reg_list[i].arch_info = &arch_info[i];
249 reg_list[i].arch_type = etm_reg_arch_type;
250 reg_list[i].size = etm_reg_arch_size_info[i];
251 arch_info[i].addr = etm_reg_arch_info[i];
252 arch_info[i].jtag_info = jtag_info;
253 }
254
255 /* the ETM might have an ETB connected */
256 if (strcmp(etm_ctx->capture_driver->name, "etb") == 0)
257 {
258 etb_t *etb = etm_ctx->capture_driver_priv;
259
260 if (!etb)
261 {
262 LOG_ERROR("etb selected as etm capture driver, but no ETB configured");
263 return ERROR_OK;
264 }
265
266 reg_cache->next = etb_build_reg_cache(etb);
267
268 etb->reg_cache = reg_cache->next;
269 }
270
271
272 return reg_cache;
273 }
274
275 int etm_setup(target_t *target)
276 {
277 int retval;
278 u32 etm_ctrl_value;
279 armv4_5_common_t *armv4_5 = target->arch_info;
280 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
281 etm_context_t *etm_ctx = arm7_9->etm_ctx;
282 reg_t *etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
283 /* initialize some ETM control register settings */
284 etm_get_reg(etm_ctrl_reg);
285 etm_ctrl_value = buf_get_u32(etm_ctrl_reg->value, 0, etm_ctrl_reg->size);
286
287 /* clear the ETM powerdown bit (0) */
288 etm_ctrl_value &= ~0x1;
289
290 /* configure port width (6:4), mode (17:16) and clocking (13) */
291 etm_ctrl_value = (etm_ctrl_value &
292 ~ETM_PORT_WIDTH_MASK & ~ETM_PORT_MODE_MASK & ~ETM_PORT_CLOCK_MASK)
293 | etm_ctx->portmode;
294
295 buf_set_u32(etm_ctrl_reg->value, 0, etm_ctrl_reg->size, etm_ctrl_value);
296 etm_store_reg(etm_ctrl_reg);
297
298 if ((retval=jtag_execute_queue())!=ERROR_OK)
299 return retval;
300
301 if ((retval=etm_ctx->capture_driver->init(etm_ctx)) != ERROR_OK)
302 {
303 LOG_ERROR("ETM capture driver initialization failed");
304 return retval;
305 }
306 return ERROR_OK;
307 }
308
309 int etm_get_reg(reg_t *reg)
310 {
311 int retval;
312 if ((retval = etm_read_reg(reg)) != ERROR_OK)
313 {
314 LOG_ERROR("BUG: error scheduling etm register read");
315 return retval;
316 }
317
318 if ((retval = jtag_execute_queue()) != ERROR_OK)
319 {
320 LOG_ERROR("register read failed");
321 return retval;
322 }
323
324 return ERROR_OK;
325 }
326
327 int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
328 {
329 etm_reg_t *etm_reg = reg->arch_info;
330 u8 reg_addr = etm_reg->addr & 0x7f;
331 scan_field_t fields[3];
332
333 LOG_DEBUG("%i", etm_reg->addr);
334
335 jtag_add_end_state(TAP_IDLE);
336 arm_jtag_scann(etm_reg->jtag_info, 0x6);
337 arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
338
339 fields[0].tap = etm_reg->jtag_info->tap;
340 fields[0].num_bits = 32;
341 fields[0].out_value = reg->value;
342
343 fields[0].in_value = NULL;
344
345
346 fields[0].in_handler = NULL;
347
348
349 fields[1].tap = etm_reg->jtag_info->tap;
350 fields[1].num_bits = 7;
351 fields[1].out_value = malloc(1);
352 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
353
354 fields[1].in_value = NULL;
355
356
357 fields[1].in_handler = NULL;
358
359
360 fields[2].tap = etm_reg->jtag_info->tap;
361 fields[2].num_bits = 1;
362 fields[2].out_value = malloc(1);
363 buf_set_u32(fields[2].out_value, 0, 1, 0);
364
365 fields[2].in_value = NULL;
366
367
368 fields[2].in_handler = NULL;
369
370
371 jtag_add_dr_scan(3, fields, TAP_INVALID);
372
373 fields[0].in_value = reg->value;
374 jtag_set_check_value(fields+0, check_value, check_mask, NULL);
375
376 jtag_add_dr_scan(3, fields, TAP_INVALID);
377
378 free(fields[1].out_value);
379 free(fields[2].out_value);
380
381 return ERROR_OK;
382 }
383
384 int etm_read_reg(reg_t *reg)
385 {
386 return etm_read_reg_w_check(reg, NULL, NULL);
387 }
388
389 int etm_set_reg(reg_t *reg, u32 value)
390 {
391 int retval;
392 if ((retval = etm_write_reg(reg, value)) != ERROR_OK)
393 {
394 LOG_ERROR("BUG: error scheduling etm register write");
395 return retval;
396 }
397
398 buf_set_u32(reg->value, 0, reg->size, value);
399 reg->valid = 1;
400 reg->dirty = 0;
401
402 return ERROR_OK;
403 }
404
405 int etm_set_reg_w_exec(reg_t *reg, u8 *buf)
406 {
407 int retval;
408 etm_set_reg(reg, buf_get_u32(buf, 0, reg->size));
409
410 if ((retval = jtag_execute_queue()) != ERROR_OK)
411 {
412 LOG_ERROR("register write failed");
413 return retval;
414 }
415 return ERROR_OK;
416 }
417
418 int etm_write_reg(reg_t *reg, u32 value)
419 {
420 etm_reg_t *etm_reg = reg->arch_info;
421 u8 reg_addr = etm_reg->addr & 0x7f;
422 scan_field_t fields[3];
423
424 LOG_DEBUG("%i: 0x%8.8x", etm_reg->addr, value);
425
426 jtag_add_end_state(TAP_IDLE);
427 arm_jtag_scann(etm_reg->jtag_info, 0x6);
428 arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
429
430 fields[0].tap = etm_reg->jtag_info->tap;
431 fields[0].num_bits = 32;
432 fields[0].out_value = malloc(4);
433 buf_set_u32(fields[0].out_value, 0, 32, value);
434
435 fields[0].in_value = NULL;
436
437
438 fields[0].in_handler = NULL;
439
440
441 fields[1].tap = etm_reg->jtag_info->tap;
442 fields[1].num_bits = 7;
443 fields[1].out_value = malloc(1);
444 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
445
446 fields[1].in_value = NULL;
447
448
449 fields[1].in_handler = NULL;
450
451
452 fields[2].tap = etm_reg->jtag_info->tap;
453 fields[2].num_bits = 1;
454 fields[2].out_value = malloc(1);
455 buf_set_u32(fields[2].out_value, 0, 1, 1);
456
457 fields[2].in_value = NULL;
458
459
460 fields[2].in_handler = NULL;
461
462
463 jtag_add_dr_scan(3, fields, TAP_INVALID);
464
465 free(fields[0].out_value);
466 free(fields[1].out_value);
467 free(fields[2].out_value);
468
469 return ERROR_OK;
470 }
471
472 int etm_store_reg(reg_t *reg)
473 {
474 return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
475 }
476
477 /* ETM trace analysis functionality
478 *
479 */
480 extern etm_capture_driver_t etm_dummy_capture_driver;
481 #if BUILD_OOCD_TRACE == 1
482 extern etm_capture_driver_t oocd_trace_capture_driver;
483 #endif
484
485 static etm_capture_driver_t *etm_capture_drivers[] =
486 {
487 &etb_capture_driver,
488 &etm_dummy_capture_driver,
489 #if BUILD_OOCD_TRACE == 1
490 &oocd_trace_capture_driver,
491 #endif
492 NULL
493 };
494
495 char *etmv1v1_branch_reason_strings[] =
496 {
497 "normal PC change",
498 "tracing enabled",
499 "trace restarted after overflow",
500 "exit from debug",
501 "periodic synchronization",
502 "reserved",
503 "reserved",
504 "reserved",
505 };
506
507 static int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instruction)
508 {
509 int i;
510 int section = -1;
511 u32 size_read;
512 u32 opcode;
513 int retval;
514
515 if (!ctx->image)
516 return ERROR_TRACE_IMAGE_UNAVAILABLE;
517
518 /* search for the section the current instruction belongs to */
519 for (i = 0; i < ctx->image->num_sections; i++)
520 {
521 if ((ctx->image->sections[i].base_address <= ctx->current_pc) &&
522 (ctx->image->sections[i].base_address + ctx->image->sections[i].size > ctx->current_pc))
523 {
524 section = i;
525 break;
526 }
527 }
528
529 if (section == -1)
530 {
531 /* current instruction couldn't be found in the image */
532 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
533 }
534
535 if (ctx->core_state == ARMV4_5_STATE_ARM)
536 {
537 u8 buf[4];
538 if ((retval = image_read_section(ctx->image, section,
539 ctx->current_pc - ctx->image->sections[section].base_address,
540 4, buf, &size_read)) != ERROR_OK)
541 {
542 LOG_ERROR("error while reading instruction: %i", retval);
543 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
544 }
545 opcode = target_buffer_get_u32(ctx->target, buf);
546 arm_evaluate_opcode(opcode, ctx->current_pc, instruction);
547 }
548 else if (ctx->core_state == ARMV4_5_STATE_THUMB)
549 {
550 u8 buf[2];
551 if ((retval = image_read_section(ctx->image, section,
552 ctx->current_pc - ctx->image->sections[section].base_address,
553 2, buf, &size_read)) != ERROR_OK)
554 {
555 LOG_ERROR("error while reading instruction: %i", retval);
556 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
557 }
558 opcode = target_buffer_get_u16(ctx->target, buf);
559 thumb_evaluate_opcode(opcode, ctx->current_pc, instruction);
560 }
561 else if (ctx->core_state == ARMV4_5_STATE_JAZELLE)
562 {
563 LOG_ERROR("BUG: tracing of jazelle code not supported");
564 exit(-1);
565 }
566 else
567 {
568 LOG_ERROR("BUG: unknown core state encountered");
569 exit(-1);
570 }
571
572 return ERROR_OK;
573 }
574
575 static int etmv1_next_packet(etm_context_t *ctx, u8 *packet, int apo)
576 {
577 while (ctx->data_index < ctx->trace_depth)
578 {
579 /* if the caller specified an address packet offset, skip until the
580 * we reach the n-th cycle marked with tracesync */
581 if (apo > 0)
582 {
583 if (ctx->trace_data[ctx->data_index].flags & ETMV1_TRACESYNC_CYCLE)
584 apo--;
585
586 if (apo > 0)
587 {
588 ctx->data_index++;
589 ctx->data_half = 0;
590 }
591 continue;
592 }
593
594 /* no tracedata output during a TD cycle
595 * or in a trigger cycle */
596 if ((ctx->trace_data[ctx->data_index].pipestat == STAT_TD)
597 || (ctx->trace_data[ctx->data_index].flags & ETMV1_TRIGGER_CYCLE))
598 {
599 ctx->data_index++;
600 ctx->data_half = 0;
601 continue;
602 }
603
604 if ((ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_16BIT)
605 {
606 if (ctx->data_half == 0)
607 {
608 *packet = ctx->trace_data[ctx->data_index].packet & 0xff;
609 ctx->data_half = 1;
610 }
611 else
612 {
613 *packet = (ctx->trace_data[ctx->data_index].packet & 0xff00) >> 8;
614 ctx->data_half = 0;
615 ctx->data_index++;
616 }
617 }
618 else if ((ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT)
619 {
620 *packet = ctx->trace_data[ctx->data_index].packet & 0xff;
621 ctx->data_index++;
622 }
623 else
624 {
625 /* on a 4-bit port, a packet will be output during two consecutive cycles */
626 if (ctx->data_index > (ctx->trace_depth - 2))
627 return -1;
628
629 *packet = ctx->trace_data[ctx->data_index].packet & 0xf;
630 *packet |= (ctx->trace_data[ctx->data_index + 1].packet & 0xf) << 4;
631 ctx->data_index += 2;
632 }
633
634 return 0;
635 }
636
637 return -1;
638 }
639
640 static int etmv1_branch_address(etm_context_t *ctx)
641 {
642 int retval;
643 u8 packet;
644 int shift = 0;
645 int apo;
646 u32 i;
647
648 /* quit analysis if less than two cycles are left in the trace
649 * because we can't extract the APO */
650 if (ctx->data_index > (ctx->trace_depth - 2))
651 return -1;
652
653 /* a BE could be output during an APO cycle, skip the current
654 * and continue with the new one */
655 if (ctx->trace_data[ctx->pipe_index + 1].pipestat & 0x4)
656 return 1;
657 if (ctx->trace_data[ctx->pipe_index + 2].pipestat & 0x4)
658 return 2;
659
660 /* address packet offset encoded in the next two cycles' pipestat bits */
661 apo = ctx->trace_data[ctx->pipe_index + 1].pipestat & 0x3;
662 apo |= (ctx->trace_data[ctx->pipe_index + 2].pipestat & 0x3) << 2;
663
664 /* count number of tracesync cycles between current pipe_index and data_index
665 * i.e. the number of tracesyncs that data_index already passed by
666 * to subtract them from the APO */
667 for (i = ctx->pipe_index; i < ctx->data_index; i++)
668 {
669 if (ctx->trace_data[ctx->pipe_index + 1].pipestat & ETMV1_TRACESYNC_CYCLE)
670 apo--;
671 }
672
673 /* extract up to four 7-bit packets */
674 do {
675 if ((retval = etmv1_next_packet(ctx, &packet, (shift == 0) ? apo + 1 : 0)) != 0)
676 return -1;
677 ctx->last_branch &= ~(0x7f << shift);
678 ctx->last_branch |= (packet & 0x7f) << shift;
679 shift += 7;
680 } while ((packet & 0x80) && (shift < 28));
681
682 /* one last packet holding 4 bits of the address, plus the branch reason code */
683 if ((shift == 28) && (packet & 0x80))
684 {
685 if ((retval = etmv1_next_packet(ctx, &packet, 0)) != 0)
686 return -1;
687 ctx->last_branch &= 0x0fffffff;
688 ctx->last_branch |= (packet & 0x0f) << 28;
689 ctx->last_branch_reason = (packet & 0x70) >> 4;
690 shift += 4;
691 }
692 else
693 {
694 ctx->last_branch_reason = 0;
695 }
696
697 if (shift == 32)
698 {
699 ctx->pc_ok = 1;
700 }
701
702 /* if a full address was output, we might have branched into Jazelle state */
703 if ((shift == 32) && (packet & 0x80))
704 {
705 ctx->core_state = ARMV4_5_STATE_JAZELLE;
706 }
707 else
708 {
709 /* if we didn't branch into Jazelle state, the current processor state is
710 * encoded in bit 0 of the branch target address */
711 if (ctx->last_branch & 0x1)
712 {
713 ctx->core_state = ARMV4_5_STATE_THUMB;
714 ctx->last_branch &= ~0x1;
715 }
716 else
717 {
718 ctx->core_state = ARMV4_5_STATE_ARM;
719 ctx->last_branch &= ~0x3;
720 }
721 }
722
723 return 0;
724 }
725
726 static int etmv1_data(etm_context_t *ctx, int size, u32 *data)
727 {
728 int j;
729 u8 buf[4];
730 int retval;
731
732 for (j = 0; j < size; j++)
733 {
734 if ((retval = etmv1_next_packet(ctx, &buf[j], 0)) != 0)
735 return -1;
736 }
737
738 if (size == 8)
739 {
740 LOG_ERROR("TODO: add support for 64-bit values");
741 return -1;
742 }
743 else if (size == 4)
744 *data = target_buffer_get_u32(ctx->target, buf);
745 else if (size == 2)
746 *data = target_buffer_get_u16(ctx->target, buf);
747 else if (size == 1)
748 *data = buf[0];
749 else
750 return -1;
751
752 return 0;
753 }
754
755 static int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
756 {
757 int retval;
758 arm_instruction_t instruction;
759
760 /* read the trace data if it wasn't read already */
761 if (ctx->trace_depth == 0)
762 ctx->capture_driver->read_trace(ctx);
763
764 /* start at the beginning of the captured trace */
765 ctx->pipe_index = 0;
766 ctx->data_index = 0;
767 ctx->data_half = 0;
768
769 /* neither the PC nor the data pointer are valid */
770 ctx->pc_ok = 0;
771 ctx->ptr_ok = 0;
772
773 while (ctx->pipe_index < ctx->trace_depth)
774 {
775 u8 pipestat = ctx->trace_data[ctx->pipe_index].pipestat;
776 u32 next_pc = ctx->current_pc;
777 u32 old_data_index = ctx->data_index;
778 u32 old_data_half = ctx->data_half;
779 u32 old_index = ctx->pipe_index;
780 u32 last_instruction = ctx->last_instruction;
781 u32 cycles = 0;
782 int current_pc_ok = ctx->pc_ok;
783
784 if (ctx->trace_data[ctx->pipe_index].flags & ETMV1_TRIGGER_CYCLE)
785 {
786 command_print(cmd_ctx, "--- trigger ---");
787 }
788
789 /* instructions execute in IE/D or BE/D cycles */
790 if ((pipestat == STAT_IE) || (pipestat == STAT_ID))
791 ctx->last_instruction = ctx->pipe_index;
792
793 /* if we don't have a valid pc skip until we reach an indirect branch */
794 if ((!ctx->pc_ok) && (pipestat != STAT_BE))
795 {
796 ctx->pipe_index++;
797 continue;
798 }
799
800 /* any indirect branch could have interrupted instruction flow
801 * - the branch reason code could indicate a trace discontinuity
802 * - a branch to the exception vectors indicates an exception
803 */
804 if ((pipestat == STAT_BE) || (pipestat == STAT_BD))
805 {
806 /* backup current data index, to be able to consume the branch address
807 * before examining data address and values
808 */
809 old_data_index = ctx->data_index;
810 old_data_half = ctx->data_half;
811
812 ctx->last_instruction = ctx->pipe_index;
813
814 if ((retval = etmv1_branch_address(ctx)) != 0)
815 {
816 /* negative return value from etmv1_branch_address means we ran out of packets,
817 * quit analysing the trace */
818 if (retval < 0)
819 break;
820
821 /* a positive return values means the current branch was abandoned,
822 * and a new branch was encountered in cycle ctx->pipe_index + retval;
823 */
824 LOG_WARNING("abandoned branch encountered, correctnes of analysis uncertain");
825 ctx->pipe_index += retval;
826 continue;
827 }
828
829 /* skip over APO cycles */
830 ctx->pipe_index += 2;
831
832 switch (ctx->last_branch_reason)
833 {
834 case 0x0: /* normal PC change */
835 next_pc = ctx->last_branch;
836 break;
837 case 0x1: /* tracing enabled */
838 command_print(cmd_ctx, "--- tracing enabled at 0x%8.8x ---", ctx->last_branch);
839 ctx->current_pc = ctx->last_branch;
840 ctx->pipe_index++;
841 continue;
842 break;
843 case 0x2: /* trace restarted after FIFO overflow */
844 command_print(cmd_ctx, "--- trace restarted after FIFO overflow at 0x%8.8x ---", ctx->last_branch);
845 ctx->current_pc = ctx->last_branch;
846 ctx->pipe_index++;
847 continue;
848 break;
849 case 0x3: /* exit from debug state */
850 command_print(cmd_ctx, "--- exit from debug state at 0x%8.8x ---", ctx->last_branch);
851 ctx->current_pc = ctx->last_branch;
852 ctx->pipe_index++;
853 continue;
854 break;
855 case 0x4: /* periodic synchronization point */
856 next_pc = ctx->last_branch;
857 /* if we had no valid PC prior to this synchronization point,
858 * we have to move on with the next trace cycle
859 */
860 if (!current_pc_ok)
861 {
862 command_print(cmd_ctx, "--- periodic synchronization point at 0x%8.8x ---", next_pc);
863 ctx->current_pc = next_pc;
864 ctx->pipe_index++;
865 continue;
866 }
867 break;
868 default: /* reserved */
869 LOG_ERROR("BUG: branch reason code 0x%x is reserved", ctx->last_branch_reason);
870 exit(-1);
871 break;
872 }
873
874 /* if we got here the branch was a normal PC change
875 * (or a periodic synchronization point, which means the same for that matter)
876 * if we didn't accquire a complete PC continue with the next cycle
877 */
878 if (!ctx->pc_ok)
879 continue;
880
881 /* indirect branch to the exception vector means an exception occured */
882 if ((ctx->last_branch <= 0x20)
883 || ((ctx->last_branch >= 0xffff0000) && (ctx->last_branch <= 0xffff0020)))
884 {
885 if ((ctx->last_branch & 0xff) == 0x10)
886 {
887 command_print(cmd_ctx, "data abort");
888 }
889 else
890 {
891 command_print(cmd_ctx, "exception vector 0x%2.2x", ctx->last_branch);
892 ctx->current_pc = ctx->last_branch;
893 ctx->pipe_index++;
894 continue;
895 }
896 }
897 }
898
899 /* an instruction was executed (or not, depending on the condition flags)
900 * retrieve it from the image for displaying */
901 if (ctx->pc_ok && (pipestat != STAT_WT) && (pipestat != STAT_TD) &&
902 !(((pipestat == STAT_BE) || (pipestat == STAT_BD)) &&
903 ((ctx->last_branch_reason != 0x0) && (ctx->last_branch_reason != 0x4))))
904 {
905 if ((retval = etm_read_instruction(ctx, &instruction)) != ERROR_OK)
906 {
907 /* can't continue tracing with no image available */
908 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
909 {
910 return retval;
911 }
912 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
913 {
914 /* TODO: handle incomplete images
915 * for now we just quit the analsysis*/
916 return retval;
917 }
918 }
919
920 cycles = old_index - last_instruction;
921 }
922
923 if ((pipestat == STAT_ID) || (pipestat == STAT_BD))
924 {
925 u32 new_data_index = ctx->data_index;
926 u32 new_data_half = ctx->data_half;
927
928 /* in case of a branch with data, the branch target address was consumed before
929 * we temporarily go back to the saved data index */
930 if (pipestat == STAT_BD)
931 {
932 ctx->data_index = old_data_index;
933 ctx->data_half = old_data_half;
934 }
935
936 if (ctx->tracemode & ETMV1_TRACE_ADDR)
937 {
938 u8 packet;
939 int shift = 0;
940
941 do {
942 if ((retval = etmv1_next_packet(ctx, &packet, 0)) != 0)
943 return ERROR_ETM_ANALYSIS_FAILED;
944 ctx->last_ptr &= ~(0x7f << shift);
945 ctx->last_ptr |= (packet & 0x7f) << shift;
946 shift += 7;
947 } while ((packet & 0x80) && (shift < 32));
948
949 if (shift >= 32)
950 ctx->ptr_ok = 1;
951
952 if (ctx->ptr_ok)
953 {
954 command_print(cmd_ctx, "address: 0x%8.8x", ctx->last_ptr);
955 }
956 }
957
958 if (ctx->tracemode & ETMV1_TRACE_DATA)
959 {
960 if ((instruction.type == ARM_LDM) || (instruction.type == ARM_STM))
961 {
962 int i;
963 for (i = 0; i < 16; i++)
964 {
965 if (instruction.info.load_store_multiple.register_list & (1 << i))
966 {
967 u32 data;
968 if (etmv1_data(ctx, 4, &data) != 0)
969 return ERROR_ETM_ANALYSIS_FAILED;
970 command_print(cmd_ctx, "data: 0x%8.8x", data);
971 }
972 }
973 }
974 else if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_STRH))
975 {
976 u32 data;
977 if (etmv1_data(ctx, arm_access_size(&instruction), &data) != 0)
978 return ERROR_ETM_ANALYSIS_FAILED;
979 command_print(cmd_ctx, "data: 0x%8.8x", data);
980 }
981 }
982
983 /* restore data index after consuming BD address and data */
984 if (pipestat == STAT_BD)
985 {
986 ctx->data_index = new_data_index;
987 ctx->data_half = new_data_half;
988 }
989 }
990
991 /* adjust PC */
992 if ((pipestat == STAT_IE) || (pipestat == STAT_ID))
993 {
994 if (((instruction.type == ARM_B) ||
995 (instruction.type == ARM_BL) ||
996 (instruction.type == ARM_BLX)) &&
997 (instruction.info.b_bl_bx_blx.target_address != 0xffffffff))
998 {
999 next_pc = instruction.info.b_bl_bx_blx.target_address;
1000 }
1001 else
1002 {
1003 next_pc += (ctx->core_state == ARMV4_5_STATE_ARM) ? 4 : 2;
1004 }
1005 }
1006 else if (pipestat == STAT_IN)
1007 {
1008 next_pc += (ctx->core_state == ARMV4_5_STATE_ARM) ? 4 : 2;
1009 }
1010
1011 if ((pipestat != STAT_TD) && (pipestat != STAT_WT))
1012 {
1013 char cycles_text[32] = "";
1014
1015 /* if the trace was captured with cycle accurate tracing enabled,
1016 * output the number of cycles since the last executed instruction
1017 */
1018 if (ctx->tracemode & ETMV1_CYCLE_ACCURATE)
1019 {
1020 snprintf(cycles_text, 32, " (%i %s)",
1021 cycles,
1022 (cycles == 1) ? "cycle" : "cycles");
1023 }
1024
1025 command_print(cmd_ctx, "%s%s%s",
1026 instruction.text,
1027 (pipestat == STAT_IN) ? " (not executed)" : "",
1028 cycles_text);
1029
1030 ctx->current_pc = next_pc;
1031
1032 /* packets for an instruction don't start on or before the preceding
1033 * functional pipestat (i.e. other than WT or TD)
1034 */
1035 if (ctx->data_index <= ctx->pipe_index)
1036 {
1037 ctx->data_index = ctx->pipe_index + 1;
1038 ctx->data_half = 0;
1039 }
1040 }
1041
1042 ctx->pipe_index += 1;
1043 }
1044
1045 return ERROR_OK;
1046 }
1047
1048 static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1049 {
1050 target_t *target;
1051 armv4_5_common_t *armv4_5;
1052 arm7_9_common_t *arm7_9;
1053 etmv1_tracemode_t tracemode;
1054
1055 target = get_current_target(cmd_ctx);
1056
1057 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1058 {
1059 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1060 return ERROR_OK;
1061 }
1062
1063 if (!arm7_9->etm_ctx)
1064 {
1065 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1066 return ERROR_OK;
1067 }
1068
1069 tracemode = arm7_9->etm_ctx->tracemode;
1070
1071 if (argc == 4)
1072 {
1073 if (strcmp(args[0], "none") == 0)
1074 {
1075 tracemode = ETMV1_TRACE_NONE;
1076 }
1077 else if (strcmp(args[0], "data") == 0)
1078 {
1079 tracemode = ETMV1_TRACE_DATA;
1080 }
1081 else if (strcmp(args[0], "address") == 0)
1082 {
1083 tracemode = ETMV1_TRACE_ADDR;
1084 }
1085 else if (strcmp(args[0], "all") == 0)
1086 {
1087 tracemode = ETMV1_TRACE_DATA | ETMV1_TRACE_ADDR;
1088 }
1089 else
1090 {
1091 command_print(cmd_ctx, "invalid option '%s'", args[0]);
1092 return ERROR_OK;
1093 }
1094
1095 switch (strtol(args[1], NULL, 0))
1096 {
1097 case 0:
1098 tracemode |= ETMV1_CONTEXTID_NONE;
1099 break;
1100 case 8:
1101 tracemode |= ETMV1_CONTEXTID_8;
1102 break;
1103 case 16:
1104 tracemode |= ETMV1_CONTEXTID_16;
1105 break;
1106 case 32:
1107 tracemode |= ETMV1_CONTEXTID_32;
1108 break;
1109 default:
1110 command_print(cmd_ctx, "invalid option '%s'", args[1]);
1111 return ERROR_OK;
1112 }
1113
1114 if (strcmp(args[2], "enable") == 0)
1115 {
1116 tracemode |= ETMV1_CYCLE_ACCURATE;
1117 }
1118 else if (strcmp(args[2], "disable") == 0)
1119 {
1120 tracemode |= 0;
1121 }
1122 else
1123 {
1124 command_print(cmd_ctx, "invalid option '%s'", args[2]);
1125 return ERROR_OK;
1126 }
1127
1128 if (strcmp(args[3], "enable") == 0)
1129 {
1130 tracemode |= ETMV1_BRANCH_OUTPUT;
1131 }
1132 else if (strcmp(args[3], "disable") == 0)
1133 {
1134 tracemode |= 0;
1135 }
1136 else
1137 {
1138 command_print(cmd_ctx, "invalid option '%s'", args[2]);
1139 return ERROR_OK;
1140 }
1141 }
1142 else if (argc != 0)
1143 {
1144 command_print(cmd_ctx, "usage: configure trace mode <none|data|address|all> <context id bits> <cycle accurate> <branch output>");
1145 return ERROR_OK;
1146 }
1147
1148 command_print(cmd_ctx, "current tracemode configuration:");
1149
1150 switch (tracemode & ETMV1_TRACE_MASK)
1151 {
1152 case ETMV1_TRACE_NONE:
1153 command_print(cmd_ctx, "data tracing: none");
1154 break;
1155 case ETMV1_TRACE_DATA:
1156 command_print(cmd_ctx, "data tracing: data only");
1157 break;
1158 case ETMV1_TRACE_ADDR:
1159 command_print(cmd_ctx, "data tracing: address only");
1160 break;
1161 case ETMV1_TRACE_DATA | ETMV1_TRACE_ADDR:
1162 command_print(cmd_ctx, "data tracing: address and data");
1163 break;
1164 }
1165
1166 switch (tracemode & ETMV1_CONTEXTID_MASK)
1167 {
1168 case ETMV1_CONTEXTID_NONE:
1169 command_print(cmd_ctx, "contextid tracing: none");
1170 break;
1171 case ETMV1_CONTEXTID_8:
1172 command_print(cmd_ctx, "contextid tracing: 8 bit");
1173 break;
1174 case ETMV1_CONTEXTID_16:
1175 command_print(cmd_ctx, "contextid tracing: 16 bit");
1176 break;
1177 case ETMV1_CONTEXTID_32:
1178 command_print(cmd_ctx, "contextid tracing: 32 bit");
1179 break;
1180 }
1181
1182 if (tracemode & ETMV1_CYCLE_ACCURATE)
1183 {
1184 command_print(cmd_ctx, "cycle-accurate tracing enabled");
1185 }
1186 else
1187 {
1188 command_print(cmd_ctx, "cycle-accurate tracing disabled");
1189 }
1190
1191 if (tracemode & ETMV1_BRANCH_OUTPUT)
1192 {
1193 command_print(cmd_ctx, "full branch address output enabled");
1194 }
1195 else
1196 {
1197 command_print(cmd_ctx, "full branch address output disabled");
1198 }
1199
1200 /* only update ETM_CTRL register if tracemode changed */
1201 if (arm7_9->etm_ctx->tracemode != tracemode)
1202 {
1203 reg_t *etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
1204
1205 etm_get_reg(etm_ctrl_reg);
1206
1207 buf_set_u32(etm_ctrl_reg->value, 2, 2, tracemode & ETMV1_TRACE_MASK);
1208 buf_set_u32(etm_ctrl_reg->value, 14, 2, (tracemode & ETMV1_CONTEXTID_MASK) >> 4);
1209 buf_set_u32(etm_ctrl_reg->value, 12, 1, (tracemode & ETMV1_CYCLE_ACCURATE) >> 8);
1210 buf_set_u32(etm_ctrl_reg->value, 8, 1, (tracemode & ETMV1_BRANCH_OUTPUT) >> 9);
1211 etm_store_reg(etm_ctrl_reg);
1212
1213 arm7_9->etm_ctx->tracemode = tracemode;
1214
1215 /* invalidate old trace data */
1216 arm7_9->etm_ctx->capture_status = TRACE_IDLE;
1217 if (arm7_9->etm_ctx->trace_depth > 0)
1218 {
1219 free(arm7_9->etm_ctx->trace_data);
1220 arm7_9->etm_ctx->trace_data = NULL;
1221 }
1222 arm7_9->etm_ctx->trace_depth = 0;
1223 }
1224
1225 return ERROR_OK;
1226 }
1227
1228 static int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1229 {
1230 target_t *target;
1231 armv4_5_common_t *armv4_5;
1232 arm7_9_common_t *arm7_9;
1233 etm_portmode_t portmode = 0x0;
1234 etm_context_t *etm_ctx = malloc(sizeof(etm_context_t));
1235 int i;
1236
1237 if (argc != 5)
1238 {
1239 return ERROR_COMMAND_SYNTAX_ERROR;
1240 }
1241
1242 target = get_target_by_num(strtoul(args[0], NULL, 0));
1243
1244 if (!target)
1245 {
1246 LOG_ERROR("target number '%s' not defined", args[0]);
1247 return ERROR_FAIL;
1248 }
1249
1250 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1251 {
1252 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1253 return ERROR_FAIL;
1254 }
1255
1256 switch (strtoul(args[1], NULL, 0))
1257 {
1258 case 4:
1259 portmode |= ETM_PORT_4BIT;
1260 break;
1261 case 8:
1262 portmode |= ETM_PORT_8BIT;
1263 break;
1264 case 16:
1265 portmode |= ETM_PORT_16BIT;
1266 break;
1267 default:
1268 command_print(cmd_ctx, "unsupported ETM port width '%s', must be 4, 8 or 16", args[1]);
1269 return ERROR_FAIL;
1270 }
1271
1272 if (strcmp("normal", args[2]) == 0)
1273 {
1274 portmode |= ETM_PORT_NORMAL;
1275 }
1276 else if (strcmp("multiplexed", args[2]) == 0)
1277 {
1278 portmode |= ETM_PORT_MUXED;
1279 }
1280 else if (strcmp("demultiplexed", args[2]) == 0)
1281 {
1282 portmode |= ETM_PORT_DEMUXED;
1283 }
1284 else
1285 {
1286 command_print(cmd_ctx, "unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'", args[2]);
1287 return ERROR_FAIL;
1288 }
1289
1290 if (strcmp("half", args[3]) == 0)
1291 {
1292 portmode |= ETM_PORT_HALF_CLOCK;
1293 }
1294 else if (strcmp("full", args[3]) == 0)
1295 {
1296 portmode |= ETM_PORT_FULL_CLOCK;
1297 }
1298 else
1299 {
1300 command_print(cmd_ctx, "unsupported ETM port clocking '%s', must be 'full' or 'half'", args[3]);
1301 return ERROR_FAIL;
1302 }
1303
1304 for (i=0; etm_capture_drivers[i]; i++)
1305 {
1306 if (strcmp(args[4], etm_capture_drivers[i]->name) == 0)
1307 {
1308 int retval;
1309 if ((retval=etm_capture_drivers[i]->register_commands(cmd_ctx)) != ERROR_OK)
1310 {
1311 free(etm_ctx);
1312 return retval;
1313 }
1314
1315 etm_ctx->capture_driver = etm_capture_drivers[i];
1316
1317 break;
1318 }
1319 }
1320
1321 if (!etm_capture_drivers[i])
1322 {
1323 /* no supported capture driver found, don't register an ETM */
1324 free(etm_ctx);
1325 LOG_ERROR("trace capture driver '%s' not found", args[4]);
1326 return ERROR_FAIL;
1327 }
1328
1329 etm_ctx->target = target;
1330 etm_ctx->trigger_percent = 50;
1331 etm_ctx->trace_data = NULL;
1332 etm_ctx->trace_depth = 0;
1333 etm_ctx->portmode = portmode;
1334 etm_ctx->tracemode = 0x0;
1335 etm_ctx->core_state = ARMV4_5_STATE_ARM;
1336 etm_ctx->image = NULL;
1337 etm_ctx->pipe_index = 0;
1338 etm_ctx->data_index = 0;
1339 etm_ctx->current_pc = 0x0;
1340 etm_ctx->pc_ok = 0;
1341 etm_ctx->last_branch = 0x0;
1342 etm_ctx->last_branch_reason = 0x0;
1343 etm_ctx->last_ptr = 0x0;
1344 etm_ctx->ptr_ok = 0x0;
1345 etm_ctx->context_id = 0x0;
1346 etm_ctx->last_instruction = 0;
1347
1348 arm7_9->etm_ctx = etm_ctx;
1349
1350 return etm_register_user_commands(cmd_ctx);
1351 }
1352
1353 int handle_etm_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1354 {
1355 target_t *target;
1356 armv4_5_common_t *armv4_5;
1357 arm7_9_common_t *arm7_9;
1358 reg_t *etm_config_reg;
1359 reg_t *etm_sys_config_reg;
1360
1361 int max_port_size;
1362
1363 target = get_current_target(cmd_ctx);
1364
1365 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1366 {
1367 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1368 return ERROR_OK;
1369 }
1370
1371 if (!arm7_9->etm_ctx)
1372 {
1373 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1374 return ERROR_OK;
1375 }
1376
1377 etm_config_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CONFIG];
1378 etm_sys_config_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_SYS_CONFIG];
1379
1380 etm_get_reg(etm_config_reg);
1381 command_print(cmd_ctx, "pairs of address comparators: %i", buf_get_u32(etm_config_reg->value, 0, 4));
1382 command_print(cmd_ctx, "pairs of data comparators: %i", buf_get_u32(etm_config_reg->value, 4, 4));
1383 command_print(cmd_ctx, "memory map decoders: %i", buf_get_u32(etm_config_reg->value, 8, 5));
1384 command_print(cmd_ctx, "number of counters: %i", buf_get_u32(etm_config_reg->value, 13, 3));
1385 command_print(cmd_ctx, "sequencer %spresent",
1386 (buf_get_u32(etm_config_reg->value, 16, 1) == 1) ? "" : "not ");
1387 command_print(cmd_ctx, "number of ext. inputs: %i", buf_get_u32(etm_config_reg->value, 17, 3));
1388 command_print(cmd_ctx, "number of ext. outputs: %i", buf_get_u32(etm_config_reg->value, 20, 3));
1389 command_print(cmd_ctx, "FIFO full %spresent",
1390 (buf_get_u32(etm_config_reg->value, 23, 1) == 1) ? "" : "not ");
1391 command_print(cmd_ctx, "protocol version: %i", buf_get_u32(etm_config_reg->value, 28, 3));
1392
1393 etm_get_reg(etm_sys_config_reg);
1394
1395 switch (buf_get_u32(etm_sys_config_reg->value, 0, 3))
1396 {
1397 case 0:
1398 max_port_size = 4;
1399 break;
1400 case 1:
1401 max_port_size = 8;
1402 break;
1403 case 2:
1404 max_port_size = 16;
1405 break;
1406 default:
1407 LOG_ERROR("Illegal max_port_size");
1408 exit(-1);
1409 }
1410 command_print(cmd_ctx, "max. port size: %i", max_port_size);
1411
1412 command_print(cmd_ctx, "half-rate clocking %ssupported",
1413 (buf_get_u32(etm_sys_config_reg->value, 3, 1) == 1) ? "" : "not ");
1414 command_print(cmd_ctx, "full-rate clocking %ssupported",
1415 (buf_get_u32(etm_sys_config_reg->value, 4, 1) == 1) ? "" : "not ");
1416 command_print(cmd_ctx, "normal trace format %ssupported",
1417 (buf_get_u32(etm_sys_config_reg->value, 5, 1) == 1) ? "" : "not ");
1418 command_print(cmd_ctx, "multiplex trace format %ssupported",
1419 (buf_get_u32(etm_sys_config_reg->value, 6, 1) == 1) ? "" : "not ");
1420 command_print(cmd_ctx, "demultiplex trace format %ssupported",
1421 (buf_get_u32(etm_sys_config_reg->value, 7, 1) == 1) ? "" : "not ");
1422 command_print(cmd_ctx, "FIFO full %ssupported",
1423 (buf_get_u32(etm_sys_config_reg->value, 8, 1) == 1) ? "" : "not ");
1424
1425 return ERROR_OK;
1426 }
1427
1428 static int handle_etm_status_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1429 {
1430 target_t *target;
1431 armv4_5_common_t *armv4_5;
1432 arm7_9_common_t *arm7_9;
1433 trace_status_t trace_status;
1434
1435 target = get_current_target(cmd_ctx);
1436
1437 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1438 {
1439 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1440 return ERROR_OK;
1441 }
1442
1443 if (!arm7_9->etm_ctx)
1444 {
1445 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1446 return ERROR_OK;
1447 }
1448
1449 trace_status = arm7_9->etm_ctx->capture_driver->status(arm7_9->etm_ctx);
1450
1451 if (trace_status == TRACE_IDLE)
1452 {
1453 command_print(cmd_ctx, "tracing is idle");
1454 }
1455 else
1456 {
1457 static char *completed = " completed";
1458 static char *running = " is running";
1459 static char *overflowed = ", trace overflowed";
1460 static char *triggered = ", trace triggered";
1461
1462 command_print(cmd_ctx, "trace collection%s%s%s",
1463 (trace_status & TRACE_RUNNING) ? running : completed,
1464 (trace_status & TRACE_OVERFLOWED) ? overflowed : "",
1465 (trace_status & TRACE_TRIGGERED) ? triggered : "");
1466
1467 if (arm7_9->etm_ctx->trace_depth > 0)
1468 {
1469 command_print(cmd_ctx, "%i frames of trace data read", arm7_9->etm_ctx->trace_depth);
1470 }
1471 }
1472
1473 return ERROR_OK;
1474 }
1475
1476 static int handle_etm_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1477 {
1478 target_t *target;
1479 armv4_5_common_t *armv4_5;
1480 arm7_9_common_t *arm7_9;
1481 etm_context_t *etm_ctx;
1482
1483 if (argc < 1)
1484 {
1485 command_print(cmd_ctx, "usage: etm image <file> [base address] [type]");
1486 return ERROR_OK;
1487 }
1488
1489 target = get_current_target(cmd_ctx);
1490
1491 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1492 {
1493 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1494 return ERROR_OK;
1495 }
1496
1497 if (!(etm_ctx = arm7_9->etm_ctx))
1498 {
1499 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1500 return ERROR_OK;
1501 }
1502
1503 if (etm_ctx->image)
1504 {
1505 image_close(etm_ctx->image);
1506 free(etm_ctx->image);
1507 command_print(cmd_ctx, "previously loaded image found and closed");
1508 }
1509
1510 etm_ctx->image = malloc(sizeof(image_t));
1511 etm_ctx->image->base_address_set = 0;
1512 etm_ctx->image->start_address_set = 0;
1513
1514 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1515 if (argc >= 2)
1516 {
1517 etm_ctx->image->base_address_set = 1;
1518 etm_ctx->image->base_address = strtoul(args[1], NULL, 0);
1519 }
1520 else
1521 {
1522 etm_ctx->image->base_address_set = 0;
1523 }
1524
1525 if (image_open(etm_ctx->image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
1526 {
1527 free(etm_ctx->image);
1528 etm_ctx->image = NULL;
1529 return ERROR_OK;
1530 }
1531
1532 return ERROR_OK;
1533 }
1534
1535 static int handle_etm_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1536 {
1537 fileio_t file;
1538 target_t *target;
1539 armv4_5_common_t *armv4_5;
1540 arm7_9_common_t *arm7_9;
1541 etm_context_t *etm_ctx;
1542 u32 i;
1543
1544 if (argc != 1)
1545 {
1546 command_print(cmd_ctx, "usage: etm dump <file>");
1547 return ERROR_OK;
1548 }
1549
1550 target = get_current_target(cmd_ctx);
1551
1552 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1553 {
1554 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1555 return ERROR_OK;
1556 }
1557
1558 if (!(etm_ctx = arm7_9->etm_ctx))
1559 {
1560 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1561 return ERROR_OK;
1562 }
1563
1564 if (etm_ctx->capture_driver->status == TRACE_IDLE)
1565 {
1566 command_print(cmd_ctx, "trace capture wasn't enabled, no trace data captured");
1567 return ERROR_OK;
1568 }
1569
1570 if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING)
1571 {
1572 /* TODO: if on-the-fly capture is to be supported, this needs to be changed */
1573 command_print(cmd_ctx, "trace capture not completed");
1574 return ERROR_OK;
1575 }
1576
1577 /* read the trace data if it wasn't read already */
1578 if (etm_ctx->trace_depth == 0)
1579 etm_ctx->capture_driver->read_trace(etm_ctx);
1580
1581 if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
1582 {
1583 return ERROR_OK;
1584 }
1585
1586 fileio_write_u32(&file, etm_ctx->capture_status);
1587 fileio_write_u32(&file, etm_ctx->portmode);
1588 fileio_write_u32(&file, etm_ctx->tracemode);
1589 fileio_write_u32(&file, etm_ctx->trace_depth);
1590
1591 for (i = 0; i < etm_ctx->trace_depth; i++)
1592 {
1593 fileio_write_u32(&file, etm_ctx->trace_data[i].pipestat);
1594 fileio_write_u32(&file, etm_ctx->trace_data[i].packet);
1595 fileio_write_u32(&file, etm_ctx->trace_data[i].flags);
1596 }
1597
1598 fileio_close(&file);
1599
1600 return ERROR_OK;
1601 }
1602
1603 static int handle_etm_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1604 {
1605 fileio_t file;
1606 target_t *target;
1607 armv4_5_common_t *armv4_5;
1608 arm7_9_common_t *arm7_9;
1609 etm_context_t *etm_ctx;
1610 u32 i;
1611
1612 if (argc != 1)
1613 {
1614 command_print(cmd_ctx, "usage: etm load <file>");
1615 return ERROR_OK;
1616 }
1617
1618 target = get_current_target(cmd_ctx);
1619
1620 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1621 {
1622 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1623 return ERROR_OK;
1624 }
1625
1626 if (!(etm_ctx = arm7_9->etm_ctx))
1627 {
1628 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1629 return ERROR_OK;
1630 }
1631
1632 if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING)
1633 {
1634 command_print(cmd_ctx, "trace capture running, stop first");
1635 return ERROR_OK;
1636 }
1637
1638 if (fileio_open(&file, args[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
1639 {
1640 return ERROR_OK;
1641 }
1642
1643 if (file.size % 4)
1644 {
1645 command_print(cmd_ctx, "size isn't a multiple of 4, no valid trace data");
1646 fileio_close(&file);
1647 return ERROR_OK;
1648 }
1649
1650 if (etm_ctx->trace_depth > 0)
1651 {
1652 free(etm_ctx->trace_data);
1653 etm_ctx->trace_data = NULL;
1654 }
1655
1656 fileio_read_u32(&file, &etm_ctx->capture_status);
1657 fileio_read_u32(&file, &etm_ctx->portmode);
1658 fileio_read_u32(&file, &etm_ctx->tracemode);
1659 fileio_read_u32(&file, &etm_ctx->trace_depth);
1660
1661 etm_ctx->trace_data = malloc(sizeof(etmv1_trace_data_t) * etm_ctx->trace_depth);
1662 if(etm_ctx->trace_data == NULL)
1663 {
1664 command_print(cmd_ctx, "not enough memory to perform operation");
1665 fileio_close(&file);
1666 return ERROR_OK;
1667 }
1668
1669 for (i = 0; i < etm_ctx->trace_depth; i++)
1670 {
1671 u32 pipestat, packet, flags;
1672 fileio_read_u32(&file, &pipestat);
1673 fileio_read_u32(&file, &packet);
1674 fileio_read_u32(&file, &flags);
1675 etm_ctx->trace_data[i].pipestat = pipestat & 0xff;
1676 etm_ctx->trace_data[i].packet = packet & 0xffff;
1677 etm_ctx->trace_data[i].flags = flags;
1678 }
1679
1680 fileio_close(&file);
1681
1682 return ERROR_OK;
1683 }
1684
1685 static int handle_etm_trigger_percent_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1686 {
1687 target_t *target;
1688 armv4_5_common_t *armv4_5;
1689 arm7_9_common_t *arm7_9;
1690 etm_context_t *etm_ctx;
1691
1692 target = get_current_target(cmd_ctx);
1693
1694 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1695 {
1696 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1697 return ERROR_OK;
1698 }
1699
1700 if (!(etm_ctx = arm7_9->etm_ctx))
1701 {
1702 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1703 return ERROR_OK;
1704 }
1705
1706 if (argc > 0)
1707 {
1708 u32 new_value = strtoul(args[0], NULL, 0);
1709
1710 if ((new_value < 2) || (new_value > 100))
1711 {
1712 command_print(cmd_ctx, "valid settings are 2% to 100%");
1713 }
1714 else
1715 {
1716 etm_ctx->trigger_percent = new_value;
1717 }
1718 }
1719
1720 command_print(cmd_ctx, "%i percent of the tracebuffer reserved for after the trigger", etm_ctx->trigger_percent);
1721
1722 return ERROR_OK;
1723 }
1724
1725 static int handle_etm_start_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1726 {
1727 target_t *target;
1728 armv4_5_common_t *armv4_5;
1729 arm7_9_common_t *arm7_9;
1730 etm_context_t *etm_ctx;
1731 reg_t *etm_ctrl_reg;
1732
1733 target = get_current_target(cmd_ctx);
1734
1735 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1736 {
1737 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1738 return ERROR_OK;
1739 }
1740
1741 if (!(etm_ctx = arm7_9->etm_ctx))
1742 {
1743 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1744 return ERROR_OK;
1745 }
1746
1747 /* invalidate old tracing data */
1748 arm7_9->etm_ctx->capture_status = TRACE_IDLE;
1749 if (arm7_9->etm_ctx->trace_depth > 0)
1750 {
1751 free(arm7_9->etm_ctx->trace_data);
1752 arm7_9->etm_ctx->trace_data = NULL;
1753 }
1754 arm7_9->etm_ctx->trace_depth = 0;
1755
1756 etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
1757 etm_get_reg(etm_ctrl_reg);
1758
1759 /* Clear programming bit (10), set port selection bit (11) */
1760 buf_set_u32(etm_ctrl_reg->value, 10, 2, 0x2);
1761
1762 etm_store_reg(etm_ctrl_reg);
1763 jtag_execute_queue();
1764
1765 etm_ctx->capture_driver->start_capture(etm_ctx);
1766
1767 return ERROR_OK;
1768 }
1769
1770 static int handle_etm_stop_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1771 {
1772 target_t *target;
1773 armv4_5_common_t *armv4_5;
1774 arm7_9_common_t *arm7_9;
1775 etm_context_t *etm_ctx;
1776 reg_t *etm_ctrl_reg;
1777
1778 target = get_current_target(cmd_ctx);
1779
1780 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1781 {
1782 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1783 return ERROR_OK;
1784 }
1785
1786 if (!(etm_ctx = arm7_9->etm_ctx))
1787 {
1788 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1789 return ERROR_OK;
1790 }
1791
1792 etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
1793 etm_get_reg(etm_ctrl_reg);
1794
1795 /* Set programming bit (10), clear port selection bit (11) */
1796 buf_set_u32(etm_ctrl_reg->value, 10, 2, 0x1);
1797
1798 etm_store_reg(etm_ctrl_reg);
1799 jtag_execute_queue();
1800
1801 etm_ctx->capture_driver->stop_capture(etm_ctx);
1802
1803 return ERROR_OK;
1804 }
1805
1806 static int handle_etm_analyze_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1807 {
1808 target_t *target;
1809 armv4_5_common_t *armv4_5;
1810 arm7_9_common_t *arm7_9;
1811 etm_context_t *etm_ctx;
1812 int retval;
1813
1814 target = get_current_target(cmd_ctx);
1815
1816 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1817 {
1818 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1819 return ERROR_OK;
1820 }
1821
1822 if (!(etm_ctx = arm7_9->etm_ctx))
1823 {
1824 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1825 return ERROR_OK;
1826 }
1827
1828 if ((retval = etmv1_analyze_trace(etm_ctx, cmd_ctx)) != ERROR_OK)
1829 {
1830 switch(retval)
1831 {
1832 case ERROR_ETM_ANALYSIS_FAILED:
1833 command_print(cmd_ctx, "further analysis failed (corrupted trace data or just end of data");
1834 break;
1835 case ERROR_TRACE_INSTRUCTION_UNAVAILABLE:
1836 command_print(cmd_ctx, "no instruction for current address available, analysis aborted");
1837 break;
1838 case ERROR_TRACE_IMAGE_UNAVAILABLE:
1839 command_print(cmd_ctx, "no image available for trace analysis");
1840 break;
1841 default:
1842 command_print(cmd_ctx, "unknown error: %i", retval);
1843 }
1844 }
1845
1846 return ERROR_OK;
1847 }
1848
1849 int etm_register_commands(struct command_context_s *cmd_ctx)
1850 {
1851 etm_cmd = register_command(cmd_ctx, NULL, "etm", NULL, COMMAND_ANY, "Embedded Trace Macrocell");
1852
1853 register_command(cmd_ctx, etm_cmd, "config", handle_etm_config_command, COMMAND_CONFIG, "etm config <target> <port_width> <port_mode> <clocking> <capture_driver>");
1854
1855 return ERROR_OK;
1856 }
1857
1858 int etm_register_user_commands(struct command_context_s *cmd_ctx)
1859 {
1860 register_command(cmd_ctx, etm_cmd, "tracemode", handle_etm_tracemode_command,
1861 COMMAND_EXEC, "configure trace mode <none|data|address|all> <context id bits> <cycle accurate> <branch output");
1862
1863 register_command(cmd_ctx, etm_cmd, "info", handle_etm_info_command,
1864 COMMAND_EXEC, "display info about the current target's ETM");
1865
1866 register_command(cmd_ctx, etm_cmd, "trigger_percent <percent>", handle_etm_trigger_percent_command,
1867 COMMAND_EXEC, "amount (<percent>) of trace buffer to be filled after the trigger occured");
1868 register_command(cmd_ctx, etm_cmd, "status", handle_etm_status_command,
1869 COMMAND_EXEC, "display current target's ETM status");
1870 register_command(cmd_ctx, etm_cmd, "start", handle_etm_start_command,
1871 COMMAND_EXEC, "start ETM trace collection");
1872 register_command(cmd_ctx, etm_cmd, "stop", handle_etm_stop_command,
1873 COMMAND_EXEC, "stop ETM trace collection");
1874
1875 register_command(cmd_ctx, etm_cmd, "analyze", handle_etm_analyze_command,
1876 COMMAND_EXEC, "anaylze collected ETM trace");
1877
1878 register_command(cmd_ctx, etm_cmd, "image", handle_etm_image_command,
1879 COMMAND_EXEC, "load image from <file> [base address]");
1880
1881 register_command(cmd_ctx, etm_cmd, "dump", handle_etm_dump_command,
1882 COMMAND_EXEC, "dump captured trace data <file>");
1883 register_command(cmd_ctx, etm_cmd, "load", handle_etm_load_command,
1884 COMMAND_EXEC, "load trace data for analysis <file>");
1885
1886 return ERROR_OK;
1887 }

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)