commit 72a26a5bc1b2c47dc5cf2bc111c7cbcd1fbaa9f7
parent 1b4559aa03e8793a3901fd4a21dfb673f6e8b8e1
Author: Brian Swetland <swetland@frotz.net>
Date: Wed, 8 Mar 2023 20:47:46 -0800
added upload and download commands
Diffstat:
4 files changed, 135 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
@@ -69,7 +69,8 @@ COMMON := src/transport-arm-debug.c src/transport-dap.c src/usb.c
XTEST_SRCS := src/xtest.c $(COMMON)
XTEST_OBJS := $(addprefix out/,$(patsubst %.c,%.o,$(filter %.c,$(XTEST_SRCS))))
-XDEBUG_SRCS := src/xdebug.c src/commands.c $(COMMON)
+XDEBUG_SRCS := src/xdebug.c $(COMMON)
+XDEBUG_SRCS += src/commands.c src/commands-file.c src/commands-agent.c
XDEBUG_SRCS += tui/tui.c termbox/termbox.c termbox/utf8.c gen/builtins.c
XDEBUG_OBJS := $(addprefix out/,$(patsubst %.c,%.o,$(filter %.c,$(XDEBUG_SRCS))))
diff --git a/src/commands-agent.c b/src/commands-agent.c
diff --git a/src/commands-file.c b/src/commands-file.c
@@ -0,0 +1,127 @@
+// Copyright 2023, Brian Swetland <swetland@frotz.net>
+// Licensed under the Apache License, Version 2.0.
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "xdebug.h"
+#include "transport.h"
+#include "arm-v7-debug.h"
+#include "arm-v7-system-control.h"
+
+void *load_file(const char *fn, size_t *_sz) {
+ int fd;
+ off_t sz;
+ void *data = NULL;
+ fd = open(fn, O_RDONLY);
+ if (fd < 0) goto fail;
+ sz = lseek(fd, 0, SEEK_END);
+ if (sz < 0) goto fail;
+ if (lseek(fd, 0, SEEK_SET)) goto fail;
+ if ((data = malloc(sz + 4)) == NULL) goto fail;
+ if (read(fd, data, sz) != sz) goto fail;
+ *_sz = sz;
+ return data;
+fail:
+ if (data) free(data);
+ if (fd >= 0) close(fd);
+ return NULL;
+}
+
+static long long now() {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return ((long long) tv.tv_usec) + ((long long) tv.tv_sec) * 1000000LL;
+}
+
+int do_upload(DC* dc, CC* cc) {
+ int status = DBG_ERR;
+ const char* fn;
+ uint32_t addr;
+ uint32_t len;
+ uint32_t sz;
+ long long t0, t1;
+ int fd, r;
+ void *data;
+
+ if (cmd_arg_str(cc, 1, &fn)) return DBG_ERR;
+ if (cmd_arg_u32(cc, 2, &addr)) return DBG_ERR;
+ if (cmd_arg_u32(cc, 3, &len)) return DBG_ERR;
+ if (addr & 3) {
+ ERROR("address not word aligned\n");
+ return DBG_ERR;
+ }
+ if ((fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644)) < 0) {
+ ERROR("cannot open '%s'\n", fn);
+ return DBG_ERR;
+ }
+ sz = (len + 3) & ~3;
+
+ if ((data = malloc(sz)) == NULL) {
+ ERROR("out of memory\n");
+ goto done;
+ }
+
+ INFO("upload: reading %d bytes...\n", sz);
+ t0 = now();
+ if (dc_mem_rd_words(dc, addr, sz / 4, data) < 0) {
+ ERROR("failed to read data\n");
+ goto done;
+ }
+ t1 = now();
+ INFO("upload: %lld uS -> %lld B/s\n", (t1 - t0),
+ (((long long)sz) * 1000000LL) / (t1 - t0));
+
+ char *x = data;
+ while (len > 0) {
+ r = write(fd, x, sz);
+ if (r < 0) {
+ if (errno == EINTR) continue;
+ ERROR("write error\n");
+ goto done;
+ }
+ x += r;
+ len -= r;
+ }
+ status = 0;
+done:
+ close(fd);
+ if (data) free(data);
+ return status;
+}
+
+int do_download(DC* dc, CC* cc) {
+ const char* fn;
+ uint32_t addr;
+ void *data;
+ size_t sz;
+ long long t0, t1;
+
+ if (cmd_arg_str(cc, 1, &fn)) return DBG_ERR;
+ if (cmd_arg_u32(cc, 2, &addr)) return DBG_ERR;
+
+ if ((data = load_file(fn, &sz)) == NULL) {
+ ERROR("cannot read '%s'\n", fn);
+ return DBG_ERR;
+ }
+ sz = (sz + 3) & ~3;
+
+ INFO("download: sending %ld bytes...\n", sz);
+ t0 = now();
+ if (dc_mem_wr_words(dc, addr, sz / 4, data) < 0) {
+ ERROR("failed to write data\n");
+ free(data);
+ return DBG_ERR;
+ }
+ t1 = now();
+ INFO("download: %lld uS -> %lld B/s\n", (t1 - t0),
+ (((long long)sz) * 1000000LL) / (t1 - t0));
+ free(data);
+ return 0;
+}
+
+
diff --git a/src/commands.c b/src/commands.c
@@ -11,7 +11,7 @@
int do_attach(DC* dc, CC* cc) {
uint32_t n;
- dc_set_clock(dc, 4000000);
+ dc_set_clock(dc, 1000000);
return dc_attach(dc, 0, 0, &n);
}
@@ -255,6 +255,9 @@ int do_exit(DC* dc, CC* cc) {
int do_help(DC* dc, CC* cc);
+int do_upload(DC* dc, CC* cc);
+int do_download(DC* dc, CC* cc);
+
struct {
const char* name;
int (*func)(DC* dc, CC* cc);
@@ -274,6 +277,8 @@ struct {
{ "dr", do_rd, NULL },
{ "wr", do_wr, "write word wr <addr> <val>" },
{ "regs", do_regs, "dump registers" },
+{ "download", do_download, "write file to memory download <file> <addr>" },
+{ "upload", do_upload, "read memory to file upload <file> <addr> <len>" },
{ "help", do_help, "list commands" },
{ "exit", do_exit, "exit debugger" },
{ "quit", do_exit, NULL },