02c33104a35c08285944102fc03669018ba6a4d1
[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
32 #include "log.h"
33 #include "arm_jtag.h"
34 #include "types.h"
35 #include "binarybuffer.h"
36 #include "target.h"
37 #include "register.h"
38 #include "jtag.h"
39 #include "fileio.h"
40
41 #include <stdlib.h>
42
43 /* ETM register access functionality
44 *
45 */
46
47 bitfield_desc_t etm_comms_ctrl_bitfield_desc[] =
48 {
49 {"R", 1},
50 {"W", 1},
51 {"reserved", 26},
52 {"version", 4}
53 };
54
55 int etm_reg_arch_info[] =
56 {
57 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
58 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
59 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
60 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
61 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
62 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
63 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
64 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
65 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
66 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
67 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
68 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
69 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67,
70 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
71 };
72
73 int etm_reg_arch_size_info[] =
74 {
75 32, 32, 17, 8, 3, 9, 32, 16,
76 17, 26, 25, 8, 17, 32, 32, 17,
77 32, 32, 32, 32, 32, 32, 32, 32,
78 32, 32, 32, 32, 32, 32, 32, 32,
79 7, 7, 7, 7, 7, 7, 7, 7,
80 7, 7, 7, 7, 7, 7, 7, 7,
81 32, 32, 32, 32, 32, 32, 32, 32,
82 32, 32, 32, 32, 32, 32, 32, 32,
83 32, 32, 32, 32, 32, 32, 32, 32,
84 32, 32, 32, 32, 32, 32, 32, 32,
85 16, 16, 16, 16, 18, 18, 18, 18,
86 17, 17, 17, 17, 16, 16, 16, 16,
87 17, 17, 17, 17, 17, 17, 2,
88 17, 17, 17, 17, 32, 32, 32, 32
89 };
90
91 char* etm_reg_list[] =
92 {
93 "ETM_CTRL",
94 "ETM_CONFIG",
95 "ETM_TRIG_EVENT",
96 "ETM_MMD_CTRL",
97 "ETM_STATUS",
98 "ETM_SYS_CONFIG",
99 "ETM_TRACE_RESOURCE_CTRL",
100 "ETM_TRACE_EN_CTRL2",
101 "ETM_TRACE_EN_EVENT",
102 "ETM_TRACE_EN_CTRL1",
103 "ETM_FIFOFULL_REGION",
104 "ETM_FIFOFULL_LEVEL",
105 "ETM_VIEWDATA_EVENT",
106 "ETM_VIEWDATA_CTRL1",
107 "ETM_VIEWDATA_CTRL2",
108 "ETM_VIEWDATA_CTRL3",
109 "ETM_ADDR_COMPARATOR_VALUE1",
110 "ETM_ADDR_COMPARATOR_VALUE2",
111 "ETM_ADDR_COMPARATOR_VALUE3",
112 "ETM_ADDR_COMPARATOR_VALUE4",
113 "ETM_ADDR_COMPARATOR_VALUE5",
114 "ETM_ADDR_COMPARATOR_VALUE6",
115 "ETM_ADDR_COMPARATOR_VALUE7",
116 "ETM_ADDR_COMPARATOR_VALUE8",
117 "ETM_ADDR_COMPARATOR_VALUE9",
118 "ETM_ADDR_COMPARATOR_VALUE10",
119 "ETM_ADDR_COMPARATOR_VALUE11",
120 "ETM_ADDR_COMPARATOR_VALUE12",
121 "ETM_ADDR_COMPARATOR_VALUE13",
122 "ETM_ADDR_COMPARATOR_VALUE14",
123 "ETM_ADDR_COMPARATOR_VALUE15",
124 "ETM_ADDR_COMPARATOR_VALUE16",
125 "ETM_ADDR_ACCESS_TYPE1",
126 "ETM_ADDR_ACCESS_TYPE2",
127 "ETM_ADDR_ACCESS_TYPE3",
128 "ETM_ADDR_ACCESS_TYPE4",
129 "ETM_ADDR_ACCESS_TYPE5",
130 "ETM_ADDR_ACCESS_TYPE6",
131 "ETM_ADDR_ACCESS_TYPE7",
132 "ETM_ADDR_ACCESS_TYPE8",
133 "ETM_ADDR_ACCESS_TYPE9",
134 "ETM_ADDR_ACCESS_TYPE10",
135 "ETM_ADDR_ACCESS_TYPE11",
136 "ETM_ADDR_ACCESS_TYPE12",
137 "ETM_ADDR_ACCESS_TYPE13",
138 "ETM_ADDR_ACCESS_TYPE14",
139 "ETM_ADDR_ACCESS_TYPE15",
140 "ETM_ADDR_ACCESS_TYPE16",
141 "ETM_DATA_COMPARATOR_VALUE1",
142 "ETM_DATA_COMPARATOR_VALUE2",
143 "ETM_DATA_COMPARATOR_VALUE3",
144 "ETM_DATA_COMPARATOR_VALUE4",
145 "ETM_DATA_COMPARATOR_VALUE5",
146 "ETM_DATA_COMPARATOR_VALUE6",
147 "ETM_DATA_COMPARATOR_VALUE7",
148 "ETM_DATA_COMPARATOR_VALUE8",
149 "ETM_DATA_COMPARATOR_VALUE9",
150 "ETM_DATA_COMPARATOR_VALUE10",
151 "ETM_DATA_COMPARATOR_VALUE11",
152 "ETM_DATA_COMPARATOR_VALUE12",
153 "ETM_DATA_COMPARATOR_VALUE13",
154 "ETM_DATA_COMPARATOR_VALUE14",
155 "ETM_DATA_COMPARATOR_VALUE15",
156 "ETM_DATA_COMPARATOR_VALUE16",
157 "ETM_DATA_COMPARATOR_MASK1",
158 "ETM_DATA_COMPARATOR_MASK2",
159 "ETM_DATA_COMPARATOR_MASK3",
160 "ETM_DATA_COMPARATOR_MASK4",
161 "ETM_DATA_COMPARATOR_MASK5",
162 "ETM_DATA_COMPARATOR_MASK6",
163 "ETM_DATA_COMPARATOR_MASK7",
164 "ETM_DATA_COMPARATOR_MASK8",
165 "ETM_DATA_COMPARATOR_MASK9",
166 "ETM_DATA_COMPARATOR_MASK10",
167 "ETM_DATA_COMPARATOR_MASK11",
168 "ETM_DATA_COMPARATOR_MASK12",
169 "ETM_DATA_COMPARATOR_MASK13",
170 "ETM_DATA_COMPARATOR_MASK14",
171 "ETM_DATA_COMPARATOR_MASK15",
172 "ETM_DATA_COMPARATOR_MASK16",
173 "ETM_COUNTER_INITAL_VALUE1",
174 "ETM_COUNTER_INITAL_VALUE2",
175 "ETM_COUNTER_INITAL_VALUE3",
176 "ETM_COUNTER_INITAL_VALUE4",
177 "ETM_COUNTER_ENABLE1",
178 "ETM_COUNTER_ENABLE2",
179 "ETM_COUNTER_ENABLE3",
180 "ETM_COUNTER_ENABLE4",
181 "ETM_COUNTER_RELOAD_VALUE1",
182 "ETM_COUNTER_RELOAD_VALUE2",
183 "ETM_COUNTER_RELOAD_VALUE3",
184 "ETM_COUNTER_RELOAD_VALUE4",
185 "ETM_COUNTER_VALUE1",
186 "ETM_COUNTER_VALUE2",
187 "ETM_COUNTER_VALUE3",
188 "ETM_COUNTER_VALUE4",
189 "ETM_SEQUENCER_CTRL1",
190 "ETM_SEQUENCER_CTRL2",
191 "ETM_SEQUENCER_CTRL3",
192 "ETM_SEQUENCER_CTRL4",
193 "ETM_SEQUENCER_CTRL5",
194 "ETM_SEQUENCER_CTRL6",
195 "ETM_SEQUENCER_STATE",
196 "ETM_EXTERNAL_OUTPUT1",
197 "ETM_EXTERNAL_OUTPUT2",
198 "ETM_EXTERNAL_OUTPUT3",
199 "ETM_EXTERNAL_OUTPUT4",
200 "ETM_CONTEXTID_COMPARATOR_VALUE1",
201 "ETM_CONTEXTID_COMPARATOR_VALUE2",
202 "ETM_CONTEXTID_COMPARATOR_VALUE3",
203 "ETM_CONTEXTID_COMPARATOR_MASK"
204 };
205
206 int etm_reg_arch_type = -1;
207
208 int etm_get_reg(reg_t *reg);
209 int etm_set_reg(reg_t *reg, u32 value);
210 int etm_set_reg_w_exec(reg_t *reg, u8 *buf);
211
212 int etm_write_reg(reg_t *reg, u32 value);
213 int etm_read_reg(reg_t *reg);
214
215 command_t *etm_cmd = NULL;
216
217 reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_context_t *etm_ctx)
218 {
219 reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
220 reg_t *reg_list = NULL;
221 etm_reg_t *arch_info = NULL;
222 int num_regs = sizeof(etm_reg_arch_info)/sizeof(int);
223 int i;
224 u32 etm_ctrl_value;
225
226 /* register a register arch-type for etm registers only once */
227 if (etm_reg_arch_type == -1)
228 etm_reg_arch_type = register_reg_arch_type(etm_get_reg, etm_set_reg_w_exec);
229
230 /* the actual registers are kept in two arrays */
231 reg_list = calloc(num_regs, sizeof(reg_t));
232 arch_info = calloc(num_regs, sizeof(etm_reg_t));
233
234 /* fill in values for the reg cache */
235 reg_cache->name = "etm registers";
236 reg_cache->next = NULL;
237 reg_cache->reg_list = reg_list;
238 reg_cache->num_regs = num_regs;
239
240 /* set up registers */
241 for (i = 0; i < num_regs; i++)
242 {
243 reg_list[i].name = etm_reg_list[i];
244 reg_list[i].size = 32;
245 reg_list[i].dirty = 0;
246 reg_list[i].valid = 0;
247 reg_list[i].bitfield_desc = NULL;
248 reg_list[i].num_bitfields = 0;
249 reg_list[i].value = calloc(1, 4);
250 reg_list[i].arch_info = &arch_info[i];
251 reg_list[i].arch_type = etm_reg_arch_type;
252 reg_list[i].size = etm_reg_arch_size_info[i];
253 arch_info[i].addr = etm_reg_arch_info[i];
254 arch_info[i].jtag_info = jtag_info;
255 }
256
257 /* initialize some ETM control register settings */
258 etm_get_reg(&reg_list[ETM_CTRL]);
259 etm_ctrl_value = buf_get_u32(reg_list[ETM_CTRL].value, 0, reg_list[ETM_CTRL].size);
260
261 /* clear the ETM powerdown bit (0) */
262 etm_ctrl_value &= ~0x1;
263
264 /* configure port width (6:4), mode (17:16) and clocking (13) */
265 etm_ctrl_value = (etm_ctrl_value &
266 ~ETM_PORT_WIDTH_MASK & ~ETM_PORT_MODE_MASK & ~ETM_PORT_CLOCK_MASK)
267 | etm_ctx->portmode;
268
269 buf_set_u32(reg_list[ETM_CTRL].value, 0, reg_list[ETM_CTRL].size, etm_ctrl_value);
270 etm_store_reg(&reg_list[ETM_CTRL]);
271
272 /* the ETM might have an ETB connected */
273 if (strcmp(etm_ctx->capture_driver->name, "etb") == 0)
274 {
275 etb_t *etb = etm_ctx->capture_driver_priv;
276
277 if (!etb)
278 {
279 ERROR("etb selected as etm capture driver, but no ETB configured");
280 return ERROR_OK;
281 }
282
283 reg_cache->next = etb_build_reg_cache(etb);
284
285 etb->reg_cache = reg_cache->next;
286
287 if (etm_ctx->capture_driver->init(etm_ctx) != ERROR_OK)
288 {
289 ERROR("ETM capture driver initialization failed");
290 exit(-1);
291 }
292 }
293
294 return reg_cache;
295 }
296
297 int etm_get_reg(reg_t *reg)
298 {
299 if (etm_read_reg(reg) != ERROR_OK)
300 {
301 ERROR("BUG: error scheduling etm register read");
302 exit(-1);
303 }
304
305 if (jtag_execute_queue() != ERROR_OK)
306 {
307 ERROR("register read failed");
308 }
309
310 return ERROR_OK;
311 }
312
313 int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
314 {
315 etm_reg_t *etm_reg = reg->arch_info;
316 u8 reg_addr = etm_reg->addr & 0x7f;
317 scan_field_t fields[3];
318
319 DEBUG("%i", etm_reg->addr);
320
321 jtag_add_end_state(TAP_RTI);
322 arm_jtag_scann(etm_reg->jtag_info, 0x6);
323 arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
324
325 fields[0].device = etm_reg->jtag_info->chain_pos;
326 fields[0].num_bits = 32;
327 fields[0].out_value = reg->value;
328 fields[0].out_mask = NULL;
329 fields[0].in_value = NULL;
330 fields[0].in_check_value = NULL;
331 fields[0].in_check_mask = NULL;
332 fields[0].in_handler = NULL;
333 fields[0].in_handler_priv = NULL;
334
335 fields[1].device = etm_reg->jtag_info->chain_pos;
336 fields[1].num_bits = 7;
337 fields[1].out_value = malloc(1);
338 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
339 fields[1].out_mask = NULL;
340 fields[1].in_value = NULL;
341 fields[1].in_check_value = NULL;
342 fields[1].in_check_mask = NULL;
343 fields[1].in_handler = NULL;
344 fields[1].in_handler_priv = NULL;
345
346 fields[2].device = etm_reg->jtag_info->chain_pos;
347 fields[2].num_bits = 1;
348 fields[2].out_value = malloc(1);
349 buf_set_u32(fields[2].out_value, 0, 1, 0);
350 fields[2].out_mask = NULL;
351 fields[2].in_value = NULL;
352 fields[2].in_check_value = NULL;
353 fields[2].in_check_mask = NULL;
354 fields[2].in_handler = NULL;
355 fields[2].in_handler_priv = NULL;
356
357 jtag_add_dr_scan(3, fields, -1, NULL);
358
359 fields[0].in_value = reg->value;
360 fields[0].in_check_value = check_value;
361 fields[0].in_check_mask = check_mask;
362
363 jtag_add_dr_scan(3, fields, -1, NULL);
364
365 free(fields[1].out_value);
366 free(fields[2].out_value);
367
368 return ERROR_OK;
369 }
370
371 int etm_read_reg(reg_t *reg)
372 {
373 return etm_read_reg_w_check(reg, NULL, NULL);
374 }
375
376 int etm_set_reg(reg_t *reg, u32 value)
377 {
378 if (etm_write_reg(reg, value) != ERROR_OK)
379 {
380 ERROR("BUG: error scheduling etm register write");
381 exit(-1);
382 }
383
384 buf_set_u32(reg->value, 0, reg->size, value);
385 reg->valid = 1;
386 reg->dirty = 0;
387
388 return ERROR_OK;
389 }
390
391 int etm_set_reg_w_exec(reg_t *reg, u8 *buf)
392 {
393 etm_set_reg(reg, buf_get_u32(buf, 0, reg->size));
394
395 if (jtag_execute_queue() != ERROR_OK)
396 {
397 ERROR("register write failed");
398 exit(-1);
399 }
400 return ERROR_OK;
401 }
402
403 int etm_write_reg(reg_t *reg, u32 value)
404 {
405 etm_reg_t *etm_reg = reg->arch_info;
406 u8 reg_addr = etm_reg->addr & 0x7f;
407 scan_field_t fields[3];
408
409 DEBUG("%i: 0x%8.8x", etm_reg->addr, value);
410
411 jtag_add_end_state(TAP_RTI);
412 arm_jtag_scann(etm_reg->jtag_info, 0x6);
413 arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
414
415 fields[0].device = etm_reg->jtag_info->chain_pos;
416 fields[0].num_bits = 32;
417 fields[0].out_value = malloc(4);
418 buf_set_u32(fields[0].out_value, 0, 32, value);
419 fields[0].out_mask = NULL;
420 fields[0].in_value = NULL;
421 fields[0].in_check_value = NULL;
422 fields[0].in_check_mask = NULL;
423 fields[0].in_handler = NULL;
424 fields[0].in_handler_priv = NULL;
425
426 fields[1].device = etm_reg->jtag_info->chain_pos;
427 fields[1].num_bits = 7;
428 fields[1].out_value = malloc(1);
429 buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
430 fields[1].out_mask = NULL;
431 fields[1].in_value = NULL;
432 fields[1].in_check_value = NULL;
433 fields[1].in_check_mask = NULL;
434 fields[1].in_handler = NULL;
435 fields[1].in_handler_priv = NULL;
436
437 fields[2].device = etm_reg->jtag_info->chain_pos;
438 fields[2].num_bits = 1;
439 fields[2].out_value = malloc(1);
440 buf_set_u32(fields[2].out_value, 0, 1, 1);
441 fields[2].out_mask = NULL;
442 fields[2].in_value = NULL;
443 fields[2].in_check_value = NULL;
444 fields[2].in_check_mask = NULL;
445 fields[2].in_handler = NULL;
446 fields[2].in_handler_priv = NULL;
447
448 jtag_add_dr_scan(3, fields, -1, NULL);
449
450 free(fields[0].out_value);
451 free(fields[1].out_value);
452 free(fields[2].out_value);
453
454 return ERROR_OK;
455 }
456
457 int etm_store_reg(reg_t *reg)
458 {
459 return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
460 }
461
462 /* ETM trace analysis functionality
463 *
464 */
465 extern etm_capture_driver_t etb_capture_driver;
466
467 etm_capture_driver_t *etm_capture_drivers[] =
468 {
469 &etb_capture_driver,
470 NULL
471 };
472
473 char *etmv1v1_branch_reason_strings[] =
474 {
475 "normal PC change",
476 "tracing enabled",
477 "trace restarted after overflow",
478 "exit from debug",
479 "periodic synchronization",
480 "reserved",
481 "reserved",
482 "reserved",
483 };
484
485 int etmv1_next_packet(etm_context_t *ctx, u8 *packet)
486 {
487
488
489 return ERROR_OK;
490 }
491
492 int etmv1_analyse_trace(etm_context_t *ctx)
493 {
494 ctx->pipe_index = 0;
495 ctx->data_index = 0;
496
497 while (ctx->pipe_index < ctx->trace_depth)
498 {
499 switch (ctx->trace_data[ctx->pipe_index].pipestat)
500 {
501 case STAT_IE:
502 case STAT_ID:
503 break;
504 case STAT_IN:
505 DEBUG("IN");
506 break;
507 case STAT_WT:
508 DEBUG("WT");
509 break;
510 case STAT_BE:
511 case STAT_BD:
512 break;
513 case STAT_TD:
514 /* TODO: in cycle accurate trace, we have to count cycles */
515 DEBUG("TD");
516 break;
517 }
518 }
519
520 return ERROR_OK;
521 }
522
523 int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
524 {
525 target_t *target;
526 armv4_5_common_t *armv4_5;
527 arm7_9_common_t *arm7_9;
528 etmv1_tracemode_t tracemode;
529
530 target = get_current_target(cmd_ctx);
531
532 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
533 {
534 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
535 return ERROR_OK;
536 }
537
538 if (!arm7_9->etm_ctx)
539 {
540 command_print(cmd_ctx, "current target doesn't have an ETM configured");
541 return ERROR_OK;
542 }
543
544 tracemode = arm7_9->etm_ctx->tracemode;
545
546 if (argc == 3)
547 {
548 if (strcmp(args[0], "none") == 0)
549 {
550 tracemode = ETMV1_TRACE_NONE;
551 }
552 else if (strcmp(args[0], "data") == 0)
553 {
554 tracemode = ETMV1_TRACE_DATA;
555 }
556 else if (strcmp(args[0], "address") == 0)
557 {
558 tracemode = ETMV1_TRACE_ADDR;
559 }
560 else if (strcmp(args[0], "all") == 0)
561 {
562 tracemode = ETMV1_TRACE_DATA | ETMV1_TRACE_ADDR;
563 }
564 else
565 {
566 command_print(cmd_ctx, "invalid option '%s'", args[0]);
567 return ERROR_OK;
568 }
569
570 switch (strtol(args[1], NULL, 0))
571 {
572 case 0:
573 tracemode |= ETMV1_CONTEXTID_NONE;
574 break;
575 case 8:
576 tracemode |= ETMV1_CONTEXTID_8;
577 break;
578 case 16:
579 tracemode |= ETMV1_CONTEXTID_16;
580 break;
581 case 32:
582 tracemode |= ETMV1_CONTEXTID_32;
583 break;
584 default:
585 command_print(cmd_ctx, "invalid option '%s'", args[1]);
586 return ERROR_OK;
587 }
588
589 if (strcmp(args[2], "enable") == 0)
590 {
591 tracemode |= ETMV1_CYCLE_ACCURATE;
592 }
593 else if (strcmp(args[2], "disable") == 0)
594 {
595 tracemode |= 0;
596 }
597 else
598 {
599 command_print(cmd_ctx, "invalid option '%s'", args[2]);
600 return ERROR_OK;
601 }
602 }
603 else if (argc != 0)
604 {
605 command_print(cmd_ctx, "usage: configure trace mode <none|data|address|all> <context id bits> <enable|disable cycle accurate>");
606 return ERROR_OK;
607 }
608
609 command_print(cmd_ctx, "current tracemode configuration:");
610
611 switch (tracemode & ETMV1_TRACE_MASK)
612 {
613 case ETMV1_TRACE_NONE:
614 command_print(cmd_ctx, "data tracing: none");
615 break;
616 case ETMV1_TRACE_DATA:
617 command_print(cmd_ctx, "data tracing: data only");
618 break;
619 case ETMV1_TRACE_ADDR:
620 command_print(cmd_ctx, "data tracing: address only");
621 break;
622 case ETMV1_TRACE_DATA | ETMV1_TRACE_ADDR:
623 command_print(cmd_ctx, "data tracing: address and data");
624 break;
625 }
626
627 switch (tracemode & ETMV1_CONTEXTID_MASK)
628 {
629 case ETMV1_CONTEXTID_NONE:
630 command_print(cmd_ctx, "contextid tracing: none");
631 break;
632 case ETMV1_CONTEXTID_8:
633 command_print(cmd_ctx, "contextid tracing: 8 bit");
634 break;
635 case ETMV1_CONTEXTID_16:
636 command_print(cmd_ctx, "contextid tracing: 16 bit");
637 break;
638 case ETMV1_CONTEXTID_32:
639 command_print(cmd_ctx, "contextid tracing: 32 bit");
640 break;
641 }
642
643 if (tracemode & ETMV1_CYCLE_ACCURATE)
644 {
645 command_print(cmd_ctx, "cycle-accurate tracing enabled");
646 }
647 else
648 {
649 command_print(cmd_ctx, "cycle-accurate tracing disabled");
650 }
651
652 /* only update ETM_CTRL register if tracemode changed */
653 if (arm7_9->etm_ctx->tracemode != tracemode)
654 {
655 reg_t *etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
656
657 etm_get_reg(etm_ctrl_reg);
658
659 buf_set_u32(etm_ctrl_reg->value, 2, 2, tracemode & ETMV1_TRACE_MASK);
660 buf_set_u32(etm_ctrl_reg->value, 14, 2, (tracemode & ETMV1_CONTEXTID_MASK) >> 4);
661 buf_set_u32(etm_ctrl_reg->value, 12, 1, (tracemode & ETMV1_CYCLE_ACCURATE) >> 8);
662
663 etm_store_reg(etm_ctrl_reg);
664
665 arm7_9->etm_ctx->tracemode = tracemode;
666
667 /* invalidate old trace data */
668 arm7_9->etm_ctx->capture_status = TRACE_IDLE;
669 if (arm7_9->etm_ctx->trace_depth > 0)
670 {
671 free(arm7_9->etm_ctx->trace_data);
672 }
673 arm7_9->etm_ctx->trace_depth = 0;
674 }
675
676 return ERROR_OK;
677 }
678
679 int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
680 {
681 target_t *target;
682 armv4_5_common_t *armv4_5;
683 arm7_9_common_t *arm7_9;
684 etm_portmode_t portmode = 0x0;
685 etm_context_t *etm_ctx = malloc(sizeof(etm_context_t));
686 int i;
687
688 if (argc != 5)
689 {
690 ERROR("incomplete 'etm config <target> <port_width> <port_mode> <clocking> <capture_driver>' command");
691 exit(-1);
692 }
693
694 target = get_target_by_num(strtoul(args[0], NULL, 0));
695
696 if (!target)
697 {
698 ERROR("target number '%s' not defined", args[0]);
699 exit(-1);
700 }
701
702 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
703 {
704 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
705 return ERROR_OK;
706 }
707
708 switch (strtoul(args[1], NULL, 0))
709 {
710 case 4:
711 portmode |= ETM_PORT_4BIT;
712 break;
713 case 8:
714 portmode |= ETM_PORT_8BIT;
715 break;
716 case 16:
717 portmode |= ETM_PORT_16BIT;
718 break;
719 default:
720 command_print(cmd_ctx, "unsupported ETM port width '%s', must be 4, 8 or 16", args[1]);
721 return ERROR_OK;
722 }
723
724 if (strcmp("normal", args[2]) == 0)
725 {
726 portmode |= ETM_PORT_NORMAL;
727 }
728 else if (strcmp("multiplexed", args[2]) == 0)
729 {
730 portmode |= ETM_PORT_MUXED;
731 }
732 else if (strcmp("demultiplexed", args[2]) == 0)
733 {
734 portmode |= ETM_PORT_DEMUXED;
735 }
736 else
737 {
738 command_print(cmd_ctx, "unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'", args[2]);
739 return ERROR_OK;
740 }
741
742 if (strcmp("half", args[3]) == 0)
743 {
744 portmode |= ETM_PORT_HALF_CLOCK;
745 }
746 else if (strcmp("full", args[3]) == 0)
747 {
748 portmode |= ETM_PORT_FULL_CLOCK;
749 }
750 else
751 {
752 command_print(cmd_ctx, "unsupported ETM port clocking '%s', must be 'full' or 'half'", args[3]);
753 return ERROR_OK;
754 }
755
756 for (i=0; etm_capture_drivers[i]; i++)
757 {
758 if (strcmp(args[4], etm_capture_drivers[i]->name) == 0)
759 {
760 if (etm_capture_drivers[i]->register_commands(cmd_ctx) != ERROR_OK)
761 {
762 free(etm_ctx);
763 exit(-1);
764 }
765
766 etm_ctx->capture_driver = etm_capture_drivers[i];
767
768 break;
769 }
770 }
771
772 etm_ctx->trace_data = NULL;
773 etm_ctx->trace_depth = 0;
774 etm_ctx->portmode = portmode;
775 etm_ctx->tracemode = 0x0;
776 etm_ctx->core_state = ARMV4_5_STATE_ARM;
777 etm_ctx->pipe_index = 0;
778 etm_ctx->data_index = 0;
779 etm_ctx->current_pc = 0x0;
780 etm_ctx->pc_ok = 0;
781 etm_ctx->last_branch = 0x0;
782 etm_ctx->last_ptr = 0x0;
783 etm_ctx->context_id = 0x0;
784
785 arm7_9->etm_ctx = etm_ctx;
786
787 etm_register_user_commands(cmd_ctx);
788
789 return ERROR_OK;
790 }
791
792 int handle_etm_status_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
793 {
794 target_t *target;
795 armv4_5_common_t *armv4_5;
796 arm7_9_common_t *arm7_9;
797 trace_status_t trace_status;
798
799 target = get_current_target(cmd_ctx);
800
801 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
802 {
803 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
804 return ERROR_OK;
805 }
806
807 if (!arm7_9->etm_ctx)
808 {
809 command_print(cmd_ctx, "current target doesn't have an ETM configured");
810 return ERROR_OK;
811 }
812
813 trace_status = arm7_9->etm_ctx->capture_driver->status(arm7_9->etm_ctx);
814
815 if (trace_status == TRACE_IDLE)
816 {
817 command_print(cmd_ctx, "tracing is idle");
818 }
819 else
820 {
821 static char *completed = " completed";
822 static char *running = " is running";
823 static char *overflowed = ", trace overflowed";
824 static char *triggered = ", trace triggered";
825
826 command_print(cmd_ctx, "trace collection%s%s%s",
827 (trace_status & TRACE_RUNNING) ? running : completed,
828 (trace_status & TRACE_OVERFLOWED) ? overflowed : "",
829 (trace_status & TRACE_TRIGGERED) ? triggered : "");
830
831 if (arm7_9->etm_ctx->trace_depth > 0)
832 {
833 command_print(cmd_ctx, "%i frames of trace data read", arm7_9->etm_ctx->trace_depth);
834 }
835 }
836
837 return ERROR_OK;
838 }
839
840 int handle_etm_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
841 {
842 fileio_t file;
843 target_t *target;
844 armv4_5_common_t *armv4_5;
845 arm7_9_common_t *arm7_9;
846 etm_context_t *etm_ctx;
847 u32 size_written;
848
849 if (argc != 1)
850 {
851 command_print(cmd_ctx, "usage: etm dump <file>");
852 return ERROR_OK;
853 }
854
855 target = get_current_target(cmd_ctx);
856
857 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
858 {
859 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
860 return ERROR_OK;
861 }
862
863 if (!(etm_ctx = arm7_9->etm_ctx))
864 {
865 command_print(cmd_ctx, "current target doesn't have an ETM configured");
866 return ERROR_OK;
867 }
868
869 if (etm_ctx->capture_driver->status == TRACE_IDLE)
870 {
871 command_print(cmd_ctx, "trace capture wasn't enabled, no trace data captured");
872 return ERROR_OK;
873 }
874
875 if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING)
876 {
877 /* TODO: if on-the-fly capture is to be supported, this needs to be changed */
878 command_print(cmd_ctx, "trace capture not completed");
879 return ERROR_OK;
880 }
881
882 /* read the trace data if it wasn't read already */
883 if (etm_ctx->trace_depth == 0)
884 etm_ctx->capture_driver->read_trace(etm_ctx);
885
886 if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
887 {
888 command_print(cmd_ctx, "file open error: %s", file.error_str);
889 return ERROR_OK;
890 }
891
892 //fileio_write(&file, etm_ctx->trace_depth * 4, (u8*)etm_ctx->trace_data, &size_written);
893
894 fileio_close(&file);
895
896 return ERROR_OK;
897 }
898
899 int handle_etm_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
900 {
901 fileio_t file;
902 target_t *target;
903 armv4_5_common_t *armv4_5;
904 arm7_9_common_t *arm7_9;
905 etm_context_t *etm_ctx;
906 u32 size_read;
907
908 if (argc != 1)
909 {
910 command_print(cmd_ctx, "usage: etm load <file>");
911 return ERROR_OK;
912 }
913
914 target = get_current_target(cmd_ctx);
915
916 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
917 {
918 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
919 return ERROR_OK;
920 }
921
922 if (!(etm_ctx = arm7_9->etm_ctx))
923 {
924 command_print(cmd_ctx, "current target doesn't have an ETM configured");
925 return ERROR_OK;
926 }
927
928 if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING)
929 {
930 command_print(cmd_ctx, "trace capture running, stop first");
931 return ERROR_OK;
932 }
933
934 if (fileio_open(&file, args[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
935 {
936 command_print(cmd_ctx, "file open error: %s", file.error_str);
937 return ERROR_OK;
938 }
939
940 if (file.size % 4)
941 {
942 command_print(cmd_ctx, "size isn't a multiple of 4, no valid trace data");
943 return ERROR_OK;
944 }
945
946 if (etm_ctx->trace_depth > 0)
947 {
948 free(etm_ctx->trace_data);
949 }
950
951 //fileio_read(&file, file.size, (u8*)etm_ctx->trace_data, &size_read);
952 etm_ctx->trace_depth = file.size / 4;
953 etm_ctx->capture_status = TRACE_COMPLETED;
954
955 fileio_close(&file);
956
957 return ERROR_OK;
958 }
959
960 int handle_etm_start_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
961 {
962 target_t *target;
963 armv4_5_common_t *armv4_5;
964 arm7_9_common_t *arm7_9;
965 etm_context_t *etm_ctx;
966 reg_t *etm_ctrl_reg;
967
968 target = get_current_target(cmd_ctx);
969
970 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
971 {
972 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
973 return ERROR_OK;
974 }
975
976 if (!(etm_ctx = arm7_9->etm_ctx))
977 {
978 command_print(cmd_ctx, "current target doesn't have an ETM configured");
979 return ERROR_OK;
980 }
981
982 /* invalidate old tracing data */
983 arm7_9->etm_ctx->capture_status = TRACE_IDLE;
984 if (arm7_9->etm_ctx->trace_depth > 0)
985 {
986 free(arm7_9->etm_ctx->trace_data);
987 }
988 arm7_9->etm_ctx->trace_depth = 0;
989
990 etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
991 etm_get_reg(etm_ctrl_reg);
992
993 /* Clear programming bit (10), set port selection bit (11) */
994 buf_set_u32(etm_ctrl_reg->value, 10, 2, 0x2);
995
996 etm_store_reg(etm_ctrl_reg);
997 jtag_execute_queue();
998
999 etm_ctx->capture_driver->start_capture(etm_ctx);
1000
1001 return ERROR_OK;
1002 }
1003
1004 int handle_etm_stop_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1005 {
1006 target_t *target;
1007 armv4_5_common_t *armv4_5;
1008 arm7_9_common_t *arm7_9;
1009 etm_context_t *etm_ctx;
1010 reg_t *etm_ctrl_reg;
1011
1012 target = get_current_target(cmd_ctx);
1013
1014 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1015 {
1016 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1017 return ERROR_OK;
1018 }
1019
1020 if (!(etm_ctx = arm7_9->etm_ctx))
1021 {
1022 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1023 return ERROR_OK;
1024 }
1025
1026 etm_ctrl_reg = &arm7_9->etm_ctx->reg_cache->reg_list[ETM_CTRL];
1027 etm_get_reg(etm_ctrl_reg);
1028
1029 /* Set programming bit (10), clear port selection bit (11) */
1030 buf_set_u32(etm_ctrl_reg->value, 10, 2, 0x1);
1031
1032 etm_store_reg(etm_ctrl_reg);
1033 jtag_execute_queue();
1034
1035 etm_ctx->capture_driver->stop_capture(etm_ctx);
1036
1037 return ERROR_OK;
1038 }
1039
1040 int handle_etm_analyse_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1041 {
1042 target_t *target;
1043 armv4_5_common_t *armv4_5;
1044 arm7_9_common_t *arm7_9;
1045 etm_context_t *etm_ctx;
1046
1047 target = get_current_target(cmd_ctx);
1048
1049 if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
1050 {
1051 command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
1052 return ERROR_OK;
1053 }
1054
1055 if (!(etm_ctx = arm7_9->etm_ctx))
1056 {
1057 command_print(cmd_ctx, "current target doesn't have an ETM configured");
1058 return ERROR_OK;
1059 }
1060
1061 etmv1_analyse_trace(etm_ctx);
1062
1063 return ERROR_OK;
1064 }
1065
1066 int etm_register_commands(struct command_context_s *cmd_ctx)
1067 {
1068 etm_cmd = register_command(cmd_ctx, NULL, "etm", NULL, COMMAND_ANY, "Embedded Trace Macrocell");
1069
1070 register_command(cmd_ctx, etm_cmd, "config", handle_etm_config_command, COMMAND_CONFIG, NULL);
1071
1072 return ERROR_OK;
1073 }
1074
1075 int etm_register_user_commands(struct command_context_s *cmd_ctx)
1076 {
1077 register_command(cmd_ctx, etm_cmd, "tracemode", handle_etm_tracemode_command,
1078 COMMAND_EXEC, "configure trace mode <none|data|address|all> <context id bits> <enable|disable cycle accurate>");
1079
1080 register_command(cmd_ctx, etm_cmd, "status", handle_etm_status_command,
1081 COMMAND_EXEC, "display current target's ETM status");
1082 register_command(cmd_ctx, etm_cmd, "start", handle_etm_start_command,
1083 COMMAND_EXEC, "start ETM trace collection");
1084 register_command(cmd_ctx, etm_cmd, "stop", handle_etm_stop_command,
1085 COMMAND_EXEC, "stop ETM trace collection");
1086
1087 register_command(cmd_ctx, etm_cmd, "analyze", handle_etm_stop_command,
1088 COMMAND_EXEC, "anaylze collected ETM trace");
1089
1090 register_command(cmd_ctx, etm_cmd, "dump", handle_etm_dump_command,
1091 COMMAND_EXEC, "dump captured trace data <file>");
1092 register_command(cmd_ctx, etm_cmd, "load", handle_etm_load_command,
1093 COMMAND_EXEC, "load trace data for analysis <file>");
1094
1095 return ERROR_OK;
1096 }

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)