Author: hailfinger Date: 2009-06-15 19:23:36 +0200 (Mon, 15 Jun 2009) New Revision: 595
Modified: trunk/82802ab.c trunk/am29f040b.c trunk/en29f002a.c trunk/flash.h trunk/flashrom.c trunk/jedec.c trunk/m29f002.c trunk/m29f400bt.c trunk/mx29f002.c trunk/pm29f002.c trunk/pm49fl00x.c trunk/sb600spi.c trunk/sharplhf00l04.c trunk/sst28sf040.c trunk/sst49lf040.c trunk/sst49lfxxxc.c trunk/sst_fwhub.c trunk/stm50flw0x0x.c trunk/w39v040c.c trunk/w39v080fa.c trunk/w49f002u.c trunk/wbsio_spi.c Log: 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.
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
Modified: trunk/82802ab.c =================================================================== --- trunk/82802ab.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/82802ab.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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); }
Modified: trunk/am29f040b.c =================================================================== --- trunk/am29f040b.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/am29f040b.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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);
Modified: trunk/en29f002a.c =================================================================== --- trunk/en29f002a.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/en29f002a.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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++) {
Modified: trunk/flash.h =================================================================== --- trunk/flash.h 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/flash.h 2009-06-15 17:23:36 UTC (rev 595) @@ -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);
Modified: trunk/flashrom.c =================================================================== --- trunk/flashrom.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/flashrom.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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");
Modified: trunk/jedec.c =================================================================== --- trunk/jedec.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/jedec.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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);
Modified: trunk/m29f002.c =================================================================== --- trunk/m29f002.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/m29f002.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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;
Modified: trunk/m29f400bt.c =================================================================== --- trunk/m29f400bt.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/m29f400bt.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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");
Modified: trunk/mx29f002.c =================================================================== --- trunk/mx29f002.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/mx29f002.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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: ");
Modified: trunk/pm29f002.c =================================================================== --- trunk/pm29f002.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/pm29f002.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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++) {
Modified: trunk/pm49fl00x.c =================================================================== --- trunk/pm49fl00x.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/pm49fl00x.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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);
Modified: trunk/sb600spi.c =================================================================== --- trunk/sb600spi.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/sb600spi.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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");
Modified: trunk/sharplhf00l04.c =================================================================== --- trunk/sharplhf00l04.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/sharplhf00l04.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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: ");
Modified: trunk/sst28sf040.c =================================================================== --- trunk/sst28sf040.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/sst28sf040.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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);
Modified: trunk/sst49lf040.c =================================================================== --- trunk/sst49lf040.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/sst49lf040.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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)
Modified: trunk/sst49lfxxxc.c =================================================================== --- trunk/sst49lfxxxc.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/sst49lfxxxc.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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);
Modified: trunk/sst_fwhub.c =================================================================== --- trunk/sst_fwhub.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/sst_fwhub.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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++) {
Modified: trunk/stm50flw0x0x.c =================================================================== --- trunk/stm50flw0x0x.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/stm50flw0x0x.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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)
Modified: trunk/w39v040c.c =================================================================== --- trunk/w39v040c.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/w39v040c.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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++) {
Modified: trunk/w39v080fa.c =================================================================== --- trunk/w39v080fa.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/w39v080fa.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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; }
Modified: trunk/w49f002u.c =================================================================== --- trunk/w49f002u.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/w49f002u.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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++) {
Modified: trunk/wbsio_spi.c =================================================================== --- trunk/wbsio_spi.c 2009-06-15 14:14:48 UTC (rev 594) +++ trunk/wbsio_spi.c 2009-06-15 17:23:36 UTC (rev 595) @@ -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;