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