1 /***************************************************************************
2 * Copyright (C) 2018 by Square, Inc. *
3 * Steven Stallion <stallion@squareup.com> *
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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
23 #include <helper/binarybuffer.h>
24 #include <helper/command.h>
25 #include <helper/fileio.h>
26 #include <helper/log.h>
27 #include <helper/types.h>
28 #include <target/target.h>
32 #define BIT_MASK(x) ((1 << (x)) - 1)
35 #define CONTROL_ST (1<<0) /* Start */
36 #define CONTROL_SP (1<<1) /* Stop */
37 #define CONTROL_W (1<<2) /* Wrap */
38 #define CONTROL_FC (1<<3) /* Flow Control */
39 #define CONTROL_FMT(x) (((x) << 4) & 0x30) /* Format */
40 #define CONTROL_PCB(x) (((x) << 10) & 0x7c00) /* PC Bits */
43 #define STATUS_T (1<<0) /* Trace Started */
44 #define STATUS_TD (1<<1) /* Trace Disabled */
45 #define STATUS_W (1<<2) /* Wrapped */
46 #define STATUS_O (1<<3) /* Overflow */
49 #define TRIGGER_TST(x) (((x) << 0) & 0xf) /* Trigger Start */
50 #define TRIGGER_DST (1<<7) /* Delay Start */
51 #define TRIGGER_TSP(x) (((x) << 8) & 0xf00) /* Trigger Stop */
52 #define TRIGGER_DSP (1<<15) /* Delay Start */
54 static const char * const esirisc_trace_delay_strings
[] = {
55 "none", "start", "stop", "both",
58 static const char * const esirisc_trace_format_strings
[] = {
59 "full", "branch", "icache",
62 static const char * const esirisc_trace_id_strings
[] = {
63 "sequential instruction",
69 static const char * const esirisc_trace_ext_id_strings
[] = {
75 "multicycle instruction",
83 static const char * const esirisc_trace_trigger_strings
[] = {
84 "none", "pc", "load", "store", "exception", "eret", "wait", "stop",
85 "high", "low", /* start only */
88 static int esirisc_trace_clear_status(struct target
*target
)
90 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
91 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
94 if (target
->state
!= TARGET_HALTED
)
95 return ERROR_TARGET_NOT_HALTED
;
97 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_STATUS
, ~0);
98 if (retval
!= ERROR_OK
) {
99 LOG_ERROR("%s: failed to write Trace CSR: Status", target_name(target
));
106 static int esirisc_trace_get_status(struct target
*target
, uint32_t *status
)
108 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
109 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
111 if (target
->state
!= TARGET_HALTED
)
112 return ERROR_TARGET_NOT_HALTED
;
114 int retval
= esirisc_jtag_read_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_STATUS
, status
);
115 if (retval
!= ERROR_OK
) {
116 LOG_ERROR("%s: failed to read Trace CSR: Status", target_name(target
));
123 static int esirisc_trace_start(struct target
*target
)
125 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
126 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
130 if (target
->state
!= TARGET_HALTED
)
131 return ERROR_TARGET_NOT_HALTED
;
133 retval
= esirisc_jtag_read_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, &control
);
134 if (retval
!= ERROR_OK
) {
135 LOG_ERROR("%s: failed to read Trace CSR: Control", target_name(target
));
139 control
|= CONTROL_ST
;
141 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, control
);
142 if (retval
!= ERROR_OK
) {
143 LOG_ERROR("%s: failed to write Trace CSR: Control", target_name(target
));
150 static int esirisc_trace_stop(struct target
*target
)
152 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
153 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
157 if (target
->state
!= TARGET_HALTED
)
158 return ERROR_TARGET_NOT_HALTED
;
160 retval
= esirisc_jtag_read_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, &control
);
161 if (retval
!= ERROR_OK
) {
162 LOG_ERROR("%s: failed to read Trace CSR: Control", target_name(target
));
166 control
|= CONTROL_SP
;
168 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, control
);
169 if (retval
!= ERROR_OK
) {
170 LOG_ERROR("%s: failed to write Trace CSR: Control", target_name(target
));
177 static int esirisc_trace_init(struct target
*target
)
179 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
180 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
181 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
182 uint32_t control
, trigger
;
185 if (target
->state
!= TARGET_HALTED
)
186 return ERROR_TARGET_NOT_HALTED
;
188 /* stop if running and clear status */
189 retval
= esirisc_trace_stop(target
);
190 if (retval
!= ERROR_OK
)
193 retval
= esirisc_trace_clear_status(target
);
194 if (retval
!= ERROR_OK
)
197 /* initialize Control CSR */
198 control
= CONTROL_FMT(trace_info
->format
)
199 | CONTROL_PCB(trace_info
->pc_bits
);
201 if (trace_info
->buffer_wrap
)
202 control
|= CONTROL_W
;
204 if (trace_info
->flow_control
)
205 control
|= CONTROL_FC
;
207 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_CONTROL
, control
);
208 if (retval
!= ERROR_OK
) {
209 LOG_ERROR("%s: failed to write Trace CSR: Control", target_name(target
));
213 /* initialize buffer CSRs */
214 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_BUFFER_START
,
215 trace_info
->buffer_start
);
216 if (retval
!= ERROR_OK
) {
217 LOG_ERROR("%s: failed to write Trace CSR: BufferStart", target_name(target
));
221 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_BUFFER_END
,
222 trace_info
->buffer_end
);
223 if (retval
!= ERROR_OK
) {
224 LOG_ERROR("%s: failed to write Trace CSR: BufferEnd", target_name(target
));
229 * The BufferCurrent CSR must be initialized to the same value as
230 * BufferStart before tracing can be enabled:
232 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_BUFFER_CUR
,
233 trace_info
->buffer_start
);
234 if (retval
!= ERROR_OK
) {
235 LOG_ERROR("%s: failed to write Trace CSR: BufferCurrent", target_name(target
));
239 /* initialize Trigger CSR */
240 trigger
= TRIGGER_TST(trace_info
->start_trigger
)
241 | TRIGGER_TSP(trace_info
->stop_trigger
);
243 if (trace_info
->delay
== ESIRISC_TRACE_DELAY_START
244 || trace_info
->delay
== ESIRISC_TRACE_DELAY_BOTH
) {
245 trigger
|= TRIGGER_DST
;
248 if (trace_info
->delay
== ESIRISC_TRACE_DELAY_STOP
249 || trace_info
->delay
== ESIRISC_TRACE_DELAY_BOTH
) {
250 trigger
|= TRIGGER_DSP
;
253 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_TRIGGER
, trigger
);
254 if (retval
!= ERROR_OK
) {
255 LOG_ERROR("%s: failed to write Trace CSR: Trigger", target_name(target
));
259 /* initialize StartData/StartMask CSRs */
260 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_START_DATA
,
261 trace_info
->start_data
);
262 if (retval
!= ERROR_OK
) {
263 LOG_ERROR("%s: failed to write Trace CSR: StartData", target_name(target
));
267 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_START_MASK
,
268 trace_info
->start_mask
);
269 if (retval
!= ERROR_OK
) {
270 LOG_ERROR("%s: failed to write Trace CSR: StartMask", target_name(target
));
274 /* initialize StopData/StopMask CSRs */
275 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_STOP_DATA
,
276 trace_info
->stop_data
);
277 if (retval
!= ERROR_OK
) {
278 LOG_ERROR("%s: failed to write Trace CSR: StopData", target_name(target
));
282 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_STOP_MASK
,
283 trace_info
->stop_mask
);
284 if (retval
!= ERROR_OK
) {
285 LOG_ERROR("%s: failed to write Trace CSR: StopMask", target_name(target
));
289 /* initialize Delay CSR */
290 retval
= esirisc_jtag_write_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_DELAY
,
291 trace_info
->delay_cycles
);
292 if (retval
!= ERROR_OK
) {
293 LOG_ERROR("%s: failed to write Trace CSR: Delay", target_name(target
));
300 static int esirisc_trace_buf_get_u32(uint8_t *buffer
, uint32_t size
,
301 unsigned *pos
, unsigned count
, uint32_t *value
)
303 const unsigned num_bits
= size
* 8;
305 if (*pos
+count
> num_bits
)
308 *value
= buf_get_u32(buffer
, *pos
, count
);
314 static int esirisc_trace_buf_get_pc(struct target
*target
, uint8_t *buffer
, uint32_t size
,
315 unsigned *pos
, uint32_t *value
)
317 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
318 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
321 retval
= esirisc_trace_buf_get_u32(buffer
, size
, pos
, trace_info
->pc_bits
, value
);
322 if (retval
!= ERROR_OK
)
325 *value
<<= esirisc
->num_bits
- trace_info
->pc_bits
;
330 static int esirisc_trace_read_memory(struct target
*target
, target_addr_t address
, uint32_t size
,
335 if (target
->state
!= TARGET_HALTED
)
336 return ERROR_TARGET_NOT_HALTED
;
338 retval
= target_read_memory(target
, address
, 1, size
, buffer
);
339 if (retval
!= ERROR_OK
) {
340 LOG_ERROR("%s: failed to read trace data", target_name(target
));
347 static int esirisc_trace_read_buffer(struct target
*target
, uint8_t *buffer
)
349 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
350 struct esirisc_jtag
*jtag_info
= &esirisc
->jtag_info
;
351 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
352 uint32_t buffer_cur
, status
;
355 if (target
->state
!= TARGET_HALTED
)
356 return ERROR_TARGET_NOT_HALTED
;
358 retval
= esirisc_jtag_read_csr(jtag_info
, CSR_TRACE
, CSR_TRACE_BUFFER_CUR
, &buffer_cur
);
359 if (retval
!= ERROR_OK
) {
360 LOG_ERROR("%s: failed to read Trace CSR: BufferCurrent", target_name(target
));
365 * If the buffer has wrapped, the BufferCurrent CSR indicates the
366 * next address to be written (ie. the start address). These bytes
367 * must be dumped first to maintain coherency when analyzing
370 retval
= esirisc_trace_get_status(target
, &status
);
371 if (retval
!= ERROR_OK
)
374 if (status
& STATUS_W
) {
375 uint32_t size
= trace_info
->buffer_end
- buffer_cur
;
377 retval
= esirisc_trace_read_memory(target
, buffer_cur
, size
, buffer
);
378 if (retval
!= ERROR_OK
)
384 return esirisc_trace_read_memory(target
, trace_info
->buffer_start
,
385 buffer_cur
- trace_info
->buffer_start
, buffer
);
388 static int esirisc_trace_analyze_full(struct command_invocation
*cmd
, uint8_t *buffer
, uint32_t size
)
390 struct target
*target
= get_current_target(cmd
->ctx
);
391 const uint32_t num_bits
= size
* 8;
395 while (pos
< num_bits
) {
398 retval
= esirisc_trace_buf_get_u32(buffer
, size
, &pos
, 2, &id
);
399 if (retval
!= ERROR_OK
)
403 case ESIRISC_TRACE_ID_EXECUTE
:
404 case ESIRISC_TRACE_ID_STALL
:
405 case ESIRISC_TRACE_ID_BRANCH
:
406 command_print(cmd
, "%s", esirisc_trace_id_strings
[id
]);
409 case ESIRISC_TRACE_ID_EXTENDED
: {
412 retval
= esirisc_trace_buf_get_u32(buffer
, size
, &pos
, 4, &ext_id
);
413 if (retval
!= ERROR_OK
)
417 case ESIRISC_TRACE_EXT_ID_STOP
:
418 case ESIRISC_TRACE_EXT_ID_WAIT
:
419 case ESIRISC_TRACE_EXT_ID_MULTICYCLE
:
420 command_print(cmd
, "%s", esirisc_trace_ext_id_strings
[ext_id
]);
423 case ESIRISC_TRACE_EXT_ID_ERET
:
424 case ESIRISC_TRACE_EXT_ID_PC
:
425 case ESIRISC_TRACE_EXT_ID_INDIRECT
:
426 case ESIRISC_TRACE_EXT_ID_END_PC
: {
429 retval
= esirisc_trace_buf_get_pc(target
, buffer
, size
, &pos
, &pc
);
430 if (retval
!= ERROR_OK
)
433 command_print(cmd
, "%s PC: 0x%" PRIx32
,
434 esirisc_trace_ext_id_strings
[ext_id
], pc
);
436 if (ext_id
== ESIRISC_TRACE_EXT_ID_END_PC
) {
437 command_print(cmd
, "--- end of trace ---");
442 case ESIRISC_TRACE_EXT_ID_EXCEPTION
: {
445 retval
= esirisc_trace_buf_get_u32(buffer
, size
, &pos
, 6, &eid
);
446 if (retval
!= ERROR_OK
)
449 retval
= esirisc_trace_buf_get_pc(target
, buffer
, size
, &pos
, &epc
);
450 if (retval
!= ERROR_OK
)
453 command_print(cmd
, "%s EID: 0x%" PRIx32
", EPC: 0x%" PRIx32
,
454 esirisc_trace_ext_id_strings
[ext_id
], eid
, epc
);
457 case ESIRISC_TRACE_EXT_ID_COUNT
: {
460 retval
= esirisc_trace_buf_get_u32(buffer
, size
, &pos
, 6, &count
);
461 if (retval
!= ERROR_OK
)
464 command_print(cmd
, "repeats %" PRIu32
" %s", count
,
465 (count
== 1) ? "time" : "times");
468 case ESIRISC_TRACE_EXT_ID_END
:
469 command_print(cmd
, "--- end of trace ---");
473 command_print(cmd
, "invalid extended trace ID: %" PRIu32
, ext_id
);
479 command_print(cmd
, "invalid trace ID: %" PRIu32
, id
);
485 command_print(cmd
, "trace buffer too small");
486 return ERROR_BUF_TOO_SMALL
;
489 static int esirisc_trace_analyze_simple(struct command_invocation
*cmd
, uint8_t *buffer
, uint32_t size
)
491 struct target
*target
= get_current_target(cmd
->ctx
);
492 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
493 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
494 const uint32_t end_of_trace
= BIT_MASK(trace_info
->pc_bits
) << 1;
495 const uint32_t num_bits
= size
* 8;
499 while (pos
< num_bits
) {
502 retval
= esirisc_trace_buf_get_pc(target
, buffer
, size
, &pos
, &pc
);
503 if (retval
!= ERROR_OK
)
506 if (pc
== end_of_trace
) {
507 command_print(cmd
, "--- end of trace ---");
511 command_print(cmd
, "PC: 0x%" PRIx32
, pc
);
514 command_print(cmd
, "trace buffer too small");
515 return ERROR_BUF_TOO_SMALL
;
518 static int esirisc_trace_analyze(struct command_invocation
*cmd
, uint8_t *buffer
, uint32_t size
)
520 struct target
*target
= get_current_target(cmd
->ctx
);
521 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
522 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
524 switch (trace_info
->format
) {
525 case ESIRISC_TRACE_FORMAT_FULL
:
526 command_print(cmd
, "--- full pipeline ---");
527 return esirisc_trace_analyze_full(cmd
, buffer
, size
);
529 case ESIRISC_TRACE_FORMAT_BRANCH
:
530 command_print(cmd
, "--- branches taken ---");
531 return esirisc_trace_analyze_full(cmd
, buffer
, size
);
533 case ESIRISC_TRACE_FORMAT_ICACHE
:
534 command_print(cmd
, "--- icache misses ---");
535 return esirisc_trace_analyze_simple(cmd
, buffer
, size
);
538 command_print(cmd
, "invalid trace format: %i", trace_info
->format
);
543 static int esirisc_trace_analyze_buffer(struct command_invocation
*cmd
)
545 struct target
*target
= get_current_target(cmd
->ctx
);
546 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
547 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
552 size
= esirisc_trace_buffer_size(trace_info
);
553 buffer
= calloc(1, size
);
555 command_print(cmd
, "out of memory");
559 retval
= esirisc_trace_read_buffer(target
, buffer
);
560 if (retval
!= ERROR_OK
)
563 retval
= esirisc_trace_analyze(cmd
, buffer
, size
);
571 static int esirisc_trace_analyze_memory(struct command_invocation
*cmd
,
572 target_addr_t address
, uint32_t size
)
574 struct target
*target
= get_current_target(cmd
->ctx
);
578 buffer
= calloc(1, size
);
580 command_print(cmd
, "out of memory");
584 retval
= esirisc_trace_read_memory(target
, address
, size
, buffer
);
585 if (retval
!= ERROR_OK
)
588 retval
= esirisc_trace_analyze(cmd
, buffer
, size
);
596 static int esirisc_trace_dump(struct command_invocation
*cmd
, const char *filename
,
597 uint8_t *buffer
, uint32_t size
)
599 struct fileio
*fileio
;
603 retval
= fileio_open(&fileio
, filename
, FILEIO_WRITE
, FILEIO_BINARY
);
604 if (retval
!= ERROR_OK
) {
605 command_print(cmd
, "could not open dump file: %s", filename
);
609 retval
= fileio_write(fileio
, size
, buffer
, &size_written
);
610 if (retval
== ERROR_OK
)
611 command_print(cmd
, "trace data dumped to: %s", filename
);
613 command_print(cmd
, "could not write dump file: %s", filename
);
615 fileio_close(fileio
);
620 static int esirisc_trace_dump_buffer(struct command_invocation
*cmd
, const char *filename
)
622 struct target
*target
= get_current_target(cmd
->ctx
);
623 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
624 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
629 size
= esirisc_trace_buffer_size(trace_info
);
630 buffer
= calloc(1, size
);
632 command_print(cmd
, "out of memory");
636 retval
= esirisc_trace_read_buffer(target
, buffer
);
637 if (retval
!= ERROR_OK
)
640 retval
= esirisc_trace_dump(cmd
, filename
, buffer
, size
);
648 static int esirisc_trace_dump_memory(struct command_invocation
*cmd
, const char *filename
,
649 target_addr_t address
, uint32_t size
)
651 struct target
*target
= get_current_target(cmd
->ctx
);
655 buffer
= calloc(1, size
);
657 command_print(cmd
, "out of memory");
661 retval
= esirisc_trace_read_memory(target
, address
, size
, buffer
);
662 if (retval
!= ERROR_OK
)
665 retval
= esirisc_trace_dump(cmd
, filename
, buffer
, size
);
673 COMMAND_HANDLER(handle_esirisc_trace_init_command
)
675 struct target
*target
= get_current_target(CMD_CTX
);
676 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
678 if (!esirisc
->has_trace
) {
679 command_print(CMD
, "target does not support trace");
683 int retval
= esirisc_trace_init(target
);
684 if (retval
== ERROR_OK
)
685 command_print(CMD
, "trace initialized");
690 COMMAND_HANDLER(handle_esirisc_trace_info_command
)
692 struct target
*target
= get_current_target(CMD_CTX
);
693 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
694 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
696 if (!esirisc
->has_trace
) {
697 command_print(CMD
, "target does not support trace");
701 if (esirisc_trace_is_fifo(trace_info
))
702 command_print(CMD
, "trace FIFO address: 0x%" TARGET_PRIxADDR
,
703 trace_info
->buffer_start
);
705 command_print(CMD
, "trace buffer start: 0x%" TARGET_PRIxADDR
,
706 trace_info
->buffer_start
);
707 command_print(CMD
, "trace buffer end: 0x%" TARGET_PRIxADDR
,
708 trace_info
->buffer_end
);
709 command_print(CMD
, "trace buffer will %swrap",
710 trace_info
->buffer_wrap
? "" : "not ");
713 command_print(CMD
, "flow control: %s",
714 trace_info
->flow_control
? "enabled" : "disabled");
716 command_print(CMD
, "trace format: %s",
717 esirisc_trace_format_strings
[trace_info
->format
]);
718 command_print(CMD
, "number of PC bits: %i", trace_info
->pc_bits
);
720 command_print(CMD
, "start trigger: %s",
721 esirisc_trace_trigger_strings
[trace_info
->start_trigger
]);
722 command_print(CMD
, "start data: 0x%" PRIx32
, trace_info
->start_data
);
723 command_print(CMD
, "start mask: 0x%" PRIx32
, trace_info
->start_mask
);
725 command_print(CMD
, "stop trigger: %s",
726 esirisc_trace_trigger_strings
[trace_info
->stop_trigger
]);
727 command_print(CMD
, "stop data: 0x%" PRIx32
, trace_info
->stop_data
);
728 command_print(CMD
, "stop mask: 0x%" PRIx32
, trace_info
->stop_mask
);
730 command_print(CMD
, "trigger delay: %s",
731 esirisc_trace_delay_strings
[trace_info
->delay
]);
732 command_print(CMD
, "trigger delay cycles: %" PRIu32
, trace_info
->delay_cycles
);
737 COMMAND_HANDLER(handle_esirisc_trace_status_command
)
739 struct target
*target
= get_current_target(CMD_CTX
);
740 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
743 if (!esirisc
->has_trace
) {
744 command_print(CMD
, "target does not support trace");
748 int retval
= esirisc_trace_get_status(target
, &status
);
749 if (retval
!= ERROR_OK
)
752 command_print(CMD
, "trace is %s%s%s%s",
753 (status
& STATUS_T
) ? "started" : "stopped",
754 (status
& STATUS_TD
) ? ", disabled" : "",
755 (status
& STATUS_W
) ? ", wrapped" : "",
756 (status
& STATUS_O
) ? ", overflowed" : "");
761 COMMAND_HANDLER(handle_esirisc_trace_start_command
)
763 struct target
*target
= get_current_target(CMD_CTX
);
764 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
766 if (!esirisc
->has_trace
) {
767 command_print(CMD
, "target does not support trace");
771 int retval
= esirisc_trace_start(target
);
772 if (retval
== ERROR_OK
)
773 command_print(CMD
, "trace started");
778 COMMAND_HANDLER(handle_esirisc_trace_stop_command
)
780 struct target
*target
= get_current_target(CMD_CTX
);
781 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
783 if (!esirisc
->has_trace
) {
784 command_print(CMD
, "target does not support trace");
788 int retval
= esirisc_trace_stop(target
);
789 if (retval
== ERROR_OK
)
790 command_print(CMD
, "trace stopped");
795 COMMAND_HANDLER(handle_esirisc_trace_analyze_command
)
797 struct target
*target
= get_current_target(CMD_CTX
);
798 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
799 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
800 target_addr_t address
;
803 if (!esirisc
->has_trace
) {
804 command_print(CMD
, "target does not support trace");
808 if (CMD_ARGC
!= 0 && CMD_ARGC
!= 2)
809 return ERROR_COMMAND_SYNTAX_ERROR
;
813 * Use of the Trace FIFO typically involves DMA to a peripheral
814 * (eg. SPI) or a separately managed buffer in memory, neither
815 * of which may be under our control. If the destination address
816 * and size are known in the latter case, they may be specified
817 * as arguments as a workaround.
819 if (esirisc_trace_is_fifo(trace_info
)) {
820 command_print(CMD
, "analyze from FIFO not supported");
824 return esirisc_trace_analyze_buffer(CMD
);
826 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], address
);
827 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], size
);
829 return esirisc_trace_analyze_memory(CMD
, address
, size
);
833 COMMAND_HANDLER(handle_esirisc_trace_dump_command
)
835 struct target
*target
= get_current_target(CMD_CTX
);
836 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
837 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
838 target_addr_t address
;
841 if (!esirisc
->has_trace
) {
842 command_print(CMD
, "target does not support trace");
846 if (CMD_ARGC
!= 1 && CMD_ARGC
!= 3)
847 return ERROR_COMMAND_SYNTAX_ERROR
;
850 /* also see: handle_esirisc_trace_analyze_command() */
851 if (esirisc_trace_is_fifo(trace_info
)) {
852 command_print(CMD
, "dump from FIFO not supported");
856 return esirisc_trace_dump_buffer(CMD
, CMD_ARGV
[0]);
858 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], address
);
859 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], size
);
861 return esirisc_trace_dump_memory(CMD
, CMD_ARGV
[2], address
, size
);
865 COMMAND_HANDLER(handle_esirisc_trace_buffer_command
)
867 struct target
*target
= get_current_target(CMD_CTX
);
868 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
869 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
872 if (CMD_ARGC
< 2 || CMD_ARGC
> 3)
873 return ERROR_COMMAND_SYNTAX_ERROR
;
875 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], trace_info
->buffer_start
);
876 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], size
);
878 trace_info
->buffer_end
= trace_info
->buffer_start
+ size
;
881 if (strcmp("wrap", CMD_ARGV
[2]) == 0)
882 trace_info
->buffer_wrap
= true;
884 return ERROR_COMMAND_SYNTAX_ERROR
;
890 COMMAND_HANDLER(handle_esirisc_trace_fifo_command
)
892 struct target
*target
= get_current_target(CMD_CTX
);
893 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
894 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
897 return ERROR_COMMAND_SYNTAX_ERROR
;
899 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], trace_info
->buffer_start
);
901 /* FIFOs have the same start and end address */
902 trace_info
->buffer_end
= trace_info
->buffer_start
;
903 trace_info
->buffer_wrap
= true;
908 COMMAND_HANDLER(handle_esirisc_trace_flow_control_command
)
910 struct target
*target
= get_current_target(CMD_CTX
);
911 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
912 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
915 return ERROR_COMMAND_SYNTAX_ERROR
;
917 if (strcmp(CMD_ARGV
[0], "enable") == 0)
918 trace_info
->flow_control
= true;
919 else if (strcmp(CMD_ARGV
[0], "disable") == 0)
920 trace_info
->flow_control
= false;
922 return ERROR_COMMAND_SYNTAX_ERROR
;
927 COMMAND_HANDLER(handle_esirisc_trace_format_command
)
929 struct target
*target
= get_current_target(CMD_CTX
);
930 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
931 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
935 return ERROR_COMMAND_SYNTAX_ERROR
;
937 if (strcmp(CMD_ARGV
[0], "full") == 0)
938 trace_info
->format
= ESIRISC_TRACE_FORMAT_FULL
;
939 else if (strcmp(CMD_ARGV
[0], "branch") == 0)
940 trace_info
->format
= ESIRISC_TRACE_FORMAT_BRANCH
;
941 else if (strcmp(CMD_ARGV
[0], "icache") == 0)
942 trace_info
->format
= ESIRISC_TRACE_FORMAT_ICACHE
;
944 return ERROR_COMMAND_SYNTAX_ERROR
;
946 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], pc_bits
);
948 if (pc_bits
< 1 || pc_bits
> 31) {
949 command_print(CMD
, "invalid pc_bits: %i; must be 1..31", pc_bits
);
950 return ERROR_COMMAND_SYNTAX_ERROR
;
953 trace_info
->pc_bits
= pc_bits
;
958 COMMAND_HANDLER(handle_esirisc_trace_trigger_start_command
)
960 struct target
*target
= get_current_target(CMD_CTX
);
961 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
962 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
964 if (CMD_ARGC
!= 1 && CMD_ARGC
!= 3)
965 return ERROR_COMMAND_SYNTAX_ERROR
;
967 if (strcmp(CMD_ARGV
[0], "none") == 0)
968 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_NONE
;
969 else if (strcmp(CMD_ARGV
[0], "pc") == 0)
970 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_PC
;
971 else if (strcmp(CMD_ARGV
[0], "load") == 0)
972 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_LOAD
;
973 else if (strcmp(CMD_ARGV
[0], "store") == 0)
974 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_STORE
;
975 else if (strcmp(CMD_ARGV
[0], "exception") == 0)
976 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_EXCEPTION
;
977 else if (strcmp(CMD_ARGV
[0], "eret") == 0)
978 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_ERET
;
979 else if (strcmp(CMD_ARGV
[0], "wait") == 0)
980 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_WAIT
;
981 else if (strcmp(CMD_ARGV
[0], "stop") == 0)
982 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_STOP
;
983 else if (strcmp(CMD_ARGV
[0], "high") == 0)
984 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_HIGH
;
985 else if (strcmp(CMD_ARGV
[0], "low") == 0)
986 trace_info
->start_trigger
= ESIRISC_TRACE_TRIGGER_LOW
;
988 return ERROR_COMMAND_SYNTAX_ERROR
;
991 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], trace_info
->start_data
);
992 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], trace_info
->start_mask
);
994 trace_info
->start_data
= 0;
995 trace_info
->start_mask
= 0;
1001 COMMAND_HANDLER(handle_esirisc_trace_trigger_stop_command
)
1003 struct target
*target
= get_current_target(CMD_CTX
);
1004 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
1005 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
1007 if (CMD_ARGC
!= 1 && CMD_ARGC
!= 3)
1008 return ERROR_COMMAND_SYNTAX_ERROR
;
1010 if (strcmp(CMD_ARGV
[0], "none") == 0)
1011 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_NONE
;
1012 else if (strcmp(CMD_ARGV
[0], "pc") == 0)
1013 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_PC
;
1014 else if (strcmp(CMD_ARGV
[0], "load") == 0)
1015 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_LOAD
;
1016 else if (strcmp(CMD_ARGV
[0], "store") == 0)
1017 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_STORE
;
1018 else if (strcmp(CMD_ARGV
[0], "exception") == 0)
1019 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_EXCEPTION
;
1020 else if (strcmp(CMD_ARGV
[0], "eret") == 0)
1021 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_ERET
;
1022 else if (strcmp(CMD_ARGV
[0], "wait") == 0)
1023 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_WAIT
;
1024 else if (strcmp(CMD_ARGV
[0], "stop") == 0)
1025 trace_info
->stop_trigger
= ESIRISC_TRACE_TRIGGER_STOP
;
1027 return ERROR_COMMAND_SYNTAX_ERROR
;
1029 if (CMD_ARGC
== 3) {
1030 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], trace_info
->stop_data
);
1031 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], trace_info
->stop_mask
);
1033 trace_info
->stop_data
= 0;
1034 trace_info
->stop_mask
= 0;
1040 COMMAND_HANDLER(handle_esirisc_trace_trigger_delay_command
)
1042 struct target
*target
= get_current_target(CMD_CTX
);
1043 struct esirisc_common
*esirisc
= target_to_esirisc(target
);
1044 struct esirisc_trace
*trace_info
= &esirisc
->trace_info
;
1046 if (CMD_ARGC
< 1 || CMD_ARGC
> 2)
1047 return ERROR_COMMAND_SYNTAX_ERROR
;
1049 if (strcmp(CMD_ARGV
[0], "none") == 0)
1050 trace_info
->delay
= ESIRISC_TRACE_DELAY_NONE
;
1051 else if (strcmp(CMD_ARGV
[0], "start") == 0)
1052 trace_info
->delay
= ESIRISC_TRACE_DELAY_START
;
1053 else if (strcmp(CMD_ARGV
[0], "stop") == 0)
1054 trace_info
->delay
= ESIRISC_TRACE_DELAY_STOP
;
1055 else if (strcmp(CMD_ARGV
[0], "both") == 0)
1056 trace_info
->delay
= ESIRISC_TRACE_DELAY_BOTH
;
1058 return ERROR_COMMAND_SYNTAX_ERROR
;
1060 if (trace_info
->delay
== ESIRISC_TRACE_DELAY_NONE
)
1061 trace_info
->delay_cycles
= 0;
1064 return ERROR_COMMAND_SYNTAX_ERROR
;
1066 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], trace_info
->delay_cycles
);
1072 static const struct command_registration esirisc_trace_exec_command_handlers
[] = {
1075 .handler
= handle_esirisc_trace_init_command
,
1076 .mode
= COMMAND_EXEC
,
1077 .help
= "initialize trace collection",
1082 .handler
= handle_esirisc_trace_info_command
,
1083 .mode
= COMMAND_EXEC
,
1084 .help
= "display trace configuration",
1089 .handler
= handle_esirisc_trace_status_command
,
1090 .mode
= COMMAND_EXEC
,
1091 .help
= "display trace collection status",
1096 .handler
= handle_esirisc_trace_start_command
,
1097 .mode
= COMMAND_EXEC
,
1098 .help
= "start trace collection",
1103 .handler
= handle_esirisc_trace_stop_command
,
1104 .mode
= COMMAND_EXEC
,
1105 .help
= "stop trace collection",
1110 .handler
= handle_esirisc_trace_analyze_command
,
1111 .mode
= COMMAND_EXEC
,
1112 .usage
= "[address size]",
1113 .help
= "analyze collected trace data",
1117 .handler
= handle_esirisc_trace_dump_command
,
1118 .mode
= COMMAND_EXEC
,
1119 .help
= "dump collected trace data to file",
1120 .usage
= "[address size] filename",
1122 COMMAND_REGISTRATION_DONE
1125 static const struct command_registration esirisc_trace_trigger_any_command_handlers
[] = {
1128 .handler
= handle_esirisc_trace_trigger_start_command
,
1129 .mode
= COMMAND_ANY
,
1130 .help
= "configure trigger start condition",
1131 .usage
= "('none'|'pc'|'load'|'store'|'exception'|'eret'|'wait'|'stop'|'high'|'low')"
1132 " [start_data start_mask]",
1136 .handler
= handle_esirisc_trace_trigger_stop_command
,
1137 .mode
= COMMAND_ANY
,
1138 .help
= "configure trigger stop condition",
1139 .usage
= "('none'|'pc'|'load'|'store'|'exception'|'eret'|'wait'|'stop')"
1140 " [stop_data stop_mask]",
1144 .handler
= handle_esirisc_trace_trigger_delay_command
,
1145 .mode
= COMMAND_ANY
,
1146 .help
= "configure trigger start/stop delay in clock cycles",
1147 .usage
= "('none'|'start'|'stop'|'both') [cycles]",
1149 COMMAND_REGISTRATION_DONE
1152 static const struct command_registration esirisc_trace_any_command_handlers
[] = {
1155 .handler
= handle_esirisc_trace_buffer_command
,
1156 .mode
= COMMAND_ANY
,
1157 .help
= "configure trace buffer",
1158 .usage
= "address size ['wrap']",
1162 .handler
= handle_esirisc_trace_fifo_command
,
1163 .mode
= COMMAND_ANY
,
1164 .help
= "configure trace FIFO",
1168 .name
= "flow_control",
1169 .handler
= handle_esirisc_trace_flow_control_command
,
1170 .mode
= COMMAND_ANY
,
1171 .help
= "enable or disable stalling CPU to collect trace data",
1172 .usage
= "('enable'|'disable')",
1176 .handler
= handle_esirisc_trace_format_command
,
1177 .mode
= COMMAND_ANY
,
1178 .help
= "configure trace format",
1179 .usage
= "('full'|'branch'|'icache') pc_bits",
1183 .mode
= COMMAND_ANY
,
1184 .help
= "eSi-Trace trigger command group",
1186 .chain
= esirisc_trace_trigger_any_command_handlers
,
1189 .chain
= esirisc_trace_exec_command_handlers
1191 COMMAND_REGISTRATION_DONE
1194 const struct command_registration esirisc_trace_command_handlers
[] = {
1197 .mode
= COMMAND_ANY
,
1198 .help
= "eSi-Trace command group",
1200 .chain
= esirisc_trace_any_command_handlers
,
1202 COMMAND_REGISTRATION_DONE