This includes PMC Pm49*, SST 49LF00*, ST M50* and Winbond W39* family.
The erase and write test status bits of all affected chips have been reset.

Signed-off-by: Carl-Daniel Hailfinger <[email protected]>
Signed-off-by: Stefan Tauner <[email protected]>
---
 82802ab.c     |  11 ----
 Makefile      |   2 +-
 chipdrivers.h |  19 +++---
 flashchips.c  |  87 +++++++++++++++------------
 jedec.c       | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 pm49fl00x.c   |  53 -----------------
 sst49lfxxxc.c |  39 -------------
 stm50.c       |  55 -----------------
 w39.c         | 112 ++---------------------------------
 9 files changed, 248 insertions(+), 315 deletions(-)
 delete mode 100644 pm49fl00x.c

diff --git a/82802ab.c b/82802ab.c
index 9e39852..e450b5d 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -108,17 +108,6 @@ uint8_t wait_82802ab(struct flashctx *flash)
        return status;
 }
 
-int unlock_82802ab(struct flashctx *flash)
-{
-       int i;
-       //chipaddr wrprotect = flash->virtual_registers + page + 2;
-
-       for (i = 0; i < flash->chip->total_size * 1024; i+= 
flash->chip->page_size)
-               chip_writeb(flash, 0, flash->virtual_registers + i + 2);
-
-       return 0;
-}
-
 int erase_block_82802ab(struct flashctx *flash, unsigned int page,
                        unsigned int pagesize)
 {
diff --git a/Makefile b/Makefile
index 64798c9..8f2d68d 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 pm49fl00x.o \
+       sst28sf040.o m29f400bt.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 03d922d..57b1340 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -131,7 +131,6 @@ int probe_82802ab(struct flashctx *flash);
 int erase_block_82802ab(struct flashctx *flash, unsigned int page, unsigned 
int pagesize);
 int write_82802ab(struct flashctx *flash, const uint8_t *buf, unsigned int 
start, unsigned int len);
 void print_status_82802ab(uint8_t status);
-int unlock_82802ab(struct flashctx *flash);
 int unlock_28f004s5(struct flashctx *flash);
 int unlock_lh28f008bjt(struct flashctx *flash);
 
@@ -146,15 +145,20 @@ int erase_sector_jedec(struct flashctx *flash, unsigned 
int page, unsigned int p
 int erase_block_jedec(struct flashctx *flash, unsigned int page, unsigned int 
blocksize);
 int erase_chip_block_jedec(struct flashctx *flash, unsigned int page, unsigned 
int blocksize);
 
+int unlock_regspace2_uniform_32k(struct flashctx *flash);
+int unlock_regspace2_uniform_64k(struct flashctx *flash);
+int unlock_regspace2_block_eraser_0(struct flashctx *flash);
+int unlock_regspace2_block_eraser_1(struct flashctx *flash);
+int unlock_regspace2_block(const struct flashctx *flash, chipaddr off);
+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);
 void protect_m29f400bt(struct flashctx *flash, chipaddr bios);
 
-/* pm49fl00x.c */
-int unlock_49fl00x(struct flashctx *flash);
-int lock_49fl00x(struct flashctx *flash);
-
 /* 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);
@@ -164,7 +168,6 @@ int protect_28sf040(struct flashctx *flash);
 
 /* sst49lfxxxc.c */
 int erase_sector_49lfxxxc(struct flashctx *flash, unsigned int address, 
unsigned int sector_size);
-int unlock_49lfxxxc(struct flashctx *flash);
 
 /* sst_fwhub.c */
 int printlock_sst_fwhub(struct flashctx *flash);
@@ -184,8 +187,6 @@ int printlock_w39v040fc(struct flashctx *flash);
 int printlock_w39v080a(struct flashctx *flash);
 int printlock_w39v080fa(struct flashctx *flash);
 int printlock_w39v080fa_dual(struct flashctx *flash);
-int unlock_w39v040fb(struct flashctx *flash);
-int unlock_w39v080fa(struct flashctx *flash);
 int printlock_at49f(struct flashctx *flash);
 
 /* w29ee011.c */
@@ -193,8 +194,6 @@ int probe_w29ee011(struct flashctx *flash);
 
 /* stm50.c */
 int erase_sector_stm50(struct flashctx *flash, unsigned int block, unsigned 
int blocksize);
-int unlock_stm50_uniform(struct flashctx *flash);
-int unlock_stm50_nonuniform(struct flashctx *flash);
 
 /* en29lv640b.c */
 int probe_en29lv640b(struct flashctx *flash);
diff --git a/flashchips.c b/flashchips.c
index 3689de5..489f7c3 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -1382,7 +1382,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 512,
                .page_size      = 64 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_jedec,
                .probe_timing   = TIMING_ZERO,  /* routine is wrapper to 
probe_jedec (pm49fl00x.c) */
                .block_erasers  =
@@ -1395,7 +1395,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_chip_block_jedec,
                        }
                },
-               .unlock         = unlock_49fl00x,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_jedec_1,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -5979,7 +5979,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 512,
                .page_size      = 64 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_82802ab,
                .probe_timing   = TIMING_IGNORED, /* routine does not use 
probe_timing (82802ab.c) */
                .block_erasers  =
@@ -5989,7 +5989,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        },
                },
-               .unlock         = unlock_82802ab,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -6014,7 +6014,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        },
                },
-               .unlock         = unlock_82802ab,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -9202,7 +9202,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 256,
                .page_size      = 16 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_jedec,
                .probe_timing   = TIMING_ZERO,  /* routine is wrapper to 
probe_jedec (pm49fl00x.c) */
                .block_erasers  =
@@ -9218,7 +9218,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_chip_block_jedec,
                        }
                },
-               .unlock         = unlock_49fl00x,
+               .unlock         = unlock_regspace2_uniform_32k,
                .write          = write_jedec_1,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -9233,7 +9233,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 512,
                .page_size      = 64 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_jedec,
                .probe_timing   = TIMING_ZERO,  /* routine is wrapper to 
probe_jedec (pm49fl00x.c) */
                .block_erasers  =
@@ -9249,7 +9249,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_chip_block_jedec,
                        }
                },
-               .unlock         = unlock_49fl00x,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_jedec_1,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -9562,7 +9562,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = NULL, /* 30 D0, only in A/A mux 
mode */
                        },
                },
-               .unlock         = unlock_82802ab,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -11104,7 +11104,8 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_49lfxxxc,
+               .printlock      = printlock_regspace2_block_eraser_1,
+               .unlock         = unlock_regspace2_block_eraser_1,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -11169,7 +11170,8 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_49lfxxxc,
+               .printlock      = printlock_regspace2_block_eraser_1,
+               .unlock         = unlock_regspace2_block_eraser_1,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -11184,7 +11186,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 2048,
                .page_size      = 4 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_82802ab,
                .probe_timing   = TIMING_IGNORED, /* routine doesn't use 
probe_timing (sst49lfxxxc.c) */
                .block_erasers  =
@@ -11202,7 +11204,8 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_49lfxxxc,
+               .printlock      = printlock_regspace2_block_eraser_1,
+               .unlock         = unlock_regspace2_block_eraser_1,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -11307,7 +11310,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 512,
                .page_size      = 64 * 1024,
                .feature_bits   = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_jedec,
                .probe_timing   = 1,            /* 150ns */
                .block_erasers  =
@@ -11323,7 +11326,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = NULL,
                        }
                },
-               .unlock         = unlock_82802ab,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_jedec_1,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -11368,7 +11371,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 2048,
                .page_size      = 4 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP,
-               .tested         = TEST_OK_PRE,
+               .tested         = TEST_OK_PR,
                .probe          = probe_82802ab,
                .probe_timing   = TIMING_IGNORED, /* routine doesn't use 
probe_timing (sst49lfxxxc.c) */
                .block_erasers  =
@@ -11386,7 +11389,8 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_49lfxxxc,
+               .printlock      = printlock_regspace2_block_eraser_1,
+               .unlock         = unlock_regspace2_block_eraser_1,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -11654,7 +11658,7 @@ const struct flashchip flashchips[] = {
                        }
                },
                .write          = write_82802ab,
-               .unlock         = unlock_stm50_uniform,
+               .unlock         = unlock_regspace2_uniform_64k,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
        },
@@ -11687,7 +11691,7 @@ const struct flashchip flashchips[] = {
                        }
                },
                .write          = write_82802ab,
-               .unlock         = unlock_stm50_uniform,
+               .unlock         = unlock_regspace2_uniform_64k,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
        },
@@ -11701,7 +11705,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 1024,
                .page_size      = 0,
                .feature_bits   = FEATURE_REGISTERMAP,
-               .tested         = TEST_OK_PRE,
+               .tested         = TEST_OK_PR,
                .probe          = probe_82802ab,
                .probe_timing   = TIMING_FIXME,
                .block_erasers  =
@@ -11719,7 +11723,8 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_stm50_nonuniform,
+               .printlock      = printlock_regspace2_block_eraser_0,
+               .unlock         = unlock_regspace2_block_eraser_0,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
@@ -11752,7 +11757,8 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_stm50_nonuniform,
+               .printlock      = printlock_regspace2_block_eraser_0,
+               .unlock         = unlock_regspace2_block_eraser_0,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
@@ -11767,9 +11773,9 @@ const struct flashchip flashchips[] = {
                .total_size     = 256,
                .page_size      = 0,
                .feature_bits   = FEATURE_REGISTERMAP,
-               .tested         = TEST_UNTESTED,
+               .tested         = TEST_OK_PR,
                .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  =
                {
                        {
@@ -11780,9 +11786,13 @@ const struct flashchip flashchips[] = {
                                        {16 * 1024, 1},
                                },
                                .block_erase = erase_block_82802ab,
+                       }, {
+                               .eraseblocks = { {256 * 1024, 1}, },
+                               .block_erase = NULL, /* Only in A/A mux mode */
                        }
                },
-               .unlock         = unlock_stm50_nonuniform,
+               .printlock      = printlock_regspace2_block_eraser_0,
+               .unlock         = unlock_regspace2_block_eraser_0,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
@@ -11807,7 +11817,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_stm50_uniform,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
@@ -11832,7 +11842,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_stm50_uniform,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
@@ -11847,7 +11857,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 1024,
                .page_size      = 0,
                .feature_bits   = FEATURE_REGISTERMAP,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_82802ab,
                .probe_timing   = TIMING_IGNORED, /* routine doesn't use 
probe_timing (82802ab.c) */
                .block_erasers  =
@@ -11857,7 +11867,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_stm50_uniform,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
@@ -11882,7 +11892,7 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_stm50_uniform,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
@@ -11913,7 +11923,8 @@ const struct flashchip flashchips[] = {
                                .block_erase = erase_block_82802ab,
                        }
                },
-               .unlock         = unlock_stm50_nonuniform,
+               .printlock      = printlock_regspace2_block_eraser_0,
+               .unlock         = unlock_regspace2_block_eraser_0,
                .write          = write_82802ab,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program & 
erase */
@@ -13181,7 +13192,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 512,
                .page_size      = 64 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_jedec,
                .probe_timing   = 10,
                .block_erasers  =
@@ -13198,7 +13209,7 @@ const struct flashchip flashchips[] = {
                        }
                },
                .printlock      = printlock_w39v040fa,
-               .unlock         = unlock_sst_fwhub,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_jedec_1,
                .read           = read_memmapped,
                .voltage        = {3000, 3600},
@@ -13213,7 +13224,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 512,
                .page_size      = 64 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_jedec,
                .probe_timing   = 10,
                .block_erasers  =
@@ -13227,7 +13238,7 @@ const struct flashchip flashchips[] = {
                        }
                },
                .printlock      = printlock_w39v040fb,
-               .unlock         = unlock_w39v040fb,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_jedec_1,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program */
@@ -13418,7 +13429,7 @@ const struct flashchip flashchips[] = {
                .total_size     = 1024,
                .page_size      = 64 * 1024,
                .feature_bits   = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-               .tested         = TEST_OK_PREW,
+               .tested         = TEST_OK_PR,
                .probe          = probe_jedec,
                .probe_timing   = 10,
                .block_erasers  =
@@ -13432,7 +13443,7 @@ const struct flashchip flashchips[] = {
                        }
                },
                .printlock      = printlock_w39v080fa,
-               .unlock         = unlock_w39v080fa,
+               .unlock         = unlock_regspace2_uniform_64k,
                .write          = write_jedec_1,
                .read           = read_memmapped,
                .voltage        = {3000, 3600}, /* Also has 12V fast program */
diff --git a/jedec.c b/jedec.c
index 08cc88b..29fdae8 100644
--- a/jedec.c
+++ b/jedec.c
@@ -4,8 +4,9 @@
  * Copyright (C) 2000 Silicon Integrated System Corporation
  * Copyright (C) 2006 Giampiero Giancipoli <[email protected]>
  * Copyright (C) 2006 coresystems GmbH <[email protected]>
- * Copyright (C) 2007 Carl-Daniel Hailfinger
+ * Copyright (C) 2007, 2011 Carl-Daniel Hailfinger
  * Copyright (C) 2009 Sean Nelson <[email protected]>
+ * Copyright (C) 2014 Stefan Tauner
  *
  * 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
@@ -510,3 +511,185 @@ int erase_chip_jedec(struct flashctx *flash)
        mask = getaddrmask(flash->chip);
        return erase_chip_jedec_common(flash, mask);
 }
+
+struct unlockblock {
+       unsigned int size;
+       unsigned int count;
+};
+
+typedef int (*unlockblock_func)(const struct flashctx *flash, chipaddr offset);
+static int regspace2_walk_unlockblocks(const struct flashctx *flash, const 
struct unlockblock *block, unlockblock_func func)
+{
+       chipaddr off = flash->virtual_registers + 2;
+       while (block->count != 0) {
+               unsigned int j;
+               for (j = 0; j < block->count; j++) {
+                       if (func(flash, off))
+                               return -1;
+                       off += block->size;
+               }
+               block++;
+       }
+       return 0;
+}
+
+#define REG2_RWLOCK ((1 << 2) | (1 << 0))
+#define REG2_LOCKDOWN (1 << 1)
+#define REG2_MASK (REG2_RWLOCK | REG2_LOCKDOWN)
+
+static int printlock_regspace2_block(const struct flashctx *flash, chipaddr 
offset)
+{
+       chipaddr wrprotect = flash->virtual_registers + offset + 2;
+       uint8_t state = chip_readb(flash, wrprotect);
+       msg_cdbg("Lock status of block at 0x%0*" PRIxPTR " is ", PRIxPTR_WIDTH, 
offset);
+       switch (state & REG2_MASK) {
+       case 0:
+               msg_cdbg("Full Access.\n");
+               break;
+       case 1:
+               msg_cdbg("Write Lock (Default State).\n");
+               break;
+       case 2:
+               msg_cdbg("Locked Open (Full Access, Locked Down).\n");
+               break;
+       case 3:
+               msg_cdbg("Write Lock, Locked Down.\n");
+               break;
+       case 4:
+               msg_cdbg("Read Lock.\n");
+               break;
+       case 5:
+               msg_cdbg("Read/Write Lock.\n");
+               break;
+       case 6:
+               msg_cdbg("Read Lock, Locked Down.\n");
+               break;
+       case 7:
+               msg_cdbg("Read/Write Lock, Locked Down.\n");
+               break;
+       }
+       return 0;
+}
+
+int printlock_regspace2_blocks(const struct flashctx *flash, const struct 
unlockblock *blocks)
+{
+       return regspace2_walk_unlockblocks(flash, blocks, 
&printlock_regspace2_block);
+}
+
+static int printlock_regspace2_uniform(struct flashctx *flash, unsigned long 
block_size)
+{
+       const unsigned int elems = flash->chip->total_size * 1024 / block_size;
+       struct unlockblock blocks[2] = {{.size = block_size, .count = elems}};
+       return regspace2_walk_unlockblocks(flash, blocks, 
&printlock_regspace2_block);
+}
+
+int printlock_regspace2_uniform_64k(struct flashctx *flash)
+{
+       return printlock_regspace2_uniform(flash, 64 * 1024);
+}
+
+int printlock_regspace2_block_eraser_0(struct flashctx *flash)
+{
+       // FIXME: this depends on the eraseblocks not to be filled up 
completely (i.e. to be null-terminated).
+       const struct unlockblock *unlockblocks =
+               (const struct unlockblock 
*)flash->chip->block_erasers[0].eraseblocks;
+       return regspace2_walk_unlockblocks(flash, unlockblocks, 
&printlock_regspace2_block);
+}
+
+int printlock_regspace2_block_eraser_1(struct flashctx *flash)
+{
+       // FIXME: this depends on the eraseblocks not to be filled up 
completely (i.e. to be null-terminated).
+       const struct unlockblock *unlockblocks =
+               (const struct unlockblock 
*)flash->chip->block_erasers[1].eraseblocks;
+       return regspace2_walk_unlockblocks(flash, unlockblocks, 
&printlock_regspace2_block);
+}
+
+static int changelock_regspace2_block(const struct flashctx *flash, chipaddr 
offset, uint8_t new_bits)
+{
+       chipaddr wrprotect = flash->virtual_registers + offset + 2;
+       uint8_t old;
+
+       if (new_bits & ~REG2_MASK) {
+               msg_cerr("Invalid locking change 0x%02x requested at 0x%0*" 
PRIxPTR "! "
+                        "Please report a bug at [email protected]\n",
+                        new_bits, PRIxPTR_WIDTH, offset);
+               return -1;
+       }
+       old = chip_readb(flash, wrprotect);
+       /* Early exist if no change (of read/write/lockdown) was requested. */
+       if (((old ^ new_bits) & REG2_MASK) == 0) {
+               msg_cdbg2("Locking status at 0x%0*" PRIxPTR " not changed\n", 
PRIxPTR_WIDTH, offset);
+               return 0;
+       }
+       /* Normally lockdowns can not be cleared. Try nevertheless if 
requested. */
+       if ((old & REG2_LOCKDOWN) && !(new_bits & REG2_LOCKDOWN)) {
+               chip_writeb(flash, old & ~REG2_LOCKDOWN, wrprotect);
+               if (chip_readb(flash, wrprotect) != (old & ~REG2_LOCKDOWN)) {
+                       msg_cerr("Lockdown can't be removed at 0x%0*" PRIxPTR 
"!\n", PRIxPTR_WIDTH, offset);
+                       return -1;
+               }
+       }
+       /* Change read or write lock? */
+       if ((old ^ new_bits) & REG2_RWLOCK) {
+               /* Do not lockdown yet. */
+               msg_cdbg("Changing locking status at 0x%0*" PRIxPTR " to 
0x%02x\n", PRIxPTR_WIDTH, offset, new_bits & REG2_RWLOCK);
+               chip_writeb(flash, new_bits & REG2_RWLOCK, wrprotect);
+               if (chip_readb(flash, wrprotect) != (new_bits & REG2_RWLOCK)) {
+                       msg_cerr("Locking status change FAILED at 0x%0*" 
PRIxPTR "!\n", PRIxPTR_WIDTH, offset);
+                       return -1;
+               }
+       }
+       /* Enable lockdown if requested. */
+       if (!(old & REG2_LOCKDOWN) && (new_bits & REG2_LOCKDOWN)) {
+               msg_cdbg("Enabling lockdown at 0x%0*" PRIxPTR "\n", 
PRIxPTR_WIDTH, offset);
+               chip_writeb(flash, new_bits, wrprotect);
+               if (chip_readb(flash, wrprotect) != new_bits) {
+                       msg_cerr("Enabling lockdown FAILED at 0x%0*" PRIxPTR 
"!\n", PRIxPTR_WIDTH, offset);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+int unlock_regspace2_block(const struct flashctx *flash, chipaddr off)
+{
+       chipaddr wrprotect = flash->virtual_registers + off + 2;
+       uint8_t old = chip_readb(flash, wrprotect);
+       /* We don't care for the lockdown bit as long as the RW locks are 0 
after we're done */
+       return changelock_regspace2_block(flash, off, old & ~REG2_RWLOCK);
+}
+
+static int unlock_regspace2_uniform(struct flashctx *flash, unsigned long 
block_size)
+{
+       const unsigned int elems = flash->chip->total_size * 1024 / block_size;
+       struct unlockblock blocks[2] = {{.size = block_size, .count = elems}};
+       return regspace2_walk_unlockblocks(flash, blocks, 
&unlock_regspace2_block);
+}
+
+int unlock_regspace2_uniform_64k(struct flashctx *flash)
+{
+       return unlock_regspace2_uniform(flash, 64 * 1024);
+}
+
+int unlock_regspace2_uniform_32k(struct flashctx *flash)
+{
+       return unlock_regspace2_uniform(flash, 32 * 1024);
+}
+
+int unlock_regspace2_block_eraser_0(struct flashctx *flash)
+{
+       // FIXME: this depends on the eraseblocks not to be filled up 
completely (i.e. to be null-terminated).
+       const struct unlockblock *unlockblocks =
+               (const struct unlockblock 
*)flash->chip->block_erasers[0].eraseblocks;
+       return regspace2_walk_unlockblocks(flash, unlockblocks, 
&unlock_regspace2_block);
+}
+
+int unlock_regspace2_block_eraser_1(struct flashctx *flash)
+{
+       // FIXME: this depends on the eraseblocks not to be filled up 
completely (i.e. to be null-terminated).
+       const struct unlockblock *unlockblocks =
+               (const struct unlockblock 
*)flash->chip->block_erasers[1].eraseblocks;
+       return regspace2_walk_unlockblocks(flash, unlockblocks, 
&unlock_regspace2_block);
+}
+
diff --git a/pm49fl00x.c b/pm49fl00x.c
deleted file mode 100644
index fe28d2b..0000000
--- a/pm49fl00x.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This file is part of the flashrom project.
- *
- * Copyright (C) 2004 Tyan Corporation
- * Copyright (C) 2007 Nikolay Petukhov <[email protected]>
- * Copyright (C) 2007 Reinder E.N. de Haan <[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"
-
-static void write_lockbits_49fl00x(const struct flashctx *flash,
-                                  unsigned int size, unsigned char bits,
-                                  unsigned int block_size)
-{
-       unsigned int i, left = size;
-       chipaddr bios = flash->virtual_registers;
-
-       for (i = 0; left >= block_size; i++, left -= block_size) {
-               /* pm49fl002 */
-               if (block_size == 16384 && i % 2)
-                       continue;
-
-               chip_writeb(flash, bits, bios + (i * block_size) + 2);
-       }
-}
-
-int unlock_49fl00x(struct flashctx *flash)
-{
-       write_lockbits_49fl00x(flash, flash->chip->total_size * 1024, 0,
-                              flash->chip->page_size);
-       return 0;
-}
-
-int lock_49fl00x(struct flashctx *flash)
-{
-       write_lockbits_49fl00x(flash, flash->chip->total_size * 1024, 1,
-                              flash->chip->page_size);
-       return 0;
-}
diff --git a/sst49lfxxxc.c b/sst49lfxxxc.c
index 3d17b5b..d6c85c8 100644
--- a/sst49lfxxxc.c
+++ b/sst49lfxxxc.c
@@ -23,45 +23,6 @@
 #include "flash.h"
 #include "chipdrivers.h"
 
-static int write_lockbits_block_49lfxxxc(struct flashctx *flash,
-                                        unsigned long address,
-                                        unsigned char bits)
-{
-       unsigned long lock = flash->virtual_registers + address + 2;
-       msg_cdbg("lockbits at address=0x%08lx is 0x%01x\n", lock,
-                chip_readb(flash, lock));
-       chip_writeb(flash, bits, lock);
-
-       return 0;
-}
-
-static int write_lockbits_49lfxxxc(struct flashctx *flash, unsigned char bits)
-{
-       chipaddr registers = flash->virtual_registers;
-       unsigned int i, left = flash->chip->total_size * 1024;
-       unsigned long address;
-
-       msg_cdbg("\nbios=0x%08" PRIxPTR "\n", registers);
-       for (i = 0; left > 65536; i++, left -= 65536) {
-               write_lockbits_block_49lfxxxc(flash, i * 65536, bits);
-       }
-       address = i * 65536;
-       write_lockbits_block_49lfxxxc(flash, address, bits);
-       address += 32768;
-       write_lockbits_block_49lfxxxc(flash, address, bits);
-       address += 8192;
-       write_lockbits_block_49lfxxxc(flash, address, bits);
-       address += 8192;
-       write_lockbits_block_49lfxxxc(flash, address, bits);
-
-       return 0;
-}
-
-int unlock_49lfxxxc(struct flashctx *flash)
-{
-       return write_lockbits_49lfxxxc(flash, 0);
-}
-
 int erase_sector_49lfxxxc(struct flashctx *flash, unsigned int address,
                          unsigned int sector_size)
 {
diff --git a/stm50.c b/stm50.c
index edcfdd2..1ae2bc4 100644
--- a/stm50.c
+++ b/stm50.c
@@ -27,63 +27,8 @@
  */
 
 #include "flash.h"
-#include "flashchips.h"
 #include "chipdrivers.h"
 
-static int stm50_unlock_address(struct flashctx *flash, int offset)
-{
-       chipaddr wrprotect = flash->virtual_registers + 2;
-       static const uint8_t unlock_sector = 0x00;
-       msg_cdbg("unlocking at 0x%x\n", offset);
-       chip_writeb(flash, unlock_sector, wrprotect + offset);
-       if (chip_readb(flash, wrprotect + offset) != unlock_sector) {
-               msg_cerr("Cannot unlock address 0x%x\n", offset);
-               return -1;
-       }
-       return 0;
-}
-
-/* Chips known to use a non-uniform block and sector layout for locking (as 
well as for erasing):
- * Name                Size    Address range of lock registers
- * M50FLW080A  1MB     FFB00002 - FFBFF002
- * M50FLW080B  1MB     FFB00002 - FFBFF002
- * M50FW002    256k    FFBC0002 - FFBFC002
- * M50LPW116   2MB     FFA00002 - FFBFC002
- */
-int unlock_stm50_nonuniform(struct flashctx *flash)
-{
-       int i;
-       struct eraseblock *eraseblocks = 
flash->chip->block_erasers[0].eraseblocks;
-       unsigned int done = 0;
-       for (i = 0; i < NUM_ERASEREGIONS && eraseblocks[i].count != 0; i++) {
-               unsigned int block_size = eraseblocks[i].size;
-               unsigned int block_count = eraseblocks[i].count;
-
-               int j;
-               for (j = 0; j < block_count; j++) {
-                       if (stm50_unlock_address(flash, done)) {
-                               msg_cerr("UNLOCK FAILED!\n");
-                               return -1;
-                       }
-                       done += block_count * block_size;
-               }
-       }
-       return 0;
-}
-
-/* Unlocking for uniform 64 kB blocks starting at offset 2 of the feature 
registers. */
-int unlock_stm50_uniform(struct flashctx *flash)
-{
-       int i;
-       for (i = 0; i < flash->chip->total_size * 1024; i+= 64 * 1024) {
-               if (stm50_unlock_address(flash, i)) {
-                       msg_cerr("UNLOCK FAILED!\n");
-                       return -1;
-               }
-       }
-       return 0;
-}
-
 static int stm50_erase_sector(struct flashctx *flash, unsigned int addr)
 {
        chipaddr bios = flash->virtual_memory + addr;
diff --git a/w39.c b/w39.c
index 9dcb06a..4dd366c 100644
--- a/w39.c
+++ b/w39.c
@@ -20,65 +20,7 @@
  */
 
 #include "flash.h"
-
-static int printlock_w39_fwh_block(struct flashctx *flash, unsigned int offset)
-{
-       chipaddr wrprotect = flash->virtual_registers + offset + 2;
-       uint8_t locking;
-
-       locking = chip_readb(flash, wrprotect);
-       msg_cdbg("Lock status of block at 0x%08x is ", offset);
-       switch (locking & 0x7) {
-       case 0:
-               msg_cdbg("Full Access.\n");
-               break;
-       case 1:
-               msg_cdbg("Write Lock (Default State).\n");
-               break;
-       case 2:
-               msg_cdbg("Locked Open (Full Access, Lock Down).\n");
-               break;
-       case 3:
-               msg_cerr("Error: Write Lock, Locked Down.\n");
-               break;
-       case 4:
-               msg_cdbg("Read Lock.\n");
-               break;
-       case 5:
-               msg_cdbg("Read/Write Lock.\n");
-               break;
-       case 6:
-               msg_cerr("Error: Read Lock, Locked Down.\n");
-               break;
-       case 7:
-               msg_cerr("Error: Read/Write Lock, Locked Down.\n");
-               break;
-       }
-
-       /* Read or write lock present? */
-       return (locking & ((1 << 2) | (1 << 0))) ? -1 : 0;
-}
-
-static int unlock_w39_fwh_block(struct flashctx *flash, unsigned int offset)
-{
-       chipaddr wrprotect = flash->virtual_registers + offset + 2;
-       uint8_t locking;
-
-       locking = chip_readb(flash, 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%08x!\n", offset);
-                       return -1;
-               } else {
-                       msg_cdbg("Unlocking block at 0x%08x\n", offset);
-                       chip_writeb(flash, 0, wrprotect);
-               }
-       }
-
-       return 0;
-}
+#include "chipdrivers.h"
 
 static uint8_t w39_idmode_readb(struct flashctx *flash, unsigned int offset)
 {
@@ -145,30 +87,6 @@ static int printlock_w39_common(struct flashctx *flash, 
unsigned int offset)
        return printlock_w39_tblwp(lock);
 }
 
-static int printlock_w39_fwh(struct flashctx *flash)
-{
-       unsigned int i, total_size = flash->chip->total_size * 1024;
-       int ret = 0;
-       
-       /* Print lock status of the complete chip */
-       for (i = 0; i < total_size; i += flash->chip->page_size)
-               ret |= printlock_w39_fwh_block(flash, i);
-
-       return ret;
-}
-
-static int unlock_w39_fwh(struct flashctx *flash)
-{
-       unsigned int i, total_size = flash->chip->total_size * 1024;
-       
-       /* Unlock the complete chip */
-       for (i = 0; i < total_size; i += flash->chip->page_size)
-               if (unlock_w39_fwh_block(flash, i))
-                       return -1;
-
-       return 0;
-}
-
 int printlock_w39f010(struct flashctx *flash)
 {
        uint8_t lock;
@@ -267,7 +185,7 @@ int printlock_w39v040fa(struct flashctx *flash)
        int ret = 0;
 
        ret = printlock_w39v040a(flash);
-       ret |= printlock_w39_fwh(flash);
+       ret |= printlock_regspace2_uniform_64k(flash);
 
        return ret;
 }
@@ -277,7 +195,7 @@ int printlock_w39v040fb(struct flashctx *flash)
        int ret = 0;
 
        ret = printlock_w39v040b(flash);
-       ret |= printlock_w39_fwh(flash);
+       ret |= printlock_regspace2_uniform_64k(flash);
 
        return ret;
 }
@@ -288,7 +206,7 @@ int printlock_w39v040fc(struct flashctx *flash)
 
        /* W39V040C and W39V040FC use different WP/TBL offsets. */
        ret = printlock_w39_common(flash, 0x7fff2);
-       ret |= printlock_w39_fwh(flash);
+       ret |= printlock_regspace2_uniform_64k(flash);
 
        return ret;
 }
@@ -303,7 +221,7 @@ int printlock_w39v080fa(struct flashctx *flash)
        int ret = 0;
 
        ret = printlock_w39v080a(flash);
-       ret |= printlock_w39_fwh(flash);
+       ret |= printlock_regspace2_uniform_64k(flash);
 
        return ret;
 }
@@ -316,26 +234,6 @@ int printlock_w39v080fa_dual(struct flashctx *flash)
        return -1;
 }
 
-int unlock_w39v040fb(struct flashctx *flash)
-{
-       if (unlock_w39_fwh(flash))
-               return -1;
-       if (printlock_w39_common(flash, 0x7fff2))
-               return -1;
-
-       return 0;
-}
-
-int unlock_w39v080fa(struct flashctx *flash)
-{
-       if (unlock_w39_fwh(flash))
-               return -1;
-       if (printlock_w39_common(flash, 0xffff2))
-               return -1;
-
-       return 0;
-}
-
 int printlock_at49f(struct flashctx *flash)
 {
        uint8_t lock = w39_idmode_readb(flash, 0x00002);
-- 
Kind regards, Stefan Tauner


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

Reply via email to