aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chipdrivers.h6
-rw-r--r--flash.h10
-rw-r--r--flashchips.c15
-rw-r--r--flashrom.c12
-rw-r--r--spi25.c39
5 files changed, 35 insertions, 47 deletions
diff --git a/chipdrivers.h b/chipdrivers.h
index d7a4aa94..8405220d 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -61,10 +61,8 @@ int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int st
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_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize);
-int spi_enter_4ba_b7(struct flashctx *flash);
-int spi_enter_4ba_b7_we(struct flashctx *flash);
-int spi_exit_4ba_e9(struct flashctx *flash);
-int spi_exit_4ba_e9_we(struct flashctx *flash);
+int spi_enter_4ba(struct flashctx *flash);
+int spi_exit_4ba(struct flashctx *flash);
/* spi25_statusreg.c */
diff --git a/flash.h b/flash.h
index a14c3029..6e86c354 100644
--- a/flash.h
+++ b/flash.h
@@ -119,11 +119,12 @@ 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_4BA_SUPPORT (1 << 10)
-#define FEATURE_4BA_EXT_ADDR (1 << 11) /**< Regular 3-byte operations can be used by writing the most
+#define FEATURE_4BA_ENTER (1 << 10) /**< Can enter/exit 4BA mode with instructions 0xb7/0xe9 w/o WREN */
+#define FEATURE_4BA_ENTER_WREN (1 << 11) /**< Can enter/exit 4BA mode with instructions 0xb7/0xe9 after WREN */
+#define FEATURE_4BA_EXT_ADDR (1 << 12) /**< Regular 3-byte operations can be used by writing the most
significant address byte into an extended address register. */
-#define FEATURE_4BA_READ (1 << 12) /**< Native 4BA read instruction (0x13) is supported. */
-#define FEATURE_4BA_WRITE (1 << 13) /**< Native 4BA byte program (0x12) is supported. */
+#define FEATURE_4BA_READ (1 << 13) /**< Native 4BA read instruction (0x13) is supported. */
+#define FEATURE_4BA_WRITE (1 << 14) /**< Native 4BA byte program (0x12) is supported. */
enum test_state {
OK = 0,
@@ -205,7 +206,6 @@ struct flashchip {
int (*unlock) (struct flashctx *flash);
int (*write) (struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
- int (*set_4ba) (struct flashctx *flash);
struct voltage {
uint16_t min;
uint16_t max;
diff --git a/flashchips.c b/flashchips.c
index c8ea5eb9..0e16a48c 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -8134,7 +8134,7 @@ const struct flashchip flashchips[] = {
.total_size = 32768,
.page_size = 256,
/* OTP: 512B total; enter 0xB1, exit 0xC1 */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_SUPPORT,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_ENTER,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -8162,7 +8162,6 @@ const struct flashchip flashchips[] = {
.unlock = spi_disable_blockprotect_bp3_srwd,
.write = spi_chip_write_256,
.read = spi_chip_read, /* Fast read (0x0B) supported */
- .set_4ba = spi_enter_4ba_b7,
.voltage = {2700, 3600},
},
@@ -8175,7 +8174,7 @@ const struct flashchip flashchips[] = {
.total_size = 65536,
.page_size = 256,
/* OTP: 512B total; enter 0xB1, exit 0xC1 */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_SUPPORT,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_ENTER,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -8203,7 +8202,6 @@ const struct flashchip flashchips[] = {
.unlock = spi_disable_blockprotect_bp3_srwd,
.write = spi_chip_write_256,
.read = spi_chip_read, /* Fast read (0x0B) supported */
- .set_4ba = spi_enter_4ba_b7,
.voltage = {2700, 3600},
},
@@ -9916,7 +9914,8 @@ const struct flashchip flashchips[] = {
.page_size = 256,
/* supports SFDP */
/* OTP: 64B total; read 0x4B, write 0x42 */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_SUPPORT | FEATURE_4BA_READ | FEATURE_4BA_WRITE,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP
+ | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_READ | FEATURE_4BA_WRITE,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -9949,7 +9948,8 @@ const struct flashchip flashchips[] = {
.page_size = 256,
/* supports SFDP */
/* OTP: 64B total; read 0x4B, write 0x42 */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_SUPPORT | FEATURE_4BA_READ | FEATURE_4BA_WRITE,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP
+ | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_READ | FEATURE_4BA_WRITE,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -14827,7 +14827,7 @@ const struct flashchip flashchips[] = {
/* supports SFDP */
/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
/* FOUR_BYTE_ADDR: supports 4-bytes addressing mode */
- .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_SUPPORT | FEATURE_4BA_READ,
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_READ,
.tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
@@ -14854,7 +14854,6 @@ const struct flashchip flashchips[] = {
.unlock = spi_disable_blockprotect,
.write = spi_chip_write_256,
.read = spi_chip_read,
- .set_4ba = spi_enter_4ba_b7_we,
.voltage = {2700, 3600},
},
diff --git a/flashrom.c b/flashrom.c
index 9cc1be66..ac987fd9 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -42,6 +42,7 @@
#include "flashchips.h"
#include "programmer.h"
#include "hwaccess.h"
+#include "chipdrivers.h"
const char flashrom_version[] = FLASHROM_VERSION;
const char *chip_to_probe = NULL;
@@ -2219,9 +2220,14 @@ int prepare_flash_access(struct flashctx *const flash,
flash->in_4ba_mode = false;
/* Enable/disable 4-byte addressing mode if flash chip supports it */
- if ((flash->chip->feature_bits & FEATURE_4BA_SUPPORT) && flash->chip->set_4ba) {
- if (flash->chip->set_4ba(flash)) {
- msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
+ if (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN)) {
+ int ret;
+ if (spi_master_4ba(flash))
+ ret = spi_enter_4ba(flash);
+ else
+ ret = spi_exit_4ba(flash);
+ if (ret) {
+ msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
return 1;
}
}
diff --git a/spi25.c b/spi25.c
index 787f62e3..00e0992c 100644
--- a/spi25.c
+++ b/spi25.c
@@ -843,42 +843,27 @@ bailout:
return SPI_GENERIC_ERROR;
}
-/* Enter 4-bytes addressing mode (without sending WREN before) */
-int spi_enter_4ba_b7(struct flashctx *flash)
+static int spi_enter_exit_4ba(struct flashctx *const flash, const bool enter)
{
- const unsigned char cmd = JEDEC_ENTER_4_BYTE_ADDR_MODE;
+ const unsigned char cmd = enter ? JEDEC_ENTER_4_BYTE_ADDR_MODE : JEDEC_EXIT_4_BYTE_ADDR_MODE;
+ int ret = 1;
- const int ret = spi_send_command(flash, sizeof(cmd), 0, &cmd, NULL);
- if (!ret)
- flash->in_4ba_mode = true;
- return ret;
-}
+ if (flash->chip->feature_bits & FEATURE_4BA_ENTER)
+ ret = spi_send_command(flash, sizeof(cmd), 0, &cmd, NULL);
+ else if (flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN)
+ ret = spi_simple_write_cmd(flash, cmd, 0);
-/* Enter 4-bytes addressing mode with sending WREN before */
-int spi_enter_4ba_b7_we(struct flashctx *flash)
-{
- const int ret = spi_simple_write_cmd(flash, JEDEC_ENTER_4_BYTE_ADDR_MODE, 0);
if (!ret)
- flash->in_4ba_mode = true;
+ flash->in_4ba_mode = enter;
return ret;
}
-/* Exit 4-bytes addressing mode (without sending WREN before) */
-int spi_exit_4ba_e9(struct flashctx *flash)
+int spi_enter_4ba(struct flashctx *const flash)
{
- const unsigned char cmd = JEDEC_EXIT_4_BYTE_ADDR_MODE;
-
- const int ret = spi_send_command(flash, sizeof(cmd), 0, &cmd, NULL);
- if (!ret)
- flash->in_4ba_mode = false;
- return ret;
+ return spi_enter_exit_4ba(flash, true);
}
-/* Exit 4-bytes addressing mode with sending WREN before */
-int spi_exit_4ba_e9_we(struct flashctx *flash)
+int spi_exit_4ba(struct flashctx *flash)
{
- const int ret = spi_simple_write_cmd(flash, JEDEC_EXIT_4_BYTE_ADDR_MODE, 0);
- if (!ret)
- flash->in_4ba_mode = false;
- return ret;
+ return spi_enter_exit_4ba(flash, false);
}