Some Parallel bus chips have a 16-bit mode and an 8-bit mode. They use normal JEDEC addresses for 16-bit mode and shifted addresses (by 1 bit) for 8-bit mode. Some programmers can access them in 16-bit mode, but on all flashrom-supported programmers so far, we access them in 8-bit mode. This means we have to shift the addresses.
Untested, should work. This is a patch written shortly after r886 was committed, and it has been forward-ported. Missing from this patch is the deletion of now-unused code.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-jedec_shifted/jedec.c =================================================================== --- flashrom-jedec_shifted/jedec.c (Revision 1818) +++ flashrom-jedec_shifted/jedec.c (Arbeitskopie) @@ -4,7 +4,7 @@ * Copyright (C) 2000 Silicon Integrated System Corporation * Copyright (C) 2006 Giampiero Giancipoli gianci@email.it * Copyright (C) 2006 coresystems GmbH info@coresystems.de - * Copyright (C) 2007 Carl-Daniel Hailfinger + * Copyright (C) 2007-2012 Carl-Daniel Hailfinger * Copyright (C) 2009 Sean Nelson audiohacked@gmail.com * * This program is free software; you can redistribute it and/or modify @@ -115,15 +115,18 @@ static void start_program_jedec_common(const struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); - chip_writeb(flash, 0xA0, bios + (0x5555 & mask)); + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; + + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); + chip_writeb(flash, 0xA0, bios + ((0x5555 << shifted) & mask)); }
static int probe_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; const struct flashchip *chip = flash->chip; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; uint8_t id1, id2; uint32_t largeid1, largeid2; uint32_t flashcontent1, flashcontent2; @@ -153,31 +156,31 @@ /* Reset chip to a clean slate */ if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) { - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); if (probe_timing_exit) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); if (probe_timing_exit) programmer_delay(10); } - chip_writeb(flash, 0xF0, bios + (0x5555 & mask)); + chip_writeb(flash, 0xF0, bios + ((0x5555 << shifted) & mask)); if (probe_timing_exit) programmer_delay(probe_timing_exit);
/* Issue JEDEC Product ID Entry command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); if (probe_timing_enter) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); if (probe_timing_enter) programmer_delay(10); - chip_writeb(flash, 0x90, bios + (0x5555 & mask)); + chip_writeb(flash, 0x90, bios + ((0x5555 << shifted) & mask)); if (probe_timing_enter) programmer_delay(probe_timing_enter);
/* Read product ID */ - id1 = chip_readb(flash, bios); - id2 = chip_readb(flash, bios + 0x01); + id1 = chip_readb(flash, bios + (0x00 << shifted)); + id2 = chip_readb(flash, bios + (0x01 << shifted)); largeid1 = id1; largeid2 = id2;
@@ -196,14 +199,14 @@ /* Issue JEDEC Product ID Exit command */ if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) { - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); if (probe_timing_exit) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); if (probe_timing_exit) programmer_delay(10); } - chip_writeb(flash, 0xF0, bios + (0x5555 & mask)); + chip_writeb(flash, 0xF0, bios + ((0x5555 << shifted) & mask)); if (probe_timing_exit) programmer_delay(probe_timing_exit);
@@ -212,8 +215,8 @@ msg_cdbg(", id1 parity violation");
/* Read the product ID location again. We should now see normal flash contents. */ - flashcontent1 = chip_readb(flash, bios); - flashcontent2 = chip_readb(flash, bios + 0x01); + flashcontent1 = chip_readb(flash, bios + (0x00 << shifted)); + flashcontent2 = chip_readb(flash, bios + (0x01 << shifted));
/* Check if it is a continuation ID, this should be a while loop. */ if (flashcontent1 == 0x7F) { @@ -244,21 +247,23 @@ unsigned int pagesize, unsigned int mask) { chipaddr bios = flash->virtual_memory; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the Sector Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); chip_writeb(flash, 0x30, bios + page); programmer_delay(delay_us); @@ -274,21 +279,23 @@ unsigned int blocksize, unsigned int mask) { chipaddr bios = flash->virtual_memory; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the Sector Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); chip_writeb(flash, 0x50, bios + block); programmer_delay(delay_us); @@ -303,23 +310,25 @@ static int erase_chip_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the JEDEC Chip Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x10, bios + (0x5555 & mask)); + chip_writeb(flash, 0x10, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us);
toggle_ready_jedec_slow(flash, bios); Index: flashrom-jedec_shifted/82802ab.c =================================================================== --- flashrom-jedec_shifted/82802ab.c (Revision 1818) +++ flashrom-jedec_shifted/82802ab.c (Arbeitskopie) @@ -44,7 +44,7 @@ { chipaddr bios = flash->virtual_memory; uint8_t id1, id2, flashcontent1, flashcontent2; - int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) != 0; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0;
/* Reset to get a clean state */ chip_writeb(flash, 0xFF, bios); Index: flashrom-jedec_shifted/flashchips.c =================================================================== --- flashrom-jedec_shifted/flashchips.c (Revision 1818) +++ flashrom-jedec_shifted/flashchips.c (Arbeitskopie) @@ -4892,10 +4892,10 @@ .model_id = FUJITSU_MBM29F400BC, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = TIMING_FIXME, .block_erasers = { { @@ -4905,13 +4905,13 @@ {32 * 1024, 1}, {64 * 1024, 7}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */ }, @@ -4924,10 +4924,10 @@ .model_id = FUJITSU_MBM29F400TC, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = TIMING_FIXME, .block_erasers = { { @@ -4937,13 +4937,13 @@ {8 * 1024, 2}, {16 * 1024, 1}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */ }, @@ -11388,10 +11388,10 @@ .model_id = ST_M29F400BB, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = TIMING_FIXME, .block_erasers = { { @@ -11401,13 +11401,13 @@ {32 * 1024, 1}, {64 * 1024, 7}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, } }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4500, 5500}, }, @@ -11420,10 +11420,10 @@ .model_id = ST_M29F400BT, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = TIMING_FIXME, .block_erasers = { { @@ -11433,13 +11433,13 @@ {8 * 1024, 2}, {16 * 1024, 1}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, } }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4500, 5500}, },
Worst timing ever :( but i'll see how i can incorporate it into my probing patch. Does it change the actual access patterns from a chip's perspective?
Am 11.06.2014 09:11 schrieb Stefan Tauner:
Worst timing ever :(
Sorry!
but i'll see how i can incorporate it into my probing patch.
Great! The alternative would be not to drop those _SHIFTED flags and I can update my patch once your probe rewrite is in. That may be possibly a better way of proceeding.
Does it change the actual access patterns from a chip's perspective?
No.
Regards, Carl-Daniel
Some Parallel bus chips have a 16-bit mode and an 8-bit mode. They use normal JEDEC addresses for 16-bit mode and shifted addresses (by 1 bit) for 8-bit mode. Some programmers can access them in 16-bit mode, but on all flashrom-supported programmers so far, we access them in 8-bit mode. This means we have to shift the addresses but apart from the addresses we can share the code.
This patch makes this possible by checking the chip's FEATURE_ADDR_SHIFTED flag in common JEDEC functions and applying the right addresses respectively.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Signed-off-by: Stefan Tauner stefan.tauner@alumni.tuwien.ac.at ---
I have removed the obsolete code, changed the probe_timing field to 10 plus a comment explaining it where relevant, applied the changes to a few other chips that probably were not there before, and refined the shift handling as discussed on IRC.
82802ab.c | 2 +- Makefile | 2 +- chipdrivers.h | 6 ----- en29lv640b.c | 48 --------------------------------- flashchips.c | 74 +++++++++++++++++++++++++------------------------- flashchips.h | 2 ++ jedec.c | 75 ++++++++++++++++++++++++++++----------------------- m29f400bt.c | 87 ----------------------------------------------------------- 8 files changed, 83 insertions(+), 213 deletions(-) delete mode 100644 m29f400bt.c
diff --git a/82802ab.c b/82802ab.c index e450b5d..70c6af0 100644 --- a/82802ab.c +++ b/82802ab.c @@ -44,7 +44,7 @@ int probe_82802ab(struct flashctx *flash) { chipaddr bios = flash->virtual_memory; uint8_t id1, id2, flashcontent1, flashcontent2; - int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) != 0; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0;
/* Reset to get a clean state */ chip_writeb(flash, 0xFF, bios); diff --git a/Makefile b/Makefile index 8f2d68d..d0d6454 100644 --- a/Makefile +++ b/Makefile @@ -351,7 +351,7 @@ endif # Flash chip drivers and bus support infrastructure.
CHIP_OBJS = jedec.o stm50.o w39.o w29ee011.o \ - sst28sf040.o m29f400bt.o 82802ab.o \ + sst28sf040.o 82802ab.o \ sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o spi25_statusreg.o \ opaque.o sfdp.o en29lv640b.o at45db.o
diff --git a/chipdrivers.h b/chipdrivers.h index dbe45b8..8529c74 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -155,10 +155,6 @@ int printlock_regspace2_uniform_64k(struct flashctx *flash); int printlock_regspace2_block_eraser_0(struct flashctx *flash); int printlock_regspace2_block_eraser_1(struct flashctx *flash);
-/* m29f400bt.c */ -int probe_m29f400bt(struct flashctx *flash); -int write_m29f400bt(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); - /* sst28sf040.c */ int erase_chip_28sf040(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int erase_sector_28sf040(struct flashctx *flash, unsigned int address, unsigned int sector_size); @@ -197,8 +193,6 @@ int erase_sector_stm50(struct flashctx *flash, unsigned int block, unsigned int
/* en29lv640b.c */ int probe_en29lv640b(struct flashctx *flash); -int erase_block_shifted_jedec(struct flashctx *flash, unsigned int start, unsigned int len); -int erase_chip_block_shifted_jedec(struct flashctx *flash, unsigned int start, unsigned int len); int write_en29lv640b(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
#endif /* !__CHIPDRIVERS_H__ */ diff --git a/en29lv640b.c b/en29lv640b.c index a274f62..3a5f611 100644 --- a/en29lv640b.c +++ b/en29lv640b.c @@ -85,51 +85,3 @@ int probe_en29lv640b(struct flashctx *flash)
return 0; } - -static int erase_chip_shifted_jedec(struct flashctx *flash) -{ - chipaddr bios = flash->virtual_memory; - - chip_writeb(flash, 0xAA, bios + 0xAAA); - chip_writeb(flash, 0x55, bios + 0x555); - chip_writeb(flash, 0x80, bios + 0xAAA); - - chip_writeb(flash, 0xAA, bios + 0xAAA); - chip_writeb(flash, 0x55, bios + 0x555); - chip_writeb(flash, 0x10, bios + 0xAAA); - - programmer_delay(10); - toggle_ready_jedec(flash, bios); - - /* FIXME: Check the status register for errors. */ - return 0; -} - -int erase_block_shifted_jedec(struct flashctx *flash, unsigned int start, unsigned int len) -{ - chipaddr bios = flash->virtual_memory; - chipaddr dst = bios + start; - - chip_writeb(flash, 0xAA, bios + 0xAAA); - chip_writeb(flash, 0x55, bios + 0x555); - chip_writeb(flash, 0x80, bios + 0xAAA); - - chip_writeb(flash, 0xAA, bios + 0xAAA); - chip_writeb(flash, 0x55, bios + 0x555); - chip_writeb(flash, 0x30, dst); - - programmer_delay(10); - toggle_ready_jedec(flash, bios); - - /* FIXME: Check the status register for errors. */ - return 0; -} - -int erase_chip_block_shifted_jedec(struct flashctx *flash, unsigned int address, unsigned int blocklen) -{ - if ((address != 0) || (blocklen != flash->chip->total_size * 1024)) { - msg_cerr("%s called with incorrect arguments\n", __func__); - return -1; - } - return erase_chip_shifted_jedec(flash); -} diff --git a/flashchips.c b/flashchips.c index 68b5dcf..74b58ba 100644 --- a/flashchips.c +++ b/flashchips.c @@ -4869,7 +4869,7 @@ const struct flashchip flashchips[] = { .model_id = EON_EN29LV640B, .total_size = 8192, .page_size = 8192, - .feature_bits = 0, + .feature_bits = FEATURE_ADDR_SHIFTED, .tested = TEST_OK_PREW, .probe = probe_en29lv640b, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ @@ -4880,10 +4880,10 @@ const struct flashchip flashchips[] = { {8 * 1024, 8}, {64 * 1024, 127}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_block_jedec, }, { .eraseblocks = { {8 * 1024 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, .write = write_en29lv640b, @@ -5078,10 +5078,10 @@ const struct flashchip flashchips[] = { .model_id = FUJITSU_MBM29F400BC, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = 10, // FIXME: check datasheet. Using the 10 us from probe_m29f400bt .block_erasers = { { @@ -5091,13 +5091,13 @@ const struct flashchip flashchips[] = { {32 * 1024, 1}, {64 * 1024, 7}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */ }, @@ -5110,10 +5110,10 @@ const struct flashchip flashchips[] = { .model_id = FUJITSU_MBM29F400TC, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = 10, // FIXME: check datasheet. Using the 10 us from probe_m29f400bt .block_erasers = { { @@ -5123,13 +5123,13 @@ const struct flashchip flashchips[] = { {8 * 1024, 2}, {16 * 1024, 1}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */ }, @@ -5144,8 +5144,8 @@ const struct flashchip flashchips[] = { .page_size = 0, .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_SHORT_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, + .probe = probe_jedec, + .probe_timing = 10, // FIXME: check datasheet. Using the 10 us from probe_m29f400bt .block_erasers = { { @@ -5155,13 +5155,13 @@ const struct flashchip flashchips[] = { {32 * 1024, 1}, {64 * 1024, 31}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_block_jedec, }, { .eraseblocks = { {2048 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, - .write = write_m29f400bt, /* Supports a fast mode too */ + .write = write_jedec_1, /* Supports a fast mode too */ .read = read_memmapped, .voltage = {3000, 3600}, /* 3.0-3.6V for type -70, others 2.7-3.6V */ }, @@ -5176,8 +5176,8 @@ const struct flashchip flashchips[] = { .page_size = 0, .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_SHORT_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, + .probe = probe_jedec, + .probe_timing = 10, // FIXME: check datasheet. Using the 10 us from probe_m29f400bt .block_erasers = { { @@ -5187,13 +5187,13 @@ const struct flashchip flashchips[] = { {8 * 1024, 2}, {16 * 1024, 1}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_block_jedec, }, { .eraseblocks = { {2048 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, - .write = write_m29f400bt, /* Supports a fast mode too */ + .write = write_jedec_1, /* Supports a fast mode too */ .read = read_memmapped, .voltage = {3000, 3600}, /* 3.0-3.6V for type -70, others 2.7-3.6V */ }, @@ -12178,10 +12178,10 @@ const struct flashchip flashchips[] = { .model_id = ST_M29F400BB, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = 10, // FIXME: check datasheet. Using the 10 us from probe_m29f400bt .block_erasers = { { @@ -12191,13 +12191,13 @@ const struct flashchip flashchips[] = { {32 * 1024, 1}, {64 * 1024, 7}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, } }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4500, 5500}, }, @@ -12210,10 +12210,10 @@ const struct flashchip flashchips[] = { .model_id = ST_M29F400BT, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = 10, // FIXME: check datasheet. Using the 10 us from probe_m29f400bt .block_erasers = { { @@ -12223,13 +12223,13 @@ const struct flashchip flashchips[] = { {8 * 1024, 2}, {16 * 1024, 1}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, } }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4500, 5500}, }, diff --git a/flashchips.h b/flashchips.h index f0fbf4b..93daeb4 100644 --- a/flashchips.h +++ b/flashchips.h @@ -295,6 +295,8 @@ #define EON_EN29LV010 0x7F6E #define EON_EN29LV040A 0x7F4F /* EN29LV040(A) */ #define EON_EN29LV640B 0xCB +#define EON_EN29LV640T 0xC9 +#define EON_EN29LV640U 0x7E #define EON_EN29F002T 0x7F92 /* Same as EN29F002A */ #define EON_EN29F002B 0x7F97 /* Same as EN29F002AN */ #define EON_EN29GL064HL 0x7E0C01 /* Uniform Sectors, WP protects Top OR Bottom sector */ diff --git a/jedec.c b/jedec.c index 59bec6f..358b850 100644 --- a/jedec.c +++ b/jedec.c @@ -4,7 +4,7 @@ * Copyright (C) 2000 Silicon Integrated System Corporation * Copyright (C) 2006 Giampiero Giancipoli gianci@email.it * Copyright (C) 2006 coresystems GmbH info@coresystems.de - * Copyright (C) 2007, 2011 Carl-Daniel Hailfinger + * Copyright (C) 2007-2012 Carl-Daniel Hailfinger * Copyright (C) 2009 Sean Nelson audiohacked@gmail.com * Copyright (C) 2014 Stefan Tauner * @@ -116,9 +116,11 @@ static unsigned int getaddrmask(const struct flashchip *chip) static void start_program_jedec_common(const struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); - chip_writeb(flash, 0xA0, bios + (0x5555 & mask)); + bool shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED); + + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); + chip_writeb(flash, 0xA0, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); }
int probe_jedec_29gl(struct flashctx *flash) @@ -174,6 +176,7 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; const struct flashchip *chip = flash->chip; + bool shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED); uint8_t id1, id2; uint32_t largeid1, largeid2; uint32_t flashcontent1, flashcontent2; @@ -203,31 +206,31 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask) /* Reset chip to a clean slate */ if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) { - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); if (probe_timing_exit) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); if (probe_timing_exit) programmer_delay(10); } - chip_writeb(flash, 0xF0, bios + (0x5555 & mask)); + chip_writeb(flash, 0xF0, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); if (probe_timing_exit) programmer_delay(probe_timing_exit);
/* Issue JEDEC Product ID Entry command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); if (probe_timing_enter) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); if (probe_timing_enter) programmer_delay(10); - chip_writeb(flash, 0x90, bios + (0x5555 & mask)); + chip_writeb(flash, 0x90, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); if (probe_timing_enter) programmer_delay(probe_timing_enter);
/* Read product ID */ - id1 = chip_readb(flash, bios); - id2 = chip_readb(flash, bios + 0x01); + id1 = chip_readb(flash, bios + (0x00 << shifted)); + id2 = chip_readb(flash, bios + (0x01 << shifted)); largeid1 = id1; largeid2 = id2;
@@ -246,14 +249,14 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask) /* Issue JEDEC Product ID Exit command */ if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) { - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); if (probe_timing_exit) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); if (probe_timing_exit) programmer_delay(10); } - chip_writeb(flash, 0xF0, bios + (0x5555 & mask)); + chip_writeb(flash, 0xF0, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); if (probe_timing_exit) programmer_delay(probe_timing_exit);
@@ -262,8 +265,8 @@ static int probe_jedec_common(struct flashctx *flash, unsigned int mask) msg_cdbg(", id1 parity violation");
/* Read the product ID location again. We should now see normal flash contents. */ - flashcontent1 = chip_readb(flash, bios); - flashcontent2 = chip_readb(flash, bios + 0x01); + flashcontent1 = chip_readb(flash, bios + (0x00 << shifted)); + flashcontent2 = chip_readb(flash, bios + (0x01 << shifted));
/* Check if it is a continuation ID, this should be a while loop. */ if (flashcontent1 == 0x7F) { @@ -294,21 +297,23 @@ static int erase_sector_jedec_common(struct flashctx *flash, unsigned int page, unsigned int pagesize, unsigned int mask) { chipaddr bios = flash->virtual_memory; + bool shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED); unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the Sector Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); programmer_delay(delay_us); chip_writeb(flash, 0x30, bios + page); programmer_delay(delay_us); @@ -324,21 +329,23 @@ static int erase_block_jedec_common(struct flashctx *flash, unsigned int block, unsigned int blocksize, unsigned int mask) { chipaddr bios = flash->virtual_memory; + bool shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED); unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the Sector Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); programmer_delay(delay_us); chip_writeb(flash, 0x50, bios + block); programmer_delay(delay_us); @@ -353,23 +360,25 @@ static int erase_block_jedec_common(struct flashctx *flash, unsigned int block, static int erase_chip_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; + bool shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED); unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the JEDEC Chip Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((shifted ? 0x5555 : 0x2AAA) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x10, bios + (0x5555 & mask)); + chip_writeb(flash, 0x10, bios + ((shifted ? 0x2AAA : 0x5555) & mask)); programmer_delay(delay_us);
toggle_ready_jedec_slow(flash, bios); diff --git a/m29f400bt.c b/m29f400bt.c deleted file mode 100644 index 399a7e0..0000000 --- a/m29f400bt.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the flashrom project. - * - * Copyright (C) 2000 Silicon Integrated System Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "flash.h" -#include "chipdrivers.h" - -/* WARNING! - This chip uses the standard JEDEC Addresses in 16-bit mode as word - addresses. In byte mode, 0xAAA has to be used instead of 0x555 and - 0x555 instead of 0x2AA. Do *not* blindly replace with standard JEDEC - functions. */ - -/* chunksize is 1 */ -int write_m29f400bt(struct flashctx *flash, const uint8_t *src, unsigned int start, unsigned int len) -{ - int i; - chipaddr bios = flash->virtual_memory; - chipaddr dst = flash->virtual_memory + start; - - for (i = 0; i < len; i++) { - chip_writeb(flash, 0xAA, bios + 0xAAA); - chip_writeb(flash, 0x55, bios + 0x555); - chip_writeb(flash, 0xA0, bios + 0xAAA); - - /* transfer data from source to destination */ - chip_writeb(flash, *src, dst); - toggle_ready_jedec(flash, dst); -#if 0 - /* We only want to print something in the error case. */ - msg_cerr("Value in the flash at address 0x%lx = %#x, want %#x\n", - (dst - bios), chip_readb(flash, dst), *src); -#endif - dst++; - src++; - } - - /* FIXME: Ignore errors for now. */ - return 0; -} - -int probe_m29f400bt(struct flashctx *flash) -{ - chipaddr bios = flash->virtual_memory; - uint8_t id1, id2; - - chip_writeb(flash, 0xAA, bios + 0xAAA); - chip_writeb(flash, 0x55, bios + 0x555); - chip_writeb(flash, 0x90, bios + 0xAAA); - - programmer_delay(10); - - id1 = chip_readb(flash, bios); - /* The data sheet says id2 is at (bios + 0x01) and id2 listed in - * flash.h does not match. It should be possible to use JEDEC probe. - */ - id2 = chip_readb(flash, bios + 0x02); - - chip_writeb(flash, 0xAA, bios + 0xAAA); - chip_writeb(flash, 0x55, bios + 0x555); - chip_writeb(flash, 0xF0, bios + 0xAAA); - - programmer_delay(10); - - msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2); - - if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id) - return 1; - - return 0; -}