d17a65d63a2776366539173103de2738c723f8d7
[fw/openocd] / src / target / esirisc_trace.c
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  ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
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>
29
30 #include "esirisc.h"
31
32 #define BIT_MASK(x)                     ((1 << (x)) - 1)
33
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 */
41
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 */
47
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 */
53
54 static const char * const esirisc_trace_delay_strings[] = {
55         "none", "start", "stop", "both",
56 };
57
58 static const char * const esirisc_trace_format_strings[] = {
59         "full", "branch", "icache",
60 };
61
62 static const char * const esirisc_trace_id_strings[] = {
63         "sequential instruction",
64         "pipeline stall",
65         "direct branch",
66         "extended ID",
67 };
68
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",
81 };
82
83 static const char * const esirisc_trace_trigger_strings[] = {
84         "none", "pc", "load", "store", "exception", "eret", "wait", "stop",
85         "high", "low",  /* start only */
86 };
87
88 static int esirisc_trace_clear_status(struct target *target)
89 {
90         struct esirisc_common *esirisc = target_to_esirisc(target);
91         struct esirisc_jtag *jtag_info = &esirisc->jtag_info;
92         int retval;
93
94         if (target->state != TARGET_HALTED)
95                 return ERROR_TARGET_NOT_HALTED;
96
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;
101         }
102
103         return ERROR_OK;
104 }
105
106 static int esirisc_trace_get_status(struct target *target, uint32_t *status)
107 {
108         struct esirisc_common *esirisc = target_to_esirisc(target);
109         struct esirisc_jtag *jtag_info = &esirisc->jtag_info;
110
111         if (target->state != TARGET_HALTED)
112                 return ERROR_TARGET_NOT_HALTED;
113
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;
118         }
119
120         return ERROR_OK;
121 }
122
123 static int esirisc_trace_start(struct target *target)
124 {
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;
129
130         if (target->state != TARGET_HALTED)
131                 return ERROR_TARGET_NOT_HALTED;
132
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;
137         }
138
139         control |= CONTROL_ST;
140
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;
145         }
146
147         return ERROR_OK;
148 }
149
150 static int esirisc_trace_stop(struct target *target)
151 {
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;
156
157         if (target->state != TARGET_HALTED)
158                 return ERROR_TARGET_NOT_HALTED;
159
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;
164         }
165
166         control |= CONTROL_SP;
167
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;
172         }
173
174         return ERROR_OK;
175 }
176
177 static int esirisc_trace_init(struct target *target)
178 {
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;
184
185         if (target->state != TARGET_HALTED)
186                 return ERROR_TARGET_NOT_HALTED;
187
188         /* stop if running and clear status */
189         retval = esirisc_trace_stop(target);
190         if (retval != ERROR_OK)
191                 return retval;
192
193         retval = esirisc_trace_clear_status(target);
194         if (retval != ERROR_OK)
195                 return retval;
196
197         /* initialize Control CSR */
198         control = CONTROL_FMT(trace_info->format)
199                         | CONTROL_PCB(trace_info->pc_bits);
200
201         if (trace_info->buffer_wrap)
202                 control |= CONTROL_W;
203
204         if (trace_info->flow_control)
205                 control |= CONTROL_FC;
206
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;
211         }
212
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;
219         }
220
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;
226         }
227
228         /*
229          * The BufferCurrent CSR must be initialized to the same value as
230          * BufferStart before tracing can be enabled:
231          */
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;
237         }
238
239         /* initialize Trigger CSR */
240         trigger = TRIGGER_TST(trace_info->start_trigger)
241                         | TRIGGER_TSP(trace_info->stop_trigger);
242
243         if (trace_info->delay == ESIRISC_TRACE_DELAY_START
244                 || trace_info->delay == ESIRISC_TRACE_DELAY_BOTH) {
245                 trigger |= TRIGGER_DST;
246         }
247
248         if (trace_info->delay == ESIRISC_TRACE_DELAY_STOP
249                 || trace_info->delay == ESIRISC_TRACE_DELAY_BOTH) {
250                 trigger |= TRIGGER_DSP;
251         }
252
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;
257         }
258
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;
265         }
266
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;
272         }
273
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;
280         }
281
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;
287         }
288
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;
295         }
296
297         return ERROR_OK;
298 }
299
300 static int esirisc_trace_buf_get_u32(uint8_t *buffer, uint32_t size,
301                 unsigned *pos, unsigned count, uint32_t *value)
302 {
303         const unsigned num_bits = size * 8;
304
305         if (*pos+count > num_bits)
306                 return ERROR_FAIL;
307
308         *value = buf_get_u32(buffer, *pos, count);
309         *pos += count;
310
311         return ERROR_OK;
312 }
313
314 static int esirisc_trace_buf_get_pc(struct target *target, uint8_t *buffer, uint32_t size,
315                 unsigned *pos, uint32_t *value)
316 {
317         struct esirisc_common *esirisc = target_to_esirisc(target);
318         struct esirisc_trace *trace_info = &esirisc->trace_info;
319         int retval;
320
321         retval = esirisc_trace_buf_get_u32(buffer, size, pos, trace_info->pc_bits, value);
322         if (retval != ERROR_OK)
323                 return retval;
324
325         *value <<= esirisc->num_bits - trace_info->pc_bits;
326
327         return ERROR_OK;
328 }
329
330 static int esirisc_trace_read_memory(struct target *target, target_addr_t address, uint32_t size,
331                 uint8_t *buffer)
332 {
333         int retval;
334
335         if (target->state != TARGET_HALTED)
336                 return ERROR_TARGET_NOT_HALTED;
337
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;
342         }
343
344         return ERROR_OK;
345 }
346
347 static int esirisc_trace_read_buffer(struct target *target, uint8_t *buffer)
348 {
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;
354
355         if (target->state != TARGET_HALTED)
356                 return ERROR_TARGET_NOT_HALTED;
357
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;
362         }
363
364         /*
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.
369          */
370         retval = esirisc_trace_get_status(target, &status);
371         if (retval != ERROR_OK)
372                 return retval;
373
374         if (status & STATUS_W) {
375                 uint32_t size = trace_info->buffer_end - buffer_cur;
376
377                 retval = esirisc_trace_read_memory(target, buffer_cur, size, buffer);
378                 if (retval != ERROR_OK)
379                         return retval;
380
381                 buffer += size;
382         }
383
384         return esirisc_trace_read_memory(target, trace_info->buffer_start,
385                         buffer_cur - trace_info->buffer_start, buffer);
386 }
387
388 static int esirisc_trace_analyze_full(struct command_invocation *cmd, uint8_t *buffer, uint32_t size)
389 {
390         struct target *target = get_current_target(cmd->ctx);
391         const uint32_t num_bits = size * 8;
392         int retval;
393
394         unsigned pos = 0;
395         while (pos < num_bits) {
396                 uint32_t id;
397
398                 retval = esirisc_trace_buf_get_u32(buffer, size, &pos, 2, &id);
399                 if (retval != ERROR_OK)
400                         goto fail;
401
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;
408
409                         case ESIRISC_TRACE_ID_EXTENDED: {
410                                 uint32_t ext_id;
411
412                                 retval = esirisc_trace_buf_get_u32(buffer, size, &pos, 4, &ext_id);
413                                 if (retval != ERROR_OK)
414                                         goto fail;
415
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;
422
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;
428
429                                                 retval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &pc);
430                                                 if (retval != ERROR_OK)
431                                                         goto fail;
432
433                                                 command_print(cmd, "%s PC: 0x%" PRIx32,
434                                                                 esirisc_trace_ext_id_strings[ext_id], pc);
435
436                                                 if (ext_id == ESIRISC_TRACE_EXT_ID_END_PC) {
437                                                         command_print(cmd, "--- end of trace ---");
438                                                         return ERROR_OK;
439                                                 }
440                                                 break;
441                                         }
442                                         case ESIRISC_TRACE_EXT_ID_EXCEPTION: {
443                                                 uint32_t eid, epc;
444
445                                                 retval = esirisc_trace_buf_get_u32(buffer, size, &pos, 6, &eid);
446                                                 if (retval != ERROR_OK)
447                                                         goto fail;
448
449                                                 retval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &epc);
450                                                 if (retval != ERROR_OK)
451                                                         goto fail;
452
453                                                 command_print(cmd, "%s EID: 0x%" PRIx32 ", EPC: 0x%" PRIx32,
454                                                                 esirisc_trace_ext_id_strings[ext_id], eid, epc);
455                                                 break;
456                                         }
457                                         case ESIRISC_TRACE_EXT_ID_COUNT: {
458                                                 uint32_t count;
459
460                                                 retval = esirisc_trace_buf_get_u32(buffer, size, &pos, 6, &count);
461                                                 if (retval != ERROR_OK)
462                                                         goto fail;
463
464                                                 command_print(cmd, "repeats %" PRIu32 " %s", count,
465                                                                 (count == 1) ? "time" : "times");
466                                                 break;
467                                         }
468                                         case ESIRISC_TRACE_EXT_ID_END:
469                                                 command_print(cmd, "--- end of trace ---");
470                                                 return ERROR_OK;
471
472                                         default:
473                                                 command_print(cmd, "invalid extended trace ID: %" PRIu32, ext_id);
474                                                 return ERROR_FAIL;
475                                 }
476                                 break;
477                         }
478                         default:
479                                 command_print(cmd, "invalid trace ID: %" PRIu32, id);
480                                 return ERROR_FAIL;
481                 }
482         }
483
484 fail:
485         command_print(cmd, "trace buffer too small");
486         return ERROR_BUF_TOO_SMALL;
487 }
488
489 static int esirisc_trace_analyze_simple(struct command_invocation *cmd, uint8_t *buffer, uint32_t size)
490 {
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;
497
498         unsigned pos = 0;
499         while (pos < num_bits) {
500                 uint32_t pc;
501
502                 retval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &pc);
503                 if (retval != ERROR_OK)
504                         break;
505
506                 if (pc == end_of_trace) {
507                         command_print(cmd, "--- end of trace ---");
508                         return ERROR_OK;
509                 }
510
511                 command_print(cmd, "PC: 0x%" PRIx32, pc);
512         }
513
514         command_print(cmd, "trace buffer too small");
515         return ERROR_BUF_TOO_SMALL;
516 }
517
518 static int esirisc_trace_analyze(struct command_invocation *cmd, uint8_t *buffer, uint32_t size)
519 {
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;
523
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);
528
529                 case ESIRISC_TRACE_FORMAT_BRANCH:
530                         command_print(cmd, "--- branches taken ---");
531                         return esirisc_trace_analyze_full(cmd, buffer, size);
532
533                 case ESIRISC_TRACE_FORMAT_ICACHE:
534                         command_print(cmd, "--- icache misses ---");
535                         return esirisc_trace_analyze_simple(cmd, buffer, size);
536
537                 default:
538                         command_print(cmd, "invalid trace format: %i", trace_info->format);
539                         return ERROR_FAIL;
540         }
541 }
542
543 static int esirisc_trace_analyze_buffer(struct command_invocation *cmd)
544 {
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;
551
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;
557         }
558
559         retval = esirisc_trace_read_buffer(target, buffer);
560         if (retval != ERROR_OK)
561                 goto done;
562
563         retval = esirisc_trace_analyze(cmd, buffer, size);
564
565 done:
566         free(buffer);
567
568         return retval;
569 }
570
571 static int esirisc_trace_analyze_memory(struct command_invocation *cmd,
572                 target_addr_t address, uint32_t size)
573 {
574         struct target *target = get_current_target(cmd->ctx);
575         uint8_t *buffer;
576         int retval;
577
578         buffer = calloc(1, size);
579         if (!buffer) {
580                 command_print(cmd, "out of memory");
581                 return ERROR_FAIL;
582         }
583
584         retval = esirisc_trace_read_memory(target, address, size, buffer);
585         if (retval != ERROR_OK)
586                 goto done;
587
588         retval = esirisc_trace_analyze(cmd, buffer, size);
589
590 done:
591         free(buffer);
592
593         return retval;
594 }
595
596 static int esirisc_trace_dump(struct command_invocation *cmd, const char *filename,
597                 uint8_t *buffer, uint32_t size)
598 {
599         struct fileio *fileio;
600         size_t size_written;
601         int retval;
602
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;
607         }
608
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);
614
615         fileio_close(fileio);
616
617         return retval;
618 }
619
620 static int esirisc_trace_dump_buffer(struct command_invocation *cmd, const char *filename)
621 {
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;
628
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;
634         }
635
636         retval = esirisc_trace_read_buffer(target, buffer);
637         if (retval != ERROR_OK)
638                 goto done;
639
640         retval = esirisc_trace_dump(cmd, filename, buffer, size);
641
642 done:
643         free(buffer);
644
645         return retval;
646 }
647
648 static int esirisc_trace_dump_memory(struct command_invocation *cmd, const char *filename,
649                 target_addr_t address, uint32_t size)
650 {
651         struct target *target = get_current_target(cmd->ctx);
652         uint8_t *buffer;
653         int retval;
654
655         buffer = calloc(1, size);
656         if (!buffer) {
657                 command_print(cmd, "out of memory");
658                 return ERROR_FAIL;
659         }
660
661         retval = esirisc_trace_read_memory(target, address, size, buffer);
662         if (retval != ERROR_OK)
663                 goto done;
664
665         retval = esirisc_trace_dump(cmd, filename, buffer, size);
666
667 done:
668         free(buffer);
669
670         return retval;
671 }
672
673 COMMAND_HANDLER(handle_esirisc_trace_init_command)
674 {
675         struct target *target = get_current_target(CMD_CTX);
676         struct esirisc_common *esirisc = target_to_esirisc(target);
677
678         if (!esirisc->has_trace) {
679                 command_print(CMD, "target does not support trace");
680                 return ERROR_FAIL;
681         }
682
683         int retval = esirisc_trace_init(target);
684         if (retval == ERROR_OK)
685                 command_print(CMD, "trace initialized");
686
687         return retval;
688 }
689
690 COMMAND_HANDLER(handle_esirisc_trace_info_command)
691 {
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;
695
696         if (!esirisc->has_trace) {
697                 command_print(CMD, "target does not support trace");
698                 return ERROR_FAIL;
699         }
700
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 ");
711         }
712
713         command_print(CMD, "flow control: %s",
714                         trace_info->flow_control ? "enabled" : "disabled");
715
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);
719
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);
724
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);
729
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);
733
734         return ERROR_OK;
735 }
736
737 COMMAND_HANDLER(handle_esirisc_trace_status_command)
738 {
739         struct target *target = get_current_target(CMD_CTX);
740         struct esirisc_common *esirisc = target_to_esirisc(target);
741         uint32_t status;
742
743         if (!esirisc->has_trace) {
744                 command_print(CMD, "target does not support trace");
745                 return ERROR_FAIL;
746         }
747
748         int retval = esirisc_trace_get_status(target, &status);
749         if (retval != ERROR_OK)
750                 return retval;
751
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" : "");
757
758         return ERROR_OK;
759 }
760
761 COMMAND_HANDLER(handle_esirisc_trace_start_command)
762 {
763         struct target *target = get_current_target(CMD_CTX);
764         struct esirisc_common *esirisc = target_to_esirisc(target);
765
766         if (!esirisc->has_trace) {
767                 command_print(CMD, "target does not support trace");
768                 return ERROR_FAIL;
769         }
770
771         int retval = esirisc_trace_start(target);
772         if (retval == ERROR_OK)
773                 command_print(CMD, "trace started");
774
775         return retval;
776 }
777
778 COMMAND_HANDLER(handle_esirisc_trace_stop_command)
779 {
780         struct target *target = get_current_target(CMD_CTX);
781         struct esirisc_common *esirisc = target_to_esirisc(target);
782
783         if (!esirisc->has_trace) {
784                 command_print(CMD, "target does not support trace");
785                 return ERROR_FAIL;
786         }
787
788         int retval = esirisc_trace_stop(target);
789         if (retval == ERROR_OK)
790                 command_print(CMD, "trace stopped");
791
792         return retval;
793 }
794
795 COMMAND_HANDLER(handle_esirisc_trace_analyze_command)
796 {
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;
802
803         if (!esirisc->has_trace) {
804                 command_print(CMD, "target does not support trace");
805                 return ERROR_FAIL;
806         }
807
808         if (CMD_ARGC != 0 && CMD_ARGC != 2)
809                 return ERROR_COMMAND_SYNTAX_ERROR;
810
811         if (CMD_ARGC == 0) {
812                 /*
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.
818                  */
819                 if (esirisc_trace_is_fifo(trace_info)) {
820                         command_print(CMD, "analyze from FIFO not supported");
821                         return ERROR_FAIL;
822                 }
823
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);
828
829                 return esirisc_trace_analyze_memory(CMD, address, size);
830         }
831 }
832
833 COMMAND_HANDLER(handle_esirisc_trace_dump_command)
834 {
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;
840
841         if (!esirisc->has_trace) {
842                 command_print(CMD, "target does not support trace");
843                 return ERROR_FAIL;
844         }
845
846         if (CMD_ARGC != 1 && CMD_ARGC != 3)
847                 return ERROR_COMMAND_SYNTAX_ERROR;
848
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;
854                 }
855
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);
860
861                 return esirisc_trace_dump_memory(CMD, CMD_ARGV[2], address, size);
862         }
863 }
864
865 COMMAND_HANDLER(handle_esirisc_trace_buffer_command)
866 {
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;
871
872         if (CMD_ARGC < 2 || CMD_ARGC > 3)
873                 return ERROR_COMMAND_SYNTAX_ERROR;
874
875         COMMAND_PARSE_ADDRESS(CMD_ARGV[0], trace_info->buffer_start);
876         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);
877
878         trace_info->buffer_end = trace_info->buffer_start + size;
879
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;
885         }
886
887         return ERROR_OK;
888 }
889
890 COMMAND_HANDLER(handle_esirisc_trace_fifo_command)
891 {
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;
895
896         if (CMD_ARGC != 1)
897                 return ERROR_COMMAND_SYNTAX_ERROR;
898
899         COMMAND_PARSE_ADDRESS(CMD_ARGV[0], trace_info->buffer_start);
900
901         /* FIFOs have the same start and end address */
902         trace_info->buffer_end = trace_info->buffer_start;
903         trace_info->buffer_wrap = true;
904
905         return ERROR_OK;
906 }
907
908 COMMAND_HANDLER(handle_esirisc_trace_flow_control_command)
909 {
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;
913
914         if (CMD_ARGC != 1)
915                 return ERROR_COMMAND_SYNTAX_ERROR;
916
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;
923
924         return ERROR_OK;
925 }
926
927 COMMAND_HANDLER(handle_esirisc_trace_format_command)
928 {
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;
933
934         if (CMD_ARGC != 2)
935                 return ERROR_COMMAND_SYNTAX_ERROR;
936
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;
945
946         COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], pc_bits);
947
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;
951         }
952
953         trace_info->pc_bits = pc_bits;
954
955         return ERROR_OK;
956 }
957
958 COMMAND_HANDLER(handle_esirisc_trace_trigger_start_command)
959 {
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;
963
964         if (CMD_ARGC != 1 && CMD_ARGC != 3)
965                 return ERROR_COMMAND_SYNTAX_ERROR;
966
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;
989
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;
996         }
997
998         return ERROR_OK;
999 }
1000
1001 COMMAND_HANDLER(handle_esirisc_trace_trigger_stop_command)
1002 {
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;
1006
1007         if (CMD_ARGC != 1 && CMD_ARGC != 3)
1008                 return ERROR_COMMAND_SYNTAX_ERROR;
1009
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;
1028
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;
1035         }
1036
1037         return ERROR_OK;
1038 }
1039
1040 COMMAND_HANDLER(handle_esirisc_trace_trigger_delay_command)
1041 {
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;
1045
1046         if (CMD_ARGC < 1 || CMD_ARGC > 2)
1047                 return ERROR_COMMAND_SYNTAX_ERROR;
1048
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;
1059
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;
1065
1066                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], trace_info->delay_cycles);
1067         }
1068
1069         return ERROR_OK;
1070 }
1071
1072 static const struct command_registration esirisc_trace_exec_command_handlers[] = {
1073         {
1074                 .name = "init",
1075                 .handler = handle_esirisc_trace_init_command,
1076                 .mode = COMMAND_EXEC,
1077                 .help = "initialize trace collection",
1078                 .usage = "",
1079         },
1080         {
1081                 .name = "info",
1082                 .handler = handle_esirisc_trace_info_command,
1083                 .mode = COMMAND_EXEC,
1084                 .help = "display trace configuration",
1085                 .usage = "",
1086         },
1087         {
1088                 .name = "status",
1089                 .handler = handle_esirisc_trace_status_command,
1090                 .mode = COMMAND_EXEC,
1091                 .help = "display trace collection status",
1092                 .usage = "",
1093         },
1094         {
1095                 .name = "start",
1096                 .handler = handle_esirisc_trace_start_command,
1097                 .mode = COMMAND_EXEC,
1098                 .help = "start trace collection",
1099                 .usage = "",
1100         },
1101         {
1102                 .name = "stop",
1103                 .handler = handle_esirisc_trace_stop_command,
1104                 .mode = COMMAND_EXEC,
1105                 .help = "stop trace collection",
1106                 .usage = "",
1107         },
1108         {
1109                 .name = "analyze",
1110                 .handler = handle_esirisc_trace_analyze_command,
1111                 .mode = COMMAND_EXEC,
1112                 .usage = "[address size]",
1113                 .help = "analyze collected trace data",
1114         },
1115         {
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",
1121         },
1122         COMMAND_REGISTRATION_DONE
1123 };
1124
1125 static const struct command_registration esirisc_trace_trigger_any_command_handlers[] = {
1126         {
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]",
1133         },
1134         {
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]",
1141         },
1142         {
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]",
1148         },
1149         COMMAND_REGISTRATION_DONE
1150 };
1151
1152 static const struct command_registration esirisc_trace_any_command_handlers[] = {
1153         {
1154                 .name = "buffer",
1155                 .handler = handle_esirisc_trace_buffer_command,
1156                 .mode = COMMAND_ANY,
1157                 .help = "configure trace buffer",
1158                 .usage = "address size ['wrap']",
1159         },
1160         {
1161                 .name = "fifo",
1162                 .handler = handle_esirisc_trace_fifo_command,
1163                 .mode = COMMAND_ANY,
1164                 .help = "configure trace FIFO",
1165                 .usage = "address",
1166         },
1167         {
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')",
1173         },
1174         {
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",
1180         },
1181         {
1182                 .name = "trigger",
1183                 .mode = COMMAND_ANY,
1184                 .help = "eSi-Trace trigger command group",
1185                 .usage = "",
1186                 .chain = esirisc_trace_trigger_any_command_handlers,
1187         },
1188         {
1189                 .chain = esirisc_trace_exec_command_handlers
1190         },
1191         COMMAND_REGISTRATION_DONE
1192 };
1193
1194 const struct command_registration esirisc_trace_command_handlers[] = {
1195         {
1196                 .name = "trace",
1197                 .mode = COMMAND_ANY,
1198                 .help = "eSi-Trace command group",
1199                 .usage = "",
1200                 .chain = esirisc_trace_any_command_handlers,
1201         },
1202         COMMAND_REGISTRATION_DONE
1203 };