flashchips,spi25: Replace `.wrea_override` with FEATURE_4BA_EAR_1716

There are two competing sets of instructions to access the extended
address register of 4BA SPI chips. Some chips even support both sets.

So far, we assumed the 0xc5/0xc8 instructions by default and allowed
to override the write instructions with the `.wrea_override` field.
This has some disadvantages:

* The additional field is easily overlooked. So when adding a new
  flash chip, one might assume only 0xc5/0xc8 are supported.

* We cannot describe flash chips completely that allow both
  instructions (and some programmers may be picky about which
  instructions can be used).

Therefore, replace the `.wrea_override` field with a feature flag.

Signed-off-by: Nico Huber <nico.h@gmx.de>
Change-Id: I6d82f24898acd0789203516a7456fd785907bc10
Ticket: https://ticket.coreboot.org/issues/357
Original-Reviewed-on: https://review.coreboot.org/c/flashrom/+/64636
Original-Reviewed-by: Thomas Heijligen <src@posteo.de>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/70993
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/dediprog.c b/dediprog.c
index abd0e0f..2c0b125 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -408,7 +408,7 @@
 			}
 		}
 	} else {
-		if (flash->chip->feature_bits & FEATURE_4BA_EAR_C5C8) {
+		if (flash->chip->feature_bits & FEATURE_4BA_EAR_ANY) {
 			if (spi_set_extended_address(flash, start >> 24))
 				return 1;
 		} else if (start >> 24) {
diff --git a/flash.h b/flash.h
index 29da202..41d8b97 100644
--- a/flash.h
+++ b/flash.h
@@ -130,10 +130,12 @@
 #define FEATURE_4BA_EAR_C5C8	(1 << 13) /**< Regular 3-byte operations can be used by writing the most
 					       significant address byte into an extended address register
 					       (using 0xc5/0xc8 instructions). */
-#define FEATURE_4BA_READ	(1 << 14) /**< Native 4BA read instruction (0x13) is supported. */
-#define FEATURE_4BA_FAST_READ	(1 << 15) /**< Native 4BA fast read instruction (0x0c) is supported. */
-#define FEATURE_4BA_WRITE	(1 << 16) /**< Native 4BA byte program (0x12) is supported. */
+#define FEATURE_4BA_EAR_1716	(1 << 14) /**< Like FEATURE_4BA_EAR_C5C8 but with 0x17/0x16 instructions. */
+#define FEATURE_4BA_READ	(1 << 15) /**< Native 4BA read instruction (0x13) is supported. */
+#define FEATURE_4BA_FAST_READ	(1 << 16) /**< Native 4BA fast read instruction (0x0c) is supported. */
+#define FEATURE_4BA_WRITE	(1 << 17) /**< Native 4BA byte program (0x12) is supported. */
 /* 4BA Shorthands */
+#define FEATURE_4BA_EAR_ANY	(FEATURE_4BA_EAR_C5C8 | FEATURE_4BA_EAR_1716)
 #define FEATURE_4BA_NATIVE	(FEATURE_4BA_READ | FEATURE_4BA_FAST_READ | FEATURE_4BA_WRITE)
 #define FEATURE_4BA		(FEATURE_4BA_ENTER | FEATURE_4BA_EAR_C5C8 | FEATURE_4BA_NATIVE)
 #define FEATURE_4BA_WREN	(FEATURE_4BA_ENTER_WREN | FEATURE_4BA_EAR_C5C8 | FEATURE_4BA_NATIVE)
@@ -142,13 +144,13 @@
  * Most flash chips are erased to ones and programmed to zeros. However, some
  * other flash chips, such as the ENE KB9012 internal flash, work the opposite way.
  */
-#define FEATURE_ERASED_ZERO	(1 << 17)
-#define FEATURE_NO_ERASE	(1 << 18)
+#define FEATURE_ERASED_ZERO	(1 << 18)
+#define FEATURE_NO_ERASE	(1 << 19)
 
-#define FEATURE_WRSR_EXT2	(1 << 19)
-#define FEATURE_WRSR2		(1 << 20)
-#define FEATURE_WRSR_EXT3	((1 << 21) | FEATURE_WRSR_EXT2)
-#define FEATURE_WRSR3		(1 << 22)
+#define FEATURE_WRSR_EXT2	(1 << 20)
+#define FEATURE_WRSR2		(1 << 21)
+#define FEATURE_WRSR_EXT3	((1 << 22) | FEATURE_WRSR_EXT2)
+#define FEATURE_WRSR3		(1 << 23)
 
 #define ERASED_VALUE(flash)	(((flash)->chip->feature_bits & FEATURE_ERASED_ZERO) ? 0x00 : 0xff)
 
@@ -278,9 +280,6 @@
 	} voltage;
 	enum write_granularity gran;
 
-	/* SPI specific options (TODO: Make it a union in case other bustypes get specific options.) */
-	uint8_t wrea_override; /**< override opcode for write extended address register */
-
 	struct reg_bit_map {
 		/* Status register protection bit (SRP) */
 		struct reg_bit_info srp;
diff --git a/flashchips.c b/flashchips.c
index 736f1b3..267009c 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -16639,7 +16639,8 @@
 		.total_size	= 32768,
 		.page_size	= 256,
 		/* OTP: 1024B total, 32B reserved; read 0x4B; write 0x42 */
-		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_4BA_EAR7,
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP |
+				  FEATURE_4BA_NATIVE | FEATURE_4BA_ENTER_EAR7 | FEATURE_4BA_EAR_1716,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -16673,7 +16674,6 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.wrea_override	= 0x17,
 	},
 
 	{
diff --git a/spi.h b/spi.h
index 80385fa..4c6ff3e 100644
--- a/spi.h
+++ b/spi.h
@@ -169,9 +169,11 @@
 
 /* Write Extended Address Register */
 #define JEDEC_WRITE_EXT_ADDR_REG	0xC5
+#define ALT_WRITE_EXT_ADDR_REG_17	0x17
 
 /* Read Extended Address Register */
 #define JEDEC_READ_EXT_ADDR_REG		0xC8
+#define ALT_READ_EXT_ADDR_REG_16	0x16
 
 /* Read the memory */
 #define JEDEC_READ		0x03
diff --git a/spi25.c b/spi25.c
index d147dbb..20f5e97 100644
--- a/spi25.c
+++ b/spi25.c
@@ -333,7 +333,16 @@
 
 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,
@@ -376,7 +385,7 @@
 		cmd_buf[4] = (addr >>  0) & 0xff;
 		return 4;
 	} else {
-		if (flash->chip->feature_bits & FEATURE_4BA_EAR_C5C8) {
+		if (flash->chip->feature_bits & FEATURE_4BA_EAR_ANY) {
 			if (spi_set_extended_address(flash, addr >> 24))
 				return -1;
 		} else if (addr >> 24) {