Edward O'Callaghan has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/67478 )
Change subject: tree/: Move {un}map_flash_region out of programmer state machine ......................................................................
tree/: Move {un}map_flash_region out of programmer state machine
Change-Id: I9f011736681481c464946386b196c9ec2e9d7e29 Signed-off-by: Edward O'Callaghan quasisec@google.com --- M atapromise.c M atavia.c M dummyflasher.c M flashrom.c M include/programmer.h M internal.c M serprog.c 7 files changed, 79 insertions(+), 33 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/78/67478/1
diff --git a/atapromise.c b/atapromise.c index ffa4698..acd98d5 100644 --- a/atapromise.c +++ b/atapromise.c @@ -127,6 +127,7 @@ .chip_writel = fallback_chip_writel, .chip_writen = fallback_chip_writen, .shutdown = atapromise_shutdown, + .map_flash_region = atapromise_map, };
static int atapromise_init(const struct programmer_cfg *cfg) @@ -190,5 +191,4 @@ .type = PCI, .devs.dev = ata_promise, .init = atapromise_init, - .map_flash_region = atapromise_map, }; diff --git a/atavia.c b/atavia.c index a0a0547..6e25e2c 100644 --- a/atavia.c +++ b/atavia.c @@ -141,6 +141,7 @@ .chip_writew = fallback_chip_writew, .chip_writel = fallback_chip_writel, .chip_writen = fallback_chip_writen, + .map_flash_region = atavia_map, };
static int atavia_init(const struct programmer_cfg *cfg) @@ -189,5 +190,4 @@ .type = PCI, .devs.dev = ata_via, .init = atavia_init, - .map_flash_region = atavia_map, }; diff --git a/dummyflasher.c b/dummyflasher.c index 40f22d9..16ce986 100644 --- a/dummyflasher.c +++ b/dummyflasher.c @@ -929,6 +929,8 @@ .write_256 = dummy_spi_write_256, .write_aai = default_spi_write_aai, .probe_opcode = dummy_spi_probe_opcode, + .map_flash_region = dummy_map, + .unmap_flash_region = dummy_unmap, };
static const struct par_master par_master_dummyflasher = { @@ -940,6 +942,8 @@ .chip_writew = dummy_chip_writew, .chip_writel = dummy_chip_writel, .chip_writen = dummy_chip_writen, + .map_flash_region = dummy_map, + .unmap_flash_region = dummy_unmap, };
static const struct opaque_master opaque_master_dummyflasher = { @@ -947,6 +951,8 @@ .read = dummy_opaque_read, .write = dummy_opaque_write, .erase = dummy_opaque_erase, + .map_flash_region = dummy_map, + .unmap_flash_region = dummy_unmap, };
static int init_data(const struct programmer_cfg *cfg, @@ -1424,6 +1430,4 @@ /* FIXME */ .devs.note = "Dummy device, does nothing and logs all accesses\n", .init = dummy_init, - .map_flash_region = dummy_map, - .unmap_flash_region = dummy_unmap, }; diff --git a/flashrom.c b/flashrom.c index 8d08341..605d0ae 100644 --- a/flashrom.c +++ b/flashrom.c @@ -197,10 +197,17 @@ static void *programmer_map_flash_region(const struct flashctx *flash, const char *descr, uintptr_t phys_addr, size_t len) { - void *ret; - if (programmer->map_flash_region) - ret = programmer->map_flash_region(descr, phys_addr, len); - else + void *ret = NULL; + if (flash->mst->buses_supported & BUS_SPI) { + if (flash->mst->spi.map_flash_region) + ret = flash->mst->spi.map_flash_region(descr, phys_addr, len); + } else if (flash->mst->buses_supported & BUS_PROG) { + if (flash->mst->par.map_flash_region) + ret = flash->mst->opaque.map_flash_region(descr, phys_addr, len); + } else if (flash->mst->buses_supported & BUS_PARALLEL) { + if (flash->mst->par.map_flash_region) + ret = flash->mst->par.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); @@ -209,13 +216,35 @@
static void programmer_unmap_flash_region(const struct flashctx *flash, void *virt_addr, size_t len) { - if (programmer->unmap_flash_region) - programmer->unmap_flash_region(virt_addr, len); - else + if (flash->mst->buses_supported & BUS_SPI) { + if (flash->mst->spi.unmap_flash_region) + flash->mst->spi.unmap_flash_region(virt_addr, len); + } else if (flash->mst->buses_supported & BUS_PROG) { + if (flash->mst->par.unmap_flash_region) + flash->mst->opaque.unmap_flash_region(virt_addr, len); + } else if (flash->mst->buses_supported & BUS_PARALLEL) { + if (flash->mst->par.unmap_flash_region) + flash->mst->par.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 is_physmap(const struct flashctx *flash) +{ + if (flash->mst->buses_supported & BUS_SPI) { + if (flash->mst->spi.map_flash_region) + return flash->mst->spi.map_flash_region == physmap; + } else if (flash->mst->buses_supported & BUS_PROG) { + if (flash->mst->par.map_flash_region) + return flash->mst->opaque.map_flash_region == physmap; + } else if (flash->mst->buses_supported & BUS_PARALLEL) { + if (flash->mst->par.map_flash_region) + return flash->mst->par.map_flash_region == physmap; + } + return false; +} + void programmer_delay(const struct flashctx *flash, unsigned int usecs) { if (usecs > 0) { @@ -828,7 +857,7 @@ flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp); free(tmp); #if CONFIG_INTERNAL == 1 - if (programmer->map_flash_region == physmap) + if (is_physmap(flash)) msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n", PRIxPTR_WIDTH, flash->physical_memory); else diff --git a/include/programmer.h b/include/programmer.h index cfd8d08..2971f79 100644 --- a/include/programmer.h +++ b/include/programmer.h @@ -49,9 +49,6 @@ } devs;
int (*init) (const struct programmer_cfg *cfg); - - void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len); - void (*unmap_flash_region) (void *virt_addr, size_t len); };
extern const struct programmer_entry *const programmer_table[]; @@ -313,6 +310,8 @@ int (*shutdown)(void *data); bool (*probe_opcode)(struct flashctx *flash, uint8_t opcode); void (*delay) (unsigned int usecs); + void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len); + void (*unmap_flash_region) (void *virt_addr, size_t len); void *data; };
@@ -413,6 +412,8 @@ enum flashrom_wp_result (*wp_write_cfg)(struct flashctx *, const struct flashrom_wp_cfg *); enum flashrom_wp_result (*wp_read_cfg)(struct flashrom_wp_cfg *, struct flashctx *); enum flashrom_wp_result (*wp_get_ranges)(struct flashrom_wp_ranges **, struct flashctx *); + void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len); + void (*unmap_flash_region) (void *virt_addr, size_t len); int (*shutdown)(void *data); void *data; }; @@ -430,6 +431,8 @@ void (*chip_readn) (const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len); int (*shutdown)(void *data); void (*delay) (unsigned int usecs); + void *(*map_flash_region) (const char *descr, uintptr_t phys_addr, size_t len); + void (*unmap_flash_region) (void *virt_addr, size_t len); void *data; }; int register_par_master(const struct par_master *mst, const enum chipbustype buses, void *data); diff --git a/internal.c b/internal.c index a20c539..cf719a4 100644 --- a/internal.c +++ b/internal.c @@ -115,6 +115,8 @@ .chip_writew = internal_chip_writew, .chip_writel = internal_chip_writel, .chip_writen = fallback_chip_writen, + .map_flash_region = physmap, + .unmap_flash_region = physunmap, };
static int get_params(const struct programmer_cfg *cfg, @@ -347,6 +349,4 @@ .type = OTHER, .devs.note = NULL, .init = internal_init, - .map_flash_region = physmap, - .unmap_flash_region = physunmap, }; diff --git a/serprog.c b/serprog.c index ee4a010..441b8a0 100644 --- a/serprog.c +++ b/serprog.c @@ -573,6 +573,21 @@ sp_prev_was_write = 0; }
+static void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len) +{ + /* Serprog transmits 24 bits only and assumes the underlying implementation handles any remaining bits + * correctly (usually setting them to one either in software (for FWH/LPC) or relying on the fact that + * the hardware observes a subset of the address bits only). Combined with the standard mapping of + * flashrom this creates a 16 MB-wide window just below the 4 GB boundary where serprog can operate (as + * needed for non-SPI chips). Below we make sure that the requested range is within this window. */ + if ((phys_addr & 0xFF000000) == 0xFF000000) { + return (void*)phys_addr; + } + msg_pwarn(MSGHEADER "requested mapping %s is incompatible: 0x%zx bytes at 0x%0*" PRIxPTR ".\n", + descr, len, PRIxPTR_WIDTH, phys_addr); + return NULL; +} + static const struct par_master par_master_serprog = { .chip_readb = serprog_chip_readb, .chip_readw = fallback_chip_readw, @@ -583,6 +598,7 @@ .chip_writel = fallback_chip_writel, .chip_writen = fallback_chip_writen, .delay = serprog_delay, + .map_flash_region = serprog_map, };
static enum chipbustype serprog_buses_supported = BUS_NONE; @@ -946,26 +962,10 @@ return 1; }
-static void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len) -{ - /* Serprog transmits 24 bits only and assumes the underlying implementation handles any remaining bits - * correctly (usually setting them to one either in software (for FWH/LPC) or relying on the fact that - * the hardware observes a subset of the address bits only). Combined with the standard mapping of - * flashrom this creates a 16 MB-wide window just below the 4 GB boundary where serprog can operate (as - * needed for non-SPI chips). Below we make sure that the requested range is within this window. */ - if ((phys_addr & 0xFF000000) == 0xFF000000) { - return (void*)phys_addr; - } - msg_pwarn(MSGHEADER "requested mapping %s is incompatible: 0x%zx bytes at 0x%0*" PRIxPTR ".\n", - descr, len, PRIxPTR_WIDTH, phys_addr); - return NULL; -} - const struct programmer_entry programmer_serprog = { .name = "serprog", .type = OTHER, /* FIXME */ .devs.note = "All programmer devices speaking the serprog protocol\n", .init = serprog_init, - .map_flash_region = serprog_map, };