diff loadtools/romload.c @ 636:3172e3111ab7

loadtools/romload.c: implemented grouping of S-records into bigger blocks
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 01 Mar 2020 05:40:29 +0000
parents 4dca8542f569
children 46d7ed4ee634
line wrap: on
line diff
--- a/loadtools/romload.c	Sun Mar 01 02:49:01 2020 +0000
+++ b/loadtools/romload.c	Sun Mar 01 05:40:29 2020 +0000
@@ -47,9 +47,16 @@
 				/* boot ROM runs with before getting this cmd */
 };
 
-static u_char write_cmd[10] = {'<', 'w', 0x01, 0x01, 0x00};
-static u_char cksum_cmd[3]  = {'<', 'c'};
-static u_char branch_cmd[6] = {'<', 'b'};
+static u_char write_cmd[1024] = {'<', 'w', 0x01, 0x01};
+static u_char cksum_cmd[3]    = {'<', 'c'};
+static u_char branch_cmd[6]   = {'<', 'b'};
+
+static uint32_t write_cmd_endaddr;
+static unsigned write_cmd_datalen;
+static unsigned write_block_count;
+static uint16_t image_cksum;
+
+#define	MAX_WRITE_LEN	0x3F6
 
 #define	INTERMEDIATE_TIMEOUT	500	/* ms to wait for responses */
 #define	SERIAL_FLUSH_DELAY	200	/* also in ms */
@@ -188,17 +195,47 @@
 	uint32_t sum;
 	int i, llen;
 
-	sum = iramimage.datalen + 5;
-	llen = iramimage.datalen + 4;
+	sum = write_cmd_datalen + 5;
+	llen = write_cmd_datalen + 4;
 	for (i = 0; i < llen; i++)
-		sum += iramimage.record[i+1];
+		sum += write_cmd[i+6];
 	return sum;
 }
 
+static void
+send_write_cmd()
+{
+	int resp;
+
+	write_cmd[4] = write_cmd_datalen >> 8;
+	write_cmd[5] = write_cmd_datalen & 0xFF;
+	write(target_fd, write_cmd, write_cmd_datalen + 10);
+	/* update our checksum accumulator */
+	image_cksum += ~compute_block_cksum() & 0xFF;
+	/* collect response */
+	resp = expect_response(INTERMEDIATE_TIMEOUT);
+	if (resp != 'w') {
+		fprintf(stderr, "Block #%lu: ", write_block_count);
+		if (resp < 0)
+			fprintf(stderr, "No response to <w command\n");
+		else if (isprint(resp))
+			fprintf(stderr,
+			"Got >%c in response to <w command; expected >w\n",
+				resp);
+		else
+			fprintf(stderr,
+			"Got > %02X in response to <w command; expected >w\n",
+				resp);
+		exit(1);
+	}
+	putchar('.');
+	fflush(stdout);
+	write_block_count++;
+}
+
 perform_romload()
 {
 	int resp;
-	uint16_t image_cksum;
 	unsigned long rec_count;
 	u_char addresp[2];
 	static int zero = 0;
@@ -240,6 +277,8 @@
 	usleep(SERIAL_FLUSH_DELAY * 1000);
 	tcflush(target_fd, TCIFLUSH);
 
+	write_cmd_datalen = 0;
+	write_block_count = 0;
 	image_cksum = 0;
 	for (rec_count = 0; ; ) {
 		if (read_s_record(&iramimage) < 0)
@@ -273,33 +312,23 @@
 				iramimage.filename, iramimage.lineno);
 			exit(1);
 		}
-		/* form <w command */
+		/* get to work */
 		if (!rec_count)
 			printf("Sending image payload\n");
-		write_cmd[5] = iramimage.datalen;
-		bcopy(iramimage.record + 1, write_cmd + 6, 4);
-		write(target_fd, write_cmd, sizeof write_cmd);
-		write(target_fd, iramimage.record + 5, iramimage.datalen);
-		/* update our checksum accumulator */
-		image_cksum += ~compute_block_cksum() & 0xFF;
-		/* collect response */
-		resp = expect_response(INTERMEDIATE_TIMEOUT);
-		if (resp != 'w') {
-			fprintf(stderr, "Block #%lu: ", rec_count);
-			if (resp < 0)
-				fprintf(stderr, "No response to <w command\n");
-			else if (isprint(resp))
-				fprintf(stderr,
-			"Got >%c in response to <w command; expected >w\n",
-					resp);
-			else
-				fprintf(stderr,
-			"Got > %02X in response to <w command; expected >w\n",
-					resp);
-			exit(1);
+		if (write_cmd_datalen &&
+		    (iramimage.addr != write_cmd_endaddr ||
+		     write_cmd_datalen + iramimage.datalen > MAX_WRITE_LEN)) {
+			send_write_cmd();
+			write_cmd_datalen = 0;
 		}
-		putchar('.');
-		fflush(stdout);
+		if (!write_cmd_datalen) {
+			bcopy(iramimage.record + 1, write_cmd + 6, 4);
+			write_cmd_endaddr = iramimage.addr;
+		}
+		bcopy(iramimage.record + 5, write_cmd + 10 + write_cmd_datalen,
+			iramimage.datalen);
+		write_cmd_endaddr += iramimage.datalen;
+		write_cmd_datalen += iramimage.datalen;
 		rec_count++;
 	}
 	/* got S7 */
@@ -310,6 +339,8 @@
 			iramimage.filename, iramimage.lineno);
 		exit(1);
 	}
+	send_write_cmd();	/* last block */
+	putchar('\n');		/* end line of dots */
 
 	/* send <c */
 	printf("Sending checksum\n");