memory_bus: Turn flashbase into a par_master member `rom_base`

Get rid of the global `flashbase`. Treat overrides for the `rom_base`
similar to `max_rom_decode`: Gather the information in `internal_data`
and then pass it to register_par_master().

Change-Id: Ib9ed7234a849fe3550200fd602226d0036da15f0
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/436
diff --git a/atahpt.c b/atahpt.c
index beaa52d..05b11e9 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, 0, NULL);
+	return register_par_master(&par_master_atahpt, BUS_PARALLEL, 0, 0, NULL);
 }
 
 static void atahpt_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/atapromise.c b/atapromise.c
index aa83577..3d50e54 100644
--- a/atapromise.c
+++ b/atapromise.c
@@ -113,7 +113,7 @@
 		  "purpose of updating the firmware of this device (padding may necessary).\n",
 		  rom_size / 1024);
 
-	return register_par_master(&par_master_atapromise, BUS_PARALLEL, rom_size, NULL);
+	return register_par_master(&par_master_atapromise, BUS_PARALLEL, 0, 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 c788b1b..bc70268 100644
--- a/atavia.c
+++ b/atavia.c
@@ -159,7 +159,7 @@
 		return 1;
 	}
 
-	return register_par_master(&lpc_master_atavia, BUS_LPC, 0, NULL);
+	return register_par_master(&lpc_master_atavia, BUS_LPC, 0, 0, NULL);
 }
 
 static void atavia_chip_writeb(const struct flashctx *flash, uint8_t val, const chipaddr addr)
diff --git a/chipset_enable.c b/chipset_enable.c
index f92afb5..6e8d723 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -479,7 +479,7 @@
 
 	/* Ignore all legacy ranges below 1 MB.
 	 * We currently only support flashing the chip which responds to
-	 * IDSEL=0. To support IDSEL!=0, flashbase and decode size calculations
+	 * IDSEL=0. To support IDSEL!=0, rom_base and decode size calculations
 	 * have to be adjusted.
 	 */
 	int max_decode_fwh_idsel = 0, max_decode_fwh_decode = 0;
@@ -1859,6 +1859,7 @@
  */
 static int get_flashbase_sc520(struct flashprog_programmer *prog, struct pci_dev *dev, const char *name)
 {
+	struct internal_data *const internal = prog->data;
 	int i, bootcs_found = 0;
 	uint32_t parx = 0;
 	void *mmcr;
@@ -1879,16 +1880,16 @@
 		}
 	}
 
-	/* 3. PARx[25] = 1b --> flashbase[29:16] = PARx[13:0]
-	 *    PARx[25] = 0b --> flashbase[29:12] = PARx[17:0]
+	/* 3. PARx[25] = 1b --> rom_base[29:16] = PARx[13:0]
+	 *    PARx[25] = 0b --> rom_base[29:12] = PARx[17:0]
 	 */
 	if (bootcs_found) {
 		if (parx & (1 << 25)) {
 			parx &= (1 << 14) - 1; /* Mask [13:0] */
-			flashbase = parx << 16;
+			internal->rom_base = parx << 16;
 		} else {
 			parx &= (1 << 18) - 1; /* Mask [17:0] */
-			flashbase = parx << 12;
+			internal->rom_base = parx << 12;
 		}
 	} else {
 		msg_pinfo("AMD Elan SC520 detected, but no BOOTCS. "
diff --git a/drkaiser.c b/drkaiser.c
index 6fcb5d2..5634b3a 100644
--- a/drkaiser.c
+++ b/drkaiser.c
@@ -74,7 +74,7 @@
 	if (drkaiser_bar == ERROR_PTR)
 		return 1;
 
-	return register_par_master(&par_master_drkaiser, BUS_PARALLEL, 128*KiB, NULL);
+	return register_par_master(&par_master_drkaiser, BUS_PARALLEL, 0, 128*KiB, NULL);
 }
 
 static void drkaiser_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/dummyflasher.c b/dummyflasher.c
index 3f3983b..9f27d91 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -519,7 +519,7 @@
 	if (dummy_buses_supported & BUS_NONSPI)
 		ret |= register_par_master(&par_master_dummyflasher,
 					   dummy_buses_supported & BUS_NONSPI,
-					   0, data);
+					   0, 0, data);
 	if (dummy_buses_supported & BUS_SPI)
 		ret |= register_spi_master(&spi_master_dummyflasher, 0, data);
 
diff --git a/flashprog.c b/flashprog.c
index b2a656d..c1a8808 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -41,9 +41,6 @@
 static const struct programmer_entry *programmer = NULL;
 static char *programmer_param = NULL;
 
-/* If nonzero, used as the start address of bottom-aligned flash. */
-unsigned long flashbase;
-
 /* Is writing allowed with this programmer? */
 bool programmer_may_write;
 
@@ -135,9 +132,6 @@
 	}
 	programmer = prog->driver;
 	programmer_param = prog->param;
-	/* Initialize all programmer specific data. */
-	/* Default to top aligned flash at 4 GB. */
-	flashbase = 0;
 	/* Registering shutdown functions is now allowed. */
 	may_register_shutdown = true;
 	/* Default to allowing writes. Broken programmers set this to 0. */
diff --git a/gfxnvidia.c b/gfxnvidia.c
index 253180e..c3e08d8 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, 0, NULL);
+	return register_par_master(&par_master_gfxnvidia, BUS_PARALLEL, 0, 0, NULL);
 }
 
 static void gfxnvidia_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/include/programmer.h b/include/programmer.h
index 04c4b42..9249f5c 100644
--- a/include/programmer.h
+++ b/include/programmer.h
@@ -226,7 +226,7 @@
 int chipset_flash_enable(struct flashprog_programmer *);
 
 /* processor_enable.c */
-int processor_flash_enable(void);
+int processor_flash_enable(struct flashprog_programmer *);
 #endif
 
 #if CONFIG_INTERNAL == 1
@@ -243,6 +243,7 @@
 
 /* internal.c */
 struct internal_data {
+	uintptr_t rom_base;
 	size_t max_rom_decode;
 };
 struct superio {
@@ -270,7 +271,6 @@
 /* flashprog.c */
 // FIXME: These need to be local, not global
 extern bool programmer_may_write;
-extern unsigned long flashbase;
 char *extract_programmer_param(const char *param_name);
 
 struct master_common {
@@ -445,6 +445,8 @@
 	/* XXX: Keep common struct first, it is overlayed with other master types. */
 	struct master_common common;
 
+	uintptr_t rom_base;
+
 	void (*chip_writeb) (const struct flashctx *flash, uint8_t val, chipaddr addr);
 	void (*chip_writew) (const struct flashctx *flash, uint16_t val, chipaddr addr);
 	void (*chip_writel) (const struct flashctx *flash, uint32_t val, chipaddr addr);
@@ -460,7 +462,7 @@
 	int (*shutdown)(void *data);
 	void *data;
 };
-int register_par_master(const struct par_master *mst, const enum chipbustype buses, size_t max_rom_decode, void *data);
+int register_par_master(const struct par_master *mst, const enum chipbustype buses, uintptr_t rom_base, size_t max_rom_decode, void *data);
 
 /* programmer.c */
 void *fallback_map(const char *descr, uintptr_t phys_addr, size_t len);
diff --git a/internal.c b/internal.c
index 8af2690..e383809 100644
--- a/internal.c
+++ b/internal.c
@@ -190,6 +190,7 @@
 		ret = 1;
 		goto internal_init_exit;
 	}
+	internal->rom_base = 0; /* Default to top aligned flash at 4 GB. */
 	internal->max_rom_decode = 0;
 	prog->data = internal;
 
@@ -213,7 +214,7 @@
 		goto internal_init_exit;
 	}
 
-	if (processor_flash_enable()) {
+	if (processor_flash_enable(prog)) {
 		msg_perr("Processor detection/init failed.\n"
 			 "Aborting.\n");
 		ret = 1;
@@ -292,7 +293,7 @@
 
 	if (internal_buses_supported & BUS_NONSPI) {
 		register_par_master(&par_master_internal, internal_buses_supported,
-				    internal->max_rom_decode, NULL);
+				    internal->rom_base, internal->max_rom_decode, NULL);
 	}
 
 	/* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */
diff --git a/it8212.c b/it8212.c
index 8158a95..5daeb3b 100644
--- a/it8212.c
+++ b/it8212.c
@@ -64,7 +64,7 @@
 	/* Restore ROM BAR decode state automatically at shutdown. */
 	rpci_write_long(dev, PCI_ROM_ADDRESS, io_base_addr | 0x01);
 
-	return register_par_master(&par_master_it8212, BUS_PARALLEL, IT8212_MEMMAP_SIZE, NULL);
+	return register_par_master(&par_master_it8212, BUS_PARALLEL, 0, IT8212_MEMMAP_SIZE, NULL);
 }
 
 static void it8212_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/memory_bus.c b/memory_bus.c
index b9cd68c..3ca71d1 100644
--- a/memory_bus.c
+++ b/memory_bus.c
@@ -46,6 +46,8 @@
 
 int prepare_memory_access(struct flashctx *flash, enum preparation_steps prep)
 {
+	const struct par_master *const par = flash->mst.par;
+
 	if (prep == PREPARE_POST_PROBE)
 		return 0;
 
@@ -54,7 +56,7 @@
 	flash->virtual_registers = (chipaddr)ERROR_PTR;
 
 	const chipsize_t size = flash->chip->total_size * 1024;
-	const uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
+	const uintptr_t base = par->rom_base ? par->rom_base : (0xffffffff - size + 1);
 	void *const addr = programmer_map_flash_region(flash, flash->chip->name, base, size);
 	if (addr == ERROR_PTR) {
 		msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
diff --git a/nic3com.c b/nic3com.c
index eec24bf..fbd5e0d 100644
--- a/nic3com.c
+++ b/nic3com.c
@@ -117,7 +117,7 @@
 	 */
 	OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
 
-	return register_par_master(&par_master_nic3com, BUS_PARALLEL, 128*KiB, NULL);
+	return register_par_master(&par_master_nic3com, BUS_PARALLEL, 0, 128*KiB, NULL);
 }
 
 static void nic3com_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/nicintel.c b/nicintel.c
index 573b361..1d9a2a7 100644
--- a/nicintel.c
+++ b/nicintel.c
@@ -93,7 +93,7 @@
 	 */
 	pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR);
 
-	return register_par_master(&par_master_nicintel, BUS_PARALLEL, NICINTEL_MEMMAP_SIZE, NULL);
+	return register_par_master(&par_master_nicintel, BUS_PARALLEL, 0, 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 44c7ef4..57a326a 100644
--- a/nicnatsemi.c
+++ b/nicnatsemi.c
@@ -70,7 +70,7 @@
 	 * to be 64KiB; and the mask in the read/write functions below wants
 	 * to be 0x0000FFFF.
 	 */
-	return register_par_master(&par_master_nicnatsemi, BUS_PARALLEL, 128*KiB, NULL);
+	return register_par_master(&par_master_nicnatsemi, BUS_PARALLEL, 0, 128*KiB, NULL);
 }
 
 static void nicnatsemi_chip_writeb(const struct flashctx *flash, uint8_t val,
diff --git a/nicrealtek.c b/nicrealtek.c
index df81274..e676e99 100644
--- a/nicrealtek.c
+++ b/nicrealtek.c
@@ -84,7 +84,7 @@
 		break;
 	}
 
-	return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, 0, NULL);
+	return register_par_master(&par_master_nicrealtek, BUS_PARALLEL, 0, 0, NULL);
 }
 
 static void nicrealtek_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/parallel.c b/parallel.c
index 3e32d59..d8a751e 100644
--- a/parallel.c
+++ b/parallel.c
@@ -64,7 +64,7 @@
 }
 
 int register_par_master(const struct par_master *mst, const enum chipbustype buses,
-			const size_t max_rom_decode, void *data)
+			const uintptr_t rom_base, const size_t max_rom_decode, void *data)
 {
 	struct registered_master rmst = { 0 };
 
@@ -86,6 +86,8 @@
 
 	rmst.buses_supported = buses;
 	rmst.par = *mst;
+
+	rmst.par.rom_base = rom_base;
 	if (data)
 		rmst.par.data = data;
 
diff --git a/processor_enable.c b/processor_enable.c
index 7c27ccd..909a531 100644
--- a/processor_enable.c
+++ b/processor_enable.c
@@ -62,7 +62,7 @@
 }
 #endif
 
-int processor_flash_enable(void)
+int processor_flash_enable(struct flashprog_programmer *prog)
 {
 	/* Default to 1 to catch not implemented architectures. */
 	int ret = 1;
@@ -70,7 +70,8 @@
 	/* FIXME: detect loongson on FreeBSD and OpenBSD as well.  */
 #if defined (__MIPSEL__) && defined (__linux)
 	if (is_loongson()) {
-		flashbase = 0x1fc00000;
+		struct internal_data *const internal = prog->data;
+		internal->rom_base = 0x1fc00000;
 		ret = 0;
 	}
 #elif defined(__i386__) || defined(__x86_64__)
diff --git a/satamv.c b/satamv.c
index a957505..7fec115 100644
--- a/satamv.c
+++ b/satamv.c
@@ -148,7 +148,7 @@
 
 	/* 512 kByte with two 8-bit latches, and
 	 * 4 MByte with additional 3-bit latch. */
-	return register_par_master(&par_master_satamv, BUS_PARALLEL, 4*MiB, NULL);
+	return register_par_master(&par_master_satamv, BUS_PARALLEL, 0, 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 abb1d4c..c3f7bb2 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, 0, NULL);
+	return register_par_master(&par_master_satasii, BUS_PARALLEL, 0, 0, NULL);
 }
 
 static void satasii_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
diff --git a/serprog.c b/serprog.c
index 257562a..e1d33ed 100644
--- a/serprog.c
+++ b/serprog.c
@@ -766,7 +766,7 @@
 	if (serprog_buses_supported & BUS_SPI)
 		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, 0, NULL);
+		register_par_master(&par_master_serprog, serprog_buses_supported & BUS_NONSPI, 0, 0, NULL);
 	return 0;
 
 init_err_cleanup_exit: