m3dev

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit ff46e3d61e09c2e5f8363b7e9a32263f66d5d335
parent 03aad6688981becb1fcdf492f96df0ee9a70b52b
Author: Brian Swetland <swetland@frotz.net>
Date:   Wed,  5 Aug 2015 14:28:02 -0700

debugger: decode SWO trace packets, handle console output

Diffstat:
Mtools/swo.c | 174+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 167 insertions(+), 7 deletions(-)

diff --git a/tools/swo.c b/tools/swo.c @@ -24,15 +24,175 @@ #include <fw/types.h> #include <debugger.h> +#define TRACE 0 + +static char console_data[256]; +static int console_ptr = 0; + +static void handle_swv_src(unsigned id, unsigned val, unsigned n) { +#if TRACE + xprintf(XDATA, "SRC %s %02x %08x\n", (id & 0x100) ? "HW" : "SW", id & 0xFF, val); +#endif + if (id == 0) { + console_data[console_ptr++] = val; + if (val == '\n') { + console_data[console_ptr] = 0; + xprintf(XDATA, "[remote] %s", console_data); + console_ptr = 0; + } else if (console_ptr == 254) { + console_data[console_ptr] = 0; + xprintf(XDATA, "[remote] %s\n", console_data); + } + } +} + +static void handle_swv_proto(unsigned char *data, unsigned len) { +#if TRACE + switch (len) { + case 1: + xprintf(XDATA, "PRO %02x\n", data[0]); + break; + case 2: + xprintf(XDATA, "PRO %02x %02x\n", data[0], data[1]); + break; + case 3: + xprintf(XDATA, "PRO %02x %02x %02x\n", + data[0], data[1], data[2]); + break; + case 4: + xprintf(XDATA, "PRO %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3]); + break; + case 5: + xprintf(XDATA, "PRO %02x %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3], data[4]);; + break; + case 6: + xprintf(XDATA, "PRO %02x %02x %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3], + data[4], data[5]); + break; + case 7: + xprintf(XDATA, "PRO %02x %02x %02x %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6]); + break; + } +#endif +} + +typedef enum { + SWV_SYNC, + SWV_1X1, + SWV_1X2, + SWV_1X4, + SWV_2X2, + SWV_2X4, + SWV_3X4, + SWV_4X4, + SWV_PROTO, + SWV_IDLE, +} swv_state_t; + +typedef struct { + swv_state_t state; + unsigned zcount; + unsigned ccount; + unsigned id; + unsigned val; + unsigned char data[8]; +} swv_t; + +static swv_t swv = { + .state = SWV_SYNC, + .zcount = 0 +}; + +static void handle_swv(swv_t *swv, unsigned x) { + // any sequence ending in 00 00 00 00 00 80 is a re-sync + if (x == 0) { + swv->zcount++; + } else { + if ((swv->zcount >= 5) && (x == 0x80)) { + swv->state = SWV_IDLE; + swv->zcount = 0; +#if TRACE + xprintf(XDATA, "SYNC\n"); +#endif + return; + } + swv->zcount = 0; + } + + switch (swv->state) { + case SWV_IDLE: + if (x & 7) { + // AAAAAHSS source packet + swv->id = (x >> 3) | ((x & 4) << 6); + swv->val = 0; + swv->state = (x & 3); + } else if (x != 0) { + // CXXXXX00 protocol packet + swv->data[0] = x; + if (x & 0x80) { + swv->ccount = 1; + swv->state = SWV_PROTO; + } else { + handle_swv_proto(swv->data, 1); + } + } else { + // 00 packets are for sync, ignore + } + break; + case SWV_PROTO: + swv->data[swv->ccount++] = x; + // protocol packets end at 7 total bytes or a byte with bit7 clear + if ((swv->ccount == 7) || (!(x & 0x80))) { + handle_swv_proto(swv->data, swv->ccount); + swv->state = SWV_IDLE; + } + break; + case SWV_1X1: + handle_swv_src(swv->id, x, 1); + swv->state = SWV_IDLE; + break; + case SWV_1X2: + swv->val = x; + swv->state = SWV_2X2; + break; + case SWV_2X2: + handle_swv_src(swv->id, swv->val | (x << 8), 2); + swv->state = SWV_IDLE; + break; + case SWV_1X4: + swv->val = x; + swv->state = SWV_2X4; + break; + case SWV_2X4: + swv->val |= (x << 8); + swv->state = SWV_3X4; + break; + case SWV_3X4: + swv->val |= (x << 16); + swv->state = SWV_4X4; + break; + case SWV_4X4: + handle_swv_src(swv->id, swv->val | (x << 24), 4); + swv->state = SWV_IDLE; + break; + case SWV_SYNC: + break; + default: + // impossible + xprintf(XDATA, "fatal error, bad state %d\n", swv->state); + exit(1); + } +} + void process_swo_data(void *_data, unsigned count) { unsigned char *data = _data; - char buf[8192]; - char *p = buf; - while (count-- > 0) { - p += sprintf(p, "%02x ", *data++); + while(count-- > 0) { + handle_swv(&swv, *data++); } - *p++ = '\n'; - *p++ = 0; - xprintf(XDATA, buf); }