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>
diff --git a/82802ab.c b/82802ab.c
index 1dc997f..28fa177 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -110,7 +110,6 @@
{
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 @@
// 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 @@
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 @@
}
/* 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 2dc4c36..7f1269c 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 @@
/* 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 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 @@
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 @@
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 f4242f5..b89eb31 100644
--- a/en29f002a.c
+++ b/en29f002a.c
@@ -98,7 +98,10 @@
//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 25ec836..97e0778 100644
--- a/flash.h
+++ b/flash.h
@@ -364,6 +364,9 @@
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 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 @@
/* 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 bb2c160..fe5826f 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -206,6 +206,11 @@
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 @@
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 @@
}
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 26e9caa..711a56d 100644
--- a/jedec.c
+++ b/jedec.c
@@ -175,8 +175,10 @@
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 @@
/* 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 @@
/* 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 @@
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 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 8ad86d2..00cbbc1 100644
--- a/m29f002.c
+++ b/m29f002.c
@@ -31,12 +31,19 @@
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 @@
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 @@
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 @@
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_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 @@
*/
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 85f9dc0..ace6dae 100644
--- a/m29f400bt.c
+++ b/m29f400bt.c
@@ -98,11 +98,17 @@
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 @@
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 @@
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 @@
* 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 c96cc93..9d50b00 100644
--- a/mx29f002.c
+++ b/mx29f002.c
@@ -71,6 +71,10 @@
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 @@
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 374582b..a01df88 100644
--- a/pm29f002.c
+++ b/pm29f002.c
@@ -27,7 +27,10 @@
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 8129654..3b284e6 100644
--- a/pm49fl00x.c
+++ b/pm49fl00x.c
@@ -53,7 +53,6 @@
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 @@
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 @@
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 10f1cb7..259ad27 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -63,7 +63,10 @@
/* 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 4d652ae..53b9931 100644
--- a/sharplhf00l04.c
+++ b/sharplhf00l04.c
@@ -124,6 +124,10 @@
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 @@
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 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 bbbdbd3..35f8c27 100644
--- a/sst28sf040.c
+++ b/sst28sf040.c
@@ -54,14 +54,20 @@
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 @@
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 @@
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 1147c92..ab1c918 100644
--- a/sst49lf040.c
+++ b/sst49lf040.c
@@ -25,12 +25,14 @@
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 @@
/* 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 733864c..2875d64 100644
--- a/sst49lfxxxc.c
+++ b/sst49lfxxxc.c
@@ -75,9 +75,10 @@
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 @@
}
} 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 @@
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 @@
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 5fbacdd..e7ae9e9 100644
--- a/sst_fwhub.c
+++ b/sst_fwhub.c
@@ -94,7 +94,7 @@
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 @@
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 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 @@
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 a68b9ad..30b7d50 100644
--- a/stm50flw0x0x.c
+++ b/stm50flw0x0x.c
@@ -164,7 +164,6 @@
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 @@
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 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 48e9bd3..7fccd53 100644
--- a/w39v040c.c
+++ b/w39v040c.c
@@ -60,16 +60,13 @@
{
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 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 8dc882a..31ef15f 100644
--- a/w39v080fa.c
+++ b/w39v080fa.c
@@ -142,9 +142,10 @@
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 @@
/* 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 1c4177a..d12bc72 100644
--- a/w49f002u.c
+++ b/w49f002u.c
@@ -27,7 +27,10 @@
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 dce6631..8ca0abc 100644
--- a/wbsio_spi.c
+++ b/wbsio_spi.c
@@ -196,7 +196,10 @@
return 1;
}
- flash->erase(flash);
+ if (flash->erase(flash)) {
+ fprintf(stderr, "ERASE FAILED!\n");
+ return -1;
+ }
result = spi_write_enable();
if (result)
return result;