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

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)