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 <[email protected]>
---
 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


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to