summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chipdrivers.h1
-rw-r--r--dediprog.c29
-rw-r--r--spi25.c2
3 files changed, 26 insertions, 6 deletions
diff --git a/chipdrivers.h b/chipdrivers.h
index 134ed265c..e380878d0 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -58,6 +58,7 @@ int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, u
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);
+int spi_set_extended_address(struct flashctx *, uint8_t addr_high);
/* spi25_statusreg.c */
diff --git a/dediprog.c b/dediprog.c
index 03675e57a..d48c541ec 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -360,7 +360,7 @@ static int dediprog_set_spi_speed(unsigned int spispeed_idx)
return 0;
}
-static void prepare_rw_cmd(
+static int prepare_rw_cmd(
struct flashctx *const flash, uint8_t *data_packet, unsigned int count,
uint8_t dedi_spi_cmd, unsigned int *value, unsigned int *idx, unsigned int start, int is_read) {
/* First 5 bytes are common in both generations. */
@@ -400,9 +400,23 @@ static void prepare_rw_cmd(
}
}
} else {
- *value = start % 0x10000;
- *idx = start / 0x10000;
+ if (flash->chip->feature_bits & FEATURE_4BA_EXT_ADDR) {
+ if (spi_set_extended_address(flash, start >> 24))
+ return 1;
+ } else if (start >> 24) {
+ msg_cerr("Can't handle 4-byte address with dediprog.\n");
+ return 1;
+ }
+ /*
+ * We don't know how the dediprog firmware handles 4-byte
+ * addresses. So let's not tell it what we are doing and
+ * only send the lower 3 bytes.
+ */
+ *value = start & 0xffff;
+ *idx = (start >> 16) & 0xff;
}
+
+ return 0;
}
/* Bulk read interface, will read multiple 512 byte chunks aligned to 512 bytes.
@@ -448,7 +462,8 @@ static int dediprog_spi_bulk_read(struct flashctx *flash, uint8_t *buf, unsigned
uint8_t data_packet[command_packet_size];
unsigned int value, idx;
- prepare_rw_cmd(flash, data_packet, count, READ_MODE_STD, &value, &idx, start, 1);
+ if (prepare_rw_cmd(flash, data_packet, count, READ_MODE_STD, &value, &idx, start, 1))
+ return 1;
int ret = dediprog_write(CMD_READ, value, idx, data_packet, sizeof(data_packet));
if (ret != sizeof(data_packet)) {
@@ -604,7 +619,8 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, const uint8_t *buf, u
uint8_t data_packet[command_packet_size];
unsigned int value, idx;
- prepare_rw_cmd(flash, data_packet, count, dedi_spi_cmd, &value, &idx, start, 0);
+ if (prepare_rw_cmd(flash, data_packet, count, dedi_spi_cmd, &value, &idx, start, 0))
+ return 1;
int ret = dediprog_write(CMD_WRITE, value, idx, data_packet, sizeof(data_packet));
if (ret != sizeof(data_packet)) {
msg_perr("Command Write SPI Bulk failed, %s!\n", libusb_error_name(ret));
@@ -1134,6 +1150,9 @@ int dediprog_init(void)
if (dediprog_standalone_mode())
return 1;
+ if (dediprog_devicetype == DEV_SF100 && protocol() == PROTOCOL_V1)
+ spi_master_dediprog.features &= ~SPI_MASTER_NO_4BA_MODES;
+
if (dediprog_devicetype == DEV_SF600 && protocol() == PROTOCOL_V2)
spi_master_dediprog.features |= SPI_MASTER_4BA;
diff --git a/spi25.c b/spi25.c
index 8b6c46264..fd87dc9a5 100644
--- a/spi25.c
+++ b/spi25.c
@@ -363,7 +363,7 @@ static int spi_write_extended_address_register(struct flashctx *const flash, con
return result;
}
-static int spi_set_extended_address(struct flashctx *const flash, const uint8_t addr_high)
+int spi_set_extended_address(struct flashctx *const flash, const uint8_t addr_high)
{
if (flash->address_high_byte != addr_high &&
spi_write_extended_address_register(flash, addr_high))