Sometimes we want to read/write more than 4 bytes of chip content at once. Add chip_{read,write}n to the external flasher infrastructure which read/write n bytes at once.
Fix a few places where the code used memcpy/memcmp although that is strictly impossible with external flashers. Place a FIXME in the layout.c code because usage is not totally clear and needs to be fixed to support external flashers.
As a nice side benefit, we get a noticeable speedup for builtin flash reading which is now a memcpy() of the full flash area instead of a series of single-byte reads.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-chip_readn_writen/flash.h =================================================================== --- flashrom-chip_readn_writen/flash.h (Revision 576) +++ flashrom-chip_readn_writen/flash.h (Arbeitskopie) @@ -100,9 +100,11 @@ void (*chip_writeb) (uint8_t val, chipaddr addr); void (*chip_writew) (uint16_t val, chipaddr addr); void (*chip_writel) (uint32_t val, chipaddr addr); + void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len); uint8_t (*chip_readb) (const chipaddr addr); uint16_t (*chip_readw) (const chipaddr addr); uint32_t (*chip_readl) (const chipaddr addr); + void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len); };
extern const struct programmer_entry programmer_table[]; @@ -115,9 +117,11 @@ void chip_writeb(uint8_t val, chipaddr addr); void chip_writew(uint16_t val, chipaddr addr); void chip_writel(uint32_t val, chipaddr addr); +void chip_writen(uint8_t *buf, chipaddr addr, size_t len); uint8_t chip_readb(const chipaddr addr); uint16_t chip_readw(const chipaddr addr); uint32_t chip_readl(const chipaddr addr); +void chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
@@ -646,6 +650,7 @@ uint8_t internal_chip_readb(const chipaddr addr); uint16_t internal_chip_readw(const chipaddr addr); uint32_t internal_chip_readl(const chipaddr addr); +void internal_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); void mmio_writeb(uint8_t val, void *addr); void mmio_writew(uint16_t val, void *addr); void mmio_writel(uint32_t val, void *addr); @@ -656,8 +661,10 @@ void fallback_unmap(void *virt_addr, size_t len); void fallback_chip_writew(uint16_t val, chipaddr addr); void fallback_chip_writel(uint32_t val, chipaddr addr); +void fallback_chip_writen(uint8_t *buf, chipaddr addr, size_t len); uint16_t fallback_chip_readw(const chipaddr addr); uint32_t fallback_chip_readl(const chipaddr addr); +void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); #if defined(__FreeBSD__) || defined(__DragonFly__) extern int io_fd; #endif @@ -671,9 +678,11 @@ void dummy_chip_writeb(uint8_t val, chipaddr addr); void dummy_chip_writew(uint16_t val, chipaddr addr); void dummy_chip_writel(uint32_t val, chipaddr addr); +void dummy_chip_writen(uint8_t *buf, chipaddr addr, size_t len); uint8_t dummy_chip_readb(const chipaddr addr); uint16_t dummy_chip_readw(const chipaddr addr); uint32_t dummy_chip_readl(const chipaddr addr); +void dummy_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); int dummy_spi_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
Index: flashrom-chip_readn_writen/dummyflasher.c =================================================================== --- flashrom-chip_readn_writen/dummyflasher.c (Revision 576) +++ flashrom-chip_readn_writen/dummyflasher.c (Arbeitskopie) @@ -103,6 +103,18 @@ printf_debug("%s: addr=0x%lx, val=0x%08x\n", __func__, addr, val); }
+void dummy_chip_writen(uint8_t *buf, chipaddr addr, size_t len) +{ + size_t i; + printf_debug("%s: addr=0x%lx, len=0x%08lx, writing data (hex):", + __func__, addr, (unsigned long)len); + for (i = 0; i < len; i++) { + if ((i % 16) == 0) + printf_debug("\n"); + printf_debug("%02x ", buf[i]) + } +} + uint8_t dummy_chip_readb(const chipaddr addr) { printf_debug("%s: addr=0x%lx, returning 0xff\n", __func__, addr); @@ -121,6 +133,14 @@ return 0xffffffff; }
+void dummy_chip_readn(uint8_t *buf, const chipaddr addr, size_t len) +{ + printf_debug("%s: addr=0x%lx, len=0x%lx, returning array of 0xff\n", + __func__, addr, (unsigned long)len); + memset(buf, 0xff, len); + return; +} + int dummy_spi_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr) { Index: flashrom-chip_readn_writen/stm50flw0x0x.c =================================================================== --- flashrom-chip_readn_writen/stm50flw0x0x.c (Revision 576) +++ flashrom-chip_readn_writen/stm50flw0x0x.c (Arbeitskopie) @@ -27,6 +27,7 @@ */
#include <string.h> +#include <stdlib.h> #include "flash.h"
void protect_stm50flw0x0x(chipaddr bios) @@ -255,6 +256,7 @@ int total_size = flash->total_size * 1024; int page_size = flash->page_size; chipaddr bios = flash->virtual_memory; + uint8_t *tmpbuf = malloc(page_size);
printf("Programming page: \n"); for (i = 0; (i < total_size / page_size) && (rc == 0); i++) { @@ -269,8 +271,8 @@ * are not erased and rewritten; data is retained also * in sudden power off situations */ - if (!memcmp((void *)(buf + i * page_size), - (void *)(bios + i * page_size), page_size)) { + chip_readn(tmpbuf, bios + i * page_size, page_size); + if (!memcmp((void *)(buf + i * page_size), tmpbuf, page_size)) { printf("SKIPPED\n"); continue; } @@ -284,6 +286,7 @@ } printf("\n"); protect_stm50flw0x0x(bios); + free(tmpbuf);
return rc; } Index: flashrom-chip_readn_writen/flashrom.c =================================================================== --- flashrom-chip_readn_writen/flashrom.c (Revision 576) +++ flashrom-chip_readn_writen/flashrom.c (Arbeitskopie) @@ -43,9 +43,11 @@ .chip_readb = internal_chip_readb, .chip_readw = internal_chip_readw, .chip_readl = internal_chip_readl, + .chip_readn = internal_chip_readn, .chip_writeb = internal_chip_writeb, .chip_writew = internal_chip_writew, .chip_writel = internal_chip_writel, + .chip_writen = fallback_chip_writen, },
{ @@ -56,9 +58,11 @@ .chip_readb = dummy_chip_readb, .chip_readw = dummy_chip_readw, .chip_readl = dummy_chip_readl, + .chip_readn = dummy_chip_readn, .chip_writeb = dummy_chip_writeb, .chip_writew = dummy_chip_writew, .chip_writel = dummy_chip_writel, + .chip_writen = dummy_chip_writen, },
{ @@ -69,9 +73,11 @@ .chip_readb = nic3com_chip_readb, .chip_readw = fallback_chip_readw, .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, .chip_writeb = nic3com_chip_writeb, .chip_writew = fallback_chip_writew, .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, },
{ @@ -82,9 +88,11 @@ .chip_readb = satasii_chip_readb, .chip_readw = fallback_chip_readw, .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, .chip_writeb = satasii_chip_writeb, .chip_writew = fallback_chip_writew, .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, },
{ @@ -93,11 +101,13 @@ .map_flash_region = dummy_map, .unmap_flash_region = dummy_unmap, .chip_readb = dummy_chip_readb, - .chip_readw = dummy_chip_readw, - .chip_readl = dummy_chip_readl, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, .chip_writeb = dummy_chip_writeb, - .chip_writew = dummy_chip_writew, - .chip_writel = dummy_chip_writel, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, },
{}, @@ -140,6 +150,11 @@ programmer_table[programmer].chip_writel(val, addr); }
+void chip_writen(uint8_t *buf, chipaddr addr, size_t len) +{ + programmer_table[programmer].chip_writen(buf, addr, len); +} + uint8_t chip_readb(const chipaddr addr) { return programmer_table[programmer].chip_readb(addr); @@ -155,6 +170,12 @@ return programmer_table[programmer].chip_readl(addr); }
+void chip_readn(uint8_t *buf, chipaddr addr, size_t len) +{ + programmer_table[programmer].chip_readn(buf, addr, len); + return; +} + void map_flash_registers(struct flashchip *flash) { size_t size = flash->total_size * 1024; @@ -164,12 +185,7 @@
int read_memmapped(struct flashchip *flash, uint8_t *buf) { - int i; - - /* We could do a memcpy as optimization if the flash is onboard */ - //memcpy(buf, (const char *)flash->virtual_memory, flash->total_size * 1024); - for (i = 0; i < flash->total_size * 1024; i++) - buf[i] = chip_readb(flash->virtual_memory + i); + chip_readn(buf, flash->virtual_memory, flash->total_size * 1024); return 0; } @@ -774,14 +790,10 @@ */
// //////////////////////////////////////////////////////////// - /* FIXME: This memcpy will not work for SPI nor external flashers. - * Convert to chip_readb. - */ if (exclude_end_position - exclude_start_position > 0) - memcpy(buf + exclude_start_position, - (const char *)flash->virtual_memory + - exclude_start_position, - exclude_end_position - exclude_start_position); + chip_readn(buf + exclude_start_position, + flash->virtual_memory + exclude_start_position, + exclude_end_position - exclude_start_position);
exclude_start_page = exclude_start_position / flash->page_size; if ((exclude_start_position % flash->page_size) != 0) { @@ -792,6 +804,7 @@
// This should be moved into each flash part's code to do it // cleanly. This does the job. + /* FIXME: Adapt to the external flasher infrastructure. */ handle_romentries(buf, (uint8_t *) flash->virtual_memory);
// //////////////////////////////////////////////////////////// Index: flashrom-chip_readn_writen/internal.c =================================================================== --- flashrom-chip_readn_writen/internal.c (Revision 576) +++ flashrom-chip_readn_writen/internal.c (Arbeitskopie) @@ -165,6 +165,12 @@ return mmio_readl((void *) addr); }
+void internal_chip_readn(uint8_t *buf, const chipaddr addr, size_t len) +{ + memcpy(buf, (void *)addr, len); + return; +} + void mmio_writeb(uint8_t val, void *addr) { *(volatile uint8_t *) addr = val; @@ -237,3 +243,19 @@ val |= chip_readw(addr + 2) << 16; return val; } + +void fallback_chip_writen(uint8_t *buf, chipaddr addr, size_t len) +{ + size_t i; + for (i = 0; i < len; i++) + chip_writeb(buf[i], addr + i); + return; +} + +void fallback_chip_readn(uint8_t *buf, chipaddr addr, size_t len) +{ + size_t i; + for (i = 0; i < len; i++) + buf[i] = chip_readb(addr + i); + return; +} Index: flashrom-chip_readn_writen/layout.c =================================================================== --- flashrom-chip_readn_writen/layout.c (Revision 576) +++ flashrom-chip_readn_writen/layout.c (Arbeitskopie) @@ -220,6 +220,7 @@ if (rom_entries[i].included) continue;
+ /* FIXME: Adapt to the external flasher infrastructure. */ memcpy(buffer + rom_entries[i].start, content + rom_entries[i].start, rom_entries[i].end - rom_entries[i].start); Index: flashrom-chip_readn_writen/82802ab.c =================================================================== --- flashrom-chip_readn_writen/82802ab.c (Revision 576) +++ flashrom-chip_readn_writen/82802ab.c (Arbeitskopie) @@ -27,6 +27,7 @@ */
#include <string.h> +#include <stdlib.h> #include "flash.h"
// I need that Berkeley bit-map printer @@ -172,6 +173,7 @@ int total_size = flash->total_size * 1024; int page_size = flash->page_size; chipaddr bios = flash->virtual_memory; + uint8_t *tmpbuf = malloc(page_size);
printf("Programming page: \n"); for (i = 0; i < total_size / page_size; i++) { @@ -186,8 +188,8 @@ * or not erased and rewritten; their data is retained also in * sudden power off situations */ - if (!memcmp((void *)(buf + i * page_size), - (void *)(bios + i * page_size), page_size)) { + chip_readn(tmpbuf, bios + i * page_size, page_size); + if (!memcmp((void *)(buf + i * page_size), tmpbuf, page_size)) { printf("SKIPPED\n"); continue; } @@ -199,6 +201,7 @@ } printf("\n"); protect_jedec(bios); + free(tmpbuf);
return 0; }
On Fri, Jun 5, 2009 at 18:36, Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
Sometimes we want to read/write more than 4 bytes of chip content at once. Add chip_{read,write}n to the external flasher infrastructure which read/write n bytes at once.
Fix a few places where the code used memcpy/memcmp although that is strictly impossible with external flashers. Place a FIXME in the layout.c code because usage is not totally clear and needs to be fixed to support external flashers.
As a nice side benefit, we get a noticeable speedup for builtin flash reading which is now a memcpy() of the full flash area instead of a series of single-byte reads.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Urja Rannikko <urjaman@gmail.com
On Fri, Jun 05, 2009 at 05:36:06PM +0200, Carl-Daniel Hailfinger wrote:
Sometimes we want to read/write more than 4 bytes of chip content at once. Add chip_{read,write}n to the external flasher infrastructure which read/write n bytes at once.
Fix a few places where the code used memcpy/memcmp although that is strictly impossible with external flashers. Place a FIXME in the layout.c code because usage is not totally clear and needs to be fixed to support external flashers.
As a nice side benefit, we get a noticeable speedup for builtin flash reading which is now a memcpy() of the full flash area instead of a series of single-byte reads.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Uwe Hermann uwe@hermann-uwe.de
But:
- Please check the malloc() return value.
- The patch needs some adaption, doesn't apply anymore to trunk.
Other than that it looks ok.
Uwe.
On 05.06.2009 20:07, Uwe Hermann wrote:
On Fri, Jun 05, 2009 at 05:36:06PM +0200, Carl-Daniel Hailfinger wrote:
Sometimes we want to read/write more than 4 bytes of chip content at once. Add chip_{read,write}n to the external flasher infrastructure which read/write n bytes at once.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Uwe Hermann uwe@hermann-uwe.de
Thanks, committed in r579 with malloc() fixed.
Regards, Carl-Daniel