commit 78e92d3effc4c8413b3e727cda2009a69040cb17
parent 57e11b8a3fdad90f001f7a899fb4db86d0e80e22
Author: Brian Swetland <swetland@frotz.net>
Date:   Sun, 21 Jun 2015 22:19:21 -0700
gdb-bridge: memory writes work now
Diffstat:
1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/tools/gdb-bridge.c b/tools/gdb-bridge.c
@@ -311,6 +311,46 @@ static void handle_set(struct gdbcnxn *gc, char *cmd, char *args) {
 	}
 }
 
+// Since we're only guaranteed 32bit reads and writes by the MEM-AP
+// convert non-aligned writes into a read-modify-write followed by
+// an aligned multiword write, followed by a read-modify-write.
+// (as necessary)
+void write_memory(u32 addr, unsigned char *data, int len) {
+	u32 x;
+
+	if (len < 1) {
+		return;
+	}
+
+	if (addr & 3) {
+		int offset = (addr & 3);
+		int count = 4 - offset;
+		if (count > len) {
+			count = len;
+		}
+		swdp_ahb_read(addr & (~3), &x);
+		memcpy(((char*) &x) + offset, data, count);
+		swdp_ahb_write(addr & (~3), x);
+		len -= count;
+		data += count;
+		addr += count;
+	}
+
+	if (len > 3) {
+		int count = (4 * (len / 4));
+		swdp_ahb_write32(addr, (void*) data, len / 4);
+		len -= count;
+		data += count;
+		addr += count;
+	}
+
+	if (len > 0) {
+		swdp_ahb_read(addr, &x);
+		memcpy(&x, data, len);
+		swdp_ahb_write(addr, x);
+	}
+}
+
 void handle_command(struct gdbcnxn *gc, unsigned char *cmd) {
 	union {
 		u32 w[256+2];
@@ -361,8 +401,8 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) {
 			break;
 		}
 		len = hextobin(gc->rxbuf, data, MAXPKT);
-		zprintf("write %d bytes at %x (%d recv)\n", n, x, len);
-		gdb_puts(gc, "EFF"); //Eerrno or OK
+		write_memory(x, gc->rxbuf, len);
+		gdb_puts(gc, "OK");
 		break;
 		}
 	// g
@@ -446,7 +486,7 @@ void gdb_server(int fd) {
 
 	gdb_init(&gc, fd);
 
-	gc.flags |= F_TRACE;
+//	gc.flags |= F_TRACE;
 
 	for (;;) {
 		r = read(fd, iobuf, sizeof(iobuf));