diff options
author | Stefan Reinauer <stepan@coresystems.de> | 2008-11-02 19:51:50 +0000 |
---|---|---|
committer | Stefan Reinauer <stepan@openbios.org> | 2008-11-02 19:51:50 +0000 |
commit | d22ef49783c60297f775f3c0136ad0d3e36ab495 (patch) | |
tree | 742621674b8e2f81f06e0a3b91ac1902ac10e6ff /util | |
parent | 54c5276c3aa9496b385097f314a6ee9abd8072d0 (diff) | |
download | coreboot-d22ef49783c60297f775f3c0136ad0d3e36ab495.tar.xz |
Drop nr/opcode_index parameter from run_opcode and search the opmenu for the opcode instead.
This is slightly slower (ha, ha), but works on boards with a locked opmenu. Tested on ICH7 and works.
Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3721 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'util')
-rw-r--r-- | util/flashrom/ichspi.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/util/flashrom/ichspi.c b/util/flashrom/ichspi.c index 095d53a222..74ce3f0c24 100644 --- a/util/flashrom/ichspi.c +++ b/util/flashrom/ichspi.c @@ -148,7 +148,7 @@ static inline uint16_t REGREAD16(int X) /* Common SPI functions */ static int program_opcodes(OPCODES * op); -static int run_opcode(uint8_t nr, OPCODE op, uint32_t offset, +static int run_opcode(OPCODE op, uint32_t offset, uint8_t datalength, uint8_t * data); static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, int offset, int maxdata); @@ -225,7 +225,7 @@ int program_opcodes(OPCODES * op) return 0; } -static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, +static int ich7_run_opcode(OPCODE op, uint32_t offset, uint8_t datalength, uint8_t * data, int maxdata) { int write_cmd = 0; @@ -233,6 +233,8 @@ static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, uint32_t temp32 = 0; uint16_t temp16; uint32_t a; + uint64_t opmenu; + int opcode_index; /* Is it a write command? */ if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS) @@ -280,7 +282,20 @@ static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, } /* Select opcode */ - temp16 |= ((uint16_t) (nr & 0x07)) << 4; + opmenu = REGREAD32(ICH7_REG_OPMENU); + opmenu |= ((uint64_t)REGREAD32(ICH7_REG_OPMENU + 4)) << 32; + + for (opcode_index=0; opcode_index<8; opcode_index++) { + if((opmenu & 0xff) == op.opcode) { + break; + } + opmenu >>= 8; + } + if (opcode_index == 8) { + printf_debug("Opcode %x not found.\n", op.opcode); + return 1; + } + temp16 |= ((uint16_t) (opcode_index & 0x07)) << 4; /* Handle Atomic */ if (op.atomic != 0) { @@ -328,13 +343,15 @@ static int ich7_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, return 0; } -static int ich9_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, +static int ich9_run_opcode(OPCODE op, uint32_t offset, uint8_t datalength, uint8_t * data) { int write_cmd = 0; int timeout; uint32_t temp32; uint32_t a; + uint64_t opmenu; + int opcode_index; /* Is it a write command? */ if ((op.spi_type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS) @@ -383,7 +400,20 @@ static int ich9_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, } /* Select opcode */ - temp32 |= ((uint32_t) (nr & 0x07)) << (8 + 4); + opmenu = REGREAD32(ICH9_REG_OPMENU); + opmenu |= ((uint64_t)REGREAD32(ICH9_REG_OPMENU + 4)) << 32; + + for (opcode_index=0; opcode_index<8; opcode_index++) { + if((opmenu & 0xff) == op.opcode) { + break; + } + opmenu >>= 8; + } + if (opcode_index == 8) { + printf_debug("Opcode %x not found.\n", op.opcode); + return 1; + } + temp32 |= ((uint32_t) (opcode_index & 0x07)) << (8 + 4); /* Handle Atomic */ if (op.atomic != 0) { @@ -431,16 +461,16 @@ static int ich9_run_opcode(uint8_t nr, OPCODE op, uint32_t offset, return 0; } -static int run_opcode(uint8_t nr, OPCODE op, uint32_t offset, +static int run_opcode(OPCODE op, uint32_t offset, uint8_t datalength, uint8_t * data) { switch (flashbus) { case BUS_TYPE_VIA_SPI: - return ich7_run_opcode(nr, op, offset, datalength, data, 16); + return ich7_run_opcode(op, offset, datalength, data, 16); case BUS_TYPE_ICH7_SPI: - return ich7_run_opcode(nr, op, offset, datalength, data, 64); + return ich7_run_opcode(op, offset, datalength, data, 64); case BUS_TYPE_ICH9_SPI: - return ich9_run_opcode(nr, op, offset, datalength, data); + return ich9_run_opcode(op, offset, datalength, data); default: printf_debug("%s: unsupported chipset\n", __FUNCTION__); } @@ -453,7 +483,7 @@ static int ich_spi_erase_block(struct flashchip *flash, int offset) { printf_debug("ich_spi_erase_block: offset=%d, sectors=%d\n", offset, 1); - if (run_opcode(2, curopcodes->opcode[2], offset, 0, NULL) != 0) { + if (run_opcode(curopcodes->opcode[2], offset, 0, NULL) != 0) { printf_debug("Error erasing sector at 0x%x", offset); return -1; } @@ -477,7 +507,7 @@ static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, int offset, if (remaining < maxdata) { if (run_opcode - (1, curopcodes->opcode[1], + (curopcodes->opcode[1], offset + (page_size - remaining), remaining, &buf[page_size - remaining]) != 0) { printf_debug("Error reading"); @@ -486,7 +516,7 @@ static int ich_spi_read_page(struct flashchip *flash, uint8_t * buf, int offset, remaining = 0; } else { if (run_opcode - (1, curopcodes->opcode[1], + (curopcodes->opcode[1], offset + (page_size - remaining), maxdata, &buf[page_size - remaining]) != 0) { printf_debug("Error reading"); @@ -512,7 +542,7 @@ static int ich_spi_write_page(struct flashchip *flash, uint8_t * bytes, for (a = 0; a < page_size; a += maxdata) { if (remaining < maxdata) { if (run_opcode - (0, curopcodes->opcode[0], + (curopcodes->opcode[0], offset + (page_size - remaining), remaining, &bytes[page_size - remaining]) != 0) { printf_debug("Error writing"); @@ -521,7 +551,7 @@ static int ich_spi_write_page(struct flashchip *flash, uint8_t * bytes, remaining = 0; } else { if (run_opcode - (0, curopcodes->opcode[0], + (curopcodes->opcode[0], offset + (page_size - remaining), maxdata, &bytes[page_size - remaining]) != 0) { printf_debug("Error writing"); @@ -641,7 +671,7 @@ int ich_spi_command(unsigned int writecnt, unsigned int readcnt, count = readcnt; } - if (run_opcode(opcode_index, *opcode, addr, count, data) != 0) { + if (run_opcode(*opcode, addr, count, data) != 0) { printf_debug("run OPCODE 0x%02x failed\n", opcode->opcode); return 1; } |