memory_mapped: Reduce `decode_sizes` to a single `max_rom_decode`
We used to store the maximum decode size, i.e. the maximum memory-mapped
range of the flash chip, per bus type (Parallel, LPC, FWH, SPI). There
was no programmer in the tree that really made use of it, though:
* The chipset drivers usually focus on a single bus type. And even if
they advertise the whole default set (PAR, LPC, FWH), they only pro-
vide a maximum decode size for one of them. The latter is probably
wrong, should really more than one bus type be supported.
* PCI and external programmers all support only a single bus type, with
the exception of `serprog` which doesn't set a maximum decode size.
What made the distinction even less useful is that for some chips that
support multiple bus types, i.e. LPC+FWH, we can't even detect which
type it is. The existing code around this also only tried to provide
the best possible warning message at the expense of breaking the pro-
grammer abstraction.
Hence, unify the set of sizes into a single `max_rom_decode` property.
We store it inside the `registered_master` struct right away, to avoid
any more use of globals.
Change-Id: I2aaea18d5b4255eb843a625b016ee74bb145ed85
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/72531
diff --git a/amd_spi100.c b/amd_spi100.c
index 14096ec..b112bfe 100644
--- a/amd_spi100.c
+++ b/amd_spi100.c
@@ -309,5 +309,5 @@
spi100_check_4ba(spi100);
- return register_spi_master(&spi100_master, spi100);
+ return register_spi_master(&spi100_master, 0, spi100);
}
diff --git a/atahpt.c b/atahpt.c
index 5b375a0..beaa52d 100644
--- a/atahpt.c
+++ b/atahpt.c
@@ -74,7 +74,7 @@
reg32 |= (1 << 24);
rpci_write_long(dev, REG_FLASH_ACCESS, reg32);
- return register_par_master(&par_master_atahpt, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_atahpt, BUS_PARALLEL, 0, NULL);
}
static void atahpt_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/atapromise.c b/atapromise.c
index dcdf4c2..62c7e3d 100644
--- a/atapromise.c
+++ b/atapromise.c
@@ -141,14 +141,12 @@
return 1;
}
- max_rom_decode.parallel = rom_size;
-
msg_pwarn("Do not use this device as a generic programmer. It will leave anything outside\n"
"the first %zu kB of the flash chip in an undefined state. It works fine for the\n"
"purpose of updating the firmware of this device (padding may necessary).\n",
rom_size / 1024);
- return register_par_master(&par_master_atapromise, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_atapromise, BUS_PARALLEL, rom_size, NULL);
}
static void atapromise_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/atavia.c b/atavia.c
index dc7317c..c788b1b 100644
--- a/atavia.c
+++ b/atavia.c
@@ -159,7 +159,7 @@
return 1;
}
- return register_par_master(&lpc_master_atavia, BUS_LPC, NULL);
+ return register_par_master(&lpc_master_atavia, BUS_LPC, 0, NULL);
}
static void atavia_chip_writeb(const struct flashctx *flash, uint8_t val, const chipaddr addr)
diff --git a/bitbang_spi.c b/bitbang_spi.c
index 610dc28..a377eb2 100644
--- a/bitbang_spi.c
+++ b/bitbang_spi.c
@@ -117,7 +117,7 @@
data->mst = master;
data->spi_data = spi_data;
- register_spi_master(&mst, data);
+ register_spi_master(&mst, 0, data);
/* Only mess with the bus if we're sure nobody else uses it. */
bitbang_spi_request_bus(master, spi_data);
diff --git a/board_enable.c b/board_enable.c
index 365e0c0..56498c0 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -601,8 +601,9 @@
* Suited for all boards with ITE IT8705F.
* The SIS950 Super I/O probably requires a similar flash write enable.
*/
-int it8705f_write_enable(uint8_t port)
+int it8705f_write_enable(struct flashprog_programmer *const prog, const uint8_t port)
{
+ struct internal_data *const internal = prog->data;
uint8_t tmp;
int ret = 0;
@@ -620,16 +621,16 @@
msg_pdbg("Enabling IT8705F flash ROM interface write.\n");
if (tmp & 0x02) {
/* The data sheet contradicts itself about max size. */
- max_rom_decode.parallel = 1024 * 1024;
+ internal->max_rom_decode = 1024 * 1024;
msg_pinfo("IT8705F with very unusual settings.\n"
"Please send the output of \"flashprog -V -p internal\" to\n"
"flashprog@flashprog.org with \"IT8705: your board name: flashprog -V\"\n"
"as the subject to help us finish support for your Super I/O. Thanks.\n");
ret = 1;
} else if (tmp & 0x08) {
- max_rom_decode.parallel = 512 * 1024;
+ internal->max_rom_decode = 512 * 1024;
} else {
- max_rom_decode.parallel = 256 * 1024;
+ internal->max_rom_decode = 256 * 1024;
}
/* Safety checks. The data sheet is unclear here: Segments 1+3
* overlap, no segment seems to cover top - 1MB to top - 512kB.
@@ -672,8 +673,8 @@
*/
ret = 1;
}
- msg_pdbg("Maximum IT8705F parallel flash decode size is %u.\n",
- max_rom_decode.parallel);
+ msg_pdbg("Maximum IT8705F parallel flash decode size is %zu.\n",
+ internal->max_rom_decode);
if (ret) {
msg_pinfo("Not enabling IT8705F flash write.\n");
} else {
@@ -2753,6 +2754,7 @@
int board_flash_enable(struct flashprog_programmer *const prog,
const char *vendor, const char *model, const char *cb_vendor, const char *cb_model)
{
+ struct internal_data *const internal = prog->data;
const struct board_match *board = NULL;
int ret = 0;
@@ -2782,7 +2784,7 @@
/* limit the maximum size of the parallel bus */
if (board->max_rom_decode_parallel)
- max_rom_decode.parallel = board->max_rom_decode_parallel * 1024;
+ internal->max_rom_decode = board->max_rom_decode_parallel * 1024;
if (board->enable != NULL) {
msg_pinfo("Enabling full flash access for board \"%s %s\"... ",
diff --git a/buspirate_spi.c b/buspirate_spi.c
index b2c58c6..34cf11f 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -607,7 +607,7 @@
goto init_err_cleanup_exit;
}
- return register_spi_master(&spi_master_buspirate, bp_data);
+ return register_spi_master(&spi_master_buspirate, 0, bp_data);
init_err_cleanup_exit:
buspirate_spi_shutdown(bp_data);
diff --git a/ch341a_spi.c b/ch341a_spi.c
index 6a2bdfb..00c2cc7 100644
--- a/ch341a_spi.c
+++ b/ch341a_spi.c
@@ -508,7 +508,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, 0, NULL);
dealloc_transfers:
for (i = 0; i < USB_IN_TRANSFERS; i++) {
diff --git a/ch347_spi.c b/ch347_spi.c
index aa1ee0b..fb6e59a 100644
--- a/ch347_spi.c
+++ b/ch347_spi.c
@@ -359,7 +359,7 @@
if (ch347_spi_config(ch347_data, div) < 0)
goto error_exit;
- return register_spi_master(&spi_master_ch347_spi, ch347_data);
+ return register_spi_master(&spi_master_ch347_spi, 0, ch347_data);
error_exit:
ch347_spi_shutdown(ch347_data);
diff --git a/chipset_enable.c b/chipset_enable.c
index 7dcadc5..2d958e3 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -378,8 +378,10 @@
return enable_flash_ich_bios_cntl_common(ich_generation, addr, NULL, 0);
}
-static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich_generation)
+static int enable_flash_ich_fwh_decode(struct flashprog_programmer *prog,
+ struct pci_dev *dev, enum ich_chipset ich_generation)
{
+ struct internal_data *const internal = prog->data;
uint8_t fwh_sel1 = 0, fwh_sel2 = 0, fwh_dec_en_lo = 0, fwh_dec_en_hi = 0; /* silence compilers */
bool implemented = 0;
void *ilb = NULL; /* Only for Baytrail */
@@ -547,18 +549,19 @@
contiguous = 0;
}
}
- max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode);
- msg_pdbg("Maximum FWH chip size: 0x%x bytes\n", max_rom_decode.fwh);
+ internal->max_rom_decode = min(max_decode_fwh_idsel, max_decode_fwh_decode);
+ msg_pdbg("Maximum FWH chip size: 0x%zx bytes\n", internal->max_rom_decode);
return 0;
}
-static int enable_flash_ich_fwh(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
+static int enable_flash_ich_fwh(struct flashprog_programmer *prog,
+ struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
{
int err;
/* Configure FWH IDSEL decoder maps. */
- if ((err = enable_flash_ich_fwh_decode(dev, ich_generation)) != 0)
+ if ((err = enable_flash_ich_fwh_decode(prog, dev, ich_generation)) != 0)
return err;
internal_buses_supported &= BUS_FWH;
@@ -567,22 +570,22 @@
static int enable_flash_ich0(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_fwh(dev, CHIPSET_ICH, 0x4e);
+ return enable_flash_ich_fwh(prog, dev, CHIPSET_ICH, 0x4e);
}
static int enable_flash_ich2345(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_fwh(dev, CHIPSET_ICH2345, 0x4e);
+ return enable_flash_ich_fwh(prog, dev, CHIPSET_ICH2345, 0x4e);
}
static int enable_flash_ich6(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_fwh(dev, CHIPSET_ICH6, 0xdc);
+ return enable_flash_ich_fwh(prog, dev, CHIPSET_ICH6, 0xdc);
}
static int enable_flash_poulsbo(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_fwh(dev, CHIPSET_POULSBO, 0xd8);
+ return enable_flash_ich_fwh(prog, dev, CHIPSET_POULSBO, 0xd8);
}
static enum chipbustype enable_flash_ich_report_gcs(
@@ -756,7 +759,8 @@
return boot_straps[bbs].bus;
}
-static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
+static int enable_flash_ich_spi(struct flashprog_programmer *prog, struct pci_dev *dev,
+ enum ich_chipset ich_generation, uint8_t bios_cntl)
{
/* Get physical address of Root Complex Register Block */
uint32_t rcra = pci_read_long(dev, 0xf0) & 0xffffc000;
@@ -770,7 +774,7 @@
const enum chipbustype boot_buses = enable_flash_ich_report_gcs(dev, ich_generation, rcrb);
/* Handle FWH-related parameters and initialization */
- int ret_fwh = enable_flash_ich_fwh(dev, ich_generation, bios_cntl);
+ int ret_fwh = enable_flash_ich_fwh(prog, dev, ich_generation, bios_cntl);
if (ret_fwh == ERROR_FATAL)
return ret_fwh;
@@ -819,80 +823,80 @@
static int enable_flash_tunnelcreek(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_TUNNEL_CREEK, 0xd8);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_TUNNEL_CREEK, 0xd8);
}
static int enable_flash_s12x0(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_CENTERTON, 0xd8);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_CENTERTON, 0xd8);
}
static int enable_flash_ich7(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_ICH7, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_ICH7, 0xdc);
}
static int enable_flash_ich8(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_ICH8, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_ICH8, 0xdc);
}
static int enable_flash_ich9(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_ICH9, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_ICH9, 0xdc);
}
static int enable_flash_ich10(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_ICH10, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_ICH10, 0xdc);
}
/* Ibex Peak aka. 5 series & 3400 series */
static int enable_flash_pch5(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_5_SERIES_IBEX_PEAK, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_5_SERIES_IBEX_PEAK, 0xdc);
}
/* Cougar Point aka. 6 series & c200 series */
static int enable_flash_pch6(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_6_SERIES_COUGAR_POINT, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_6_SERIES_COUGAR_POINT, 0xdc);
}
/* Panther Point aka. 7 series */
static int enable_flash_pch7(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_7_SERIES_PANTHER_POINT, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_7_SERIES_PANTHER_POINT, 0xdc);
}
/* Lynx Point aka. 8 series */
static int enable_flash_pch8(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_LYNX_POINT, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_8_SERIES_LYNX_POINT, 0xdc);
}
/* Lynx Point LP aka. 8 series low-power */
static int enable_flash_pch8_lp(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_LYNX_POINT_LP, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_8_SERIES_LYNX_POINT_LP, 0xdc);
}
/* Wellsburg (for Haswell-EP Xeons) */
static int enable_flash_pch8_wb(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc);
}
/* Wildcat Point */
static int enable_flash_pch9(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_9_SERIES_WILDCAT_POINT, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_9_SERIES_WILDCAT_POINT, 0xdc);
}
/* Wildcat Point LP */
static int enable_flash_pch9_lp(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
- return enable_flash_ich_spi(dev, CHIPSET_9_SERIES_WILDCAT_POINT_LP, 0xdc);
+ return enable_flash_ich_spi(prog, dev, CHIPSET_9_SERIES_WILDCAT_POINT_LP, 0xdc);
}
/* Sunrise Point */
@@ -1033,7 +1037,7 @@
physunmap(rcrb, 4);
/* Handle fwh_idsel parameter */
- int ret_fwh = enable_flash_ich_fwh_decode(dev, ich_generation);
+ int ret_fwh = enable_flash_ich_fwh_decode(prog, dev, ich_generation);
if (ret_fwh == ERROR_FATAL)
return ret_fwh;
@@ -1176,6 +1180,7 @@
static int enable_flash_cs5530(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
+ struct internal_data *const internal = prog->data;
uint8_t reg8;
#define DECODE_CONTROL_REG2 0x5b /* F0 index 0x5b */
@@ -1212,18 +1217,18 @@
reg8 = pci_read_byte(dev, CS5530_RESET_CONTROL_REG);
if (reg8 & CS5530_ISA_MASTER) {
/* We have A0-A23 available. */
- max_rom_decode.parallel = 16 * 1024 * 1024;
+ internal->max_rom_decode = 16*MiB;
} else {
reg8 = pci_read_byte(dev, CS5530_USB_SHADOW_REG);
if (reg8 & CS5530_ENABLE_SA2320) {
/* We have A0-19, A20-A23 available. */
- max_rom_decode.parallel = 16 * 1024 * 1024;
+ internal->max_rom_decode = 16*MiB;
} else if (reg8 & CS5530_ENABLE_SA20) {
/* We have A0-19, A20 available. */
- max_rom_decode.parallel = 2 * 1024 * 1024;
+ internal->max_rom_decode = 2*MiB;
} else {
/* A20 and above are not active. */
- max_rom_decode.parallel = 1024 * 1024;
+ internal->max_rom_decode = 1*MiB;
}
}
@@ -1328,23 +1333,26 @@
static int enable_flash_amd_768_8111(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
+ struct internal_data *const internal = prog->data;
/* Enable decoding of 0xFFB00000 to 0xFFFFFFFF (5 MB). */
- max_rom_decode.lpc = 5 * 1024 * 1024;
+ internal->max_rom_decode = 5 * 1024 * 1024;
return enable_flash_amd_via(dev, name, 0xC0);
}
static int enable_flash_vt82c586(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
+ struct internal_data *const internal = prog->data;
/* Enable decoding of 0xFFF80000 to 0xFFFFFFFF. (512 kB) */
- max_rom_decode.parallel = 512 * 1024;
+ internal->max_rom_decode = 512 * 1024;
return enable_flash_amd_via(dev, name, 0xC0);
}
/* Works for VT82C686A/B too. */
static int enable_flash_vt82c596(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
{
+ struct internal_data *const internal = prog->data;
/* Enable decoding of 0xFFF00000 to 0xFFFFFFFF. (1 MB) */
- max_rom_decode.parallel = 1024 * 1024;
+ internal->max_rom_decode = 1024 * 1024;
return enable_flash_amd_via(dev, name, 0xE0);
}
diff --git a/cli_classic.c b/cli_classic.c
index 79159c3..fede2ca 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -189,48 +189,16 @@
return ret;
}
-/* Returns the number of buses commonly supported by the current programmer and flash chip where the latter
- * can not be completely accessed due to size/address limits of the programmer. */
-static unsigned int count_max_decode_exceedings(const struct flashctx *flash,
- const struct decode_sizes *max_rom_decode_)
+/* Returns true if the flash chip cannot be completely accessed due to size/address limits of the programmer. */
+static bool max_decode_exceeded(const struct registered_master *const mst, const struct flashctx *const flash)
{
- unsigned int limitexceeded = 0;
- uint32_t size = flash->chip->total_size * 1024;
- enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
+ if (flashprog_flash_getsize(flash) <= mst->max_rom_decode)
+ return false;
- if ((buses & BUS_PARALLEL) && (max_rom_decode_->parallel < size)) {
- limitexceeded++;
- msg_pdbg("Chip size %u kB is bigger than supported "
- "size %u kB of chipset/board/programmer "
- "for %s interface, "
- "probe/read/erase/write may fail. ", size / 1024,
- max_rom_decode_->parallel / 1024, "Parallel");
- }
- if ((buses & BUS_LPC) && (max_rom_decode_->lpc < size)) {
- limitexceeded++;
- msg_pdbg("Chip size %u kB is bigger than supported "
- "size %u kB of chipset/board/programmer "
- "for %s interface, "
- "probe/read/erase/write may fail. ", size / 1024,
- max_rom_decode_->lpc / 1024, "LPC");
- }
- if ((buses & BUS_FWH) && (max_rom_decode_->fwh < size)) {
- limitexceeded++;
- msg_pdbg("Chip size %u kB is bigger than supported "
- "size %u kB of chipset/board/programmer "
- "for %s interface, "
- "probe/read/erase/write may fail. ", size / 1024,
- max_rom_decode_->fwh / 1024, "FWH");
- }
- if ((buses & BUS_SPI) && (max_rom_decode_->spi < size)) {
- limitexceeded++;
- msg_pdbg("Chip size %u kB is bigger than supported "
- "size %u kB of chipset/board/programmer "
- "for %s interface, "
- "probe/read/erase/write may fail. ", size / 1024,
- max_rom_decode_->spi / 1024, "SPI");
- }
- return limitexceeded;
+ msg_pdbg("Chip size %u kB is bigger than supported size %zu kB of\n"
+ "chipset/board/programmer for memory-mapped interface, probe/read/erase/write\n"
+ "may fail.\n", flash->chip->total_size, mst->max_rom_decode / KiB);
+ return true;
}
int main(int argc, char *argv[])
@@ -604,12 +572,15 @@
msg_pdbg("The following protocols are supported: %s.\n", tempstr);
free(tempstr);
+ struct registered_master *matched_master = NULL;
for (j = 0; j < registered_master_count; j++) {
startchip = 0;
while (chipcount < (int)ARRAY_SIZE(flashes)) {
startchip = probe_flash(®istered_masters[j], startchip, &flashes[chipcount], 0);
if (startchip == -1)
break;
+ if (chipcount == 0)
+ matched_master = ®istered_masters[j];
chipcount++;
startchip++;
}
@@ -680,16 +651,7 @@
print_chip_support_status(fill_flash->chip);
- unsigned int limitexceeded = count_max_decode_exceedings(fill_flash, &max_rom_decode);
- if (limitexceeded > 0 && !force) {
- enum chipbustype commonbuses = fill_flash->mst->buses_supported & fill_flash->chip->bustype;
-
- /* Sometimes chip and programmer have more than one bus in common,
- * and the limit is not exceeded on all buses. Tell the user. */
- if ((bitcount(commonbuses) > limitexceeded)) {
- msg_pdbg("There is at least one interface available which could support the size of\n"
- "the selected flash chip.\n");
- }
+ if (max_decode_exceeded(matched_master, fill_flash) && !force) {
msg_cerr("This flash chip is too big for this programmer (--verbose/-V gives details).\n"
"Use --force/-f to override at your own risk.\n");
ret = 1;
diff --git a/dediprog.c b/dediprog.c
index 60bea4c..ffc8a1b 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -1325,7 +1325,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, 0, dp_data);
init_err_cleanup_exit:
dediprog_shutdown(dp_data);
diff --git a/digilent_spi.c b/digilent_spi.c
index afdbcd3..ee4d497 100644
--- a/digilent_spi.c
+++ b/digilent_spi.c
@@ -449,7 +449,7 @@
if (spi_set_mode(0x00) != 0)
goto close_handle;
- return register_spi_master(&spi_master_digilent_spi, NULL);
+ return register_spi_master(&spi_master_digilent_spi, 0, NULL);
close_handle:
libusb_close(handle);
diff --git a/dirtyjtag_spi.c b/dirtyjtag_spi.c
index 06099de..3074489 100644
--- a/dirtyjtag_spi.c
+++ b/dirtyjtag_spi.c
@@ -399,7 +399,7 @@
goto cleanup_libusb_handle;
}
- return register_spi_master(&dirtyjtag_spi, djtag_data);
+ return register_spi_master(&dirtyjtag_spi, 0, djtag_data);
cleanup_libusb_handle:
libusb_attach_kernel_driver(handle, 0);
diff --git a/drkaiser.c b/drkaiser.c
index 0a67f09..6fcb5d2 100644
--- a/drkaiser.c
+++ b/drkaiser.c
@@ -74,8 +74,7 @@
if (drkaiser_bar == ERROR_PTR)
return 1;
- max_rom_decode.parallel = 128 * 1024;
- return register_par_master(&par_master_drkaiser, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_drkaiser, BUS_PARALLEL, 128*KiB, NULL);
}
static void drkaiser_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/dummyflasher.c b/dummyflasher.c
index 548c16f..6b74ce2 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -503,9 +503,9 @@
if (dummy_buses_supported & BUS_NONSPI)
ret |= register_par_master(&par_master_dummyflasher,
dummy_buses_supported & BUS_NONSPI,
- data);
+ 0, data);
if (dummy_buses_supported & BUS_SPI)
- ret |= register_spi_master(&spi_master_dummyflasher, data);
+ ret |= register_spi_master(&spi_master_dummyflasher, 0, data);
return ret;
}
diff --git a/flashprog.c b/flashprog.c
index 4e669c7..1878997 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -40,12 +40,6 @@
static const struct programmer_entry *programmer = NULL;
static char *programmer_param = NULL;
-/*
- * Programmers supporting multiple buses can have differing size limits on
- * each bus. Store the limits for each bus in a common struct.
- */
-struct decode_sizes max_rom_decode;
-
/* If nonzero, used as the start address of bottom-aligned flash. */
unsigned long flashbase;
@@ -141,13 +135,6 @@
programmer = prog->driver;
programmer_param = prog->param;
/* Initialize all programmer specific data. */
- /* Default to unlimited decode sizes. */
- max_rom_decode = (const struct decode_sizes) {
- .parallel = 0xffffffff,
- .lpc = 0xffffffff,
- .fwh = 0xffffffff,
- .spi = 0xffffffff,
- };
/* Default to top aligned flash at 4 GB. */
flashbase = 0;
/* Registering shutdown functions is now allowed. */
diff --git a/ft2232_spi.c b/ft2232_spi.c
index 020eadc..e3b19d0 100644
--- a/ft2232_spi.c
+++ b/ft2232_spi.c
@@ -691,7 +691,7 @@
spi_data->aux_bits = aux_bits;
spi_data->pindir = pindir;
- return register_spi_master(&spi_master_ft2232, spi_data);
+ return register_spi_master(&spi_master_ft2232, 0, spi_data);
ftdi_err:
if ((f = ftdi_usb_close(ftdic)) < 0) {
diff --git a/gfxnvidia.c b/gfxnvidia.c
index 5055b8b..253180e 100644
--- a/gfxnvidia.c
+++ b/gfxnvidia.c
@@ -102,7 +102,7 @@
/* Write/erase doesn't work. */
programmer_may_write = false;
- return register_par_master(&par_master_gfxnvidia, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_gfxnvidia, BUS_PARALLEL, 0, NULL);
}
static void gfxnvidia_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/ichspi.c b/ichspi.c
index b4555b9..c7e8fe7 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -1827,7 +1827,7 @@
}
ich_init_opcodes();
ich_set_bbar(0);
- register_spi_master(&spi_master_ich7, NULL);
+ register_spi_master(&spi_master_ich7, 0, NULL);
break;
case CHIPSET_ICH8:
default: /* Future version might behave the same */
@@ -2065,7 +2065,7 @@
register_opaque_master(&opaque_master_ich_hwseq, NULL);
} else {
- register_spi_master(&spi_master_ich9, NULL);
+ register_spi_master(&spi_master_ich9, 0, NULL);
}
break;
}
@@ -2095,7 +2095,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, 0, 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/programmer.h b/include/programmer.h
index 6425788..418eadd 100644
--- a/include/programmer.h
+++ b/include/programmer.h
@@ -20,6 +20,7 @@
#ifndef __PROGRAMMER_H__
#define __PROGRAMMER_H__ 1
+#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdbool.h>
@@ -99,6 +100,7 @@
struct flashprog_programmer {
const struct programmer_entry *driver;
char *param; /* TODO: Replace with flashprog_cfg (cf. flashrom/master) */
+ void *data;
};
int programmer_init(struct flashprog_programmer *);
@@ -226,7 +228,7 @@
void w836xx_ext_enter(uint16_t port);
void w836xx_ext_leave(uint16_t port);
void probe_superio_winbond(void);
-int it8705f_write_enable(uint8_t port);
+int it8705f_write_enable(struct flashprog_programmer *, uint8_t port);
uint8_t sio_read(uint16_t port, uint8_t reg);
void sio_write(uint16_t port, uint8_t reg, uint8_t data);
void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask);
@@ -254,6 +256,9 @@
#endif // defined(__i386__) || defined(__x86_64__)
/* internal.c */
+struct internal_data {
+ size_t max_rom_decode;
+};
struct superio {
uint16_t vendor;
uint16_t port;
@@ -281,14 +286,7 @@
/* flashprog.c */
-struct decode_sizes {
- uint32_t parallel;
- uint32_t lpc;
- uint32_t fwh;
- uint32_t spi;
-};
// FIXME: These need to be local, not global
-extern struct decode_sizes max_rom_decode;
extern bool programmer_may_write;
extern unsigned long flashbase;
char *extract_programmer_param(const char *param_name);
@@ -326,7 +324,7 @@
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(const 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, size_t max_rom_decode, void *data);
/* The following enum is needed by ich_descriptor_tool and ich* code as well as in chipset_enable.c. */
enum ich_chipset {
@@ -374,7 +372,7 @@
void enter_conf_mode_ite(uint16_t port);
void exit_conf_mode_ite(uint16_t port);
void probe_superio_ite(void);
-int init_superio_ite(void);
+int init_superio_ite(struct flashprog_programmer *);
#if CONFIG_LINUX_MTD == 1 && LINUX_MTD_AS_INTERNAL == 1
/* trivial wrapper to avoid cluttering internal_init() with #if */
@@ -424,7 +422,7 @@
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, size_t max_rom_decode, void *data);
/* programmer.c */
void *fallback_map(const char *descr, uintptr_t phys_addr, size_t len);
@@ -435,7 +433,10 @@
uint16_t fallback_chip_readw(const struct flashctx *flash, const chipaddr addr);
uint32_t fallback_chip_readl(const struct flashctx *flash, const chipaddr addr);
void fallback_chip_readn(const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len);
+#define DEFAULT_MAX_DECODE_PARALLEL (16*MiB)
+#define MAX_ROM_DECODE_UNLIMITED UINT32_MAX
struct registered_master {
+ size_t max_rom_decode;
enum chipbustype buses_supported;
union {
struct par_master par;
diff --git a/internal.c b/internal.c
index 72a7a22..8af2690 100644
--- a/internal.c
+++ b/internal.c
@@ -180,6 +180,19 @@
if (ret)
return ret;
+ struct internal_data *const internal = malloc(sizeof(*internal));
+ if (!internal) {
+ msg_perr("Out of memory!\n");
+ ret = 1;
+ goto internal_init_exit;
+ }
+ if (register_shutdown(shutdown_free, internal)) {
+ ret = 1;
+ goto internal_init_exit;
+ }
+ internal->max_rom_decode = 0;
+ prog->data = internal;
+
/* Unconditionally reset global state from previous operation. */
laptop_ok = false;
@@ -268,7 +281,7 @@
#if defined(__i386__) || defined(__x86_64__)
/* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
* parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
- init_superio_ite();
+ init_superio_ite(prog);
if (board_flash_enable(prog, board_vendor, board_model, cb_vendor, cb_model)) {
msg_perr("Aborting to be safe.\n");
@@ -277,8 +290,10 @@
}
#endif
- if (internal_buses_supported & BUS_NONSPI)
- register_par_master(&par_master_internal, internal_buses_supported, NULL);
+ if (internal_buses_supported & BUS_NONSPI) {
+ register_par_master(&par_master_internal, internal_buses_supported,
+ internal->max_rom_decode, NULL);
+ }
/* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */
if (is_laptop && !laptop_ok) {
diff --git a/it8212.c b/it8212.c
index 4cf0e80..8158a95 100644
--- a/it8212.c
+++ b/it8212.c
@@ -64,8 +64,7 @@
/* Restore ROM BAR decode state automatically at shutdown. */
rpci_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, NULL);
+ return register_par_master(&par_master_it8212, BUS_PARALLEL, IT8212_MEMMAP_SIZE, NULL);
}
static void it8212_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/it87spi.c b/it87spi.c
index 6dfbe5c..25e826e 100644
--- a/it87spi.c
+++ b/it87spi.c
@@ -233,11 +233,11 @@
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? */
- register_spi_master(&spi_master_it87xx, NULL);
+ register_spi_master(&spi_master_it87xx, 0, NULL);
return 0;
}
-int init_superio_ite(void)
+int init_superio_ite(struct flashprog_programmer *const prog)
{
int i;
int ret = 0;
@@ -248,7 +248,7 @@
switch (superios[i].model) {
case 0x8705:
- ret |= it8705f_write_enable(superios[i].port);
+ ret |= it8705f_write_enable(prog, superios[i].port);
break;
case 0x8686:
case 0x8716:
diff --git a/jlink_spi.c b/jlink_spi.c
index b234b0e..61338b6 100644
--- a/jlink_spi.c
+++ b/jlink_spi.c
@@ -518,7 +518,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, 0, jlink_data);
init_err:
if (jaylink_devh)
diff --git a/linux_spi.c b/linux_spi.c
index aac232a..891c493 100644
--- a/linux_spi.c
+++ b/linux_spi.c
@@ -186,7 +186,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, 0, spi_data);
init_err:
close(fd);
diff --git a/mstarddc_spi.c b/mstarddc_spi.c
index 9888d1f..b9ee23f 100644
--- a/mstarddc_spi.c
+++ b/mstarddc_spi.c
@@ -142,7 +142,7 @@
}
// Register programmer
- register_spi_master(&spi_master_mstarddc, NULL);
+ register_spi_master(&spi_master_mstarddc, 0, NULL);
out:
free(i2c_device);
return ret;
diff --git a/ni845x_spi.c b/ni845x_spi.c
index beb5ea5..8b2dcb3 100644
--- a/ni845x_spi.c
+++ b/ni845x_spi.c
@@ -476,7 +476,7 @@
return 1;
}
- return register_spi_master(&spi_programmer_ni845x, NULL);
+ return register_spi_master(&spi_programmer_ni845x, 0, NULL);
}
static int ni845x_spi_shutdown(void *data)
diff --git a/nic3com.c b/nic3com.c
index 64cb259..eec24bf 100644
--- a/nic3com.c
+++ b/nic3com.c
@@ -117,9 +117,7 @@
*/
OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
- max_rom_decode.parallel = 128 * 1024;
-
- return register_par_master(&par_master_nic3com, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_nic3com, BUS_PARALLEL, 128*KiB, NULL);
}
static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/nicintel.c b/nicintel.c
index 1c63081..573b361 100644
--- a/nicintel.c
+++ b/nicintel.c
@@ -93,8 +93,7 @@
*/
pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR);
- max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE;
- return register_par_master(&par_master_nicintel, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_nicintel, BUS_PARALLEL, NICINTEL_MEMMAP_SIZE, NULL);
}
static void nicintel_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/nicnatsemi.c b/nicnatsemi.c
index 65a42fa..44c7ef4 100644
--- a/nicnatsemi.c
+++ b/nicnatsemi.c
@@ -63,14 +63,14 @@
if (!io_base_addr)
return 1;
- /* The datasheet shows address lines MA0-MA16 in one place and MA0-MA15
+ /*
+ * The datasheet shows address lines MA0-MA16 in one place and MA0-MA15
* in another. My NIC has MA16 connected to A16 on the boot ROM socket
- * so I'm assuming it is accessible. If not then next line wants to be
- * max_rom_decode.parallel = 65536; and the mask in the read/write
- * functions below wants to be 0x0000FFFF.
+ * so I'm assuming it is accessible. If not then max_rom_decode wants
+ * to be 64KiB; and the mask in the read/write functions below wants
+ * to be 0x0000FFFF.
*/
- max_rom_decode.parallel = 131072;
- return register_par_master(&par_master_nicnatsemi, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_nicnatsemi, BUS_PARALLEL, 128*KiB, NULL);
}
static void nicnatsemi_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/nicrealtek.c b/nicrealtek.c
index 2f51495..df81274 100644
--- a/nicrealtek.c
+++ b/nicrealtek.c
@@ -84,7 +84,7 @@
break;
}
- return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, 0, NULL);
}
static void nicrealtek_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/opaque.c b/opaque.c
index f12c7d9..72bb131 100644
--- a/opaque.c
+++ b/opaque.c
@@ -63,6 +63,7 @@
__func__);
return ERROR_FLASHPROG_BUG;
}
+ rmst.max_rom_decode = MAX_ROM_DECODE_UNLIMITED;
rmst.buses_supported = BUS_PROG;
rmst.opaque = *mst;
if (data)
diff --git a/parallel.c b/parallel.c
index 3fb25b4..fb3def8 100644
--- a/parallel.c
+++ b/parallel.c
@@ -63,9 +63,8 @@
flash->mst->par.chip_readn(flash, buf, addr, len);
}
-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 size_t max_rom_decode, void *data)
{
struct registered_master rmst;
@@ -85,6 +84,10 @@
return ERROR_FLASHPROG_BUG;
}
+ if (max_rom_decode)
+ rmst.max_rom_decode = max_rom_decode;
+ else
+ rmst.max_rom_decode = DEFAULT_MAX_DECODE_PARALLEL;
rmst.buses_supported = buses;
rmst.par = *mst;
if (data)
diff --git a/pickit2_spi.c b/pickit2_spi.c
index 13a47f9..a7b658e 100644
--- a/pickit2_spi.c
+++ b/pickit2_spi.c
@@ -498,7 +498,7 @@
goto init_err_cleanup_exit;
}
- return register_spi_master(&spi_master_pickit2, pickit2_data);
+ return register_spi_master(&spi_master_pickit2, 0, pickit2_data);
init_err_cleanup_exit:
pickit2_shutdown(pickit2_data);
diff --git a/satamv.c b/satamv.c
index cefe4c4..a957505 100644
--- a/satamv.c
+++ b/satamv.c
@@ -148,8 +148,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, NULL);
+ return register_par_master(&par_master_satamv, BUS_PARALLEL, 4*MiB, NULL);
}
/* BAR2 (MEM) can map NVRAM and flash. We set it to flash in the init function.
diff --git a/satasii.c b/satasii.c
index a638cdb..abb1d4c 100644
--- a/satasii.c
+++ b/satasii.c
@@ -98,7 +98,7 @@
if ((id != 0x0680) && (!(pci_mmio_readl(sii_bar) & (1 << 26))))
msg_pwarn("Warning: Flash seems unconnected.\n");
- return register_par_master(&par_master_satasii, BUS_PARALLEL, NULL);
+ return register_par_master(&par_master_satasii, BUS_PARALLEL, 0, NULL);
}
static void satasii_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/sb600spi.c b/sb600spi.c
index ba7bd3e..41496a5 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -652,8 +652,8 @@
/* 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, NULL);
+ register_spi_master(&spi_master_sb600, 0, NULL);
else
- register_spi_master(&spi_master_yangtze, NULL);
+ register_spi_master(&spi_master_yangtze, 0, NULL);
return 0;
}
diff --git a/serprog.c b/serprog.c
index 50ec327..90813fd 100644
--- a/serprog.c
+++ b/serprog.c
@@ -730,9 +730,9 @@
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, 0, 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, 0, NULL);
return 0;
init_err_cleanup_exit:
diff --git a/spi.c b/spi.c
index ddf76f5..1c1586e 100644
--- a/spi.c
+++ b/spi.c
@@ -136,7 +136,7 @@
return true;
}
-int register_spi_master(const struct spi_master *mst, void *data)
+int register_spi_master(const struct spi_master *mst, size_t max_rom_decode, void *data)
{
struct registered_master rmst;
@@ -157,7 +157,10 @@
return ERROR_FLASHPROG_BUG;
}
-
+ if (max_rom_decode)
+ rmst.max_rom_decode = max_rom_decode;
+ else
+ rmst.max_rom_decode = MAX_ROM_DECODE_UNLIMITED;
rmst.buses_supported = BUS_SPI;
rmst.spi = *mst;
if (data)
diff --git a/stlinkv3_spi.c b/stlinkv3_spi.c
index b15c703..b1c7457 100644
--- a/stlinkv3_spi.c
+++ b/stlinkv3_spi.c
@@ -505,7 +505,7 @@
if (stlinkv3_spi_open(sck_freq_kHz))
goto init_err_exit;
- return register_spi_master(&spi_programmer_stlinkv3, NULL);
+ return register_spi_master(&spi_programmer_stlinkv3, 0, NULL);
init_err_exit:
if (stlinkv3_handle)
diff --git a/usbblaster_spi.c b/usbblaster_spi.c
index 5be423b..5464c11 100644
--- a/usbblaster_spi.c
+++ b/usbblaster_spi.c
@@ -110,7 +110,7 @@
return -1;
}
- register_spi_master(&spi_master_usbblaster, NULL);
+ register_spi_master(&spi_master_usbblaster, 0, NULL);
return 0;
}
diff --git a/wbsio_spi.c b/wbsio_spi.c
index d4f2aac..2b36d16 100644
--- a/wbsio_spi.c
+++ b/wbsio_spi.c
@@ -92,8 +92,7 @@
msg_pdbg("%s: Winbond saved on 4 register bits so max chip size is "
"1024 kB!\n", __func__);
- max_rom_decode.spi = wbsio_max_mmapped;
- register_spi_master(&spi_master_wbsio, NULL);
+ register_spi_master(&spi_master_wbsio, wbsio_max_mmapped, NULL);
return 0;
}