[flashrom] [PATCH] generic programmer registration

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Fri Nov 11 07:42:44 CET 2011


Please note that this patch breaks every programmer except hwseq because
we're not passing struct flashchip around yet. To get this working, the
following changes have to be made:
- Pass struct flashchip * everywhere (or struct flashctx *), see my
other patch for that
- Change parallel-style and SPI programmers to use flash->pgm... instead
of par_programmer->... and spi_programmer->...

This compiles and should help you review it, but it is not for merge
until the "struct flashchip * everywhere" patch is in.
Some code has been removed with #if 0 because I wanted to discuss
removing it. The final patch will have no #if 0 at all.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>

Index: flashrom-register_all_programmers_register_generic/flash.h
===================================================================
--- flashrom-register_all_programmers_register_generic/flash.h	(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/flash.h	(Arbeitskopie)
@@ -153,6 +153,7 @@
 	/* Some flash devices have an additional register space. */
 	chipaddr virtual_memory;
 	chipaddr virtual_registers;
+	struct registered_programmer *pgm;
 };
 
 #define TEST_UNTESTED	0
@@ -197,14 +198,13 @@
 	write_gran_1byte,
 	write_gran_256bytes,
 };
-extern enum chipbustype buses_supported;
 extern int verbose;
 extern const char flashrom_version[];
 extern char *chip_to_probe;
 void map_flash_registers(struct flashchip *flash);
 int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len);
 int erase_flash(struct flashchip *flash);
-int probe_flash(int startchip, struct flashchip *fill_flash, int force);
+int probe_flash(struct registered_programmer *pgm, int startchip, struct flashchip *fill_flash, int force);
 int read_flash_to_file(struct flashchip *flash, const char *filename);
 int min(int a, int b);
 int max(int a, int b);
@@ -271,4 +271,5 @@
 int spi_send_multicommand(struct spi_command *cmds);
 uint32_t spi_get_valid_read_addr(void);
 
+enum chipbustype get_buses_supported(void);
 #endif				/* !__FLASH_H__ */
Index: flashrom-register_all_programmers_register_generic/cli_classic.c
===================================================================
--- flashrom-register_all_programmers_register_generic/cli_classic.c	(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/cli_classic.c	(Arbeitskopie)
@@ -172,7 +172,7 @@
 	struct flashchip flashes[3];
 	struct flashchip *fill_flash;
 	const char *name;
-	int namelen, opt, i;
+	int namelen, opt, i, j;
 	int startchip = 0, chipcount = 0, option_index = 0, force = 0;
 #if CONFIG_PRINT_WIKI == 1
 	int list_supported_wiki = 0;
@@ -443,17 +443,21 @@
 		ret = 1;
 		goto out_shutdown;
 	}
-	tempstr = flashbuses_to_text(buses_supported);
+	tempstr = flashbuses_to_text(get_buses_supported());
 	msg_pdbg("This programmer supports the following protocols: %s.\n",
 		 tempstr);
 	free(tempstr);
 
-	for (i = 0; i < ARRAY_SIZE(flashes); i++) {
-		startchip = probe_flash(startchip, &flashes[i], 0);
-		if (startchip == -1)
-			break;
-		chipcount++;
-		startchip++;
+	for (j = 0; j < registered_programmer_count; j++) {
+		startchip = 0;
+		for (i = 0; i < ARRAY_SIZE(flashes); i++) {
+			startchip = probe_flash(&registered_programmers[j],
+						startchip, &flashes[i], 0);
+			if (startchip == -1)
+				break;
+			chipcount++;
+			startchip++;
+		}
 	}
 
 	if (chipcount > 1) {
@@ -471,6 +475,7 @@
 			printf("Note: flashrom can never write if the flash "
 			       "chip isn't found automatically.\n");
 		}
+#if 0 // FIXME: What happens for a forced chip read if multiple compatible programmers are registered?
 		if (force && read_it && chip_to_probe) {
 			printf("Force read (-f -r -c) requested, pretending "
 			       "the chip is there:\n");
@@ -485,6 +490,7 @@
 			       "contain garbage.\n");
 			return read_flash_to_file(&flashes[0], filename);
 		}
+#endif
 		ret = 1;
 		goto out_shutdown;
 	} else if (!chip_to_probe) {
@@ -501,7 +507,7 @@
 	check_chip_supported(fill_flash);
 
 	size = fill_flash->total_size * 1024;
-	if (check_max_decode((buses_supported & fill_flash->bustype), size) &&
+	if (check_max_decode((get_buses_supported() & fill_flash->bustype), size) &&
 	    (!force)) {
 		fprintf(stderr, "Chip is too big for this programmer "
 			"(-V gives details). Use --force to override.\n");
Index: flashrom-register_all_programmers_register_generic/ichspi.c
===================================================================
--- flashrom-register_all_programmers_register_generic/ichspi.c	(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/ichspi.c	(Arbeitskopie)
@@ -1295,7 +1295,7 @@
 	REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS));
 
 	while (len > 0) {
-		block_len = min(len, opaque_programmer->max_data_read);
+		block_len = min(len, flash->pgm->opaque.max_data_read);
 		ich_hwseq_set_addr(addr);
 		hsfc = REGREAD16(ICH9_REG_HSFC);
 		hsfc &= ~HSFC_FCYCLE; /* set read operation */
@@ -1333,7 +1333,7 @@
 
 	while (len > 0) {
 		ich_hwseq_set_addr(addr);
-		block_len = min(len, opaque_programmer->max_data_write);
+		block_len = min(len, flash->pgm->opaque.max_data_write);
 		ich_fill_data(buf, block_len, ICH9_REG_FDATA0);
 		hsfc = REGREAD16(ICH9_REG_HSFC);
 		hsfc &= ~HSFC_FCYCLE; /* clear operation */
Index: flashrom-register_all_programmers_register_generic/opaque.c
===================================================================
--- flashrom-register_all_programmers_register_generic/opaque.c	(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/opaque.c	(Arbeitskopie)
@@ -30,70 +30,62 @@
 #include "chipdrivers.h"
 #include "programmer.h"
 
-const struct opaque_programmer opaque_programmer_none = {
-	.max_data_read = MAX_DATA_UNSPECIFIED,
-	.max_data_write = MAX_DATA_UNSPECIFIED,
-	.probe = NULL,
-	.read = NULL,
-	.write = NULL,
-	.erase = NULL,
-};
-
-const struct opaque_programmer *opaque_programmer = &opaque_programmer_none;
-
 int probe_opaque(struct flashchip *flash)
 {
-	if (!opaque_programmer->probe) {
+	if (!flash->pgm->opaque.probe) {
 		msg_perr("%s called before register_opaque_programmer. "
 			 "Please report a bug at flashrom at flashrom.org\n",
 			 __func__);
 		return 0;
 	}
 
-	return opaque_programmer->probe(flash);
+	return flash->pgm->opaque.probe(flash);
 }
 
 int read_opaque(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
-	if (!opaque_programmer->read) {
+	if (!flash->pgm->opaque.read) {
 		msg_perr("%s called before register_opaque_programmer. "
 			 "Please report a bug at flashrom at flashrom.org\n",
 			 __func__);
 		return 1;
 	}
-	return opaque_programmer->read(flash, buf, start, len);
+	return flash->pgm->opaque.read(flash, buf, start, len);
 }
 
 int write_opaque(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
-	if (!opaque_programmer->write) {
+	if (!flash->pgm->opaque.write) {
 		msg_perr("%s called before register_opaque_programmer. "
 			 "Please report a bug at flashrom at flashrom.org\n",
 			 __func__);
 		return 1;
 	}
-	return opaque_programmer->write(flash, buf, start, len);
+	return flash->pgm->opaque.write(flash, buf, start, len);
 }
 
 int erase_opaque(struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen)
 {
-	if (!opaque_programmer->erase) {
+	if (!flash->pgm->opaque.erase) {
 		msg_perr("%s called before register_opaque_programmer. "
 			 "Please report a bug at flashrom at flashrom.org\n",
 			 __func__);
 		return 1;
 	}
-	return opaque_programmer->erase(flash, blockaddr, blocklen);
+	return flash->pgm->opaque.erase(flash, blockaddr, blocklen);
 }
 
 void register_opaque_programmer(const struct opaque_programmer *pgm)
 {
+	struct registered_programmer rpgm;
+
 	if (!pgm->probe || !pgm->read || !pgm->write || !pgm->erase) {
 		msg_perr("%s called with one of probe/read/write/erase being "
 			 "NULL. Please report a bug at flashrom at flashrom.org\n",
 			 __func__);
 		return;
 	}
-	opaque_programmer = pgm;
-	buses_supported |= BUS_PROG;
+	rpgm.buses_supported = BUS_PROG;
+	rpgm.opaque = *pgm;
+	register_programmer(&rpgm);
 }
Index: flashrom-register_all_programmers_register_generic/spi.c
===================================================================
--- flashrom-register_all_programmers_register_generic/spi.c	(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/spi.c	(Arbeitskopie)
@@ -194,6 +194,9 @@
 
 void register_spi_programmer(const struct spi_programmer *pgm)
 {
-	spi_programmer = pgm;
-	buses_supported |= BUS_SPI;
+	struct registered_programmer rpgm;
+
+	rpgm.buses_supported = BUS_SPI;
+	rpgm.spi = *pgm;
+	register_programmer(&rpgm);
 }
Index: flashrom-register_all_programmers_register_generic/programmer.c
===================================================================
--- flashrom-register_all_programmers_register_generic/programmer.c	(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/programmer.c	(Arbeitskopie)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the flashrom project.
  *
- * Copyright (C) 2009,2010 Carl-Daniel Hailfinger
+ * Copyright (C) 2009,2010,2011 Carl-Daniel Hailfinger
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -113,6 +113,38 @@
 
 void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses)
 {
-	par_programmer = pgm;
-	buses_supported |= buses;
+	struct registered_programmer rpgm;
+
+	rpgm.buses_supported = buses;
+	rpgm.par = *pgm;
+	register_programmer(&rpgm);
 }
+
+/* The limit of 4 is totally arbitrary. */
+#define PROGRAMMERS_MAX 4
+struct registered_programmer registered_programmers[PROGRAMMERS_MAX];
+int registered_programmer_count = 0;
+
+int register_programmer(struct registered_programmer *pgm)
+{
+	if (registered_programmer_count >= PROGRAMMERS_MAX) {
+		msg_perr("Tried to register more than %i programmer "
+			 "interfaces.\n", PROGRAMMERS_MAX);
+		return 1;
+	}
+	registered_programmers[registered_programmer_count] = *pgm;
+	registered_programmer_count++;
+
+	return 0;
+}
+
+enum chipbustype get_buses_supported(void)
+{
+	int i;
+	enum chipbustype ret = BUS_NONE;
+
+	for (i = 0; i < registered_programmer_count; i++)
+		ret |= registered_programmers[i].buses_supported;
+
+	return ret;
+}
Index: flashrom-register_all_programmers_register_generic/flashrom.c
===================================================================
--- flashrom-register_all_programmers_register_generic/flashrom.c	(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/flashrom.c	(Arbeitskopie)
@@ -46,9 +46,6 @@
 
 static char *programmer_param = NULL;
 
-/* Supported buses for the current programmer. */
-enum chipbustype buses_supported;
-
 /*
  * Programmers supporting multiple buses can have differing size limits on
  * each bus. Store the limits for each bus in a common struct.
@@ -314,7 +311,6 @@
 		.fwh		= 0xffffffff,
 		.spi		= 0xffffffff,
 	};
-	buses_supported = BUS_NONE;
 	/* Default to top aligned flash at 4 GB. */
 	flashbase = 0;
 	/* Registering shutdown functions is now allowed. */
@@ -936,7 +932,8 @@
 	return 1;
 }
 
-int probe_flash(int startchip, struct flashchip *fill_flash, int force)
+int probe_flash(struct registered_programmer *pgm, int startchip,
+		struct flashchip *fill_flash, int force)
 {
 	const struct flashchip *flash;
 	unsigned long base = 0;
@@ -948,11 +945,12 @@
 	for (flash = flashchips + startchip; flash && flash->name; flash++) {
 		if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0)
 			continue;
-		buses_common = buses_supported & flash->bustype;
+		buses_common = pgm->buses_supported & flash->bustype;
 		if (!buses_common) {
+#if 0 // Does not really make sense anymore if we use a programmer-centric walk.
 			msg_gspew("Probing for %s %s, %d kB: skipped. ",
 			         flash->vendor, flash->name, flash->total_size);
-			tmp = flashbuses_to_text(buses_supported);
+			tmp = flashbuses_to_text(get_buses_supported());
 			msg_gspew("Host bus type %s ", tmp);
 			free(tmp);
 			tmp = flashbuses_to_text(flash->bustype);
@@ -960,6 +958,7 @@
 				  tmp);
 			free(tmp);
 			msg_gspew("\n");
+#endif
 			continue;
 		}
 		msg_gdbg("Probing for %s %s, %d kB: ",
@@ -975,6 +974,7 @@
 
 		/* Start filling in the dynamic data. */
 		*fill_flash = *flash;
+		fill_flash->pgm = pgm;
 
 		base = flashbase ? flashbase : (0xffffffff - size + 1);
 		fill_flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size);
Index: flashrom-register_all_programmers_register_generic/programmer.h
===================================================================
--- flashrom-register_all_programmers_register_generic/programmer.h	(Revision 1463)
+++ flashrom-register_all_programmers_register_generic/programmer.h	(Arbeitskopie)
@@ -93,8 +93,8 @@
 
 	int (*init) (void);
 
-	void * (*map_flash_region) (const char *descr, unsigned long phys_addr,
-				    size_t len);
+	void *(*map_flash_region) (const char *descr, unsigned long phys_addr,
+				   size_t len);
 	void (*unmap_flash_region) (void *virt_addr, size_t len);
 
 	void (*delay) (int usecs);
@@ -341,31 +341,6 @@
 void rmmio_valw(void *addr);
 void rmmio_vall(void *addr);
 
-/* programmer.c */
-int noop_shutdown(void);
-void *fallback_map(const char *descr, unsigned long phys_addr, size_t len);
-void fallback_unmap(void *virt_addr, size_t len);
-uint8_t noop_chip_readb(const chipaddr addr);
-void noop_chip_writeb(uint8_t val, chipaddr addr);
-void fallback_chip_writew(uint16_t val, chipaddr addr);
-void fallback_chip_writel(uint32_t val, chipaddr addr);
-void fallback_chip_writen(uint8_t *buf, chipaddr addr, size_t len);
-uint16_t fallback_chip_readw(const chipaddr addr);
-uint32_t fallback_chip_readl(const chipaddr addr);
-void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
-struct par_programmer {
-	void (*chip_writeb) (uint8_t val, chipaddr addr);
-	void (*chip_writew) (uint16_t val, chipaddr addr);
-	void (*chip_writel) (uint32_t val, chipaddr addr);
-	void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len);
-	uint8_t (*chip_readb) (const chipaddr addr);
-	uint16_t (*chip_readw) (const chipaddr addr);
-	uint32_t (*chip_readl) (const chipaddr addr);
-	void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len);
-};
-extern const struct par_programmer *par_programmer;
-void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses);
-
 /* dummyflasher.c */
 #if CONFIG_DUMMY == 1
 int dummy_init(void);
@@ -632,6 +607,42 @@
 extern const struct opaque_programmer *opaque_programmer;
 void register_opaque_programmer(const struct opaque_programmer *pgm);
 
+/* programmer.c */
+int noop_shutdown(void);
+void *fallback_map(const char *descr, unsigned long phys_addr, size_t len);
+void fallback_unmap(void *virt_addr, size_t len);
+uint8_t noop_chip_readb(const chipaddr addr);
+void noop_chip_writeb(uint8_t val, chipaddr addr);
+void fallback_chip_writew(uint16_t val, chipaddr addr);
+void fallback_chip_writel(uint32_t val, chipaddr addr);
+void fallback_chip_writen(uint8_t *buf, chipaddr addr, size_t len);
+uint16_t fallback_chip_readw(const chipaddr addr);
+uint32_t fallback_chip_readl(const chipaddr addr);
+void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
+struct par_programmer {
+	void (*chip_writeb) (uint8_t val, chipaddr addr);
+	void (*chip_writew) (uint16_t val, chipaddr addr);
+	void (*chip_writel) (uint32_t val, chipaddr addr);
+	void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len);
+	uint8_t (*chip_readb) (const chipaddr addr);
+	uint16_t (*chip_readw) (const chipaddr addr);
+	uint32_t (*chip_readl) (const chipaddr addr);
+	void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len);
+};
+extern const struct par_programmer *par_programmer;
+void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses);
+struct registered_programmer {
+	enum chipbustype buses_supported;
+	union {
+		struct par_programmer par;
+		struct spi_programmer spi;
+		struct opaque_programmer opaque;
+	};
+};
+extern struct registered_programmer registered_programmers[];
+extern int registered_programmer_count;
+int register_programmer(struct registered_programmer *pgm);
+
 /* serprog.c */
 #if CONFIG_SERPROG == 1
 int serprog_init(void);


-- 
http://www.hailfinger.org/





More information about the flashrom mailing list