Register Parallel/LPC/FWH programmers the same way SPI programmers are registered.
This patch is not yet 100% clean (80 column limit violations etc.), but the general idea should be clear.
We need something like this patch to handle programmers with multiple flash chips (e.g. LPC/FWH chips mapped to different regions on mainboards).
TODO: - Should register_par_programmer(...) be called before or after setting max_rom_decode.*? - Is there a better name for register_par_programmer? - Should max_rom_decode.* be part of the registration? - Should map_flash_region/unmap_flash_region be part of the registration?
Please check that all programmers have a register_par_programmer call unless the chip_* functions were noop.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-register_par_programmer/drkaiser.c =================================================================== --- flashrom-register_par_programmer/drkaiser.c (Revision 1325) +++ flashrom-register_par_programmer/drkaiser.c (Arbeitskopie) @@ -37,6 +37,17 @@
static uint8_t *drkaiser_bar;
+static const struct par_programmer par_programmer_drkaiser = { + .chip_readb = drkaiser_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = drkaiser_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + int drkaiser_init(void) { uint32_t addr; @@ -53,7 +64,8 @@ drkaiser_bar = physmap("Dr. Kaiser PC-Waechter flash memory", addr, 128 * 1024);
- buses_supported = CHIP_BUSTYPE_PARALLEL; + register_par_programmer(&par_programmer_drkaiser, CHIP_BUSTYPE_PARALLEL); + max_rom_decode.parallel = 131072;
return 0; } Index: flashrom-register_par_programmer/it87spi.c =================================================================== --- flashrom-register_par_programmer/it87spi.c (Revision 1325) +++ flashrom-register_par_programmer/it87spi.c (Arbeitskopie) @@ -193,7 +193,7 @@ free(portpos); exit_conf_mode_ite(port); it8716f_flashport = flashport; - if (buses_supported & CHIP_BUSTYPE_SPI) + if (internal_buses_supported & CHIP_BUSTYPE_SPI) msg_pdbg("Overriding chipset SPI with IT87 SPI.\n"); /* FIXME: Add the SPI bus or replace the other buses with it? */ register_spi_programmer(&spi_programmer_it87xx); Index: flashrom-register_par_programmer/gfxnvidia.c =================================================================== --- flashrom-register_par_programmer/gfxnvidia.c (Revision 1325) +++ flashrom-register_par_programmer/gfxnvidia.c (Arbeitskopie) @@ -60,6 +60,17 @@ {}, };
+static const struct par_programmer par_programmer_gfxnvidia = { + .chip_readb = gfxnvidia_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = gfxnvidia_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + int gfxnvidia_init(void) { uint32_t reg32; @@ -78,7 +89,7 @@
nvidia_bar = physmap("NVIDIA", io_base_addr, 16 * 1024 * 1024);
- buses_supported = CHIP_BUSTYPE_PARALLEL; + register_par_programmer(&par_programmer_gfxnvidia, CHIP_BUSTYPE_PARALLEL);
/* Write/erase doesn't work. */ programmer_may_write = 0; Index: flashrom-register_par_programmer/nicrealtek.c =================================================================== --- flashrom-register_par_programmer/nicrealtek.c (Revision 1325) +++ flashrom-register_par_programmer/nicrealtek.c (Arbeitskopie) @@ -36,13 +36,24 @@ {}, };
+static const struct par_programmer par_programmer_nicrealtek = { + .chip_readb = nicrealtek_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicrealtek_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + int nicrealtek_init(void) { get_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_realtek);
- buses_supported = CHIP_BUSTYPE_PARALLEL; + register_par_programmer(&par_programmer_nicrealtek, CHIP_BUSTYPE_PARALLEL);
return 0; } Index: flashrom-register_par_programmer/serprog.c =================================================================== --- flashrom-register_par_programmer/serprog.c (Revision 1325) +++ flashrom-register_par_programmer/serprog.c (Arbeitskopie) @@ -295,6 +295,19 @@ return 0; }
+static const struct par_programmer par_programmer_serprog = { + .chip_readb = serprog_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = serprog_chip_readn, + .chip_writeb = serprog_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + +enum chipbustype serprog_buses_supported = CHIP_BUSTYPE_NONE; + int serprog_init(void) { uint16_t iface; @@ -454,7 +467,7 @@ msg_perr("Warning: NAK to query supported buses\n"); c = CHIP_BUSTYPE_NONSPI; /* A reasonable default for now. */ } - buses_supported = c; + serprog_buses_supported = c;
if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) { msg_perr("Error: NAK to initialize operation buffer\n"); @@ -490,6 +503,8 @@ sp_max_read_n = 0; }
+ register_par_programmer(&par_programmer_serprog, serprog_buses_supported); + sp_prev_was_write = 0; sp_streamed_transmit_ops = 0; sp_streamed_transmit_bytes = 0; Index: flashrom-register_par_programmer/satamv.c =================================================================== --- flashrom-register_par_programmer/satamv.c (Revision 1325) +++ flashrom-register_par_programmer/satamv.c (Arbeitskopie) @@ -40,6 +40,17 @@ #define PCI_BAR2_CONTROL 0x00c08 #define GPIO_PORT_CONTROL 0x104f0
+static const struct par_programmer par_programmer_satamv = { + .chip_readb = satamv_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = satamv_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + /* * Random notes: * FCE# Flash Chip Enable @@ -125,7 +136,7 @@ mv_iobar = tmp & 0xffff; msg_pspew("Activating I/O BAR at 0x%04x\n", mv_iobar);
- buses_supported = CHIP_BUSTYPE_PARALLEL; + register_par_programmer(&par_programmer_satamv, CHIP_BUSTYPE_PARALLEL);
/* 512 kByte with two 8-bit latches, and * 4 MByte with additional 3-bit latch. */ Index: flashrom-register_par_programmer/dummyflasher.c =================================================================== --- flashrom-register_par_programmer/dummyflasher.c (Revision 1325) +++ flashrom-register_par_programmer/dummyflasher.c (Arbeitskopie) @@ -73,6 +73,20 @@ .read = default_spi_read, .write_256 = dummy_spi_write_256, }; + +static const struct par_programmer par_programmer_dummy = { + .chip_readb = dummy_chip_readb, + .chip_readw = dummy_chip_readw, + .chip_readl = dummy_chip_readl, + .chip_readn = dummy_chip_readn, + .chip_writeb = dummy_chip_writeb, + .chip_writew = dummy_chip_writew, + .chip_writel = dummy_chip_writel, + .chip_writen = dummy_chip_writen, +}; + +enum chipbustype dummy_buses_supported = CHIP_BUSTYPE_NONE; + int dummy_init(void) { char *bustext = NULL; @@ -90,24 +104,31 @@ /* Convert the parameters to lowercase. */ tolower_string(bustext);
- buses_supported = CHIP_BUSTYPE_NONE; + dummy_buses_supported = CHIP_BUSTYPE_NONE; if (strstr(bustext, "parallel")) { - buses_supported |= CHIP_BUSTYPE_PARALLEL; + dummy_buses_supported |= CHIP_BUSTYPE_PARALLEL; msg_pdbg("Enabling support for %s flash.\n", "parallel"); } if (strstr(bustext, "lpc")) { - buses_supported |= CHIP_BUSTYPE_LPC; + dummy_buses_supported |= CHIP_BUSTYPE_LPC; msg_pdbg("Enabling support for %s flash.\n", "LPC"); } if (strstr(bustext, "fwh")) { - buses_supported |= CHIP_BUSTYPE_FWH; + dummy_buses_supported |= CHIP_BUSTYPE_FWH; msg_pdbg("Enabling support for %s flash.\n", "FWH"); } + if (dummy_buses_supported & (CHIP_BUSTYPE_PARALLEL | CHIP_BUSTYPE_LPC | + CHIP_BUSTYPE_FWH)) + register_par_programmer(&par_programmer_dummy, + dummy_buses_supported & + (CHIP_BUSTYPE_PARALLEL | + CHIP_BUSTYPE_LPC | + CHIP_BUSTYPE_FWH)); if (strstr(bustext, "spi")) { register_spi_programmer(&spi_programmer_dummyflasher); msg_pdbg("Enabling support for %s flash.\n", "SPI"); } - if (buses_supported == CHIP_BUSTYPE_NONE) + if (dummy_buses_supported == CHIP_BUSTYPE_NONE) msg_pdbg("Support for all flash bus types disabled.\n"); free(bustext);
Index: flashrom-register_par_programmer/internal.c =================================================================== --- flashrom-register_par_programmer/internal.c (Revision 1325) +++ flashrom-register_par_programmer/internal.c (Arbeitskopie) @@ -127,6 +127,19 @@ int is_laptop = 0; int laptop_ok = 0;
+static const struct par_programmer par_programmer_internal = { + .chip_readb = internal_chip_readb, + .chip_readw = internal_chip_readw, + .chip_readl = internal_chip_readl, + .chip_readn = internal_chip_readn, + .chip_writeb = internal_chip_writeb, + .chip_writew = internal_chip_writew, + .chip_writel = internal_chip_writel, + .chip_writen = fallback_chip_writen, +}; + +enum chipbustype internal_buses_supported = CHIP_BUSTYPE_NONE; + int internal_init(void) { #if __FLASHROM_LITTLE_ENDIAN__ @@ -180,9 +193,10 @@ get_io_perms();
/* Default to Parallel/LPC/FWH flash devices. If a known host controller - * is found, the init routine sets the buses_supported bitfield. + * is found, the host controller init routine sets the + * internal_buses_supported bitfield. */ - buses_supported = CHIP_BUSTYPE_NONSPI; + internal_buses_supported = CHIP_BUSTYPE_NONSPI;
/* Initialize PCI access for flash enables */ pacc = pci_alloc(); /* Get the pci_access structure */ @@ -267,6 +281,11 @@ * Besides that, we don't check the board enable return code either. */ #if defined(__i386__) || defined(__x86_64__) || defined (__mips) + register_par_programmer(&par_programmer_internal, internal_buses_supported); + /* FIXME: Move this message out of chipset_enable.c. */ + msg_pinfo("This chipset supports the following protocols: %s.\n", + flashbuses_to_text(buses_supported)); + return 0; #else msg_perr("Your platform is not supported yet for the internal " Index: flashrom-register_par_programmer/nicnatsemi.c =================================================================== --- flashrom-register_par_programmer/nicnatsemi.c (Revision 1325) +++ flashrom-register_par_programmer/nicnatsemi.c (Arbeitskopie) @@ -35,13 +35,24 @@ {}, };
+static const struct par_programmer par_programmer_nicnatsemi = { + .chip_readb = nicnatsemi_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicnatsemi_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + int nicnatsemi_init(void) { get_io_perms();
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_natsemi);
- buses_supported = CHIP_BUSTYPE_PARALLEL; + register_par_programmer(&par_programmer_nicnatsemi, CHIP_BUSTYPE_PARALLEL);
/* 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 Index: flashrom-register_par_programmer/it85spi.c =================================================================== --- flashrom-register_par_programmer/it85spi.c (Revision 1325) +++ flashrom-register_par_programmer/it85spi.c (Arbeitskopie) @@ -254,7 +254,11 @@ INDIRECT_A3(shm_io_base, (base >> 24)); #endif #ifdef LPC_MEMORY - base = (chipaddr)programmer_map_flash_region("it85 communication", + /* WTF?!? FIXME: This should use physmap instead. And it should + * automatically block accessing that region for anything else. + * Major TODO here, and it will be a lot of work. + */ + base = (chipaddr)physmap("it85 communication", 0xFFFFF000, 0x1000); msg_pdbg("%s():%d base=0x%08x\n", __func__, __LINE__, (unsigned int)base); @@ -282,16 +286,17 @@ { int ret;
- if (!(buses_supported & CHIP_BUSTYPE_FWH)) { + if (!(internal_buses_supported & CHIP_BUSTYPE_FWH)) { msg_pdbg("%s():%d buses not support FWH\n", __func__, __LINE__); return 1; } ret = it85xx_spi_common_init(s); msg_pdbg("FWH: %s():%d ret=%d\n", __func__, __LINE__, ret); if (!ret) { - msg_pdbg("%s():%d buses_supported=0x%x\n", __func__, __LINE__, - buses_supported); - if (buses_supported & CHIP_BUSTYPE_FWH) + msg_pdbg("%s():%d internal_buses_supported=0x%x\n", __func__, __LINE__, + internal_buses_supported); + /* FIXME: We check for FWH, but claim SPI override? WTF? */ + if (internal_buses_supported & CHIP_BUSTYPE_FWH) msg_pdbg("Overriding chipset SPI with IT85 FWH|SPI.\n"); /* Really leave FWH enabled? */ /* Set this as spi controller. */ Index: flashrom-register_par_programmer/atahpt.c =================================================================== --- flashrom-register_par_programmer/atahpt.c (Revision 1325) +++ flashrom-register_par_programmer/atahpt.c (Arbeitskopie) @@ -38,6 +38,17 @@ {}, };
+static const struct par_programmer par_programmer_atahpt = { + .chip_readb = atahpt_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = atahpt_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + int atahpt_init(void) { uint32_t reg32; @@ -51,7 +62,7 @@ reg32 |= (1 << 24); rpci_write_long(pcidev_dev, REG_FLASH_ACCESS, reg32);
- buses_supported = CHIP_BUSTYPE_PARALLEL; + register_par_programmer(&par_programmer_atahpt, CHIP_BUSTYPE_PARALLEL);
return 0; } Index: flashrom-register_par_programmer/nic3com.c =================================================================== --- flashrom-register_par_programmer/nic3com.c (Revision 1325) +++ flashrom-register_par_programmer/nic3com.c (Arbeitskopie) @@ -55,6 +55,17 @@ {}, };
+static const struct par_programmer par_programmer_nic3com = { + .chip_readb = nic3com_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nic3com_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + int nic3com_init(void) { get_io_perms(); @@ -81,8 +92,8 @@ */ OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
- buses_supported = CHIP_BUSTYPE_PARALLEL; max_rom_decode.parallel = 128 * 1024; + register_par_programmer(&par_programmer_nic3com, CHIP_BUSTYPE_PARALLEL);
return 0; } Index: flashrom-register_par_programmer/satasii.c =================================================================== --- flashrom-register_par_programmer/satasii.c (Revision 1325) +++ flashrom-register_par_programmer/satasii.c (Arbeitskopie) @@ -40,6 +40,17 @@ {}, };
+static const struct par_programmer par_programmer_satasii = { + .chip_readb = satasii_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = satasii_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + int satasii_init(void) { uint32_t addr; @@ -65,7 +76,7 @@ if ((id != 0x0680) && (!(pci_mmio_readl(sii_bar) & (1 << 26)))) msg_pinfo("Warning: Flash seems unconnected.\n");
- buses_supported = CHIP_BUSTYPE_PARALLEL; + register_par_programmer(&par_programmer_satasii, CHIP_BUSTYPE_PARALLEL);
return 0; } Index: flashrom-register_par_programmer/nicintel.c =================================================================== --- flashrom-register_par_programmer/nicintel.c (Revision 1325) +++ flashrom-register_par_programmer/nicintel.c (Arbeitskopie) @@ -41,6 +41,17 @@
#define CSR_FCR 0x0c
+static const struct par_programmer par_programmer_nicintel = { + .chip_readb = nicintel_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicintel_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + int nicintel_init(void) { uintptr_t addr; @@ -78,9 +89,8 @@ */ pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR);
- buses_supported = CHIP_BUSTYPE_PARALLEL; - max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE; + register_par_programmer(&par_programmer_nicintel, CHIP_BUSTYPE_PARALLEL);
return 0;
Index: flashrom-register_par_programmer/chipset_enable.c =================================================================== --- flashrom-register_par_programmer/chipset_enable.c (Revision 1325) +++ flashrom-register_par_programmer/chipset_enable.c (Arbeitskopie) @@ -208,7 +208,7 @@ uint16_t old, new; uint16_t xbcs = 0x4e; /* X-Bus Chip Select register. */
- buses_supported = CHIP_BUSTYPE_PARALLEL; + internal_buses_supported = CHIP_BUSTYPE_PARALLEL;
old = pci_read_word(dev, xbcs);
@@ -286,7 +286,7 @@ * FWH_DEC_EN1, but they are called FB_SEL1, FB_SEL2, FB_DEC_EN1 and * FB_DEC_EN2. */ - buses_supported = CHIP_BUSTYPE_FWH; + internal_buses_supported = CHIP_BUSTYPE_FWH; return enable_flash_ich(dev, name, 0x4e); }
@@ -383,9 +383,9 @@ msg_pdbg("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh);
/* If we're called by enable_flash_ich_dc_spi, it will override - * buses_supported anyway. + * internal_buses_supported anyway. */ - buses_supported = CHIP_BUSTYPE_FWH; + internal_buses_supported = CHIP_BUSTYPE_FWH; return enable_flash_ich(dev, name, 0xdc); }
@@ -405,7 +405,7 @@ if (new != old) rpci_write_byte(dev, 0xd9, new);
- buses_supported = CHIP_BUSTYPE_FWH; + internal_buses_supported = CHIP_BUSTYPE_FWH; return 0; }
@@ -458,7 +458,7 @@ * on ICH7 when the southbridge is strapped to LPC */
- buses_supported = CHIP_BUSTYPE_FWH; + internal_buses_supported = CHIP_BUSTYPE_FWH; if (ich_generation == 7) { if(bbs == ICH_STRAP_LPC) { /* No further SPI initialization required */ @@ -466,7 +466,7 @@ } else /* Disable LPC/FWH if strapped to PCI or SPI */ - buses_supported = 0; + internal_buses_supported = 0; }
/* this adds CHIP_BUSTYPE_SPI */ @@ -557,7 +557,7 @@ #define CS5530_ENABLE_SA2320 (1 << 2) #define CS5530_ENABLE_SA20 (1 << 6)
- buses_supported = CHIP_BUSTYPE_PARALLEL; + internal_buses_supported = CHIP_BUSTYPE_PARALLEL; /* Decode 0x000E0000-0x000FFFFF (128 kB), not just 64 kB, and * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 kB. * FIXME: Should we really touch the low mapping below 1 MB? Flashrom @@ -707,7 +707,7 @@ (prot & 0xfffff800) + (((prot & 0x7fc) << 8) | 0x3ff)); }
- buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH; + internal_buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH;
ret = sb600_probe_spi(dev);
@@ -793,7 +793,7 @@ { uint8_t tmp;
- buses_supported = CHIP_BUSTYPE_PARALLEL; + internal_buses_supported = CHIP_BUSTYPE_PARALLEL;
tmp = INB(0xc06); tmp |= 0x1; @@ -893,7 +893,7 @@ switch ((val >> 5) & 0x3) { case 0x0: ret = enable_flash_mcp55(dev, name); - buses_supported = CHIP_BUSTYPE_LPC; + internal_buses_supported = CHIP_BUSTYPE_LPC; msg_pdbg("Flash bus type is LPC\n"); break; case 0x2: @@ -901,14 +901,14 @@ /* SPI is added in mcp6x_spi_init if it works. * Do we really want to disable LPC in this case? */ - buses_supported = CHIP_BUSTYPE_NONE; + internal_buses_supported = CHIP_BUSTYPE_NONE; msg_pdbg("Flash bus type is SPI\n"); msg_perr("SPI on this chipset is WIP. Write is unsupported!\n"); programmer_may_write = 0; break; default: /* Should not happen. */ - buses_supported = CHIP_BUSTYPE_NONE; + internal_buses_supported = CHIP_BUSTYPE_NONE; msg_pdbg("Flash bus type is unknown (none)\n"); msg_pinfo("Something went wrong with bus type detection.\n"); goto out_msg; @@ -1215,8 +1215,5 @@ msg_pinfo("PROBLEMS, continuing anyway\n"); }
- msg_pinfo("This chipset supports the following protocols: %s.\n", - flashbuses_to_text(buses_supported)); - return ret; } Index: flashrom-register_par_programmer/programmer.c =================================================================== --- flashrom-register_par_programmer/programmer.c (Revision 1325) +++ flashrom-register_par_programmer/programmer.c (Arbeitskopie) @@ -19,7 +19,21 @@ */
#include "flash.h" +#include "programmer.h"
+static const struct par_programmer par_programmer_none = { + .chip_readb = noop_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = noop_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + +const struct par_programmer *par_programmer = &par_programmer_none; + /* No-op shutdown() for programmers which don't need special handling */ int noop_shutdown(void) { @@ -96,3 +110,9 @@ buf[i] = chip_readb(addr + i); return; } + +void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses) +{ + par_programmer = pgm; + buses_supported |= buses; +} Index: flashrom-register_par_programmer/flashrom.c =================================================================== --- flashrom-register_par_programmer/flashrom.c (Revision 1325) +++ flashrom-register_par_programmer/flashrom.c (Arbeitskopie) @@ -132,14 +132,6 @@ .shutdown = internal_shutdown, .map_flash_region = physmap, .unmap_flash_region = physunmap, - .chip_readb = internal_chip_readb, - .chip_readw = internal_chip_readw, - .chip_readl = internal_chip_readl, - .chip_readn = internal_chip_readn, - .chip_writeb = internal_chip_writeb, - .chip_writew = internal_chip_writew, - .chip_writel = internal_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -151,14 +143,6 @@ .shutdown = dummy_shutdown, .map_flash_region = dummy_map, .unmap_flash_region = dummy_unmap, - .chip_readb = dummy_chip_readb, - .chip_readw = dummy_chip_readw, - .chip_readl = dummy_chip_readl, - .chip_readn = dummy_chip_readn, - .chip_writeb = dummy_chip_writeb, - .chip_writew = dummy_chip_writew, - .chip_writel = dummy_chip_writel, - .chip_writen = dummy_chip_writen, .delay = internal_delay, }, #endif @@ -170,14 +154,6 @@ .shutdown = nic3com_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = nic3com_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nic3com_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -191,14 +167,6 @@ .shutdown = nicrealtek_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = nicrealtek_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicrealtek_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -210,14 +178,6 @@ .shutdown = nicnatsemi_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = nicnatsemi_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicnatsemi_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -229,14 +189,6 @@ .shutdown = gfxnvidia_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = gfxnvidia_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = gfxnvidia_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -248,14 +200,6 @@ .shutdown = drkaiser_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = drkaiser_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = drkaiser_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -267,14 +211,6 @@ .shutdown = satasii_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = satasii_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = satasii_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -286,14 +222,6 @@ .shutdown = atahpt_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = atahpt_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = atahpt_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -305,14 +233,6 @@ .shutdown = noop_shutdown, /* Missing shutdown */ .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -324,14 +244,6 @@ .shutdown = serprog_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = serprog_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = serprog_chip_readn, - .chip_writeb = serprog_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = serprog_delay, }, #endif @@ -343,14 +255,6 @@ .shutdown = buspirate_spi_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -362,14 +266,6 @@ .shutdown = dediprog_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -381,14 +277,6 @@ .shutdown = noop_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -400,14 +288,6 @@ .shutdown = nicintel_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = nicintel_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicintel_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -419,14 +299,6 @@ .shutdown = nicintel_spi_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -438,14 +310,6 @@ .shutdown = ogp_spi_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -457,14 +321,6 @@ .shutdown = satamv_shutdown, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = satamv_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = satamv_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -566,42 +422,42 @@
void chip_writeb(uint8_t val, chipaddr addr) { - programmer_table[programmer].chip_writeb(val, addr); + par_programmer->chip_writeb(val, addr); }
void chip_writew(uint16_t val, chipaddr addr) { - programmer_table[programmer].chip_writew(val, addr); + par_programmer->chip_writew(val, addr); }
void chip_writel(uint32_t val, chipaddr addr) { - programmer_table[programmer].chip_writel(val, addr); + par_programmer->chip_writel(val, addr); }
void chip_writen(uint8_t *buf, chipaddr addr, size_t len) { - programmer_table[programmer].chip_writen(buf, addr, len); + par_programmer->chip_writen(buf, addr, len); }
uint8_t chip_readb(const chipaddr addr) { - return programmer_table[programmer].chip_readb(addr); + return par_programmer->chip_readb(addr); }
uint16_t chip_readw(const chipaddr addr) { - return programmer_table[programmer].chip_readw(addr); + return par_programmer->chip_readw(addr); }
uint32_t chip_readl(const chipaddr addr) { - return programmer_table[programmer].chip_readl(addr); + return par_programmer->chip_readl(addr); }
void chip_readn(uint8_t *buf, chipaddr addr, size_t len) { - programmer_table[programmer].chip_readn(buf, addr, len); + par_programmer->chip_readn(buf, addr, len); }
void programmer_delay(int usecs) Index: flashrom-register_par_programmer/programmer.h =================================================================== --- flashrom-register_par_programmer/programmer.h (Revision 1325) +++ flashrom-register_par_programmer/programmer.h (Arbeitskopie) @@ -95,14 +95,6 @@ size_t len); void (*unmap_flash_region) (void *virt_addr, size_t len);
- void (*chip_writeb) (uint8_t val, chipaddr addr); - void (*chip_writew) (uint16_t val, chipaddr addr); - void (*chip_writel) (uint32_t val, chipaddr addr); - void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len); - uint8_t (*chip_readb) (const chipaddr addr); - uint16_t (*chip_readw) (const chipaddr addr); - uint32_t (*chip_readl) (const chipaddr addr); - void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len); void (*delay) (int usecs); };
@@ -302,6 +294,7 @@ extern int force_boardmismatch; void probe_superio(void); int register_superio(struct superio s); +extern enum chipbustype internal_buses_supported; int internal_init(void); int internal_shutdown(void); void internal_chip_writeb(uint8_t val, chipaddr addr); @@ -357,6 +350,18 @@ uint16_t fallback_chip_readw(const chipaddr addr); uint32_t fallback_chip_readl(const chipaddr addr); void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); +struct par_programmer { + void (*chip_writeb) (uint8_t val, chipaddr addr); + void (*chip_writew) (uint16_t val, chipaddr addr); + void (*chip_writel) (uint32_t val, chipaddr addr); + void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len); + uint8_t (*chip_readb) (const chipaddr addr); + uint16_t (*chip_readw) (const chipaddr addr); + uint32_t (*chip_readl) (const chipaddr addr); + void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len); +}; +extern const struct par_programmer *par_programmer; +void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses);
/* dummyflasher.c */ #if CONFIG_DUMMY == 1 Index: flashrom-register_par_programmer/board_enable.c =================================================================== --- flashrom-register_par_programmer/board_enable.c (Revision 1325) +++ flashrom-register_par_programmer/board_enable.c (Arbeitskopie) @@ -424,7 +424,7 @@ /* Check if at least one flash segment is enabled. */ if (tmp & 0xf0) { /* The IT8705F will respond to LPC cycles and translate them. */ - buses_supported = CHIP_BUSTYPE_PARALLEL; + internal_buses_supported = CHIP_BUSTYPE_PARALLEL; /* Flash ROM I/F Writes Enable */ tmp |= 0x04; msg_pdbg("Enabling IT8705F flash ROM interface write.\n");
New version, against svn HEAD. Please comment on the RFC part.
Register Parallel/LPC/FWH programmers the same way SPI programmers are registered.
Additional fixes: Set max_rom_decode.parallel for drkaiser. Remove abuse of programmer_map_flash_region in it85spi. Annotate several FIXMEs in it85spi.
Note: Programmers without parallel/LPC/FWH chip support should not call register_par_programmer().
This patch is not yet 100% clean (80 column limit violations etc.), but the general idea should be clear.
We need something like this patch to handle programmers with multiple flash chips (e.g. LPC/FWH chips mapped to different regions on mainboards).
RFC/TODO: - Should register_par_programmer(...) be called before or after setting max_rom_decode.*? - Should register_par_programmer(...) be called before or after register_shutdown()? - Is there a better name for register_par_programmer? - Should max_rom_decode.* be part of the registration? - Should map_flash_region/unmap_flash_region be part of the registration?
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-register_par_programmer/drkaiser.c =================================================================== --- flashrom-register_par_programmer/drkaiser.c (Revision 1433) +++ flashrom-register_par_programmer/drkaiser.c (Arbeitskopie) @@ -39,6 +39,19 @@
static uint8_t *drkaiser_bar;
+static const struct par_programmer par_programmer_drkaiser = { + .chip_readb = drkaiser_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = drkaiser_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int drkaiser_shutdown(void *data) { physunmap(drkaiser_bar, DRKAISER_MEMMAP_SIZE); @@ -64,7 +77,8 @@ drkaiser_bar = physmap("Dr. Kaiser PC-Waechter flash memory", addr, DRKAISER_MEMMAP_SIZE);
- buses_supported = BUS_PARALLEL; + register_par_programmer(&par_programmer_drkaiser, BUS_PARALLEL); + max_rom_decode.parallel = 131072;
if (register_shutdown(drkaiser_shutdown, NULL)) return 1; Index: flashrom-register_par_programmer/it87spi.c =================================================================== --- flashrom-register_par_programmer/it87spi.c (Revision 1433) +++ flashrom-register_par_programmer/it87spi.c (Arbeitskopie) @@ -192,7 +192,7 @@ free(portpos); exit_conf_mode_ite(port); it8716f_flashport = flashport; - if (buses_supported & BUS_SPI) + 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_programmer(&spi_programmer_it87xx); Index: flashrom-register_par_programmer/gfxnvidia.c =================================================================== --- flashrom-register_par_programmer/gfxnvidia.c (Revision 1433) +++ flashrom-register_par_programmer/gfxnvidia.c (Arbeitskopie) @@ -61,6 +61,19 @@ {}, };
+static const struct par_programmer par_programmer_gfxnvidia = { + .chip_readb = gfxnvidia_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = gfxnvidia_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int gfxnvidia_shutdown(void *data) { physunmap(nvidia_bar, GFXNVIDIA_MEMMAP_SIZE); @@ -94,7 +107,7 @@ reg32 &= ~(1 << 0); rpci_write_long(pcidev_dev, 0x50, reg32);
- buses_supported = BUS_PARALLEL; + register_par_programmer(&par_programmer_gfxnvidia, BUS_PARALLEL);
/* Write/erase doesn't work. */ programmer_may_write = 0; Index: flashrom-register_par_programmer/serprog.c =================================================================== --- flashrom-register_par_programmer/serprog.c (Revision 1433) +++ flashrom-register_par_programmer/serprog.c (Arbeitskopie) @@ -302,6 +302,21 @@ return 0; }
+static const struct par_programmer par_programmer_serprog = { + .chip_readb = serprog_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = serprog_chip_readn, + .chip_writeb = serprog_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + +static enum chipbustype serprog_buses_supported = BUS_NONE; + int serprog_init(void) { uint16_t iface; @@ -460,11 +475,15 @@ msg_pdbg(MSGHEADER "operation buffer size %d\n", sp_device_opbuf_size);
+ /* FIXME: This assumes that serprog device bustypes are always + * identical with flashrom bustype enums and that they all fit + * in a single byte. + */ if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) { msg_perr("Warning: NAK to query supported buses\n"); c = BUS_NONSPI; /* A reasonable default for now. */ } - buses_supported = c; + serprog_buses_supported = c;
if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) { msg_perr("Error: NAK to initialize operation buffer\n"); @@ -504,6 +523,9 @@ sp_streamed_transmit_ops = 0; sp_streamed_transmit_bytes = 0; sp_opbuf_usage = 0; + + register_par_programmer(&par_programmer_serprog, serprog_buses_supported); + return 0; }
Index: flashrom-register_par_programmer/nicrealtek.c =================================================================== --- flashrom-register_par_programmer/nicrealtek.c (Revision 1433) +++ flashrom-register_par_programmer/nicrealtek.c (Arbeitskopie) @@ -36,6 +36,19 @@ {}, };
+static const struct par_programmer par_programmer_nicrealtek = { + .chip_readb = nicrealtek_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicrealtek_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int nicrealtek_shutdown(void *data) { /* FIXME: We forgot to disable software access again. */ @@ -50,7 +63,7 @@
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_realtek);
- buses_supported = BUS_PARALLEL; + register_par_programmer(&par_programmer_nicrealtek, BUS_PARALLEL);
if (register_shutdown(nicrealtek_shutdown, NULL)) return 1; Index: flashrom-register_par_programmer/satamv.c =================================================================== --- flashrom-register_par_programmer/satamv.c (Revision 1433) +++ flashrom-register_par_programmer/satamv.c (Arbeitskopie) @@ -41,6 +41,19 @@ #define PCI_BAR2_CONTROL 0x00c08 #define GPIO_PORT_CONTROL 0x104f0
+static const struct par_programmer par_programmer_satamv = { + .chip_readb = satamv_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = satamv_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int satamv_shutdown(void *data) { physunmap(mv_bar, 0x20000); @@ -137,7 +150,7 @@ mv_iobar = tmp & 0xffff; msg_pspew("Activating I/O BAR at 0x%04x\n", mv_iobar);
- buses_supported = BUS_PARALLEL; + register_par_programmer(&par_programmer_satamv, BUS_PARALLEL);
/* 512 kByte with two 8-bit latches, and * 4 MByte with additional 3-bit latch. */ Index: flashrom-register_par_programmer/dummyflasher.c =================================================================== --- flashrom-register_par_programmer/dummyflasher.c (Revision 1433) +++ flashrom-register_par_programmer/dummyflasher.c (Arbeitskopie) @@ -75,6 +75,21 @@ .write_256 = dummy_spi_write_256, };
+static const struct par_programmer par_programmer_dummy = { + .chip_readb = dummy_chip_readb, + .chip_readw = dummy_chip_readw, + .chip_readl = dummy_chip_readl, + .chip_readn = dummy_chip_readn, + .chip_writeb = dummy_chip_writeb, + .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, +}; + +enum chipbustype dummy_buses_supported = BUS_NONE; + static int dummy_shutdown(void *data) { msg_pspew("%s\n", __func__); @@ -108,24 +123,29 @@ /* Convert the parameters to lowercase. */ tolower_string(bustext);
- buses_supported = BUS_NONE; + dummy_buses_supported = BUS_NONE; if (strstr(bustext, "parallel")) { - buses_supported |= BUS_PARALLEL; + dummy_buses_supported |= BUS_PARALLEL; msg_pdbg("Enabling support for %s flash.\n", "parallel"); } if (strstr(bustext, "lpc")) { - buses_supported |= BUS_LPC; + dummy_buses_supported |= BUS_LPC; msg_pdbg("Enabling support for %s flash.\n", "LPC"); } if (strstr(bustext, "fwh")) { - buses_supported |= BUS_FWH; + dummy_buses_supported |= BUS_FWH; msg_pdbg("Enabling support for %s flash.\n", "FWH"); } + if (dummy_buses_supported & (BUS_PARALLEL | BUS_LPC | BUS_FWH)) + register_par_programmer(&par_programmer_dummy, + dummy_buses_supported & + (BUS_PARALLEL | BUS_LPC | + BUS_FWH)); if (strstr(bustext, "spi")) { register_spi_programmer(&spi_programmer_dummyflasher); msg_pdbg("Enabling support for %s flash.\n", "SPI"); } - if (buses_supported == BUS_NONE) + if (dummy_buses_supported == BUS_NONE) msg_pdbg("Support for all flash bus types disabled.\n"); free(bustext);
Index: flashrom-register_par_programmer/cli_classic.c =================================================================== --- flashrom-register_par_programmer/cli_classic.c (Revision 1433) +++ flashrom-register_par_programmer/cli_classic.c (Arbeitskopie) @@ -443,7 +443,10 @@ ret = 1; goto out_shutdown; } + msg_pdbg("This programmer supports the following protocols: %s.\n", + flashbuses_to_text(buses_supported));
+ for (i = 0; i < ARRAY_SIZE(flashes); i++) { startchip = probe_flash(startchip, &flashes[i], 0); if (startchip == -1) Index: flashrom-register_par_programmer/internal.c =================================================================== --- flashrom-register_par_programmer/internal.c (Revision 1433) +++ flashrom-register_par_programmer/internal.c (Arbeitskopie) @@ -127,6 +127,21 @@ int is_laptop = 0; int laptop_ok = 0;
+static const struct par_programmer par_programmer_internal = { + .chip_readb = internal_chip_readb, + .chip_readw = internal_chip_readw, + .chip_readl = internal_chip_readl, + .chip_readn = internal_chip_readn, + .chip_writeb = internal_chip_writeb, + .chip_writew = internal_chip_writew, + .chip_writel = internal_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = physmap, + .unmap_flash_region = physunmap, +}; + +enum chipbustype internal_buses_supported = BUS_NONE; + static int internal_shutdown(void *data) { release_io_perms(); @@ -188,9 +203,10 @@ return 1;
/* Default to Parallel/LPC/FWH flash devices. If a known host controller - * is found, the init routine sets the buses_supported bitfield. + * is found, the host controller init routine sets the + * internal_buses_supported bitfield. */ - buses_supported = BUS_NONSPI; + internal_buses_supported = BUS_NONSPI;
/* Initialize PCI access for flash enables */ pacc = pci_alloc(); /* Get the pci_access structure */ @@ -285,6 +301,7 @@ * Besides that, we don't check the board enable return code either. */ #if defined(__i386__) || defined(__x86_64__) || defined (__mips) + register_par_programmer(&par_programmer_internal, internal_buses_supported); return 0; #else msg_perr("Your platform is not supported yet for the internal " Index: flashrom-register_par_programmer/ichspi.c =================================================================== --- flashrom-register_par_programmer/ichspi.c (Revision 1433) +++ flashrom-register_par_programmer/ichspi.c (Arbeitskopie) @@ -1359,7 +1359,7 @@ ich_spibar = physmap("VT8237S MMIO registers", mmio_base, 0x70);
/* Not sure if it speaks all these bus protocols. */ - buses_supported = BUS_LPC | BUS_FWH; + internal_buses_supported = BUS_LPC | BUS_FWH; register_spi_programmer(&spi_programmer_via);
msg_pdbg("0x00: 0x%04x (SPIS)\n", mmio_readw(ich_spibar + 0)); Index: flashrom-register_par_programmer/nicnatsemi.c =================================================================== --- flashrom-register_par_programmer/nicnatsemi.c (Revision 1433) +++ flashrom-register_par_programmer/nicnatsemi.c (Arbeitskopie) @@ -35,6 +35,19 @@ {}, };
+static const struct par_programmer par_programmer_nicnatsemi = { + .chip_readb = nicnatsemi_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicnatsemi_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int nicnatsemi_shutdown(void *data) { pci_cleanup(pacc); @@ -48,7 +61,7 @@
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_natsemi);
- buses_supported = BUS_PARALLEL; + register_par_programmer(&par_programmer_nicnatsemi, BUS_PARALLEL);
/* 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 Index: flashrom-register_par_programmer/it85spi.c =================================================================== --- flashrom-register_par_programmer/it85spi.c (Revision 1433) +++ flashrom-register_par_programmer/it85spi.c (Arbeitskopie) @@ -257,8 +257,10 @@ INDIRECT_A3(shm_io_base, (base >> 24)); #endif #ifdef LPC_MEMORY - base = (chipaddr)programmer_map_flash_region("it85 communication", - 0xFFFFF000, 0x1000); + /* FIXME: We should block accessing that region for anything else. + * Major TODO here, and it will be a lot of work. + */ + base = (chipaddr)physmap("it85 communication", 0xFFFFF000, 0x1000); msg_pdbg("%s():%d base=0x%08x\n", __func__, __LINE__, (unsigned int)base); ce_high = (unsigned char *)(base + 0xE00); /* 0xFFFFFE00 */ @@ -285,18 +287,26 @@ { int ret;
- if (!(buses_supported & BUS_FWH)) { + if (!(internal_buses_supported & BUS_FWH)) { msg_pdbg("%s():%d buses not support FWH\n", __func__, __LINE__); return 1; } ret = it85xx_spi_common_init(s); msg_pdbg("FWH: %s():%d ret=%d\n", __func__, __LINE__, ret); if (!ret) { - msg_pdbg("%s():%d buses_supported=0x%x\n", __func__, __LINE__, - buses_supported); - if (buses_supported & BUS_FWH) - msg_pdbg("Overriding chipset SPI with IT85 FWH|SPI.\n"); - /* Really leave FWH enabled? */ + msg_pdbg("%s: internal_buses_supported=0x%x\n", __func__, + internal_buses_supported); + /* Check for FWH because IT85 listens to FWH cycles. + * FIXME: The big question is whether FWH cycles are necessary + * for communication even if LPC_IO is defined. + */ + if (internal_buses_supported & BUS_FWH) + msg_pdbg("Registering IT85 SPI.\n"); + /* FIXME: Really leave FWH enabled? We can't use this region + * anymore since accessing it would mess up IT85 communication. + * If we decide to disable FWH for this region, we should print + * a debug message about it. + */ /* Set this as SPI controller. */ register_spi_programmer(&spi_programmer_it85xx); } Index: flashrom-register_par_programmer/atahpt.c =================================================================== --- flashrom-register_par_programmer/atahpt.c (Revision 1433) +++ flashrom-register_par_programmer/atahpt.c (Arbeitskopie) @@ -40,6 +40,19 @@ {}, };
+static const struct par_programmer par_programmer_atahpt = { + .chip_readb = atahpt_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = atahpt_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int atahpt_shutdown(void *data) { /* Flash access is disabled automatically by PCI restore. */ @@ -61,7 +74,7 @@ reg32 |= (1 << 24); rpci_write_long(pcidev_dev, REG_FLASH_ACCESS, reg32);
- buses_supported = BUS_PARALLEL; + register_par_programmer(&par_programmer_atahpt, BUS_PARALLEL);
if (register_shutdown(atahpt_shutdown, NULL)) return 1; Index: flashrom-register_par_programmer/nic3com.c =================================================================== --- flashrom-register_par_programmer/nic3com.c (Revision 1433) +++ flashrom-register_par_programmer/nic3com.c (Arbeitskopie) @@ -55,6 +55,19 @@ {}, };
+static const struct par_programmer par_programmer_nic3com = { + .chip_readb = nic3com_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nic3com_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int nic3com_shutdown(void *data) { /* 3COM 3C90xB cards need a special fixup. */ @@ -96,8 +109,8 @@ */ OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
- buses_supported = BUS_PARALLEL; max_rom_decode.parallel = 128 * 1024; + register_par_programmer(&par_programmer_nic3com, BUS_PARALLEL);
if (register_shutdown(nic3com_shutdown, NULL)) return 1; Index: flashrom-register_par_programmer/satasii.c =================================================================== --- flashrom-register_par_programmer/satasii.c (Revision 1433) +++ flashrom-register_par_programmer/satasii.c (Arbeitskopie) @@ -42,6 +42,19 @@ {}, };
+static const struct par_programmer par_programmer_satasii = { + .chip_readb = satasii_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = satasii_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int satasii_shutdown(void *data) { physunmap(sii_bar, SATASII_MEMMAP_SIZE); @@ -76,7 +89,7 @@ if ((id != 0x0680) && (!(pci_mmio_readl(sii_bar) & (1 << 26)))) msg_pinfo("Warning: Flash seems unconnected.\n");
- buses_supported = BUS_PARALLEL; + register_par_programmer(&par_programmer_satasii, BUS_PARALLEL);
if (register_shutdown(satasii_shutdown, NULL)) return 1; Index: flashrom-register_par_programmer/chipset_enable.c =================================================================== --- flashrom-register_par_programmer/chipset_enable.c (Revision 1433) +++ flashrom-register_par_programmer/chipset_enable.c (Arbeitskopie) @@ -213,7 +213,7 @@ uint16_t old, new; uint16_t xbcs = 0x4e; /* X-Bus Chip Select register. */
- buses_supported = BUS_PARALLEL; + internal_buses_supported = BUS_PARALLEL;
old = pci_read_word(dev, xbcs);
@@ -302,7 +302,7 @@ * FWH_DEC_EN1, but they are called FB_SEL1, FB_SEL2, FB_DEC_EN1 and * FB_DEC_EN2. */ - buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; return enable_flash_ich(dev, name, 0x4e); }
@@ -411,9 +411,9 @@ msg_pdbg("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh);
/* If we're called by enable_flash_ich_dc_spi, it will override - * buses_supported anyway. + * internal_buses_supported anyway. */ - buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; return enable_flash_ich(dev, name, 0xdc); }
@@ -433,7 +433,7 @@ if (new != old) rpci_write_byte(dev, 0xd9, new);
- buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; return 0; }
@@ -555,7 +555,7 @@ * time. At least not with our current code. So we prevent searching * on ICH7 when the southbridge is strapped to LPC */ - buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; if (ich_generation == 7) { if (bbs == 0x03) { /* If strapped to LPC, no further SPI initialization is @@ -563,7 +563,7 @@ return ret; } else { /* Disable LPC/FWH if strapped to PCI or SPI */ - buses_supported = 0; + internal_buses_supported = BUS_NONE; } }
@@ -666,7 +666,7 @@ #define CS5530_ENABLE_SA2320 (1 << 2) #define CS5530_ENABLE_SA20 (1 << 6)
- buses_supported = BUS_PARALLEL; + internal_buses_supported = BUS_PARALLEL; /* Decode 0x000E0000-0x000FFFFF (128 kB), not just 64 kB, and * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 kB. * FIXME: Should we really touch the low mapping below 1 MB? Flashrom @@ -819,7 +819,7 @@ (prot & 0xfffff800) + (((prot & 0x7fc) << 8) | 0x3ff)); }
- buses_supported = BUS_LPC | BUS_FWH; + internal_buses_supported = BUS_LPC | BUS_FWH;
ret = sb600_probe_spi(dev);
@@ -913,7 +913,7 @@ { uint8_t tmp;
- buses_supported = BUS_PARALLEL; + internal_buses_supported = BUS_PARALLEL;
tmp = INB(0xc06); tmp |= 0x1; @@ -1013,7 +1013,7 @@ switch ((val >> 5) & 0x3) { case 0x0: ret = enable_flash_mcp55(dev, name); - buses_supported = BUS_LPC; + internal_buses_supported = BUS_LPC; msg_pdbg("Flash bus type is LPC\n"); break; case 0x2: @@ -1021,7 +1021,7 @@ /* SPI is added in mcp6x_spi_init if it works. * Do we really want to disable LPC in this case? */ - buses_supported = BUS_NONE; + internal_buses_supported = BUS_NONE; msg_pdbg("Flash bus type is SPI\n"); msg_pinfo("SPI on this chipset is WIP. Please report any " "success or failure by mailing us the verbose " @@ -1029,7 +1029,7 @@ break; default: /* Should not happen. */ - buses_supported = BUS_NONE; + internal_buses_supported = BUS_NONE; msg_pdbg("Flash bus type is unknown (none)\n"); msg_pinfo("Something went wrong with bus type detection.\n"); goto out_msg; @@ -1322,7 +1322,6 @@ struct pci_dev *dev = NULL; int ret = -2; /* Nothing! */ int i; - char *s;
/* Now let's try to find the chipset we have... */ for (i = 0; chipset_enables[i].vendor_name != NULL; i++) { @@ -1374,9 +1373,5 @@ } }
- s = flashbuses_to_text(buses_supported); - msg_pinfo("This chipset supports the following protocols: %s.\n", s); - free(s); - return ret; } Index: flashrom-register_par_programmer/nicintel.c =================================================================== --- flashrom-register_par_programmer/nicintel.c (Revision 1433) +++ flashrom-register_par_programmer/nicintel.c (Arbeitskopie) @@ -43,6 +43,19 @@
#define CSR_FCR 0x0c
+static const struct par_programmer par_programmer_nicintel = { + .chip_readb = nicintel_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicintel_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + static int nicintel_shutdown(void *data) { physunmap(nicintel_control_bar, NICINTEL_CONTROL_MEMMAP_SIZE); @@ -93,9 +106,8 @@ */ pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR);
- buses_supported = BUS_PARALLEL; - max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE; + register_par_programmer(&par_programmer_nicintel, BUS_PARALLEL);
return 0;
Index: flashrom-register_par_programmer/programmer.c =================================================================== --- flashrom-register_par_programmer/programmer.c (Revision 1433) +++ flashrom-register_par_programmer/programmer.c (Arbeitskopie) @@ -19,7 +19,23 @@ */
#include "flash.h" +#include "programmer.h"
+static const struct par_programmer par_programmer_none = { + .chip_readb = noop_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = noop_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, +}; + +const struct par_programmer *par_programmer = &par_programmer_none; + /* No-op shutdown() for programmers which don't need special handling */ int noop_shutdown(void) { @@ -96,3 +112,9 @@ buf[i] = chip_readb(addr + i); return; } + +void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses) +{ + par_programmer = pgm; + buses_supported |= buses; +} Index: flashrom-register_par_programmer/flashrom.c =================================================================== --- flashrom-register_par_programmer/flashrom.c (Revision 1433) +++ flashrom-register_par_programmer/flashrom.c (Arbeitskopie) @@ -66,16 +66,6 @@ { .name = "internal", .init = internal_init, - .map_flash_region = physmap, - .unmap_flash_region = physunmap, - .chip_readb = internal_chip_readb, - .chip_readw = internal_chip_readw, - .chip_readl = internal_chip_readl, - .chip_readn = internal_chip_readn, - .chip_writeb = internal_chip_writeb, - .chip_writew = internal_chip_writew, - .chip_writel = internal_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -84,16 +74,6 @@ { .name = "dummy", .init = dummy_init, - .map_flash_region = dummy_map, - .unmap_flash_region = dummy_unmap, - .chip_readb = dummy_chip_readb, - .chip_readw = dummy_chip_readw, - .chip_readl = dummy_chip_readl, - .chip_readn = dummy_chip_readn, - .chip_writeb = dummy_chip_writeb, - .chip_writew = dummy_chip_writew, - .chip_writel = dummy_chip_writel, - .chip_writen = dummy_chip_writen, .delay = internal_delay, }, #endif @@ -102,16 +82,6 @@ { .name = "nic3com", .init = nic3com_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = nic3com_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nic3com_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -122,16 +92,6 @@ .name = "nicrealtek", //.name = "nicsmc1211", .init = nicrealtek_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = nicrealtek_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicrealtek_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -140,16 +100,6 @@ { .name = "nicnatsemi", .init = nicnatsemi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = nicnatsemi_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicnatsemi_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -158,16 +108,6 @@ { .name = "gfxnvidia", .init = gfxnvidia_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = gfxnvidia_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = gfxnvidia_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -176,16 +116,6 @@ { .name = "drkaiser", .init = drkaiser_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = drkaiser_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = drkaiser_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -194,16 +124,6 @@ { .name = "satasii", .init = satasii_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = satasii_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = satasii_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -212,16 +132,6 @@ { .name = "atahpt", .init = atahpt_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = atahpt_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = atahpt_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -230,16 +140,6 @@ { .name = "ft2232_spi", .init = ft2232_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -248,16 +148,6 @@ { .name = "serprog", .init = serprog_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = serprog_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = serprog_chip_readn, - .chip_writeb = serprog_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = serprog_delay, }, #endif @@ -266,16 +156,6 @@ { .name = "buspirate_spi", .init = buspirate_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -284,16 +164,6 @@ { .name = "dediprog", .init = dediprog_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -302,16 +172,6 @@ { .name = "rayer_spi", .init = rayer_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -320,16 +180,6 @@ { .name = "nicintel", .init = nicintel_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = nicintel_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicintel_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -338,16 +188,6 @@ { .name = "nicintel_spi", .init = nicintel_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -356,16 +196,6 @@ { .name = "ogp_spi", .init = ogp_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -374,16 +204,6 @@ { .name = "satamv", .init = satamv_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = satamv_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = satamv_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -392,16 +212,6 @@ { .name = "linux_spi", .init = linux_spi_init, - .map_flash_region = fallback_map, - .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -502,53 +312,52 @@ void *programmer_map_flash_region(const char *descr, unsigned long phys_addr, size_t len) { - return programmer_table[programmer].map_flash_region(descr, - phys_addr, len); + return par_programmer->map_flash_region(descr, phys_addr, len); }
void programmer_unmap_flash_region(void *virt_addr, size_t len) { - programmer_table[programmer].unmap_flash_region(virt_addr, len); + par_programmer->unmap_flash_region(virt_addr, len); }
void chip_writeb(uint8_t val, chipaddr addr) { - programmer_table[programmer].chip_writeb(val, addr); + par_programmer->chip_writeb(val, addr); }
void chip_writew(uint16_t val, chipaddr addr) { - programmer_table[programmer].chip_writew(val, addr); + par_programmer->chip_writew(val, addr); }
void chip_writel(uint32_t val, chipaddr addr) { - programmer_table[programmer].chip_writel(val, addr); + par_programmer->chip_writel(val, addr); }
void chip_writen(uint8_t *buf, chipaddr addr, size_t len) { - programmer_table[programmer].chip_writen(buf, addr, len); + par_programmer->chip_writen(buf, addr, len); }
uint8_t chip_readb(const chipaddr addr) { - return programmer_table[programmer].chip_readb(addr); + return par_programmer->chip_readb(addr); }
uint16_t chip_readw(const chipaddr addr) { - return programmer_table[programmer].chip_readw(addr); + return par_programmer->chip_readw(addr); }
uint32_t chip_readl(const chipaddr addr) { - return programmer_table[programmer].chip_readl(addr); + return par_programmer->chip_readl(addr); }
void chip_readn(uint8_t *buf, chipaddr addr, size_t len) { - programmer_table[programmer].chip_readn(buf, addr, len); + par_programmer->chip_readn(buf, addr, len); }
void programmer_delay(int usecs) @@ -1156,7 +965,7 @@ return -1;
#if CONFIG_INTERNAL == 1 - if (programmer_table[programmer].map_flash_region == physmap) + if (par_programmer->map_flash_region == physmap) snprintf(location, sizeof(location), "at physical address 0x%lx", base); else #endif Index: flashrom-register_par_programmer/programmer.h =================================================================== --- flashrom-register_par_programmer/programmer.h (Revision 1433) +++ flashrom-register_par_programmer/programmer.h (Arbeitskopie) @@ -91,18 +91,6 @@
int (*init) (void);
- void * (*map_flash_region) (const char *descr, unsigned long phys_addr, - size_t len); - void (*unmap_flash_region) (void *virt_addr, size_t len); - - void (*chip_writeb) (uint8_t val, chipaddr addr); - void (*chip_writew) (uint16_t val, chipaddr addr); - void (*chip_writel) (uint32_t val, chipaddr addr); - void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len); - uint8_t (*chip_readb) (const chipaddr addr); - uint16_t (*chip_readw) (const chipaddr addr); - uint32_t (*chip_readl) (const chipaddr addr); - void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len); void (*delay) (int usecs); };
@@ -304,6 +292,7 @@ extern int force_boardmismatch; void probe_superio(void); int register_superio(struct superio s); +extern enum chipbustype internal_buses_supported; int internal_init(void); void internal_chip_writeb(uint8_t val, chipaddr addr); void internal_chip_writew(uint16_t val, chipaddr addr); @@ -358,7 +347,23 @@ uint16_t fallback_chip_readw(const chipaddr addr); uint32_t fallback_chip_readl(const chipaddr addr); void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); +struct par_programmer { + void (*chip_writeb) (uint8_t val, chipaddr addr); + void (*chip_writew) (uint16_t val, chipaddr addr); + void (*chip_writel) (uint32_t val, chipaddr addr); + void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len); + uint8_t (*chip_readb) (const chipaddr addr); + uint16_t (*chip_readw) (const chipaddr addr); + uint32_t (*chip_readl) (const chipaddr addr); + void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len);
+ void *(*map_flash_region) (const char *descr, unsigned long phys_addr, + size_t len); + void (*unmap_flash_region) (void *virt_addr, size_t len); +}; +extern const struct par_programmer *par_programmer; +void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses); + /* dummyflasher.c */ #if CONFIG_DUMMY == 1 int dummy_init(void); Index: flashrom-register_par_programmer/board_enable.c =================================================================== --- flashrom-register_par_programmer/board_enable.c (Revision 1433) +++ flashrom-register_par_programmer/board_enable.c (Arbeitskopie) @@ -425,7 +425,7 @@ /* Check if at least one flash segment is enabled. */ if (tmp & 0xf0) { /* The IT8705F will respond to LPC cycles and translate them. */ - buses_supported = BUS_PARALLEL; + internal_buses_supported = BUS_PARALLEL; /* Flash ROM I/F Writes Enable */ tmp |= 0x04; msg_pdbg("Enabling IT8705F flash ROM interface write.\n");
On Thu, 08 Sep 2011 02:14:06 +0200 Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
RFC/TODO:
- Should register_par_programmer(...) be called before or after setting max_rom_decode.*?
why is that not a field in the different programmer structs (yet?)?
- Should register_par_programmer(...) be called before or after register_shutdown()?
like register_spi_programmer (no idea when that is, but consistency is the one main argument i can think of atm)
- Is there a better name for register_par_programmer?
register_parallel_programmer ofc, and imho it is not too long, because it is seldom used, but i don't care that much (due to the same reason).
- Should max_rom_decode.* be part of the registration?
either that or declaration, see question above. if it has to be modified (board enables do this it seems...), this can't be done at registration (only)...
- Should map_flash_region/unmap_flash_region be part of the registration?
no idea what that does exactly :P
--- flashrom-register_par_programmer/cli_classic.c (Revision 1433) +++ flashrom-register_par_programmer/cli_classic.c (Arbeitskopie) […]
flashbuses_to_text(buses_supported));
free()!!!
sorry for the lame "review", but i thought better some feedback than none at all :)
Am 08.09.2011 23:36 schrieb Stefan Tauner:
On Thu, 08 Sep 2011 02:14:06 +0200 Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
RFC/TODO:
- Should register_par_programmer(...) be called before or after setting max_rom_decode.*?
why is that not a field in the different programmer structs (yet?)?
Why do you always ask the really hard questions?
Given that the registration for parallel and SPI programmers is pretty different but max_rom_decode.* is used from common code, it is not immediately obvious to handle this sanely. Supply it as register_par_programmer() parameter and extend register_spi_programmer to accept that parameter as well?
- Should register_par_programmer(...) be called before or after register_shutdown()?
like register_spi_programmer (no idea when that is, but consistency is the one main argument i can think of atm)
They should be called after register_shutdown, otherwise there is a time when chip access functions are callable although the programmer has already been shut down. Will audit the code and change where appropriate.
- Is there a better name for register_par_programmer?
register_parallel_programmer ofc, and imho it is not too long, because it is seldom used, but i don't care that much (due to the same reason).
80 column limit... I think that was one of the reasons we used a shorter name.
- Should max_rom_decode.* be part of the registration?
either that or declaration, see question above. if it has to be modified (board enables do this it seems...), this can't be done at registration (only)...
Same trick as buses_supported. Have a local static (not part of the official interface) chipset_max_rom_decode variable which can be modified by chipset/mainboard init, and then use the end result in registration.
- Should map_flash_region/unmap_flash_region be part of the registration?
no idea what that does exactly :P
It makes the flash chip accessible. This is essentially physmap for programmers with memory mapped flash and a no-op for everything else.
--- flashrom-register_par_programmer/cli_classic.c (Revision 1433) +++ flashrom-register_par_programmer/cli_classic.c (Arbeitskopie) […]
flashbuses_to_text(buses_supported));
free()!!!
Argh, yes.
sorry for the lame "review", but i thought better some feedback than none at all :)
Thanks, it was helpful, will rework the code and audit registration ordering.
Regards, Carl-Daniel
Am 09.09.2011 19:55 schrieb Carl-Daniel Hailfinger:
Am 08.09.2011 23:36 schrieb Stefan Tauner:
On Thu, 08 Sep 2011 02:14:06 +0200 Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net wrote:
RFC/TODO:
- Should register_par_programmer(...) be called before or after setting max_rom_decode.*?
why is that not a field in the different programmer structs (yet?)?
Given that the registration for parallel and SPI programmers is pretty different but max_rom_decode.* is used from common code, it is not immediately obvious to handle this sanely. Supply it as register_par_programmer() parameter and extend register_spi_programmer to accept that parameter as well?
I'm now setting max_rom_decode before calling register_par_programmer. Given that such restrictions may exist for any programmer, I'll postpone handling max_rom_decode to the universal programmer registration patch where we get the infrastructure to deal with such programmer limitations. If you have any objections, please tell me.
- Should register_par_programmer(...) be called before or after register_shutdown()?
like register_spi_programmer (no idea when that is, but consistency is the one main argument i can think of atm)
They should be called after register_shutdown, otherwise there is a time when chip access functions are callable although the programmer has already been shut down. Will audit the code and change where appropriate.
Done.
- Is there a better name for register_par_programmer?
register_parallel_programmer ofc, and imho it is not too long, because it is seldom used, but i don't care that much (due to the same reason).
80 column limit... I think that was one of the reasons we used a shorter name.
- Should max_rom_decode.* be part of the registration?
either that or declaration, see question above. if it has to be modified (board enables do this it seems...), this can't be done at registration (only)...
Same trick as buses_supported. Have a local static (not part of the official interface) chipset_max_rom_decode variable which can be modified by chipset/mainboard init, and then use the end result in registration.
max_rom_decode is conceptually different from buses_supported although that was not obvious when I wrote the paragraph above. It will be handled in the universal programmer registration patch.
- Should map_flash_region/unmap_flash_region be part of the registration?
no idea what that does exactly :P
It makes the flash chip accessible. This is essentially physmap for programmers with memory mapped flash and a no-op for everything else.
And moving it into the parallel programmer struct may not have been the best idea. Sure, that gets it out of the way conveniently, but once the universal programmer registration patch is in, we will not have any dummy parallel programmer struct for such fallbacks anymore. This will cause all sorts of design headaches which are not obvious right now.
New version. Testing on all programmers is very appreciated.
Register Parallel/LPC/FWH programmers the same way SPI programmers are registered.
Additional fixes: Set max_rom_decode.parallel for drkaiser. Remove abuse of programmer_map_flash_region in it85spi. Annotate several FIXMEs in it85spi.
Note: Programmers without parallel/LPC/FWH chip support should not call register_par_programmer().
I did not check for 80 column limit violations, but the rest should be OK.
We need something like this patch to handle programmers with multiple flash chips (e.g. LPC/FWH chips mapped to different regions on mainboards).
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-register_par_programmer/drkaiser.c =================================================================== --- flashrom-register_par_programmer/drkaiser.c (Revision 1460) +++ flashrom-register_par_programmer/drkaiser.c (Arbeitskopie) @@ -39,6 +39,17 @@
static uint8_t *drkaiser_bar;
+static const struct par_programmer par_programmer_drkaiser = { + .chip_readb = drkaiser_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = drkaiser_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int drkaiser_shutdown(void *data) { physunmap(drkaiser_bar, DRKAISER_MEMMAP_SIZE); @@ -64,10 +75,12 @@ drkaiser_bar = physmap("Dr. Kaiser PC-Waechter flash memory", addr, DRKAISER_MEMMAP_SIZE);
- buses_supported = BUS_PARALLEL; - if (register_shutdown(drkaiser_shutdown, NULL)) return 1; + + max_rom_decode.parallel = 131072; + register_par_programmer(&par_programmer_drkaiser, BUS_PARALLEL); + return 0; }
Index: flashrom-register_par_programmer/it87spi.c =================================================================== --- flashrom-register_par_programmer/it87spi.c (Revision 1460) +++ flashrom-register_par_programmer/it87spi.c (Arbeitskopie) @@ -192,7 +192,7 @@ free(portpos); exit_conf_mode_ite(port); it8716f_flashport = flashport; - if (buses_supported & BUS_SPI) + 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_programmer(&spi_programmer_it87xx); Index: flashrom-register_par_programmer/gfxnvidia.c =================================================================== --- flashrom-register_par_programmer/gfxnvidia.c (Revision 1460) +++ flashrom-register_par_programmer/gfxnvidia.c (Arbeitskopie) @@ -61,6 +61,17 @@ {}, };
+static const struct par_programmer par_programmer_gfxnvidia = { + .chip_readb = gfxnvidia_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = gfxnvidia_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int gfxnvidia_shutdown(void *data) { physunmap(nvidia_bar, GFXNVIDIA_MEMMAP_SIZE); @@ -94,10 +105,9 @@ reg32 &= ~(1 << 0); rpci_write_long(pcidev_dev, 0x50, reg32);
- buses_supported = BUS_PARALLEL; - /* Write/erase doesn't work. */ programmer_may_write = 0; + register_par_programmer(&par_programmer_gfxnvidia, BUS_PARALLEL);
return 0; } Index: flashrom-register_par_programmer/nicrealtek.c =================================================================== --- flashrom-register_par_programmer/nicrealtek.c (Revision 1460) +++ flashrom-register_par_programmer/nicrealtek.c (Arbeitskopie) @@ -36,6 +36,17 @@ {}, };
+static const struct par_programmer par_programmer_nicrealtek = { + .chip_readb = nicrealtek_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicrealtek_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int nicrealtek_shutdown(void *data) { /* FIXME: We forgot to disable software access again. */ @@ -50,10 +61,11 @@
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_realtek);
- buses_supported = BUS_PARALLEL; - if (register_shutdown(nicrealtek_shutdown, NULL)) return 1; + + register_par_programmer(&par_programmer_nicrealtek, BUS_PARALLEL); + return 0; }
Index: flashrom-register_par_programmer/serprog.c =================================================================== --- flashrom-register_par_programmer/serprog.c (Revision 1460) +++ flashrom-register_par_programmer/serprog.c (Arbeitskopie) @@ -299,6 +299,11 @@ return 0; }
+static int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, + unsigned char *readarr); +static int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, + int len); static struct spi_programmer spi_programmer_serprog = { .type = SPI_CONTROLLER_SERPROG, .max_data_read = MAX_DATA_READ_UNLIMITED, @@ -309,6 +314,19 @@ .write_256 = default_spi_write_256, };
+static const struct par_programmer par_programmer_serprog = { + .chip_readb = serprog_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = serprog_chip_readn, + .chip_writeb = serprog_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + +static enum chipbustype serprog_buses_supported = BUS_NONE; + int serprog_init(void) { uint16_t iface; @@ -400,41 +418,45 @@
if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) { msg_perr("Error: NAK to query interface version\n"); - exit(1); + return 1; }
if (iface != 1) { msg_perr("Error: Unknown interface version: %d\n", iface); - exit(1); + return 1; }
msg_pdbg(MSGHEADER "Interface version ok.\n");
if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) { msg_perr("Error: query command map not supported\n"); - exit(1); + return 1; }
sp_check_avail_automatic = 1;
- + /* FIXME: This assumes that serprog device bustypes are always + * identical with flashrom bustype enums and that they all fit + * in a single byte. + */ if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) { msg_perr("Warning: NAK to query supported buses\n"); c = BUS_NONSPI; /* A reasonable default for now. */ } - buses_supported = c; + serprog_buses_supported = c; + msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n", (c & BUS_PARALLEL) ? "on" : "off", (c & BUS_LPC) ? "on" : "off", (c & BUS_FWH) ? "on" : "off", (c & BUS_SPI) ? "on" : "off"); /* Check for the minimum operational set of commands. */ - if (buses_supported & BUS_SPI) { + if (serprog_buses_supported & BUS_SPI) { uint8_t bt = BUS_SPI; if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) { msg_perr("Error: SPI operation not supported while the " "bustype is SPI\n"); - exit(1); + return 1; } /* Success of any of these commands is optional. We don't need the programmer to tell us its limits, but if it doesn't, we @@ -461,40 +483,39 @@ spi_programmer_serprog.max_data_read = v; msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v); } - bt = buses_supported; + bt = serprog_buses_supported; sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL); - register_spi_programmer(&spi_programmer_serprog); }
- if (buses_supported & BUS_NONSPI) { + if (serprog_buses_supported & BUS_NONSPI) { if (sp_check_commandavail(S_CMD_O_INIT) == 0) { msg_perr("Error: Initialize operation buffer " "not supported\n"); - exit(1); + return 1; }
if (sp_check_commandavail(S_CMD_O_DELAY) == 0) { msg_perr("Error: Write to opbuf: " "delay not supported\n"); - exit(1); + return 1; }
/* S_CMD_O_EXEC availability checked later. */
if (sp_check_commandavail(S_CMD_R_BYTE) == 0) { msg_perr("Error: Single byte read not supported\n"); - exit(1); + return 1; } /* This could be translated to single byte reads (if missing), * but now we don't support that. */ if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) { msg_perr("Error: Read n bytes not supported\n"); - exit(1); + return 1; } if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) { msg_perr("Error: Write to opbuf: " "write byte not supported\n"); - exit(1); + return 1; }
if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) { @@ -513,7 +534,7 @@ if (!sp_write_n_buf) { msg_perr("Error: cannot allocate memory for " "Write-n buffer\n"); - exit(1); + return 1; } sp_write_n_bytes = 0; } @@ -551,12 +572,12 @@ if (sp_check_commandavail(S_CMD_O_EXEC) == 0) { msg_perr("Error: Execute operation buffer not " "supported\n"); - exit(1); + return 1; }
if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) { msg_perr("Error: NAK to initialize operation buffer\n"); - exit(1); + return 1; }
if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2, @@ -572,6 +593,11 @@ sp_streamed_transmit_ops = 0; sp_streamed_transmit_bytes = 0; sp_opbuf_usage = 0; + if (serprog_buses_supported & BUS_SPI) + register_spi_programmer(&spi_programmer_serprog); + if (serprog_buses_supported & BUS_NONSPI) + register_par_programmer(&par_programmer_serprog, + serprog_buses_supported & BUS_NONSPI); return 0; }
@@ -766,7 +792,7 @@ sp_prev_was_write = 0; }
-int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, +static int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr) { @@ -796,7 +822,7 @@ * the advantage that it is much faster for most chips, but breaks those with * non-contiguous address space (like AT45DB161D). When spi_read_chunked is * fixed this method can be removed. */ -int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) +static int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { int i; int cur_len; Index: flashrom-register_par_programmer/satamv.c =================================================================== --- flashrom-register_par_programmer/satamv.c (Revision 1460) +++ flashrom-register_par_programmer/satamv.c (Arbeitskopie) @@ -41,6 +41,17 @@ #define PCI_BAR2_CONTROL 0x00c08 #define GPIO_PORT_CONTROL 0x104f0
+static const struct par_programmer par_programmer_satamv = { + .chip_readb = satamv_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = satamv_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int satamv_shutdown(void *data) { physunmap(mv_bar, 0x20000); @@ -137,11 +148,10 @@ mv_iobar = tmp & 0xffff; msg_pspew("Activating I/O BAR at 0x%04x\n", mv_iobar);
- buses_supported = BUS_PARALLEL; - /* 512 kByte with two 8-bit latches, and * 4 MByte with additional 3-bit latch. */ max_rom_decode.parallel = 4 * 1024 * 1024; + register_par_programmer(&par_programmer_satamv, BUS_PARALLEL);
return 0;
Index: flashrom-register_par_programmer/dummyflasher.c =================================================================== --- flashrom-register_par_programmer/dummyflasher.c (Revision 1460) +++ flashrom-register_par_programmer/dummyflasher.c (Arbeitskopie) @@ -75,6 +75,19 @@ .write_256 = dummy_spi_write_256, };
+static const struct par_programmer par_programmer_dummy = { + .chip_readb = dummy_chip_readb, + .chip_readw = dummy_chip_readw, + .chip_readl = dummy_chip_readl, + .chip_readn = dummy_chip_readn, + .chip_writeb = dummy_chip_writeb, + .chip_writew = dummy_chip_writew, + .chip_writel = dummy_chip_writel, + .chip_writen = dummy_chip_writen, +}; + +enum chipbustype dummy_buses_supported = BUS_NONE; + static int dummy_shutdown(void *data) { msg_pspew("%s\n", __func__); @@ -108,24 +121,24 @@ /* Convert the parameters to lowercase. */ tolower_string(bustext);
- buses_supported = BUS_NONE; + dummy_buses_supported = BUS_NONE; if (strstr(bustext, "parallel")) { - buses_supported |= BUS_PARALLEL; + dummy_buses_supported |= BUS_PARALLEL; msg_pdbg("Enabling support for %s flash.\n", "parallel"); } if (strstr(bustext, "lpc")) { - buses_supported |= BUS_LPC; + dummy_buses_supported |= BUS_LPC; msg_pdbg("Enabling support for %s flash.\n", "LPC"); } if (strstr(bustext, "fwh")) { - buses_supported |= BUS_FWH; + dummy_buses_supported |= BUS_FWH; msg_pdbg("Enabling support for %s flash.\n", "FWH"); } if (strstr(bustext, "spi")) { - register_spi_programmer(&spi_programmer_dummyflasher); + dummy_buses_supported |= BUS_SPI; msg_pdbg("Enabling support for %s flash.\n", "SPI"); } - if (buses_supported == BUS_NONE) + if (dummy_buses_supported == BUS_NONE) msg_pdbg("Support for all flash bus types disabled.\n"); free(bustext);
@@ -226,6 +239,14 @@ free(flashchip_contents); return 1; } + if (dummy_buses_supported & (BUS_PARALLEL | BUS_LPC | BUS_FWH)) + register_par_programmer(&par_programmer_dummy, + dummy_buses_supported & + (BUS_PARALLEL | BUS_LPC | + BUS_FWH)); + if (dummy_buses_supported & BUS_SPI) + register_spi_programmer(&spi_programmer_dummyflasher); + return 0; }
Index: flashrom-register_par_programmer/cli_classic.c =================================================================== --- flashrom-register_par_programmer/cli_classic.c (Revision 1460) +++ flashrom-register_par_programmer/cli_classic.c (Arbeitskopie) @@ -443,6 +443,10 @@ ret = 1; goto out_shutdown; } + tempstr = flashbuses_to_text(buses_supported); + msg_pdbg("This programmer supports the following protocols: %s.\n", + tempstr); + free(tempstr);
for (i = 0; i < ARRAY_SIZE(flashes); i++) { startchip = probe_flash(startchip, &flashes[i], 0); Index: flashrom-register_par_programmer/internal.c =================================================================== --- flashrom-register_par_programmer/internal.c (Revision 1460) +++ flashrom-register_par_programmer/internal.c (Arbeitskopie) @@ -127,6 +127,19 @@ int is_laptop = 0; int laptop_ok = 0;
+static const struct par_programmer par_programmer_internal = { + .chip_readb = internal_chip_readb, + .chip_readw = internal_chip_readw, + .chip_readl = internal_chip_readl, + .chip_readn = internal_chip_readn, + .chip_writeb = internal_chip_writeb, + .chip_writew = internal_chip_writew, + .chip_writel = internal_chip_writel, + .chip_writen = fallback_chip_writen, +}; + +enum chipbustype internal_buses_supported = BUS_NONE; + static int internal_shutdown(void *data) { release_io_perms(); @@ -191,9 +204,10 @@ return 1;
/* Default to Parallel/LPC/FWH flash devices. If a known host controller - * is found, the init routine sets the buses_supported bitfield. + * is found, the host controller init routine sets the + * internal_buses_supported bitfield. */ - buses_supported = BUS_NONSPI; + internal_buses_supported = BUS_NONSPI;
/* Initialize PCI access for flash enables */ pacc = pci_alloc(); /* Get the pci_access structure */ @@ -287,6 +301,7 @@ * Besides that, we don't check the board enable return code either. */ #if defined(__i386__) || defined(__x86_64__) || defined (__mips) + register_par_programmer(&par_programmer_internal, internal_buses_supported); return 0; #else msg_perr("Your platform is not supported yet for the internal " Index: flashrom-register_par_programmer/ichspi.c =================================================================== --- flashrom-register_par_programmer/ichspi.c (Revision 1460) +++ flashrom-register_par_programmer/ichspi.c (Arbeitskopie) @@ -1507,7 +1507,7 @@ ich_spibar = physmap("VT8237S MMIO registers", mmio_base, 0x70);
/* Not sure if it speaks all these bus protocols. */ - buses_supported = BUS_LPC | BUS_FWH; + internal_buses_supported = BUS_LPC | BUS_FWH; ich_generation = CHIPSET_ICH7; register_spi_programmer(&spi_programmer_via);
Index: flashrom-register_par_programmer/nicnatsemi.c =================================================================== --- flashrom-register_par_programmer/nicnatsemi.c (Revision 1460) +++ flashrom-register_par_programmer/nicnatsemi.c (Arbeitskopie) @@ -35,6 +35,17 @@ {}, };
+static const struct par_programmer par_programmer_nicnatsemi = { + .chip_readb = nicnatsemi_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicnatsemi_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int nicnatsemi_shutdown(void *data) { pci_cleanup(pacc); @@ -48,7 +59,8 @@
io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_natsemi);
- buses_supported = BUS_PARALLEL; + if (register_shutdown(nicnatsemi_shutdown, NULL)) + return 1;
/* 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 @@ -57,9 +69,8 @@ * functions below wants to be 0x0000FFFF. */ max_rom_decode.parallel = 131072; + register_par_programmer(&par_programmer_nicnatsemi, BUS_PARALLEL);
- if (register_shutdown(nicnatsemi_shutdown, NULL)) - return 1; return 0; }
Index: flashrom-register_par_programmer/it85spi.c =================================================================== --- flashrom-register_par_programmer/it85spi.c (Revision 1460) +++ flashrom-register_par_programmer/it85spi.c (Arbeitskopie) @@ -257,8 +257,10 @@ INDIRECT_A3(shm_io_base, (base >> 24)); #endif #ifdef LPC_MEMORY - base = (chipaddr)programmer_map_flash_region("it85 communication", - 0xFFFFF000, 0x1000); + /* FIXME: We should block accessing that region for anything else. + * Major TODO here, and it will be a lot of work. + */ + base = (chipaddr)physmap("it85 communication", 0xFFFFF000, 0x1000); msg_pdbg("%s():%d base=0x%08x\n", __func__, __LINE__, (unsigned int)base); ce_high = (unsigned char *)(base + 0xE00); /* 0xFFFFFE00 */ @@ -285,18 +287,26 @@ { int ret;
- if (!(buses_supported & BUS_FWH)) { + if (!(internal_buses_supported & BUS_FWH)) { msg_pdbg("%s():%d buses not support FWH\n", __func__, __LINE__); return 1; } ret = it85xx_spi_common_init(s); msg_pdbg("FWH: %s():%d ret=%d\n", __func__, __LINE__, ret); if (!ret) { - msg_pdbg("%s():%d buses_supported=0x%x\n", __func__, __LINE__, - buses_supported); - if (buses_supported & BUS_FWH) - msg_pdbg("Overriding chipset SPI with IT85 FWH|SPI.\n"); - /* Really leave FWH enabled? */ + msg_pdbg("%s: internal_buses_supported=0x%x\n", __func__, + internal_buses_supported); + /* Check for FWH because IT85 listens to FWH cycles. + * FIXME: The big question is whether FWH cycles are necessary + * for communication even if LPC_IO is defined. + */ + if (internal_buses_supported & BUS_FWH) + msg_pdbg("Registering IT85 SPI.\n"); + /* FIXME: Really leave FWH enabled? We can't use this region + * anymore since accessing it would mess up IT85 communication. + * If we decide to disable FWH for this region, we should print + * a debug message about it. + */ /* Set this as SPI controller. */ register_spi_programmer(&spi_programmer_it85xx); } Index: flashrom-register_par_programmer/atahpt.c =================================================================== --- flashrom-register_par_programmer/atahpt.c (Revision 1460) +++ flashrom-register_par_programmer/atahpt.c (Arbeitskopie) @@ -40,6 +40,17 @@ {}, };
+static const struct par_programmer par_programmer_atahpt = { + .chip_readb = atahpt_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = atahpt_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int atahpt_shutdown(void *data) { /* Flash access is disabled automatically by PCI restore. */ @@ -61,10 +72,11 @@ reg32 |= (1 << 24); rpci_write_long(pcidev_dev, REG_FLASH_ACCESS, reg32);
- buses_supported = BUS_PARALLEL; - if (register_shutdown(atahpt_shutdown, NULL)) return 1; + + register_par_programmer(&par_programmer_atahpt, BUS_PARALLEL); + return 0; }
Index: flashrom-register_par_programmer/nic3com.c =================================================================== --- flashrom-register_par_programmer/nic3com.c (Revision 1460) +++ flashrom-register_par_programmer/nic3com.c (Arbeitskopie) @@ -55,6 +55,17 @@ {}, };
+static const struct par_programmer par_programmer_nic3com = { + .chip_readb = nic3com_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nic3com_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int nic3com_shutdown(void *data) { /* 3COM 3C90xB cards need a special fixup. */ @@ -96,11 +107,12 @@ */ OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
- buses_supported = BUS_PARALLEL; + if (register_shutdown(nic3com_shutdown, NULL)) + return 1; + max_rom_decode.parallel = 128 * 1024; + register_par_programmer(&par_programmer_nic3com, BUS_PARALLEL);
- if (register_shutdown(nic3com_shutdown, NULL)) - return 1; return 0; }
Index: flashrom-register_par_programmer/satasii.c =================================================================== --- flashrom-register_par_programmer/satasii.c (Revision 1460) +++ flashrom-register_par_programmer/satasii.c (Arbeitskopie) @@ -42,6 +42,17 @@ {}, };
+static const struct par_programmer par_programmer_satasii = { + .chip_readb = satasii_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = satasii_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int satasii_shutdown(void *data) { physunmap(sii_bar, SATASII_MEMMAP_SIZE); @@ -76,10 +87,11 @@ if ((id != 0x0680) && (!(pci_mmio_readl(sii_bar) & (1 << 26)))) msg_pinfo("Warning: Flash seems unconnected.\n");
- buses_supported = BUS_PARALLEL; - if (register_shutdown(satasii_shutdown, NULL)) return 1; + + register_par_programmer(&par_programmer_satasii, BUS_PARALLEL); + return 0; }
Index: flashrom-register_par_programmer/wbsio_spi.c =================================================================== --- flashrom-register_par_programmer/wbsio_spi.c (Revision 1460) +++ flashrom-register_par_programmer/wbsio_spi.c (Arbeitskopie) @@ -82,10 +82,10 @@
msg_pspew("\nwbsio_spibase = 0x%x\n", wbsio_spibase);
- register_spi_programmer(&spi_programmer_wbsio); msg_pdbg("%s: Winbond saved on 4 register bits so max chip size is " "1024 kB!\n", __func__); max_rom_decode.spi = 1024 * 1024; + register_spi_programmer(&spi_programmer_wbsio);
return 0; } Index: flashrom-register_par_programmer/nicintel.c =================================================================== --- flashrom-register_par_programmer/nicintel.c (Revision 1460) +++ flashrom-register_par_programmer/nicintel.c (Arbeitskopie) @@ -43,6 +43,17 @@
#define CSR_FCR 0x0c
+static const struct par_programmer par_programmer_nicintel = { + .chip_readb = nicintel_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = nicintel_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + static int nicintel_shutdown(void *data) { physunmap(nicintel_control_bar, NICINTEL_CONTROL_MEMMAP_SIZE); @@ -93,9 +104,8 @@ */ pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR);
- buses_supported = BUS_PARALLEL; - max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE; + register_par_programmer(&par_programmer_nicintel, BUS_PARALLEL);
return 0;
Index: flashrom-register_par_programmer/chipset_enable.c =================================================================== --- flashrom-register_par_programmer/chipset_enable.c (Revision 1460) +++ flashrom-register_par_programmer/chipset_enable.c (Arbeitskopie) @@ -213,7 +213,7 @@ uint16_t old, new; uint16_t xbcs = 0x4e; /* X-Bus Chip Select register. */
- buses_supported = BUS_PARALLEL; + internal_buses_supported = BUS_PARALLEL;
old = pci_read_word(dev, xbcs);
@@ -303,7 +303,7 @@ * FWH_DEC_EN1, but they are called FB_SEL1, FB_SEL2, FB_DEC_EN1 and * FB_DEC_EN2. */ - buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; return enable_flash_ich(dev, name, 0x4e); }
@@ -412,9 +412,9 @@ msg_pdbg("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh);
/* If we're called by enable_flash_ich_dc_spi, it will override - * buses_supported anyway. + * internal_buses_supported anyway. */ - buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; return enable_flash_ich(dev, name, 0xdc); }
@@ -434,7 +434,7 @@ if (new != old) rpci_write_byte(dev, 0xd9, new);
- buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; return 0; }
@@ -468,12 +468,11 @@ bnt = mmio_readl(rcrb + 0x3410); if (bnt & 0x02) { /* If strapped to LPC, no SPI initialization is required */ - buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; return 0; }
/* This adds BUS_SPI */ - buses_supported = BUS_SPI; if (ich_init_spi(dev, tmp, rcrb, 7) != 0) { if (!ret) ret = ERROR_NONFATAL; @@ -556,7 +555,7 @@ * time. At least not with our current code. So we prevent searching * on ICH7 when the southbridge is strapped to LPC */ - buses_supported = BUS_FWH; + internal_buses_supported = BUS_FWH; if (ich_generation == CHIPSET_ICH7) { if (bbs == 0x03) { /* If strapped to LPC, no further SPI initialization is @@ -564,7 +563,7 @@ return ret; } else { /* Disable LPC/FWH if strapped to PCI or SPI */ - buses_supported = 0; + internal_buses_supported = BUS_NONE; } }
@@ -667,7 +666,7 @@ #define CS5530_ENABLE_SA2320 (1 << 2) #define CS5530_ENABLE_SA20 (1 << 6)
- buses_supported = BUS_PARALLEL; + internal_buses_supported = BUS_PARALLEL; /* Decode 0x000E0000-0x000FFFFF (128 kB), not just 64 kB, and * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 kB. * FIXME: Should we really touch the low mapping below 1 MB? Flashrom @@ -820,7 +819,7 @@ (prot & 0xfffff800) + (((prot & 0x7fc) << 8) | 0x3ff)); }
- buses_supported = BUS_LPC | BUS_FWH; + internal_buses_supported = BUS_LPC | BUS_FWH;
ret = sb600_probe_spi(dev);
@@ -914,7 +913,7 @@ { uint8_t tmp;
- buses_supported = BUS_PARALLEL; + internal_buses_supported = BUS_PARALLEL;
tmp = INB(0xc06); tmp |= 0x1; @@ -1014,7 +1013,7 @@ switch ((val >> 5) & 0x3) { case 0x0: ret = enable_flash_mcp55(dev, name); - buses_supported = BUS_LPC; + internal_buses_supported = BUS_LPC; msg_pdbg("Flash bus type is LPC\n"); break; case 0x2: @@ -1022,7 +1021,7 @@ /* SPI is added in mcp6x_spi_init if it works. * Do we really want to disable LPC in this case? */ - buses_supported = BUS_NONE; + internal_buses_supported = BUS_NONE; msg_pdbg("Flash bus type is SPI\n"); msg_pinfo("SPI on this chipset is WIP. Please report any " "success or failure by mailing us the verbose " @@ -1030,7 +1029,7 @@ break; default: /* Should not happen. */ - buses_supported = BUS_NONE; + internal_buses_supported = BUS_NONE; msg_pdbg("Flash bus type is unknown (none)\n"); msg_pinfo("Something went wrong with bus type detection.\n"); goto out_msg; @@ -1323,7 +1322,6 @@ struct pci_dev *dev = NULL; int ret = -2; /* Nothing! */ int i; - char *s;
/* Now let's try to find the chipset we have... */ for (i = 0; chipset_enables[i].vendor_name != NULL; i++) { @@ -1375,9 +1373,5 @@ } }
- s = flashbuses_to_text(buses_supported); - msg_pinfo("This chipset supports the following protocols: %s.\n", s); - free(s); - return ret; } Index: flashrom-register_par_programmer/programmer.c =================================================================== --- flashrom-register_par_programmer/programmer.c (Revision 1460) +++ flashrom-register_par_programmer/programmer.c (Arbeitskopie) @@ -19,7 +19,21 @@ */
#include "flash.h" +#include "programmer.h"
+static const struct par_programmer par_programmer_none = { + .chip_readb = noop_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = noop_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, +}; + +const struct par_programmer *par_programmer = &par_programmer_none; + /* No-op shutdown() for programmers which don't need special handling */ int noop_shutdown(void) { @@ -96,3 +110,9 @@ buf[i] = chip_readb(addr + i); return; } + +void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses) +{ + par_programmer = pgm; + buses_supported |= buses; +} Index: flashrom-register_par_programmer/flashrom.c =================================================================== --- flashrom-register_par_programmer/flashrom.c (Revision 1460) +++ flashrom-register_par_programmer/flashrom.c (Arbeitskopie) @@ -68,14 +68,6 @@ .init = internal_init, .map_flash_region = physmap, .unmap_flash_region = physunmap, - .chip_readb = internal_chip_readb, - .chip_readw = internal_chip_readw, - .chip_readl = internal_chip_readl, - .chip_readn = internal_chip_readn, - .chip_writeb = internal_chip_writeb, - .chip_writew = internal_chip_writew, - .chip_writel = internal_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -86,14 +78,6 @@ .init = dummy_init, .map_flash_region = dummy_map, .unmap_flash_region = dummy_unmap, - .chip_readb = dummy_chip_readb, - .chip_readw = dummy_chip_readw, - .chip_readl = dummy_chip_readl, - .chip_readn = dummy_chip_readn, - .chip_writeb = dummy_chip_writeb, - .chip_writew = dummy_chip_writew, - .chip_writel = dummy_chip_writel, - .chip_writen = dummy_chip_writen, .delay = internal_delay, }, #endif @@ -104,14 +88,6 @@ .init = nic3com_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = nic3com_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nic3com_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -124,14 +100,6 @@ .init = nicrealtek_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = nicrealtek_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicrealtek_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -142,14 +110,6 @@ .init = nicnatsemi_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = nicnatsemi_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicnatsemi_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -160,14 +120,6 @@ .init = gfxnvidia_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = gfxnvidia_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = gfxnvidia_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -178,14 +130,6 @@ .init = drkaiser_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = drkaiser_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = drkaiser_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -196,14 +140,6 @@ .init = satasii_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = satasii_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = satasii_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -214,14 +150,6 @@ .init = atahpt_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = atahpt_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = atahpt_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -232,14 +160,6 @@ .init = ft2232_spi_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -250,14 +170,6 @@ .init = serprog_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = serprog_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = serprog_chip_readn, - .chip_writeb = serprog_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = serprog_delay, }, #endif @@ -268,14 +180,6 @@ .init = buspirate_spi_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -286,14 +190,6 @@ .init = dediprog_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -304,14 +200,6 @@ .init = rayer_spi_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -322,14 +210,6 @@ .init = nicintel_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = nicintel_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = nicintel_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -340,14 +220,6 @@ .init = nicintel_spi_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -358,14 +230,6 @@ .init = ogp_spi_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -376,14 +240,6 @@ .init = satamv_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = satamv_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = satamv_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -394,14 +250,6 @@ .init = linux_spi_init, .map_flash_region = fallback_map, .unmap_flash_region = fallback_unmap, - .chip_readb = noop_chip_readb, - .chip_readw = fallback_chip_readw, - .chip_readl = fallback_chip_readl, - .chip_readn = fallback_chip_readn, - .chip_writeb = noop_chip_writeb, - .chip_writew = fallback_chip_writew, - .chip_writel = fallback_chip_writel, - .chip_writen = fallback_chip_writen, .delay = internal_delay, }, #endif @@ -513,42 +361,42 @@
void chip_writeb(uint8_t val, chipaddr addr) { - programmer_table[programmer].chip_writeb(val, addr); + par_programmer->chip_writeb(val, addr); }
void chip_writew(uint16_t val, chipaddr addr) { - programmer_table[programmer].chip_writew(val, addr); + par_programmer->chip_writew(val, addr); }
void chip_writel(uint32_t val, chipaddr addr) { - programmer_table[programmer].chip_writel(val, addr); + par_programmer->chip_writel(val, addr); }
void chip_writen(uint8_t *buf, chipaddr addr, size_t len) { - programmer_table[programmer].chip_writen(buf, addr, len); + par_programmer->chip_writen(buf, addr, len); }
uint8_t chip_readb(const chipaddr addr) { - return programmer_table[programmer].chip_readb(addr); + return par_programmer->chip_readb(addr); }
uint16_t chip_readw(const chipaddr addr) { - return programmer_table[programmer].chip_readw(addr); + return par_programmer->chip_readw(addr); }
uint32_t chip_readl(const chipaddr addr) { - return programmer_table[programmer].chip_readl(addr); + return par_programmer->chip_readl(addr); }
void chip_readn(uint8_t *buf, chipaddr addr, size_t len) { - programmer_table[programmer].chip_readn(buf, addr, len); + par_programmer->chip_readn(buf, addr, len); }
void programmer_delay(int usecs) Index: flashrom-register_par_programmer/programmer.h =================================================================== --- flashrom-register_par_programmer/programmer.h (Revision 1460) +++ flashrom-register_par_programmer/programmer.h (Arbeitskopie) @@ -97,14 +97,6 @@ size_t len); void (*unmap_flash_region) (void *virt_addr, size_t len);
- void (*chip_writeb) (uint8_t val, chipaddr addr); - void (*chip_writew) (uint16_t val, chipaddr addr); - void (*chip_writel) (uint32_t val, chipaddr addr); - void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len); - uint8_t (*chip_readb) (const chipaddr addr); - uint16_t (*chip_readw) (const chipaddr addr); - uint32_t (*chip_readl) (const chipaddr addr); - void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len); void (*delay) (int usecs); };
@@ -306,6 +298,7 @@ extern int force_boardmismatch; void probe_superio(void); int register_superio(struct superio s); +extern enum chipbustype internal_buses_supported; int internal_init(void); void internal_chip_writeb(uint8_t val, chipaddr addr); void internal_chip_writew(uint16_t val, chipaddr addr); @@ -360,6 +353,18 @@ uint16_t fallback_chip_readw(const chipaddr addr); uint32_t fallback_chip_readl(const chipaddr addr); void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); +struct par_programmer { + void (*chip_writeb) (uint8_t val, chipaddr addr); + void (*chip_writew) (uint16_t val, chipaddr addr); + void (*chip_writel) (uint32_t val, chipaddr addr); + void (*chip_writen) (uint8_t *buf, chipaddr addr, size_t len); + uint8_t (*chip_readb) (const chipaddr addr); + uint16_t (*chip_readw) (const chipaddr addr); + uint32_t (*chip_readl) (const chipaddr addr); + void (*chip_readn) (uint8_t *buf, const chipaddr addr, size_t len); +}; +extern const struct par_programmer *par_programmer; +void register_par_programmer(const struct par_programmer *pgm, const enum chipbustype buses);
/* dummyflasher.c */ #if CONFIG_DUMMY == 1 @@ -634,10 +639,6 @@ uint8_t serprog_chip_readb(const chipaddr addr); void serprog_chip_readn(uint8_t *buf, const chipaddr addr, size_t len); void serprog_delay(int usecs); -int serprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, - const unsigned char *writearr, - unsigned char *readarr); -int serprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); #endif
/* serial.c */ Index: flashrom-register_par_programmer/board_enable.c =================================================================== --- flashrom-register_par_programmer/board_enable.c (Revision 1460) +++ flashrom-register_par_programmer/board_enable.c (Arbeitskopie) @@ -425,7 +425,7 @@ /* Check if at least one flash segment is enabled. */ if (tmp & 0xf0) { /* The IT8705F will respond to LPC cycles and translate them. */ - buses_supported = BUS_PARALLEL; + internal_buses_supported = BUS_PARALLEL; /* Flash ROM I/F Writes Enable */ tmp |= 0x04; msg_pdbg("Enabling IT8705F flash ROM interface write.\n");
Am Montag, den 07.11.2011, 14:47 +0100 schrieb Carl-Daniel Hailfinger:
- Should register_par_programmer(...) be called before or after setting max_rom_decode.*?
why is that not a field in the different programmer structs (yet?)?
Supply it as register_par_programmer() parameter and extend register_spi_programmer to accept that parameter as well?
I'm now setting max_rom_decode before calling register_par_programmer. Given that such restrictions may exist for any programmer, I'll postpone handling max_rom_decode to the universal programmer registration patch where we get the infrastructure to deal with such programmer limitations. If you have any objections, please tell me.
As we are heading strongly towards having a dynamic list of programmers, and there might even be two SPI programmers with different max decode size, storing it with the programmer structure seems like the only sane option. Having the registeration function fill a field in the dynamic programmer structure using a parameter is one sensible choice to get that field populated.
- Is there a better name for register_par_programmer?
register_parallel_programmer ofc, and imho it is not too long, because it is seldom used, but i don't care that much (due to the same reason).
80 column limit... I think that was one of the reasons we used a shorter name.
I am not really convinced "parallel" is to the point. While even LPC/FWH is still using 4 bits in parallel, the real distinction between parallel/LPC/FWH and SPI is that parallel/LPC/FWH is pushing commands through a memory read/write interface, while SPI pushes memory read/writes through a command interface. (At least if you look at the layer of abstraction applying to flashrom)
But "register_memcycle_programmer" is most likely something people are not going to understand, although, looking at the contents of your par_programmer structure, all the functions really are about memory cylces.
max_rom_decode is conceptually different from buses_supported although that was not obvious when I wrote the paragraph above. It will be handled in the universal programmer registration patch.
In the end, I don't even think we need buses_supported outside of the classic/memcycle/parallel programmer (however you call it), because SPI interface chips just support spi flash chips, and for opaque programmers we even had to introduce a fake bus type. Maximum supported chip size on the other hand is a concept that likely applies sensibly apply to every type of programmer.
- Should map_flash_region/unmap_flash_region be part of the registration?
no idea what that does exactly :P
It makes the flash chip accessible. This is essentially physmap for programmers with memory mapped flash and a no-op for everything else.
If the idea of a future flashrom (or libflashrom) is that you scan the system for programmers and build a table from the registrations, then I don't think you really want to initialize the hardware/map the memory at the time of registration further than needed for detection, but you need a hardware startup callback in the programmer.
And moving it into the parallel programmer struct may not have been the best idea. Sure, that gets it out of the way conveniently, but once the universal programmer registration patch is in, we will not have any dummy parallel programmer struct for such fallbacks anymore.
[drkaiser]
- max_rom_decode.parallel = 131072;
"128 * 1024" to comply with the flashrom style?
- register_par_programmer(&par_programmer_drkaiser, BUS_PARALLEL);
- return 0;
}
- /* FIXME: This assumes that serprog device bustypes are always
* identical with flashrom bustype enums and that they all fit
* in a single byte.
*/
I guess that is how the serprog protocol is "specified" ;)
Index: flashrom-register_par_programmer/it85spi.c
--- flashrom-register_par_programmer/it85spi.c (Revision 1460) +++ flashrom-register_par_programmer/it85spi.c (Arbeitskopie) @@ -257,8 +257,10 @@ INDIRECT_A3(shm_io_base, (base >> 24)); #endif #ifdef LPC_MEMORY
- base = (chipaddr)programmer_map_flash_region("it85 communication",
0xFFFFF000, 0x1000);
- /* FIXME: We should block accessing that region for anything else.
* Major TODO here, and it will be a lot of work.
*/
"blocking it for anything else" just means disabling the "classic/parallel" interface of the internal programmer, if I understand it correctly, so...
/* FIXME: Really leave FWH enabled? We can't use this region
* anymore since accessing it would mess up IT85 communication.
* If we decide to disable FWH for this region, we should print
* a debug message about it.
*/
... of course FWH/LPC/Parallel needs to be turned off here. I hope this code verifies that the IT85 SPI flash translator is really enabled, before concluding this.
Looks fine so far. So go ahead and commit.
Acked-By: Michael Karcher flashrom@mkarcher.dialup.fu-berlin.de
Regards, Michael Karcher
Am 09.11.2011 23:19 schrieb Michael Karcher:
Am Montag, den 07.11.2011, 14:47 +0100 schrieb Carl-Daniel Hailfinger:
- Should register_par_programmer(...) be called before or after setting max_rom_decode.*?
why is that not a field in the different programmer structs (yet?)?
Supply it as register_par_programmer() parameter and extend register_spi_programmer to accept that parameter as well?
I'm now setting max_rom_decode before calling register_par_programmer. Given that such restrictions may exist for any programmer, I'll postpone handling max_rom_decode to the universal programmer registration patch where we get the infrastructure to deal with such programmer limitations. If you have any objections, please tell me.
As we are heading strongly towards having a dynamic list of programmers, and there might even be two SPI programmers with different max decode size, storing it with the programmer structure seems like the only sane option. Having the registeration function fill a field in the dynamic programmer structure using a parameter is one sensible choice to get that field populated.
Indeed, that's the plan. I'll post a followup patch for this.
- Is there a better name for register_par_programmer?
register_parallel_programmer ofc, and imho it is not too long, because it is seldom used, but i don't care that much (due to the same reason).
80 column limit... I think that was one of the reasons we used a shorter name.
I am not really convinced "parallel" is to the point. While even LPC/FWH is still using 4 bits in parallel, the real distinction between parallel/LPC/FWH and SPI is that parallel/LPC/FWH is pushing commands through a memory read/write interface, while SPI pushes memory read/writes through a command interface. (At least if you look at the layer of abstraction applying to flashrom)
But "register_memcycle_programmer" is most likely something people are not going to understand, although, looking at the contents of your par_programmer structure, all the functions really are about memory cylces.
There are three types of programmers: In-band commands (Parallel/LPC/FWH) Out-of-band commands (SPI/I2C) Opaque programmers (ICH HWSeq)
All in-band programmers have a common way to interface with the flash chip. Sharing a common registration function makes sense, and I'm not too happy with the name "par" either. Admittedly people outside the x86 world usually know only Parallel flash and SPI flash, so for them a name referencing parallel flash is easiest to understand. OTOH, we could use "ib" or "inband" instead of "par", but I'm not sure if that is understood more easily. Out-of-band programmers all share a command submission mechanism which is used for all accesses, but the mechanism differs between SPI and I2C (and even between classic single-IO SPI and the new dual-/quad-IO SPI). Thus a common registration function for SPI and I2C would be difficult. Fortunately we don't support I2C yet.
max_rom_decode is conceptually different from buses_supported although that was not obvious when I wrote the paragraph above. It will be handled in the universal programmer registration patch.
In the end, I don't even think we need buses_supported outside of the classic/memcycle/parallel programmer (however you call it), because SPI interface chips just support spi flash chips, and for opaque programmers we even had to introduce a fake bus type.
In the future, probing will be registered-programmer-centric (i.e. walk the registered-programmer list, and for each registered programmer walk the flash chip list) and buses_supported will be a per-registered-programmer field used to match chips with compatible buses during probing. Probing doesn't care about the bus type except for determining compatible chips.
Maximum supported chip size on the other hand is a concept that likely applies sensibly apply to every type of programmer.
Indeed.
- Should map_flash_region/unmap_flash_region be part of the registration?
no idea what that does exactly :P
It makes the flash chip accessible. This is essentially physmap for programmers with memory mapped flash and a no-op for everything else.
If the idea of a future flashrom (or libflashrom) is that you scan the system for programmers and build a table from the registrations, then I don't think you really want to initialize the hardware/map the memory at the time of registration further than needed for detection, but you need a hardware startup callback in the programmer.
That's the idea. map_flash_region is only called during flash chip probing and not during programmer probing/registration.
[drkaiser]
- max_rom_decode.parallel = 131072;
"128 * 1024" to comply with the flashrom style?
Fixed.
- /* FIXME: This assumes that serprog device bustypes are always
* identical with flashrom bustype enums and that they all fit
* in a single byte.
*/
I guess that is how the serprog protocol is "specified" ;)
Heh, yes.
Index: flashrom-register_par_programmer/it85spi.c
--- flashrom-register_par_programmer/it85spi.c (Revision 1460) +++ flashrom-register_par_programmer/it85spi.c (Arbeitskopie) @@ -257,8 +257,10 @@ INDIRECT_A3(shm_io_base, (base >> 24)); #endif #ifdef LPC_MEMORY
- base = (chipaddr)programmer_map_flash_region("it85 communication",
0xFFFFF000, 0x1000);
- /* FIXME: We should block accessing that region for anything else.
* Major TODO here, and it will be a lot of work.
*/
"blocking it for anything else" just means disabling the "classic/parallel" interface of the internal programmer, if I understand it correctly, so...
Not necessarily. If there are multiple flash chips on a board, e.g. a 512 kByte SPI chip behind IT85 SPI translation and a 512 kByte FWH chip attached to the southbridge and if the SPI chip is mapped at 4G-512k to 4G and the FWH chip is mapped in the region 4G-1M to 4G-512k, no conflict arises as long as FWH probing does not touch the top 512 kB. A possible solution would be replacing physmap in programmer_map_flash_region and in IT85 with a variant exclusive_physmap which refuses mapping if another exclusive mapping exists in the same region.
/* FIXME: Really leave FWH enabled? We can't use this region
* anymore since accessing it would mess up IT85 communication.
* If we decide to disable FWH for this region, we should print
* a debug message about it.
*/
... of course FWH/LPC/Parallel needs to be turned off here. I hope this code verifies that the IT85 SPI flash translator is really enabled, before concluding this.
I'll try to get Google to merge their current IT85 SPI code into mainline flashrom and then fix any issues which still arise. To be honest, picking LPC_IO instead of LPC_MEMORY would solve the whole problem without introducing any conflicts, but that would also need cooperation from the IT85 chip to disable listening to LPC memory cycles for its command interface.
Looks fine so far. So go ahead and commit.
Acked-By: Michael Karcher flashrom@mkarcher.dialup.fu-berlin.de
Thanks a lot.
Committed in r1463.
Regards, Carl-Daniel