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