changeset 409:23ab8fe81764

Intel flash: unlock command implemented
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Tue, 17 Jun 2014 03:18:02 +0000
parents 431023033c86
children 81d387690063
files loadtools/flash.h loadtools/flashops.c loadtools/flmain.c loadtools/flmisc.c
diffstat 4 files changed, 66 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/loadtools/flash.h	Tue Jun 17 01:52:46 2014 +0000
+++ b/loadtools/flash.h	Tue Jun 17 03:18:02 2014 +0000
@@ -60,6 +60,7 @@
 	int	(*prep_for_program)();
 	char	*loadagent_setbase_cmd;
 	char	*loadagent_program_cmd;
+	int	needs_unlock;
 };
 
 struct flash_bank_info {
--- a/loadtools/flashops.c	Tue Jun 17 01:52:46 2014 +0000
+++ b/loadtools/flashops.c	Tue Jun 17 03:18:02 2014 +0000
@@ -92,6 +92,7 @@
 	.prep_for_program	= noop,
 	.loadagent_setbase_cmd	= "AMFB",
 	.loadagent_program_cmd	= "AMFW",
+	.needs_unlock		= 0,
 };
 
 /* Intel flash functions */
@@ -200,4 +201,5 @@
 	.erase_sector		= intel_sector_erase,
 	.loadagent_setbase_cmd	= "INFB",
 	.loadagent_program_cmd	= "INFW",
+	.needs_unlock		= 1,
 };
--- a/loadtools/flmain.c	Tue Jun 17 01:52:46 2014 +0000
+++ b/loadtools/flmain.c	Tue Jun 17 03:18:02 2014 +0000
@@ -203,6 +203,7 @@
 extern int flashcmd_reset();
 extern int flashcmd_sectors();
 extern int flashcmd_status();
+extern int flashcmd_unlock();
 
 static struct cmdtab {
 	char *cmd;
@@ -221,6 +222,7 @@
 	{"reset", flashcmd_reset},
 	{"sectors", flashcmd_sectors},
 	{"status", flashcmd_status},
+	{"unlock", flashcmd_unlock},
 	{0, 0}
 };
 
--- a/loadtools/flmisc.c	Tue Jun 17 01:52:46 2014 +0000
+++ b/loadtools/flmisc.c	Tue Jun 17 03:18:02 2014 +0000
@@ -248,3 +248,64 @@
 	bi = flash_bank_info + bank;
 	return bi->ops->status_cmd(bi);
 }
+
+flashcmd_unlock(argc, argv, bank)
+	char **argv;
+{
+	struct flash_bank_info *bi;
+	u_long offset, len;
+	char *strtoul_endp;
+	struct sector_info *startsec, *endsec, *sp;
+	int stat;
+
+	if (flash_get_cfi(bank) < 0)
+		return(-1);
+	bi = flash_bank_info + bank;
+	if (!bi->ops->needs_unlock) {
+		fprintf(stderr,
+	    "This operation is not applicable to the selected flash type\n");
+		return(-1);
+	}
+	if (argc != 4) {
+inv:		fprintf(stderr, "usage: %s %s hex-start-offset hex-length\n",
+			argv[0], argv[1]);
+		return(-1);
+	}
+	offset = strtoul(argv[2], &strtoul_endp, 16);
+	if (*strtoul_endp)
+		goto inv;
+	if (offset >= bi->geom->total_size) {
+		fprintf(stderr,
+		"error: specified offset exceeds flash bank size (0x%lx)\n",
+			(u_long) bi->geom->total_size);
+		return(-1);
+	}
+	len = strtoul(argv[3], &strtoul_endp, 16);
+	if (*strtoul_endp)
+		goto inv;
+	if (len > bi->geom->total_size - offset) {
+		fprintf(stderr,
+	"error: specified offset+length exceed flash bank size (0x%lx)\n",
+			(u_long) bi->geom->total_size);
+		return(-1);
+	}
+	if (!len) {
+		printf("Zero length specified - nothing to do!\n");
+		return(0);
+	}
+	/* now enforce sector alignment for both offset and length */
+	if (get_flash_sector_table(bank) < 0)
+		return(-1);
+	if (get_flash_sector_range(bi, offset, len, &startsec, &endsec) < 0)
+		return(-1);
+	printf("Unlocking %d sector(s)\n", endsec - startsec);
+	for (sp = startsec; sp < endsec; sp++) {
+		stat = bi->ops->unlock_sector(bi, sp);
+		if (stat)
+			return(stat);
+		putchar('.');
+		fflush(stdout);
+	}
+	putchar('\n');
+	return(0);
+}