diff loadtools/flprogsrec.c @ 0:e7502631a0f9

initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 Jun 2016 00:13:35 +0000
parents
children 0dd2c87c1b63
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loadtools/flprogsrec.c	Sat Jun 11 00:13:35 2016 +0000
@@ -0,0 +1,158 @@
+/*
+ * This module implements the flash program-srec and flash program-m0 commands:
+ * programming flash using S-record files as the data source.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "flash.h"
+#include "srecreader.h"
+
+extern struct flash_bank_info flash_bank_info[2];
+
+flashcmd_progsrec_gen(bank, imgfile, is_m0)
+	char *imgfile;
+{
+	struct flash_bank_info *bi;
+	struct srecreader srr;
+	char *targv[4], shortarg[10], longarg[513];
+	int resp;
+	unsigned long rec_count;
+
+	if (flash_get_cfi(bank) < 0)
+		return(-1);
+	bi = flash_bank_info + bank;
+	srr.filename = imgfile;
+	resp = open_srec_file(&srr);
+	if (resp < 0)
+		return(resp);
+	resp = flash_id_check(bank, 0);
+	if (resp) {
+		fclose(srr.openfile);
+		return(resp);
+	}
+	sprintf(shortarg, "%lx", (u_long) bi->base_addr);
+	targv[0] = bi->ops->loadagent_setbase_cmd;
+	targv[1] = shortarg;
+	targv[2] = 0;
+	printf("Setting flash base address: %s %s\n", targv[0], targv[1]);
+	tpinterf_make_cmd(targv);
+	if (tpinterf_send_cmd() < 0) {
+		fclose(srr.openfile);
+		return(-1);
+	}
+	resp = tpinterf_pass_output(1);
+	if (resp) {
+		fclose(srr.openfile);
+		return(resp);
+	}
+	if (bi->ops->prep_for_program(bi) < 0) {
+		fclose(srr.openfile);
+		return(-1);
+	}
+	targv[0] = bi->ops->loadagent_program_cmd;
+	targv[1] = shortarg;
+	targv[2] = longarg;
+	targv[3] = 0;
+	for (rec_count = 0; ; ) {
+		if (read_s_record(&srr) < 0) {
+			/* error msg already printed */
+			fclose(srr.openfile);
+			return(-1);
+		}
+		if (srr.record_type == '0') {
+			if (srr.lineno == 1)
+				continue;
+			fprintf(stderr,
+	"Warning: S0 record found in line %d of %s (expected in line 1 only)\n",
+				srr.lineno, srr.filename);
+			continue;
+		} else if (srr.record_type == '7')
+			break;
+		else if (srr.record_type != '3') {
+			fprintf(stderr,
+		"Warning: unsupported S%c record type in line %d of %s\n",
+				srr.record_type, srr.lineno, srr.filename);
+			continue;
+		}
+		/* must be S3 */
+		if (s3s7_get_addr_data(&srr) < 0) {
+			/* error msg already printed */
+			fclose(srr.openfile);
+			return(-1);
+		}
+		if (srr.datalen < 1) {
+			fprintf(stderr,
+			"%s line %d: S3 record of zero data length ignored\n",
+				srr.filename, srr.lineno);
+			continue;
+		}
+		if (srr.addr & 1 || srr.datalen & 1) {
+			fprintf(stderr,
+			"%s line %d: violates word alignment requirement\n",
+				srr.filename, srr.lineno);
+			fclose(srr.openfile);
+			return(-1);
+		}
+		srr.addr &= bi->geom->total_size - 1;
+		if (srr.addr + srr.datalen > bi->geom->total_size) {
+			fprintf(stderr,
+			"%s line %d: goes past the end of the flash bank\n",
+				srr.filename, srr.lineno);
+			fclose(srr.openfile);
+			return(-1);
+		}
+		if (!rec_count)
+		    printf("Programming flash, each \'.\' is 100 S-records\n");
+		sprintf(shortarg, "%lx", (u_long) srr.addr);
+		build_flashw_hex_string(srr.record + 5, longarg,
+					srr.datalen >> 1, is_m0);
+		tpinterf_make_cmd(targv);
+		if (tpinterf_send_cmd() < 0) {
+			fclose(srr.openfile);
+			return(-1);
+		}
+		resp = tpinterf_pass_output(8);	/* 8 s timeout */
+		if (resp) {
+			fclose(srr.openfile);
+			return(resp);
+		}
+		rec_count++;
+		if (rec_count % 100 == 0) {
+			putchar('.');
+			fflush(stdout);
+		}
+	}
+	/* got S7 */
+	fclose(srr.openfile);
+	if (!rec_count) {
+		fprintf(stderr,
+		"%s line %d: S7 without any preceding S3 data records\n",
+			srr.filename, srr.lineno);
+		return(-1);
+	}
+	printf("\nProgramming complete\n");
+	return(0);
+}
+
+flashcmd_program_srec(argc, argv, bank)
+	char **argv;
+{
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s %s image.srec\n", argv[0], argv[1]);
+		return(-1);
+	}
+	return flashcmd_progsrec_gen(bank, argv[2], 0);
+}
+
+flashcmd_program_m0(argc, argv, bank)
+	char **argv;
+{
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s %s image.m0\n", argv[0], argv[1]);
+		return(-1);
+	}
+	return flashcmd_progsrec_gen(bank, argv[2], 1);
+}