On 04.12.2010 04:34, Carl-Daniel Hailfinger wrote: > On 04.12.2010 04:12, Carl-Daniel Hailfinger wrote: > >> Print lock status for all supported Winbond W39* chips: >> W39V040A >> W39V040(F)B >> W39V040(F)C >> W39V040FA >> W39V080A >> W39V080FA >> W39V080FA (dual mode) >> >> Please note that the W39V040B/W39V040FB pair has identical IDs, >> identical read/write/erase, but locking differs. Right now they have a >> common chip definition, but that will have to change in the future. For >> chipsets which support LPC and FWH, separating the chips will be really >> painful because both variants will be detected and the user will have to >> choose. Same problem appears for W39V040C/W39V040FC. >> A better evil twin handling (patch available) will resolve that problem. >>
Oh well... twin complaints are better than non-working chips. Now each chip has its own definition. > I forgot to mention that I fixed the probe timing for some of the above > chips as well. > > > >> Signed-off-by: Carl-Daniel Hailfinger <[email protected]> >> >> Please run "svn mv w39v080fa.c w39.c" before applying this patch. >> >> > > That will cause the patch to fail partially, but the end result will be > correct. If you hate failing patches, you can run > cp w39v080fa.c w39.c > > Please note that svn has problems auto-merging something like this, so > once this patch is checked in, you'll have to run > > svn revert w39v080fa.c w39.c > rm w39.c > svn up > > to be able to update to the latest tree if you applied this patch. > > If you didn't apply the patch, "svn up" will work normally. > New version, old instructions still apply. Signed-off-by: Carl-Daniel Hailfinger <[email protected]> Index: flashrom-w39_printlock/w39.c =================================================================== --- flashrom-w39_printlock/w39.c (Revision 1241) +++ flashrom-w39_printlock/w39.c (Arbeitskopie) @@ -2,6 +2,7 @@ * This file is part of the flashrom project. * * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2010 Carl-Daniel Hailfinger * * 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 @@ -21,67 +22,78 @@ #include "flash.h" #include "chipdrivers.h" -static int unlock_block_winbond_fwhub(struct flashchip *flash, int offset) +static int printlock_w39_fwh_block(struct flashchip *flash, int offset) { chipaddr wrprotect = flash->virtual_registers + offset + 2; uint8_t locking; - msg_cdbg("Trying to unlock block @0x%08x = 0x%02x\n", offset, - chip_readb(wrprotect)); - locking = chip_readb(wrprotect); + msg_cdbg("Lock status of block at 0x%08x is ", offset); switch (locking & 0x7) { case 0: msg_cdbg("Full Access.\n"); - return 0; + break; case 1: msg_cdbg("Write Lock (Default State).\n"); - chip_writeb(0, wrprotect); - return 0; + break; case 2: msg_cdbg("Locked Open (Full Access, Lock Down).\n"); - return 0; + break; case 3: msg_cerr("Error: Write Lock, Locked Down.\n"); - return -1; + break; case 4: msg_cdbg("Read Lock.\n"); - chip_writeb(0, wrprotect); - return 0; + break; case 5: msg_cdbg("Read/Write Lock.\n"); - chip_writeb(0, wrprotect); - return 0; + break; case 6: msg_cerr("Error: Read Lock, Locked Down.\n"); - return -1; + break; case 7: msg_cerr("Error: Read/Write Lock, Locked Down.\n"); - return -1; + break; } - /* We will never reach this point, but GCC doesn't know */ - return -1; + /* Read or write lock present? */ + return (locking & ((1 << 2) | (1 << 0))) ? -1 : 0; } -int unlock_winbond_fwhub(struct flashchip *flash) +static int unlock_w39_fwh_block(struct flashchip *flash, int offset) { - int i, total_size = flash->total_size * 1024; - chipaddr bios = flash->virtual_memory; + chipaddr wrprotect = flash->virtual_registers + offset + 2; uint8_t locking; - /* Are there any hardware restrictions that we can't overcome? - * If flashrom fail here, someone's got to check all those GPIOs. - */ + locking = chip_readb(wrprotect); + /* Read or write lock present? */ + if (locking & ((1 << 2) | (1 << 0))) { + /* Lockdown active? */ + if (locking & (1 << 1)) { + msg_cerr("Can't unlock block at 0x%x!\n", offset); + return -1; + } else { + msg_cdbg("Unlocking block at 0x%x\n", offset); + chip_writeb(0, wrprotect); + } + } + return 0; +} + +static uint8_t w39_idmode_readb(struct flashchip *flash, int offset) +{ + chipaddr bios = flash->virtual_memory; + uint8_t val; + /* Product Identification Entry */ chip_writeb(0xAA, bios + 0x5555); chip_writeb(0x55, bios + 0x2AAA); chip_writeb(0x90, bios + 0x5555); programmer_delay(10); - /* Read Hardware Lock Bits */ - locking = chip_readb(bios + 0xffff2); + /* Read something, maybe hardware lock bits */ + val = chip_readb(bios + offset); /* Product Identification Exit */ chip_writeb(0xAA, bios + 0x5555); @@ -89,25 +101,164 @@ chip_writeb(0xF0, bios + 0x5555); programmer_delay(10); - msg_cdbg("Lockout bits:\n"); + return val; +} - if (locking & (1 << 2)) - msg_cerr("Error: hardware bootblock locking (#TBL).\n"); - else - msg_cdbg("No hardware bootblock locking (good!)\n"); +static int printlock_w39_wblwp(uint8_t lock) +{ + msg_cdbg("Hardware bootblock locking (#TBL) is %sactive.\n", + (lock & (1 << 2)) ? "" : "not "); + msg_cdbg("Hardware remaining chip locking (#WP) is %sactive..\n", + (lock & (1 << 3)) ? "" : "not "); + if (lock & ((1 << 2) | (1 << 3))) + return -1; - if (locking & (1 << 3)) - msg_cerr("Error: hardware block locking (#WP).\n"); - else - msg_cdbg("No hardware block locking (good!)\n"); + return 0; +} - if (locking & ((1 << 2) | (1 << 3))) +static int printlock_w39_bootblock_64k16k(uint8_t lock) +{ + msg_cdbg("Software 64 kB bootblock locking is %sactive.\n", + (lock & (1 << 0)) ? "" : "not "); + msg_cdbg("Software 16 kB bootblock locking is %sactive.\n", + (lock & (1 << 1)) ? "" : "not "); + if (lock & ((1 << 1) | (1 << 0))) return -1; + return 0; +} + +static int printlock_w39_common(struct flashchip *flash, int offset) +{ + uint8_t lock; + + lock = w39_idmode_readb(flash, offset); + msg_cdbg("Lockout bits:\n"); + return printlock_w39_wblwp(lock); +} + +static int printlock_w39_fwh(struct flashchip *flash) +{ + int i, total_size = flash->total_size * 1024; + + /* Print lock status of the complete chip */ + for (i = 0; i < total_size; i += flash->page_size) + if (printlock_w39_fwh_block(flash, i)) + return -1; + + return 0; +} + +static int unlock_w39_fwh(struct flashchip *flash) +{ + int i, total_size = flash->total_size * 1024; + /* Unlock the complete chip */ for (i = 0; i < total_size; i += flash->page_size) - if (unlock_block_winbond_fwhub(flash, i)) + if (unlock_w39_fwh_block(flash, i)) return -1; return 0; } + +int printlock_w39v040a(struct flashchip *flash) +{ + uint8_t lock; + int ret = 0; + + /* The W39V040A datasheet contradicts itself on the lock register + * location: 0x00002 and 0x7fff2 are both mentioned. Pick the one + * which is similar to the other chips of the same family. + */ + lock = w39_idmode_readb(flash, 0x7fff2); + msg_cdbg("Lockout bits:\n"); + + ret = printlock_w39_wblwp(lock); + ret |= printlock_w39_bootblock_64k16k(lock); + + return ret; +} + +int printlock_w39v040b(struct flashchip *flash) +{ + return printlock_w39_common(flash, 0x7fff2); +} + +int printlock_w39v040c(struct flashchip *flash) +{ + return printlock_w39_common(flash, 0xfff2); +} + +int printlock_w39v040fa(struct flashchip *flash) +{ + int ret = 0; + + ret = printlock_w39v040a(flash); + ret |= printlock_w39_fwh(flash); + + return ret; +} + +/* Unused because W39V040B and W39V040FB can not be distinguished from each + * other based on ID. + */ +int printlock_w39v040fb(struct flashchip *flash) +{ + int ret = 0; + + ret = printlock_w39v040b(flash); + ret |= printlock_w39_fwh(flash); + + return ret; +} + +/* Unused because W39V040C and W39V040FC can not be distinguished from each + * other based on ID. + */ +int printlock_w39v040fc(struct flashchip *flash) +{ + int ret = 0; + + /* W39V040C and W39V040FC use different WP/TBL offsets. */ + ret = printlock_w39_common(flash, 0x7fff2); + ret |= printlock_w39_fwh(flash); + + return ret; +} + +int printlock_w39v080a(struct flashchip *flash) +{ + return printlock_w39_common(flash, 0xffff2); +} + +int printlock_w39v080fa(struct flashchip *flash) +{ + int ret = 0; + + ret = printlock_w39v080a(flash); + ret |= printlock_w39_fwh(flash); + + return ret; +} + +int printlock_w39v080fa_dual(struct flashchip *flash) +{ + msg_cinfo("Block locking for W39V080FA in dual mode is " + "undocumented.\n"); + /* Better safe than sorry. */ + return -1; +} + +int unlock_w39v080fa(struct flashchip *flash) +{ + if (unlock_w39_fwh(flash)) + return -1; + /* The soft bootblock locks may have been deactivated by the unlock + * above, so check them last. + */ + if (printlock_w39_common(flash, 0xffff2)) + return -1; + + return 0; +} + Index: flashrom-w39_printlock/Makefile =================================================================== --- flashrom-w39_printlock/Makefile (Revision 1242) +++ flashrom-w39_printlock/Makefile (Arbeitskopie) @@ -82,7 +82,7 @@ endif endif -CHIP_OBJS = jedec.o stm50flw0x0x.o w39v040c.o w39v080fa.o w29ee011.o \ +CHIP_OBJS = jedec.o stm50flw0x0x.o w39.o w29ee011.o \ sst28sf040.o m29f400bt.o 82802ab.o pm49fl00x.o \ sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o sharplhf00l04.o Index: flashrom-w39_printlock/w39v040c.c =================================================================== --- flashrom-w39_printlock/w39v040c.c (Revision 1242) +++ flashrom-w39_printlock/w39v040c.c (Arbeitskopie) @@ -1,48 +0,0 @@ -/* - * This file is part of the flashrom project. - * - * Copyright (C) 2008 Peter Stuge <[email protected]> - * - * 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" - -int printlock_w39v040c(struct flashchip *flash) -{ - chipaddr bios = flash->virtual_memory; - uint8_t lock; - - chip_writeb(0xAA, bios + 0x5555); - programmer_delay(10); - chip_writeb(0x55, bios + 0x2AAA); - programmer_delay(10); - chip_writeb(0x90, bios + 0x5555); - programmer_delay(10); - - lock = chip_readb(bios + 0xfff2); - - chip_writeb(0xAA, bios + 0x5555); - programmer_delay(10); - chip_writeb(0x55, bios + 0x2AAA); - programmer_delay(10); - chip_writeb(0xF0, bios + 0x5555); - programmer_delay(40); - - msg_cdbg("%s: Boot block #TBL is %slocked, rest of chip #WP is %slocked.\n", - __func__, lock & 0x4 ? "" : "un", lock & 0x8 ? "" : "un"); - return 0; -} Index: flashrom-w39_printlock/flashchips.c =================================================================== --- flashrom-w39_printlock/flashchips.c (Revision 1242) +++ flashrom-w39_printlock/flashchips.c (Arbeitskopie) @@ -7593,13 +7593,14 @@ .block_erase = erase_chip_block_jedec, } }, + .printlock = printlock_w39v040a, .write = write_jedec_1, .read = read_memmapped, }, { .vendor = "Winbond", - .name = "W39V040(F)B", + .name = "W39V040B", .bustype = CHIP_BUSTYPE_LPC, .manufacture_id = WINBOND_ID, .model_id = WINBOND_W39V040B, @@ -7619,13 +7620,14 @@ .block_erase = erase_chip_block_jedec, } }, + .printlock = printlock_w39v040b, .write = write_jedec_1, .read = read_memmapped, }, { .vendor = "Winbond", - .name = "W39V040(F)C", + .name = "W39V040C", .bustype = CHIP_BUSTYPE_LPC, .manufacture_id = WINBOND_ID, .model_id = WINBOND_W39V040C, @@ -7634,7 +7636,7 @@ .feature_bits = FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, + .probe_timing = 10, .block_erasers = { { @@ -7675,7 +7677,7 @@ .block_erase = erase_chip_block_jedec, } }, - .printlock = printlock_sst_fwhub, + .printlock = printlock_w39v040fa, .unlock = unlock_sst_fwhub, .write = write_jedec_1, .read = read_memmapped, @@ -7683,6 +7685,60 @@ { .vendor = "Winbond", + .name = "W39V040FB", + .bustype = CHIP_BUSTYPE_FWH, + .manufacture_id = WINBOND_ID, + .model_id = WINBOND_W39V040B, + .total_size = 512, + .page_size = 64 * 1024, + .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, + .tested = TEST_OK_PRE, + .probe = probe_jedec, + .probe_timing = 10, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 8} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, + .printlock = printlock_w39v040fb, + .write = write_jedec_1, + .read = read_memmapped, + }, + + { + .vendor = "Winbond", + .name = "W39V040FC", + .bustype = CHIP_BUSTYPE_FWH, + .manufacture_id = WINBOND_ID, + .model_id = WINBOND_W39V040C, + .total_size = 512, + .page_size = 64 * 1024, + .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec, + .probe_timing = 10, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 8} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, + .printlock = printlock_w39v040fc, + .write = write_jedec_1, + .read = read_memmapped, + }, + + { + .vendor = "Winbond", .name = "W39V080A", .bustype = CHIP_BUSTYPE_LPC, .manufacture_id = WINBOND_ID, @@ -7703,6 +7759,7 @@ .block_erase = erase_chip_block_jedec, } }, + .printlock = printlock_w39v080a, .write = write_jedec_1, .read = read_memmapped, }, @@ -7834,7 +7891,7 @@ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, .tested = TEST_OK_PRE, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, + .probe_timing = 10, .block_erasers = { { @@ -7845,7 +7902,8 @@ .block_erase = erase_chip_block_jedec, } }, - .unlock = unlock_winbond_fwhub, + .printlock = printlock_w39v080fa, + .unlock = unlock_w39v080fa, .write = write_jedec_1, .read = read_memmapped, }, @@ -7861,7 +7919,7 @@ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, .probe = probe_jedec, - .probe_timing = TIMING_FIXME, + .probe_timing = 10, .block_erasers = { { @@ -7872,7 +7930,7 @@ .block_erase = erase_chip_block_jedec, } }, - .unlock = unlock_winbond_fwhub, + .printlock = printlock_w39v080fa_dual, .write = write_jedec_1, .read = read_memmapped, }, Index: flashrom-w39_printlock/w39v080fa.c =================================================================== --- flashrom-w39_printlock/w39v080fa.c (Revision 1242) +++ flashrom-w39_printlock/w39v080fa.c (Arbeitskopie) @@ -1,113 +0,0 @@ -/* - * This file is part of the flashrom project. - * - * Copyright (C) 2008 coresystems GmbH - * - * 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" - -static int unlock_block_winbond_fwhub(struct flashchip *flash, int offset) -{ - chipaddr wrprotect = flash->virtual_registers + offset + 2; - uint8_t locking; - - msg_cdbg("Trying to unlock block @0x%08x = 0x%02x\n", offset, - chip_readb(wrprotect)); - - locking = chip_readb(wrprotect); - switch (locking & 0x7) { - case 0: - msg_cdbg("Full Access.\n"); - return 0; - case 1: - msg_cdbg("Write Lock (Default State).\n"); - chip_writeb(0, wrprotect); - return 0; - case 2: - msg_cdbg("Locked Open (Full Access, Lock Down).\n"); - return 0; - case 3: - msg_cerr("Error: Write Lock, Locked Down.\n"); - return -1; - case 4: - msg_cdbg("Read Lock.\n"); - chip_writeb(0, wrprotect); - return 0; - case 5: - msg_cdbg("Read/Write Lock.\n"); - chip_writeb(0, wrprotect); - return 0; - case 6: - msg_cerr("Error: Read Lock, Locked Down.\n"); - return -1; - case 7: - msg_cerr("Error: Read/Write Lock, Locked Down.\n"); - return -1; - } - - /* We will never reach this point, but GCC doesn't know */ - return -1; -} - -int unlock_winbond_fwhub(struct flashchip *flash) -{ - int i, total_size = flash->total_size * 1024; - chipaddr bios = flash->virtual_memory; - uint8_t locking; - - /* Are there any hardware restrictions that we can't overcome? - * If flashrom fail here, someone's got to check all those GPIOs. - */ - - /* Product Identification Entry */ - chip_writeb(0xAA, bios + 0x5555); - chip_writeb(0x55, bios + 0x2AAA); - chip_writeb(0x90, bios + 0x5555); - programmer_delay(10); - - /* Read Hardware Lock Bits */ - locking = chip_readb(bios + 0xffff2); - - /* Product Identification Exit */ - chip_writeb(0xAA, bios + 0x5555); - chip_writeb(0x55, bios + 0x2AAA); - chip_writeb(0xF0, bios + 0x5555); - programmer_delay(10); - - msg_cdbg("Lockout bits:\n"); - - if (locking & (1 << 2)) - msg_cerr("Error: hardware bootblock locking (#TBL).\n"); - else - msg_cdbg("No hardware bootblock locking (good!)\n"); - - if (locking & (1 << 3)) - msg_cerr("Error: hardware block locking (#WP).\n"); - else - msg_cdbg("No hardware block locking (good!)\n"); - - if (locking & ((1 << 2) | (1 << 3))) - return -1; - - /* Unlock the complete chip */ - for (i = 0; i < total_size; i += flash->page_size) - if (unlock_block_winbond_fwhub(flash, i)) - return -1; - - return 0; -} Index: flashrom-w39_printlock/chipdrivers.h =================================================================== --- flashrom-w39_printlock/chipdrivers.h (Revision 1242) +++ flashrom-w39_printlock/chipdrivers.h (Arbeitskopie) @@ -109,12 +109,18 @@ int printlock_sst_fwhub(struct flashchip *flash); int unlock_sst_fwhub(struct flashchip *flash); -/* w39v040c.c */ +/* w39.c */ +int printlock_w39v040a(struct flashchip *flash); +int printlock_w39v040b(struct flashchip *flash); int printlock_w39v040c(struct flashchip *flash); +int printlock_w39v040fa(struct flashchip *flash); +int printlock_w39v040fb(struct flashchip *flash); +int printlock_w39v040fc(struct flashchip *flash); +int printlock_w39v080a(struct flashchip *flash); +int printlock_w39v080fa(struct flashchip *flash); +int printlock_w39v080fa_dual(struct flashchip *flash); +int unlock_w39v080fa(struct flashchip *flash); -/* w39V080fa.c */ -int unlock_winbond_fwhub(struct flashchip *flash); - /* w29ee011.c */ int probe_w29ee011(struct flashchip *flash); -- http://www.hailfinger.org/ _______________________________________________ flashrom mailing list [email protected] http://www.flashrom.org/mailman/listinfo/flashrom
