m3dev

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

commit 377df4c3326727764f7401b94db4da8fd97deab1
parent 92a86ad93f305238ce2f4b98f08e0f0e74265e40
Author: Brian Swetland <swetland@frotz.net>
Date:   Tue,  4 Aug 2015 18:00:17 -0700

debugger: initial plumbing for SWO

Diffstat:
Minclude/protocol/rswdp.h | 2++
Mtools/debugger-commands.c | 9++++++++-
Mtools/module.mk | 1+
Mtools/rswdp.c | 48++++++++++++++++++++++++++++++++----------------
Mtools/rswdp.h | 1+
Atools/swo.c | 38++++++++++++++++++++++++++++++++++++++
6 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/include/protocol/rswdp.h b/include/protocol/rswdp.h @@ -56,10 +56,12 @@ #define CMD_TRACE 0x08 /* op=tracebits n=0 */ #define CMD_BOOTLOADER 0x09 /* return to bootloader for reflashing */ #define CMD_SET_CLOCK 0x0A /* set SWCLK rate to n khz */ +#define CMD_SWO_CLOCK 0x0B /* set SWOCLK rate to n khz, 0 = disable SWO */ /* valid: target to host */ #define CMD_STATUS 0x10 /* op=errorcode, arg=commands since last TXN_START */ #define CMD_SWD_DATA 0x11 /* op=0 arg=count, payload: data x count */ +#define CMD_SWO_DATA 0x12 /* op=0 arg=count, payload: count * 4 bytes */ /* valid: target to host async */ #define CMD_DEBUG_PRINT 0x20 /* arg*4 bytes of ascii debug output */ diff --git a/tools/debugger-commands.c b/tools/debugger-commands.c @@ -409,6 +409,12 @@ int do_setclock(int argc, param *argv) { return swdp_set_clock(argv[0].n); } +int do_swoclock(int argc, param *argv) { + if (argc < 1) + return -1; + return swo_set_clock(argv[0].n); +} + int do_help(int argc, param *argv) { struct debugger_command *cmd; for (cmd = debugger_commands; cmd->func != NULL; cmd++) { @@ -836,7 +842,8 @@ struct debugger_command debugger_commands[] = { { "print", "", do_print, "print numeric arguments" }, { "echo", "", do_echo, "echo command line" }, { "bootloader", "", do_bootloader, "reboot into bootloader" }, - { "setclock", "", do_setclock, "set clock rate (khz)" }, + { "setclock", "", do_setclock, "set SWD clock rate (khz)" }, + { "swoclock", "", do_swoclock, "set SWO clock rate (khz)" }, { "arch", "", do_setarch, "set architecture for flash agent" }, { "threads", "", do_threads, "thread dump" }, { "text", "", do_text, "dump text" }, diff --git a/tools/module.mk b/tools/module.mk @@ -10,6 +10,7 @@ M_OBJS += tools/usb.o M_OBJS += tools/socket.o M_OBJS += tools/gdb-bridge.o M_OBJS += tools/lkdebug.o +M_OBJS += tools/swo.o M_OBJS += out/debugger-builtins.o $(call build-host-executable) diff --git a/tools/rswdp.c b/tools/rswdp.c @@ -89,18 +89,18 @@ struct txn { unsigned magic; }; +void process_swo_data(void *data, unsigned count); + static void process_async(u32 *data, unsigned count) { unsigned msg, n; u32 tmp; - while (count-- > 0) { msg = *data++; switch (RSWD_MSG_CMD(msg)) { case CMD_NULL: continue; case CMD_DEBUG_PRINT: - //op = RSWD_MSG_OP(msg); - n = RSWD_MSG_ARG(msg); + n = RSWD_MSG_ARG(msg); if (n > count) return; tmp = data[n]; @@ -110,6 +110,13 @@ static void process_async(u32 *data, unsigned count) { data += n; count -= n; break; + case CMD_SWO_DATA: + n = RSWD_MSG_ARG(msg); + if (n > count) + return; + process_swo_data(data, n * 4); + data += n; + count -= n; default: return; } @@ -312,19 +319,17 @@ restart: query_id = 0; process_query(data + 1, (r / 4) - 1); swd_online = 1; - } else if (swd_txn_status == TXN_STATUS_WAIT) { - if (data[0] == swd_txn_id) { - swd_txn_status = r; - memcpy(swd_txn_data, data, r); - pthread_cond_broadcast(&swd_event); - } else if (data[0] == RSWD_TXN_ASYNC) { - pthread_mutex_unlock(&swd_lock); - process_async(data + 1, (r / 4) - 1); - pthread_mutex_lock(&swd_lock); - } else { - xprintf(XSWD, "usb: rx: unexpected txn %08x (%d)\n", - data[0], r); - } + } else if (data[0] == RSWD_TXN_ASYNC) { + pthread_mutex_unlock(&swd_lock); + process_async(data + 1, (r / 4) - 1); + pthread_mutex_lock(&swd_lock); + } else if ((swd_txn_status == TXN_STATUS_WAIT) && + (data[0] == swd_txn_id)) { + swd_txn_status = r; + memcpy(swd_txn_data, data, r); + pthread_cond_broadcast(&swd_event); + } else { + xprintf(XSWD, "usb: rx: unexpected txn %08x (%d)\n", data[0], r); } } // wait for a reader to ack the shutdown (and close usb) @@ -793,6 +798,17 @@ int swdp_set_clock(unsigned khz) { return q_exec(&t); } +int swo_set_clock(unsigned khz) { + struct txn t; + if (khz > 0xFFFF) + return -1; + if (khz < 1000) + khz = 1000; + q_init(&t); + t.tx[t.txc++] = RSWD_MSG(CMD_SWO_CLOCK, 0, khz); + return q_exec(&t); +} + int swdp_open(void) { pthread_create(&swd_thread, NULL, swd_reader, NULL); return 0; diff --git a/tools/rswdp.h b/tools/rswdp.h @@ -62,6 +62,7 @@ void swdp_target_reset(int enable); int swdp_bootloader(void); int swdp_set_clock(unsigned khz); +int swo_set_clock(unsigned khz); #endif diff --git a/tools/swo.c b/tools/swo.c @@ -0,0 +1,38 @@ +/* swo.c + * + * Copyright 2015 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <pthread.h> +#include <fw/types.h> +#include <debugger.h> + +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++); + } + *p++ = '\n'; + *p++ = 0; + xprintf(XDATA, buf); +} +