summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--chipdrivers.h4
-rw-r--r--flash.h2
-rw-r--r--flashchips.c14
-rw-r--r--flashrom.c12
-rw-r--r--pm49fl00x.c6
-rw-r--r--sst49lfxxxc.c5
-rw-r--r--w39v040c.c26
8 files changed, 64 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index b9445b7..3b9432f 100644
--- a/Makefile
+++ b/Makefile
@@ -41,7 +41,7 @@ CPPFLAGS += -I/usr/local/include
LDFLAGS += -L/usr/local/lib
endif
-CHIP_OBJS = jedec.o stm50flw0x0x.o w39v080fa.o sharplhf00l04.o w29ee011.o \
+CHIP_OBJS = jedec.o stm50flw0x0x.o w39v040c.o w39v080fa.o sharplhf00l04.o w29ee011.o \
sst28sf040.o m29f400bt.o 82802ab.o pm49fl00x.o \
sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o
diff --git a/chipdrivers.h b/chipdrivers.h
index c5062ca..e262c2d 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -117,6 +117,7 @@ int write_29f002(struct flashchip *flash, uint8_t *buf);
int probe_49fl00x(struct flashchip *flash);
int erase_49fl00x(struct flashchip *flash);
int write_49fl00x(struct flashchip *flash, uint8_t *buf);
+int unlock_49fl00x(struct flashchip *flash);
/* sharplhf00l04.c */
int probe_lhf00l04(struct flashchip *flash);
@@ -145,6 +146,7 @@ int erase_sector_49lfxxxc(struct flashchip *flash, unsigned int address, unsigne
int erase_block_49lfxxxc(struct flashchip *flash, unsigned int address, unsigned int sector_size);
int erase_chip_49lfxxxc(struct flashchip *flash, unsigned int addr, unsigned int blocksize);
int write_49lfxxxc(struct flashchip *flash, uint8_t *buf);
+int unlock_49lfxxxc(struct flashchip *flash);
/* sst_fwhub.c */
int probe_sst_fwhub(struct flashchip *flash);
@@ -157,11 +159,13 @@ int write_sst_fwhub(struct flashchip *flash, uint8_t *buf);
int probe_w39v040c(struct flashchip *flash);
int erase_w39v040c(struct flashchip *flash);
int write_w39v040c(struct flashchip *flash, uint8_t *buf);
+int printlock_w39v040c(struct flashchip *flash);
/* w39V080fa.c */
int probe_winbond_fwhub(struct flashchip *flash);
int erase_winbond_fwhub(struct flashchip *flash);
int write_winbond_fwhub(struct flashchip *flash, uint8_t *buf);
+int unlock_winbond_fwhub(struct flashchip *flash);
/* w29ee011.c */
int probe_w29ee011(struct flashchip *flash);
diff --git a/flash.h b/flash.h
index 1474a38..1378b61 100644
--- a/flash.h
+++ b/flash.h
@@ -206,6 +206,8 @@ struct flashchip {
int (*block_erase) (struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen);
} block_erasers[NUM_ERASEFUNCTIONS];
+ int (*printlock) (struct flashchip *flash);
+ int (*unlock) (struct flashchip *flash);
int (*write) (struct flashchip *flash, uint8_t *buf);
int (*read) (struct flashchip *flash, uint8_t *buf, int start, int len);
diff --git a/flashchips.c b/flashchips.c
index cfe9dba..875d5b3 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -49,6 +49,8 @@ struct flashchip flashchips[] = {
* .eraseblocks[] = Array of { blocksize, blockcount }
* .block_erase = Block erase function
* }
+ * .printlock = Chip lock status function
+ * .unlock = Chip unlock function
* .write = Chip write function
* .read = Chip read function
*/
@@ -3330,7 +3332,6 @@ struct flashchip flashchips[] = {
.tested = TEST_UNTESTED,
.probe = probe_jedec,
.probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
- /* .erase = NULL, Was: erase_49fl00x */
.block_erasers =
{
{
@@ -3344,6 +3345,7 @@ struct flashchip flashchips[] = {
.block_erase = erase_chip_block_jedec,
}
},
+ .unlock = unlock_49fl00x,
.write = write_49fl00x,
.read = read_memmapped,
},
@@ -3360,7 +3362,6 @@ struct flashchip flashchips[] = {
.tested = TEST_UNTESTED,
.probe = probe_jedec,
.probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
- /* .erase = NULL, Was: erase_49fl00x */
.block_erasers =
{
{
@@ -3374,6 +3375,7 @@ struct flashchip flashchips[] = {
.block_erase = erase_chip_block_jedec,
}
},
+ .unlock = unlock_49fl00x,
.write = write_49fl00x,
.read = read_memmapped,
},
@@ -4406,7 +4408,6 @@ struct flashchip flashchips[] = {
.tested = TEST_OK_PRW,
.probe = probe_49lfxxxc,
.probe_timing = TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */
- /* .erase = NULL, Was: erase_49flxxxc */
.block_erasers =
{
{
@@ -4422,6 +4423,7 @@ struct flashchip flashchips[] = {
.block_erase = erase_block_49lfxxxc,
}
},
+ .unlock = unlock_49lfxxxc,
.write = write_49lfxxxc,
.read = read_memmapped,
},
@@ -5740,7 +5742,6 @@ struct flashchip flashchips[] = {
.tested = TEST_UNTESTED,
.probe = probe_jedec,
.probe_timing = TIMING_FIXME,
- /* .erase = NULL, Was erase_w39v040c */
.block_erasers =
{
{
@@ -5751,6 +5752,7 @@ struct flashchip flashchips[] = {
.block_erase = erase_chip_block_jedec,
}
},
+ .printlock = printlock_w39v040c,
.write = write_jedec_1,
.read = read_memmapped,
},
@@ -5915,7 +5917,6 @@ struct flashchip flashchips[] = {
.tested = TEST_UNTESTED,
.probe = probe_jedec,
.probe_timing = TIMING_FIXME,
- /* .erase = NULL, Was erase_winbond_fwhub */
.block_erasers =
{
{
@@ -5926,6 +5927,7 @@ struct flashchip flashchips[] = {
.block_erase = erase_chip_block_jedec,
}
},
+ .unlock = unlock_winbond_fwhub,
.write = write_jedec_1,
.read = read_memmapped,
},
@@ -5942,7 +5944,6 @@ struct flashchip flashchips[] = {
.tested = TEST_UNTESTED,
.probe = probe_jedec,
.probe_timing = TIMING_FIXME,
- /* .erase = NULL, Was erase_winbond_fwhub */
.block_erasers =
{
{
@@ -5953,6 +5954,7 @@ struct flashchip flashchips[] = {
.block_erase = erase_chip_block_jedec,
}
},
+ .unlock = unlock_winbond_fwhub,
.write = write_jedec_1,
.read = read_memmapped,
},
diff --git a/flashrom.c b/flashrom.c
index b8de3c1..d67680a 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -838,6 +838,9 @@ notfound:
flash->vendor, flash->name, flash->total_size,
flashbuses_to_text(flash->bustype), base);
+ if (flash->printlock)
+ flash->printlock(flash);
+
return flash;
}
@@ -1147,12 +1150,18 @@ int doit(struct flashchip *flash, int force, char *filename, int read_it, int wr
fprintf(stderr, "Continuing anyway.\n");
}
}
+ if (flash->unlock)
+ flash->unlock(flash);
+
if (erase_flash(flash)) {
emergency_help_message();
programmer_shutdown();
return 1;
}
} else if (read_it) {
+ if (flash->unlock)
+ flash->unlock(flash);
+
if (read_flash(flash, filename)) {
programmer_shutdown();
return 1;
@@ -1160,6 +1169,9 @@ int doit(struct flashchip *flash, int force, char *filename, int read_it, int wr
} else {
struct stat image_stat;
+ if (flash->unlock)
+ flash->unlock(flash);
+
if (flash->tested & TEST_BAD_ERASE) {
fprintf(stderr, "Erase is not working on this chip "
"and erase is needed for write. ");
diff --git a/pm49fl00x.c b/pm49fl00x.c
index 9d104e2..e8c498d 100644
--- a/pm49fl00x.c
+++ b/pm49fl00x.c
@@ -36,6 +36,12 @@ void write_lockbits_49fl00x(chipaddr bios, int size,
}
}
+int unlock_49fl00x(struct flashchip *flash)
+{
+ write_lockbits_49fl00x(flash->virtual_registers, flash->total_size * 1024, 0, flash->page_size);
+ return 0;
+}
+
int erase_49fl00x(struct flashchip *flash)
{
int i;
diff --git a/sst49lfxxxc.c b/sst49lfxxxc.c
index 80e5520..a65450e 100644
--- a/sst49lfxxxc.c
+++ b/sst49lfxxxc.c
@@ -82,6 +82,11 @@ static int write_lockbits_49lfxxxc(struct flashchip *flash, unsigned char bits)
return 0;
}
+int unlock_49lfxxxc(struct flashchip *flash)
+{
+ return write_lockbits_49lfxxxc(flash, 0);
+}
+
int erase_sector_49lfxxxc(struct flashchip *flash, unsigned int address, unsigned int sector_size)
{
unsigned char status;
diff --git a/w39v040c.c b/w39v040c.c
index 66ab115..853419a 100644
--- a/w39v040c.c
+++ b/w39v040c.c
@@ -50,6 +50,32 @@ int probe_w39v040c(struct flashchip *flash)
return 1;
}
+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);
+
+ printf("%s: Boot block #TBL is %slocked, rest of chip #WP is %slocked.\n",
+ __func__, lock & 0x4 ? "" : "un", lock & 0x8 ? "" : "un");
+ return 0;
+}
+
int erase_w39v040c(struct flashchip *flash)
{
int i;
OpenPOWER on IntegriCloud