amd_spi100: Fix memory-mapped reads for partially mapped chips

If the memory-mapping doesn't cover exactly the full flash chip,
we have to translate the `start` offset by subtracting the offset
of the mapping inside the chip's space (`mapped_start`). This
calculation should also work if more than the chip's size is
mapped. Then this offset would be negative.

We also use the newly added `mapped_start` for the preceding
calculations in the SPI engine fallback case. It keeps its exact
semantics, though.

Change-Id: I4881b2420cb80c079052235ad54cedbb6fa3c945
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/73671
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Marty E. Plummer <hanetzer@startmail.com>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/amd_spi100.c b/amd_spi100.c
index d0d2f28..a09aea6 100644
--- a/amd_spi100.c
+++ b/amd_spi100.c
@@ -130,10 +130,13 @@
 {
 	const struct spi100 *const spi100 = flash->mst->spi.data;
 
-	/* Use SPI100 engine for data outside the memory-mapped range */
-	const chipoff_t from_top = flashrom_flash_getsize(flash) - start;
-	if (from_top > spi100->mapped_len) {
-		const chipsize_t unmapped_len = MIN(len, from_top - spi100->mapped_len);
+	/* Where in the flash does the memory mapped part start?
+	   Can be negative if the mapping is bigger than the chip. */
+	const long long mapped_start = flashrom_flash_getsize(flash) - spi100->mapped_len;
+
+	/* Use SPI100 engine for data outside the memory-mapped range. */
+	if ((long long)start < mapped_start) {
+		const chipsize_t unmapped_len = MIN(len, mapped_start - start);
 		const int ret = default_spi_read(flash, buf, start, unmapped_len);
 		if (ret)
 			return ret;
@@ -142,6 +145,9 @@
 		len -= unmapped_len;
 	}
 
+	/* Translate `start` to memory-mapped offset. */
+	start -= mapped_start;
+
 	mmio_readn_aligned(spi100->memory + start, buf, len, 8);
 
 	return 0;