1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2018 by Square, Inc. *
5 * Steven Stallion <stallion@squareup.com> *
6 ***************************************************************************/
12 #include <helper/binarybuffer.h>
13 #include <helper/command.h>
14 #include <helper/fileio.h>
15 #include <helper/log.h>
16 #include <helper/types.h>
17 #include <target/target.h>
21 #define BIT_MASK(x) ((1 << (x)) - 1)
24 #define CONTROL_ST (1<<0) /* Start */
25 #define CONTROL_SP (1<<1) /* Stop */
26 #define CONTROL_W (1<<2) /* Wrap */
27 #define CONTROL_FC (1<<3) /* Flow Control */
28 #define CONTROL_FMT(x) (((x) << 4) & 0x30) /* Format */
29 #define CONTROL_PCB(x) (((x) << 10) & 0x7c00) /* PC Bits */
32 #define STATUS_T (1<<0) /* Trace Started */
33 #define STATUS_TD (1<<1) /* Trace Disabled */
34 #define STATUS_W (1<<2) /* Wrapped */
35 #define STATUS_O (1<<3) /* Overflow */
38 #define TRIGGER_TST(x) (((x) << 0) & 0xf) /* Trigger Start */
39 #define TRIGGER_DST (1<<7) /* Delay Start */
40 #define TRIGGER_TSP(x) (((x) << 8) & 0xf00) /* Trigger Stop */
41 #define TRIGGER_DSP (1<<15) /* Delay Start */
43 static const char * const esirisc_trace_delay_strings
[] = {
44 "none", "start", "stop", "both",
47 static const char * const esirisc_trace_format_strings
[] = {
48 "full", "branch", "icache",
51 static const char * const esirisc_trace_id_strings
[] = {
52 "sequential instruction",
58 static const char * const esirisc_trace_ext_id_strings
[] = {
64 "multicycle instruction",
72 static const char * const esirisc_trace_trigger_strings
[] = {
73 "none", "pc", "load", "store", "exception", "eret", "wait", "stop",
74 "high", "low", /* start only */
77 static int esirisc_trace_clear_status(struct target
*target
)
79 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
80 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
83 if (target
->state
!= TARGET_HALTED
)
84 return ERROR_TARGET_NOT_HALTED
;
86 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_STATUS
, ~0);
87 if (retval
!= ERROR_OK
) {
88 LOG_ERROR("%s: failed to write Trace CSR: Status", target_name(target
));
95 static int esirisc_trace_get_status(struct target
*target
, uint32_t *status
)
97 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
98 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
100 if (target
->state
!= TARGET_HALTED
)
101 return ERROR_TARGET_NOT_HALTED
;
103 int retval
= esirisc_jtag_read_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_STATUS
, status
);
104 if (retval
!= ERROR_OK
) {
105 LOG_ERROR("%s: failed to read Trace CSR: Status", target_name(target
));
112 static int esirisc_trace_start(struct target
*target
)
114 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
115 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
119 if (target
->state
!= TARGET_HALTED
)
120 return ERROR_TARGET_NOT_HALTED
;
122 retval
= esirisc_jtag_read_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, &control
);
123 if (retval
!= ERROR_OK
) {
124 LOG_ERROR("%s: failed to read Trace CSR: Control", target_name(target
));
128 control
|= CONTROL_ST
;
130 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, control
);
131 if (retval
!= ERROR_OK
) {
132 LOG_ERROR("%s: failed to write Trace CSR: Control", target_name(target
));
139 static int esirisc_trace_stop(struct target
*target
)
141 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
142 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
146 if (target
->state
!= TARGET_HALTED
)
147 return ERROR_TARGET_NOT_HALTED
;
149 retval
= esirisc_jtag_read_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, &control
);
150 if (retval
!= ERROR_OK
) {
151 LOG_ERROR("%s: failed to read Trace CSR: Control", target_name(target
));
155 control
|= CONTROL_SP
;
157 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, control
);
158 if (retval
!= ERROR_OK
) {
159 LOG_ERROR("%s: failed to write Trace CSR: Control", target_name(target
));
166 static int esirisc_trace_init(struct target
*target
)
168 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
169 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
170 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
171 uint32_t control
, trigger
;
174 if (target
->state
!= TARGET_HALTED
)
175 return ERROR_TARGET_NOT_HALTED
;
177 /* stop if running and clear status */
178 retval
= esirisc_trace_stop(target
);
179 if (retval
!= ERROR_OK
)
182 retval
= esirisc_trace_clear_status(target
);
183 if (retval
!= ERROR_OK
)
186 /* initialize Control CSR */
187 control
= CONTROL_FMT(trace_info
->format
)
188 | CONTROL_PCB(trace_info
->pc_bits
);
190 if (trace_info
->buffer_wrap
)
191 control
|= CONTROL_W
;
193 if (trace_info
->flow_control
)
194 control
|= CONTROL_FC
;
196 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, control
);
197 if (retval
!= ERROR_OK
) {
198 LOG_ERROR("%s: failed to write Trace CSR: Control", target_name(target
));
202 /* initialize buffer CSRs */
203 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_BUFFER_START
,
204 trace_info
->buffer_start
);
205 if (retval
!= ERROR_OK
) {
206 LOG_ERROR("%s: failed to write Trace CSR: BufferStart", target_name(target
));
210 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_BUFFER_END
,
211 trace_info
->buffer_end
);
212 if (retval
!= ERROR_OK
) {
213 LOG_ERROR("%s: failed to write Trace CSR: BufferEnd", target_name(target
));
218 * The BufferCurrent CSR must be initialized to the same value as
219 * BufferStart before tracing can be enabled:
221 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_BUFFER_CUR
,
222 trace_info
->buffer_start
);
223 if (retval
!= ERROR_OK
) {
224 LOG_ERROR("%s: failed to write Trace CSR: BufferCurrent", target_name(target
));
228 /* initialize Trigger CSR */
229 trigger
= TRIGGER_TST(trace_info
->start_trigger
)
230 | TRIGGER_TSP(trace_info
->stop_trigger
);
232 if (trace_info
->delay
== ESIRISC_TRACE_DELAY_START
233 || trace_info
->delay
== ESIRISC_TRACE_DELAY_BOTH
) {
234 trigger
|= TRIGGER_DST
;
237 if (trace_info
->delay
== ESIRISC_TRACE_DELAY_STOP
238 || trace_info
->delay
== ESIRISC_TRACE_DELAY_BOTH
) {
239 trigger
|= TRIGGER_DSP
;
242 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_TRIGGER
, trigger
);
243 if (retval
!= ERROR_OK
) {
244 LOG_ERROR("%s: failed to write Trace CSR: Trigger", target_name(target
));
248 /* initialize StartData/StartMask CSRs */
249 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_START_DATA
,
250 trace_info
->start_data
);
251 if (retval
!= ERROR_OK
) {
252 LOG_ERROR("%s: failed to write Trace CSR: StartData", target_name(target
));
256 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_START_MASK
,
257 trace_info
->start_mask
);
258 if (retval
!= ERROR_OK
) {
259 LOG_ERROR("%s: failed to write Trace CSR: StartMask", target_name(target
));
263 /* initialize StopData/StopMask CSRs */
264 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_STOP_DATA
,
265 trace_info
->stop_data
);
266 if (retval
!= ERROR_OK
) {
267 LOG_ERROR("%s: failed to write Trace CSR: StopData", target_name(target
));
271 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_STOP_MASK
,
272 trace_info
->stop_mask
);
273 if (retval
!= ERROR_OK
) {
274 LOG_ERROR("%s: failed to write Trace CSR: StopMask", target_name(target
));
278 /* initialize Delay CSR */
279 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_DELAY
,
280 trace_info
->delay_cycles
);
281 if (retval
!= ERROR_OK
) {
282 LOG_ERROR("%s: failed to write Trace CSR: Delay", target_name(target
));
289 static int esirisc_trace_buf_get_u32(uint8_t *buffer
, uint32_t size
,
290 unsigned *pos
, unsigned count
, uint32_t *value
)
292 const unsigned num_bits
= size
* 8;
294 if (*pos
+count
> num_bits
)
297 *value
= buf_get_u32(buffer
, *pos
, count
);
303 static int esirisc_trace_buf_get_pc(struct target
*target
, uint8_t *buffer
, uint32_t size
,
304 unsigned *pos
, uint32_t *value
)
306 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
307 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
310 retval
= esirisc_trace_buf_get_u32(buffer
, size
, pos
, trace_info
->pc_bits
, value
);
311 if (retval
!= ERROR_OK
)
314 *value
<<= esirisc
->num_bits
- trace_info
->pc_bits
;
319 static int esirisc_trace_read_memory(struct target
*target
, target_addr_t address
, uint32_t size
,
324 if (target
->state
!= TARGET_HALTED
)
325 return ERROR_TARGET_NOT_HALTED
;
327 retval
= target_read_memory(target
, address
, 1, size
, buffer
);
328 if (retval
!= ERROR_OK
) {
329 LOG_ERROR("%s: failed to read trace data", target_name(target
));
336 static int esirisc_trace_read_buffer(struct target
*target
, uint8_t *buffer
)
338 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
339 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
340 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
341 uint32_t buffer_cur
, status
;
344 if (target
->state
!= TARGET_HALTED
)
345 return ERROR_TARGET_NOT_HALTED
;
347 retval
= esirisc_jtag_read_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_BUFFER_CUR
, &buffer_cur
);
348 if (retval
!= ERROR_OK
) {
349 LOG_ERROR("%s: failed to read Trace CSR: BufferCurrent", target_name(target
));
354 * If the buffer has wrapped, the BufferCurrent CSR indicates the
355 * next address to be written (ie. the start address). These bytes
356 * must be dumped first to maintain coherency when analyzing
359 retval
= esirisc_trace_get_status(target
, &status
);
360 if (retval
!= ERROR_OK
)
363 if (status
& STATUS_W
) {
364 uint32_t size
= trace_info
->buffer_end
- buffer_cur
;
366 retval
= esirisc_trace_read_memory(target
, buffer_cur
, size
, buffer
);
367 if (retval
!= ERROR_OK
)
373 return esirisc_trace_read_memory(target
, trace_info
->buffer_start
,
374 buffer_cur
- trace_info
->buffer_start
, buffer
);
377 static int esirisc_trace_analyze_full(struct command_invocation
*cmd
, uint8_t *buffer
, uint32_t size
)
379 struct target
*target
= get_current_target(cmd
->ctx
);
380 const uint32_t num_bits
= size
* 8;
384 while (pos
< num_bits
) {
387 retval
= esirisc_trace_buf_get_u32(buffer
, size
, &pos
, 2, &id
);
388 if (retval
!= ERROR_OK
)
392 case ESIRISC_TRACE_ID_EXECUTE
:
393 case ESIRISC_TRACE_ID_STALL
:
394 case ESIRISC_TRACE_ID_BRANCH
:
395 command_print(cmd
, "%s", esirisc_trace_id_strings
[id
]);
398 case ESIRISC_TRACE_ID_EXTENDED
: {
401 retval
= esirisc_trace_buf_get_u32(buffer
, size
, &pos
, 4, &ext_id
);
402 if (retval
!= ERROR_OK
)
406 case ESIRISC_TRACE_EXT_ID_STOP
:
407 case ESIRISC_TRACE_EXT_ID_WAIT
:
408 case ESIRISC_TRACE_EXT_ID_MULTICYCLE
:
409 command_print(cmd
, "%s", esirisc_trace_ext_id_strings
[ext_id
]);
412 case ESIRISC_TRACE_EXT_ID_ERET
:
413 case ESIRISC_TRACE_EXT_ID_PC
:
414 case ESIRISC_TRACE_EXT_ID_INDIRECT
:
415 case ESIRISC_TRACE_EXT_ID_END_PC
: {
418 retval
= esirisc_trace_buf_get_pc(target
, buffer
, size
, &pos
, &pc
);
419 if (retval
!= ERROR_OK
)
422 command_print(cmd
, "%s PC: 0x%" PRIx32
,
423 esirisc_trace_ext_id_strings
[ext_id
], pc
);
425 if (ext_id
== ESIRISC_TRACE_EXT_ID_END_PC
) {
426 command_print(cmd
, "--- end of trace ---");
431 case ESIRISC_TRACE_EXT_ID_EXCEPTION
: {
434 retval
= esirisc_trace_buf_get_u32(buffer
, size
, &pos
, 6, &eid
);
435 if (retval
!= ERROR_OK
)
438 retval
= esirisc_trace_buf_get_pc(target
, buffer
, size
, &pos
, &epc
);
439 if (retval
!= ERROR_OK
)
442 command_print(cmd
, "%s EID: 0x%" PRIx32
", EPC: 0x%" PRIx32
,
443 esirisc_trace_ext_id_strings
[ext_id
], eid
, epc
);
446 case ESIRISC_TRACE_EXT_ID_COUNT
: {
449 retval
= esirisc_trace_buf_get_u32(buffer
, size
, &pos
, 6, &count
);
450 if (retval
!= ERROR_OK
)
453 command_print(cmd
, "repeats %" PRIu32
" %s", count
,
454 (count
== 1) ? "time" : "times");
457 case ESIRISC_TRACE_EXT_ID_END
:
458 command_print(cmd
, "--- end of trace ---");
462 command_print(cmd
, "invalid extended trace ID: %" PRIu32
, ext_id
);
468 command_print(cmd
, "invalid trace ID: %" PRIu32
, id
);
474 command_print(cmd
, "trace buffer too small");
475 return ERROR_BUF_TOO_SMALL
;
478 static int esirisc_trace_analyze_simple(struct command_invocation
*cmd
, uint8_t *buffer
, uint32_t size
)
480 struct target
*target
= get_current_target(cmd
->ctx
);
481 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
482 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
483 const uint32_t end_of_trace
= BIT_MASK(trace_info
->pc_bits
) << 1;
484 const uint32_t num_bits
= size
* 8;
488 while (pos
< num_bits
) {
491 retval
= esirisc_trace_buf_get_pc(target
, buffer
, size
, &pos
, &pc
);
492 if (retval
!= ERROR_OK
)
495 if (pc
== end_of_trace
) {
496 command_print(cmd
, "--- end of trace ---");
500 command_print(cmd
, "PC: 0x%" PRIx32
, pc
);
503 command_print(cmd
, "trace buffer too small");
504 return ERROR_BUF_TOO_SMALL
;
507 static int esirisc_trace_analyze(struct command_invocation
*cmd
, uint8_t *buffer
, uint32_t size
)
509 struct target
*target
= get_current_target(cmd
->ctx
);
510 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
511 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
513 switch (trace_info
->format
) {
514 case ESIRISC_TRACE_FORMAT_FULL
:
515 command_print(cmd
, "--- full pipeline ---");
516 return esirisc_trace_analyze_full(cmd
, buffer
, size
);
518 case ESIRISC_TRACE_FORMAT_BRANCH
:
519 command_print(cmd
, "--- branches taken ---");
520 return esirisc_trace_analyze_full(cmd
, buffer
, size
);
522 case ESIRISC_TRACE_FORMAT_ICACHE
:
523 command_print(cmd
, "--- icache misses ---");
524 return esirisc_trace_analyze_simple(cmd
, buffer
, size
);
527 command_print(cmd
, "invalid trace format: %i", trace_info
->format
);
532 static int esirisc_trace_analyze_buffer(struct command_invocation
*cmd
)
534 struct target
*target
= get_current_target(cmd
->ctx
);
535 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
536 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
541 size
= esirisc_trace_buffer_size(trace_info
);
542 buffer
= calloc(1, size
);
544 command_print(cmd
, "out of memory");
548 retval
= esirisc_trace_read_buffer(target
, buffer
);
549 if (retval
!= ERROR_OK
)
552 retval
= esirisc_trace_analyze(cmd
, buffer
, size
);
560 static int esirisc_trace_analyze_memory(struct command_invocation
*cmd
,
561 target_addr_t address
, uint32_t size
)
563 struct target
*target
= get_current_target(cmd
->ctx
);
567 buffer
= calloc(1, size
);
569 command_print(cmd
, "out of memory");
573 retval
= esirisc_trace_read_memory(target
, address
, size
, buffer
);
574 if (retval
!= ERROR_OK
)
577 retval
= esirisc_trace_analyze(cmd
, buffer
, size
);
585 static int esirisc_trace_dump(struct command_invocation
*cmd
, const char *filename
,
586 uint8_t *buffer
, uint32_t size
)
588 struct fileio
*fileio
;
592 retval
= fileio_open(&fileio
, filename
, FILEIO_WRITE
, FILEIO_BINARY
);
593 if (retval
!= ERROR_OK
) {
594 command_print(cmd
, "could not open dump file: %s", filename
);
598 retval
= fileio_write(fileio
, size
, buffer
, &size_written
);
599 if (retval
== ERROR_OK
)
600 command_print(cmd
, "trace data dumped to: %s", filename
);
602 command_print(cmd
, "could not write dump file: %s", filename
);
604 fileio_close(fileio
);
609 static int esirisc_trace_dump_buffer(struct command_invocation
*cmd
, const char *filename
)
611 struct target
*target
= get_current_target(cmd
->ctx
);
612 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
613 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
618 size
= esirisc_trace_buffer_size(trace_info
);
619 buffer
= calloc(1, size
);
621 command_print(cmd
, "out of memory");
625 retval
= esirisc_trace_read_buffer(target
, buffer
);
626 if (retval
!= ERROR_OK
)
629 retval
= esirisc_trace_dump(cmd
, filename
, buffer
, size
);
637 static int esirisc_trace_dump_memory(struct command_invocation
*cmd
, const char *filename
,
638 target_addr_t address
, uint32_t size
)
640 struct target
*target
= get_current_target(cmd
->ctx
);
644 buffer
= calloc(1, size
);
646 command_print(cmd
, "out of memory");
650 retval
= esirisc_trace_read_memory(target
, address
, size
, buffer
);
651 if (retval
!= ERROR_OK
)
654 retval
= esirisc_trace_dump(cmd
, filename
, buffer
, size
);
662 COMMAND_HANDLER(handle_esirisc_trace_init_command
)
664 struct target
*target
= get_current_target(CMD_CTX
);
665 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
667 if (!esirisc
->has_trace
) {
668 command_print(CMD
, "target does not support trace");
672 int retval
= esirisc_trace_init(target
);
673 if (retval
== ERROR_OK
)
674 command_print(CMD
, "trace initialized");
679 COMMAND_HANDLER(handle_esirisc_trace_info_command
)
681 struct target
*target
= get_current_target(CMD_CTX
);
682 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
683 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
685 if (!esirisc
->has_trace
) {
686 command_print(CMD
, "target does not support trace");
690 if (esirisc_trace_is_fifo(trace_info
))
691 command_print(CMD
, "trace FIFO address: 0x%" TARGET_PRIxADDR
,
692 trace_info
->buffer_start
);
694 command_print(CMD
, "trace buffer start: 0x%" TARGET_PRIxADDR
,
695 trace_info
->buffer_start
);
696 command_print(CMD
, "trace buffer end: 0x%" TARGET_PRIxADDR
,
697 trace_info
->buffer_end
);
698 command_print(CMD
, "trace buffer will %swrap",
699 trace_info
->buffer_wrap
? "" : "not ");
702 command_print(CMD
, "flow control: %s",
703 trace_info
->flow_control
? "enabled" : "disabled");
705 command_print(CMD
, "trace format: %s",
706 esirisc_trace_format_strings
[trace_info
->format
]);
707 command_print(CMD
, "number of PC bits: %i", trace_info
->pc_bits
);
709 command_print(CMD
, "start trigger: %s",
710 esirisc_trace_trigger_strings
[trace_info
->start_trigger
]);
711 command_print(CMD
, "start data: 0x%" PRIx32
, trace_info
->start_data
);
712 command_print(CMD
, "start mask: 0x%" PRIx32
, trace_info
->start_mask
);
714 command_print(CMD
, "stop trigger: %s",
715 esirisc_trace_trigger_strings
[trace_info
->stop_trigger
]);
716 command_print(CMD
, "stop data: 0x%" PRIx32
, trace_info
->stop_data
);
717 command_print(CMD
, "stop mask: 0x%" PRIx32
, trace_info
->stop_mask
);
719 command_print(CMD
, "trigger delay: %s",
720 esirisc_trace_delay_strings
[trace_info
->delay
]);
721 command_print(CMD
, "trigger delay cycles: %" PRIu32
, trace_info
->delay_cycles
);
726 COMMAND_HANDLER(handle_esirisc_trace_status_command
)
728 struct target
*target
= get_current_target(CMD_CTX
);
729 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
732 if (!esirisc
->has_trace
) {
733 command_print(CMD
, "target does not support trace");
737 int retval
= esirisc_trace_get_status(target
, &status
);
738 if (retval
!= ERROR_OK
)
741 command_print(CMD
, "trace is %s%s%s%s",
742 (status
& STATUS_T
) ? "started" : "stopped",
743 (status
& STATUS_TD
) ? ", disabled" : "",
744 (status
& STATUS_W
) ? ", wrapped" : "",
745 (status
& STATUS_O
) ? ", overflowed" : "");
750 COMMAND_HANDLER(handle_esirisc_trace_start_command
)
752 struct target
*target
= get_current_target(CMD_CTX
);
753 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
755 if (!esirisc
->has_trace
) {
756 command_print(CMD
, "target does not support trace");
760 int retval
= esirisc_trace_start(target
);
761 if (retval
== ERROR_OK
)
762 command_print(CMD
, "trace started");
767 COMMAND_HANDLER(handle_esirisc_trace_stop_command
)
769 struct target
*target
= get_current_target(CMD_CTX
);
770 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
772 if (!esirisc
->has_trace
) {
773 command_print(CMD
, "target does not support trace");
777 int retval
= esirisc_trace_stop(target
);
778 if (retval
== ERROR_OK
)
779 command_print(CMD
, "trace stopped");
784 COMMAND_HANDLER(handle_esirisc_trace_analyze_command
)
786 struct target
*target
= get_current_target(CMD_CTX
);
787 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
788 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
789 target_addr_t address
;
792 if (!esirisc
->has_trace
) {
793 command_print(CMD
, "target does not support trace");
797 if (CMD_ARGC
!= 0 && CMD_ARGC
!= 2)
798 return ERROR_COMMAND_SYNTAX_ERROR
;
802 * Use of the Trace FIFO typically involves DMA to a peripheral
803 * (eg. SPI) or a separately managed buffer in memory, neither
804 * of which may be under our control. If the destination address
805 * and size are known in the latter case, they may be specified
806 * as arguments as a workaround.
808 if (esirisc_trace_is_fifo(trace_info
)) {
809 command_print(CMD
, "analyze from FIFO not supported");
813 return esirisc_trace_analyze_buffer(CMD
);
815 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], address
);
816 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], size
);
818 return esirisc_trace_analyze_memory(CMD
, address
, size
);
822 COMMAND_HANDLER(handle_esirisc_trace_dump_command
)
824 struct target
*target
= get_current_target(CMD_CTX
);
825 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
826 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
827 target_addr_t address
;
830 if (!esirisc
->has_trace
) {
831 command_print(CMD
, "target does not support trace");
835 if (CMD_ARGC
!= 1 && CMD_ARGC
!= 3)
836 return ERROR_COMMAND_SYNTAX_ERROR
;
839 /* also see: handle_esirisc_trace_analyze_command() */
840 if (esirisc_trace_is_fifo(trace_info
)) {
841 command_print(CMD
, "dump from FIFO not supported");
845 return esirisc_trace_dump_buffer(CMD
, CMD_ARGV
[0]);
847 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], address
);
848 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], size
);
850 return esirisc_trace_dump_memory(CMD
, CMD_ARGV
[2], address
, size
);
854 COMMAND_HANDLER(handle_esirisc_trace_buffer_command
)
856 struct target
*target
= get_current_target(CMD_CTX
);
857 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
858 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
861 if (CMD_ARGC
< 2 || CMD_ARGC
> 3)
862 return ERROR_COMMAND_SYNTAX_ERROR
;
864 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], trace_info
->buffer_start
);
865 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], size
);
867 trace_info
->buffer_end
= trace_info
->buffer_start
+ size
;
870 if (strcmp("wrap", CMD_ARGV
[2]) == 0)
871 trace_info
->buffer_wrap
= true;
873 return ERROR_COMMAND_SYNTAX_ERROR
;
879 COMMAND_HANDLER(handle_esirisc_trace_fifo_command
)
881 struct target
*target
= get_current_target(CMD_CTX
);
882 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
883 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
886 return ERROR_COMMAND_SYNTAX_ERROR
;
888 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], trace_info
->buffer_start
);
890 /* FIFOs have the same start and end address */
891 trace_info
->buffer_end
= trace_info
->buffer_start
;
892 trace_info
->buffer_wrap
= true;
897 COMMAND_HANDLER(handle_esirisc_trace_flow_control_command
)
899 struct target
*target
= get_current_target(CMD_CTX
);
900 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
901 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
904 return ERROR_COMMAND_SYNTAX_ERROR
;
906 if (strcmp(CMD_ARGV
[0], "enable") == 0)
907 trace_info
->flow_control
= true;
908 else if (strcmp(CMD_ARGV
[0], "disable") == 0)
909 trace_info
->flow_control
= false;
911 return ERROR_COMMAND_SYNTAX_ERROR
;
916 COMMAND_HANDLER(handle_esirisc_trace_format_command
)
918 struct target
*target
= get_current_target(CMD_CTX
);
919 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
920 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
924 return ERROR_COMMAND_SYNTAX_ERROR
;
926 if (strcmp(CMD_ARGV
[0], "full") == 0)
927 trace_info
->format
= ESIRISC_TRACE_FORMAT_FULL
;
928 else if (strcmp(CMD_ARGV
[0], "branch") == 0)
929 trace_info
->format
= ESIRISC_TRACE_FORMAT_BRANCH
;
930 else if (strcmp(CMD_ARGV
[0], "icache") == 0)
931 trace_info
->format
= ESIRISC_TRACE_FORMAT_ICACHE
;
933 return ERROR_COMMAND_SYNTAX_ERROR
;
935 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], pc_bits
);
937 if (pc_bits
< 1 || pc_bits
> 31) {
938 command_print(CMD
, "invalid pc_bits: %i; must be 1..31", pc_bits
);
939 return ERROR_COMMAND_SYNTAX_ERROR
;
942 trace_info
->pc_bits
= pc_bits
;
947 COMMAND_HANDLER(handle_esirisc_trace_trigger_start_command
)
949 struct target
*target
= get_current_target(CMD_CTX
);
950 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
951 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
953 if (CMD_ARGC
!= 1 && CMD_ARGC
!= 3)
954 return ERROR_COMMAND_SYNTAX_ERROR
;
956 if (strcmp(CMD_ARGV
[0], "none") == 0)
957 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_NONE
;
958 else if (strcmp(CMD_ARGV
[0], "pc") == 0)
959 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_PC
;
960 else if (strcmp(CMD_ARGV
[0], "load") == 0)
961 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_LOAD
;
962 else if (strcmp(CMD_ARGV
[0], "store") == 0)
963 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_STORE
;
964 else if (strcmp(CMD_ARGV
[0], "exception") == 0)
965 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_EXCEPTION
;
966 else if (strcmp(CMD_ARGV
[0], "eret") == 0)
967 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_ERET
;
968 else if (strcmp(CMD_ARGV
[0], "wait") == 0)
969 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_WAIT
;
970 else if (strcmp(CMD_ARGV
[0], "stop") == 0)
971 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_STOP
;
972 else if (strcmp(CMD_ARGV
[0], "high") == 0)
973 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_HIGH
;
974 else if (strcmp(CMD_ARGV
[0], "low") == 0)
975 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_LOW
;
977 return ERROR_COMMAND_SYNTAX_ERROR
;
980 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], trace_info
->start_data
);
981 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], trace_info
->start_mask
);
983 trace_info
->start_data
= 0;
984 trace_info
->start_mask
= 0;
990 COMMAND_HANDLER(handle_esirisc_trace_trigger_stop_command
)
992 struct target
*target
= get_current_target(CMD_CTX
);
993 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
994 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
996 if (CMD_ARGC
!= 1 && CMD_ARGC
!= 3)
997 return ERROR_COMMAND_SYNTAX_ERROR
;
999 if (strcmp(CMD_ARGV
[0], "none") == 0)
1000 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_NONE
;
1001 else if (strcmp(CMD_ARGV
[0], "pc") == 0)
1002 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_PC
;
1003 else if (strcmp(CMD_ARGV
[0], "load") == 0)
1004 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_LOAD
;
1005 else if (strcmp(CMD_ARGV
[0], "store") == 0)
1006 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_STORE
;
1007 else if (strcmp(CMD_ARGV
[0], "exception") == 0)
1008 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_EXCEPTION
;
1009 else if (strcmp(CMD_ARGV
[0], "eret") == 0)
1010 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_ERET
;
1011 else if (strcmp(CMD_ARGV
[0], "wait") == 0)
1012 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_WAIT
;
1013 else if (strcmp(CMD_ARGV
[0], "stop") == 0)
1014 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_STOP
;
1016 return ERROR_COMMAND_SYNTAX_ERROR
;
1018 if (CMD_ARGC
== 3) {
1019 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], trace_info
->stop_data
);
1020 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], trace_info
->stop_mask
);
1022 trace_info
->stop_data
= 0;
1023 trace_info
->stop_mask
= 0;
1029 COMMAND_HANDLER(handle_esirisc_trace_trigger_delay_command
)
1031 struct target
*target
= get_current_target(CMD_CTX
);
1032 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
1033 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
1035 if (CMD_ARGC
< 1 || CMD_ARGC
> 2)
1036 return ERROR_COMMAND_SYNTAX_ERROR
;
1038 if (strcmp(CMD_ARGV
[0], "none") == 0)
1039 trace_info
->delay
= ESIRISC_TRACE_DELAY_NONE
;
1040 else if (strcmp(CMD_ARGV
[0], "start") == 0)
1041 trace_info
->delay
= ESIRISC_TRACE_DELAY_START
;
1042 else if (strcmp(CMD_ARGV
[0], "stop") == 0)
1043 trace_info
->delay
= ESIRISC_TRACE_DELAY_STOP
;
1044 else if (strcmp(CMD_ARGV
[0], "both") == 0)
1045 trace_info
->delay
= ESIRISC_TRACE_DELAY_BOTH
;
1047 return ERROR_COMMAND_SYNTAX_ERROR
;
1049 if (trace_info
->delay
== ESIRISC_TRACE_DELAY_NONE
)
1050 trace_info
->delay_cycles
= 0;
1053 return ERROR_COMMAND_SYNTAX_ERROR
;
1055 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], trace_info
->delay_cycles
);
1061 static const struct command_registration esirisc_trace_exec_command_handlers
[] = {
1064 .handler
= handle_esirisc_trace_init_command
,
1065 .mode
= COMMAND_EXEC
,
1066 .help
= "initialize trace collection",
1071 .handler
= handle_esirisc_trace_info_command
,
1072 .mode
= COMMAND_EXEC
,
1073 .help
= "display trace configuration",
1078 .handler
= handle_esirisc_trace_status_command
,
1079 .mode
= COMMAND_EXEC
,
1080 .help
= "display trace collection status",
1085 .handler
= handle_esirisc_trace_start_command
,
1086 .mode
= COMMAND_EXEC
,
1087 .help
= "start trace collection",
1092 .handler
= handle_esirisc_trace_stop_command
,
1093 .mode
= COMMAND_EXEC
,
1094 .help
= "stop trace collection",
1099 .handler
= handle_esirisc_trace_analyze_command
,
1100 .mode
= COMMAND_EXEC
,
1101 .usage
= "[address size]",
1102 .help
= "analyze collected trace data",
1106 .handler
= handle_esirisc_trace_dump_command
,
1107 .mode
= COMMAND_EXEC
,
1108 .help
= "dump collected trace data to file",
1109 .usage
= "[address size] filename",
1111 COMMAND_REGISTRATION_DONE
1114 static const struct command_registration esirisc_trace_trigger_any_command_handlers
[] = {
1117 .handler
= handle_esirisc_trace_trigger_start_command
,
1118 .mode
= COMMAND_ANY
,
1119 .help
= "configure trigger start condition",
1120 .usage
= "('none'|'pc'|'load'|'store'|'exception'|'eret'|'wait'|'stop'|'high'|'low')"
1121 " [start_data start_mask]",
1125 .handler
= handle_esirisc_trace_trigger_stop_command
,
1126 .mode
= COMMAND_ANY
,
1127 .help
= "configure trigger stop condition",
1128 .usage
= "('none'|'pc'|'load'|'store'|'exception'|'eret'|'wait'|'stop')"
1129 " [stop_data stop_mask]",
1133 .handler
= handle_esirisc_trace_trigger_delay_command
,
1134 .mode
= COMMAND_ANY
,
1135 .help
= "configure trigger start/stop delay in clock cycles",
1136 .usage
= "('none'|'start'|'stop'|'both') [cycles]",
1138 COMMAND_REGISTRATION_DONE
1141 static const struct command_registration esirisc_trace_any_command_handlers
[] = {
1144 .handler
= handle_esirisc_trace_buffer_command
,
1145 .mode
= COMMAND_ANY
,
1146 .help
= "configure trace buffer",
1147 .usage
= "address size ['wrap']",
1151 .handler
= handle_esirisc_trace_fifo_command
,
1152 .mode
= COMMAND_ANY
,
1153 .help
= "configure trace FIFO",
1157 .name
= "flow_control",
1158 .handler
= handle_esirisc_trace_flow_control_command
,
1159 .mode
= COMMAND_ANY
,
1160 .help
= "enable or disable stalling CPU to collect trace data",
1161 .usage
= "('enable'|'disable')",
1165 .handler
= handle_esirisc_trace_format_command
,
1166 .mode
= COMMAND_ANY
,
1167 .help
= "configure trace format",
1168 .usage
= "('full'|'branch'|'icache') pc_bits",
1172 .mode
= COMMAND_ANY
,
1173 .help
= "eSi-Trace trigger command group",
1175 .chain
= esirisc_trace_trigger_any_command_handlers
,
1178 .chain
= esirisc_trace_exec_command_handlers
1180 COMMAND_REGISTRATION_DONE
1183 const struct command_registration esirisc_trace_command_handlers
[] = {
1186 .mode
= COMMAND_ANY
,
1187 .help
= "eSi-Trace command group",
1189 .chain
= esirisc_trace_any_command_handlers
,
1191 COMMAND_REGISTRATION_DONE