[flashrom] [PATCH] Add support for generic SPI RES matching
Carl-Daniel Hailfinger
c-d.hailfinger.devel.2006 at gmx.net
Sat Aug 25 17:43:02 CEST 2012
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 at gmx.net>
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:
--
http://www.hailfinger.org/
More information about the flashrom
mailing list