Unlock ST M50FW002 correctly
Refactor ST M50 family unlocking
TODO: Unify write_lockbits_49fl00x() and unlock_block_stm50() and unlock_w39_fwh_block() and unlock_82802ab() and write_lockbits_block_49lfxxxc(). They all use exactly the same mechanism, but they don't share any code.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-stm50fw002_unlock/flashchips.c =================================================================== --- flashrom-stm50fw002_unlock/flashchips.c (Revision 1437) +++ flashrom-stm50fw002_unlock/flashchips.c (Arbeitskopie) @@ -7523,9 +7523,9 @@ .total_size = 256, .page_size = 64 * 1024, .feature_bits = FEATURE_REGISTERMAP, - .tested = TEST_UNTESTED, + .tested = TEST_OK_PREW, .probe = probe_82802ab, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */ + .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */ .block_erasers = { { @@ -7536,9 +7536,12 @@ {16 * 1024, 1}, }, .block_erase = erase_block_82802ab, + }, { + .eraseblocks = { {256 * 1024, 1}, }, + .block_erase = NULL, /* Only in A/A mux mode */ } }, - .unlock = unlock_stm50flw0x0x, + .unlock = unlock_stm50fw002, .write = write_82802ab, .read = read_memmapped, .voltage = {3000, 3600}, /* Also has 12V fast program & erase */ Index: flashrom-stm50fw002_unlock/stm50flw0x0x.c =================================================================== --- flashrom-stm50fw002_unlock/stm50flw0x0x.c (Revision 1437) +++ flashrom-stm50fw002_unlock/stm50flw0x0x.c (Arbeitskopie) @@ -3,6 +3,7 @@ * * Copyright (C) 2008 Claus Gindhart claus.gindhart@kontron.com * Copyright (C) 2009 Sean Nelson audiohacked@gmail.com + * Copyright (C) 2011 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 @@ -31,6 +32,21 @@ #include "flashchips.h" #include "chipdrivers.h"
+#define STM50_UNLOCKED 0x00 + +static int unlock_block_stm50(struct flashchip *flash, int offset) +{ + chipaddr lock = flash->virtual_registers + offset + 2; + + msg_cdbg("Unlocking at 0x%x\n", offset); + chip_writeb(STM50_UNLOCKED, lock); + if (chip_readb(lock) != STM50_UNLOCKED) { + msg_cerr("Cannot unlock at 0x%x\n", offset); + return -1; + } + return 0; +} + /* * claus.gindhart@kontron.com * The ST M50FLW080B and STM50FLW080B chips have to be unlocked, @@ -38,8 +54,6 @@ */ static int unlock_block_stm50flw0x0x(struct flashchip *flash, int offset) { - chipaddr wrprotect = flash->virtual_registers + 2; - static const uint8_t unlock_sector = 0x00; int j;
/* @@ -58,22 +72,12 @@ || (offset == 0xF0000)) {
// unlock each 4k-sector - for (j = 0; j < 0x10000; j += 0x1000) { - msg_cdbg("unlocking at 0x%x\n", offset + j); - chip_writeb(unlock_sector, wrprotect + offset + j); - if (chip_readb(wrprotect + offset + j) != unlock_sector) { - msg_cerr("Cannot unlock sector @ 0x%x\n", - offset + j); + for (j = 0; j < 0x10000; j += 0x1000) + if (unlock_block_stm50(flash, offset + j)) return -1; - } - } } else { - msg_cdbg("unlocking at 0x%x\n", offset); - chip_writeb(unlock_sector, wrprotect + offset); - if (chip_readb(wrprotect + offset) != unlock_sector) { - msg_cerr("Cannot unlock sector @ 0x%x\n", offset); + if (unlock_block_stm50(flash, offset)) return -1; - } }
return 0; @@ -93,6 +97,27 @@ return 0; }
+/* FIXME: Should this be moved to a generic walk_unlockregions()? */ +int unlock_stm50fw002(struct flashchip *flash) +{ + static const struct eraseblock unlockregions[4] = { + {64 * 1024, 3}, + {32 * 1024, 1}, + {8 * 1024, 2}, + {16 * 1024, 1}}; + int i, j; + int addr = 0; + + for (i = 0; i < 4; i++) { + for (j = 0; j < unlockregions[i].count; j++) { + if (unlock_block_stm50(flash, addr)) + return 1; + addr += unlockregions[i].size; + } + } + return 0; +} + /* This function is unused. */ int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int sector, unsigned int sectorsize) { Index: flashrom-stm50fw002_unlock/chipdrivers.h =================================================================== --- flashrom-stm50fw002_unlock/chipdrivers.h (Revision 1437) +++ flashrom-stm50fw002_unlock/chipdrivers.h (Arbeitskopie) @@ -146,5 +146,6 @@ /* stm50flw0x0x.c */ int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int block, unsigned int blocksize); int unlock_stm50flw0x0x(struct flashchip *flash); +int unlock_stm50fw002(struct flashchip *flash);
#endif /* !__CHIPDRIVERS_H__ */