[flashrom] [PATCH] dummyflasher.c: add support for SFDP by adding a new emulator chip: W25Q64CV

Stefan Tauner stefan.tauner at student.tuwien.ac.at
Mon Feb 20 17:07:45 CET 2012


TODO:
 - how should the SFDP data be supplied/selected by the user?
   - option A (suggested one): add a default table with a legit complete table and
     a programmer option to use a binary file instead.
   - option B: add multiple legit and invalid tables to cover most useful test cases
     and add a programmer option to select which table should be used.
   - option C: some combination of A and B
 - Manpage

Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
---
 dummyflasher.c |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/dummyflasher.c b/dummyflasher.c
index afe0518..6d8b9a2 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -45,6 +45,7 @@ enum emu_chip {
 	EMULATE_ST_M25P10_RES,
 	EMULATE_SST_SST25VF040_REMS,
 	EMULATE_SST_SST25VF032B,
+	EMULATE_WINBOND_W25Q64CV,
 };
 static enum emu_chip emu_chip = EMULATE_NONE;
 static char *emu_persistent_image = NULL;
@@ -61,6 +62,40 @@ unsigned char spi_blacklist[256];
 unsigned char spi_ignorelist[256];
 int spi_blacklist_size = 0;
 int spi_ignorelist_size = 0;
+
+/* legit intel version */
+/*
+static const uint8_t const sfdp_table[256] = {
+	0x53, 0x46, 0x44, 0x50, // @0x00
+	0x00, 0x01, 0x00, 0xFF, // @0x04
+	0x00, 0x00, 0x01, 0x04, // @0x08: len = 4 instead of 9
+	0x14, 0x00, 0x00, 0xFF, // @0x0C: PTP0 = 0x14 instead of 0x80
+	0xFF, 0xFF, 0xFF, 0xFF, // @0x10
+	0xE5, 0x20, 0xF1, 0xFF, // @0x14
+	0xFF, 0xFF, 0xFF, 0x03, // @0x18
+	0x44, 0xEB, 0x08, 0x6B, // @0x1C
+	0x08, 0x3B, 0x80, 0xBB, // @0x20
+	
+};
+*/
+/* legit complete table */
+static const uint8_t const sfdp_table[256] = {
+	0x53, 0x46, 0x44, 0x50, // @0x00
+	0x00, 0x01, 0x00, 0xFF, // @0x04
+	0x00, 0x00, 0x01, 0x09, // @0x08
+	0x14, 0x00, 0x00, 0xFF, // @0x0C: PTP0 = 0x14 instead of 0x80
+	0xFF, 0xFF, 0xFF, 0xFF, // @0x10
+	0xE5, 0x20, 0xF1, 0xFF, // @0x14
+	0xFF, 0xFF, 0xFF, 0x03, // @0x18
+	0x44, 0xEB, 0x08, 0x6B, // @0x1C
+	0x08, 0x3B, 0x80, 0xBB, // @0x20
+	0xEE, 0xFF, 0xFF, 0xFF, // @0x24
+	0xFF, 0xFF, 0x00, 0x00, // @0x28
+	0xFF, 0xFF, 0x00, 0x00, // @0x2C
+	0x0C, 0x20, 0x0F, 0x52, // @0x30
+	0x10, 0xD8, 0x00, 0x00, // @0x34
+};
+
 #endif
 #endif
 
@@ -296,6 +331,19 @@ int dummy_init(void)
 		msg_pdbg("Emulating SST SST25VF032B SPI flash chip (RDID, AAI "
 			 "write)\n");
 	}
+	if (!strcmp(tmp, "W25Q64CV")) {
+		emu_chip = EMULATE_WINBOND_W25Q64CV;
+		emu_chip_size = 8 * 1024 * 1024;
+		emu_max_byteprogram_size = 256;
+		emu_max_aai_size = 0;
+		emu_jedec_se_size = 4 * 1024;
+		emu_jedec_be_52_size = 32 * 1024;
+		emu_jedec_be_d8_size = 64 * 1024;
+		emu_jedec_ce_60_size = emu_chip_size;
+		emu_jedec_ce_c7_size = emu_chip_size;
+		msg_pdbg("Emulating Winbond W25Q64CV SPI flash chip (RDID, "
+			 "SFDP)\n");
+	}
 #endif
 	if (emu_chip == EMULATE_NONE) {
 		msg_perr("Invalid chip specified for emulation: %s\n", tmp);
@@ -471,15 +519,26 @@ static int emulate_spi_chip_response(unsigned int writecnt,
 			readarr[1] = 0x44;
 		break;
 	case JEDEC_RDID:
-		if (emu_chip != EMULATE_SST_SST25VF032B)
+		switch (emu_chip) {
+		case EMULATE_SST_SST25VF032B:
+			if (readcnt > 0)
+				readarr[0] = 0xbf;
+			if (readcnt > 1)
+				readarr[1] = 0x25;
+			if (readcnt > 2)
+				readarr[2] = 0x4a;
 			break;
-		/* Respond with SST_SST25VF032B. */
-		if (readcnt > 0)
-			readarr[0] = 0xbf;
-		if (readcnt > 1)
-			readarr[1] = 0x25;
-		if (readcnt > 2)
-			readarr[2] = 0x4a;
+		case EMULATE_WINBOND_W25Q64CV:
+			if (readcnt > 0)
+				readarr[0] = 0xef;
+			if (readcnt > 1)
+				readarr[1] = 0x40;
+			if (readcnt > 2)
+				readarr[2] = 0x17;
+			break;
+		default: /* ignore */
+			break;
+		}
 		break;
 	case JEDEC_RDSR:
 		memset(readarr, 0, readcnt);
@@ -629,6 +688,20 @@ static int emulate_spi_chip_response(unsigned int writecnt,
 		/* emu_jedec_ce_c7_size is emu_chip_size. */
 		memset(flashchip_contents, 0xff, emu_jedec_ce_c7_size);
 		break;
+	case JEDEC_SFDP:
+		if (emu_chip != EMULATE_WINBOND_W25Q64CV)
+			break;
+		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
+		/*
+		 * FIXME: There is one dummy byte (i.e. 8 clock cycles) to be
+		 * transferred after the address. Since we can not observe the
+		 * clock, we would need to check for appropriate writecnt and/or
+		 * readcnt and recalculate the parameters below.
+		 */
+		/* FIXME: this could be more sophisticated. */
+		memcpy(readarr, sfdp_table + offs,
+		       min(sizeof(sfdp_table) - offs, readcnt));
+		break;
 	default:
 		/* No special response. */
 		break;
@@ -657,6 +730,7 @@ static int dummy_spi_send_command(struct flashctx *flash, unsigned int writecnt,
 	case EMULATE_ST_M25P10_RES:
 	case EMULATE_SST_SST25VF040_REMS:
 	case EMULATE_SST_SST25VF032B:
+	case EMULATE_WINBOND_W25Q64CV:
 		if (emulate_spi_chip_response(writecnt, readcnt, writearr,
 					      readarr)) {
 			msg_pdbg("Invalid command sent to flash chip!\n");
-- 
1.7.1





More information about the flashrom mailing list