summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2009-06-15 17:23:36 +0000
committerCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2009-06-15 17:23:36 +0000
commit30f7cb2f3c570c99b61bd5df72621f44f1bdd0d0 (patch)
treed714754c298d7d247786e19c4b2b4afd6067a795
parent084546449983c1d6f147c1a3e381e225887e322c (diff)
downloadflashrom-30f7cb2f3c570c99b61bd5df72621f44f1bdd0d0.tar.gz
flashrom-30f7cb2f3c570c99b61bd5df72621f44f1bdd0d0.tar.bz2
flashrom-30f7cb2f3c570c99b61bd5df72621f44f1bdd0d0.zip
Flashrom only checks for very few chips if the erase worked
And even when it checks if the erase worked, the result of that check is often ignored. Convert all erase functions and actually check return codes almost everywhere. Check inside all erase_* routines if erase worked, not outside. erase_sector_jedec and erase_block_jedec have changed prototypes to enable erase checking. Uwe successfully tested LPC on an CK804 box and SPI on some SB600 box. Corresponding to flashrom svn r595. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Signed-off-by: Urja Rannikko <urjaman@gmail.com> Acked-by: Uwe Hermann <uwe@hermann-uwe.de>
-rw-r--r--82802ab.c19
-rw-r--r--am29f040b.c19
-rw-r--r--en29f002a.c5
-rw-r--r--flash.h10
-rw-r--r--flashrom.c88
-rw-r--r--jedec.c33
-rw-r--r--m29f002.c46
-rw-r--r--m29f400bt.c57
-rw-r--r--mx29f002.c9
-rw-r--r--pm29f002.c5
-rw-r--r--pm49fl00x.c11
-rw-r--r--sb600spi.c5
-rw-r--r--sharplhf00l04.c14
-rw-r--r--sst28sf040.c17
-rw-r--r--sst49lf040.c11
-rw-r--r--sst49lfxxxc.c14
-rw-r--r--sst_fwhub.c22
-rw-r--r--stm50flw0x0x.c27
-rw-r--r--w39v040c.c15
-rw-r--r--w39v080fa.c21
-rw-r--r--w49f002u.c5
-rw-r--r--wbsio_spi.c5
22 files changed, 345 insertions, 113 deletions
diff --git a/82802ab.c b/82802ab.c
index 1dc997fa2..28fa17759 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -110,7 +110,6 @@ int erase_82802ab_block(struct flashchip *flash, int offset)
{
chipaddr bios = flash->virtual_memory + offset;
chipaddr wrprotect = flash->virtual_registers + offset + 2;
- int j;
uint8_t status;
// clear status register
@@ -129,11 +128,9 @@ int erase_82802ab_block(struct flashchip *flash, int offset)
// now let's see what the register is
status = wait_82802ab(flash->virtual_memory);
//print_82802ab_status(status);
- for (j = 0; j < flash->page_size; j++) {
- if (chip_readb(bios + j) != 0xFF) {
- printf("BLOCK ERASE failed at 0x%x\n", offset);
- return -1;
- }
+ if (check_erased_range(flash, offset, flash->page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
}
printf("DONE BLOCK 0x%x\n", offset);
@@ -148,7 +145,10 @@ int erase_82802ab(struct flashchip *flash)
printf("total_size is %d; flash->page_size is %d\n",
total_size, flash->page_size);
for (i = 0; i < total_size; i += flash->page_size)
- erase_82802ab_block(flash, i);
+ if (erase_82802ab_block(flash, i)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
printf("DONE ERASE\n");
return 0;
@@ -199,7 +199,10 @@ int write_82802ab(struct flashchip *flash, uint8_t *buf)
}
/* erase block by block and write block by block; this is the most secure way */
- erase_82802ab_block(flash, i * page_size);
+ if (erase_82802ab_block(flash, i * page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_82802ab(bios, buf + i * page_size,
bios + i * page_size, page_size);
}
diff --git a/am29f040b.c b/am29f040b.c
index 2dc4c365e..7f1269c3d 100644
--- a/am29f040b.c
+++ b/am29f040b.c
@@ -20,8 +20,11 @@
#include "flash.h"
-static int erase_sector_29f040b(chipaddr bios, unsigned long address)
+static int erase_sector_29f040b(struct flashchip *flash, unsigned long address)
{
+ int page_size = flash->page_size;
+ chipaddr bios = flash->virtual_memory;
+
chip_writeb(0xAA, bios + 0x555);
chip_writeb(0x55, bios + 0x2AA);
chip_writeb(0x80, bios + 0x555);
@@ -34,6 +37,10 @@ static int erase_sector_29f040b(chipaddr bios, unsigned long address)
/* wait for Toggle bit ready */
toggle_ready_jedec(bios + address);
+ if (check_erased_range(flash, address, page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -86,6 +93,7 @@ int probe_29f040b(struct flashchip *flash)
int erase_29f040b(struct flashchip *flash)
{
+ int total_size = flash->total_size * 1024;
chipaddr bios = flash->virtual_memory;
chip_writeb(0xAA, bios + 0x555);
@@ -98,6 +106,10 @@ int erase_29f040b(struct flashchip *flash)
programmer_delay(10);
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, 0, total_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -111,7 +123,10 @@ int write_29f040b(struct flashchip *flash, uint8_t *buf)
printf("Programming page ");
for (i = 0; i < total_size / page_size; i++) {
/* erase the page before programming */
- erase_sector_29f040b(bios, i * page_size);
+ if (erase_sector_29f040b(flash, i * page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
/* write to the sector */
printf("%04d at address: ", i);
diff --git a/en29f002a.c b/en29f002a.c
index f4242f596..b89eb316f 100644
--- a/en29f002a.c
+++ b/en29f002a.c
@@ -98,7 +98,10 @@ int write_en29f002a(struct flashchip *flash, uint8_t *buf)
//chip_writeb(0xF0, bios);
programmer_delay(10);
- erase_chip_jedec(flash);
+ if (erase_chip_jedec(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
printf("Programming page: ");
for (i = 0; i < total_size; i++) {
diff --git a/flash.h b/flash.h
index 25ec836a3..97e0778f5 100644
--- a/flash.h
+++ b/flash.h
@@ -364,6 +364,9 @@ extern int verbose;
void map_flash_registers(struct flashchip *flash);
int read_memmapped(struct flashchip *flash, uint8_t *buf);
int min(int a, int b);
+int max(int a, int b);
+int check_erased_range(struct flashchip *flash, int start, int len);
+int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message);
extern char *pcidev_bdf;
/* layout.c */
@@ -471,8 +474,8 @@ int write_byte_program_jedec(chipaddr bios, uint8_t *src,
int probe_jedec(struct flashchip *flash);
int erase_chip_jedec(struct flashchip *flash);
int write_jedec(struct flashchip *flash, uint8_t *buf);
-int erase_sector_jedec(chipaddr bios, unsigned int page);
-int erase_block_jedec(chipaddr bios, unsigned int page);
+int erase_sector_jedec(struct flashchip *flash, unsigned int page, int pagesize);
+int erase_block_jedec(struct flashchip *flash, unsigned int page, int blocksize);
int write_sector_jedec(chipaddr bios, uint8_t *src,
chipaddr dst, unsigned int page_size);
@@ -484,8 +487,7 @@ int write_m29f002b(struct flashchip *flash, uint8_t *buf);
/* m29f400bt.c */
int probe_m29f400bt(struct flashchip *flash);
int erase_m29f400bt(struct flashchip *flash);
-int block_erase_m29f400bt(chipaddr bios,
- chipaddr dst);
+int block_erase_m29f400bt(struct flashchip *flash, int start, int len);
int write_m29f400bt(struct flashchip *flash, uint8_t *buf);
int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf);
void toggle_ready_m29f400bt(chipaddr dst);
diff --git a/flashrom.c b/flashrom.c
index bb2c160a3..fe5826faa 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -206,6 +206,11 @@ int min(int a, int b)
return (a < b) ? a : b;
}
+int max(int a, int b)
+{
+ return (a > b) ? a : b;
+}
+
char *strcat_realloc(char *dest, const char *src)
{
dest = realloc(dest, strlen(dest) + strlen(src) + 1);
@@ -246,6 +251,86 @@ char *flashbuses_to_text(enum chipbustype bustype)
return ret;
}
+/* start is an offset to the base address of the flash chip */
+int check_erased_range(struct flashchip *flash, int start, int len)
+{
+ int ret;
+ uint8_t *cmpbuf = malloc(len);
+
+ if (!cmpbuf) {
+ fprintf(stderr, "Could not allocate memory!\n");
+ exit(1);
+ }
+ memset(cmpbuf, 0xff, len);
+ ret = verify_range(flash, cmpbuf, start, len, "ERASE");
+ free(cmpbuf);
+ return ret;
+}
+
+/**
+ * @cmpbuf buffer to compare against
+ * @start offset to the base address of the flash chip
+ * @len length of the verified area
+ * @message string to print in the "FAILED" message
+ * @return 0 for success, -1 for failure
+ */
+int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message)
+{
+ int i, j, starthere, lenhere, ret = 0;
+ chipaddr bios = flash->virtual_memory;
+ int page_size = flash->page_size;
+ uint8_t *readbuf = malloc(page_size);
+
+ if (!len)
+ goto out_free;
+
+ if (!readbuf) {
+ fprintf(stderr, "Could not allocate memory!\n");
+ exit(1);
+ }
+
+ if (start + len > flash->total_size * 1024) {
+ fprintf(stderr, "Error: %s called with start 0x%x + len 0x%x >"
+ " total_size 0x%x\n", __func__, start, len,
+ flash->total_size * 1024);
+ ret = -1;
+ goto out_free;
+ }
+ if (!message)
+ message = "VERIFY";
+
+ /* Warning: This loop has a very unusual condition and body.
+ * The loop needs to go through each page with at least one affected
+ * byte. The lowest page number is (start / page_size) since that
+ * division rounds down. The highest page number we want is the page
+ * where the last byte of the range lives. That last byte has the
+ * address (start + len - 1), thus the highest page number is
+ * (start + len - 1) / page_size. Since we want to include that last
+ * page as well, the loop condition uses <=.
+ */
+ for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
+ /* Byte position of the first byte in the range in this page. */
+ starthere = max(start, i * page_size);
+ /* Length of bytes in the range in this page. */
+ lenhere = min(start + len, (i + 1) * page_size) - starthere;
+ chip_readn(readbuf, bios + starthere, lenhere);
+ for (j = 0; j < lenhere; j++) {
+ if (cmpbuf[starthere - start + j] != readbuf[j]) {
+ fprintf(stderr, "%s FAILED at 0x%08x! "
+ "Expected=0x%02x, Read=0x%02x\n",
+ message, starthere + j,
+ cmpbuf[starthere - start + j], readbuf[j]);
+ ret = -1;
+ goto out_free;
+ }
+ }
+ }
+
+out_free:
+ free(readbuf);
+ return ret;
+}
+
struct flashchip *probe_flash(struct flashchip *first_flash, int force)
{
struct flashchip *flash;
@@ -389,6 +474,9 @@ int erase_flash(struct flashchip *flash)
}
flash->erase(flash);
+ /* FIXME: The lines below are superfluous. We should check the result
+ * of flash->erase(flash) instead.
+ */
if (!flash->read) {
printf("FAILED!\n");
fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
diff --git a/jedec.c b/jedec.c
index 26e9caa7b..711a56d27 100644
--- a/jedec.c
+++ b/jedec.c
@@ -175,8 +175,10 @@ int probe_jedec(struct flashchip *flash)
return 0;
}
-int erase_sector_jedec(chipaddr bios, unsigned int page)
+int erase_sector_jedec(struct flashchip *flash, unsigned int page, int pagesize)
{
+ chipaddr bios = flash->virtual_memory;
+
/* Issue the Sector Erase command */
chip_writeb(0xAA, bios + 0x5555);
programmer_delay(10);
@@ -195,11 +197,17 @@ int erase_sector_jedec(chipaddr bios, unsigned int page)
/* wait for Toggle bit ready */
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, page, pagesize)) {
+ fprintf(stderr,"ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
-int erase_block_jedec(chipaddr bios, unsigned int block)
+int erase_block_jedec(struct flashchip *flash, unsigned int block, int blocksize)
{
+ chipaddr bios = flash->virtual_memory;
+
/* Issue the Sector Erase command */
chip_writeb(0xAA, bios + 0x5555);
programmer_delay(10);
@@ -218,11 +226,16 @@ int erase_block_jedec(chipaddr bios, unsigned int block)
/* wait for Toggle bit ready */
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, block, blocksize)) {
+ fprintf(stderr,"ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
int erase_chip_jedec(struct flashchip *flash)
{
+ int total_size = flash->total_size * 1024;
chipaddr bios = flash->virtual_memory;
/* Issue the JEDEC Chip Erase command */
@@ -242,6 +255,10 @@ int erase_chip_jedec(struct flashchip *flash)
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, 0, total_size)) {
+ fprintf(stderr,"ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -342,15 +359,11 @@ int write_jedec(struct flashchip *flash, uint8_t *buf)
int page_size = flash->page_size;
chipaddr bios = flash->virtual_memory;
- erase_chip_jedec(flash);
- // dumb check if erase was successful.
- for (i = 0; i < total_size; i++) {
- if (chip_readb(bios + i) != 0xff) {
- printf("ERASE FAILED @%d, val %02x!\n", i, chip_readb(bios + i));
- return -1;
- }
+ if (erase_chip_jedec(flash)) {
+ fprintf(stderr,"ERASE FAILED!\n");
+ return -1;
}
-
+
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
printf("%04d at address: 0x%08x", i, i * page_size);
diff --git a/m29f002.c b/m29f002.c
index 8ad86d27c..00cbbc140 100644
--- a/m29f002.c
+++ b/m29f002.c
@@ -31,12 +31,19 @@ int erase_m29f002(struct flashchip *flash)
chip_writeb(0x10, bios + 0x555);
programmer_delay(10);
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, 0, flash->total_size * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
-static void rewrite_block(chipaddr bios, uint8_t *src,
- chipaddr dst, int size)
+static int rewrite_block(struct flashchip *flash, uint8_t *src,
+ unsigned long start, int size)
{
+ chipaddr bios = flash->virtual_memory;
+ chipaddr dst = bios + start;
+
/* erase */
chip_writeb(0xaa, bios + 0x555);
chip_writeb(0x55, bios + 0xaaa);
@@ -46,6 +53,10 @@ static void rewrite_block(chipaddr bios, uint8_t *src,
chip_writeb(0x30, dst);
programmer_delay(10);
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, start, size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
/* program */
while (size--) {
@@ -57,20 +68,24 @@ static void rewrite_block(chipaddr bios, uint8_t *src,
dst++;
src++;
}
+ return 0;
}
-static void do_block(chipaddr bios, uint8_t *src, int i,
+static int do_block(struct flashchip *flash, uint8_t *src, int i,
unsigned long start, int size)
{
+ int ret;
printf("%d at address: 0x%08lx", i, start);
- rewrite_block(bios, src + start, bios + start, size);
+ ret = rewrite_block(flash, src + start, start, size);
+ if (ret)
+ return ret;
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
}
int write_m29f002t(struct flashchip *flash, uint8_t *buf)
{
int i, page_size = flash->page_size;
- chipaddr bios = flash->virtual_memory;
/* M29F002(N)T has 7 blocks. From bottom to top their sizes are:
* 64k 64k 64k 32k 8k 8k 16k
@@ -79,11 +94,11 @@ int write_m29f002t(struct flashchip *flash, uint8_t *buf)
printf("Programming block: ");
for (i = 0; i < 3; i++)
- do_block(bios, buf, i, i * page_size, page_size);
- do_block(bios, buf, i++, 0x30000, 32 * 1024);
- do_block(bios, buf, i++, 0x38000, 8 * 1024);
- do_block(bios, buf, i++, 0x3a000, 8 * 1024);
- do_block(bios, buf, i, 0x3c000, 16 * 1024);
+ do_block(flash, buf, i, i * page_size, page_size);
+ do_block(flash, buf, i++, 0x30000, 32 * 1024);
+ do_block(flash, buf, i++, 0x38000, 8 * 1024);
+ do_block(flash, buf, i++, 0x3a000, 8 * 1024);
+ do_block(flash, buf, i, 0x3c000, 16 * 1024);
printf("\n");
return 0;
@@ -92,7 +107,6 @@ int write_m29f002t(struct flashchip *flash, uint8_t *buf)
int write_m29f002b(struct flashchip *flash, uint8_t *buf)
{
int i = 0, page_size = flash->page_size;
- chipaddr bios = flash->virtual_memory;
/* M29F002B has 7 blocks. From bottom to top their sizes are:
* 16k 8k 8k 32k 64k 64k 64k
@@ -100,12 +114,12 @@ int write_m29f002b(struct flashchip *flash, uint8_t *buf)
*/
printf("Programming block: ");
- do_block(bios, buf, i++, 0x00000, 16 * 1024);
- do_block(bios, buf, i++, 0x04000, 8 * 1024);
- do_block(bios, buf, i++, 0x06000, 8 * 1024);
- do_block(bios, buf, i++, 0x08000, 32 * 1024);
+ do_block(flash, buf, i++, 0x00000, 16 * 1024);
+ do_block(flash, buf, i++, 0x04000, 8 * 1024);
+ do_block(flash, buf, i++, 0x06000, 8 * 1024);
+ do_block(flash, buf, i++, 0x08000, 32 * 1024);
for (; i < 7; i++)
- do_block(bios, buf, i, (i - 3) * page_size, page_size);
+ do_block(flash, buf, i, (i - 3) * page_size, page_size);
printf("\n");
return 0;
diff --git a/m29f400bt.c b/m29f400bt.c
index 85f9dc07f..ace6dae14 100644
--- a/m29f400bt.c
+++ b/m29f400bt.c
@@ -98,11 +98,17 @@ int erase_m29f400bt(struct flashchip *flash)
programmer_delay(10);
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, 0, flash->total_size * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
-int block_erase_m29f400bt(chipaddr bios, chipaddr dst)
+int block_erase_m29f400bt(struct flashchip *flash, int start, int len)
{
+ chipaddr bios = flash->virtual_memory;
+ chipaddr dst = bios + start;
chip_writeb(0xAA, bios + 0xAAA);
chip_writeb(0x55, bios + 0x555);
@@ -116,6 +122,10 @@ int block_erase_m29f400bt(chipaddr bios, chipaddr dst)
programmer_delay(10);
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, start, len)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -146,26 +156,41 @@ int write_m29f400bt(struct flashchip *flash, uint8_t *buf)
printf("total_size/page_size = %d\n", total_size / page_size);
for (i = 0; i < (total_size / page_size) - 1; i++) {
printf("%04d at address: 0x%08x\n", i, i * page_size);
- block_erase_m29f400bt(bios, bios + i * page_size);
+ if (block_erase_m29f400bt(flash, i * page_size, page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + i * page_size,
bios + i * page_size, page_size);
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
}
printf("%04d at address: 0x%08x\n", 7, 0x70000);
- block_erase_m29f400bt(bios, bios + 0x70000);
+ if (block_erase_m29f400bt(flash, 0x70000, 32 * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
printf("%04d at address: 0x%08x\n", 8, 0x78000);
- block_erase_m29f400bt(bios, bios + 0x78000);
+ if (block_erase_m29f400bt(flash, 0x78000, 8 * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
printf("%04d at address: 0x%08x\n", 9, 0x7a000);
- block_erase_m29f400bt(bios, bios + 0x7a000);
+ if (block_erase_m29f400bt(flash, 0x7a000, 8 * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
printf("%04d at address: 0x%08x\n", 10, 0x7c000);
- block_erase_m29f400bt(bios, bios + 0x7c000);
+ if (block_erase_m29f400bt(flash, 0x7c000, 16 * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
printf("\n");
@@ -195,19 +220,31 @@ int write_coreboot_m29f400bt(struct flashchip *flash, uint8_t *buf)
* 64 0x00000 0x0ffff BOTTOM
*********************************/
printf("%04d at address: 0x%08x\n", 7, 0x00000);
- block_erase_m29f400bt(bios, bios + 0x00000);
+ if (block_erase_m29f400bt(flash, 0x00000, 64 * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000, 64 * 1024);
printf("%04d at address: 0x%08x\n", 7, 0x10000);
- block_erase_m29f400bt(bios, bios + 0x10000);
+ if (block_erase_m29f400bt(flash, 0x10000, 64 * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000, 64 * 1024);
printf("%04d at address: 0x%08x\n", 7, 0x20000);
- block_erase_m29f400bt(bios, bios + 0x20000);
+ if (block_erase_m29f400bt(flash, 0x20000, 64 * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000, 64 * 1024);
printf("%04d at address: 0x%08x\n", 7, 0x30000);
- block_erase_m29f400bt(bios, bios + 0x30000);
+ if (block_erase_m29f400bt(flash, 0x30000, 64 * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000, 64 * 1024);
printf("\n");
diff --git a/mx29f002.c b/mx29f002.c
index c96cc9310..9d50b00f0 100644
--- a/mx29f002.c
+++ b/mx29f002.c
@@ -71,6 +71,10 @@ int erase_29f002(struct flashchip *flash)
chip_writeb(0x30, bios + 0x3bfff);
#endif
+ if (check_erased_range(flash, 0, flash->total_size * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -83,7 +87,10 @@ int write_29f002(struct flashchip *flash, uint8_t *buf)
chip_writeb(0xF0, bios);
programmer_delay(10);
- erase_29f002(flash);
+ if (erase_29f002(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
//*bios = 0xF0;
#if 1
printf("Programming page: ");
diff --git a/pm29f002.c b/pm29f002.c
index 374582b98..a01df88de 100644
--- a/pm29f002.c
+++ b/pm29f002.c
@@ -27,7 +27,10 @@ int write_pm29f002(struct flashchip *flash, uint8_t *buf)
chipaddr dst = bios;
/* Pm29F002T/B use the same erase method... */
- erase_29f040b(flash);
+ if (erase_29f040b(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
printf("Programming page: ");
for (i = 0; i < total_size; i++) {
diff --git a/pm49fl00x.c b/pm49fl00x.c
index 8129654d8..3b284e6b1 100644
--- a/pm49fl00x.c
+++ b/pm49fl00x.c
@@ -53,7 +53,6 @@ int erase_49fl00x(struct flashchip *flash)
int i;
int total_size = flash->total_size * 1024;
int page_size = flash->page_size;
- chipaddr bios = flash->virtual_memory;
/* unprotected */
write_lockbits_49fl00x(flash->virtual_registers,
@@ -69,7 +68,10 @@ int erase_49fl00x(struct flashchip *flash)
continue;
/* erase the page */
- erase_block_jedec(bios, i * page_size);
+ if (erase_block_jedec(flash, i * page_size, page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
printf("%04d at address: 0x%08x", i, i * page_size);
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
@@ -100,7 +102,10 @@ int write_49fl00x(struct flashchip *flash, uint8_t *buf)
continue;
/* erase the page before programming */
- erase_block_jedec(bios, i * page_size);
+ if (erase_block_jedec(flash, i * page_size, page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
/* write to the sector */
printf("%04d at address: 0x%08x", i, i * page_size);
diff --git a/sb600spi.c b/sb600spi.c
index 10f1cb7af..259ad27be 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -63,7 +63,10 @@ int sb600_spi_write_1(struct flashchip *flash, uint8_t *buf)
/* Erase first */
printf("Erasing flash before programming... ");
- flash->erase(flash);
+ if (flash->erase(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
printf("done.\n");
printf("Programming flash");
diff --git a/sharplhf00l04.c b/sharplhf00l04.c
index 4d652ae2e..53b993156 100644
--- a/sharplhf00l04.c
+++ b/sharplhf00l04.c
@@ -124,6 +124,10 @@ int erase_lhf00l04_block(struct flashchip *flash, int offset)
print_lhf00l04_status(status);
printf("DONE BLOCK 0x%x\n", offset);
+ if (check_erased_range(flash, offset, flash->page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -135,7 +139,10 @@ int erase_lhf00l04(struct flashchip *flash)
printf("total_size is %d; flash->page_size is %d\n",
total_size, flash->page_size);
for (i = 0; i < total_size; i += flash->page_size)
- erase_lhf00l04_block(flash, i);
+ if (erase_lhf00l04_block(flash, i)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
printf("DONE ERASE\n");
return 0;
@@ -161,9 +168,8 @@ int write_lhf00l04(struct flashchip *flash, uint8_t *buf)
int page_size = flash->page_size;
chipaddr bios = flash->virtual_memory;
- erase_lhf00l04(flash);
- if (chip_readb(bios) != 0xff) {
- printf("ERASE FAILED!\n");
+ if (erase_lhf00l04(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
return -1;
}
printf("Programming page: ");
diff --git a/sst28sf040.c b/sst28sf040.c
index bbbdbd3b2..35f8c2770 100644
--- a/sst28sf040.c
+++ b/sst28sf040.c
@@ -54,14 +54,20 @@ static void unprotect_28sf040(chipaddr bios)
tmp = chip_readb(bios + 0x041A);
}
-static int erase_sector_28sf040(chipaddr bios, unsigned long address)
+static int erase_sector_28sf040(struct flashchip *flash, unsigned long address, int sector_size)
{
+ chipaddr bios = flash->virtual_memory;
+
chip_writeb(AUTO_PG_ERASE1, bios);
chip_writeb(AUTO_PG_ERASE2, bios + address);
/* wait for Toggle bit ready */
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, address, sector_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -124,6 +130,10 @@ int erase_28sf040(struct flashchip *flash)
programmer_delay(10);
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, 0, flash->total_size * 1024)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -139,7 +149,10 @@ int write_28sf040(struct flashchip *flash, uint8_t *buf)
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
/* erase the page before programming */
- erase_sector_28sf040(bios, i * page_size);
+ if (erase_sector_28sf040(flash, i * page_size, page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
/* write to the sector */
printf("%04d at address: 0x%08x", i, i * page_size);
diff --git a/sst49lf040.c b/sst49lf040.c
index 1147c928b..ab1c91821 100644
--- a/sst49lf040.c
+++ b/sst49lf040.c
@@ -25,12 +25,14 @@ int erase_49lf040(struct flashchip *flash)
int i;
int total_size = flash->total_size * 1024;
int page_size = flash->page_size;
- chipaddr bios = flash->virtual_memory;
for (i = 0; i < total_size / page_size; i++) {
/* Chip erase only works in parallel programming mode
* for the 49lf040. Use sector-erase instead */
- erase_sector_jedec(bios, i * page_size);
+ if (erase_sector_jedec(flash, i * page_size, page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
}
return 0;
@@ -48,7 +50,10 @@ int write_49lf040(struct flashchip *flash, uint8_t *buf)
/* erase the page before programming
* Chip erase only works in parallel programming mode
* for the 49lf040. Use sector-erase instead */
- erase_sector_jedec(bios, i * page_size);
+ if (erase_sector_jedec(flash, i * page_size, page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
/* write to the sector */
if (i % 10 == 0)
diff --git a/sst49lfxxxc.c b/sst49lfxxxc.c
index 733864cb3..2875d649d 100644
--- a/sst49lfxxxc.c
+++ b/sst49lfxxxc.c
@@ -75,9 +75,10 @@ static int write_lockbits_49lfxxxc(struct flashchip *flash, unsigned char bits)
return 0;
}
-static int erase_sector_49lfxxxc(chipaddr bios, unsigned long address)
+static int erase_sector_49lfxxxc(struct flashchip *flash, unsigned long address, int sector_size)
{
unsigned char status;
+ chipaddr bios = flash->virtual_memory;
chip_writeb(SECTOR_ERASE, bios);
chip_writeb(ERASE, bios + address);
@@ -91,6 +92,10 @@ static int erase_sector_49lfxxxc(chipaddr bios, unsigned long address)
}
} while (!(status & STATUS_WSMS));
+ if (check_erased_range(flash, address, sector_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
@@ -156,7 +161,7 @@ int erase_49lfxxxc(struct flashchip *flash)
write_lockbits_49lfxxxc(flash, 0);
for (i = 0; i < total_size; i += flash->page_size)
- if (erase_sector_49lfxxxc(bios, i) != 0)
+ if (erase_sector_49lfxxxc(flash, i, flash->page_size))
return (-1);
chip_writeb(RESET, bios);
@@ -175,7 +180,10 @@ int write_49lfxxxc(struct flashchip *flash, uint8_t *buf)
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
/* erase the page before programming */
- erase_sector_49lfxxxc(bios, i * page_size);
+ if (erase_sector_49lfxxxc(flash, i * page_size, flash->page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
/* write to the sector */
printf("%04d at address: 0x%08x", i, i * page_size);
diff --git a/sst_fwhub.c b/sst_fwhub.c
index 5fbacdd3d..e7ae9e93e 100644
--- a/sst_fwhub.c
+++ b/sst_fwhub.c
@@ -94,7 +94,7 @@ int probe_sst_fwhub(struct flashchip *flash)
return 1;
}
-int erase_sst_fwhub_block(struct flashchip *flash, int offset)
+int erase_sst_fwhub_block(struct flashchip *flash, int offset, int page_size)
{
uint8_t blockstatus = clear_sst_fwhub_block_lock(flash, offset);
@@ -104,7 +104,10 @@ int erase_sst_fwhub_block(struct flashchip *flash, int offset)
return 1;
}
- erase_block_jedec(flash->virtual_memory, offset);
+ if (erase_block_jedec(flash, offset, page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
toggle_ready_jedec(flash->virtual_memory);
return 0;
@@ -114,15 +117,10 @@ int erase_sst_fwhub(struct flashchip *flash)
{
int i;
unsigned int total_size = flash->total_size * 1024;
- chipaddr bios = flash->virtual_memory;
- for (i = 0; i < total_size; i += flash->page_size)
- erase_sst_fwhub_block(flash, i);
-
- // dumb check if erase was successful.
- for (i = 0; i < total_size; i++) {
- if (chip_readb(bios + i) != 0xff) {
- printf("ERASE FAILED!\n");
+ for (i = 0; i < total_size; i += flash->page_size) {
+ if (erase_sst_fwhub_block(flash, i, flash->page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
return -1;
}
}
@@ -139,8 +137,10 @@ int write_sst_fwhub(struct flashchip *flash, uint8_t *buf)
uint8_t blockstatus;
// FIXME: We want block wide erase instead of ironing the whole chip
- if (erase_sst_fwhub(flash))
+ if (erase_sst_fwhub(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
return -1;
+ }
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
diff --git a/stm50flw0x0x.c b/stm50flw0x0x.c
index a68b9ad4e..30b7d50fd 100644
--- a/stm50flw0x0x.c
+++ b/stm50flw0x0x.c
@@ -164,7 +164,6 @@ int unlock_block_stm50flw0x0x(struct flashchip *flash, int offset)
int erase_block_stm50flw0x0x(struct flashchip *flash, int offset)
{
chipaddr bios = flash->virtual_memory + offset;
- int j;
// clear status register
chip_writeb(0x50, bios);
@@ -176,13 +175,10 @@ int erase_block_stm50flw0x0x(struct flashchip *flash, int offset)
wait_stm50flw0x0x(flash->virtual_memory);
- for (j = 0; j < flash->page_size; j++) {
- if (chip_readb(bios + j) != 0xFF) {
- printf("Erase failed at 0x%x\n", offset + j);
- return -1;
- }
+ if (check_erased_range(flash, offset, flash->page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
}
-
printf("DONE BLOCK 0x%x\n", offset);
return 0;
@@ -231,24 +227,29 @@ int write_page_stm50flw0x0x(chipaddr bios, uint8_t *src,
*/
int erase_stm50flw0x0x(struct flashchip *flash)
{
- int i, rc = 0;
+ int i;
int total_size = flash->total_size * 1024;
int page_size = flash->page_size;
chipaddr bios = flash->virtual_memory;
printf("Erasing page:\n");
- for (i = 0; (i < total_size / page_size) && (rc == 0); i++) {
+ for (i = 0; i < total_size / page_size; i++) {
printf
("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
printf("%04d at address: 0x%08x ", i, i * page_size);
- rc = unlock_block_stm50flw0x0x(flash, i * page_size);
- if (!rc)
- rc = erase_block_stm50flw0x0x(flash, i * page_size);
+ if (unlock_block_stm50flw0x0x(flash, i * page_size)) {
+ fprintf(stderr, "UNLOCK FAILED!\n");
+ return -1;
+ }
+ if (erase_block_stm50flw0x0x(flash, i * page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
}
printf("\n");
protect_stm50flw0x0x(bios);
- return rc;
+ return 0;
}
int write_stm50flw0x0x(struct flashchip *flash, uint8_t * buf)
diff --git a/w39v040c.c b/w39v040c.c
index 48e9bd3d2..7fccd538b 100644
--- a/w39v040c.c
+++ b/w39v040c.c
@@ -60,16 +60,13 @@ int erase_w39v040c(struct flashchip *flash)
{
int i;
unsigned int total_size = flash->total_size * 1024;
- chipaddr bios = flash->virtual_memory;
-
- for (i = 0; i < total_size; i += flash->page_size)
- erase_sector_jedec(flash->virtual_memory, i);
- for (i = 0; i < total_size; i++)
- if (0xff != chip_readb(bios + i)) {
- printf("ERASE FAILED at 0x%08x! Expected=0xff, Read=0x%02x\n", i, chip_readb(bios + i));
+ for (i = 0; i < total_size; i += flash->page_size) {
+ if (erase_sector_jedec(flash, i, flash->page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
return -1;
}
+ }
return 0;
}
@@ -81,8 +78,10 @@ int write_w39v040c(struct flashchip *flash, uint8_t *buf)
int page_size = flash->page_size;
chipaddr bios = flash->virtual_memory;
- if (flash->erase(flash))
+ if (flash->erase(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
return -1;
+ }
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
diff --git a/w39v080fa.c b/w39v080fa.c
index 8dc882a30..31ef15f6b 100644
--- a/w39v080fa.c
+++ b/w39v080fa.c
@@ -142,9 +142,10 @@ int unlock_winbond_fwhub(struct flashchip *flash)
return 0;
}
-static int erase_sector_winbond_fwhub(chipaddr bios,
+static int erase_sector_winbond_fwhub(struct flashchip *flash,
unsigned int sector)
{
+ chipaddr bios = flash->virtual_memory;
/* Remember: too much sleep can waste your day. */
printf("0x%08x\b\b\b\b\b\b\b\b\b\b", sector);
@@ -161,30 +162,30 @@ static int erase_sector_winbond_fwhub(chipaddr bios,
/* wait for Toggle bit ready */
toggle_ready_jedec(bios);
+ if (check_erased_range(flash, sector, flash->page_size)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
return 0;
}
int erase_winbond_fwhub(struct flashchip *flash)
{
int i, total_size = flash->total_size * 1024;
- chipaddr bios = flash->virtual_memory;
unlock_winbond_fwhub(flash);
printf("Erasing: ");
- for (i = 0; i < total_size; i += flash->page_size)
- erase_sector_winbond_fwhub(bios, i);
-
- printf("\n");
-
- for (i = 0; i < total_size; i++) {
- if (chip_readb(bios + i) != 0xff) {
- fprintf(stderr, "Error: Flash chip erase failed at 0x%08x(0x%02x)\n", i, chip_readb(bios + i));
+ for (i = 0; i < total_size; i += flash->page_size) {
+ if (erase_sector_winbond_fwhub(flash, i)) {
+ fprintf(stderr, "ERASE FAILED!\n");
return -1;
}
}
+ printf("\n");
+
return 0;
}
diff --git a/w49f002u.c b/w49f002u.c
index 1c4177a08..d12bc72c5 100644
--- a/w49f002u.c
+++ b/w49f002u.c
@@ -27,7 +27,10 @@ int write_49f002(struct flashchip *flash, uint8_t *buf)
int page_size = flash->page_size;
chipaddr bios = flash->virtual_memory;
- erase_chip_jedec(flash);
+ if (erase_chip_jedec(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
diff --git a/wbsio_spi.c b/wbsio_spi.c
index dce6631a9..8ca0abcb7 100644
--- a/wbsio_spi.c
+++ b/wbsio_spi.c
@@ -196,7 +196,10 @@ int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf)
return 1;
}
- flash->erase(flash);
+ if (flash->erase(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
result = spi_write_enable();
if (result)
return result;