From 353501580cf044c7645874ef6bad63bd478c81b2 Mon Sep 17 00:00:00 2001 From: stefanct Date: Tue, 5 Aug 2014 23:28:47 +0000 Subject: ichspi: fix missing set_addr on erases and possible crossings of 256 B boundaries. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Acked-by: Stefan Tauner git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@1837 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- ichspi.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ichspi.c') diff --git a/ichspi.c b/ichspi.c index 90bb0de..5d37d06 100644 --- a/ichspi.c +++ b/ichspi.c @@ -1272,6 +1272,7 @@ static int ich_hwseq_block_erase(struct flashctx *flash, unsigned int addr, } 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 @@ static int ich_hwseq_read(struct flashctx *flash, uint8_t *buf, 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 @@ static int ich_hwseq_write(struct flashctx *flash, const uint8_t *buf, unsigned 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 */ -- cgit v1.2.1