summaryrefslogtreecommitdiffstats
path: root/spi25.c
diff options
context:
space:
mode:
Diffstat (limited to 'spi25.c')
-rw-r--r--spi25.c131
1 files changed, 75 insertions, 56 deletions
diff --git a/spi25.c b/spi25.c
index 213273f21..6a6ee75da 100644
--- a/spi25.c
+++ b/spi25.c
@@ -37,7 +37,7 @@ enum id_type {
};
static struct {
- int is_cached;
+ bool is_cached;
unsigned char bytes[4]; /* enough to hold largest ID type */
} id_cache[NUM_ID_TYPES];
@@ -141,7 +141,7 @@ static int compare_id(const struct flashctx *flash, uint32_t id1, uint32_t id2)
{
const struct flashchip *chip = flash->chip;
- msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
+ msg_cdbg("%s: id1 0x%02"PRIx32", id2 0x%02"PRIx32"\n", __func__, id1, id2);
if (id1 == chip->manufacture_id && id2 == chip->model_id)
return 1;
@@ -167,7 +167,7 @@ static int probe_spi_rdid_generic(struct flashctx *flash, int bytes)
msg_cinfo("%d byte RDID not supported on this SPI controller\n", bytes);
if (ret)
return 0;
- id_cache[idty].is_cached = 1;
+ id_cache[idty].is_cached = true;
}
rdid_get_ids(id_cache[idty].bytes, bytes, &id1, &id2);
@@ -191,7 +191,7 @@ int probe_spi_rems(struct flashctx *flash)
if (!id_cache[REMS].is_cached) {
if (spi_rems(flash, id_cache[REMS].bytes))
return 0;
- id_cache[REMS].is_cached = 1;
+ id_cache[REMS].is_cached = true;
}
id1 = id_cache[REMS].bytes[0];
@@ -232,7 +232,7 @@ int probe_spi_res1(struct flashctx *flash)
id2 = readarr[0];
- msg_cdbg("%s: id 0x%x\n", __func__, id2);
+ msg_cdbg("%s: id 0x%"PRIx32"\n", __func__, id2);
if (id2 != flash->chip->model_id)
return 0;
@@ -247,12 +247,12 @@ int probe_spi_res2(struct flashctx *flash)
if (!id_cache[RES2].is_cached) {
if (spi_res(flash, id_cache[RES2].bytes, 2))
return 0;
- id_cache[RES2].is_cached = 1;
+ id_cache[RES2].is_cached = true;
}
id1 = id_cache[RES2].bytes[0];
id2 = id_cache[RES2].bytes[1];
- msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
+ msg_cdbg("%s: id1 0x%"PRIx32", id2 0x%"PRIx32"\n", __func__, id1, id2);
if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
return 0;
@@ -267,12 +267,12 @@ int probe_spi_res3(struct flashctx *flash)
if (!id_cache[RES3].is_cached) {
if (spi_res(flash, id_cache[RES3].bytes, 3))
return 0;
- id_cache[RES3].is_cached = 1;
+ id_cache[RES3].is_cached = true;
}
id1 = (id_cache[RES3].bytes[0] << 8) | id_cache[RES3].bytes[1];
id2 = id_cache[RES3].bytes[3];
- msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
+ msg_cdbg("%s: id1 0x%"PRIx32", id2 0x%"PRIx32"\n", __func__, id1, id2);
if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
return 0;
@@ -294,7 +294,7 @@ int probe_spi_at25f(struct flashctx *flash)
id1 = readarr[0];
id2 = readarr[1];
- msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
+ msg_cdbg("%s: id1 0x%02"PRIx32", id2 0x%02"PRIx32"\n", __func__, id1, id2);
if (id1 == flash->chip->manufacture_id && id2 == flash->chip->model_id)
return 1;
@@ -304,12 +304,17 @@ int probe_spi_at25f(struct flashctx *flash)
static int spi_poll_wip(struct flashctx *const flash, const unsigned int poll_delay)
{
- /* FIXME: We can't tell if spi_read_status_register() failed. */
/* FIXME: We don't time out. */
- while (spi_read_status_register(flash) & SPI_SR_WIP)
- programmer_delay(poll_delay);
- /* FIXME: Check the status register for errors. */
- return 0;
+ while (true) {
+ uint8_t status;
+ int ret = spi_read_register(flash, STATUS1, &status);
+ if (ret)
+ return ret;
+ if (!(status & SPI_SR_WIP))
+ return 0;
+
+ programmer_delay(flash, poll_delay);
+ }
}
/**
@@ -346,7 +351,16 @@ static int spi_simple_write_cmd(struct flashctx *const flash, const uint8_t op,
static int spi_write_extended_address_register(struct flashctx *const flash, const uint8_t regdata)
{
- const uint8_t op = flash->chip->wrea_override ? : JEDEC_WRITE_EXT_ADDR_REG;
+ uint8_t op;
+ if (flash->chip->feature_bits & FEATURE_4BA_EAR_C5C8) {
+ op = JEDEC_WRITE_EXT_ADDR_REG;
+ } else if (flash->chip->feature_bits & FEATURE_4BA_EAR_1716) {
+ op = ALT_WRITE_EXT_ADDR_REG_17;
+ } else {
+ msg_cerr("Flash misses feature flag for extended-address register.\n");
+ return -1;
+ }
+
struct spi_command cmds[] = {
{
.readarr = 0,
@@ -389,7 +403,7 @@ static int spi_prepare_address(struct flashctx *const flash, uint8_t cmd_buf[],
cmd_buf[4] = (addr >> 0) & 0xff;
return 4;
} else {
- if (flash->chip->feature_bits & FEATURE_4BA_EXT_ADDR) {
+ if (flash->chip->feature_bits & FEATURE_4BA_EAR_ANY) {
if (spi_set_extended_address(flash, addr >> 24))
return -1;
} else if (addr >> 24) {
@@ -584,6 +598,13 @@ int spi_block_erase_21(struct flashctx *flash, unsigned int addr, unsigned int b
}
/* Erase 32 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */
+int spi_block_erase_53(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
+{
+ /* This usually takes 100-4000ms, so wait in 100ms steps. */
+ return spi_write_cmd(flash, 0x53, true, addr, NULL, 0, 100 * 1000);
+}
+
+/* Erase 32 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */
int spi_block_erase_5c(struct flashctx *flash, unsigned int addr, unsigned int blocklen)
{
/* This usually takes 100-4000ms, so wait in 100ms steps. */
@@ -597,46 +618,37 @@ int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int b
return spi_write_cmd(flash, 0xdc, true, addr, NULL, 0, 100 * 1000);
}
-erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode)
-{
- switch(opcode){
- case 0xff:
- case 0x00:
- /* Not specified, assuming "not supported". */
- return NULL;
- case 0x20:
- return &spi_block_erase_20;
- case 0x21:
- return &spi_block_erase_21;
- case 0x50:
- return &spi_block_erase_50;
- case 0x52:
- return &spi_block_erase_52;
- case 0x5c:
- return &spi_block_erase_5c;
- case 0x60:
- return &spi_block_erase_60;
- case 0x62:
- return &spi_block_erase_62;
- case 0x81:
- return &spi_block_erase_81;
- case 0xc4:
- return &spi_block_erase_c4;
- case 0xc7:
- return &spi_block_erase_c7;
- case 0xd7:
- return &spi_block_erase_d7;
- case 0xd8:
- return &spi_block_erase_d8;
- case 0xdb:
- return &spi_block_erase_db;
- case 0xdc:
- return &spi_block_erase_dc;
- default:
- msg_cinfo("%s: unknown erase opcode (0x%02x). Please report "
- "this at flashrom@flashrom.org\n", __func__, opcode);
- return NULL;
+static const struct {
+ enum block_erase_func func;
+ uint8_t opcode;
+} spi25_function_opcode_list[] = {
+ {SPI_BLOCK_ERASE_20, 0x20},
+ {SPI_BLOCK_ERASE_21, 0x21},
+ {SPI_BLOCK_ERASE_50, 0x50},
+ {SPI_BLOCK_ERASE_52, 0x52},
+ {SPI_BLOCK_ERASE_53, 0x53},
+ {SPI_BLOCK_ERASE_5C, 0x5c},
+ {SPI_BLOCK_ERASE_60, 0x60},
+ {SPI_BLOCK_ERASE_62, 0x62},
+ {SPI_BLOCK_ERASE_81, 0x81},
+ {SPI_BLOCK_ERASE_C4, 0xc4},
+ {SPI_BLOCK_ERASE_C7, 0xc7},
+ {SPI_BLOCK_ERASE_D7, 0xd7},
+ {SPI_BLOCK_ERASE_D8, 0xd8},
+ {SPI_BLOCK_ERASE_DB, 0xdb},
+ {SPI_BLOCK_ERASE_DC, 0xdc},
+};
+
+enum block_erase_func spi25_get_erasefn_from_opcode(uint8_t opcode)
+{
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(spi25_function_opcode_list); i++) {
+ if (spi25_function_opcode_list[i].opcode == opcode)
+ return spi25_function_opcode_list[i].func;
}
+ msg_cinfo("%s: unknown erase opcode (0x%02x). Please report "
+ "this at flashrom@flashrom.org\n", __func__, opcode);
+ return NO_BLOCK_ERASE_FUNC;
}
static int spi_nbyte_program(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, unsigned int len)
@@ -669,11 +681,14 @@ int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start,
{
int ret;
size_t to_read;
+ size_t start_address = start;
+ size_t end_address = len - start;
for (; len; len -= to_read, buf += to_read, start += to_read) {
to_read = min(chunksize, len);
ret = spi_nbyte_read(flash, start, buf, to_read);
if (ret)
return ret;
+ update_progress(flash, FLASHROM_PROGRESS_READ, start - start_address + to_read, end_address);
}
return 0;
}
@@ -693,6 +708,8 @@ int spi_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int s
* we're OK for now.
*/
unsigned int page_size = flash->chip->page_size;
+ size_t start_address = start;
+ size_t end_address = len - start;
/* Warning: This loop has a very unusual condition and body.
* The loop needs to go through each page with at least one affected
@@ -717,6 +734,7 @@ int spi_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int s
if (rc)
return rc;
}
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, start - start_address + lenhere, end_address);
}
return 0;
@@ -736,6 +754,7 @@ int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int st
for (i = start; i < start + len; i++) {
if (spi_nbyte_program(flash, i, buf + i - start, 1))
return 1;
+ update_progress(flash, FLASHROM_PROGRESS_WRITE, i - start, len - start);
}
return 0;
}