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;