Patchwork Add support for generic SPI RES matching

login
register
about
Submitter Carl-Daniel Hailfinger
Date 2012-08-25 15:43:02
Message ID <5038F286.70107@gmx.net>
Download mbox | patch
Permalink /patch/3722/
State Superseded
Headers show

Comments

Carl-Daniel Hailfinger - 2012-08-25 15:43:02
Support generic 1-byte SPI RES matching (low match quality).
Support generic 2-byte SPI RES matching (high match quality).
Add RES/REMS support to all dummyflasher emulated chips as a test case.
Fix a few odd corner cases in RES/REMS support in dummyflasher emulation.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Stefan Tauner - 2012-08-25 20:35:28
The first on is not for merge... if we want it like this, ill add it to
my tested_stuff branch. but i wonder if those 3 functions should be
inside spi.c instead of spi25.c at all. There is probably a thread from
the time when the files were split... but i am lazy :)

the second patch is just an extract from carl-daniel's first version
of the patch.

and the last one is a refined version that is not complete yet.

Stefan Tauner (3):
  Resort SPI function in chipdrivers.h.
  Add RES/REMS support to all dummyflasher emulated chips.
  Add support for generic SPI RES matching.

 chipdrivers.h  |   11 ++++--
 dummyflasher.c |   57 ++++++++++++++++++++++-----
 flashchips.c   |   31 +++++++++++++++
 flashrom.c     |    4 +-
 sfdp.c         |   48 +----------------------
 spi25.c        |  117 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 6 files changed, 195 insertions(+), 73 deletions(-)

Patch

Index: flashrom-spi_res_generic_chips/dummyflasher.c
===================================================================
--- flashrom-spi_res_generic_chips/dummyflasher.c	(Revision 1579)
+++ flashrom-spi_res_generic_chips/dummyflasher.c	(Arbeitskopie)
@@ -493,6 +493,9 @@ 
 {
 	unsigned int offs, i, toread;
 	static int unsigned aai_offs;
+	const unsigned char sst25vf040_rems_response[2] = {0xbf, 0x44};
+	const unsigned char sst25vf032b_rems_response[2] = {0xbf, 0x4a};
+	const unsigned char mx25l6436_rems_response[2] = {0xc2, 0x16};
 
 	if (writecnt == 0) {
 		msg_perr("No command sent to the chip!\n");
@@ -529,20 +532,54 @@ 
 
 	switch (writearr[0]) {
 	case JEDEC_RES:
-		if (emu_chip != EMULATE_ST_M25P10_RES)
+		if (writecnt < JEDEC_RES_OUTSIZE)
 			break;
-		/* Respond with ST_M25P10_RES. */
-		if (readcnt > 0)
-			readarr[0] = 0x10;
+		/* offs calculation is only needed for SST chips which treat RES like REMS. */
+		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
+		offs += writecnt - JEDEC_REMS_OUTSIZE;
+		switch (emu_chip) {
+		case EMULATE_ST_M25P10_RES:
+			if (readcnt > 0)
+				memset(readarr, 0x10, readcnt);
+			break;
+		case EMULATE_SST_SST25VF040_REMS:
+			for (i = 0; i < readcnt; i++)
+				readarr[i] = sst25vf040_rems_response[(offs + i) % 2];
+			break;
+		case EMULATE_SST_SST25VF032B:
+			for (i = 0; i < readcnt; i++)
+				readarr[i] = sst25vf032b_rems_response[(offs + i) % 2];
+			break;
+		case EMULATE_MACRONIX_MX25L6436:
+			if (readcnt > 0)
+				memset(readarr, 0x16, readcnt);
+			break;
+		default: /* ignore */
+			break;
+		}
 		break;
 	case JEDEC_REMS:
-		if (emu_chip != EMULATE_SST_SST25VF040_REMS)
+		/* REMS response has wraparound and uses an address parameter. */
+		if (writecnt < JEDEC_REMS_OUTSIZE)
 			break;
-		/* Respond with SST_SST25VF040_REMS. */
-		if (readcnt > 0)
-			readarr[0] = 0xbf;
-		if (readcnt > 1)
-			readarr[1] = 0x44;
+		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
+		offs += writecnt - JEDEC_REMS_OUTSIZE;
+		switch (emu_chip) {
+		case EMULATE_SST_SST25VF040_REMS:
+			for (i = 0; i < readcnt; i++)
+				readarr[i] = sst25vf040_rems_response[(offs + i) % 2];
+			break;
+		case EMULATE_SST_SST25VF032B:
+			for (i = 0; i < readcnt; i++)
+				readarr[i] = sst25vf032b_rems_response[(offs + i) % 2];
+			break;
+		case EMULATE_MACRONIX_MX25L6436:
+			for (i = 0; i < readcnt; i++)
+				readarr[i] = mx25l6436_rems_response[(offs + i) % 2];
+			break;
+		default: /* ignore */
+			break;
+		}
 		break;
 	case JEDEC_RDID:
 		switch (emu_chip) {
Index: flashrom-spi_res_generic_chips/spi25.c
===================================================================
--- flashrom-spi_res_generic_chips/spi25.c	(Revision 1579)
+++ flashrom-spi_res_generic_chips/spi25.c	(Arbeitskopie)
@@ -232,6 +232,7 @@ 
 
 int probe_spi_res1(struct flashctx *flash)
 {
+	const struct flashchip *chip = flash->chip;
 	static const unsigned char allff[] = {0xff, 0xff, 0xff};
 	static const unsigned char all00[] = {0x00, 0x00, 0x00};
 	unsigned char readarr[3];
@@ -265,18 +266,23 @@ 
 
 	msg_cdbg("%s: id 0x%x\n", __func__, id2);
 
-	if (id2 != flash->chip->model_id)
-		return 0;
+	if (id2 == flash->chip->model_id) {
+		/* Print the status register to tell the user about possible write protection. */
+		spi_prettyprint_status_register(flash);
 
-	/* Print the status register to tell the
-	 * user about possible write protection.
-	 */
-	spi_prettyprint_status_register(flash);
-	return 1;
+		return 1;
+	}
+
+	/* Test if there is any device ID. */
+	if (GENERIC_MANUF_ID == chip->manufacture_id && id2 != 0xff)
+		return 1;
+
+	return 0;
 }
 
 int probe_spi_res2(struct flashctx *flash)
 {
+	const struct flashchip *chip = flash->chip;
 	unsigned char readarr[2];
 	uint32_t id1, id2;
 
@@ -289,14 +295,24 @@ 
 
 	msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
 
-	if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
-		return 0;
+	if (id1 == chip->manufacture_id && id2 == chip->model_id) {
+		/* Print the status register to tell the
+		 * user about possible write protection.
+		 */
+		spi_prettyprint_status_register(flash);
 
-	/* Print the status register to tell the
-	 * user about possible write protection.
-	 */
-	spi_prettyprint_status_register(flash);
-	return 1;
+		return 1;
+	}
+
+	/* Test if this is a pure vendor match. */
+	if (id1 == chip->manufacture_id && GENERIC_DEVICE_ID == chip->model_id)
+		return 1;
+
+	/* Test if there is any vendor ID and if this is indeed a two-byte RES. */
+	if (GENERIC_MANUF_ID == chip->manufacture_id && id1 != 0xff && id1 != id2)
+		return 1;
+
+	return 0;
 }
 
 uint8_t spi_read_status_register(struct flashctx *flash)
Index: flashrom-spi_res_generic_chips/flashchips.c
===================================================================
--- flashrom-spi_res_generic_chips/flashchips.c	(Revision 1579)
+++ flashrom-spi_res_generic_chips/flashchips.c	(Arbeitskopie)
@@ -9673,5 +9673,162 @@ 
 		.write		= NULL,
 	},
 
+	{
+		.vendor		= "Generic",
+		.name		= "unknown SPI chip (RES2)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_DEVICE_ID,
+		.total_size	= 0,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res2,
+		.write		= NULL,
+	},
+
+	{
+		.vendor		= "Generic",
+		.name		= "unknown 128 kB SPI chip (RES)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_SPI_RES_128K,
+		.total_size	= 128,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res1,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	= {},
+		.unlock		= NULL,
+		.write		= NULL,
+		.read		= NULL,
+		.voltage	= {},
+	},
+
+	{
+		.vendor		= "Generic",
+		.name		= "unknown 256 kB SPI chip (RES)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_SPI_RES_256K,
+		.total_size	= 256,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res1,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	= {},
+		.unlock		= NULL,
+		.write		= NULL,
+		.read		= NULL,
+		.voltage	= {},
+	},
+
+	{
+		.vendor		= "Generic",
+		.name		= "unknown 512 kB SPI chip (RES)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_SPI_RES_512K,
+		.total_size	= 512,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res1,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	= {},
+		.unlock		= NULL,
+		.write		= NULL,
+		.read		= NULL,
+		.voltage	= {},
+	},
+
+	{
+		.vendor		= "Generic",
+		.name		= "unknown 1024 kB SPI chip (RES)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_SPI_RES_1024K,
+		.total_size	= 1024,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res1,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	= {},
+		.unlock		= NULL,
+		.write		= NULL,
+		.read		= NULL,
+		.voltage	= {},
+	},
+
+	{
+		.vendor		= "Generic",
+		.name		= "unknown 2048 kB SPI chip (RES)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_SPI_RES_2048K,
+		.total_size	= 2048,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res1,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	= {},
+		.unlock		= NULL,
+		.write		= NULL,
+		.read		= NULL,
+		.voltage	= {},
+	},
+
+	{
+		.vendor		= "Generic",
+		.name		= "unknown 4096 kB SPI chip (RES)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_SPI_RES_4096K,
+		.total_size	= 4096,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res1,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	= {},
+		.unlock		= NULL,
+		.write		= NULL,
+		.read		= NULL,
+		.voltage	= {},
+	},
+
+	{
+		.vendor		= "Generic",
+		.name		= "unknown 8192 kB SPI chip (RES)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_SPI_RES_8192K,
+		.total_size	= 8192,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res1,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	= {},
+		.unlock		= NULL,
+		.write		= NULL,
+		.read		= NULL,
+		.voltage	= {},
+	},
+
+	{
+		.vendor		= "Generic",
+		.name		= "unknown 16384 kB SPI chip (RES)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= GENERIC_MANUF_ID,
+		.model_id	= GENERIC_SPI_RES_16384K,
+		.total_size	= 16384,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_res1,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	= {},
+		.unlock		= NULL,
+		.write		= NULL,
+		.read		= NULL,
+		.voltage	= {},
+	},
+
 	{ NULL 	}
 };
Index: flashrom-spi_res_generic_chips/flashchips.h
===================================================================
--- flashrom-spi_res_generic_chips/flashchips.h	(Revision 1579)
+++ flashrom-spi_res_generic_chips/flashchips.h	(Arbeitskopie)
@@ -39,6 +39,14 @@ 
 #define SFDP_DEVICE_ID		0xFFFE
 #define PROGMANUF_ID		0xFFFE	/* dummy ID for opaque chips behind a programmer */
 #define PROGDEV_ID		0x01	/* dummy ID for opaque chips behind a programmer */
+#define GENERIC_SPI_RES_128K	0x10	/* SPI RES response for 128 kByte chip */
+#define GENERIC_SPI_RES_256K	0x11
+#define GENERIC_SPI_RES_512K	0x12
+#define GENERIC_SPI_RES_1024K	0x13
+#define GENERIC_SPI_RES_2048K	0x14
+#define GENERIC_SPI_RES_4096K	0x15
+#define GENERIC_SPI_RES_8192K	0x16
+#define GENERIC_SPI_RES_16384K	0x17
 
 #define ALLIANCE_ID		0x52	/* Alliance Semiconductor */
 #define ALLIANCE_AS29F002B	0x34
Index: flashrom-spi_res_generic_chips/flashrom.c
===================================================================
--- flashrom-spi_res_generic_chips/flashrom.c	(Revision 1579)
+++ flashrom-spi_res_generic_chips/flashrom.c	(Arbeitskopie)
@@ -1029,7 +1029,8 @@ 
 		if (startchip == 0)
 			break;
 		/* Not the first flash chip detected on this bus, but not a generic match either. */
-		if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
+		if ((flash->chip->manufacture_id != GENERIC_MANUF_ID) &&
+		    (flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
 			break;
 		/* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
 notfound: