On 12/25/09 11:23 AM, Carl-Daniel Hailfinger wrote:
On 25.12.2009 07:03, Sean Nelson wrote:
This patch demonstrates how we could refactor the jedec code. After
the refactor
we can delete these:
* am29f040b
* en29f002a -> file_not_used
* m29f002
* mx29f002
* pm29f002
* sst49lf040
* w49f002u
Great.
What does the file_not_used mean? Was it never hooked up at all? In that
case, it would be cool if we could go through each of the functions and
check if we have to add a corresponding flashchip entry for it.
file not used is a file that is not hooked up anywhere in the source
code. What I could figure out is that the en29f002a functions are
nearly exactly the same as the am29f040b. And the flashchip entries are
already using the _29f040b functions.
These files can be deleted if we *could* find a way to integrate the
problems
into jedec.c:
* w29ee011 -> checks specifically for w29ee011
I think that was due to the probe sequence being non-standard, and that
probe sequence could mess up the internal state of another chip
(apparently not resettable).
As it stands, we still need/use w29ee011 for that very check.
* w39v040c -> checks for lock in probe: address 0xfff2
Will be solved once I update my locking infrastructure patch which
splits lock printing/disabling/enabling away from probe.
* pm49fl00x -> uses chip protect code
Will be solved by the locking infrastructure.
* m29f002 -> block based writing
* m29f400bt -> block based writing
I need to finish my eraseblock based writing patch which will not only
remove all chip specific code, it will also allow us to perform partial
writes.
The good news is that I don't know any chips which need different write
functions for different chip areas, so a simple writelen/writefunc
function pair in struct flashchip will address all partial write needs.
Can send a prototype patch if you want.
I was looking through these two files and saw that they used variable
block
sizes for writing sectors, maybe we can do something simpler to
block_erasers:
* m29f002
* m29f400bt
Yes, eraseblock based writing will solve this.
There are a few files that performs another map_flash_registers() after
successful probe, I was wondering if we could add the re-mapping to
probe_jedec_common or if its safe to omit the function call:
* pm49fl00x
* stm50flw0x0x
* w39v080fa
Mapping flash registers or not is something that should end up outside
probe, probably being controlled by a flag in a to-be-created bitfield
in struct flashchip. For now, I think a pretty good heuristic is that
LPC/FWH flahs has registers, and Parallel/SPI doesn't because Parallel
doesn't have enough address lines for this and SPI has opcodes which
take care of this register stuff.
In struct flashchips, I've added "int remap" for this very reason.
List of chips that use a specific addressing for command codes:
0x2AA based chips:
* am29f040b
* mx29f002
* pm29f002
0xAAA based chips:
* m29f002
* m29f400bt
0x2AAA based chips:
* pm49fl00x
* sst49lf040
* stm50flw0x0x
* w29ee011
* w39v040c
* w39v080fa
* w49f002u
If you want I can send my full notes so you can see what each file's
functions
can be converted to, on request.
The notes you sent are already awesome, but I'm realling thinking we
should have all this on the list (or in the wiki) for future
generations. We never know when someone else will come along and take
over flashrom development, and that person should have all the
information we had.
IMHO first priority is getting your patch merged, though.
I don't know if my methods for the address mask
is proper. If you can think of a better way, I'm all ears.
I think the (0x5555& mask) is a good idea (would have done exactly the
same thing). Given that the shift stuff is only needed for a specific
subset of chips and for those chips only in a subset of configurations
(AFAIK it only affects chips with 16-bit access granularity which are
strapped to give 8-bit output) I would really like to leave out the
shift parameter for now. Without shift, the code is IMHO more readable
and the conversion is easier to review. We still can hook up shifting
later (and such a single-purpose patch will be a lot easier to review as
well).
Everything is now using mask-only.
Once you commit, please use the long contents of your mail as changelog.
It is very enlightening and I want to keep it around in case someone
besides me digs through code history.
On to the comments.
IMHO the _common stuff should not be in any header. It is internal to
jedec.c. To get this to work, we may have to reorder some functions
inside jedec.c. If these declarations help you right now, we can still
reorder those functions (and remove the declarations) in a followup patch.
I've removed the common stuff from the header except for
erase_sector_jedec_common since at the moment I'd like to keep the other
files intact and its used in the other files.
I don't see a replacement for write_jedec_1. Is there something I
missed? Some chips need the byte program sequence before each
single-byte write.
One way of solving and replacing write_jedec_1 is to add a
byte_based_write field to struct flashchips
Can you replace chipaddr bios with struct flashchip *flash in the
function signature?
Done.
I think entry_cmd is taking the refactoring a bit too far. If the
sequence is non-standard, it shoudln't be called foo_jedec.
I also agree. Fixed.
+ unsigned int mid_cmd, unsigned int did_cmd,
mid_addr, did_addr please.
Fixed.
+ unsigned int mask, unsigned int shift, int reset)
I am unconvinced that shift is the right approach right now, I'd like to
operate mask-only if possible.
Done. Using masks: (0x5555 & mask) and (0x2AAA & mask). To get 0x2AA, we
use mask 0x7FF; same to get 0x555.
Hmm. Can you rename reset to long_reset? Both variants (AA 55 F0 and F0)
are reset sequences.
Done. Also using : "if (long_reset)"
Either make it conditional on the flash bus (as suggested above) or add
some flag to a bitfield in struct flashchip.
Conditional on "flash->remap".
Isn't write_helper_{page, byte} taking the refactoring a bit too far?
Agreed, Removed.
Why is verify_range commented out here?
I couldn't figure out how to get "int start" back for it, I think I
fixed it. See the patch.
+}
- printf("Programming page: ");
- for (i = 0; i< flash->total_size; i++) {
- if ((i& 0x3) == 0)
- printf("address: 0x%08lx", (unsigned long)i * 1024);
+void start_program_jedec_aaa(chipaddr bios)
struct flashchip *flash instead of chipaddr bios please.
+{
+ start_program_jedec_common(bios, 0xf000, 0);
mask should be 0xfff or 0x1fff.
For now I'm ignoring the _aaa functions since its used for m29lf400bt
I am unconvinced unless you also fix up page_size (and to fix page_size,
you have to convert all chips to struct eraseblock because some chips
use page_size as eraseblock size.
After this patch is committed, I'll continue coverting all chips to
struct eraseblock.
Since the chips that used the _aaa functions were byte based sequences
I'm going to ignore them and leave the associated file alone.
diff --git a/chipdrivers.h b/chipdrivers.h
index adcb46d..3ccc478 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -78,20 +78,21 @@ void toggle_ready_jedec(chipaddr dst);
void data_polling_jedec(chipaddr dst, uint8_t data);
void start_program_jedec(chipaddr bios);
int write_byte_program_jedec(chipaddr bios, uint8_t *src,
chipaddr dst);
int probe_jedec(struct flashchip *flash);
int erase_chip_jedec(struct flashchip *flash);
int write_jedec(struct flashchip *flash, uint8_t *buf);
-int write_jedec_1(struct flashchip *flash, uint8_t *buf);
int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned
int pagesize);
int erase_block_jedec(struct flashchip *flash, unsigned int page, unsigned int
blocksize);
int erase_chip_block_jedec(struct flashchip *flash, unsigned int page,
unsigned int blocksize);
-int write_sector_jedec(chipaddr bios, uint8_t *src,
- chipaddr dst, unsigned int page_size);
+int write_sector_jedec_common(struct flashchip *flash, uint8_t *src,
+ chipaddr dst, unsigned int page_size,
+ unsigned int mask);
+
/* m29f002.c */
int erase_m29f002(struct flashchip *flash);
int write_m29f002t(struct flashchip *flash, uint8_t *buf);
int write_m29f002b(struct flashchip *flash, uint8_t *buf);
/* m29f400bt.c */
diff --git a/flash.h b/flash.h
index feac98e..cb3bc77 100644
--- a/flash.h
+++ b/flash.h
@@ -156,14 +156,16 @@ struct flashchip {
* Identification code.
*/
uint32_t manufacture_id;
uint32_t model_id;
int total_size;
int page_size;
+ int remap;
+ int byte_based_write;
/*
* Indicate if flashrom has been tested with this flash chip and if
* everything worked correctly.
*/
uint32_t tested;
diff --git a/flashchips.c b/flashchips.c
index 59f9139..af9039d 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -102,15 +102,15 @@ struct flashchip flashchips[] = {
},
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {256 * 1024, 1} },
.block_erase = erase_chip_block_jedec,
},
},
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "AMD",
.name = "Am29F002(N)BT",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -133,15 +133,15 @@ struct flashchip flashchips[] = {
},
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {256 * 1024, 1} },
.block_erase = erase_chip_block_jedec,
},
},
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "AMD",
.name = "Am29F016D",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -1178,15 +1178,15 @@ struct flashchip flashchips[] = {
},
.block_erase = erase_sector_29f002,
}, {
.eraseblocks = { {256 * 1024, 1} },
.block_erase = erase_chip_29f002,
},
},
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "AMIC",
.name = "A29002T",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -1209,15 +1209,15 @@ struct flashchip flashchips[] = {
},
.block_erase = erase_sector_29f002,
}, {
.eraseblocks = { {256 * 1024, 1} },
.block_erase = erase_chip_29f002,
},
},
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "AMIC",
.name = "A29040B",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -1570,15 +1570,15 @@ struct flashchip flashchips[] = {
},
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {256 * 1024, 1} },
.block_erase = erase_chip_block_jedec,
},
},
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "EON",
.name = "EN29F002(A)(N)T",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -1601,15 +1601,15 @@ struct flashchip flashchips[] = {
},
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {256 * 1024, 1} },
.block_erase = erase_chip_block_jedec,
},
},
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "Fujitsu",
.name = "MBM29F004BC",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -2108,15 +2108,15 @@ struct flashchip flashchips[] = {
.model_id = MX_29F001B,
.total_size = 128,
.page_size = 32 * 1024,
.tested = TEST_OK_PRE,
.probe = probe_29f002,
.probe_timing = TIMING_IGNORED, /* routine don't use
probe_timing (mx29f002.c) */
.erase = erase_29f002,
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "Macronix",
.name = "MX29F001T",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -2124,15 +2124,15 @@ struct flashchip flashchips[] = {
.model_id = MX_29F001T,
.total_size = 128,
.page_size = 32 * 1024,
.tested = TEST_OK_PRE,
.probe = probe_29f002,
.probe_timing = TIMING_IGNORED, /* routine don't use
probe_timing (mx29f002.c) */
.erase = erase_29f002,
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "Macronix",
.name = "MX29F002B",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -2155,15 +2155,15 @@ struct flashchip flashchips[] = {
},
.block_erase = erase_sector_29f002, /* This
erase function has 64k blocksize for eLiteFlash */
}, {
.eraseblocks = { {256 * 1024, 1} },
.block_erase = erase_chip_29f002,
},
},
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "Macronix",
.name = "MX29F002T",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -2186,15 +2186,15 @@ struct flashchip flashchips[] = {
},
.block_erase = erase_sector_29f002, /* This
erase function has 64k blocksize for eLiteFlash */
}, {
.eraseblocks = { {256 * 1024, 1} },
.block_erase = erase_chip_29f002,
},
},
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "Macronix",
.name = "MX29LV040",
.bustype = CHIP_BUSTYPE_PARALLEL,
@@ -2202,15 +2202,15 @@ struct flashchip flashchips[] = {
.model_id = MX_29LV040,
.total_size = 512,
.page_size = 64 * 1024,
.tested = TEST_OK_PR,
.probe = probe_29f002,
.probe_timing = TIMING_IGNORED, /* routine don't use
probe_timing (mx29f002.c) */
.erase = erase_29f002,
- .write = write_jedec_1,
+ .write = write_jedec,
.read = read_memmapped,
},
{
.vendor = "Numonyx",
.name = "M25PE10",
.bustype = CHIP_BUSTYPE_SPI,
diff --git a/jedec.c b/jedec.c
index d6cad41..302bee0 100644
--- a/jedec.c
+++ b/jedec.c
@@ -83,22 +83,25 @@ void data_polling_jedec(chipaddr dst, uint8_t data)
break;
}
}
if (i > 0x100000)
printf_debug("%s: excessive loops, i=0x%x\n", __func__, i);
}
-void start_program_jedec(chipaddr bios)
+void start_program_jedec_common(struct flashchip *flash, unsigned int mask)
{
- chip_writeb(0xAA, bios + 0x5555);
- chip_writeb(0x55, bios + 0x2AAA);
- chip_writeb(0xA0, bios + 0x5555);
+ chipaddr bios = flash->virtual_memory;
+ chip_writeb(0xAA, bios + (0x5555 & mask));
+ chip_writeb(0x55, bios + (0x2AAA & mask));
+ chip_writeb(0xA0, bios + (0x5555 & mask));
}
-int probe_jedec(struct flashchip *flash)
+int probe_jedec_common(struct flashchip *flash,
+ unsigned int mid_addr, unsigned int did_addr,
+ unsigned int mask, int long_reset)
{
chipaddr bios = flash->virtual_memory;
uint8_t id1, id2;
uint32_t largeid1, largeid2;
uint32_t flashcontent1, flashcontent2;
int probe_timing_enter, probe_timing_exit;
@@ -114,27 +117,27 @@ int probe_jedec(struct flashchip *flash)
} else {
printf("Chip has negative value in probe_timing, failing "
"without chip access\n");
return 0;
}
/* Issue JEDEC Product ID Entry command */
- chip_writeb(0xAA, bios + 0x5555);
+ chip_writeb(0xAA, bios + (0x5555 & mask));
if (probe_timing_enter)
programmer_delay(10);
- chip_writeb(0x55, bios + 0x2AAA);
+ chip_writeb(0x55, bios + (0x2AAA & mask));
if (probe_timing_enter)
programmer_delay(10);
- chip_writeb(0x90, bios + 0x5555);
+ chip_writeb(0x90, bios + (0x5555 & mask));
if (probe_timing_enter)
programmer_delay(probe_timing_enter);
/* Read product ID */
- id1 = chip_readb(bios);
- id2 = chip_readb(bios + 0x01);
+ id1 = chip_readb(bios + mid_addr);
+ id2 = chip_readb(bios + did_addr);
largeid1 = id1;
largeid2 = id2;
/* Check if it is a continuation ID, this should be a while loop. */
if (id1 == 0x7F) {
largeid1 <<= 8;
id1 = chip_readb(bios + 0x100);
@@ -143,21 +146,24 @@ int probe_jedec(struct flashchip *flash)
if (id2 == 0x7F) {
largeid2 <<= 8;
id2 = chip_readb(bios + 0x101);
largeid2 |= id2;
}
/* Issue JEDEC Product ID Exit command */
- chip_writeb(0xAA, bios + 0x5555);
- if (probe_timing_exit)
- programmer_delay(10);
- chip_writeb(0x55, bios + 0x2AAA);
- if (probe_timing_exit)
- programmer_delay(10);
- chip_writeb(0xF0, bios + 0x5555);
+ if (long_reset)
+ {
+ chip_writeb(0xAA, bios + (0x5555 & mask));
+ if (probe_timing_exit)
+ programmer_delay(10);
+ chip_writeb(0x55, bios + (0x2AAA & mask));
+ if (probe_timing_exit)
+ programmer_delay(10);
+ }
+ chip_writeb(0xF0, bios + (0x5555 & mask));
if (probe_timing_exit)
programmer_delay(probe_timing_exit);
printf_debug("%s: id1 0x%02x, id2 0x%02x", __func__, largeid1,
largeid2);
if (!oddparity(id1))
printf_debug(", id1 parity violation");
@@ -180,243 +186,213 @@ int probe_jedec(struct flashchip *flash)
if (largeid2 == flashcontent2)
printf_debug(", id2 is normal flash content");
printf_debug("\n");
if (largeid1 == flash->manufacture_id && largeid2 == flash->model_id)
return 1;
+ if (flash->remap)
+ map_flash_registers(flash);
+
return 0;
}
-int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned
int pagesize)
+int erase_sector_jedec_common(struct flashchip *flash, unsigned int page,
+ unsigned int pagesize, unsigned int mask)
{
chipaddr bios = flash->virtual_memory;
/* Issue the Sector Erase command */
- chip_writeb(0xAA, bios + 0x5555);
+ chip_writeb(0xAA, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0x55, bios + 0x2AAA);
+ chip_writeb(0x55, bios + (0x2AAA & mask));
programmer_delay(10);
- chip_writeb(0x80, bios + 0x5555);
+ chip_writeb(0x80, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0xAA, bios + 0x5555);
+ chip_writeb(0xAA, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0x55, bios + 0x2AAA);
+ chip_writeb(0x55, bios + (0x2AAA & mask));
programmer_delay(10);
chip_writeb(0x30, bios + page);
programmer_delay(10);
/* wait for Toggle bit ready */
toggle_ready_jedec_slow(bios);
if (check_erased_range(flash, page, pagesize)) {
fprintf(stderr,"ERASE FAILED!\n");
return -1;
}
return 0;
}
-int erase_block_jedec(struct flashchip *flash, unsigned int block, unsigned
int blocksize)
+int erase_block_jedec_common(struct flashchip *flash, unsigned int block,
+ unsigned int blocksize, unsigned int mask)
{
chipaddr bios = flash->virtual_memory;
/* Issue the Sector Erase command */
- chip_writeb(0xAA, bios + 0x5555);
+ chip_writeb(0xAA, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0x55, bios + 0x2AAA);
+ chip_writeb(0x55, bios + (0x2AAA & mask));
programmer_delay(10);
- chip_writeb(0x80, bios + 0x5555);
+ chip_writeb(0x80, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0xAA, bios + 0x5555);
+ chip_writeb(0xAA, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0x55, bios + 0x2AAA);
+ chip_writeb(0x55, bios + (0x2AAA & mask));
programmer_delay(10);
chip_writeb(0x50, bios + block);
programmer_delay(10);
/* wait for Toggle bit ready */
toggle_ready_jedec_slow(bios);
if (check_erased_range(flash, block, blocksize)) {
fprintf(stderr,"ERASE FAILED!\n");
return -1;
}
return 0;
}
-/* erase chip with block_erase() prototype */
-int erase_chip_block_jedec(struct flashchip *flash, unsigned int addr,
unsigned int blocksize)
-{
- if ((addr != 0) || (blocksize != flash->total_size * 1024)) {
- fprintf(stderr, "%s called with incorrect arguments\n",
- __func__);
- return -1;
- }
- return erase_chip_jedec(flash);
-}
-
-int erase_chip_jedec(struct flashchip *flash)
+int erase_chip_jedec_common(struct flashchip *flash, unsigned int mask)
{
int total_size = flash->total_size * 1024;
chipaddr bios = flash->virtual_memory;
/* Issue the JEDEC Chip Erase command */
- chip_writeb(0xAA, bios + 0x5555);
+ chip_writeb(0xAA, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0x55, bios + 0x2AAA);
+ chip_writeb(0x55, bios + (0x2AAA & mask));
programmer_delay(10);
- chip_writeb(0x80, bios + 0x5555);
+ chip_writeb(0x80, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0xAA, bios + 0x5555);
+ chip_writeb(0xAA, bios + (0x5555 & mask));
programmer_delay(10);
- chip_writeb(0x55, bios + 0x2AAA);
+ chip_writeb(0x55, bios + (0x2AAA & mask));
programmer_delay(10);
- chip_writeb(0x10, bios + 0x5555);
+ chip_writeb(0x10, bios + (0x5555 & mask));
programmer_delay(10);
toggle_ready_jedec_slow(bios);
if (check_erased_range(flash, 0, total_size)) {
fprintf(stderr,"ERASE FAILED!\n");
return -1;
}
return 0;
}
-int write_page_write_jedec(struct flashchip *flash, uint8_t *src,
- int start, int page_size)
+int write_sector_jedec_common(struct flashchip *flash, uint8_t *src,
+ chipaddr dst, unsigned int page_size,
+ unsigned int mask)
{
int i, tried = 0, failed;
- uint8_t *s = src;
chipaddr bios = flash->virtual_memory;
- chipaddr dst = bios + start;
- chipaddr d = dst;
+ chipaddr v = bios;
+ unsigned int start = dst - bios;
retry:
/* Issue JEDEC Data Unprotect comand */
- start_program_jedec(bios);
+ start_program_jedec_common(flash, mask);
/* transfer data from source to destination */
- for (i = 0; i < page_size; i++) {
- /* If the data is 0xFF, don't program it */
+ if (flash->byte_based_write)
+ {
+ for (i = 0; i < page_size; i++) {
+ /* If the data is 0xFF, don't program it */
+ if (*src != 0xFF)
+ chip_writeb(*src, dst);
+ dst++;
+ src++;
+ }
+ v = dst - 1;
+ }
+ else
+ {
if (*src != 0xFF)
chip_writeb(*src, dst);
- dst++;
- src++;
}
- toggle_ready_jedec(dst - 1);
-
- dst = d;
- src = s;
+ toggle_ready_jedec(v);
failed = verify_range(flash, src, start, page_size, NULL);
if (failed && tried++ < MAX_REFLASH_TRIES) {
fprintf(stderr, "retrying.\n");
goto retry;
}
if (failed) {
fprintf(stderr, " page 0x%lx failed!\n",
- (d - bios) / page_size);
- }
- return failed;
-}
-
-int write_byte_program_jedec(chipaddr bios, uint8_t *src,
- chipaddr dst)
-{
- int tried = 0, failed = 0;
-
- /* If the data is 0xFF, don't program it and don't complain. */
- if (*src == 0xFF) {
- return 0;
- }
-
-retry:
- /* Issue JEDEC Byte Program command */
- start_program_jedec(bios);
-
- /* transfer data from source to destination */
- chip_writeb(*src, dst);
- toggle_ready_jedec(bios);
-
- if (chip_readb(dst) != *src && tried++ < MAX_REFLASH_TRIES) {
- goto retry;
- }
-
- if (tried >= MAX_REFLASH_TRIES)
- failed = 1;
-
- return failed;
-}
-
-int write_sector_jedec(chipaddr bios, uint8_t *src,
- chipaddr dst, unsigned int page_size)
-{
- int i, failed = 0;
- chipaddr olddst;
-
- olddst = dst;
- for (i = 0; i < page_size; i++) {
- if (write_byte_program_jedec(bios, src, dst))
- failed = 1;
- dst++, src++;
+ (dst - bios) / page_size);
}
- if (failed)
- fprintf(stderr, " writing sector at 0x%lx failed!\n", olddst);
-
return failed;
}
-int write_jedec(struct flashchip *flash, uint8_t *buf)
+int write_jedec_common(struct flashchip *flash, uint8_t *buf, unsigned int
mask)
{
int i, failed = 0;
int total_size = flash->total_size * 1024;
int page_size = flash->page_size;
- if (erase_chip_jedec(flash)) {
+ if (erase_chip_jedec_common(flash, mask)) {
fprintf(stderr,"ERASE FAILED!\n");
return -1;
}
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
printf("%04d at address: 0x%08x", i, i * page_size);
- if (write_page_write_jedec(flash, buf + i * page_size,
- i * page_size, page_size))
+ if (write_sector_jedec_common(flash, buf + i * page_size,
+ i * page_size, page_size, mask))
failed = 1;
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
}
printf("\n");
return failed;
}
-int write_jedec_1(struct flashchip *flash, uint8_t * buf)
-{
- int i;
- chipaddr bios = flash->virtual_memory;
- chipaddr dst = bios;
- programmer_delay(10);
- if (erase_flash(flash)) {
- fprintf(stderr, "ERASE FAILED!\n");
+/* erase chip with block_erase() prototype */
+int erase_chip_block_jedec(struct flashchip *flash, unsigned int addr,
+ unsigned int blocksize)
+{
+ if ((addr != 0) || (blocksize != flash->total_size * 1024)) {
+ fprintf(stderr, "%s called with incorrect arguments\n",
+ __func__);
return -1;
}
+ return erase_chip_jedec_common(flash, 0xffff);
+}
- printf("Programming page: ");
- for (i = 0; i < flash->total_size; i++) {
- if ((i & 0x3) == 0)
- printf("address: 0x%08lx", (unsigned long)i * 1024);
+void start_program_jedec(struct flashchip *flash)
+{
+ start_program_jedec_common(flash, 0xffff);
+}
- write_sector_jedec(bios, buf + i * 1024, dst + i * 1024, 1024);
+int probe_jedec(struct flashchip *flash)
+{
+ return probe_jedec_common(flash, 0x00, 0x01, 0xffff, 1);
+}
- if ((i & 0x3) == 0)
- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
- }
+int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned
int size)
+{
+ return erase_sector_jedec_common(flash, page, size, 0xffff);
+}
+int erase_block_jedec(struct flashchip *flash, unsigned int page, unsigned int
size)
+{
+ return erase_block_jedec_common(flash, page, size, 0xffff);
+}
- printf("\n");
- return 0;
+int erase_chip_jedec(struct flashchip *flash)
+{
+ return erase_chip_jedec_common(flash, 0xffff);
}
+
+int write_jedec(struct flashchip *flash, uint8_t *buf)
+{
+ return write_jedec_common(flash, buf, 0xffff);
+}
+
diff --git a/pm29f002.c b/pm29f002.c
index bf78d13..8f1d010 100644
--- a/pm29f002.c
+++ b/pm29f002.c
@@ -17,15 +17,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "flash.h"
/* if write_sector_jedec is used,
- this is write_jedec_1 */
+ this is write_jedec */
int write_pm29f002(struct flashchip *flash, uint8_t *buf)
{
int i, total_size = flash->total_size * 1024;
chipaddr bios = flash->virtual_memory;
chipaddr dst = bios;
if (erase_flash(flash)) {
diff --git a/pm49fl00x.c b/pm49fl00x.c
index 27a1163..424b0ed 100644
--- a/pm49fl00x.c
+++ b/pm49fl00x.c
@@ -97,16 +97,16 @@ int write_49fl00x(struct flashchip *flash, uint8_t *buf)
if (erase_block_jedec(flash, i * page_size, page_size)) {
fprintf(stderr, "ERASE FAILED!\n");
return -1;
}
/* write to the sector */
printf("%04d at address: 0x%08x", i, i * page_size);
- write_sector_jedec(bios, buf + i * page_size,
- bios + i * page_size, page_size);
+ write_sector_jedec_common(flash, buf + i * page_size,
+ bios + i * page_size, page_size, 0xffff);
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
printf("\n");
/* protected */
write_lockbits_49fl00x(flash->virtual_registers, total_size, 1,
diff --git a/sst49lf040.c b/sst49lf040.c
index ab1c918..c91a139 100644
--- a/sst49lf040.c
+++ b/sst49lf040.c
@@ -55,16 +55,16 @@ int write_49lf040(struct flashchip *flash, uint8_t *buf)
return -1;
}
/* write to the sector */
if (i % 10 == 0)
printf("%04d at address: 0x%08x ", i, i * page_size);
- write_sector_jedec(bios, buf + i * page_size,
- bios + i * page_size, page_size);
+ write_sector_jedec_common(flash, buf + i * page_size,
+ bios + i * page_size, page_size, 0xffff);
if (i % 10 == 0)
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
printf("\n");
diff --git a/sst_fwhub.c b/sst_fwhub.c
index f09aa54..4a976e6 100644
--- a/sst_fwhub.c
+++ b/sst_fwhub.c
@@ -153,16 +153,16 @@ int write_sst_fwhub(struct flashchip *flash, uint8_t *buf)
flash->read(flash, readbuf, i * page_size, page_size);
if (memcmp((void *)(buf + i * page_size),
(void *)(readbuf), page_size)) {
rc = erase_sst_fwhub_block(flash, i * page_size,
page_size);
if (rc)
return 1;
- write_sector_jedec(bios, buf + i * page_size,
- bios + i * page_size, page_size);
+ write_sector_jedec_common(flash, buf + i * page_size,
+ bios + i * page_size, page_size,
0xffff);
}
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
}
printf("\n");
return 0;
}
diff --git a/w39v040c.c b/w39v040c.c
index 722ae29..66ab115 100644
--- a/w39v040c.c
+++ b/w39v040c.c
@@ -76,15 +76,15 @@ int write_w39v040c(struct flashchip *flash, uint8_t *buf)
fprintf(stderr, "ERASE FAILED!\n");
return -1;
}
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
printf("%04d at address: 0x%08x", i, i * page_size);
- write_sector_jedec(bios, buf + i * page_size,
- bios + i * page_size, page_size);
+ write_sector_jedec_common(flash, buf + i * page_size,
+ bios + i * page_size, page_size, 0xffff);
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
}
printf("\n");
return 0;
}
diff --git a/w39v080fa.c b/w39v080fa.c
index 580657f..311e55b 100644
--- a/w39v080fa.c
+++ b/w39v080fa.c
@@ -178,13 +178,13 @@ int write_winbond_fwhub(struct flashchip *flash, uint8_t
*buf)
if (erase_winbond_fwhub(flash))
return -1;
printf("Programming: ");
for (i = 0; i < total_size; i += flash->page_size) {
printf("0x%08x\b\b\b\b\b\b\b\b\b\b", i);
- write_sector_jedec(bios, buf + i, bios + i, flash->page_size);
+ write_sector_jedec_common(flash, buf + i, bios + i,
flash->page_size, 0xffff);
}
printf("\n");
return 0;
}
diff --git a/w49f002u.c b/w49f002u.c
index d12bc72..87ce000 100644
--- a/w49f002u.c
+++ b/w49f002u.c
@@ -32,16 +32,16 @@ int write_49f002(struct flashchip *flash, uint8_t *buf)
return -1;
}
printf("Programming page: ");
for (i = 0; i < total_size / page_size; i++) {
printf("%04d at address: 0x%08x ", i, i * page_size);
/* Byte-wise writing of 'page_size' bytes. */
- write_sector_jedec(bios, buf + i * page_size,
- bios + i * page_size, page_size);
+ write_sector_jedec_common(flash, buf + i * page_size,
+ bios + i * page_size, page_size, 0xffff);
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
fflush(stdout);
}
printf("\n");
return 0;
}
_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom