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
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:
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(-)