1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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. *
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. *
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 ***************************************************************************/
30 #include "arm7_9_common.h"
31 #include "arm_disassembler.h"
32 #include "arm_simulator.h"
37 #include "binarybuffer.h"
45 /* ETM register access functionality
50 static bitfield_desc_t etm_comms_ctrl_bitfield_desc
[] =
59 static int etm_reg_arch_info
[] =
61 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
62 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
63 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
64 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
65 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
66 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
67 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
68 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
69 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
70 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
71 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
72 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
73 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67,
74 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
77 static int etm_reg_arch_size_info
[] =
79 32, 32, 17, 8, 3, 9, 32, 16,
80 17, 26, 25, 8, 17, 32, 32, 17,
81 32, 32, 32, 32, 32, 32, 32, 32,
82 32, 32, 32, 32, 32, 32, 32, 32,
83 7, 7, 7, 7, 7, 7, 7, 7,
84 7, 7, 7, 7, 7, 7, 7, 7,
85 32, 32, 32, 32, 32, 32, 32, 32,
86 32, 32, 32, 32, 32, 32, 32, 32,
87 32, 32, 32, 32, 32, 32, 32, 32,
88 32, 32, 32, 32, 32, 32, 32, 32,
89 16, 16, 16, 16, 18, 18, 18, 18,
90 17, 17, 17, 17, 16, 16, 16, 16,
91 17, 17, 17, 17, 17, 17, 2,
92 17, 17, 17, 17, 32, 32, 32, 32
95 static char* etm_reg_list
[] =
103 "ETM_TRACE_RESOURCE_CTRL",
104 "ETM_TRACE_EN_CTRL2",
105 "ETM_TRACE_EN_EVENT",
106 "ETM_TRACE_EN_CTRL1",
107 "ETM_FIFOFULL_REGION",
108 "ETM_FIFOFULL_LEVEL",
109 "ETM_VIEWDATA_EVENT",
110 "ETM_VIEWDATA_CTRL1",
111 "ETM_VIEWDATA_CTRL2",
112 "ETM_VIEWDATA_CTRL3",
113 "ETM_ADDR_COMPARATOR_VALUE1",
114 "ETM_ADDR_COMPARATOR_VALUE2",
115 "ETM_ADDR_COMPARATOR_VALUE3",
116 "ETM_ADDR_COMPARATOR_VALUE4",
117 "ETM_ADDR_COMPARATOR_VALUE5",
118 "ETM_ADDR_COMPARATOR_VALUE6",
119 "ETM_ADDR_COMPARATOR_VALUE7",
120 "ETM_ADDR_COMPARATOR_VALUE8",
121 "ETM_ADDR_COMPARATOR_VALUE9",
122 "ETM_ADDR_COMPARATOR_VALUE10",
123 "ETM_ADDR_COMPARATOR_VALUE11",
124 "ETM_ADDR_COMPARATOR_VALUE12",
125 "ETM_ADDR_COMPARATOR_VALUE13",
126 "ETM_ADDR_COMPARATOR_VALUE14",
127 "ETM_ADDR_COMPARATOR_VALUE15",
128 "ETM_ADDR_COMPARATOR_VALUE16",
129 "ETM_ADDR_ACCESS_TYPE1",
130 "ETM_ADDR_ACCESS_TYPE2",
131 "ETM_ADDR_ACCESS_TYPE3",
132 "ETM_ADDR_ACCESS_TYPE4",
133 "ETM_ADDR_ACCESS_TYPE5",
134 "ETM_ADDR_ACCESS_TYPE6",
135 "ETM_ADDR_ACCESS_TYPE7",
136 "ETM_ADDR_ACCESS_TYPE8",
137 "ETM_ADDR_ACCESS_TYPE9",
138 "ETM_ADDR_ACCESS_TYPE10",
139 "ETM_ADDR_ACCESS_TYPE11",
140 "ETM_ADDR_ACCESS_TYPE12",
141 "ETM_ADDR_ACCESS_TYPE13",
142 "ETM_ADDR_ACCESS_TYPE14",
143 "ETM_ADDR_ACCESS_TYPE15",
144 "ETM_ADDR_ACCESS_TYPE16",
145 "ETM_DATA_COMPARATOR_VALUE1",
146 "ETM_DATA_COMPARATOR_VALUE2",
147 "ETM_DATA_COMPARATOR_VALUE3",
148 "ETM_DATA_COMPARATOR_VALUE4",
149 "ETM_DATA_COMPARATOR_VALUE5",
150 "ETM_DATA_COMPARATOR_VALUE6",
151 "ETM_DATA_COMPARATOR_VALUE7",
152 "ETM_DATA_COMPARATOR_VALUE8",
153 "ETM_DATA_COMPARATOR_VALUE9",
154 "ETM_DATA_COMPARATOR_VALUE10",
155 "ETM_DATA_COMPARATOR_VALUE11",
156 "ETM_DATA_COMPARATOR_VALUE12",
157 "ETM_DATA_COMPARATOR_VALUE13",
158 "ETM_DATA_COMPARATOR_VALUE14",
159 "ETM_DATA_COMPARATOR_VALUE15",
160 "ETM_DATA_COMPARATOR_VALUE16",
161 "ETM_DATA_COMPARATOR_MASK1",
162 "ETM_DATA_COMPARATOR_MASK2",
163 "ETM_DATA_COMPARATOR_MASK3",
164 "ETM_DATA_COMPARATOR_MASK4",
165 "ETM_DATA_COMPARATOR_MASK5",
166 "ETM_DATA_COMPARATOR_MASK6",
167 "ETM_DATA_COMPARATOR_MASK7",
168 "ETM_DATA_COMPARATOR_MASK8",
169 "ETM_DATA_COMPARATOR_MASK9",
170 "ETM_DATA_COMPARATOR_MASK10",
171 "ETM_DATA_COMPARATOR_MASK11",
172 "ETM_DATA_COMPARATOR_MASK12",
173 "ETM_DATA_COMPARATOR_MASK13",
174 "ETM_DATA_COMPARATOR_MASK14",
175 "ETM_DATA_COMPARATOR_MASK15",
176 "ETM_DATA_COMPARATOR_MASK16",
177 "ETM_COUNTER_INITAL_VALUE1",
178 "ETM_COUNTER_INITAL_VALUE2",
179 "ETM_COUNTER_INITAL_VALUE3",
180 "ETM_COUNTER_INITAL_VALUE4",
181 "ETM_COUNTER_ENABLE1",
182 "ETM_COUNTER_ENABLE2",
183 "ETM_COUNTER_ENABLE3",
184 "ETM_COUNTER_ENABLE4",
185 "ETM_COUNTER_RELOAD_VALUE1",
186 "ETM_COUNTER_RELOAD_VALUE2",
187 "ETM_COUNTER_RELOAD_VALUE3",
188 "ETM_COUNTER_RELOAD_VALUE4",
189 "ETM_COUNTER_VALUE1",
190 "ETM_COUNTER_VALUE2",
191 "ETM_COUNTER_VALUE3",
192 "ETM_COUNTER_VALUE4",
193 "ETM_SEQUENCER_CTRL1",
194 "ETM_SEQUENCER_CTRL2",
195 "ETM_SEQUENCER_CTRL3",
196 "ETM_SEQUENCER_CTRL4",
197 "ETM_SEQUENCER_CTRL5",
198 "ETM_SEQUENCER_CTRL6",
199 "ETM_SEQUENCER_STATE",
200 "ETM_EXTERNAL_OUTPUT1",
201 "ETM_EXTERNAL_OUTPUT2",
202 "ETM_EXTERNAL_OUTPUT3",
203 "ETM_EXTERNAL_OUTPUT4",
204 "ETM_CONTEXTID_COMPARATOR_VALUE1",
205 "ETM_CONTEXTID_COMPARATOR_VALUE2",
206 "ETM_CONTEXTID_COMPARATOR_VALUE3",
207 "ETM_CONTEXTID_COMPARATOR_MASK"
210 static int etm_reg_arch_type
= -1;
212 static int etm_get_reg(reg_t
*reg
);
214 static command_t
*etm_cmd
= NULL
;
216 reg_cache_t
* etm_build_reg_cache(target_t
*target
, arm_jtag_t
*jtag_info
, etm_context_t
*etm_ctx
)
218 reg_cache_t
*reg_cache
= malloc(sizeof(reg_cache_t
));
219 reg_t
*reg_list
= NULL
;
220 etm_reg_t
*arch_info
= NULL
;
221 int num_regs
= sizeof(etm_reg_arch_info
)/sizeof(int);
224 /* register a register arch-type for etm registers only once */
225 if (etm_reg_arch_type
== -1)
226 etm_reg_arch_type
= register_reg_arch_type(etm_get_reg
, etm_set_reg_w_exec
);
228 /* the actual registers are kept in two arrays */
229 reg_list
= calloc(num_regs
, sizeof(reg_t
));
230 arch_info
= calloc(num_regs
, sizeof(etm_reg_t
));
232 /* fill in values for the reg cache */
233 reg_cache
->name
= "etm registers";
234 reg_cache
->next
= NULL
;
235 reg_cache
->reg_list
= reg_list
;
236 reg_cache
->num_regs
= num_regs
;
238 /* set up registers */
239 for (i
= 0; i
< num_regs
; i
++)
241 reg_list
[i
].name
= etm_reg_list
[i
];
242 reg_list
[i
].size
= 32;
243 reg_list
[i
].dirty
= 0;
244 reg_list
[i
].valid
= 0;
245 reg_list
[i
].bitfield_desc
= NULL
;
246 reg_list
[i
].num_bitfields
= 0;
247 reg_list
[i
].value
= calloc(1, 4);
248 reg_list
[i
].arch_info
= &arch_info
[i
];
249 reg_list
[i
].arch_type
= etm_reg_arch_type
;
250 reg_list
[i
].size
= etm_reg_arch_size_info
[i
];
251 arch_info
[i
].addr
= etm_reg_arch_info
[i
];
252 arch_info
[i
].jtag_info
= jtag_info
;
255 /* the ETM might have an ETB connected */
256 if (strcmp(etm_ctx
->capture_driver
->name
, "etb") == 0)
258 etb_t
*etb
= etm_ctx
->capture_driver_priv
;
262 LOG_ERROR("etb selected as etm capture driver, but no ETB configured");
266 reg_cache
->next
= etb_build_reg_cache(etb
);
268 etb
->reg_cache
= reg_cache
->next
;
275 int etm_setup(target_t
*target
)
279 armv4_5_common_t
*armv4_5
= target
->arch_info
;
280 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
281 etm_context_t
*etm_ctx
= arm7_9
->etm_ctx
;
282 reg_t
*etm_ctrl_reg
= &arm7_9
->etm_ctx
->reg_cache
->reg_list
[ETM_CTRL
];
284 /* initialize some ETM control register settings */
285 etm_get_reg(etm_ctrl_reg
);
286 etm_ctrl_value
= buf_get_u32(etm_ctrl_reg
->value
, 0, etm_ctrl_reg
->size
);
288 /* clear the ETM powerdown bit (0) */
289 etm_ctrl_value
&= ~0x1;
291 /* configure port width (6:4), mode (17:16) and clocking (13) */
292 etm_ctrl_value
= (etm_ctrl_value
&
293 ~ETM_PORT_WIDTH_MASK
& ~ETM_PORT_MODE_MASK
& ~ETM_PORT_CLOCK_MASK
)
296 buf_set_u32(etm_ctrl_reg
->value
, 0, etm_ctrl_reg
->size
, etm_ctrl_value
);
297 etm_store_reg(etm_ctrl_reg
);
299 if ((retval
=jtag_execute_queue())!=ERROR_OK
)
302 if ((retval
=etm_ctx
->capture_driver
->init(etm_ctx
)) != ERROR_OK
)
304 LOG_ERROR("ETM capture driver initialization failed");
310 int etm_get_reg(reg_t
*reg
)
314 if ((retval
= etm_read_reg(reg
)) != ERROR_OK
)
316 LOG_ERROR("BUG: error scheduling etm register read");
320 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
322 LOG_ERROR("register read failed");
329 int etm_read_reg_w_check(reg_t
*reg
, u8
* check_value
, u8
* check_mask
)
331 etm_reg_t
*etm_reg
= reg
->arch_info
;
332 u8 reg_addr
= etm_reg
->addr
& 0x7f;
333 scan_field_t fields
[3];
335 LOG_DEBUG("%i", etm_reg
->addr
);
337 jtag_add_end_state(TAP_IDLE
);
338 arm_jtag_scann(etm_reg
->jtag_info
, 0x6);
339 arm_jtag_set_instr(etm_reg
->jtag_info
, etm_reg
->jtag_info
->intest_instr
, NULL
);
341 fields
[0].tap
= etm_reg
->jtag_info
->tap
;
342 fields
[0].num_bits
= 32;
343 fields
[0].out_value
= reg
->value
;
344 fields
[0].in_value
= NULL
;
346 fields
[1].tap
= etm_reg
->jtag_info
->tap
;
347 fields
[1].num_bits
= 7;
348 fields
[1].out_value
= malloc(1);
349 buf_set_u32(fields
[1].out_value
, 0, 7, reg_addr
);
350 fields
[1].in_value
= NULL
;
352 fields
[2].tap
= etm_reg
->jtag_info
->tap
;
353 fields
[2].num_bits
= 1;
354 fields
[2].out_value
= malloc(1);
355 buf_set_u32(fields
[2].out_value
, 0, 1, 0);
356 fields
[2].in_value
= NULL
;
358 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
360 fields
[0].in_value
= reg
->value
;
362 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
364 jtag_check_value_mask(fields
+0, check_value
, check_mask
);
366 free(fields
[1].out_value
);
367 free(fields
[2].out_value
);
372 int etm_read_reg(reg_t
*reg
)
374 return etm_read_reg_w_check(reg
, NULL
, NULL
);
377 int etm_set_reg(reg_t
*reg
, u32 value
)
381 if ((retval
= etm_write_reg(reg
, value
)) != ERROR_OK
)
383 LOG_ERROR("BUG: error scheduling etm register write");
387 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
394 int etm_set_reg_w_exec(reg_t
*reg
, u8
*buf
)
398 etm_set_reg(reg
, buf_get_u32(buf
, 0, reg
->size
));
400 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
402 LOG_ERROR("register write failed");
408 int etm_write_reg(reg_t
*reg
, u32 value
)
410 etm_reg_t
*etm_reg
= reg
->arch_info
;
411 u8 reg_addr
= etm_reg
->addr
& 0x7f;
412 scan_field_t fields
[3];
414 LOG_DEBUG("%i: 0x%8.8x", etm_reg
->addr
, value
);
416 jtag_add_end_state(TAP_IDLE
);
417 arm_jtag_scann(etm_reg
->jtag_info
, 0x6);
418 arm_jtag_set_instr(etm_reg
->jtag_info
, etm_reg
->jtag_info
->intest_instr
, NULL
);
420 fields
[0].tap
= etm_reg
->jtag_info
->tap
;
421 fields
[0].num_bits
= 32;
422 fields
[0].out_value
= malloc(4);
423 buf_set_u32(fields
[0].out_value
, 0, 32, value
);
425 fields
[0].in_value
= NULL
;
427 fields
[1].tap
= etm_reg
->jtag_info
->tap
;
428 fields
[1].num_bits
= 7;
429 fields
[1].out_value
= malloc(1);
430 buf_set_u32(fields
[1].out_value
, 0, 7, reg_addr
);
432 fields
[1].in_value
= NULL
;
434 fields
[2].tap
= etm_reg
->jtag_info
->tap
;
435 fields
[2].num_bits
= 1;
436 fields
[2].out_value
= malloc(1);
437 buf_set_u32(fields
[2].out_value
, 0, 1, 1);
439 fields
[2].in_value
= NULL
;
441 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
443 free(fields
[0].out_value
);
444 free(fields
[1].out_value
);
445 free(fields
[2].out_value
);
450 int etm_store_reg(reg_t
*reg
)
452 return etm_write_reg(reg
, buf_get_u32(reg
->value
, 0, reg
->size
));
455 /* ETM trace analysis functionality
458 extern etm_capture_driver_t etm_dummy_capture_driver
;
459 #if BUILD_OOCD_TRACE == 1
460 extern etm_capture_driver_t oocd_trace_capture_driver
;
463 static etm_capture_driver_t
*etm_capture_drivers
[] =
466 &etm_dummy_capture_driver
,
467 #if BUILD_OOCD_TRACE == 1
468 &oocd_trace_capture_driver
,
473 char *etmv1v1_branch_reason_strings
[] =
477 "trace restarted after overflow",
479 "periodic synchronization",
485 static int etm_read_instruction(etm_context_t
*ctx
, arm_instruction_t
*instruction
)
494 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
496 /* search for the section the current instruction belongs to */
497 for (i
= 0; i
< ctx
->image
->num_sections
; i
++)
499 if ((ctx
->image
->sections
[i
].base_address
<= ctx
->current_pc
) &&
500 (ctx
->image
->sections
[i
].base_address
+ ctx
->image
->sections
[i
].size
> ctx
->current_pc
))
509 /* current instruction couldn't be found in the image */
510 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
513 if (ctx
->core_state
== ARMV4_5_STATE_ARM
)
516 if ((retval
= image_read_section(ctx
->image
, section
,
517 ctx
->current_pc
- ctx
->image
->sections
[section
].base_address
,
518 4, buf
, &size_read
)) != ERROR_OK
)
520 LOG_ERROR("error while reading instruction: %i", retval
);
521 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
523 opcode
= target_buffer_get_u32(ctx
->target
, buf
);
524 arm_evaluate_opcode(opcode
, ctx
->current_pc
, instruction
);
526 else if (ctx
->core_state
== ARMV4_5_STATE_THUMB
)
529 if ((retval
= image_read_section(ctx
->image
, section
,
530 ctx
->current_pc
- ctx
->image
->sections
[section
].base_address
,
531 2, buf
, &size_read
)) != ERROR_OK
)
533 LOG_ERROR("error while reading instruction: %i", retval
);
534 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
536 opcode
= target_buffer_get_u16(ctx
->target
, buf
);
537 thumb_evaluate_opcode(opcode
, ctx
->current_pc
, instruction
);
539 else if (ctx
->core_state
== ARMV4_5_STATE_JAZELLE
)
541 LOG_ERROR("BUG: tracing of jazelle code not supported");
546 LOG_ERROR("BUG: unknown core state encountered");
553 static int etmv1_next_packet(etm_context_t
*ctx
, u8
*packet
, int apo
)
555 while (ctx
->data_index
< ctx
->trace_depth
)
557 /* if the caller specified an address packet offset, skip until the
558 * we reach the n-th cycle marked with tracesync */
561 if (ctx
->trace_data
[ctx
->data_index
].flags
& ETMV1_TRACESYNC_CYCLE
)
572 /* no tracedata output during a TD cycle
573 * or in a trigger cycle */
574 if ((ctx
->trace_data
[ctx
->data_index
].pipestat
== STAT_TD
)
575 || (ctx
->trace_data
[ctx
->data_index
].flags
& ETMV1_TRIGGER_CYCLE
))
582 if ((ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_16BIT
)
584 if (ctx
->data_half
== 0)
586 *packet
= ctx
->trace_data
[ctx
->data_index
].packet
& 0xff;
591 *packet
= (ctx
->trace_data
[ctx
->data_index
].packet
& 0xff00) >> 8;
596 else if ((ctx
->portmode
& ETM_PORT_WIDTH_MASK
) == ETM_PORT_8BIT
)
598 *packet
= ctx
->trace_data
[ctx
->data_index
].packet
& 0xff;
603 /* on a 4-bit port, a packet will be output during two consecutive cycles */
604 if (ctx
->data_index
> (ctx
->trace_depth
- 2))
607 *packet
= ctx
->trace_data
[ctx
->data_index
].packet
& 0xf;
608 *packet
|= (ctx
->trace_data
[ctx
->data_index
+ 1].packet
& 0xf) << 4;
609 ctx
->data_index
+= 2;
618 static int etmv1_branch_address(etm_context_t
*ctx
)
626 /* quit analysis if less than two cycles are left in the trace
627 * because we can't extract the APO */
628 if (ctx
->data_index
> (ctx
->trace_depth
- 2))
631 /* a BE could be output during an APO cycle, skip the current
632 * and continue with the new one */
633 if (ctx
->trace_data
[ctx
->pipe_index
+ 1].pipestat
& 0x4)
635 if (ctx
->trace_data
[ctx
->pipe_index
+ 2].pipestat
& 0x4)
638 /* address packet offset encoded in the next two cycles' pipestat bits */
639 apo
= ctx
->trace_data
[ctx
->pipe_index
+ 1].pipestat
& 0x3;
640 apo
|= (ctx
->trace_data
[ctx
->pipe_index
+ 2].pipestat
& 0x3) << 2;
642 /* count number of tracesync cycles between current pipe_index and data_index
643 * i.e. the number of tracesyncs that data_index already passed by
644 * to subtract them from the APO */
645 for (i
= ctx
->pipe_index
; i
< ctx
->data_index
; i
++)
647 if (ctx
->trace_data
[ctx
->pipe_index
+ 1].pipestat
& ETMV1_TRACESYNC_CYCLE
)
651 /* extract up to four 7-bit packets */
653 if ((retval
= etmv1_next_packet(ctx
, &packet
, (shift
== 0) ? apo
+ 1 : 0)) != 0)
655 ctx
->last_branch
&= ~(0x7f << shift
);
656 ctx
->last_branch
|= (packet
& 0x7f) << shift
;
658 } while ((packet
& 0x80) && (shift
< 28));
660 /* one last packet holding 4 bits of the address, plus the branch reason code */
661 if ((shift
== 28) && (packet
& 0x80))
663 if ((retval
= etmv1_next_packet(ctx
, &packet
, 0)) != 0)
665 ctx
->last_branch
&= 0x0fffffff;
666 ctx
->last_branch
|= (packet
& 0x0f) << 28;
667 ctx
->last_branch_reason
= (packet
& 0x70) >> 4;
672 ctx
->last_branch_reason
= 0;
680 /* if a full address was output, we might have branched into Jazelle state */
681 if ((shift
== 32) && (packet
& 0x80))
683 ctx
->core_state
= ARMV4_5_STATE_JAZELLE
;
687 /* if we didn't branch into Jazelle state, the current processor state is
688 * encoded in bit 0 of the branch target address */
689 if (ctx
->last_branch
& 0x1)
691 ctx
->core_state
= ARMV4_5_STATE_THUMB
;
692 ctx
->last_branch
&= ~0x1;
696 ctx
->core_state
= ARMV4_5_STATE_ARM
;
697 ctx
->last_branch
&= ~0x3;
704 static int etmv1_data(etm_context_t
*ctx
, int size
, u32
*data
)
710 for (j
= 0; j
< size
; j
++)
712 if ((retval
= etmv1_next_packet(ctx
, &buf
[j
], 0)) != 0)
718 LOG_ERROR("TODO: add support for 64-bit values");
722 *data
= target_buffer_get_u32(ctx
->target
, buf
);
724 *data
= target_buffer_get_u16(ctx
->target
, buf
);
733 static int etmv1_analyze_trace(etm_context_t
*ctx
, struct command_context_s
*cmd_ctx
)
736 arm_instruction_t instruction
;
738 /* read the trace data if it wasn't read already */
739 if (ctx
->trace_depth
== 0)
740 ctx
->capture_driver
->read_trace(ctx
);
742 /* start at the beginning of the captured trace */
747 /* neither the PC nor the data pointer are valid */
751 while (ctx
->pipe_index
< ctx
->trace_depth
)
753 u8 pipestat
= ctx
->trace_data
[ctx
->pipe_index
].pipestat
;
754 u32 next_pc
= ctx
->current_pc
;
755 u32 old_data_index
= ctx
->data_index
;
756 u32 old_data_half
= ctx
->data_half
;
757 u32 old_index
= ctx
->pipe_index
;
758 u32 last_instruction
= ctx
->last_instruction
;
760 int current_pc_ok
= ctx
->pc_ok
;
762 if (ctx
->trace_data
[ctx
->pipe_index
].flags
& ETMV1_TRIGGER_CYCLE
)
764 command_print(cmd_ctx
, "--- trigger ---");
767 /* instructions execute in IE/D or BE/D cycles */
768 if ((pipestat
== STAT_IE
) || (pipestat
== STAT_ID
))
769 ctx
->last_instruction
= ctx
->pipe_index
;
771 /* if we don't have a valid pc skip until we reach an indirect branch */
772 if ((!ctx
->pc_ok
) && (pipestat
!= STAT_BE
))
778 /* any indirect branch could have interrupted instruction flow
779 * - the branch reason code could indicate a trace discontinuity
780 * - a branch to the exception vectors indicates an exception
782 if ((pipestat
== STAT_BE
) || (pipestat
== STAT_BD
))
784 /* backup current data index, to be able to consume the branch address
785 * before examining data address and values
787 old_data_index
= ctx
->data_index
;
788 old_data_half
= ctx
->data_half
;
790 ctx
->last_instruction
= ctx
->pipe_index
;
792 if ((retval
= etmv1_branch_address(ctx
)) != 0)
794 /* negative return value from etmv1_branch_address means we ran out of packets,
795 * quit analysing the trace */
799 /* a positive return values means the current branch was abandoned,
800 * and a new branch was encountered in cycle ctx->pipe_index + retval;
802 LOG_WARNING("abandoned branch encountered, correctnes of analysis uncertain");
803 ctx
->pipe_index
+= retval
;
807 /* skip over APO cycles */
808 ctx
->pipe_index
+= 2;
810 switch (ctx
->last_branch_reason
)
812 case 0x0: /* normal PC change */
813 next_pc
= ctx
->last_branch
;
815 case 0x1: /* tracing enabled */
816 command_print(cmd_ctx
, "--- tracing enabled at 0x%8.8x ---", ctx
->last_branch
);
817 ctx
->current_pc
= ctx
->last_branch
;
821 case 0x2: /* trace restarted after FIFO overflow */
822 command_print(cmd_ctx
, "--- trace restarted after FIFO overflow at 0x%8.8x ---", ctx
->last_branch
);
823 ctx
->current_pc
= ctx
->last_branch
;
827 case 0x3: /* exit from debug state */
828 command_print(cmd_ctx
, "--- exit from debug state at 0x%8.8x ---", ctx
->last_branch
);
829 ctx
->current_pc
= ctx
->last_branch
;
833 case 0x4: /* periodic synchronization point */
834 next_pc
= ctx
->last_branch
;
835 /* if we had no valid PC prior to this synchronization point,
836 * we have to move on with the next trace cycle
840 command_print(cmd_ctx
, "--- periodic synchronization point at 0x%8.8x ---", next_pc
);
841 ctx
->current_pc
= next_pc
;
846 default: /* reserved */
847 LOG_ERROR("BUG: branch reason code 0x%x is reserved", ctx
->last_branch_reason
);
852 /* if we got here the branch was a normal PC change
853 * (or a periodic synchronization point, which means the same for that matter)
854 * if we didn't accquire a complete PC continue with the next cycle
859 /* indirect branch to the exception vector means an exception occured */
860 if ((ctx
->last_branch
<= 0x20)
861 || ((ctx
->last_branch
>= 0xffff0000) && (ctx
->last_branch
<= 0xffff0020)))
863 if ((ctx
->last_branch
& 0xff) == 0x10)
865 command_print(cmd_ctx
, "data abort");
869 command_print(cmd_ctx
, "exception vector 0x%2.2x", ctx
->last_branch
);
870 ctx
->current_pc
= ctx
->last_branch
;
877 /* an instruction was executed (or not, depending on the condition flags)
878 * retrieve it from the image for displaying */
879 if (ctx
->pc_ok
&& (pipestat
!= STAT_WT
) && (pipestat
!= STAT_TD
) &&
880 !(((pipestat
== STAT_BE
) || (pipestat
== STAT_BD
)) &&
881 ((ctx
->last_branch_reason
!= 0x0) && (ctx
->last_branch_reason
!= 0x4))))
883 if ((retval
= etm_read_instruction(ctx
, &instruction
)) != ERROR_OK
)
885 /* can't continue tracing with no image available */
886 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
890 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
892 /* TODO: handle incomplete images
893 * for now we just quit the analsysis*/
898 cycles
= old_index
- last_instruction
;
901 if ((pipestat
== STAT_ID
) || (pipestat
== STAT_BD
))
903 u32 new_data_index
= ctx
->data_index
;
904 u32 new_data_half
= ctx
->data_half
;
906 /* in case of a branch with data, the branch target address was consumed before
907 * we temporarily go back to the saved data index */
908 if (pipestat
== STAT_BD
)
910 ctx
->data_index
= old_data_index
;
911 ctx
->data_half
= old_data_half
;
914 if (ctx
->tracemode
& ETMV1_TRACE_ADDR
)
920 if ((retval
= etmv1_next_packet(ctx
, &packet
, 0)) != 0)
921 return ERROR_ETM_ANALYSIS_FAILED
;
922 ctx
->last_ptr
&= ~(0x7f << shift
);
923 ctx
->last_ptr
|= (packet
& 0x7f) << shift
;
925 } while ((packet
& 0x80) && (shift
< 32));
932 command_print(cmd_ctx
, "address: 0x%8.8x", ctx
->last_ptr
);
936 if (ctx
->tracemode
& ETMV1_TRACE_DATA
)
938 if ((instruction
.type
== ARM_LDM
) || (instruction
.type
== ARM_STM
))
941 for (i
= 0; i
< 16; i
++)
943 if (instruction
.info
.load_store_multiple
.register_list
& (1 << i
))
946 if (etmv1_data(ctx
, 4, &data
) != 0)
947 return ERROR_ETM_ANALYSIS_FAILED
;
948 command_print(cmd_ctx
, "data: 0x%8.8x", data
);
952 else if ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_STRH
))
955 if (etmv1_data(ctx
, arm_access_size(&instruction
), &data
) != 0)
956 return ERROR_ETM_ANALYSIS_FAILED
;
957 command_print(cmd_ctx
, "data: 0x%8.8x", data
);
961 /* restore data index after consuming BD address and data */
962 if (pipestat
== STAT_BD
)
964 ctx
->data_index
= new_data_index
;
965 ctx
->data_half
= new_data_half
;
970 if ((pipestat
== STAT_IE
) || (pipestat
== STAT_ID
))
972 if (((instruction
.type
== ARM_B
) ||
973 (instruction
.type
== ARM_BL
) ||
974 (instruction
.type
== ARM_BLX
)) &&
975 (instruction
.info
.b_bl_bx_blx
.target_address
!= 0xffffffff))
977 next_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
981 next_pc
+= (ctx
->core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
984 else if (pipestat
== STAT_IN
)
986 next_pc
+= (ctx
->core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
989 if ((pipestat
!= STAT_TD
) && (pipestat
!= STAT_WT
))
991 char cycles_text
[32] = "";
993 /* if the trace was captured with cycle accurate tracing enabled,
994 * output the number of cycles since the last executed instruction
996 if (ctx
->tracemode
& ETMV1_CYCLE_ACCURATE
)
998 snprintf(cycles_text
, 32, " (%i %s)",
1000 (cycles
== 1) ? "cycle" : "cycles");
1003 command_print(cmd_ctx
, "%s%s%s",
1005 (pipestat
== STAT_IN
) ? " (not executed)" : "",
1008 ctx
->current_pc
= next_pc
;
1010 /* packets for an instruction don't start on or before the preceding
1011 * functional pipestat (i.e. other than WT or TD)
1013 if (ctx
->data_index
<= ctx
->pipe_index
)
1015 ctx
->data_index
= ctx
->pipe_index
+ 1;
1020 ctx
->pipe_index
+= 1;
1026 static int handle_etm_tracemode_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1029 armv4_5_common_t
*armv4_5
;
1030 arm7_9_common_t
*arm7_9
;
1031 etmv1_tracemode_t tracemode
;
1033 target
= get_current_target(cmd_ctx
);
1035 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1037 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1041 if (!arm7_9
->etm_ctx
)
1043 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1047 tracemode
= arm7_9
->etm_ctx
->tracemode
;
1051 if (strcmp(args
[0], "none") == 0)
1053 tracemode
= ETMV1_TRACE_NONE
;
1055 else if (strcmp(args
[0], "data") == 0)
1057 tracemode
= ETMV1_TRACE_DATA
;
1059 else if (strcmp(args
[0], "address") == 0)
1061 tracemode
= ETMV1_TRACE_ADDR
;
1063 else if (strcmp(args
[0], "all") == 0)
1065 tracemode
= ETMV1_TRACE_DATA
| ETMV1_TRACE_ADDR
;
1069 command_print(cmd_ctx
, "invalid option '%s'", args
[0]);
1073 switch (strtol(args
[1], NULL
, 0))
1076 tracemode
|= ETMV1_CONTEXTID_NONE
;
1079 tracemode
|= ETMV1_CONTEXTID_8
;
1082 tracemode
|= ETMV1_CONTEXTID_16
;
1085 tracemode
|= ETMV1_CONTEXTID_32
;
1088 command_print(cmd_ctx
, "invalid option '%s'", args
[1]);
1092 if (strcmp(args
[2], "enable") == 0)
1094 tracemode
|= ETMV1_CYCLE_ACCURATE
;
1096 else if (strcmp(args
[2], "disable") == 0)
1102 command_print(cmd_ctx
, "invalid option '%s'", args
[2]);
1106 if (strcmp(args
[3], "enable") == 0)
1108 tracemode
|= ETMV1_BRANCH_OUTPUT
;
1110 else if (strcmp(args
[3], "disable") == 0)
1116 command_print(cmd_ctx
, "invalid option '%s'", args
[2]);
1122 command_print(cmd_ctx
, "usage: configure trace mode <none|data|address|all> <context id bits> <cycle accurate> <branch output>");
1126 command_print(cmd_ctx
, "current tracemode configuration:");
1128 switch (tracemode
& ETMV1_TRACE_MASK
)
1130 case ETMV1_TRACE_NONE
:
1131 command_print(cmd_ctx
, "data tracing: none");
1133 case ETMV1_TRACE_DATA
:
1134 command_print(cmd_ctx
, "data tracing: data only");
1136 case ETMV1_TRACE_ADDR
:
1137 command_print(cmd_ctx
, "data tracing: address only");
1139 case ETMV1_TRACE_DATA
| ETMV1_TRACE_ADDR
:
1140 command_print(cmd_ctx
, "data tracing: address and data");
1144 switch (tracemode
& ETMV1_CONTEXTID_MASK
)
1146 case ETMV1_CONTEXTID_NONE
:
1147 command_print(cmd_ctx
, "contextid tracing: none");
1149 case ETMV1_CONTEXTID_8
:
1150 command_print(cmd_ctx
, "contextid tracing: 8 bit");
1152 case ETMV1_CONTEXTID_16
:
1153 command_print(cmd_ctx
, "contextid tracing: 16 bit");
1155 case ETMV1_CONTEXTID_32
:
1156 command_print(cmd_ctx
, "contextid tracing: 32 bit");
1160 if (tracemode
& ETMV1_CYCLE_ACCURATE
)
1162 command_print(cmd_ctx
, "cycle-accurate tracing enabled");
1166 command_print(cmd_ctx
, "cycle-accurate tracing disabled");
1169 if (tracemode
& ETMV1_BRANCH_OUTPUT
)
1171 command_print(cmd_ctx
, "full branch address output enabled");
1175 command_print(cmd_ctx
, "full branch address output disabled");
1178 /* only update ETM_CTRL register if tracemode changed */
1179 if (arm7_9
->etm_ctx
->tracemode
!= tracemode
)
1181 reg_t
*etm_ctrl_reg
= &arm7_9
->etm_ctx
->reg_cache
->reg_list
[ETM_CTRL
];
1183 etm_get_reg(etm_ctrl_reg
);
1185 buf_set_u32(etm_ctrl_reg
->value
, 2, 2, tracemode
& ETMV1_TRACE_MASK
);
1186 buf_set_u32(etm_ctrl_reg
->value
, 14, 2, (tracemode
& ETMV1_CONTEXTID_MASK
) >> 4);
1187 buf_set_u32(etm_ctrl_reg
->value
, 12, 1, (tracemode
& ETMV1_CYCLE_ACCURATE
) >> 8);
1188 buf_set_u32(etm_ctrl_reg
->value
, 8, 1, (tracemode
& ETMV1_BRANCH_OUTPUT
) >> 9);
1189 etm_store_reg(etm_ctrl_reg
);
1191 arm7_9
->etm_ctx
->tracemode
= tracemode
;
1193 /* invalidate old trace data */
1194 arm7_9
->etm_ctx
->capture_status
= TRACE_IDLE
;
1195 if (arm7_9
->etm_ctx
->trace_depth
> 0)
1197 free(arm7_9
->etm_ctx
->trace_data
);
1198 arm7_9
->etm_ctx
->trace_data
= NULL
;
1200 arm7_9
->etm_ctx
->trace_depth
= 0;
1206 static int handle_etm_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1209 armv4_5_common_t
*armv4_5
;
1210 arm7_9_common_t
*arm7_9
;
1211 etm_portmode_t portmode
= 0x0;
1212 etm_context_t
*etm_ctx
= malloc(sizeof(etm_context_t
));
1217 return ERROR_COMMAND_SYNTAX_ERROR
;
1220 target
= get_target_by_num(strtoul(args
[0], NULL
, 0));
1224 LOG_ERROR("target number '%s' not defined", args
[0]);
1228 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1230 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1234 switch (strtoul(args
[1], NULL
, 0))
1237 portmode
|= ETM_PORT_4BIT
;
1240 portmode
|= ETM_PORT_8BIT
;
1243 portmode
|= ETM_PORT_16BIT
;
1246 command_print(cmd_ctx
, "unsupported ETM port width '%s', must be 4, 8 or 16", args
[1]);
1250 if (strcmp("normal", args
[2]) == 0)
1252 portmode
|= ETM_PORT_NORMAL
;
1254 else if (strcmp("multiplexed", args
[2]) == 0)
1256 portmode
|= ETM_PORT_MUXED
;
1258 else if (strcmp("demultiplexed", args
[2]) == 0)
1260 portmode
|= ETM_PORT_DEMUXED
;
1264 command_print(cmd_ctx
, "unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'", args
[2]);
1268 if (strcmp("half", args
[3]) == 0)
1270 portmode
|= ETM_PORT_HALF_CLOCK
;
1272 else if (strcmp("full", args
[3]) == 0)
1274 portmode
|= ETM_PORT_FULL_CLOCK
;
1278 command_print(cmd_ctx
, "unsupported ETM port clocking '%s', must be 'full' or 'half'", args
[3]);
1282 for (i
=0; etm_capture_drivers
[i
]; i
++)
1284 if (strcmp(args
[4], etm_capture_drivers
[i
]->name
) == 0)
1287 if ((retval
=etm_capture_drivers
[i
]->register_commands(cmd_ctx
)) != ERROR_OK
)
1293 etm_ctx
->capture_driver
= etm_capture_drivers
[i
];
1299 if (!etm_capture_drivers
[i
])
1301 /* no supported capture driver found, don't register an ETM */
1303 LOG_ERROR("trace capture driver '%s' not found", args
[4]);
1307 etm_ctx
->target
= target
;
1308 etm_ctx
->trigger_percent
= 50;
1309 etm_ctx
->trace_data
= NULL
;
1310 etm_ctx
->trace_depth
= 0;
1311 etm_ctx
->portmode
= portmode
;
1312 etm_ctx
->tracemode
= 0x0;
1313 etm_ctx
->core_state
= ARMV4_5_STATE_ARM
;
1314 etm_ctx
->image
= NULL
;
1315 etm_ctx
->pipe_index
= 0;
1316 etm_ctx
->data_index
= 0;
1317 etm_ctx
->current_pc
= 0x0;
1319 etm_ctx
->last_branch
= 0x0;
1320 etm_ctx
->last_branch_reason
= 0x0;
1321 etm_ctx
->last_ptr
= 0x0;
1322 etm_ctx
->ptr_ok
= 0x0;
1323 etm_ctx
->context_id
= 0x0;
1324 etm_ctx
->last_instruction
= 0;
1326 arm7_9
->etm_ctx
= etm_ctx
;
1328 return etm_register_user_commands(cmd_ctx
);
1331 int handle_etm_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1334 armv4_5_common_t
*armv4_5
;
1335 arm7_9_common_t
*arm7_9
;
1336 reg_t
*etm_config_reg
;
1337 reg_t
*etm_sys_config_reg
;
1341 target
= get_current_target(cmd_ctx
);
1343 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1345 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1349 if (!arm7_9
->etm_ctx
)
1351 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1355 etm_config_reg
= &arm7_9
->etm_ctx
->reg_cache
->reg_list
[ETM_CONFIG
];
1356 etm_sys_config_reg
= &arm7_9
->etm_ctx
->reg_cache
->reg_list
[ETM_SYS_CONFIG
];
1358 etm_get_reg(etm_config_reg
);
1359 command_print(cmd_ctx
, "pairs of address comparators: %i", buf_get_u32(etm_config_reg
->value
, 0, 4));
1360 command_print(cmd_ctx
, "pairs of data comparators: %i", buf_get_u32(etm_config_reg
->value
, 4, 4));
1361 command_print(cmd_ctx
, "memory map decoders: %i", buf_get_u32(etm_config_reg
->value
, 8, 5));
1362 command_print(cmd_ctx
, "number of counters: %i", buf_get_u32(etm_config_reg
->value
, 13, 3));
1363 command_print(cmd_ctx
, "sequencer %spresent",
1364 (buf_get_u32(etm_config_reg
->value
, 16, 1) == 1) ? "" : "not ");
1365 command_print(cmd_ctx
, "number of ext. inputs: %i", buf_get_u32(etm_config_reg
->value
, 17, 3));
1366 command_print(cmd_ctx
, "number of ext. outputs: %i", buf_get_u32(etm_config_reg
->value
, 20, 3));
1367 command_print(cmd_ctx
, "FIFO full %spresent",
1368 (buf_get_u32(etm_config_reg
->value
, 23, 1) == 1) ? "" : "not ");
1369 command_print(cmd_ctx
, "protocol version: %i", buf_get_u32(etm_config_reg
->value
, 28, 3));
1371 etm_get_reg(etm_sys_config_reg
);
1373 switch (buf_get_u32(etm_sys_config_reg
->value
, 0, 3))
1385 LOG_ERROR("Illegal max_port_size");
1388 command_print(cmd_ctx
, "max. port size: %i", max_port_size
);
1390 command_print(cmd_ctx
, "half-rate clocking %ssupported",
1391 (buf_get_u32(etm_sys_config_reg
->value
, 3, 1) == 1) ? "" : "not ");
1392 command_print(cmd_ctx
, "full-rate clocking %ssupported",
1393 (buf_get_u32(etm_sys_config_reg
->value
, 4, 1) == 1) ? "" : "not ");
1394 command_print(cmd_ctx
, "normal trace format %ssupported",
1395 (buf_get_u32(etm_sys_config_reg
->value
, 5, 1) == 1) ? "" : "not ");
1396 command_print(cmd_ctx
, "multiplex trace format %ssupported",
1397 (buf_get_u32(etm_sys_config_reg
->value
, 6, 1) == 1) ? "" : "not ");
1398 command_print(cmd_ctx
, "demultiplex trace format %ssupported",
1399 (buf_get_u32(etm_sys_config_reg
->value
, 7, 1) == 1) ? "" : "not ");
1400 command_print(cmd_ctx
, "FIFO full %ssupported",
1401 (buf_get_u32(etm_sys_config_reg
->value
, 8, 1) == 1) ? "" : "not ");
1406 static int handle_etm_status_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1409 armv4_5_common_t
*armv4_5
;
1410 arm7_9_common_t
*arm7_9
;
1411 trace_status_t trace_status
;
1413 target
= get_current_target(cmd_ctx
);
1415 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1417 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1421 if (!arm7_9
->etm_ctx
)
1423 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1427 trace_status
= arm7_9
->etm_ctx
->capture_driver
->status(arm7_9
->etm_ctx
);
1429 if (trace_status
== TRACE_IDLE
)
1431 command_print(cmd_ctx
, "tracing is idle");
1435 static char *completed
= " completed";
1436 static char *running
= " is running";
1437 static char *overflowed
= ", trace overflowed";
1438 static char *triggered
= ", trace triggered";
1440 command_print(cmd_ctx
, "trace collection%s%s%s",
1441 (trace_status
& TRACE_RUNNING
) ? running
: completed
,
1442 (trace_status
& TRACE_OVERFLOWED
) ? overflowed
: "",
1443 (trace_status
& TRACE_TRIGGERED
) ? triggered
: "");
1445 if (arm7_9
->etm_ctx
->trace_depth
> 0)
1447 command_print(cmd_ctx
, "%i frames of trace data read", arm7_9
->etm_ctx
->trace_depth
);
1454 static int handle_etm_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1457 armv4_5_common_t
*armv4_5
;
1458 arm7_9_common_t
*arm7_9
;
1459 etm_context_t
*etm_ctx
;
1463 command_print(cmd_ctx
, "usage: etm image <file> [base address] [type]");
1467 target
= get_current_target(cmd_ctx
);
1469 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1471 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1475 if (!(etm_ctx
= arm7_9
->etm_ctx
))
1477 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1483 image_close(etm_ctx
->image
);
1484 free(etm_ctx
->image
);
1485 command_print(cmd_ctx
, "previously loaded image found and closed");
1488 etm_ctx
->image
= malloc(sizeof(image_t
));
1489 etm_ctx
->image
->base_address_set
= 0;
1490 etm_ctx
->image
->start_address_set
= 0;
1492 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1495 etm_ctx
->image
->base_address_set
= 1;
1496 etm_ctx
->image
->base_address
= strtoul(args
[1], NULL
, 0);
1500 etm_ctx
->image
->base_address_set
= 0;
1503 if (image_open(etm_ctx
->image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
1505 free(etm_ctx
->image
);
1506 etm_ctx
->image
= NULL
;
1513 static int handle_etm_dump_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1517 armv4_5_common_t
*armv4_5
;
1518 arm7_9_common_t
*arm7_9
;
1519 etm_context_t
*etm_ctx
;
1524 command_print(cmd_ctx
, "usage: etm dump <file>");
1528 target
= get_current_target(cmd_ctx
);
1530 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1532 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1536 if (!(etm_ctx
= arm7_9
->etm_ctx
))
1538 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1542 if (etm_ctx
->capture_driver
->status
== TRACE_IDLE
)
1544 command_print(cmd_ctx
, "trace capture wasn't enabled, no trace data captured");
1548 if (etm_ctx
->capture_driver
->status(etm_ctx
) & TRACE_RUNNING
)
1550 /* TODO: if on-the-fly capture is to be supported, this needs to be changed */
1551 command_print(cmd_ctx
, "trace capture not completed");
1555 /* read the trace data if it wasn't read already */
1556 if (etm_ctx
->trace_depth
== 0)
1557 etm_ctx
->capture_driver
->read_trace(etm_ctx
);
1559 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
1564 fileio_write_u32(&file
, etm_ctx
->capture_status
);
1565 fileio_write_u32(&file
, etm_ctx
->portmode
);
1566 fileio_write_u32(&file
, etm_ctx
->tracemode
);
1567 fileio_write_u32(&file
, etm_ctx
->trace_depth
);
1569 for (i
= 0; i
< etm_ctx
->trace_depth
; i
++)
1571 fileio_write_u32(&file
, etm_ctx
->trace_data
[i
].pipestat
);
1572 fileio_write_u32(&file
, etm_ctx
->trace_data
[i
].packet
);
1573 fileio_write_u32(&file
, etm_ctx
->trace_data
[i
].flags
);
1576 fileio_close(&file
);
1581 static int handle_etm_load_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1585 armv4_5_common_t
*armv4_5
;
1586 arm7_9_common_t
*arm7_9
;
1587 etm_context_t
*etm_ctx
;
1592 command_print(cmd_ctx
, "usage: etm load <file>");
1596 target
= get_current_target(cmd_ctx
);
1598 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1600 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1604 if (!(etm_ctx
= arm7_9
->etm_ctx
))
1606 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1610 if (etm_ctx
->capture_driver
->status(etm_ctx
) & TRACE_RUNNING
)
1612 command_print(cmd_ctx
, "trace capture running, stop first");
1616 if (fileio_open(&file
, args
[0], FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1623 command_print(cmd_ctx
, "size isn't a multiple of 4, no valid trace data");
1624 fileio_close(&file
);
1628 if (etm_ctx
->trace_depth
> 0)
1630 free(etm_ctx
->trace_data
);
1631 etm_ctx
->trace_data
= NULL
;
1634 fileio_read_u32(&file
, &etm_ctx
->capture_status
);
1635 fileio_read_u32(&file
, &etm_ctx
->portmode
);
1636 fileio_read_u32(&file
, &etm_ctx
->tracemode
);
1637 fileio_read_u32(&file
, &etm_ctx
->trace_depth
);
1639 etm_ctx
->trace_data
= malloc(sizeof(etmv1_trace_data_t
) * etm_ctx
->trace_depth
);
1640 if (etm_ctx
->trace_data
== NULL
)
1642 command_print(cmd_ctx
, "not enough memory to perform operation");
1643 fileio_close(&file
);
1647 for (i
= 0; i
< etm_ctx
->trace_depth
; i
++)
1649 u32 pipestat
, packet
, flags
;
1650 fileio_read_u32(&file
, &pipestat
);
1651 fileio_read_u32(&file
, &packet
);
1652 fileio_read_u32(&file
, &flags
);
1653 etm_ctx
->trace_data
[i
].pipestat
= pipestat
& 0xff;
1654 etm_ctx
->trace_data
[i
].packet
= packet
& 0xffff;
1655 etm_ctx
->trace_data
[i
].flags
= flags
;
1658 fileio_close(&file
);
1663 static int handle_etm_trigger_percent_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1666 armv4_5_common_t
*armv4_5
;
1667 arm7_9_common_t
*arm7_9
;
1668 etm_context_t
*etm_ctx
;
1670 target
= get_current_target(cmd_ctx
);
1672 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1674 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1678 if (!(etm_ctx
= arm7_9
->etm_ctx
))
1680 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1686 u32 new_value
= strtoul(args
[0], NULL
, 0);
1688 if ((new_value
< 2) || (new_value
> 100))
1690 command_print(cmd_ctx
, "valid settings are 2% to 100%");
1694 etm_ctx
->trigger_percent
= new_value
;
1698 command_print(cmd_ctx
, "%i percent of the tracebuffer reserved for after the trigger", etm_ctx
->trigger_percent
);
1703 static int handle_etm_start_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1706 armv4_5_common_t
*armv4_5
;
1707 arm7_9_common_t
*arm7_9
;
1708 etm_context_t
*etm_ctx
;
1709 reg_t
*etm_ctrl_reg
;
1711 target
= get_current_target(cmd_ctx
);
1713 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1715 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1719 if (!(etm_ctx
= arm7_9
->etm_ctx
))
1721 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1725 /* invalidate old tracing data */
1726 arm7_9
->etm_ctx
->capture_status
= TRACE_IDLE
;
1727 if (arm7_9
->etm_ctx
->trace_depth
> 0)
1729 free(arm7_9
->etm_ctx
->trace_data
);
1730 arm7_9
->etm_ctx
->trace_data
= NULL
;
1732 arm7_9
->etm_ctx
->trace_depth
= 0;
1734 etm_ctrl_reg
= &arm7_9
->etm_ctx
->reg_cache
->reg_list
[ETM_CTRL
];
1735 etm_get_reg(etm_ctrl_reg
);
1737 /* Clear programming bit (10), set port selection bit (11) */
1738 buf_set_u32(etm_ctrl_reg
->value
, 10, 2, 0x2);
1740 etm_store_reg(etm_ctrl_reg
);
1741 jtag_execute_queue();
1743 etm_ctx
->capture_driver
->start_capture(etm_ctx
);
1748 static int handle_etm_stop_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1751 armv4_5_common_t
*armv4_5
;
1752 arm7_9_common_t
*arm7_9
;
1753 etm_context_t
*etm_ctx
;
1754 reg_t
*etm_ctrl_reg
;
1756 target
= get_current_target(cmd_ctx
);
1758 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1760 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1764 if (!(etm_ctx
= arm7_9
->etm_ctx
))
1766 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1770 etm_ctrl_reg
= &arm7_9
->etm_ctx
->reg_cache
->reg_list
[ETM_CTRL
];
1771 etm_get_reg(etm_ctrl_reg
);
1773 /* Set programming bit (10), clear port selection bit (11) */
1774 buf_set_u32(etm_ctrl_reg
->value
, 10, 2, 0x1);
1776 etm_store_reg(etm_ctrl_reg
);
1777 jtag_execute_queue();
1779 etm_ctx
->capture_driver
->stop_capture(etm_ctx
);
1784 static int handle_etm_analyze_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1787 armv4_5_common_t
*armv4_5
;
1788 arm7_9_common_t
*arm7_9
;
1789 etm_context_t
*etm_ctx
;
1792 target
= get_current_target(cmd_ctx
);
1794 if (arm7_9_get_arch_pointers(target
, &armv4_5
, &arm7_9
) != ERROR_OK
)
1796 command_print(cmd_ctx
, "current target isn't an ARM7/ARM9 target");
1800 if (!(etm_ctx
= arm7_9
->etm_ctx
))
1802 command_print(cmd_ctx
, "current target doesn't have an ETM configured");
1806 if ((retval
= etmv1_analyze_trace(etm_ctx
, cmd_ctx
)) != ERROR_OK
)
1810 case ERROR_ETM_ANALYSIS_FAILED
:
1811 command_print(cmd_ctx
, "further analysis failed (corrupted trace data or just end of data");
1813 case ERROR_TRACE_INSTRUCTION_UNAVAILABLE
:
1814 command_print(cmd_ctx
, "no instruction for current address available, analysis aborted");
1816 case ERROR_TRACE_IMAGE_UNAVAILABLE
:
1817 command_print(cmd_ctx
, "no image available for trace analysis");
1820 command_print(cmd_ctx
, "unknown error: %i", retval
);
1827 int etm_register_commands(struct command_context_s
*cmd_ctx
)
1829 etm_cmd
= register_command(cmd_ctx
, NULL
, "etm", NULL
, COMMAND_ANY
, "Embedded Trace Macrocell");
1831 register_command(cmd_ctx
, etm_cmd
, "config", handle_etm_config_command
, COMMAND_CONFIG
, "etm config <target> <port_width> <port_mode> <clocking> <capture_driver>");
1836 int etm_register_user_commands(struct command_context_s
*cmd_ctx
)
1838 register_command(cmd_ctx
, etm_cmd
, "tracemode", handle_etm_tracemode_command
,
1839 COMMAND_EXEC
, "configure trace mode <none|data|address|all> <context id bits> <cycle accurate> <branch output");
1841 register_command(cmd_ctx
, etm_cmd
, "info", handle_etm_info_command
,
1842 COMMAND_EXEC
, "display info about the current target's ETM");
1844 register_command(cmd_ctx
, etm_cmd
, "trigger_percent <percent>", handle_etm_trigger_percent_command
,
1845 COMMAND_EXEC
, "amount (<percent>) of trace buffer to be filled after the trigger occured");
1846 register_command(cmd_ctx
, etm_cmd
, "status", handle_etm_status_command
,
1847 COMMAND_EXEC
, "display current target's ETM status");
1848 register_command(cmd_ctx
, etm_cmd
, "start", handle_etm_start_command
,
1849 COMMAND_EXEC
, "start ETM trace collection");
1850 register_command(cmd_ctx
, etm_cmd
, "stop", handle_etm_stop_command
,
1851 COMMAND_EXEC
, "stop ETM trace collection");
1853 register_command(cmd_ctx
, etm_cmd
, "analyze", handle_etm_analyze_command
,
1854 COMMAND_EXEC
, "anaylze collected ETM trace");
1856 register_command(cmd_ctx
, etm_cmd
, "image", handle_etm_image_command
,
1857 COMMAND_EXEC
, "load image from <file> [base address]");
1859 register_command(cmd_ctx
, etm_cmd
, "dump", handle_etm_dump_command
,
1860 COMMAND_EXEC
, "dump captured trace data <file>");
1861 register_command(cmd_ctx
, etm_cmd
, "load", handle_etm_load_command
,
1862 COMMAND_EXEC
, "load trace data for analysis <file>");
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)