Hi,
I was adding support for the AT49F040 parallel flash chip, but have some questions. This chip has a boot block which once locked cannot be erased / rewritten. Should I add erase functions for both cases? Currently the erase function handles unlocked chips only. In addition, the datasheet specifies no command timings, is the timing something I can infer from the read / program cycle characteristics tables?
Regards,
David
Signed-off-by: David Borg borg.db@gmail.com
datasheet: http://pdf1.alldatasheet.com/datasheet-pdf/view/56184/ATMEL/AT49F040.html
Index: flashchips.c =================================================================== --- flashchips.c (revision 1145) +++ flashchips.c (working copy) @@ -1985,6 +1985,29 @@ },
{ + .vendor = "Atmel", + .name = "AT49F040", + .bustype = CHIP_BUSTYPE_PARALLEL, + .manufacture_id = ATMEL_ID, + .model_id = AT_49F040, + .total_size = 512, + .page_size = 512, + .feature_bits = FEATURE_EITHER_RESET | FEATURE_ADDR_FULL, + .tested = TEST_UNTESTED, + .probe = probe_jedec, + .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ + .block_erasers = + { + { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + }, + .write = write_jedec_1, + .read = read_memmapped, + }, + + { .vendor = "EMST", .name = "F49B002UA", .bustype = CHIP_BUSTYPE_PARALLEL, Index: flashchips.h =================================================================== --- flashchips.h (revision 1145) +++ flashchips.h (working copy) @@ -174,6 +174,7 @@ #define AT_49F020 0x0B #define AT_49F002N 0x07 /* for AT49F002(N) */ #define AT_49F002NT 0x08 /* for AT49F002(N)T */ +#define AT_49F040 0x13
#define CATALYST_ID 0x31 /* Catalyst */
Hi David,
you somehow manage to find really evil chips.
On 31.08.2010 23:19, David Borg wrote:
I was adding support for the AT49F040 parallel flash chip, but have some questions. This chip has a boot block which once locked cannot be erased / rewritten.
Yes, permanent lockdown sucks.
Should I add erase functions for both cases?
I'd say yes, but currently flashrom can't specify erase functions which work only for a part of the chip. Maybe add a comment to flashchips.c that there is an erase-without-bootblock which only applies to chips with locked bootblock.
Currently the erase function handles unlocked chips only.
There is the possibility of adding a printlock function which would be extremely hopeful here. While it won't solve the lockdown problem, it can at least make users aware of the lockdown.
In addition, the datasheet specifies no command timings, is the timing something I can infer from the read / program cycle characteristics tables?
No. I'd say this is a chip with zero delay (that is, zero additional delay).
Signed-off-by: David Borg borg.db@gmail.com
datasheet: http://pdf1.alldatasheet.com/datasheet-pdf/view/56184/ATMEL/AT49F040.html
Index: flashchips.c
--- flashchips.c (revision 1145) +++ flashchips.c (working copy) @@ -1985,6 +1985,29 @@ },
{
.vendor = "Atmel",
.name = "AT49F040",
.bustype = CHIP_BUSTYPE_PARALLEL,
.manufacture_id = ATMEL_ID,
.model_id = AT_49F040,
.total_size = 512,
.page_size = 512,
.feature_bits = FEATURE_EITHER_RESET | FEATURE_ADDR_FULL,
.tested = TEST_UNTESTED,
.probe = probe_jedec,
.probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
.block_erasers =
{
{
.eraseblocks = { {512 * 1024, 1} },
.block_erase = erase_chip_block_jedec,
}
Comment about the erase-without-bootblock goes here.
},
.write = write_jedec_1,
.read = read_memmapped,
- },
- { .vendor = "EMST", .name = "F49B002UA", .bustype = CHIP_BUSTYPE_PARALLEL,
Index: flashchips.h
--- flashchips.h (revision 1145) +++ flashchips.h (working copy) @@ -174,6 +174,7 @@ #define AT_49F020 0x0B #define AT_49F002N 0x07 /* for AT49F002(N) */ #define AT_49F002NT 0x08 /* for AT49F002(N)T */ +#define AT_49F040 0x13
I think this part no longer applies to the tree.
#define CATALYST_ID 0x31 /* Catalyst */
Looks good, we should get this merged with the bootblock lock printing and a comment in flashchips.c. Will ack after that change.
Regards, Carl-Daniel
Chip features an optional permanent boot block write protection.
Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at Signed-off-by: David Borg borg.db@gmail.com
--- diff of flashchips.c looks very odd, this is because i moved AT49F020 down. - rebased - voltages added - FEATURE_ADDR_FULL flag removed - printlock_at49f040 added (location dubios, but w39_idmode_readb implements what is needed already (and is static...) - AT49F020 does also feature a permanent lock (8 kB boot block), which uses the same detection method... --- chipdrivers.h | 1 + flashchips.c | 80 ++++++++++++++++++++++++++++++++++++++++++--------------- flashchips.h | 5 ++- w39.c | 8 +++++ 4 files changed, 71 insertions(+), 23 deletions(-)
diff --git a/chipdrivers.h b/chipdrivers.h index 92ddbea..4583ae6 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -136,6 +136,7 @@ int printlock_w39v080fa(struct flashchip *flash); int printlock_w39v080fa_dual(struct flashchip *flash); int unlock_w39v040fb(struct flashchip *flash); int unlock_w39v080fa(struct flashchip *flash); +int printlock_at49f(struct flashchip *flash);
/* w29ee011.c */ int probe_w29ee011(struct flashchip *flash); diff --git a/flashchips.c b/flashchips.c index 1a5622f..3d260b9 100644 --- a/flashchips.c +++ b/flashchips.c @@ -2218,19 +2218,27 @@ const struct flashchip flashchips[] = {
{ .vendor = "Atmel", - .name = "AT49F020", + .name = "AT49F002(N)", .bustype = BUS_PARALLEL, .manufacture_id = ATMEL_ID, - .model_id = ATMEL_AT49F020, + .model_id = ATMEL_AT49F002N, .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PRE, + .tested = TEST_UNTESTED, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = { { + .eraseblocks = { + {16 * 1024, 1}, + {8 * 1024, 2}, + {96 * 1024, 1}, + {128 * 1024, 1}, + }, + .block_erase = erase_sector_jedec, + }, { .eraseblocks = { {256 * 1024, 1} }, .block_erase = erase_chip_block_jedec, } @@ -2242,24 +2250,24 @@ const struct flashchip flashchips[] = {
{ .vendor = "Atmel", - .name = "AT49F002(N)", + .name = "AT49F002(N)T", .bustype = BUS_PARALLEL, .manufacture_id = ATMEL_ID, - .model_id = ATMEL_AT49F002N, + .model_id = ATMEL_AT49F002NT, .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_UNTESTED, + .tested = TEST_OK_PR, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = { { .eraseblocks = { - {16 * 1024, 1}, - {8 * 1024, 2}, - {96 * 1024, 1}, {128 * 1024, 1}, + {96 * 1024, 1}, + {8 * 1024, 2}, + {16 * 1024, 1}, }, .block_erase = erase_sector_jedec, }, { @@ -2274,31 +2282,61 @@ const struct flashchip flashchips[] = {
{ .vendor = "Atmel", - .name = "AT49F002(N)T", + .name = "AT49F020", .bustype = BUS_PARALLEL, .manufacture_id = ATMEL_ID, - .model_id = ATMEL_AT49F002NT, + .model_id = ATMEL_AT49F020, .total_size = 256, .page_size = 256, .feature_bits = FEATURE_EITHER_RESET, - .tested = TEST_OK_PR, + .tested = TEST_OK_PRE, .probe = probe_jedec, .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ .block_erasers = { { - .eraseblocks = { - {128 * 1024, 1}, - {96 * 1024, 1}, - {8 * 1024, 2}, - {16 * 1024, 1}, - }, - .block_erase = erase_sector_jedec, - }, { .eraseblocks = { {256 * 1024, 1} }, .block_erase = erase_chip_block_jedec, } + /* Chip features an optional permanent write protection + * of the first 8 kB. The erase function is the same as + * above, but 00000H to 01FFFH will not be erased. + * FIXME: add another eraser when partial erasers are + * supported. + */ + }, + .printlock = printlock_at49f, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {4500, 5500}, + }, + + { + .vendor = "Atmel", + .name = "AT49F040", + .bustype = BUS_PARALLEL, + .manufacture_id = ATMEL_ID, + .model_id = ATMEL_AT49F040, + .total_size = 512, + .page_size = 512, + .feature_bits = FEATURE_EITHER_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec, + .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */ + .block_erasers = + { + { + .eraseblocks = { {512 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + } + /* Chip features an optional permanent write protection + * of the first 16 kB. The erase function is the same as + * above, but 00000H to 03FFFH will not be erased. + * FIXME: add another eraser when partial erasers are + * supported. + */ }, + .printlock = printlock_at49f, .write = write_jedec_1, .read = read_memmapped, .voltage = {4500, 5500}, diff --git a/flashchips.h b/flashchips.h index ff49d31..c9685ac 100644 --- a/flashchips.h +++ b/flashchips.h @@ -181,9 +181,10 @@ #define ATMEL_AT45DB642 /* No ID available */ #define ATMEL_AT45DB642D 0x2800 #define ATMEL_AT49BV512 0x03 -#define ATMEL_AT49F020 0x0B #define ATMEL_AT49F002N 0x07 /* for AT49F002(N) */ -#define ATMEL_AT49F002NT 0x08 /* for AT49F002(N)T */ +#define ATMEL_AT49F002NT 0x08 /* for AT49F002(N)T */ +#define ATMEL_AT49F020 0x0B +#define ATMEL_AT49F040 0x13
/* Bright Microelectronics has the same manufacturer ID as Hyundai... */ #define BRIGHT_ID 0xAD /* Bright Microelectronics */ diff --git a/w39.c b/w39.c index 920a43f..8cc71e8 100644 --- a/w39.c +++ b/w39.c @@ -279,3 +279,11 @@ int unlock_w39v080fa(struct flashchip *flash)
return 0; } + +int printlock_at49f(struct flashchip *flash) +{ + uint8_t lock = w39_idmode_readb(flash, 0x00002); + msg_cdbg("Hardware bootblock lockout is %sactive.\n", + (lock & 0x01) ? "" : "not "); + return 0; +}