Edward O'Callaghan has uploaded this change for review.

View Change

Add support for continuous SPI reads

Forward port the original patch from Duncan Laurie <dlaurie@chromium.org>
in commit 06ffd5263892061c5ebf46e52b7878786cf2cece so that it fits for
upstream consumption.

This patch adds support for "unbounded reads" which are for continous
reads to a SPI flash chip instead of reading in page size blocks.

This speeds up the flash process over FTDI by quite a bit, testing
the read of a 16MB part it goes from 2m11s to 0m15s.

Change-Id: I804545aeb1b827ffdd41b21024fd618475e8263a
Signed-off-by: Edward O'Callaghan <quasisec@chromium.org>
---
M chipdrivers.h
M flash.h
M spi.c
M spi25.c
4 files changed, 40 insertions(+), 1 deletion(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/84/34584/1
diff --git a/chipdrivers.h b/chipdrivers.h
index e380878..77e1943 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -55,6 +55,7 @@
int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
int spi_nbyte_read(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len);
int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize);
+int spi_read_unbound(struct flashchip *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize);
int spi_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize);
int spi_enter_4ba(struct flashctx *flash);
int spi_exit_4ba(struct flashctx *flash);
diff --git a/flash.h b/flash.h
index b60a980..981f88b 100644
--- a/flash.h
+++ b/flash.h
@@ -143,6 +143,8 @@

#define ERASED_VALUE(flash) (((flash)->chip->feature_bits & FEATURE_ERASED_ZERO) ? 0x00 : 0xff)

+#define FEATURE_UNBOUND_READ (1 << 19)
+
enum test_state {
OK = 0,
NT = 1, /* Not tested */
diff --git a/spi.c b/spi.c
index 489baf3..23f4cfe 100644
--- a/spi.c
+++ b/spi.c
@@ -75,13 +75,18 @@
unsigned int len)
{
unsigned int max_data = flash->mst->spi.max_data_read;
+ int rc;
if (max_data == MAX_DATA_UNSPECIFIED) {
msg_perr("%s called, but SPI read chunk size not defined "
"on this hardware. Please report a bug at "
"flashrom@flashrom.org\n", __func__);
return 1;
}
- return spi_read_chunked(flash, buf, start, len, max_data);
+ if (flash->feature_bits & FEATURE_UNBOUND_READ)
+ rc = spi_read_unbound(flash, buf, start, len, max_data);
+ else
+ rc = spi_read_chunked(flash, buf, start, len, max_data);
+ return rc;
}

int default_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
diff --git a/spi25.c b/spi25.c
index 2a1d492..3327110 100644
--- a/spi25.c
+++ b/spi25.c
@@ -659,6 +659,37 @@
}

/*
+ * Read a part of the flash chip.
+ * Ignore pages and read the data continuously, the only bound is the chunksize.
+ */
+int spi_read_unbound(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize)
+{
+ int rc = 0;
+ unsigned int i;
+
+ for (i = start; i < (start + len); i += chunksize) {
+ int chunk_status = 0;
+ unsigned int toread = min(chunksize, start + len - i);
+
+ chunk_status = spi_nbyte_read(flash, i, buf + (i - start), toread);
+ if (chunk_status) {
+ if (ignore_error(chunk_status)) {
+ /* fill this chunk with 0xff bytes and
+ let caller know about the error */
+ memset(buf + (i - start), 0xff, toread);
+ rc = chunk_status;
+ continue;
+ } else {
+ rc = chunk_status;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
* Write a part of the flash chip.
* FIXME: Use the chunk code from Michael Karcher instead.
* Each page is written separately in chunks with a maximum size of chunksize.

To view, visit change 34584. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I804545aeb1b827ffdd41b21024fd618475e8263a
Gerrit-Change-Number: 34584
Gerrit-PatchSet: 1
Gerrit-Owner: Edward O'Callaghan <quasisec@chromium.org>
Gerrit-MessageType: newchange