On Wed, 15 Jun 2011 16:23:27 -0700 David Hendricks <[email protected]> wrote:
> fyi, the following small errors are made in multiple times (copy + paste?) > in ichspi.c thanks a lot. i can remember that i was distracted a lot while i have done those bits, sorry for stealing your time! please test the attached patch to be applied on top of the last patch set (i.e. 4.2). i don't have an idea about the 0x3a97c timeout yet, but maybe we can get new insights with correct error messages... -- Kind regards/Mit freundlichen Grüßen, Stefan Tauner
>From 640fc0400b5be71ef9976d19533f2f0664e9ee71 Mon Sep 17 00:00:00 2001 From: Stefan Tauner <[email protected]> Date: Thu, 16 Jun 2011 16:42:22 +0200 Subject: [PATCH] fixup! add support for Intel Hardware Sequencing Signed-off-by: Stefan Tauner <[email protected]> --- ichspi.c | 160 +++++++++++++++++++++++++++++--------------------------------- 1 files changed, 74 insertions(+), 86 deletions(-) diff --git a/ichspi.c b/ichspi.c index 7865dfb..f6b1bbe 100644 --- a/ichspi.c +++ b/ichspi.c @@ -1138,6 +1138,44 @@ static uint32_t ich_hwseq_get_erase_block_size(unsigned int addr) return dec_berase[enc_berase]; } +/* Polls for Cycle Done Status, Flash Cycle Error or timeout in 10 us intervals. + Resets all error flags in HSFS. + Returns 0 if the cycle completes successfully without errors within + timeout us, 1 on errors. */ +static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout, + unsigned int len) +{ + uint16_t hsfs; + uint32_t addr; + + while ((((hsfs = REGREAD16(ICH9_REG_HSFS)) & + (HSFS_FDONE | HSFS_FCERR)) == 0) && + --timeout) { + programmer_delay(10); + } + REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS)); + if (!timeout) { + addr = REGREAD32(ICH9_REG_FADDR); + msg_perr("Timeout error between offset 0x%06x and " + "0x%06x + %d (=0x%06x)!\n", + addr, addr, len - 1, addr + len - 1); + prettyprint_ich9_reg_hsfs(hsfs); + prettyprint_ich9_reg_hsfc(REGREAD16(ICH9_REG_HSFC)); + return 1; + } + + if (hsfs & HSFS_FCERR) { + addr = REGREAD32(ICH9_REG_FADDR); + msg_perr("Transaction error between offset 0x%06x and " + "0x%06x + %d (=0x%06x)!\n", + addr, addr, len - 1, addr + len - 1); + prettyprint_ich9_reg_hsfs(hsfs); + prettyprint_ich9_reg_hsfc(REGREAD16(ICH9_REG_HSFC)); + return 1; + } + return 0; +} + int ich_hwseq_probe(struct flashchip *flash) { uint32_t total_size, boundary; @@ -1224,7 +1262,6 @@ int ich_hwseq_block_erase(struct flashchip *flash, { uint32_t erase_block; uint32_t hsfc; - uint32_t hsfs; uint32_t timeout = 5000 * 1000; /* 5 s for max 64 kB */ if (flash->manufacture_id != INTEL_ID || @@ -1238,10 +1275,7 @@ int ich_hwseq_block_erase(struct flashchip *flash, if (len != erase_block) { msg_cerr("Erase block size for address 0x%06x is %d B, " "but requested erase block size is %d B. " - "Not erasing anything.\n", - addr, - erase_block, - len); + "Not erasing anything.\n", addr, erase_block, len); return -1; } @@ -1250,53 +1284,37 @@ int ich_hwseq_block_erase(struct flashchip *flash, if (addr % erase_block != 0) { msg_cerr("Erase address 0x%06x is not aligned to the erase " "block boundary (any multiple of %d). " - "Not erasing anything.\n", - addr, - erase_block); + "Not erasing anything.\n", addr, erase_block); return -1; } - msg_pdbg("Erasing %d bytes starting at 0x%06x\n", len, addr); + if (addr < 0 || addr + len > 0x00FFFFFF) { + msg_perr("Request to erase some inaccessible memory address(es)" + " (addr=0x%x, len=%d). " + "Not erasing anything.\n", addr, len); + return -1; + } + + msg_pdbg("Erasing %d bytes starting at 0x%06x.\n", len, addr); - hsfc = REGREAD16(ICH9_REG_HSFC); /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ - REGWRITE16(ICH9_REG_HSFC, hsfc); + REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS)); + + hsfc = REGREAD16(ICH9_REG_HSFC); hsfc &= ~HSFC_FCYCLE; /* clear operation */ hsfc = (0x11 << HSFC_FCYCLE_OFF); /* set erase operation */ hsfc |= HSFC_FGO; /* start */ REGWRITE16(ICH9_REG_HSFC, hsfc); - /* Wait for Cycle Done Status or Flash Cycle Error. */ - while (((REGREAD16(ICH9_REG_HSFS) & - (HSFS_FDONE | HSFS_FCERR)) == 0) && - --timeout) { - programmer_delay(10); - } - hsfs = REGREAD16(ICH9_REG_HSFS); - if (!timeout) { - msg_perr("timeout!\n"); - prettyprint_ich9_reg_hsfs(hsfs); - prettyprint_ich9_reg_hsfc(hsfs); - return 1; - } - - REGWRITE16(ICH9_REG_HSFS, hsfs); /* clear all error bits */ - if (hsfs & HSFS_FCERR) { - msg_perr("Transaction error between offset 0x%06x and 0x%06x + " - "%d (=0x%06x)!\n", - addr, addr, len, addr+len); - prettyprint_ich9_reg_hsfs(hsfs); - prettyprint_ich9_reg_hsfc(hsfs); + if (ich_hwseq_wait_for_cycle_complete(timeout, len)) return 1; - } return 0; } int ich_hwseq_read(struct flashchip *flash, uint8_t *buf, int addr, int len) { uint32_t *buf32 = (uint32_t *)buf; - uint16_t hsfc = REGREAD16(ICH9_REG_HSFC); - uint16_t hsfs; + uint16_t hsfc; uint16_t timeout = 100 * 60; int i; @@ -1313,11 +1331,18 @@ int ich_hwseq_read(struct flashchip *flash, uint8_t *buf, int addr, int len) return -1; } - msg_pdbg("reading %d bytes starting at 0x%06x\n", len, addr); + if (addr < 0 || addr + len > 0x00FFFFFF) { + msg_perr("Request to read from inaccessible memory address " + "(addr=0x%x, len=%d).\n", addr, len); + return -1; + } + + msg_pdbg("Reading %d bytes starting at 0x%06x.\n", len, addr); /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ - REGWRITE16(ICH9_REG_HSFC, hsfc); + REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS)); for (i = 0; i < len; i += 4) { + /* FIXME: reserved bits */ REGWRITE32(ICH9_REG_FADDR, (addr & 0x00FFFFFF)); hsfc = REGREAD16(ICH9_REG_HSFC); hsfc &= ~HSFC_FCYCLE; /* set read operation */ @@ -1326,30 +1351,8 @@ int ich_hwseq_read(struct flashchip *flash, uint8_t *buf, int addr, int len) hsfc |= HSFC_FGO; /* start */ REGWRITE16(ICH9_REG_HSFC, hsfc); - /* Wait for Cycle Done Status or Flash Cycle Error. */ - while (((REGREAD16(ICH9_REG_HSFS) & - (HSFS_FDONE | HSFS_FCERR)) == 0) && - --timeout) { - programmer_delay(10); - } - hsfs = REGREAD16(ICH9_REG_HSFS); - if (!timeout) { - msg_perr("timeout!\n"); - prettyprint_ich9_reg_hsfs(hsfs); - prettyprint_ich9_reg_hsfc(hsfs); + if (ich_hwseq_wait_for_cycle_complete(timeout, 4)) return 1; - } - - REGWRITE16(ICH9_REG_HSFS, hsfs); /* clear all error bits */ - if (hsfs & HSFS_FCERR) { - msg_perr("Transaction error between offset 0x%06x and " - "0x%06x + %d (= 0x%06x)!\n", - addr, addr, 4, addr + 4); - prettyprint_ich9_reg_hsfs(hsfs); - prettyprint_ich9_reg_hsfc(hsfs); - return 1; - } - *buf32++ = REGREAD32(ICH9_REG_FDATA0); addr += 4; } @@ -1359,8 +1362,7 @@ int ich_hwseq_read(struct flashchip *flash, uint8_t *buf, int addr, int len) int ich_hwseq_write_256(struct flashchip *flash, uint8_t *buf, int addr, int len) { uint32_t *buf32 = (uint32_t *)buf; - uint16_t hsfc = REGREAD16(ICH9_REG_HSFC); - uint16_t hsfs; + uint16_t hsfc; uint16_t timeout = 100 * 60; int i; if (flash->manufacture_id != INTEL_ID || @@ -1376,11 +1378,18 @@ int ich_hwseq_write_256(struct flashchip *flash, uint8_t *buf, int addr, int len return -1; } - msg_pdbg("writing %d bytes starting at 0x%06x\n", len, addr); + if (addr < 0 || addr + len > 0x00FFFFFF) { + msg_perr("Request to write to inaccessible memory address " + "(addr=0x%x, len=%d).\n", addr, len); + return -1; + } + + msg_pdbg("Writing %d bytes starting at 0x%06x.\n", len, addr); /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ - REGWRITE16(ICH9_REG_HSFC, hsfc); + REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS)); for (i = 0; i < len; i += 4) { + /* FIXME: reserved bits */ REGWRITE32(ICH9_REG_FADDR, (addr & 0x00FFFFFF)); REGWRITE32(ICH9_REG_FDATA0, *buf32++); hsfc = REGREAD16(ICH9_REG_HSFC); @@ -1391,29 +1400,8 @@ int ich_hwseq_write_256(struct flashchip *flash, uint8_t *buf, int addr, int len hsfc |= HSFC_FGO; /* start */ REGWRITE16(ICH9_REG_HSFC, hsfc); - /* Wait for Cycle Done Status or Flash Cycle Error. */ - while (((REGREAD16(ICH9_REG_HSFS) & - (HSFS_FDONE | HSFS_FCERR)) == 0) && - --timeout) { - programmer_delay(10); - } - hsfs = REGREAD16(ICH9_REG_HSFS); - if (!timeout) { - msg_perr("timeout!\n"); - prettyprint_ich9_reg_hsfs(hsfs); - prettyprint_ich9_reg_hsfc(hsfs); + if (ich_hwseq_wait_for_cycle_complete(timeout, 4)) return 1; - } - - REGWRITE16(ICH9_REG_HSFS, hsfs); /* clear all error bits */ - if (hsfs & HSFS_FCERR) { - msg_perr("Transaction error between offset 0x%06x and " - "0x%06x + %d (= 0x%06x)!\n", - addr, addr, 4, addr + 4); - prettyprint_ich9_reg_hsfs(hsfs); - prettyprint_ich9_reg_hsfc(hsfs); - return 1; - } addr += 4; } return 0; -- 1.7.1
_______________________________________________ flashrom mailing list [email protected] http://www.flashrom.org/mailman/listinfo/flashrom
