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

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)