target/tcl: Add get_reg function
[openocd.git] / src / target / esirisc_trace.c
blobd17a65d63a2776366539173103de2738c723f8d7
1 /***************************************************************************
2 * Copyright (C) 2018 by Square, Inc. *
3 * Steven Stallion <stallion@squareup.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
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>
30 #include "esirisc.h"
32 #define BIT_MASK(x) ((1 << (x)) - 1)
34 /* Control Fields */
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 */
42 /* Status Fields */
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 */
48 /* Trigger Fields */
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",
64 "pipeline stall",
65 "direct branch",
66 "extended ID",
69 static const char * const esirisc_trace_ext_id_strings[] = {
70 "", /* unused */
71 "exception",
72 "eret",
73 "stop instruction",
74 "wait instruction",
75 "multicycle instruction",
76 "count",
77 "initial",
78 "indirect branch",
79 "end of trace",
80 "final",
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;
92 int retval;
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));
100 return retval;
103 return ERROR_OK;
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));
117 return retval;
120 return ERROR_OK;
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;
127 uint32_t control;
128 int retval;
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));
136 return retval;
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));
144 return retval;
147 return ERROR_OK;
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;
154 uint32_t control;
155 int retval;
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));
163 return retval;
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));
171 return retval;
174 return ERROR_OK;
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;
183 int retval;
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)
191 return retval;
193 retval = esirisc_trace_clear_status(target);
194 if (retval != ERROR_OK)
195 return retval;
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));
210 return retval;
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));
218 return retval;
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));
225 return retval;
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));
236 return retval;
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));
256 return retval;
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));
264 return retval;
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));
271 return retval;
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));
279 return retval;
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));
286 return retval;
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));
294 return retval;
297 return ERROR_OK;
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)
306 return ERROR_FAIL;
308 *value = buf_get_u32(buffer, *pos, count);
309 *pos += count;
311 return ERROR_OK;
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;
319 int retval;
321 retval = esirisc_trace_buf_get_u32(buffer, size, pos, trace_info->pc_bits, value);
322 if (retval != ERROR_OK)
323 return retval;
325 *value <<= esirisc->num_bits - trace_info->pc_bits;
327 return ERROR_OK;
330 static int esirisc_trace_read_memory(struct target *target, target_addr_t address, uint32_t size,
331 uint8_t *buffer)
333 int retval;
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));
341 return retval;
344 return ERROR_OK;
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;
353 int retval;
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));
361 return retval;
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
368 * captured data.
370 retval = esirisc_trace_get_status(target, &status);
371 if (retval != ERROR_OK)
372 return retval;
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)
379 return retval;
381 buffer += size;
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;
392 int retval;
394 unsigned pos = 0;
395 while (pos < num_bits) {
396 uint32_t id;
398 retval = esirisc_trace_buf_get_u32(buffer, size, &pos, 2, &id);
399 if (retval != ERROR_OK)
400 goto fail;
402 switch (id) {
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]);
407 break;
409 case ESIRISC_TRACE_ID_EXTENDED: {
410 uint32_t ext_id;
412 retval = esirisc_trace_buf_get_u32(buffer, size, &pos, 4, &ext_id);
413 if (retval != ERROR_OK)
414 goto fail;
416 switch (ext_id) {
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]);
421 break;
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: {
427 uint32_t pc;
429 retval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &pc);
430 if (retval != ERROR_OK)
431 goto fail;
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 ---");
438 return ERROR_OK;
440 break;
442 case ESIRISC_TRACE_EXT_ID_EXCEPTION: {
443 uint32_t eid, epc;
445 retval = esirisc_trace_buf_get_u32(buffer, size, &pos, 6, &eid);
446 if (retval != ERROR_OK)
447 goto fail;
449 retval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &epc);
450 if (retval != ERROR_OK)
451 goto fail;
453 command_print(cmd, "%s EID: 0x%" PRIx32 ", EPC: 0x%" PRIx32,
454 esirisc_trace_ext_id_strings[ext_id], eid, epc);
455 break;
457 case ESIRISC_TRACE_EXT_ID_COUNT: {
458 uint32_t count;
460 retval = esirisc_trace_buf_get_u32(buffer, size, &pos, 6, &count);
461 if (retval != ERROR_OK)
462 goto fail;
464 command_print(cmd, "repeats %" PRIu32 " %s", count,
465 (count == 1) ? "time" : "times");
466 break;
468 case ESIRISC_TRACE_EXT_ID_END:
469 command_print(cmd, "--- end of trace ---");
470 return ERROR_OK;
472 default:
473 command_print(cmd, "invalid extended trace ID: %" PRIu32, ext_id);
474 return ERROR_FAIL;
476 break;
478 default:
479 command_print(cmd, "invalid trace ID: %" PRIu32, id);
480 return ERROR_FAIL;
484 fail:
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;
496 int retval;
498 unsigned pos = 0;
499 while (pos < num_bits) {
500 uint32_t pc;
502 retval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &pc);
503 if (retval != ERROR_OK)
504 break;
506 if (pc == end_of_trace) {
507 command_print(cmd, "--- end of trace ---");
508 return ERROR_OK;
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);
537 default:
538 command_print(cmd, "invalid trace format: %i", trace_info->format);
539 return ERROR_FAIL;
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;
548 uint8_t *buffer;
549 uint32_t size;
550 int retval;
552 size = esirisc_trace_buffer_size(trace_info);
553 buffer = calloc(1, size);
554 if (!buffer) {
555 command_print(cmd, "out of memory");
556 return ERROR_FAIL;
559 retval = esirisc_trace_read_buffer(target, buffer);
560 if (retval != ERROR_OK)
561 goto done;
563 retval = esirisc_trace_analyze(cmd, buffer, size);
565 done:
566 free(buffer);
568 return retval;
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);
575 uint8_t *buffer;
576 int retval;
578 buffer = calloc(1, size);
579 if (!buffer) {
580 command_print(cmd, "out of memory");
581 return ERROR_FAIL;
584 retval = esirisc_trace_read_memory(target, address, size, buffer);
585 if (retval != ERROR_OK)
586 goto done;
588 retval = esirisc_trace_analyze(cmd, buffer, size);
590 done:
591 free(buffer);
593 return retval;
596 static int esirisc_trace_dump(struct command_invocation *cmd, const char *filename,
597 uint8_t *buffer, uint32_t size)
599 struct fileio *fileio;
600 size_t size_written;
601 int retval;
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);
606 return retval;
609 retval = fileio_write(fileio, size, buffer, &size_written);
610 if (retval == ERROR_OK)
611 command_print(cmd, "trace data dumped to: %s", filename);
612 else
613 command_print(cmd, "could not write dump file: %s", filename);
615 fileio_close(fileio);
617 return retval;
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;
625 uint8_t *buffer;
626 uint32_t size;
627 int retval;
629 size = esirisc_trace_buffer_size(trace_info);
630 buffer = calloc(1, size);
631 if (!buffer) {
632 command_print(cmd, "out of memory");
633 return ERROR_FAIL;
636 retval = esirisc_trace_read_buffer(target, buffer);
637 if (retval != ERROR_OK)
638 goto done;
640 retval = esirisc_trace_dump(cmd, filename, buffer, size);
642 done:
643 free(buffer);
645 return retval;
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);
652 uint8_t *buffer;
653 int retval;
655 buffer = calloc(1, size);
656 if (!buffer) {
657 command_print(cmd, "out of memory");
658 return ERROR_FAIL;
661 retval = esirisc_trace_read_memory(target, address, size, buffer);
662 if (retval != ERROR_OK)
663 goto done;
665 retval = esirisc_trace_dump(cmd, filename, buffer, size);
667 done:
668 free(buffer);
670 return retval;
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");
680 return ERROR_FAIL;
683 int retval = esirisc_trace_init(target);
684 if (retval == ERROR_OK)
685 command_print(CMD, "trace initialized");
687 return retval;
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");
698 return ERROR_FAIL;
701 if (esirisc_trace_is_fifo(trace_info))
702 command_print(CMD, "trace FIFO address: 0x%" TARGET_PRIxADDR,
703 trace_info->buffer_start);
704 else {
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);
734 return ERROR_OK;
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);
741 uint32_t status;
743 if (!esirisc->has_trace) {
744 command_print(CMD, "target does not support trace");
745 return ERROR_FAIL;
748 int retval = esirisc_trace_get_status(target, &status);
749 if (retval != ERROR_OK)
750 return retval;
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" : "");
758 return ERROR_OK;
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");
768 return ERROR_FAIL;
771 int retval = esirisc_trace_start(target);
772 if (retval == ERROR_OK)
773 command_print(CMD, "trace started");
775 return retval;
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");
785 return ERROR_FAIL;
788 int retval = esirisc_trace_stop(target);
789 if (retval == ERROR_OK)
790 command_print(CMD, "trace stopped");
792 return retval;
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;
801 uint32_t size;
803 if (!esirisc->has_trace) {
804 command_print(CMD, "target does not support trace");
805 return ERROR_FAIL;
808 if (CMD_ARGC != 0 && CMD_ARGC != 2)
809 return ERROR_COMMAND_SYNTAX_ERROR;
811 if (CMD_ARGC == 0) {
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");
821 return ERROR_FAIL;
824 return esirisc_trace_analyze_buffer(CMD);
825 } else {
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;
839 uint32_t size;
841 if (!esirisc->has_trace) {
842 command_print(CMD, "target does not support trace");
843 return ERROR_FAIL;
846 if (CMD_ARGC != 1 && CMD_ARGC != 3)
847 return ERROR_COMMAND_SYNTAX_ERROR;
849 if (CMD_ARGC == 1) {
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");
853 return ERROR_FAIL;
856 return esirisc_trace_dump_buffer(CMD, CMD_ARGV[0]);
857 } else {
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;
870 uint32_t size;
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;
880 if (CMD_ARGC == 3) {
881 if (strcmp("wrap", CMD_ARGV[2]) == 0)
882 trace_info->buffer_wrap = true;
883 else
884 return ERROR_COMMAND_SYNTAX_ERROR;
887 return ERROR_OK;
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;
896 if (CMD_ARGC != 1)
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;
905 return ERROR_OK;
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;
914 if (CMD_ARGC != 1)
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;
921 else
922 return ERROR_COMMAND_SYNTAX_ERROR;
924 return ERROR_OK;
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;
932 int pc_bits;
934 if (CMD_ARGC != 2)
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;
943 else
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;
955 return ERROR_OK;
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;
987 else
988 return ERROR_COMMAND_SYNTAX_ERROR;
990 if (CMD_ARGC == 3) {
991 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], trace_info->start_data);
992 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], trace_info->start_mask);
993 } else {
994 trace_info->start_data = 0;
995 trace_info->start_mask = 0;
998 return ERROR_OK;
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;
1026 else
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);
1032 } else {
1033 trace_info->stop_data = 0;
1034 trace_info->stop_mask = 0;
1037 return ERROR_OK;
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;
1057 else
1058 return ERROR_COMMAND_SYNTAX_ERROR;
1060 if (trace_info->delay == ESIRISC_TRACE_DELAY_NONE)
1061 trace_info->delay_cycles = 0;
1062 else {
1063 if (CMD_ARGC != 2)
1064 return ERROR_COMMAND_SYNTAX_ERROR;
1066 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], trace_info->delay_cycles);
1069 return ERROR_OK;
1072 static const struct command_registration esirisc_trace_exec_command_handlers[] = {
1074 .name = "init",
1075 .handler = handle_esirisc_trace_init_command,
1076 .mode = COMMAND_EXEC,
1077 .help = "initialize trace collection",
1078 .usage = "",
1081 .name = "info",
1082 .handler = handle_esirisc_trace_info_command,
1083 .mode = COMMAND_EXEC,
1084 .help = "display trace configuration",
1085 .usage = "",
1088 .name = "status",
1089 .handler = handle_esirisc_trace_status_command,
1090 .mode = COMMAND_EXEC,
1091 .help = "display trace collection status",
1092 .usage = "",
1095 .name = "start",
1096 .handler = handle_esirisc_trace_start_command,
1097 .mode = COMMAND_EXEC,
1098 .help = "start trace collection",
1099 .usage = "",
1102 .name = "stop",
1103 .handler = handle_esirisc_trace_stop_command,
1104 .mode = COMMAND_EXEC,
1105 .help = "stop trace collection",
1106 .usage = "",
1109 .name = "analyze",
1110 .handler = handle_esirisc_trace_analyze_command,
1111 .mode = COMMAND_EXEC,
1112 .usage = "[address size]",
1113 .help = "analyze collected trace data",
1116 .name = "dump",
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[] = {
1127 .name = "start",
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]",
1135 .name = "stop",
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]",
1143 .name = "delay",
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[] = {
1154 .name = "buffer",
1155 .handler = handle_esirisc_trace_buffer_command,
1156 .mode = COMMAND_ANY,
1157 .help = "configure trace buffer",
1158 .usage = "address size ['wrap']",
1161 .name = "fifo",
1162 .handler = handle_esirisc_trace_fifo_command,
1163 .mode = COMMAND_ANY,
1164 .help = "configure trace FIFO",
1165 .usage = "address",
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')",
1175 .name = "format",
1176 .handler = handle_esirisc_trace_format_command,
1177 .mode = COMMAND_ANY,
1178 .help = "configure trace format",
1179 .usage = "('full'|'branch'|'icache') pc_bits",
1182 .name = "trigger",
1183 .mode = COMMAND_ANY,
1184 .help = "eSi-Trace trigger command group",
1185 .usage = "",
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[] = {
1196 .name = "trace",
1197 .mode = COMMAND_ANY,
1198 .help = "eSi-Trace command group",
1199 .usage = "",
1200 .chain = esirisc_trace_any_command_handlers,
1202 COMMAND_REGISTRATION_DONE