changeset 656:9f5a3e9e6294

fc-xram: implemented CRC-32 verification
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 03 Mar 2020 00:08:27 +0000
parents a880f48d6ac0
children 742c99c1ff52
files loadtools/Makefile loadtools/chainload.c
diffstat 2 files changed, 58 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/loadtools/Makefile	Mon Mar 02 23:33:37 2020 +0000
+++ b/loadtools/Makefile	Tue Mar 03 00:08:27 2020 +0000
@@ -21,10 +21,10 @@
 		ltpassthru.o ltscript.o romload.o srecreader.o tpinterf.o \
 		tpinterf2.o tpinterf3.o tpinterfb.o
 
-XRAM_OBJS=	chainload.o clmain.o compalload.o defexitstub.o defpath.o \
-		flashstubs.o hexdecode.o hwparam.o initscript.o labaud.o \
-		romload.o secondprog.o srecreader.o tpinterf.o tpinterfb.o \
-		ttypassthru.o
+XRAM_OBJS=	chainload.o clmain.o compalload.o crc32tab.o defexitstub.o \
+		defpath.o flashstubs.o hexdecode.o hwparam.o initscript.o \
+		labaud.o lacrc32.o romload.o secondprog.o srecreader.o \
+		tpinterf.o tpinterf2.o tpinterfb.o ttypassthru.o
 
 BUZPLAY_OBJS=	bpdispatch.o bpmain.o buzplay.o compalload.o defpath.o \
 		flashstubs.o hexdecode.o hwparam.o labaud.o ltexit.o \
--- a/loadtools/chainload.c	Mon Mar 02 23:33:37 2020 +0000
+++ b/loadtools/chainload.c	Tue Mar 03 00:08:27 2020 +0000
@@ -10,6 +10,7 @@
 #include <strings.h>
 #include <time.h>
 #include "../libserial/baudrate.h"
+#include "discontig.h"
 #include "srecreader.h"
 
 extern int target_fd;
@@ -19,15 +20,20 @@
 extern struct baudrate *current_baud_rate;
 extern struct baudrate *xram_run_baudrate;
 extern int xram_jtag_mode;
+extern uint32_t crc32_table[];
 
 perform_chain_load()
 {
-	int resp, reclen;
+	int rc, reclen, too_many_regions;
 	unsigned long rec_count;
+	struct discontig_prog regions[MAX_SREC_REGIONS], *regp;
+	unsigned regcount, reg;
 	char *argv[3], jumparg[10];
 	u_char scratch[3], expect_conf[3];
 	time_t start_time, finish_time;
 	unsigned duration, mm, ss;
+	u_long crc_from_target;
+	int i, c;
 
 	if (open_srec_file(&xramimage) < 0)
 		exit(1);
@@ -39,6 +45,9 @@
 		exit(1);
 	/* read and send S-record image */
 	expect_conf[0] = 0x06;
+	regp = regions;
+	regcount = 0;
+	too_many_regions = 0;
 	for (rec_count = 0; ; ) {
 		if (read_s_record(&xramimage) < 0)
 			exit(1);
@@ -82,6 +91,33 @@
 			exit(1);
 		}
 		rec_count++;
+		/* discontiguous regions and CRC-32 accumulation */
+		if (!regcount) {
+			regp->start = xramimage.addr;
+			regp->end = xramimage.addr;
+			regp->crc = 0xFFFFFFFF;
+			regcount = 1;
+		}
+		if (xramimage.addr != regp->end) {
+			if (regcount >= MAX_SREC_REGIONS)
+				too_many_regions = 1;
+			else {
+				regp++;
+				regcount++;
+				regp->start = xramimage.addr;
+				regp->end = xramimage.addr;
+				regp->crc = 0xFFFFFFFF;
+			}
+		}
+		if (!too_many_regions) {
+			for (i = 0; i < xramimage.datalen; i++) {
+				c = xramimage.record[i+5];
+				regp->crc = crc32_table[regp->crc & 0xFF ^ c]
+					^ (regp->crc >> 8);
+			}
+			regp->end += xramimage.datalen;
+		}
+		/* target sync and progress indication */
 		if (rec_count % current_baud_rate->xram_records == 0) {
 			scratch[0] = 0x05;	/* ENQ */
 			write(target_fd, scratch, 1);
@@ -120,9 +156,24 @@
 	mm = duration / 60;
 	ss = duration - mm * 60;
 	printf("XRAM image transferred in %um%us\n", mm, ss);
+	printf("Verifying CRC-32 of %u downloaded region(s)\n", regcount);
+	for (reg = 0, regp = regions; reg < regcount; reg++, regp++) {
+		rc = crc32_on_target((u_long) regp->start,
+				     (u_long) (regp->end - regp->start),
+				     &crc_from_target);
+		if (rc < 0)
+			exit(1);
+		if (crc_from_target != regp->crc) {
+			fprintf(stderr, "error: CRC mismatch!\n");
+			exit(1);
+		}
+		putchar('.');
+		fflush(stdout);
+	}
+	putchar('\n');
 	if (xram_run_baudrate != current_baud_rate) {
-		resp = loadagent_switch_baud(xram_run_baudrate);
-		if (resp)
+		rc = loadagent_switch_baud(xram_run_baudrate);
+		if (rc)
 			exit(1);
 	}
 	if (xram_jtag_mode) {