summaryrefslogtreecommitdiffstats
path: root/flashrom.c
diff options
context:
space:
mode:
authorJonathon Hall <jonathon.hall@puri.sm>2022-09-16 17:05:20 -0400
committerAngel Pons <th3fanbus@gmail.com>2022-10-08 18:45:03 +0000
commit5afd4aeecec3793e62f9b5af363ee300bc879167 (patch)
tree2c4d8fc92e772deba6c861991395841d6de1fe7d /flashrom.c
parent67d50156170b17e5bca460ab6e5648e2b11f061c (diff)
downloadflashrom-5afd4aeecec3793e62f9b5af363ee300bc879167.tar.gz
flashrom-5afd4aeecec3793e62f9b5af363ee300bc879167.tar.bz2
flashrom-5afd4aeecec3793e62f9b5af363ee300bc879167.zip
drivers: Move (un)map_flash_region to par/spi/opaque_master
Move (un)map_flash_region function pointers from programmer_entry to par_master, spi_master, and opaque_master. This enables programmers to specify a different mapper per bus, which is needed for the internal programmer. Mapping is closely tied to the way the memory is accessed using the other functions in the bus master structs. Validate that FWH/LPC programmers provide specialized mapping in register_par_master(); this is needed for chips with FEATURE_REGISTERMAP, which only exist on FWH or LPC buses. programmer.c: Update comment in fallback_map(), NULL return is the desired behavior. Test: Read firmware on SB600 Promontory mainboard (requires physmap) Test: Read firmware externally with ft2232_spi Test: Read firmware on ICH hwseq, verify physmap still occurs Change-Id: I9c3df6ae260bcdb246dfb0cd8e043919609b014b Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm> Co-Authored-by: Edward O'Callaghan <quasisec@google.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/67695 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'flashrom.c')
-rw-r--r--flashrom.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/flashrom.c b/flashrom.c
index f74b79a93..90899f059 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -203,27 +203,62 @@ int programmer_shutdown(void)
return ret;
}
-void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
+void *master_map_flash_region(const struct registered_master *mst,
+ const char *descr, uintptr_t phys_addr,
+ size_t len)
{
+ /* Check the bus master for a specialized map_flash_region; default to
+ * fallback if it does not specialize it
+ */
+ void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len) = NULL;
+ if (mst->buses_supported & BUS_PROG)
+ map_flash_region = mst->opaque.map_flash_region;
+ else if (mst->buses_supported & BUS_SPI)
+ map_flash_region = mst->spi.map_flash_region;
+ else if (mst->buses_supported & BUS_NONSPI)
+ map_flash_region = mst->par.map_flash_region;
+
void *ret;
- if (programmer->map_flash_region)
- ret = programmer->map_flash_region(descr, phys_addr, len);
+ if (map_flash_region)
+ ret = map_flash_region(descr, phys_addr, len);
else
ret = fallback_map(descr, phys_addr, len);
msg_gspew("%s: mapping %s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
- __func__, descr, PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t) ret);
+ __func__, descr, PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t) ret);
return ret;
}
-void programmer_unmap_flash_region(void *virt_addr, size_t len)
+void master_unmap_flash_region(const struct registered_master *mst,
+ void *virt_addr, size_t len)
{
- if (programmer->unmap_flash_region)
- programmer->unmap_flash_region(virt_addr, len);
+ void (*unmap_flash_region) (void *virt_addr, size_t len) = NULL;
+ if (mst->buses_supported & BUS_PROG)
+ unmap_flash_region = mst->opaque.unmap_flash_region;
+ else if (mst->buses_supported & BUS_SPI)
+ unmap_flash_region = mst->spi.unmap_flash_region;
+ else if (mst->buses_supported & BUS_NONSPI)
+ unmap_flash_region = mst->par.unmap_flash_region;
+
+ if (unmap_flash_region)
+ unmap_flash_region(virt_addr, len);
else
fallback_unmap(virt_addr, len);
msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
}
+static bool master_uses_physmap(const struct registered_master *mst)
+{
+#if CONFIG_INTERNAL == 1
+ if (mst->buses_supported & BUS_PROG)
+ return mst->opaque.map_flash_region == physmap;
+ else if (mst->buses_supported & BUS_SPI)
+ return mst->spi.map_flash_region == physmap;
+ else if (mst->buses_supported & BUS_NONSPI)
+ return mst->par.map_flash_region == physmap;
+#endif
+ return false;
+}
+
void programmer_delay(unsigned int usecs)
{
if (usecs > 0) {
@@ -647,13 +682,13 @@ unsigned int count_max_decode_exceedings(const struct flashctx *flash)
void unmap_flash(struct flashctx *flash)
{
if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
- programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
+ master_unmap_flash_region(flash->mst, (void *)flash->virtual_registers, flash->chip->total_size * 1024);
flash->physical_registers = 0;
flash->virtual_registers = (chipaddr)ERROR_PTR;
}
if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
- programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
+ master_unmap_flash_region(flash->mst, (void *)flash->virtual_memory, flash->chip->total_size * 1024);
flash->physical_memory = 0;
flash->virtual_memory = (chipaddr)ERROR_PTR;
}
@@ -673,7 +708,7 @@ int map_flash(struct flashctx *flash)
const chipsize_t size = flash->chip->total_size * 1024;
uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
- void *addr = programmer_map_flash_region(flash->chip->name, base, size);
+ void *addr = master_map_flash_region(flash->mst, flash->chip->name, base, size);
if (addr == ERROR_PTR) {
msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
flash->chip->name, PRIxPTR_WIDTH, base);
@@ -687,7 +722,7 @@ int map_flash(struct flashctx *flash)
* Ignore these problems for now and always report success. */
if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
base = 0xffffffff - size - 0x400000 + 1;
- addr = programmer_map_flash_region("flash chip registers", base, size);
+ addr = master_map_flash_region(flash->mst, "flash chip registers", base, size);
if (addr == ERROR_PTR) {
msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
flash->chip->name, PRIxPTR_WIDTH, base);
@@ -831,12 +866,10 @@ notfound:
msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
free(tmp);
-#if CONFIG_INTERNAL == 1
- if (programmer->map_flash_region == physmap)
+ if (master_uses_physmap(mst))
msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
PRIxPTR_WIDTH, flash->physical_memory);
else
-#endif
msg_cinfo("on %s.\n", programmer->name);
/* Flash registers may more likely not be mapped if the chip was forced.