spi: Implement top-aligned to avoid BBAR hassle

The BBAR quirk in `ichspi' is the only case left where we need a flash
context in the SPI `.send_command' functions. Our Git history suggests
that the elaborate calculation there  was not added for an encountered
setup but rather all possible settings of BBAR [1]. There are only few
settings that make sense, however.

BBAR sets a simple address boundary. Reads for any flash address below
the BBAR setting will be rejected.  This was originally the only read-
protection mechanism, introduced with ICH7.  The ICH7 datasheet states
that upper bits, above the flash chip's size, should be set to all 1s.
This makes sense, as otherwise the read-protection could be circumven-
ted by setting a higher address above BBAR, where the flash chip would
simply ignore the most significant bits.  Conversely, this requires us
to "lift" the flash addresses when the BBAR is configured properly. We
can achieve this by top-aligning all addresses.

Newer chipsets have protected-range registers (PRx) now, that allow to
configure read protection. Also the descriptor mode was introduced. So
flash addresses have to match the descriptor regions, and lifting them
isn't feasible.  The BBAR register was still around until Wilcat Point
(PCH9), though, probably useless, and without the note about upper ad-
dress bits.  Odd though, since [2], we only consider the BBAR on newer
chipsets when in descriptor mode.

As the BBAR protection seems unlikely on newer chipsets, and the quirk
handling error-prone,  we'll only change addresses on ICH7 and similar
old chipsets. We don't want the dependency on the flash context, hence
let the generic `spi25' code top align the addresses.

[1] commit ed098d62d66d (spi: Move ICH BBAR quirk out of the way)
[2] commit 4095ed797f87 (Add support for Intel Silvermont: Bay Trail,
    Rangeley and Avoton)

Change-Id: Ic6f6f5a24d89d4a1ebe2b99f08aabfcd65df129f
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/74896
diff --git a/spi25.c b/spi25.c
index b1d6288..334e87a 100644
--- a/spi25.c
+++ b/spi25.c
@@ -394,9 +394,13 @@
 }
 
 static int spi_prepare_address(struct flashctx *const flash, uint8_t cmd_buf[],
-			       const bool native_4ba, const unsigned int addr)
+			       const bool native_4ba, const unsigned int rel_addr)
 {
 	const size_t len = spi_address_length(flash, native_4ba);
+	unsigned int addr = rel_addr;
+
+	if (spi_master_top_aligned(flash))
+		addr = rel_addr - flashprog_flash_getsize(flash); /* intentional integer underflow */
 
 	switch (len) {
 	case 4:
@@ -411,9 +415,9 @@
 		return len;
 	case 3:
 		if (flash->chip->feature_bits & FEATURE_4BA_EAR_ANY) {
-			if (spi_set_extended_address(flash, addr >> 24))
+			if (spi_set_extended_address(flash, rel_addr >> 24))
 				return -1;
-		} else if (addr >> 24) {
+		} else if (rel_addr >> 24) {
 			msg_cerr("Can't handle 4-byte address for opcode '0x%02x'\n"
 				 "with this chip/programmer combination.\n", cmd_buf[0]);
 			return -1;