summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 1dc997f..28fa177 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 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 @@ 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 f4242f5..b89eb31 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 25ec836..97e0778 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 bb2c160..fe5826f 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 26e9caa..711a56d 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 8ad86d2..00cbbc1 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 85f9dc0..ace6dae 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 c96cc93..9d50b00 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 374582b..a01df88 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 8129654..3b284e6 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 10f1cb7..259ad27 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 4d652ae..53b9931 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 bbbdbd3..35f8c27 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 1147c92..ab1c918 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 733864c..2875d64 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 5fbacdd..e7ae9e9 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 a68b9ad..30b7d50 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 48e9bd3..7fccd53 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 8dc882a..31ef15f 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 1c4177a..d12bc72 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 dce6631..8ca0abc 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;
OpenPOWER on IntegriCloud