Some Parallel bus chips have a 16-bit mode and an 8-bit mode. They use normal JEDEC addresses for 16-bit mode and shifted addresses (by 1 bit) for 8-bit mode. Some programmers can access them in 16-bit mode, but on all flashrom-supported programmers so far, we access them in 8-bit mode. This means we have to shift the addresses.
Untested, should work. This is a patch written shortly after r886 was committed, and it has been forward-ported. Missing from this patch is the deletion of now-unused code.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-jedec_shifted/jedec.c =================================================================== --- flashrom-jedec_shifted/jedec.c (Revision 1818) +++ flashrom-jedec_shifted/jedec.c (Arbeitskopie) @@ -4,7 +4,7 @@ * Copyright (C) 2000 Silicon Integrated System Corporation * Copyright (C) 2006 Giampiero Giancipoli gianci@email.it * Copyright (C) 2006 coresystems GmbH info@coresystems.de - * Copyright (C) 2007 Carl-Daniel Hailfinger + * Copyright (C) 2007-2012 Carl-Daniel Hailfinger * Copyright (C) 2009 Sean Nelson audiohacked@gmail.com * * This program is free software; you can redistribute it and/or modify @@ -115,15 +115,18 @@ static void start_program_jedec_common(const struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); - chip_writeb(flash, 0xA0, bios + (0x5555 & mask)); + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; + + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); + chip_writeb(flash, 0xA0, bios + ((0x5555 << shifted) & mask)); }
static int probe_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; const struct flashchip *chip = flash->chip; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; uint8_t id1, id2; uint32_t largeid1, largeid2; uint32_t flashcontent1, flashcontent2; @@ -153,31 +156,31 @@ /* Reset chip to a clean slate */ if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) { - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); if (probe_timing_exit) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); if (probe_timing_exit) programmer_delay(10); } - chip_writeb(flash, 0xF0, bios + (0x5555 & mask)); + chip_writeb(flash, 0xF0, bios + ((0x5555 << shifted) & mask)); if (probe_timing_exit) programmer_delay(probe_timing_exit);
/* Issue JEDEC Product ID Entry command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); if (probe_timing_enter) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); if (probe_timing_enter) programmer_delay(10); - chip_writeb(flash, 0x90, bios + (0x5555 & mask)); + chip_writeb(flash, 0x90, bios + ((0x5555 << shifted) & mask)); if (probe_timing_enter) programmer_delay(probe_timing_enter);
/* Read product ID */ - id1 = chip_readb(flash, bios); - id2 = chip_readb(flash, bios + 0x01); + id1 = chip_readb(flash, bios + (0x00 << shifted)); + id2 = chip_readb(flash, bios + (0x01 << shifted)); largeid1 = id1; largeid2 = id2;
@@ -196,14 +199,14 @@ /* Issue JEDEC Product ID Exit command */ if ((chip->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET) { - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); if (probe_timing_exit) programmer_delay(10); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); if (probe_timing_exit) programmer_delay(10); } - chip_writeb(flash, 0xF0, bios + (0x5555 & mask)); + chip_writeb(flash, 0xF0, bios + ((0x5555 << shifted) & mask)); if (probe_timing_exit) programmer_delay(probe_timing_exit);
@@ -212,8 +215,8 @@ msg_cdbg(", id1 parity violation");
/* Read the product ID location again. We should now see normal flash contents. */ - flashcontent1 = chip_readb(flash, bios); - flashcontent2 = chip_readb(flash, bios + 0x01); + flashcontent1 = chip_readb(flash, bios + (0x00 << shifted)); + flashcontent2 = chip_readb(flash, bios + (0x01 << shifted));
/* Check if it is a continuation ID, this should be a while loop. */ if (flashcontent1 == 0x7F) { @@ -244,21 +247,23 @@ unsigned int pagesize, unsigned int mask) { chipaddr bios = flash->virtual_memory; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the Sector Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); chip_writeb(flash, 0x30, bios + page); programmer_delay(delay_us); @@ -274,21 +279,23 @@ unsigned int blocksize, unsigned int mask) { chipaddr bios = flash->virtual_memory; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the Sector Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); chip_writeb(flash, 0x50, bios + block); programmer_delay(delay_us); @@ -303,23 +310,25 @@ static int erase_chip_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0; unsigned int delay_us = 0; + if(flash->chip->probe_timing != TIMING_ZERO) delay_us = 10;
/* Issue the JEDEC Chip Erase command */ - chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x80, bios + (0x5555 & mask)); + chip_writeb(flash, 0x80, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us);
- chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0xAA, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x55, bios + ((0x2AAA << shifted) & mask)); programmer_delay(delay_us); - chip_writeb(flash, 0x10, bios + (0x5555 & mask)); + chip_writeb(flash, 0x10, bios + ((0x5555 << shifted) & mask)); programmer_delay(delay_us);
toggle_ready_jedec_slow(flash, bios); Index: flashrom-jedec_shifted/82802ab.c =================================================================== --- flashrom-jedec_shifted/82802ab.c (Revision 1818) +++ flashrom-jedec_shifted/82802ab.c (Arbeitskopie) @@ -44,7 +44,7 @@ { chipaddr bios = flash->virtual_memory; uint8_t id1, id2, flashcontent1, flashcontent2; - int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) != 0; + int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0;
/* Reset to get a clean state */ chip_writeb(flash, 0xFF, bios); Index: flashrom-jedec_shifted/flashchips.c =================================================================== --- flashrom-jedec_shifted/flashchips.c (Revision 1818) +++ flashrom-jedec_shifted/flashchips.c (Arbeitskopie) @@ -4892,10 +4892,10 @@ .model_id = FUJITSU_MBM29F400BC, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = TIMING_FIXME, .block_erasers = { { @@ -4905,13 +4905,13 @@ {32 * 1024, 1}, {64 * 1024, 7}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */ }, @@ -4924,10 +4924,10 @@ .model_id = FUJITSU_MBM29F400TC, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_AAA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = TIMING_FIXME, .block_erasers = { { @@ -4937,13 +4937,13 @@ {8 * 1024, 2}, {16 * 1024, 1}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, }, }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */ }, @@ -11388,10 +11388,10 @@ .model_id = ST_M29F400BB, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = TIMING_FIXME, .block_erasers = { { @@ -11401,13 +11401,13 @@ {32 * 1024, 1}, {64 * 1024, 7}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, } }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4500, 5500}, }, @@ -11420,10 +11420,10 @@ .model_id = ST_M29F400BT, .total_size = 512, .page_size = 64 * 1024, - .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET, + .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, .tested = TEST_UNTESTED, - .probe = probe_m29f400bt, - .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */ + .probe = probe_jedec, + .probe_timing = TIMING_FIXME, .block_erasers = { { @@ -11433,13 +11433,13 @@ {8 * 1024, 2}, {16 * 1024, 1}, }, - .block_erase = erase_block_shifted_jedec, + .block_erase = erase_sector_jedec, }, { .eraseblocks = { {512 * 1024, 1} }, - .block_erase = erase_chip_block_shifted_jedec, + .block_erase = erase_chip_block_jedec, } }, - .write = write_m29f400bt, + .write = write_jedec_1, .read = read_memmapped, .voltage = {4500, 5500}, },