W39F010 is 128kB parallel 5V flash chip, 16k bootblocks. W39L010 is 128kB parallel 3V flash chip, 8k bootblocks. W39L020 is 256kB parallel 3V flash chip, 64k/16k bootblocks.
Considering the test of W39F010, on the platform [1] the first write attempt after erase returned with verify failure. Second write attempt and following read-verify was succesful.
[1] "Silicon Image SiI 3124 PCI-X SATA Ctrl" (1095:3124, BDF 07:04.0).
Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com
diff --git a/chipdrivers.h b/chipdrivers.h index b43e16e..854269d 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -137,6 +137,9 @@ int printlock_sst_fwhub(struct flashctx *flash); int unlock_sst_fwhub(struct flashctx *flash);
/* w39.c */ +int printlock_w39f010(struct flashctx * flash); +int printlock_w39l010(struct flashctx * flash); +int printlock_w39l020(struct flashctx * flash); int printlock_w39l040(struct flashctx * flash); int printlock_w39v040a(struct flashctx *flash); int printlock_w39v040b(struct flashctx *flash); diff --git a/flashchips.c b/flashchips.c index 1afed36..56333eb 100644 --- a/flashchips.c +++ b/flashchips.c @@ -9102,6 +9102,93 @@ const struct flashchip flashchips[] = {
{ .vendor = "Winbond", + .name = "W39F010", + .bustype = BUS_PARALLEL, + .manufacture_id = WINBOND_ID, + .model_id = WINBOND_W39F010, + .total_size = 128, + .page_size = 4 * 1024, + .feature_bits = FEATURE_EITHER_RESET, + .tested = TEST_OK_PREW, + .probe = probe_jedec, + .probe_timing = 10, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 32} }, + .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {128 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, + .printlock = printlock_w39f010, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {4500, 5500}, + }, + + { + .vendor = "Winbond", + .name = "W39L010", + .bustype = BUS_PARALLEL, + .manufacture_id = WINBOND_ID, + .model_id = WINBOND_W39L010, + .total_size = 128, + .page_size = 4 * 1024, + .feature_bits = FEATURE_EITHER_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec, + .probe_timing = 10, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 32} }, + .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {128 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, + .printlock = printlock_w39l010, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {3000, 3600}, + }, + + { + .vendor = "Winbond", + .name = "W39L020", + .bustype = BUS_PARALLEL, + .manufacture_id = WINBOND_ID, + .model_id = WINBOND_W39L020, + .total_size = 256, + .page_size = 4 * 1024, + .feature_bits = FEATURE_EITHER_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec, + .probe_timing = 10, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 64} }, + .block_erase = erase_block_jedec, + }, { + .eraseblocks = { {64 * 1024, 4} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {256 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, + .printlock = printlock_w39l020, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {3000, 3600}, + }, + + { + .vendor = "Winbond", .name = "W39L040", .bustype = BUS_PARALLEL, .manufacture_id = WINBOND_ID, diff --git a/flashchips.h b/flashchips.h index e6c74c4..3a8e655 100644 --- a/flashchips.h +++ b/flashchips.h @@ -648,6 +648,7 @@ #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_W39F010 0xA1 #define WINBOND_W39L010 0x31 #define WINBOND_W39L020 0xB5 #define WINBOND_W39L040 0xB6 diff --git a/w39.c b/w39.c index da61d23..d6504ff 100644 --- a/w39.c +++ b/w39.c @@ -115,6 +115,26 @@ static int printlock_w39_tblwp(uint8_t lock) return 0; }
+static int printlock_w39_bootblock_8k(uint8_t lock) +{ + msg_cdbg("Software 8 kB bootblock locking is %sactive.\n", + (lock & 0x03) ? "" : "not "); + if (lock & 0x03) + return -1; + + return 0; +} + +static int printlock_w39_bootblock_16k(uint8_t lock) +{ + msg_cdbg("Software 16 kB bootblock locking is %sactive.\n", + (lock & 0x03) ? "" : "not "); + if (lock & 0x03) + return -1; + + return 0; +} + static int printlock_w39_bootblock_64k16k(uint8_t lock) { msg_cdbg("Software 64 kB bootblock locking is %sactive.\n", @@ -160,6 +180,54 @@ static int unlock_w39_fwh(struct flashctx *flash) return 0; }
+int printlock_w39f010(struct flashctx *flash) +{ + uint8_t lock; + int ret; + + lock = w39_idmode_readb(flash, 0x00002); + msg_cdbg("Bottom boot block:\n"); + ret = printlock_w39_bootblock_16k(lock); + + lock = w39_idmode_readb(flash, 0x1fff2); + msg_cdbg("Top boot block:\n"); + ret |= printlock_w39_bootblock_16k(lock); + + return ret; +} + +int printlock_w39l010(struct flashctx *flash) +{ + uint8_t lock; + int ret; + + lock = w39_idmode_readb(flash, 0x00002); + msg_cdbg("Bottom boot block:\n"); + ret = printlock_w39_bootblock_8k(lock); + + lock = w39_idmode_readb(flash, 0x1fff2); + msg_cdbg("Top boot block:\n"); + ret |= printlock_w39_bootblock_8k(lock); + + return ret; +} + +int printlock_w39l020(struct flashctx *flash) +{ + uint8_t lock; + int ret; + + lock = w39_idmode_readb(flash, 0x00002); + msg_cdbg("Bottom boot block:\n"); + ret = printlock_w39_bootblock_64k16k(lock); + + lock = w39_idmode_readb(flash, 0x3fff2); + msg_cdbg("Top boot block:\n"); + ret |= printlock_w39_bootblock_64k16k(lock); + + return ret; +} + int printlock_w39l040(struct flashctx *flash) { uint8_t lock;