They use a new 3-Byte device ID probing function (although the first one
seems to always be a continuation indicator) at addresses 0x01, 0x0E, 0x0F.

Supported families include...
 - EON EN29GL
 - Gigadevice GD29GL (if they really exist)
 - Macronix MX29GL (+MX68GL1G0F)
 - Spansion 29GL (+S70GL02G)
 - Winbond W29GL

Signed-off-by: Stefan Tauner <[email protected]>
---
Hello Gilbert,

I've tried to come up with a probing function that works on all 29GL chips.
Please apply the patch to r1796, recompile and post a verbose log,
e.g. by running './flashrom -p internal -o 29gl_probe.log and attaching
29gl_probe.log to the mail. Thanks!

I have very little experience with parallel flash chips so it might not
work at all. If it does detect the chip correctly, it will probably read
it correctly too, and maybe even erase it. I am not so sure about writing
though, so I would rather noth attempt writes or erases yet.

 chipdrivers.h |  1 +
 flashchips.c  | 27 ++++++++++++++++
 flashchips.h  | 66 ++++++++++++++++++++++++++++++++++++---
 jedec.c       | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 188 insertions(+), 5 deletions(-)

diff --git a/chipdrivers.h b/chipdrivers.h
index f270b55..1f6d57a 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -140,6 +140,7 @@ void data_polling_jedec(struct flashctx *flash, chipaddr 
dst, uint8_t data);
 int write_byte_program_jedec(struct flashctx *flash, chipaddr bios, uint8_t 
*src,
                             chipaddr dst);
 int probe_jedec(struct flashctx *flash);
+int probe_jedec_29gl(struct flashctx *flash);
 int write_jedec(struct flashctx *flash, const uint8_t *buf, unsigned int 
start, unsigned int len);
 int write_jedec_1(struct flashctx *flash, const uint8_t *buf, unsigned int 
start, unsigned int len);
 int erase_sector_jedec(struct flashctx *flash, unsigned int page, unsigned int 
pagesize);
diff --git a/flashchips.c b/flashchips.c
index dee7d9e..40f79b3 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -6910,6 +6910,33 @@ const struct flashchip flashchips[] = {
 
        {
                .vendor         = "Macronix",
+               .name           = "MX29GL128F",
+               .bustype        = BUS_PARALLEL,
+               .manufacture_id = MACRONIX_ID,
+               .model_id       = MACRONIX_MX29GL128F,
+               .total_size     = 16384,
+               .page_size      = 128 * 1024,
+               .feature_bits   = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+               .tested         = TEST_UNTESTED,
+               .probe          = probe_jedec_29gl,
+               .probe_timing   = TIMING_ZERO,
+               .block_erasers  =
+               {
+                       {
+                               .eraseblocks = { {128 * 1024, 128}, },
+                               .block_erase = erase_sector_jedec,
+                       }, {
+                               .eraseblocks = { {16 * 1024 * 1024, 1} },
+                               .block_erase = erase_chip_block_jedec,
+                       },
+               },
+               .write          = write_jedec_1,
+               .read           = read_memmapped,
+               .voltage        = {2700, 3600},
+       },
+
+       {
+               .vendor         = "Macronix",
                .name           = "MX29LV040",
                .bustype        = BUS_PARALLEL,
                .manufacture_id = MACRONIX_ID,
diff --git a/flashchips.h b/flashchips.h
index 234e58c..7eea262 100644
--- a/flashchips.h
+++ b/flashchips.h
@@ -287,6 +287,11 @@
 #define EON_EN29LV640B         0xCB
 #define EON_EN29F002T          0x7F92  /* Same as EN29F002A */
 #define EON_EN29F002B          0x7F97  /* Same as EN29F002AN */
+#define EON_EN29GL064HL                0x7F0C01
+#define EON_EN29GL064T         0x7F1001        /* Same ID as EN29GL064AT */
+#define EON_EN29GL064B         0x7F1001        /* Same ID as EN29GL064AB */
+#define EON_EN29GL128HL                0x7F2101        /* Uniform Sectors, WP 
protects Top OR Bottom sector */
+#define EON_EN29GL256HL                0x7F2201        /* Uniform Sectors, WP 
protects Top OR Bottom sector */
 
 #define EXCEL_ID               0x7F7F7F7F4A    /* Excel Semiconductor Inc. 
(ESI) resides in bank 5 */
 #define EXCEL_ID_NOPREFIX      0x4A    /* ESI, missing 0x7F prefix */
@@ -353,6 +358,7 @@
 #define GIGADEVICE_GD25LQ32    0x6016
 #define GIGADEVICE_GD25LQ64    0x6017  /* Same as GD25LQ64B (which is faster) 
*/
 #define GIGADEVICE_GD25LQ128   0x6018
+#define GIGADEVICE_GD29GL064CAB        0x7E0601
 
 #define HYUNDAI_ID             0xAD    /* Hyundai */
 #define HYUNDAI_HY29F400T      0x23    /* Same as HY29F400AT */
@@ -464,6 +470,16 @@
 #define MACRONIX_MX29F400T     0x23    /* Same as MX29F400CT */
 #define MACRONIX_MX29F800B     0x58
 #define MACRONIX_MX29F800T     0xD6
+#define MACRONIX_MX29GL320EB   0x7E1A00
+#define MACRONIX_MX29GL320ET   0x7E1A01
+#define MACRONIX_MX29GL320EHL  0x7E1D00
+#define MACRONIX_MX29GL640EB   0x7E1000
+#define MACRONIX_MX29GL640ET   0x7E1001
+#define MACRONIX_MX29GL640EHL  0x7E0C01
+#define MACRONIX_MX29GL128F    0x7E2101
+#define MACRONIX_MX29GL256F    0x7E2201
+#define MACRONIX_MX29GL512F    0x7E2301
+#define MACRONIX_MX68GL1G0F    0x7E2801
 #define MACRONIX_MX29LV002CB   0x5A
 #define MACRONIX_MX29LV002CT   0x59
 #define MACRONIX_MX29LV004B    0xB6    /* Same as MX29LV004CB */
@@ -551,12 +567,10 @@
 #define SHARP_LHF00L02         0xC9    /* Same as LHF00L06/LHF00L07 */
 #define SHARP_LHF00L04         0xCF    /* Same as LHF00L03/LHF00L05 */
 
-/*
- * Spansion was previously a joint venture of AMD and Fujitsu.
- * S25 chips are SPI. The first device ID byte is memory type and
- * the second device ID byte is memory capacity.
- */
+/* Spansion was previously a joint venture of AMD and Fujitsu. */
 #define SPANSION_ID            0x01    /* Spansion, same ID as AMD */
+/* S25 chips are SPI. The first device ID byte is memory type and
+ * the second device ID byte is memory capacity. */
 #define SPANSION_S25FL004A     0x0212
 #define SPANSION_S25FL008A     0x0213
 #define SPANSION_S25FL016A     0x0214
@@ -571,6 +585,40 @@
 #define SPANSION_S25FL132K     0x4016
 #define SPANSION_S25FL164K     0x4017
 
+/* Spansion 29GL families got a suffix indicating the process technology but 
share the same 3-Byte IDs. They can
+ * however be differentiated by CFI byte 45h. Some versions exist which have 
special top or bottom boot sectors
+ * and various WP configurations (not heeded in the table below).
+ *
+ * Suf.  Process Sector Sz  Rd Page  Wr Page  Data Width  OTP Sz   Min Size    
 Max Size
+ *  A     200 nm    64 kB      8 B     32 B     x8/x16     256 B   16Mb/ 2MB   
64Mb/  8MB
+ *  M     230 nm    64 kB      8 B     32 B     x8/x16     256 B   32Mb/ 4MB  
256Mb/ 32MB
+ *  N*    110 nm    64 kB     16 B     32 B     x8/x16     256 B   32Mb/ 4MB   
64Mb/  8MB
+ *  N*    110 nm   128 kB     16 B     32 B     x8/x16     256 B  128Mb/16MB  
256Mb/ 64MB
+ *  P      90 nm   128 kB     16 B     64 B     x8/x16     256 B  128Mb/16MB   
 2Gb/256MB
+ *  S      65 nm   128 kB     32 B    512 B     x8 only    512 B  128Mb/16MB   
 2Gb/256MB
+ *
+ * For the N series there are two subgroups: the 4 and 8MB devices (S29GL032N, 
S29GL064N) have 64 kB erase
+ * sectors while the bigger chips got 128 kB sectors.
+ * Each series includes multiple models varying in speedgrade, boot block 
configurations etc.
+ */
+#define SPANSION_S29GL016_1    0xC4    /* Top Boot Sector, WP protects Top 2 
sectors */
+#define SPANSION_S29GL016_2    0x49    /* Bottom Boot Sector, WP protects 
Bottom 2 sectors */
+/* Same IDs for S29GL032A, S29GL032M, S29GL032N (variations) */
+#define SPANSION_S29GL032_1289 0x7E1D00        /* Uniform Sectors, WP protects 
Top OR Bottom sector */
+#define SPANSION_S29GL032_3    0x7E1A01        /* Top Boot Sector, WP protects 
Top 2 sectors */
+#define SPANSION_S29GL032_4    0x7E1A00        /* Bottom Boot Sector, WP 
protects Bottom 2 sectors */
+/* Same IDs for S29GL064A, S29GL064M, S29GL064N, S29GL064S (variations) */
+#define SPANSION_S29GL064_1289 0x7E0C01        /* Uniform Sectors, WP protects 
Top OR Bottom sector */
+#define SPANSION_S29GL064_3    0x7E1001        /* Top Boot Sector, WP protects 
Top 2 sectors */
+#define SPANSION_S29GL064_4    0x7E1000        /* Bottom Boot Sector, WP 
protects Bottom 2 sectors */
+#define SPANSION_S29GL064_567  0x7E1301        /* x16 only, Uniform Sectors */
+
+#define SPANSION_S29GL128      0x7E2101        /* Same ID for S29GL128M, 
S29GL128N, S29GL128P, S29GL128S */
+#define SPANSION_S29GL256      0x7E2201        /* Same ID for S29GL256M, 
S29GL256N, S29GL256P, S29GL256S */
+#define SPANSION_S29GL512      0x7E2301        /* Same ID for S29GL512P, 
S29GL512S */
+#define SPANSION_S29GL01G      0x7E2801        /* Same ID for S29GL01GP, 
S29GL01GS */
+#define SPANSION_S70GL02G      0x7E4801        /* Same ID for S70GL02GP, 
S70GL02GS; based on two S29GL01G dies respectively */
+
 /*
  * SST25 chips are SPI, first byte of device ID is memory type, second
  * byte of device ID is related to log(bitsize) at least for some chips.
@@ -770,6 +818,14 @@
 #define WINBOND_W29C020                0x45    /* Same as W29C020C, W29C022 
and ASD AE29F2008 */
 #define WINBOND_W29C040                0x46    /* Same as W29C040P */
 #define WINBOND_W29C512A       0xC8    /* Same as W29EE512 */
+#define WINBOND_W29GL032CHL    0x7E1D01        /* Uniform Sectors, WP protects 
Top OR Bottom sector */
+#define WINBOND_W29GL032CB     0x7E1A00        /* Top Boot Sector, WP protects 
Top 2 sectors */
+#define WINBOND_W29GL032CT     0x7E1A01        /* Bottom Boot Sector, WP 
protects Bottom 2 sectors */
+#define WINBOND_W29GL064CHL    0x7E0C01        /* Uniform Sectors, WP protects 
Top OR Bottom sector */
+#define WINBOND_W29GL064CB     0x7E1000        /* Top Boot Sector, WP protects 
Top 2 sectors */
+#define WINBOND_W29GL064CT     0x7E1001        /* Bottom Boot Sector, WP 
protects Bottom 2 sectors */
+#define WINBOND_W29GL0128CHL   0x7E2101        /* Uniform Sectors, WP protects 
Top OR Bottom sector */
+#define WINBOND_W29GL0256HL    0x7E2201        /* Same ID for W29GL0256P and 
W29GL0256S; uniform Sectors, WP protects Top OR Bottom sector */
 #define WINBOND_W39F010                0xA1
 #define WINBOND_W39L010                0x31
 #define WINBOND_W39L020                0xB5
diff --git a/jedec.c b/jedec.c
index be4782a..2569729 100644
--- a/jedec.c
+++ b/jedec.c
@@ -120,6 +120,105 @@ static void start_program_jedec_common(struct flashctx 
*flash,
        chip_writeb(flash, 0xA0, bios + (0x5555 & mask));
 }
 
+int probe_jedec_29gl(struct flashctx *flash)
+{
+       unsigned int mask = getaddrmask(flash->chip);
+       chipaddr bios = flash->virtual_memory;
+       const struct flashchip *chip = flash->chip;
+
+       //unsigned int probe_timing_enter, probe_timing_exit;
+       //if (chip->probe_timing > 0)
+               //probe_timing_enter = probe_timing_exit = chip->probe_timing;
+       //else if (chip->probe_timing == TIMING_ZERO) { /* No delay. */
+               //probe_timing_enter = probe_timing_exit = 0;
+       //} else if (chip->probe_timing == TIMING_FIXME) { /* == _IGNORED */
+               //msg_cdbg("Chip lacks correct probe timing information, "
+                            //"using default 10mS/40uS. ");
+               //probe_timing_enter = 10000;
+               //probe_timing_exit = 40;
+       //} else {
+               //msg_cerr("Chip has negative value in probe_timing, failing "
+                      //"without chip access\n");
+               //return 0;
+       //}
+
+       /* Earlier probes might have been too fast for the chip to enter ID
+        * mode completely. Allow the chip to finish this before seeing a
+        * reset command.
+        */
+       //if (probe_timing_enter)
+               //programmer_delay(probe_timing_enter);
+
+       /* Reset chip to a clean slate */
+       if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
+       {
+               chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
+               //if (probe_timing_exit)
+                       //programmer_delay(10);
+               chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
+               //if (probe_timing_exit)
+                       //programmer_delay(10);
+       }
+       chip_writeb(flash, 0xF0, bios + (0x5555 & mask));
+       //if (probe_timing_exit)
+               //programmer_delay(probe_timing_exit);
+
+       /* Issue JEDEC Product ID Entry command */
+       chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
+       //if (probe_timing_enter)
+               //programmer_delay(10);
+       chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
+       //if (probe_timing_enter)
+               //programmer_delay(10);
+       chip_writeb(flash, 0x90, bios + (0x5555 & mask));
+       //if (probe_timing_enter)
+               //programmer_delay(probe_timing_enter);
+
+       /* Read product ID */
+       uint32_t man_id = chip_readb(flash, bios + 0x00); // FIXME: 
Continuation loop
+       uint32_t dev_id = (chip_readb(flash, bios + 0x01) << 16) |
+                         (chip_readb(flash, bios + 0x0E) <<  8) |
+                         (chip_readb(flash, bios + 0x0F) <<  0);
+
+       /* Issue JEDEC Product ID Exit command */
+       if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
+       {
+               chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
+               //if (probe_timing_exit)
+                       //programmer_delay(10);
+               chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
+               //if (probe_timing_exit)
+                       //programmer_delay(10);
+       }
+       chip_writeb(flash, 0xF0, bios + (0x5555 & mask));
+       //if (probe_timing_exit)
+               //programmer_delay(probe_timing_exit);
+
+       msg_cdbg("%s: man_id 0x%02x, dev_id 0x%06x", __func__, man_id, dev_id);
+       if (!oddparity(man_id))
+               msg_cdbg(", man_id parity violation");
+
+       /* Read the product ID location again. We should now see normal flash 
contents. */
+       uint32_t flashcontent1 = chip_readb(flash, bios + 0x00); // FIXME: 
Continuation loop
+       uint32_t flashcontent2 = (chip_readb(flash, bios + 0x01) << 16) |
+                                (chip_readb(flash, bios + 0x0E) <<  8) |
+                                (chip_readb(flash, bios + 0x0F) <<  0);
+
+       if (man_id == flashcontent1)
+               msg_cdbg(", man_id seems to be normal flash content");
+       if (dev_id == flashcontent2)
+               msg_cdbg(", dev_id seems to be normal flash content");
+
+       msg_cdbg("\n");
+       if (man_id != chip->manufacture_id || dev_id != chip->model_id)
+               return 0;
+
+       if (chip->feature_bits & FEATURE_REGISTERMAP)
+               map_flash_registers(flash);
+
+       return 1;
+}
+
 static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
 {
        chipaddr bios = flash->virtual_memory;
-- 
Kind regards, Stefan Tauner


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

Reply via email to