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.
Corresponding to flashrom svn r579.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Urja Rannikko <urjaman@gmail.com>
Acked-by: Uwe Hermann <uwe@hermann-uwe.de>
diff --git a/82802ab.c b/82802ab.c
index c5cf52f..1dc997f 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -27,6 +27,7 @@
*/
#include <string.h>
+#include <stdlib.h>
#include "flash.h"
// I need that Berkeley bit-map printer
@@ -172,7 +173,12 @@
int total_size = flash->total_size * 1024;
int page_size = flash->page_size;
chipaddr bios = flash->virtual_memory;
+ uint8_t *tmpbuf = malloc(page_size);
+ if (!tmpbuf) {
+ printf("Could not allocate memory!\n");
+ exit(1);
+ }
printf("Programming page: \n");
for (i = 0; i < total_size / page_size; i++) {
printf
@@ -186,8 +192,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 +205,7 @@
}
printf("\n");
protect_jedec(bios);
+ free(tmpbuf);
return 0;
}
diff --git a/dummyflasher.c b/dummyflasher.c
index 784cc55..64b083e 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -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)
{
diff --git a/flash.h b/flash.h
index 31c2fed..3111dbf 100644
--- a/flash.h
+++ b/flash.h
@@ -100,10 +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);
void (*delay) (int usecs);
};
@@ -117,9 +118,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);
void programmer_delay(int usecs);
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
@@ -649,6 +652,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);
@@ -660,8 +664,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
@@ -675,9 +681,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);
diff --git a/flashrom.c b/flashrom.c
index 7368d4f..20532e8 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -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,
.delay = internal_delay,
},
@@ -57,9 +59,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,
.delay = internal_delay,
},
@@ -71,9 +75,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,
.delay = internal_delay,
},
@@ -85,9 +91,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,
.delay = internal_delay,
},
@@ -97,11 +105,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,
.delay = internal_delay,
},
@@ -145,6 +155,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);
@@ -160,6 +175,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 programmer_delay(int usecs)
{
programmer_table[programmer].delay(usecs);
@@ -174,12 +195,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;
}
@@ -784,14 +800,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) {
@@ -802,6 +814,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);
// ////////////////////////////////////////////////////////////
diff --git a/internal.c b/internal.c
index d24bb34..302c7a9 100644
--- a/internal.c
+++ b/internal.c
@@ -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;
@@ -249,3 +255,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;
+}
diff --git a/layout.c b/layout.c
index 4326aea..68684a7 100644
--- a/layout.c
+++ b/layout.c
@@ -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);
diff --git a/stm50flw0x0x.c b/stm50flw0x0x.c
index 5ca769b..83c95bb 100644
--- a/stm50flw0x0x.c
+++ b/stm50flw0x0x.c
@@ -27,6 +27,7 @@
*/
#include <string.h>
+#include <stdlib.h>
#include "flash.h"
void protect_stm50flw0x0x(chipaddr bios)
@@ -255,7 +256,12 @@
int total_size = flash->total_size * 1024;
int page_size = flash->page_size;
chipaddr bios = flash->virtual_memory;
+ uint8_t *tmpbuf = malloc(page_size);
+ if (!tmpbuf) {
+ printf("Could not allocate memory!\n");
+ exit(1);
+ }
printf("Programming page: \n");
for (i = 0; (i < total_size / page_size) && (rc == 0); i++) {
printf
@@ -269,8 +275,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 +290,7 @@
}
printf("\n");
protect_stm50flw0x0x(bios);
+ free(tmpbuf);
return rc;
}