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

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)