Jonathon Hall has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/67695 )
Change subject: drivers: Move (un)map_flash_region from programmer to bus master ......................................................................
drivers: Move (un)map_flash_region from programmer to bus master
Move (un)map_flash_region function pointers from programmer_entry to registered_master. Mapping is closely tied to the way the memory is accessed through the mapping, which is specified by registered_master.
This will allow progammers that only need mappings for specific bus types to set it on each bus master. (ICH SPI cannot provide a real memory mapping for flash >16 MB, but older parallel flash may still need it.)
Change-Id: I9c3df6ae260bcdb246dfb0cd8e043919609b014b Signed-off-by: Jonathon Hall jonathon.hall@puri.sm --- M atahpt.c M atapromise.c M atavia.c M bitbang_spi.c M buspirate_spi.c M ch341a_spi.c M dediprog.c M developerbox_spi.c M digilent_spi.c M drkaiser.c M dummyflasher.c M flashrom.c M ft2232_spi.c M gfxnvidia.c M hwaccess_physmap.c M ichspi.c M include/flash.h M include/hwaccess_physmap.h M include/programmer.h M internal.c M it8212.c M it87spi.c M jlink_spi.c M linux_mtd.c M linux_spi.c M mediatek_i2c_spi.c M mstarddc_spi.c M ni845x_spi.c M nic3com.c M nicintel.c M nicintel_eeprom.c M nicintel_spi.c M nicnatsemi.c M nicrealtek.c M ogp_spi.c M opaque.c M parade_lspcon.c M parallel.c M pickit2_spi.c M pony_spi.c M programmer.c M raiden_debug_spi.c M rayer_spi.c M realtek_mst_i2c_spi.c M satamv.c M satasii.c M sb600spi.c M serprog.c M spi.c M stlinkv3_spi.c M usbblaster_spi.c M wbsio_spi.c 52 files changed, 180 insertions(+), 165 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/95/67695/1
diff --git a/atahpt.c b/atahpt.c index 5c636d1..ec1c47b 100644 --- a/atahpt.c +++ b/atahpt.c @@ -112,7 +112,7 @@ data->flash_access = pci_read_long(dev, REG_FLASH_ACCESS); pci_write_long(dev, REG_FLASH_ACCESS, data->flash_access | BIT_FLASH_ACCESS);
- return register_par_master(&par_master_atahpt, BUS_PARALLEL, data); + return register_par_master(&par_master_atahpt, BUS_PARALLEL, NULL, data); }
const struct programmer_entry programmer_atahpt = { @@ -120,7 +120,5 @@ .type = PCI, .devs.dev = ata_hpt, .init = atahpt_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/atapromise.c b/atapromise.c index 63463f5..9128660 100644 --- a/atapromise.c +++ b/atapromise.c @@ -129,6 +129,11 @@ .shutdown = atapromise_shutdown, };
+static const struct flash_mapper mapper_atapromise = { + .map_flash_region = atapromise_map, + .unmap_flash_region = fallback_unmap, +}; + static int atapromise_init(const struct programmer_cfg *cfg) { struct pci_dev *dev = NULL; @@ -182,7 +187,8 @@ data->rom_size = rom_size;
max_rom_decode.parallel = rom_size; - return register_par_master(&par_master_atapromise, BUS_PARALLEL, data); + return register_par_master(&par_master_atapromise, BUS_PARALLEL, + &mapper_atapromise, data); }
const struct programmer_entry programmer_atapromise = { @@ -190,7 +196,5 @@ .type = PCI, .devs.dev = ata_promise, .init = atapromise_init, - .map_flash_region = atapromise_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/atavia.c b/atavia.c index 51530a4..b38223c 100644 --- a/atavia.c +++ b/atavia.c @@ -143,6 +143,11 @@ .chip_writen = fallback_chip_writen, };
+static const struct flash_mapper mapper_atavia = { + .map_flash_region = atavia_map, + .unmap_flash_region = fallback_unmap, +}; + static int atavia_init(const struct programmer_cfg *cfg) { char *arg = extract_programmer_param_str(cfg, "offset"); @@ -181,7 +186,7 @@ return 1; }
- return register_par_master(&lpc_master_atavia, BUS_LPC, NULL); + return register_par_master(&lpc_master_atavia, BUS_LPC, &mapper_atavia, NULL); }
const struct programmer_entry programmer_atavia = { @@ -189,7 +194,5 @@ .type = PCI, .devs.dev = ata_via, .init = atavia_init, - .map_flash_region = atavia_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/bitbang_spi.c b/bitbang_spi.c index a926b10..08cae9c 100644 --- a/bitbang_spi.c +++ b/bitbang_spi.c @@ -169,7 +169,7 @@ if (spi_data) data->spi_data = spi_data;
- register_spi_master(&mst, data); + register_spi_master(&mst, NULL, data);
/* Only mess with the bus if we're sure nobody else uses it. */ bitbang_spi_request_bus(master, spi_data); diff --git a/buspirate_spi.c b/buspirate_spi.c index 0704887..11533a8 100644 --- a/buspirate_spi.c +++ b/buspirate_spi.c @@ -701,7 +701,7 @@ goto init_err_cleanup_exit; }
- return register_spi_master(&spi_master_buspirate, bp_data); + return register_spi_master(&spi_master_buspirate, NULL, bp_data);
init_err_cleanup_exit: buspirate_spi_shutdown(bp_data); @@ -714,7 +714,5 @@ /* FIXME */ .devs.note = "Dangerous Prototypes Bus Pirate\n", .init = buspirate_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/ch341a_spi.c b/ch341a_spi.c index 48c6420..73e18a3 100644 --- a/ch341a_spi.c +++ b/ch341a_spi.c @@ -500,7 +500,7 @@ if ((config_stream(CH341A_STM_I2C_100K) < 0) || (enable_pins(true) < 0)) goto dealloc_transfers;
- return register_spi_master(&spi_master_ch341a_spi, NULL); + return register_spi_master(&spi_master_ch341a_spi, NULL, NULL);
dealloc_transfers: for (i = 0; i < USB_IN_TRANSFERS; i++) { @@ -525,7 +525,5 @@ .type = USB, .devs.dev = devs_ch341a_spi, .init = ch341a_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = ch341a_spi_delay, }; diff --git a/dediprog.c b/dediprog.c index f957be6..dc186dd 100644 --- a/dediprog.c +++ b/dediprog.c @@ -1303,7 +1303,7 @@ if (dediprog_set_leds(LED_NONE, dp_data)) goto init_err_cleanup_exit;
- return register_spi_master(&spi_master_dediprog, dp_data); + return register_spi_master(&spi_master_dediprog, NULL, dp_data);
init_err_cleanup_exit: dediprog_shutdown(dp_data); @@ -1319,7 +1319,5 @@ .type = USB, .devs.dev = devs_dediprog, .init = dediprog_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/developerbox_spi.c b/developerbox_spi.c index 3774d04..c5dc322 100644 --- a/developerbox_spi.c +++ b/developerbox_spi.c @@ -193,7 +193,5 @@ .type = USB, .devs.dev = devs_developerbox_spi, .init = developerbox_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/digilent_spi.c b/digilent_spi.c index 41342a8..b10ddaa 100644 --- a/digilent_spi.c +++ b/digilent_spi.c @@ -456,7 +456,7 @@ digilent_data->reset_board = reset_board; digilent_data->handle = handle;
- return register_spi_master(&spi_master_digilent_spi, digilent_data); + return register_spi_master(&spi_master_digilent_spi, NULL, digilent_data);
close_handle: libusb_close(handle); @@ -468,7 +468,5 @@ .type = USB, .devs.dev = devs_digilent_spi, .init = digilent_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/drkaiser.c b/drkaiser.c index b121eec..c4c557a 100644 --- a/drkaiser.c +++ b/drkaiser.c @@ -114,7 +114,7 @@
max_rom_decode.parallel = 128 * 1024;
- return register_par_master(&par_master_drkaiser, BUS_PARALLEL, data); + return register_par_master(&par_master_drkaiser, BUS_PARALLEL, NULL, data); }
const struct programmer_entry programmer_drkaiser = { @@ -122,7 +122,5 @@ .type = PCI, .devs.dev = drkaiser_pcidev, .init = drkaiser_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/dummyflasher.c b/dummyflasher.c index 49a541b..541deb9 100644 --- a/dummyflasher.c +++ b/dummyflasher.c @@ -1340,6 +1340,11 @@ return 0; }
+static const struct flash_mapper mapper_dummy = { + .map_flash_region = dummy_map, + .unmap_flash_region = dummy_unmap, +}; + static int dummy_init(const struct programmer_cfg *cfg) { struct stat image_stat; @@ -1407,13 +1412,14 @@ }
if (dummy_buses_supported & BUS_PROG) - register_opaque_master(&opaque_master_dummyflasher, data); + register_opaque_master(&opaque_master_dummyflasher, + &mapper_dummy, data); if (dummy_buses_supported & BUS_NONSPI) register_par_master(&par_master_dummyflasher, dummy_buses_supported & BUS_NONSPI, - data); + &mapper_dummy, data); if (dummy_buses_supported & BUS_SPI) - register_spi_master(&spi_master_dummyflasher, data); + register_spi_master(&spi_master_dummyflasher, &mapper_dummy, data);
return 0; } @@ -1424,7 +1430,5 @@ /* 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, .delay = internal_delay, }; diff --git a/flashrom.c b/flashrom.c index b68ba55..20cab1b 100644 --- a/flashrom.c +++ b/flashrom.c @@ -194,17 +194,20 @@ 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) { - void *ret = programmer->map_flash_region(descr, phys_addr, len); + void *ret = mst->mapper.map_flash_region(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); 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) { - programmer->unmap_flash_region(virt_addr, len); + mst->mapper.unmap_flash_region(virt_addr, len); msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr); }
@@ -627,13 +630,13 @@ 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; } @@ -653,7 +656,7 @@
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); @@ -667,7 +670,7 @@ * 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); @@ -812,7 +815,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 (mst->mapper.map_flash_region == physmap) msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n", PRIxPTR_WIDTH, flash->physical_memory); else @@ -1414,14 +1417,6 @@ msg_gerr("Programmer %s does not have a valid delay function!\n", p->name); ret = 1; } - if (p->map_flash_region == NULL) { - msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p->name); - ret = 1; - } - if (p->unmap_flash_region == NULL) { - msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p->name); - ret = 1; - } }
/* It would be favorable if we could check for the correct layout (especially termination) of various diff --git a/ft2232_spi.c b/ft2232_spi.c index 5b45d7e..0354314 100644 --- a/ft2232_spi.c +++ b/ft2232_spi.c @@ -696,7 +696,7 @@ spi_data->pindir = pindir; spi_data->ftdic_context = ftdic;
- return register_spi_master(&spi_master_ft2232, spi_data); + return register_spi_master(&spi_master_ft2232, NULL, spi_data);
ftdi_err: if ((f = ftdi_usb_close(&ftdic)) < 0) { @@ -711,7 +711,5 @@ .type = USB, .devs.dev = devs_ft2232spi, .init = ft2232_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/gfxnvidia.c b/gfxnvidia.c index ff510ef..86dc6a5 100644 --- a/gfxnvidia.c +++ b/gfxnvidia.c @@ -142,7 +142,7 @@
/* Write/erase doesn't work. */ programmer_may_write = false; - return register_par_master(&par_master_gfxnvidia, BUS_PARALLEL, data); + return register_par_master(&par_master_gfxnvidia, BUS_PARALLEL, NULL, data); }
const struct programmer_entry programmer_gfxnvidia = { @@ -150,7 +150,5 @@ .type = PCI, .devs.dev = gfx_nvidia, .init = gfxnvidia_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/hwaccess_physmap.c b/hwaccess_physmap.c index 81adf18..896d115 100644 --- a/hwaccess_physmap.c +++ b/hwaccess_physmap.c @@ -25,6 +25,7 @@ #include <errno.h> #include "flash.h" #include "platform.h" +#include "programmer.h" #include "hwaccess_physmap.h"
#if !defined(__DJGPP__) && !defined(__LIBPAYLOAD__) @@ -367,6 +368,11 @@ return physmap_common(descr, phys_addr, len, PHYSM_RO, PHYSM_NOCLEANUP, PHYSM_EXACT); }
+const struct flash_mapper mapper_phys = { + .map_flash_region = physmap, + .unmap_flash_region = physunmap, +}; + /* Prevent reordering and/or merging of reads/writes to hardware. * Such reordering and/or merging would break device accesses which depend on the exact access order. */ diff --git a/ichspi.c b/ichspi.c index f5876b7..77822fd 100644 --- a/ichspi.c +++ b/ichspi.c @@ -1862,7 +1862,7 @@ } ich_init_opcodes(ich_gen); ich_set_bbar(0, ich_gen); - register_spi_master(&spi_master_ich7, NULL); + register_spi_master(&spi_master_ich7, &mapper_phys, NULL);
return 0; } @@ -2205,9 +2205,9 @@ } g_hwseq_data.size_comp1 = tmpi;
- register_opaque_master(&opaque_master_ich_hwseq, &g_hwseq_data); + register_opaque_master(&opaque_master_ich_hwseq, NULL, &g_hwseq_data); } else { - register_spi_master(&spi_master_ich9, NULL); + register_spi_master(&spi_master_ich9, NULL, NULL); }
return 0; @@ -2252,7 +2252,7 @@ /* Not sure if it speaks all these bus protocols. */ internal_buses_supported &= BUS_LPC | BUS_FWH; ich_generation = CHIPSET_ICH7; - register_spi_master(&spi_master_via, NULL); + register_spi_master(&spi_master_via, NULL, NULL);
msg_pdbg("0x00: 0x%04x (SPIS)\n", mmio_readw(ich_spibar + 0)); msg_pdbg("0x02: 0x%04x (SPIC)\n", mmio_readw(ich_spibar + 2)); diff --git a/include/flash.h b/include/flash.h index 79aaa64..c696f64 100644 --- a/include/flash.h +++ b/include/flash.h @@ -55,8 +55,11 @@ #define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2))
int register_shutdown(int (*function) (void *data), void *data); -void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len); -void programmer_unmap_flash_region(void *virt_addr, size_t len); +struct registered_master; +void *master_map_flash_region(const struct registered_master *mast, + const char *descr, uintptr_t phys_addr, size_t len); +void master_unmap_flash_region(const struct registered_master *mast, + void *virt_addr, size_t len); void programmer_delay(unsigned int usecs);
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) diff --git a/include/hwaccess_physmap.h b/include/hwaccess_physmap.h index a0a7e74..4342c06 100644 --- a/include/hwaccess_physmap.h +++ b/include/hwaccess_physmap.h @@ -24,6 +24,8 @@ void physunmap(void *virt_addr, size_t len); void physunmap_unaligned(void *virt_addr, size_t len);
+extern const struct flash_mapper mapper_phys; + void mmio_writeb(uint8_t val, void *addr); void mmio_writew(uint16_t val, void *addr); void mmio_writel(uint32_t val, void *addr); @@ -56,4 +58,4 @@ void rmmio_valw(void *addr); void rmmio_vall(void *addr);
-#endif /* __HWACCESS_PHYSMAP_H__ */ \ No newline at end of file +#endif /* __HWACCESS_PHYSMAP_H__ */ diff --git a/include/programmer.h b/include/programmer.h index a7cea5e..a64e48a 100644 --- a/include/programmer.h +++ b/include/programmer.h @@ -50,9 +50,6 @@
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); - void (*delay) (unsigned int usecs); };
@@ -300,6 +297,12 @@ #define SPI_MASTER_NO_4BA_MODES (1U << 1) /**< Compatibility modes (i.e. extended address register, 4BA mode switch) don't work */
+struct flash_mapper { + 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 flash_mapper mapper_fallback; + struct spi_master { uint32_t features; unsigned int max_data_read; // (Ideally,) maximum data read size in one go (excluding opcode+address). @@ -324,7 +327,8 @@ int default_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int default_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); bool default_spi_probe_opcode(struct flashctx *flash, uint8_t opcode); -int register_spi_master(const struct spi_master *mst, void *data); +int register_spi_master(const struct spi_master *mst, + const struct flash_mapper *mapper, void *data);
/* The following enum is needed by ich_descriptor_tool and ich* code as well as in chipset_enable.c. */ enum ich_chipset { @@ -417,7 +421,8 @@ int (*shutdown)(void *data); void *data; }; -int register_opaque_master(const struct opaque_master *mst, void *data); +int register_opaque_master(const struct opaque_master *mst, + const struct flash_mapper *mapper, void *data);
/* parallel.c */ struct par_master { @@ -432,7 +437,8 @@ int (*shutdown)(void *data); void *data; }; -int register_par_master(const struct par_master *mst, const enum chipbustype buses, void *data); +int register_par_master(const struct par_master *mst, const enum chipbustype buses, + const struct flash_mapper *mapper, void *data);
/* programmer.c */ void *fallback_map(const char *descr, uintptr_t phys_addr, size_t len); @@ -450,6 +456,7 @@ struct spi_master spi; struct opaque_master opaque; }; + struct flash_mapper mapper; }; extern struct registered_master registered_masters[]; extern int registered_master_count; diff --git a/internal.c b/internal.c index 43aa51b..6be913e 100644 --- a/internal.c +++ b/internal.c @@ -304,7 +304,8 @@ #endif
if (internal_buses_supported & BUS_NONSPI) - register_par_master(&par_master_internal, internal_buses_supported, NULL); + register_par_master(&par_master_internal, internal_buses_supported, + &mapper_phys, NULL);
/* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */ if (is_laptop && !laptop_ok) { @@ -347,7 +348,5 @@ .type = OTHER, .devs.note = NULL, .init = internal_init, - .map_flash_region = physmap, - .unmap_flash_region = physunmap, .delay = internal_delay, }; diff --git a/it8212.c b/it8212.c index 18d1173..7369ac5 100644 --- a/it8212.c +++ b/it8212.c @@ -104,14 +104,12 @@ pci_write_long(dev, PCI_ROM_ADDRESS, io_base_addr | 0x01);
max_rom_decode.parallel = IT8212_MEMMAP_SIZE; - return register_par_master(&par_master_it8212, BUS_PARALLEL, data); + return register_par_master(&par_master_it8212, BUS_PARALLEL, NULL, data); } const struct programmer_entry programmer_it8212 = { .name = "it8212", .type = PCI, .devs.dev = devs_it8212, .init = it8212_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/it87spi.c b/it87spi.c index 85da150..a1f7dd4 100644 --- a/it87spi.c +++ b/it87spi.c @@ -438,7 +438,7 @@ if (internal_buses_supported & BUS_SPI) msg_pdbg("Overriding chipset SPI with IT87 SPI.\n"); /* FIXME: Add the SPI bus or replace the other buses with it? */ - return register_spi_master(&spi_master_it87xx, data); + return register_spi_master(&spi_master_it87xx, NULL, data); }
int init_superio_ite(const struct programmer_cfg *cfg) diff --git a/jlink_spi.c b/jlink_spi.c index 52fc786..5d75856 100644 --- a/jlink_spi.c +++ b/jlink_spi.c @@ -516,7 +516,7 @@ if (!deassert_cs(jlink_data)) goto init_err;
- return register_spi_master(&spi_master_jlink_spi, jlink_data); + return register_spi_master(&spi_master_jlink_spi, NULL, jlink_data);
init_err: if (jaylink_devh) @@ -536,7 +536,5 @@ .type = OTHER, .init = jlink_spi_init, .devs.note = "SEGGER J-Link and compatible devices\n", - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/linux_mtd.c b/linux_mtd.c index c0147f6..833f4b3 100644 --- a/linux_mtd.c +++ b/linux_mtd.c @@ -545,7 +545,7 @@ return 1; }
- return register_opaque_master(&linux_mtd_opaque_master, data); + return register_opaque_master(&linux_mtd_opaque_master, NULL, data);
linux_mtd_init_exit: free(param_str); @@ -557,7 +557,5 @@ .type = OTHER, .devs.note = "Device files /dev/mtd*\n", .init = linux_mtd_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/linux_spi.c b/linux_spi.c index 09ee8a0..ad73b84 100644 --- a/linux_spi.c +++ b/linux_spi.c @@ -239,7 +239,7 @@ spi_data->fd = fd; spi_data->max_kernel_buf_size = max_kernel_buf_size;
- return register_spi_master(&spi_master_linux, spi_data); + return register_spi_master(&spi_master_linux, NULL, spi_data);
init_err: close(fd); @@ -251,7 +251,5 @@ .type = OTHER, .devs.note = "Device files /dev/spidev*.*\n", .init = linux_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/mediatek_i2c_spi.c b/mediatek_i2c_spi.c index 39a9cea..4dab56b 100644 --- a/mediatek_i2c_spi.c +++ b/mediatek_i2c_spi.c @@ -534,7 +534,7 @@ return ret; }
- return register_spi_master(&spi_master_i2c_mediatek, port); + return register_spi_master(&spi_master_i2c_mediatek, NULL, port); }
const struct programmer_entry programmer_mediatek_i2c_spi = { @@ -542,7 +542,5 @@ .type = OTHER, .devs.note = "Device files /dev/i2c-*\n", .init = mediatek_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/mstarddc_spi.c b/mstarddc_spi.c index af46b24..16d70ae 100644 --- a/mstarddc_spi.c +++ b/mstarddc_spi.c @@ -242,7 +242,7 @@ mstarddc_data->doreset = mstarddc_doreset;
// Register programmer - register_spi_master(&spi_master_mstarddc, mstarddc_data); + register_spi_master(&spi_master_mstarddc, NULL, mstarddc_data); out: free(i2c_device); if (ret && (mstarddc_fd >= 0)) @@ -255,7 +255,5 @@ .type = OTHER, .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n", .init = mstarddc_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/ni845x_spi.c b/ni845x_spi.c index 3d74fd9..2165941 100644 --- a/ni845x_spi.c +++ b/ni845x_spi.c @@ -627,7 +627,7 @@ return 1; }
- return register_spi_master(&spi_programmer_ni845x, NULL); + return register_spi_master(&spi_programmer_ni845x, NULL, NULL); }
const struct programmer_entry programmer_ni845x_spi = { @@ -635,7 +635,5 @@ .type = OTHER, // choose other because NI-845x uses own USB implementation .devs.note = "National Instruments USB-845x\n", .init = ni845x_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/nic3com.c b/nic3com.c index 44710ed..3ffb1db 100644 --- a/nic3com.c +++ b/nic3com.c @@ -150,7 +150,7 @@
max_rom_decode.parallel = 128 * 1024;
- return register_par_master(&par_master_nic3com, BUS_PARALLEL, data); + return register_par_master(&par_master_nic3com, BUS_PARALLEL, NULL, data);
init_err_cleanup_exit: /* 3COM 3C90xB cards need a special fixup. */ @@ -168,7 +168,5 @@ .type = PCI, .devs.dev = nics_3com, .init = nic3com_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/nicintel.c b/nicintel.c index 16cb5e4..e759c87 100644 --- a/nicintel.c +++ b/nicintel.c @@ -125,7 +125,7 @@ data->nicintel_control_bar = control_bar;
max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE; - return register_par_master(&par_master_nicintel, BUS_PARALLEL, data); + return register_par_master(&par_master_nicintel, BUS_PARALLEL, NULL, data); }
const struct programmer_entry programmer_nicintel = { @@ -133,7 +133,5 @@ .type = PCI, .devs.dev = nics_intel, .init = nicintel_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/nicintel_eeprom.c b/nicintel_eeprom.c index 4d3e7d5..ae1e206 100644 --- a/nicintel_eeprom.c +++ b/nicintel_eeprom.c @@ -530,7 +530,7 @@ data->eec = eec; data->done_i20_write = false;
- return register_opaque_master(mst, data); + return register_opaque_master(mst, NULL, data); }
const struct programmer_entry programmer_nicintel_eeprom = { @@ -538,7 +538,5 @@ .type = PCI, .devs.dev = nics_intel_ee, .init = nicintel_ee_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/nicintel_spi.c b/nicintel_spi.c index 851b525..9f23be1 100644 --- a/nicintel_spi.c +++ b/nicintel_spi.c @@ -337,7 +337,5 @@ .type = PCI, .devs.dev = nics_intel_spi, .init = nicintel_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/nicnatsemi.c b/nicnatsemi.c index 779fb33..6edc36a 100644 --- a/nicnatsemi.c +++ b/nicnatsemi.c @@ -118,7 +118,7 @@ * functions below wants to be 0x0000FFFF. */ max_rom_decode.parallel = 131072; - return register_par_master(&par_master_nicnatsemi, BUS_PARALLEL, data); + return register_par_master(&par_master_nicnatsemi, BUS_PARALLEL, NULL, data); }
@@ -127,7 +127,5 @@ .type = PCI, .devs.dev = nics_natsemi, .init = nicnatsemi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/nicrealtek.c b/nicrealtek.c index 7bf1ac9..264f08f 100644 --- a/nicrealtek.c +++ b/nicrealtek.c @@ -138,7 +138,7 @@ data->bios_rom_addr = bios_rom_addr; data->bios_rom_data = bios_rom_data;
- return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, data); + return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, NULL, data); }
const struct programmer_entry programmer_nicrealtek = { @@ -146,7 +146,5 @@ .type = PCI, .devs.dev = nics_realtek, .init = nicrealtek_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/ogp_spi.c b/ogp_spi.c index 94915a3..fe4773c 100644 --- a/ogp_spi.c +++ b/ogp_spi.c @@ -178,7 +178,5 @@ .type = PCI, .devs.dev = ogp_spi, .init = ogp_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/opaque.c b/opaque.c index 7704ec7..53d27ba 100644 --- a/opaque.c +++ b/opaque.c @@ -46,7 +46,8 @@ return flash->mst->opaque.erase(flash, blockaddr, blocklen); }
-int register_opaque_master(const struct opaque_master *mst, void *data) +int register_opaque_master(const struct opaque_master *mst, + const struct flash_mapper *mapper, void *data) { struct registered_master rmst = {0};
@@ -65,6 +66,15 @@ } rmst.buses_supported = BUS_PROG; rmst.opaque = *mst; + if (!mapper) + mapper = &mapper_fallback; + if(!mapper->map_flash_region || !mapper->unmap_flash_region) { + msg_perr("%s called with incomplete flash mapper definition. " + "Please report a bug at flashrom@flashrom.org\n", + __func__); + return ERROR_FLASHROM_BUG; + } + rmst.mapper = *mapper; if (data) rmst.opaque.data = data; return register_master(&rmst); diff --git a/parade_lspcon.c b/parade_lspcon.c index 761e46b..af36cb3 100644 --- a/parade_lspcon.c +++ b/parade_lspcon.c @@ -499,7 +499,7 @@
data->fd = fd;
- return register_spi_master(&spi_master_parade_lspcon, data); + return register_spi_master(&spi_master_parade_lspcon, NULL, data); }
const struct programmer_entry programmer_parade_lspcon = { @@ -507,7 +507,5 @@ .type = OTHER, .devs.note = "Device files /dev/i2c-*.\n", .init = parade_lspcon_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/parallel.c b/parallel.c index 9001fe8..9c5f7ef 100644 --- a/parallel.c +++ b/parallel.c @@ -65,6 +65,7 @@
int register_par_master(const struct par_master *mst, const enum chipbustype buses, + const struct flash_mapper *mapper, void *data) { struct registered_master rmst = {0}; @@ -87,6 +88,15 @@
rmst.buses_supported = buses; rmst.par = *mst; + if (!mapper) + mapper = &mapper_fallback; + if(!mapper->map_flash_region || !mapper->unmap_flash_region) { + msg_perr("%s called with incomplete flash mapper definition. " + "Please report a bug at flashrom@flashrom.org\n", + __func__); + return ERROR_FLASHROM_BUG; + } + rmst.mapper = *mapper; if (data) rmst.par.data = data; return register_master(&rmst); diff --git a/pickit2_spi.c b/pickit2_spi.c index b838234..5a25560 100644 --- a/pickit2_spi.c +++ b/pickit2_spi.c @@ -499,7 +499,7 @@ goto init_err_cleanup_exit; }
- return register_spi_master(&spi_master_pickit2, pickit2_data); + return register_spi_master(&spi_master_pickit2, NULL, pickit2_data);
init_err_cleanup_exit: pickit2_shutdown(pickit2_data); @@ -511,7 +511,5 @@ .type = USB, .devs.dev = devs_pickit2_spi, .init = pickit2_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/pony_spi.c b/pony_spi.c index ebeac94..008ae3a 100644 --- a/pony_spi.c +++ b/pony_spi.c @@ -272,7 +272,5 @@ /* FIXME */ .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n", .init = pony_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/programmer.c b/programmer.c index 2b960e6..e4bd263 100644 --- a/programmer.c +++ b/programmer.c @@ -29,6 +29,11 @@ { }
+const struct flash_mapper mapper_fallback = { + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + /* Little-endian fallback for drivers not supporting 16 bit accesses */ void fallback_chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr) diff --git a/raiden_debug_spi.c b/raiden_debug_spi.c index 28cab06..372b421 100644 --- a/raiden_debug_spi.c +++ b/raiden_debug_spi.c @@ -1641,7 +1641,7 @@ return SPI_GENERIC_ERROR; }
- return register_spi_master(spi_config, data); + return register_spi_master(spi_config, NULL, data); }
const struct programmer_entry programmer_raiden_debug_spi = { @@ -1649,7 +1649,5 @@ .type = USB, .devs.dev = devs_raiden, .init = raiden_debug_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/rayer_spi.c b/rayer_spi.c index 3867cfc..362b565 100644 --- a/rayer_spi.c +++ b/rayer_spi.c @@ -329,7 +329,5 @@ /* FIXME */ .devs.note = "RayeR parallel port programmer\n", .init = rayer_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/realtek_mst_i2c_spi.c b/realtek_mst_i2c_spi.c index 74458c8..18182ef 100644 --- a/realtek_mst_i2c_spi.c +++ b/realtek_mst_i2c_spi.c @@ -536,7 +536,7 @@
data->fd = fd; data->reset = reset; - return register_spi_master(&spi_master_i2c_realtek_mst, data); + return register_spi_master(&spi_master_i2c_realtek_mst, NULL, data); }
const struct programmer_entry programmer_realtek_mst_i2c_spi = { @@ -544,7 +544,5 @@ .type = OTHER, .devs.note = "Device files /dev/i2c-*.\n", .init = realtek_mst_i2c_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/satamv.c b/satamv.c index f886076..8219ba2 100644 --- a/satamv.c +++ b/satamv.c @@ -203,7 +203,7 @@ /* 512 kByte with two 8-bit latches, and * 4 MByte with additional 3-bit latch. */ max_rom_decode.parallel = 4 * 1024 * 1024; - return register_par_master(&par_master_satamv, BUS_PARALLEL, data); + return register_par_master(&par_master_satamv, BUS_PARALLEL, NULL, data); }
const struct programmer_entry programmer_satamv = { @@ -211,7 +211,5 @@ .type = PCI, .devs.dev = satas_mv, .init = satamv_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/satasii.c b/satasii.c index 44b7331..83ceae0 100644 --- a/satasii.c +++ b/satasii.c @@ -146,14 +146,12 @@ } data->bar = bar;
- return register_par_master(&par_master_satasii, BUS_PARALLEL, data); + return register_par_master(&par_master_satasii, BUS_PARALLEL, NULL, data); } const struct programmer_entry programmer_satasii = { .name = "satasii", .type = PCI, .devs.dev = satas_sii, .init = satasii_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/sb600spi.c b/sb600spi.c index 8b02b51..59aea15 100644 --- a/sb600spi.c +++ b/sb600spi.c @@ -808,11 +808,11 @@
/* Starting with Yangtze the SPI controller got a different interface with a much bigger buffer. */ if (amd_gen < CHIPSET_YANGTZE) - register_spi_master(&spi_master_sb600, data); + register_spi_master(&spi_master_sb600, &mapper_phys, data); else if (amd_gen == CHIPSET_YANGTZE) - register_spi_master(&spi_master_yangtze, data); + register_spi_master(&spi_master_yangtze, &mapper_phys, data); else - register_spi_master(&spi_master_promontory, data); + register_spi_master(&spi_master_promontory, &mapper_phys, data);
return 0; } diff --git a/serprog.c b/serprog.c index 57196a9..018b05d 100644 --- a/serprog.c +++ b/serprog.c @@ -563,6 +563,26 @@ .chip_writen = fallback_chip_writen, };
+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 flash_mapper mapper_serprog = { + .map_flash_region = serprog_map, + .unmap_flash_region = fallback_unmap, +}; + static enum chipbustype serprog_buses_supported = BUS_NONE;
static int serprog_init(const struct programmer_cfg *cfg) @@ -914,9 +934,10 @@ if (register_shutdown(serprog_shutdown, NULL)) goto init_err_cleanup_exit; if (serprog_buses_supported & BUS_SPI) - register_spi_master(&spi_master_serprog, NULL); + register_spi_master(&spi_master_serprog, &mapper_serprog, NULL); if (serprog_buses_supported & BUS_NONSPI) - register_par_master(&par_master_serprog, serprog_buses_supported & BUS_NONSPI, NULL); + register_par_master(&par_master_serprog, serprog_buses_supported & BUS_NONSPI, + &mapper_serprog, NULL); return 0;
init_err_cleanup_exit: @@ -945,28 +966,11 @@ 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; -} - 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, - .unmap_flash_region = fallback_unmap, .delay = serprog_delay, }; diff --git a/spi.c b/spi.c index 38d8d01..4b5d9e9 100644 --- a/spi.c +++ b/spi.c @@ -139,7 +139,8 @@ return true; }
-int register_spi_master(const struct spi_master *mst, void *data) +int register_spi_master(const struct spi_master *mst, + const struct flash_mapper *mapper, void *data) { struct registered_master rmst = {0};
@@ -163,6 +164,15 @@
rmst.buses_supported = BUS_SPI; rmst.spi = *mst; + if (!mapper) + mapper = &mapper_fallback; + if(!mapper->map_flash_region || !mapper->unmap_flash_region) { + msg_perr("%s called with incomplete flash mapper definition. " + "Please report a bug at flashrom@flashrom.org\n", + __func__); + return ERROR_FLASHROM_BUG; + } + rmst.mapper = *mapper; if (data) rmst.spi.data = data; return register_master(&rmst); diff --git a/stlinkv3_spi.c b/stlinkv3_spi.c index 38fe9f9..141aa9a 100644 --- a/stlinkv3_spi.c +++ b/stlinkv3_spi.c @@ -542,7 +542,7 @@ stlinkv3_data->usb_ctx = usb_ctx; stlinkv3_data->handle = stlinkv3_handle;
- return register_spi_master(&spi_programmer_stlinkv3, stlinkv3_data); + return register_spi_master(&spi_programmer_stlinkv3, NULL, stlinkv3_data);
init_err_exit: if (stlinkv3_handle) @@ -556,7 +556,5 @@ .type = USB, .devs.dev = devs_stlinkv3_spi, .init = stlinkv3_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/usbblaster_spi.c b/usbblaster_spi.c index 2880a3c..37b5ec3 100644 --- a/usbblaster_spi.c +++ b/usbblaster_spi.c @@ -224,7 +224,7 @@ } usbblaster_data->ftdic = ftdic;
- return register_spi_master(&spi_master_usbblaster, usbblaster_data); + return register_spi_master(&spi_master_usbblaster, NULL, usbblaster_data); }
const struct programmer_entry programmer_usbblaster_spi = { @@ -232,7 +232,5 @@ .type = USB, .devs.dev = devs_usbblasterspi, .init = usbblaster_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, .delay = internal_delay, }; diff --git a/wbsio_spi.c b/wbsio_spi.c index 95ca1e9..f478969 100644 --- a/wbsio_spi.c +++ b/wbsio_spi.c @@ -215,5 +215,5 @@ } data->spibase = wbsio_spibase;
- return register_spi_master(&spi_master_wbsio, data); + return register_spi_master(&spi_master_wbsio, &mapper_phys, data); }