changeset 981:f21798eb13cf

fc-loadtool: implement flash ppb-* commands
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 02 Dec 2023 05:46:00 +0000
parents 0a4d19aab608
children 1c5b485f10ba
files loadtools/flamdsec.c loadtools/flmain.c
diffstat 2 files changed, 144 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/loadtools/flamdsec.c	Sat Dec 02 04:31:58 2023 +0000
+++ b/loadtools/flamdsec.c	Sat Dec 02 05:46:00 2023 +0000
@@ -13,6 +13,46 @@
 
 extern struct flash_bank_info flash_bank_info[2];
 
+/*
+ * Some common functions for Spansion PL-N flash: common between
+ * flash lock-state retrieval and active PPB programming.
+ */
+
+static
+pln_special_mode_entry(base_addr, mode_opc)
+	uint32_t base_addr;
+	uint16_t mode_opc;
+{
+	if (do_w16(base_addr + 0xAAA, 0xAA)) {
+bad_w16:	fprintf(stderr,
+"unexpected response to w16 in PL-N special mode entry sequence - aborting\n");
+		return(-1);
+	}
+	if (do_w16(base_addr + 0x554, 0x55))
+		goto bad_w16;
+	if (do_w16(base_addr + 0xAAA, mode_opc))
+		goto bad_w16;
+	return(0);
+}
+
+static
+pln_special_mode_exit(base_addr)
+	uint32_t base_addr;
+{
+	if (do_w16(base_addr, 0x90)) {
+bad_w16:	fprintf(stderr,
+"unexpected response to w16 in PL-N special mode exit sequence - aborting\n");
+		return(-1);
+	}
+	if (do_w16(base_addr, 0x00))
+		goto bad_w16;
+	return(0);
+}
+
+/*
+ * flash lock-state implementation with its helper functions.
+ */
+
 static
 issue_read_id(base_addr)
 	uint32_t base_addr;
@@ -62,37 +102,6 @@
 	return(0);
 }
 
-static
-pln_special_mode_entry(base_addr, mode_opc)
-	uint32_t base_addr;
-	uint16_t mode_opc;
-{
-	if (do_w16(base_addr + 0xAAA, 0xAA)) {
-bad_w16:	fprintf(stderr,
-"unexpected response to w16 in PL-N special mode entry sequence - aborting\n");
-		return(-1);
-	}
-	if (do_w16(base_addr + 0x554, 0x55))
-		goto bad_w16;
-	if (do_w16(base_addr + 0xAAA, mode_opc))
-		goto bad_w16;
-	return(0);
-}
-
-static
-pln_special_mode_exit(base_addr)
-	uint32_t base_addr;
-{
-	if (do_w16(base_addr, 0x90)) {
-bad_w16:	fprintf(stderr,
-"unexpected response to w16 in PL-N special mode exit sequence - aborting\n");
-		return(-1);
-	}
-	if (do_w16(base_addr, 0x00))
-		goto bad_w16;
-	return(0);
-}
-
 flashcmd_lock_state(argc, argv, bank)
 	char **argv;
 {
@@ -171,6 +180,11 @@
 	return(0);
 }
 
+/*
+ * Spansion PL-J PPB write functions, referenced from lock_info structures
+ * in fldevs.c device descriptions.
+ */
+
 static
 plj_ppb_write_op(base_addr, is_erase, retp)
 	uint32_t base_addr;
@@ -307,3 +321,96 @@
 		return(-1);
 	return plj_ppb_erase_cycle(reqbank);
 }
+
+/*
+ * Front end functions for PPB operation commands.
+ */
+
+flashcmd_ppb_program(argc, argv, bank)
+	char **argv;
+{
+	struct flash_bank_info *bi;
+	struct amd_lock_info *li;
+	u_long offset_arg;
+	struct sector_info *sp;
+	char *strtoul_endp;
+
+	if (argc != 3) {
+inv:		fprintf(stderr, "usage: %s %s sector-offset\n",
+			argv[0], argv[1]);
+		return(-1);
+	}
+	offset_arg = strtoul(argv[2], &strtoul_endp, 16);
+	if (*strtoul_endp)
+		goto inv;
+	if (flash_detect(bank, 0) < 0)
+		return(-1);
+	bi = flash_bank_info + bank;
+	li = bi->amd_lock;
+	if (!li || !li->ppb_program_one) {
+		fprintf(stderr,
+			"Operation not supported for this flash chip type\n");
+		return(-1);
+	}
+	if (offset_arg >= bi->geom->total_size) {
+		fprintf(stderr,
+		"error: specified offset exceeds flash bank size (0x%lx)\n",
+			(u_long) bi->geom->total_size);
+		return(-1);
+	}
+	if (get_flash_sector_table(bi) < 0)
+		return(-1);
+	for (sp = bi->sectors; sp->size; sp++)
+		if (sp->start == offset_arg)
+			break;
+	if (!sp->size) {
+		fprintf(stderr,
+	"error: specified offset not aligned to a flash sector boundary\n");
+		return(-1);
+	}
+	return li->ppb_program_one(bi, sp->start);
+}
+
+flashcmd_ppb_program_all(argc, argv, bank)
+	char **argv;
+{
+	struct flash_bank_info *bi;
+	struct amd_lock_info *li;
+
+	if (argc > 2) {
+		fprintf(stderr, "error: too many arguments\n");
+		return(-1);
+	}
+	if (flash_detect(bank, 0) < 0)
+		return(-1);
+	bi = flash_bank_info + bank;
+	li = bi->amd_lock;
+	if (!li || !li->ppb_program_all) {
+		fprintf(stderr,
+			"Operation not supported for this flash chip type\n");
+		return(-1);
+	}
+	return li->ppb_program_all(bank);
+}
+
+flashcmd_ppb_erase_all(argc, argv, bank)
+	char **argv;
+{
+	struct flash_bank_info *bi;
+	struct amd_lock_info *li;
+
+	if (argc > 2) {
+		fprintf(stderr, "error: too many arguments\n");
+		return(-1);
+	}
+	if (flash_detect(bank, 0) < 0)
+		return(-1);
+	bi = flash_bank_info + bank;
+	li = bi->amd_lock;
+	if (!li || !li->ppb_erase_all) {
+		fprintf(stderr,
+			"Operation not supported for this flash chip type\n");
+		return(-1);
+	}
+	return li->ppb_erase_all(bank);
+}
--- a/loadtools/flmain.c	Sat Dec 02 04:31:58 2023 +0000
+++ b/loadtools/flmain.c	Sat Dec 02 05:46:00 2023 +0000
@@ -97,6 +97,9 @@
 extern int flashcmd_erase();
 extern int flashcmd_erase_program_boot();
 extern int flashcmd_lock_state();
+extern int flashcmd_ppb_program();
+extern int flashcmd_ppb_program_all();
+extern int flashcmd_ppb_erase_all();
 extern int flashcmd_progbin_wrap();
 extern int flashcmd_program_m0();
 extern int flashcmd_program_srec();
@@ -125,6 +128,9 @@
 	{"id", flashcmd_id},
 	{"info", flashcmd_info},
 	{"lock-state", flashcmd_lock_state},
+	{"ppb-program", flashcmd_ppb_program},
+	{"ppb-program-all", flashcmd_ppb_program_all},
+	{"ppb-erase-all", flashcmd_ppb_erase_all},
 	{"program-bin", flashcmd_progbin_wrap},
 	{"program-m0", flashcmd_program_m0},
 	{"program-srec", flashcmd_program_srec},