Author: stefanct Date: Wed Aug 6 01:28:47 2014 New Revision: 1837 URL: http://flashrom.org/trac/flashrom/changeset/1837
Log: ichspi: fix missing set_addr on erases and possible crossings of 256 B boundaries.
Apparently the erase function did never set any address before issuing the erase commands. How could this ever work? Also, according to PCH documentation crossing 256 byte boundaries is invalid and may cause wraparound due to the flash chip's pages. Check for this on reads as well as writes.
Thanks to Vladimir 'φ-coder/phcoder' Serbinenko for noticing these issues and providing the initial patch.
Signed-off-by: Stefan Tauner stefan.tauner@alumni.tuwien.ac.at Acked-by: Stefan Tauner stefan.tauner@alumni.tuwien.ac.at
Modified: trunk/ichspi.c
Modified: trunk/ichspi.c ============================================================================== --- trunk/ichspi.c Wed Aug 6 00:16:01 2014 (r1836) +++ trunk/ichspi.c Wed Aug 6 01:28:47 2014 (r1837) @@ -1272,6 +1272,7 @@ }
msg_pdbg("Erasing %d bytes starting at 0x%06x.\n", len, addr); + ich_hwseq_set_addr(addr);
/* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS)); @@ -1307,7 +1308,11 @@ REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS));
while (len > 0) { + /* Obey programmer limit... */ block_len = min(len, flash->mst->opaque.max_data_read); + /* as well as flash chip page borders as demanded in the Intel datasheets. */ + block_len = min(block_len, 256 - (addr & 0xFF)); + ich_hwseq_set_addr(addr); hsfc = REGREAD16(ICH9_REG_HSFC); hsfc &= ~HSFC_FCYCLE; /* set read operation */ @@ -1345,7 +1350,10 @@
while (len > 0) { ich_hwseq_set_addr(addr); + /* Obey programmer limit... */ block_len = min(len, flash->mst->opaque.max_data_write); + /* as well as flash chip page borders as demanded in the Intel datasheets. */ + block_len = min(block_len, 256 - (addr & 0xFF)); ich_fill_data(buf, block_len, ICH9_REG_FDATA0); hsfc = REGREAD16(ICH9_REG_HSFC); hsfc &= ~HSFC_FCYCLE; /* clear operation */