changeset 660:b34384991094

loadagent: implemented binary flash programming
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 04 Mar 2020 06:51:52 +0000
parents 761e8b0c65b0
children fd7b447b99e3
files target-utils/loadagent/Makefile target-utils/loadagent/amdflash.c target-utils/loadagent/binflash.c target-utils/loadagent/cmdtab.c target-utils/loadagent/intelflash.c
diffstat 5 files changed, 88 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/target-utils/loadagent/Makefile	Tue Mar 03 17:55:20 2020 +0000
+++ b/target-utils/loadagent/Makefile	Wed Mar 04 06:51:52 2020 +0000
@@ -7,8 +7,8 @@
 INSTDIR=/opt/freecalypso/target-bin
 
 PROG=	loadagent
-OBJS=	crt0.o amdflash.o bindump.o binload.o cmd_blankchk.o cmd_memload.o \
-	cmdtab.o intelflash.o main.o serextra.o sertimeout.o
+OBJS=	crt0.o amdflash.o bindump.o binflash.o binload.o cmd_blankchk.o \
+	cmd_memload.o cmdtab.o intelflash.o main.o serextra.o sertimeout.o
 LIBS=	../libcommon/libcommon.a ../libprintf/libprintf.a \
 	../libbase/libbase.a ../libc/libc.a
 LIBGCC=	`${CC} -print-file-name=libgcc.a`
--- a/target-utils/loadagent/amdflash.c	Tue Mar 03 17:55:20 2020 +0000
+++ b/target-utils/loadagent/amdflash.c	Wed Mar 04 06:51:52 2020 +0000
@@ -124,3 +124,9 @@
 	}
 	return(0);
 }
+
+void
+cmd_AMFWB()
+{
+	binary_flash_prog_main(amdflash_binary_prog);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/target-utils/loadagent/binflash.c	Wed Mar 04 06:51:52 2020 +0000
@@ -0,0 +1,70 @@
+/*
+ * Here we are going to implement our new binary protocol
+ * for flash programming.
+ */
+
+#include "types.h"
+
+void
+binary_flash_prog_main(program_func)
+	int (*program_func)();
+{
+	u8 buf[2048] __attribute__ ((aligned (2)));
+	u32 flash_offset;
+	unsigned nbytes, p;
+	int c;
+
+	for (;;) {
+		do
+			c = serial_in_poll();
+		while (c < 0);
+		if (c == 0x04)
+			return;
+		if (c != 0x01) {
+			serial_out(0x15);	/* NAK */
+			printf("ERROR: invalid command opcode\n");
+			return;
+		}
+		/* receive header */
+		for (p = 0; p < 6; p++) {
+			c = serial_in_timeout(1000000);		/* 0.6 s */
+			if (c < 0) {
+intermediate_timeout:		serial_out(0x15);	/* NAK */
+				printf("ERROR: timeout receiving command\n");
+				return;
+			}
+			buf[p] = c;
+		}
+		flash_offset =  ((u32) buf[0] << 24) |
+				((u32) buf[1] << 16) |
+				((u32) buf[2] << 8) |
+				 (u32) buf[3];
+		if (flash_offset & 1) {
+			serial_out(0x15);	/* NAK */
+			printf("ERROR: odd flash offset\n");
+			return;
+		}
+		nbytes = ((u32) buf[4] << 8) | (u32) buf[5];
+		if (nbytes & 1) {
+			serial_out(0x15);	/* NAK */
+			printf("ERROR: odd byte count\n");
+			return;
+		}
+		if (nbytes > sizeof buf) {
+			serial_out(0x15);	/* NAK */
+			printf("ERROR: byte count exceeds buffer\n");
+			return;
+		}
+		/* receive data */
+		for (p = 0; p < nbytes; p++) {
+			c = serial_in_timeout(1000000);		/* 0.6 s */
+			if (c < 0)
+				goto intermediate_timeout;
+			buf[p] = c;
+		}
+		c = program_func(flash_offset, nbytes >> 1, buf);
+		if (c < 0)
+			return;
+		serial_out(0x06);	/* ACK */
+	}
+}
--- a/target-utils/loadagent/cmdtab.c	Tue Mar 03 17:55:20 2020 +0000
+++ b/target-utils/loadagent/cmdtab.c	Wed Mar 04 06:51:52 2020 +0000
@@ -2,8 +2,10 @@
 
 extern void cmd_AMFB();
 extern void cmd_AMFW();
+extern void cmd_AMFWB();
 extern void cmd_INFB();
 extern void cmd_INFW();
+extern void cmd_INFWB();
 extern void cmd_abbr();
 extern void cmd_abbw();
 extern void cmd_blankchk();
@@ -32,11 +34,13 @@
 const struct cmdtab cmdtab[] = {
 	{"AMFB", cmd_AMFB},
 	{"AMFW", cmd_AMFW},
+	{"AMFWB", cmd_AMFWB},
 	{"BINDUMP", cmd_memdump_binary},
 	{"BINML", cmd_binary_memload},
 	{"DUMP", cmd_memdump_machine},
 	{"INFB", cmd_INFB},
 	{"INFW", cmd_INFW},
+	{"INFWB", cmd_INFWB},
 	{"ML", cmd_memload},
 	{"abbinit", abb_init},
 	{"abbpage2", abb_unlock_page2},
--- a/target-utils/loadagent/intelflash.c	Tue Mar 03 17:55:20 2020 +0000
+++ b/target-utils/loadagent/intelflash.c	Wed Mar 04 06:51:52 2020 +0000
@@ -118,6 +118,12 @@
 }
 
 void
+cmd_INFWB()
+{
+	binary_flash_prog_main(intelflash_binary_prog);
+}
+
+void
 cmd_intel_rewrite_sector(argbulk)
 	char *argbulk;
 {