Erasing Confirmed working on my hardware : chip-set : "Intel ICH7M" chip : "SST SST25VF080B"
Output image is now completely full of 0xFF (s) Regards -- Ali Nadalizadeh On Thu, May 7, 2009 at 4:48 PM, Carl-Daniel Hailfinger < c-d.hailfinger.devel.2...@gmx.net> wrote: > On 07.05.2009 13:44, Carl-Daniel Hailfinger wrote: > > Until the ICH SPI driver can handle preopcodes as standalone opcodes, we > > should handle such special opcode failure gracefully on ICH and > > compatible chipsets. > > > > This fixes chip erase on almost all ICH+VIA SPI masters. > > > > Thanks to Ali Nadalizadeh for helping track down this bug! > > > > Improved version, refactored to isolate the impact to a single function. > > As a bonus, all invocations of spi_write_enable() now have error checking. > > Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2...@gmx.net> > > Index: flashrom-spi_write_enable_error_checking/it87spi.c > =================================================================== > --- flashrom-spi_write_enable_error_checking/it87spi.c (Revision 471) > +++ flashrom-spi_write_enable_error_checking/it87spi.c (Arbeitskopie) > @@ -196,11 +196,14 @@ > } > > /* Page size is usually 256 bytes */ > -static void it8716f_spi_page_program(int block, uint8_t *buf, uint8_t > *bios) > +static int it8716f_spi_page_program(int block, uint8_t *buf, uint8_t > *bios) > { > int i; > + int result; > > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > OUTB(0x06, it8716f_flashport + 1); > OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport); > for (i = 0; i < 256; i++) { > @@ -212,6 +215,7 @@ > */ > while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) > usleep(1000); > + return 0; > } > > /* > @@ -222,12 +226,15 @@ > { > int total_size = 1024 * flash->total_size; > int i; > + int result; > > fast_spi = 0; > > spi_disable_blockprotect(); > for (i = 0; i < total_size; i++) { > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > spi_byte_program(i, buf[i]); > while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) > myusec_delay(10); > Index: flashrom-spi_write_enable_error_checking/spi.c > =================================================================== > --- flashrom-spi_write_enable_error_checking/spi.c (Revision 471) > +++ flashrom-spi_write_enable_error_checking/spi.c (Arbeitskopie) > @@ -88,9 +88,24 @@ > int spi_write_enable(void) > { > const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN }; > + int result; > > /* Send WREN (Write Enable) */ > - return spi_command(sizeof(cmd), 0, cmd, NULL); > + result = spi_command(sizeof(cmd), 0, cmd, NULL); > + if (result) { > + printf_debug("spi_write_enable failed"); > + switch (flashbus) { > + case BUS_TYPE_ICH7_SPI: > + case BUS_TYPE_ICH9_SPI: > + case BUS_TYPE_VIA_SPI: > + printf_debug(" due to SPI master limitation, > ignoring" > + " and hoping it will be run as > PREOP\n"); > + return 0; > + default: > + printf_debug("\n"); > + } > + } > + return result; > } > > int spi_write_disable(void) > @@ -361,10 +376,8 @@ > return result; > } > result = spi_write_enable(); > - if (result) { > - printf_debug("spi_write_enable failed\n"); > + if (result) > return result; > - } > /* Send CE (Chip Erase) */ > result = spi_command(sizeof(cmd), 0, cmd, NULL); > if (result) { > @@ -391,10 +404,8 @@ > return result; > } > result = spi_write_enable(); > - if (result) { > - printf_debug("spi_write_enable failed\n"); > + if (result) > return result; > - } > /* Send CE (Chip Erase) */ > result = spi_command(sizeof(cmd), 0, cmd, NULL); > if (result) { > @@ -424,11 +435,14 @@ > int spi_block_erase_52(const struct flashchip *flash, unsigned long addr) > { > unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52}; > + int result; > > cmd[1] = (addr & 0x00ff0000) >> 16; > cmd[2] = (addr & 0x0000ff00) >> 8; > cmd[3] = (addr & 0x000000ff); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > /* Send BE (Block Erase) */ > spi_command(sizeof(cmd), 0, cmd, NULL); > /* Wait until the Write-In-Progress bit is cleared. > @@ -447,11 +461,14 @@ > int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr) > { > unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8 }; > + int result; > > cmd[1] = (addr & 0x00ff0000) >> 16; > cmd[2] = (addr & 0x0000ff00) >> 8; > cmd[3] = (addr & 0x000000ff); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > /* Send BE (Block Erase) */ > spi_command(sizeof(cmd), 0, cmd, NULL); > /* Wait until the Write-In-Progress bit is cleared. > @@ -489,11 +506,15 @@ > int spi_sector_erase(const struct flashchip *flash, unsigned long addr) > { > unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE }; > + int result; > + > cmd[1] = (addr & 0x00ff0000) >> 16; > cmd[2] = (addr & 0x0000ff00) >> 8; > cmd[3] = (addr & 0x000000ff); > > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > /* Send SE (Sector Erase) */ > spi_command(sizeof(cmd), 0, cmd, NULL); > /* Wait until the Write-In-Progress bit is cleared. > @@ -623,6 +644,8 @@ > { > uint32_t pos = 2, size = flash->total_size * 1024; > unsigned char w[6] = {0xad, 0, 0, 0, buf[0], buf[1]}; > + int result; > + > switch (flashbus) { > case BUS_TYPE_WBSIO_SPI: > fprintf(stderr, "%s: impossible with Winbond SPI masters," > @@ -632,7 +655,9 @@ > break; > } > flash->erase(flash); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > spi_command(6, 0, w, NULL); > while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) > myusec_delay(5); /* SST25VF040B Tbp is max 10us */ > Index: flashrom-spi_write_enable_error_checking/wbsio_spi.c > =================================================================== > --- flashrom-spi_write_enable_error_checking/wbsio_spi.c (Revision > 471) > +++ flashrom-spi_write_enable_error_checking/wbsio_spi.c > (Arbeitskopie) > @@ -189,6 +189,7 @@ > int wbsio_spi_write(struct flashchip *flash, uint8_t *buf) > { > int pos, size = flash->total_size * 1024; > + int result; > > if (flash->total_size > 1024) { > fprintf(stderr, "%s: Winbond saved on 4 register bits so max > chip size is 1024 KB!\n", __func__); > @@ -196,7 +197,9 @@ > } > > flash->erase(flash); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > for (pos = 0; pos < size; pos++) { > spi_byte_program(pos, buf[pos]); > while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) > Index: flashrom-spi_write_enable_error_checking/sb600spi.c > =================================================================== > --- flashrom-spi_write_enable_error_checking/sb600spi.c (Revision 471) > +++ flashrom-spi_write_enable_error_checking/sb600spi.c (Arbeitskopie) > @@ -68,6 +68,7 @@ > { > int rc = 0, i; > int total_size = flash->total_size * 1024; > + int result; > > /* Erase first */ > printf("Erasing flash before programming... "); > @@ -77,7 +78,9 @@ > printf("Programming flash"); > for (i = 0; i < total_size; i++, buf++) { > spi_disable_blockprotect(); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > spi_byte_program(i, *buf); > /* wait program complete. */ > if (i % 0x8000 == 0) > > > -- > http://www.hailfinger.org/ > > > Index: flashrom-spi_write_enable_error_checking/it87spi.c > =================================================================== > --- flashrom-spi_write_enable_error_checking/it87spi.c (Revision 471) > +++ flashrom-spi_write_enable_error_checking/it87spi.c (Arbeitskopie) > @@ -196,11 +196,14 @@ > } > > /* Page size is usually 256 bytes */ > -static void it8716f_spi_page_program(int block, uint8_t *buf, uint8_t > *bios) > +static int it8716f_spi_page_program(int block, uint8_t *buf, uint8_t > *bios) > { > int i; > + int result; > > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > OUTB(0x06, it8716f_flashport + 1); > OUTB(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport); > for (i = 0; i < 256; i++) { > @@ -212,6 +215,7 @@ > */ > while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) > usleep(1000); > + return 0; > } > > /* > @@ -222,12 +226,15 @@ > { > int total_size = 1024 * flash->total_size; > int i; > + int result; > > fast_spi = 0; > > spi_disable_blockprotect(); > for (i = 0; i < total_size; i++) { > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > spi_byte_program(i, buf[i]); > while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) > myusec_delay(10); > Index: flashrom-spi_write_enable_error_checking/spi.c > =================================================================== > --- flashrom-spi_write_enable_error_checking/spi.c (Revision 471) > +++ flashrom-spi_write_enable_error_checking/spi.c (Arbeitskopie) > @@ -88,9 +88,24 @@ > int spi_write_enable(void) > { > const unsigned char cmd[JEDEC_WREN_OUTSIZE] = { JEDEC_WREN }; > + int result; > > /* Send WREN (Write Enable) */ > - return spi_command(sizeof(cmd), 0, cmd, NULL); > + result = spi_command(sizeof(cmd), 0, cmd, NULL); > + if (result) { > + printf_debug("spi_write_enable failed"); > + switch (flashbus) { > + case BUS_TYPE_ICH7_SPI: > + case BUS_TYPE_ICH9_SPI: > + case BUS_TYPE_VIA_SPI: > + printf_debug(" due to SPI master limitation, > ignoring" > + " and hoping it will be run as > PREOP\n"); > + return 0; > + default: > + printf_debug("\n"); > + } > + } > + return result; > } > > int spi_write_disable(void) > @@ -361,10 +376,8 @@ > return result; > } > result = spi_write_enable(); > - if (result) { > - printf_debug("spi_write_enable failed\n"); > + if (result) > return result; > - } > /* Send CE (Chip Erase) */ > result = spi_command(sizeof(cmd), 0, cmd, NULL); > if (result) { > @@ -391,10 +404,8 @@ > return result; > } > result = spi_write_enable(); > - if (result) { > - printf_debug("spi_write_enable failed\n"); > + if (result) > return result; > - } > /* Send CE (Chip Erase) */ > result = spi_command(sizeof(cmd), 0, cmd, NULL); > if (result) { > @@ -424,11 +435,14 @@ > int spi_block_erase_52(const struct flashchip *flash, unsigned long addr) > { > unsigned char cmd[JEDEC_BE_52_OUTSIZE] = {JEDEC_BE_52}; > + int result; > > cmd[1] = (addr & 0x00ff0000) >> 16; > cmd[2] = (addr & 0x0000ff00) >> 8; > cmd[3] = (addr & 0x000000ff); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > /* Send BE (Block Erase) */ > spi_command(sizeof(cmd), 0, cmd, NULL); > /* Wait until the Write-In-Progress bit is cleared. > @@ -447,11 +461,14 @@ > int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr) > { > unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = { JEDEC_BE_D8 }; > + int result; > > cmd[1] = (addr & 0x00ff0000) >> 16; > cmd[2] = (addr & 0x0000ff00) >> 8; > cmd[3] = (addr & 0x000000ff); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > /* Send BE (Block Erase) */ > spi_command(sizeof(cmd), 0, cmd, NULL); > /* Wait until the Write-In-Progress bit is cleared. > @@ -489,11 +506,15 @@ > int spi_sector_erase(const struct flashchip *flash, unsigned long addr) > { > unsigned char cmd[JEDEC_SE_OUTSIZE] = { JEDEC_SE }; > + int result; > + > cmd[1] = (addr & 0x00ff0000) >> 16; > cmd[2] = (addr & 0x0000ff00) >> 8; > cmd[3] = (addr & 0x000000ff); > > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > /* Send SE (Sector Erase) */ > spi_command(sizeof(cmd), 0, cmd, NULL); > /* Wait until the Write-In-Progress bit is cleared. > @@ -623,6 +644,8 @@ > { > uint32_t pos = 2, size = flash->total_size * 1024; > unsigned char w[6] = {0xad, 0, 0, 0, buf[0], buf[1]}; > + int result; > + > switch (flashbus) { > case BUS_TYPE_WBSIO_SPI: > fprintf(stderr, "%s: impossible with Winbond SPI masters," > @@ -632,7 +655,9 @@ > break; > } > flash->erase(flash); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > spi_command(6, 0, w, NULL); > while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) > myusec_delay(5); /* SST25VF040B Tbp is max 10us */ > Index: flashrom-spi_write_enable_error_checking/wbsio_spi.c > =================================================================== > --- flashrom-spi_write_enable_error_checking/wbsio_spi.c (Revision > 471) > +++ flashrom-spi_write_enable_error_checking/wbsio_spi.c > (Arbeitskopie) > @@ -189,6 +189,7 @@ > int wbsio_spi_write(struct flashchip *flash, uint8_t *buf) > { > int pos, size = flash->total_size * 1024; > + int result; > > if (flash->total_size > 1024) { > fprintf(stderr, "%s: Winbond saved on 4 register bits so max > chip size is 1024 KB!\n", __func__); > @@ -196,7 +197,9 @@ > } > > flash->erase(flash); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > for (pos = 0; pos < size; pos++) { > spi_byte_program(pos, buf[pos]); > while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) > Index: flashrom-spi_write_enable_error_checking/sb600spi.c > =================================================================== > --- flashrom-spi_write_enable_error_checking/sb600spi.c (Revision 471) > +++ flashrom-spi_write_enable_error_checking/sb600spi.c (Arbeitskopie) > @@ -68,6 +68,7 @@ > { > int rc = 0, i; > int total_size = flash->total_size * 1024; > + int result; > > /* Erase first */ > printf("Erasing flash before programming... "); > @@ -77,7 +78,9 @@ > printf("Programming flash"); > for (i = 0; i < total_size; i++, buf++) { > spi_disable_blockprotect(); > - spi_write_enable(); > + result = spi_write_enable(); > + if (result) > + return result; > spi_byte_program(i, *buf); > /* wait program complete. */ > if (i % 0x8000 == 0) > > -- > coreboot mailing list: coreboot@coreboot.org > http://www.coreboot.org/mailman/listinfo/coreboot >
-- coreboot mailing list: coreboot@coreboot.org http://www.coreboot.org/mailman/listinfo/coreboot