Rebased this old, rotting patch. Not tested in the last two years, but
might help to speed up some things (ftdi got pretty fast with this).
It has to be enabled per chip (see WINBOND/W25Q64.V for example).
---
chipdrivers.h | 1 +
cli_common.c | 14 +++++++++++---
flash.h | 23 ++++++++++++++---------
flashchips.c | 4 ++--
spi.c | 5 ++++-
spi25.c | 18 ++++++++++++++++++
6 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/chipdrivers.h b/chipdrivers.h
index cac94f3..f79195c 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -59,6 +59,7 @@ int spi_byte_program(struct flashctx *flash, unsigned int addr, uint8_t databyte
int spi_nbyte_program(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, 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 flashctx *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);
/* spi25_statusreg.c */
diff --git a/cli_common.c b/cli_common.c
index 71cc2dd..289d56a 100644
--- a/cli_common.c
+++ b/cli_common.c
@@ -73,17 +73,22 @@ void print_chip_support_status(const struct flashchip *chip)
if ((chip->tested.probe == BAD) || (chip->tested.probe == NT) ||
(chip->tested.read == BAD) || (chip->tested.read == NT) ||
(chip->tested.erase == BAD) || (chip->tested.erase == NT) ||
- (chip->tested.write == BAD) || (chip->tested.write == NT)){
+ (chip->tested.write == BAD) || (chip->tested.write == NT) ||
+ ((chip->feature_bits & FEATURE_UNBOUND_READ) &&
+ chip->tested.uread == BAD || chip->tested.uread == NT)) {
msg_cinfo("===\n");
if ((chip->tested.probe == BAD) ||
(chip->tested.read == BAD) ||
(chip->tested.erase == BAD) ||
- (chip->tested.write == BAD)) {
+ (chip->tested.write == BAD) ||
+ ((chip->feature_bits & FEATURE_UNBOUND_READ) && chip->tested.uread == BAD)) {
msg_cinfo("This flash part has status NOT WORKING for operations:");
if (chip->tested.probe == BAD)
msg_cinfo(" PROBE");
if (chip->tested.read == BAD)
msg_cinfo(" READ");
+ if ((chip->feature_bits & FEATURE_UNBOUND_READ) && chip->tested.uread == BAD)
+ msg_cinfo(" UNBOUND_READ");
if (chip->tested.erase == BAD)
msg_cinfo(" ERASE");
if (chip->tested.write == BAD)
@@ -93,12 +98,15 @@ void print_chip_support_status(const struct flashchip *chip)
if ((chip->tested.probe == NT) ||
(chip->tested.read == NT) ||
(chip->tested.erase == NT) ||
- (chip->tested.write == NT)) {
+ (chip->tested.write == NT) ||
+ ((chip->feature_bits & FEATURE_UNBOUND_READ) && chip->tested.uread == NT)) {
msg_cinfo("This flash part has status UNTESTED for operations:");
if (chip->tested.probe == NT)
msg_cinfo(" PROBE");
if (chip->tested.read == NT)
msg_cinfo(" READ");
+ if ((chip->feature_bits & FEATURE_UNBOUND_READ) && chip->tested.uread == NT)
+ msg_cinfo(" UNBOUND_READ");
if (chip->tested.erase == NT)
msg_cinfo(" ERASE");
if (chip->tested.write == NT)
diff --git a/flash.h b/flash.h
index 2c2839f..b3962ee 100644
--- a/flash.h
+++ b/flash.h
@@ -122,6 +122,7 @@ enum write_granularity {
#define FEATURE_WRSR_EITHER (FEATURE_WRSR_EWSR | FEATURE_WRSR_WREN)
#define FEATURE_OTP (1 << 8)
#define FEATURE_QPI (1 << 9)
+#define FEATURE_UNBOUND_READ (1 << 10)
enum test_state {
OK = 0,
@@ -131,17 +132,20 @@ enum test_state {
NA, /* Not applicable (e.g. write support on ROM chips) */
};
-#define TEST_UNTESTED (struct tested){ .probe = NT, .read = NT, .erase = NT, .write = NT }
+#define TEST_UNTESTED (struct tested){ .probe = NT, .read = NT, .uread = NT, .erase = NT, .write = NT }
-#define TEST_OK_PROBE (struct tested){ .probe = OK, .read = NT, .erase = NT, .write = NT }
-#define TEST_OK_PR (struct tested){ .probe = OK, .read = OK, .erase = NT, .write = NT }
-#define TEST_OK_PRE (struct tested){ .probe = OK, .read = OK, .erase = OK, .write = NT }
-#define TEST_OK_PREW (struct tested){ .probe = OK, .read = OK, .erase = OK, .write = OK }
+#define TEST_OK_PROBE (struct tested){ .probe = OK, .read = NT, .uread = NT, .erase = NT, .write = NT }
+#define TEST_OK_PR (struct tested){ .probe = OK, .read = OK, .uread = NT, .erase = NT, .write = NT }
+#define TEST_OK_PRU (struct tested){ .probe = OK, .read = OK, .uread = OK, .erase = NT, .write = NT }
+#define TEST_OK_PRE (struct tested){ .probe = OK, .read = OK, .uread = NT, .erase = OK, .write = NT }
+#define TEST_OK_PRUE (struct tested){ .probe = OK, .read = OK, .uread = OK, .erase = OK, .write = NT }
+#define TEST_OK_PREW (struct tested){ .probe = OK, .read = OK, .uread = NT, .erase = OK, .write = OK }
+#define TEST_OK_PRUEW (struct tested){ .probe = OK, .read = OK, .uread = OK, .erase = OK, .write = OK }
-#define TEST_BAD_PROBE (struct tested){ .probe = BAD, .read = NT, .erase = NT, .write = NT }
-#define TEST_BAD_PR (struct tested){ .probe = BAD, .read = BAD, .erase = NT, .write = NT }
-#define TEST_BAD_PRE (struct tested){ .probe = BAD, .read = BAD, .erase = BAD, .write = NT }
-#define TEST_BAD_PREW (struct tested){ .probe = BAD, .read = BAD, .erase = BAD, .write = BAD }
+#define TEST_BAD_PROBE (struct tested){ .probe = BAD, .read = NT, .uread = NT, .erase = NT, .write = NT }
+#define TEST_BAD_PR (struct tested){ .probe = BAD, .read = BAD, .uread = NT, .erase = NT, .write = NT }
+#define TEST_BAD_PRE (struct tested){ .probe = BAD, .read = BAD, .uread = NT, .erase = BAD, .write = NT }
+#define TEST_BAD_PREW (struct tested){ .probe = BAD, .read = BAD, .uread = NT, .erase = BAD, .write = BAD }
struct flashctx;
typedef int (erasefunc_t)(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
@@ -170,6 +174,7 @@ struct flashchip {
struct tested {
enum test_state probe;
enum test_state read;
+ enum test_state uread;
enum test_state erase;
enum test_state write;
} tested;
diff --git a/flashchips.c b/flashchips.c
index 574ad74..be6383b 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -13961,8 +13961,8 @@ const struct flashchip flashchips[] = {
.page_size = 256,
/* supports SFDP */
/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
- .tested = TEST_OK_PREW,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_UNBOUND_READ,
+ .tested = TEST_OK_PRUEW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
diff --git a/spi.c b/spi.c
index 894f73f..a7da50a 100644
--- a/spi.c
+++ b/spi.c
@@ -85,7 +85,10 @@ int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start,
"flashrom(a)flashrom.org\n", __func__);
return 1;
}
- return spi_read_chunked(flash, buf, start, len, max_data);
+ if (flash->chip->feature_bits & FEATURE_UNBOUND_READ)
+ return spi_read_unbound(flash, buf, start, len, max_data);
+ else
+ return spi_read_chunked(flash, buf, start, len, max_data);
}
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 af4b6db..34fd7d5 100644
--- a/spi25.c
+++ b/spi25.c
@@ -978,6 +978,24 @@ int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
}
/*
+ * Read a part of the flash chip.
+ * Ignore pages as we shall 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) {
+ rc = spi_nbyte_read(flash, i, buf + (i - start), min(chunksize, start + len - i));
+ if (rc)
+ 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.
--
2.4.6