OK, here's the current megapatch. Will split later, right now I just want to get this out for review.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-rom_decode_check/flash.h =================================================================== --- flashrom-rom_decode_check/flash.h (Revision 753) +++ flashrom-rom_decode_check/flash.h (Arbeitskopie) @@ -352,9 +352,17 @@ void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask); int board_flash_enable(const char *vendor, const char *part);
+struct decode_sizes { + uint32_t parallel; + uint32_t lpc; + uint32_t fwh; + uint32_t spi; +}; + /* chipset_enable.c */ extern enum chipbustype buses_supported; int chipset_flash_enable(void); +extern struct decode_sizes max_rom_decode;
extern unsigned long flashbase;
Index: flashrom-rom_decode_check/chipset_enable.c =================================================================== --- flashrom-rom_decode_check/chipset_enable.c (Revision 753) +++ flashrom-rom_decode_check/chipset_enable.c (Arbeitskopie) @@ -41,6 +41,12 @@ */
enum chipbustype buses_supported = CHIP_BUSTYPE_NONSPI; +struct decode_sizes max_rom_decode = { + .parallel = 0xffffffff, + .lpc = 0xffffffff, + .fwh = 0xffffffff, + .spi = 0xffffffff +};
extern int ichspi_lock;
@@ -204,34 +210,73 @@ uint32_t fwh_conf; int i; char *idsel = NULL; + int tmp; + int max_decode_fwh_idsel = 0; + int max_decode_fwh_decode = 0; + int contiguous = 1;
- /* Ignore all legacy ranges below 1 MB. */ + /* Ignore all legacy ranges below 1 MB. + * We currently only support flashing the chip which responds to + * IDSEL=0. To support IDSEL!=0, flashbase and decode size calculations + * have to be adjusted. + */ /* FWH_SEL1 */ fwh_conf = pci_read_long(dev, 0xd0); - for (i = 7; i >= 0; i--) + for (i = 7; i >= 0; i--) { + tmp = (fwh_conf >> (i * 4)) & 0xf; printf_debug("\n0x%08x/0x%08x FWH IDSEL: 0x%x", (0x1ff8 + i) * 0x80000, (0x1ff0 + i) * 0x80000, - (fwh_conf >> (i * 4)) & 0xf); + tmp); + if ((tmp == 0) && contiguous) { + max_decode_fwh_idsel = (8 - i) * 0x80000; + } else { + contiguous = 0; + } + } /* FWH_SEL2 */ fwh_conf = pci_read_word(dev, 0xd4); - for (i = 3; i >= 0; i--) + for (i = 3; i >= 0; i--) { + tmp = (fwh_conf >> (i * 4)) & 0xf; printf_debug("\n0x%08x/0x%08x FWH IDSEL: 0x%x", (0xff4 + i) * 0x100000, (0xff0 + i) * 0x100000, - (fwh_conf >> (i * 4)) & 0xf); + tmp); + if ((tmp == 0) && contiguous) { + max_decode_fwh_idsel = (8 - i) * 0x100000; + } else { + contiguous = 0; + } + } + contiguous = 1; /* FWH_DEC_EN1 */ fwh_conf = pci_read_word(dev, 0xd8); - for (i = 7; i >= 0; i--) + for (i = 7; i >= 0; i--) { + tmp = (fwh_conf >> (i + 0x8)) & 0x1; printf_debug("\n0x%08x/0x%08x FWH decode %sabled", (0x1ff8 + i) * 0x80000, (0x1ff0 + i) * 0x80000, - (fwh_conf >> (i + 0x8)) & 0x1 ? "en" : "dis"); - for (i = 3; i >= 0; i--) + tmp ? "en" : "dis"); + if ((tmp == 0) && contiguous) { + max_decode_fwh_decode = (8 - i) * 0x80000; + } else { + contiguous = 0; + } + } + for (i = 3; i >= 0; i--) { + tmp = (fwh_conf >> i) & 0x1; printf_debug("\n0x%08x/0x%08x FWH decode %sabled", (0xff4 + i) * 0x100000, (0xff0 + i) * 0x100000, - (fwh_conf >> i) & 0x1 ? "en" : "dis"); + tmp ? "en" : "dis"); + if ((tmp == 0) && contiguous) { + max_decode_fwh_decode = (8 - i) * 0x100000; + } else { + contiguous = 0; + } + } + max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode); + printf_debug("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh);
if (programmer_param) idsel = strstr(programmer_param, "fwh_idsel="); @@ -244,8 +289,13 @@ printf("\nSetting IDSEL=0x%x for top 16 MB", fwh_conf); pci_write_long(dev, 0xd0, fwh_conf); pci_write_word(dev, 0xd4, fwh_conf); + /* FIXME: Decode settings are not changed. */ }
+ /* If we're called by enable_flash_ich_dc, it will override + * buses_supported anyway. + */ + buses_supported = CHIP_BUSTYPE_FWH; return enable_flash_ich(dev, name, 0xdc); }
@@ -258,6 +308,7 @@ { uint32_t mmio_base;
+ /* Do we really need no write enable? */ mmio_base = (pci_read_long(dev, 0xbc)) << 8; printf_debug("MMIO base at = 0x%x\n", mmio_base); spibar = physmap("VT8237S MMIO registers", mmio_base, 0x70); @@ -312,8 +363,7 @@ */
if (ich_generation == 7 && bbs == ICH_STRAP_LPC) { - /* Not sure if it speaks LPC as well. */ - buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH; + buses_supported = CHIP_BUSTYPE_FWH; /* No further SPI initialization required */ return ret; } @@ -325,16 +375,14 @@ spibar_offset = 0x3020; break; case 8: - /* Not sure if it speaks LPC as well. */ - buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI; + buses_supported = CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI; spi_controller = SPI_CONTROLLER_ICH9; spibar_offset = 0x3020; break; case 9: case 10: default: /* Future version might behave the same */ - /* Not sure if it speaks LPC as well. */ - buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI; + buses_supported = CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI; spi_controller = SPI_CONTROLLER_ICH9; spibar_offset = 0x3800; break; @@ -515,14 +563,22 @@
#define DECODE_CONTROL_REG2 0x5b /* F0 index 0x5b */ #define ROM_AT_LOGIC_CONTROL_REG 0x52 /* F0 index 0x52 */ +#define CS5530_RESET_CONTROL_REG 0x44 /* F0 index 0x44 */ +#define CS5530_USB_SHADOW_REG 0x43 /* F0 index 0x43 */
#define LOWER_ROM_ADDRESS_RANGE (1 << 0) #define ROM_WRITE_ENABLE (1 << 1) #define UPPER_ROM_ADDRESS_RANGE (1 << 2) #define BIOS_ROM_POSITIVE_DECODE (1 << 5) +#define CS5530_ISA_MASTER (1 << 7) +#define CS5530_ENABLE_SA2320 (1 << 2) +#define CS5530_ENABLE_SA20 (1 << 6)
+ 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 + * ignores that region completely. * Make the configured ROM areas writable. */ reg8 = pci_read_byte(dev, ROM_AT_LOGIC_CONTROL_REG); @@ -536,6 +592,24 @@ reg8 |= BIOS_ROM_POSITIVE_DECODE; pci_write_byte(dev, DECODE_CONTROL_REG2, reg8);
+ reg8 = pci_read_byte(dev, CS5530_RESET_CONTROL_REG); + if (reg8 & CS5530_ISA_MASTER) { + /* We have A0-A23 available. */ + max_rom_decode.parallel = 16 * 1024 * 1024; + } else { + reg8 = pci_read_byte(dev, CS5530_USB_SHADOW_REG); + if (reg8 & CS5530_ENABLE_SA2320) { + /* We have A0-19, A20-A23 available. */ + max_rom_decode.parallel = 16 * 1024 * 1024; + } else if (reg8 & CS5530_ENABLE_SA20) { + /* We have A0-19, A20 available. */ + max_rom_decode.parallel = 2 * 1024 * 1024; + } else { + /* A20 and above are not active. */ + max_rom_decode.parallel = 1024 * 1024; + } + } + return 0; }
Index: flashrom-rom_decode_check/flashrom.c =================================================================== --- flashrom-rom_decode_check/flashrom.c (Revision 753) +++ flashrom-rom_decode_check/flashrom.c (Arbeitskopie) @@ -299,6 +299,15 @@ return (a > b) ? a : b; }
+int bitcount(unsigned long a) +{ + int i = 0; + for (; a != 0; a >>= 1) + if (a & 1) + i++; + return i; +} + char *strcat_realloc(char *dest, const char *src) { dest = realloc(dest, strlen(dest) + strlen(src) + 1); @@ -398,10 +407,63 @@ return ret; }
+int check_max_decode(enum chipbustype buses, unsigned int size, int warn) +{ + int limitexceeded = 0; + if ((buses & CHIP_BUSTYPE_PARALLEL) && + (max_rom_decode.parallel < size)) { + limitexceeded++; + printf_debug("Chip size %u is bigger than supported " + "size %u of chipset/board/programmer " + "for Parallel interface, " + "probe/read/erase/write may fail. ", size, + max_rom_decode.parallel); + } + if ((buses & CHIP_BUSTYPE_LPC) && + (max_rom_decode.lpc < size)) { + limitexceeded++; + printf_debug("Chip size %u is bigger than supported " + "size %u of chipset/board/programmer " + "for LPC interface, " + "probe/read/erase/write may fail. ", size, + max_rom_decode.lpc); + } + if ((buses & CHIP_BUSTYPE_FWH) && + (max_rom_decode.fwh < size)) { + limitexceeded++; + printf_debug("Chip size %u is bigger than supported " + "size %u of chipset/board/programmer " + "for FWH interface, " + "probe/read/erase/write may fail. ", size, + max_rom_decode.fwh); + } + if ((buses & CHIP_BUSTYPE_SPI) && + (max_rom_decode.spi < size)) { + limitexceeded++; + printf_debug("Chip size %u is bigger than supported " + "size %u of chipset/board/programmer " + "for SPI interface, " + "probe/read/erase/write may fail. ", size, + max_rom_decode.spi); + } + if (!limitexceeded) + return 0; + /* Sometimes chip and programmer have more than one bus in common, + * and the limit is not exceeded on all buses. Tell the user. + */ + if (bitcount(buses) > limitexceeded) + printf_debug("There is at least one common chip/programmer " + "interface which can support a chip of this size. " + "You can try --force at your own risk.\n"); + return 1; +} + struct flashchip *probe_flash(struct flashchip *first_flash, int force) { struct flashchip *flash; - unsigned long base = 0, size; + unsigned long base = 0; + unsigned int size; + enum chipbustype buses_common; char *tmp;
for (flash = first_flash; flash && flash->name; flash++) { @@ -413,7 +475,8 @@ printf_debug("failed! flashrom has no probe function for this flash chip.\n"); continue; } - if (!(buses_supported & flash->bustype)) { + buses_common = buses_supported & flash->bustype; + if (!buses_common) { tmp = flashbuses_to_text(buses_supported); printf_debug("skipped. Host bus type %s ", tmp); free(tmp); @@ -424,6 +487,7 @@ }
size = flash->total_size * 1024; + check_max_decode(buses_common, size, 0);
base = flashbase ? flashbase : (0xffffffff - size + 1); flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size); @@ -975,6 +1039,14 @@ verify_it = 1;
size = flash->total_size * 1024; + if (check_max_decode((buses_supported & flash->bustype), size, 1) && + (!force)) { + fprintf(stderr, "This chip is too big for this programmer. " + "Details are given in verbose mode. You can override " + "this check with --force."); + programmer_shutdown(); + return 1; + } buf = (uint8_t *) calloc(size, sizeof(char));
if (erase_it) { Index: flashrom-rom_decode_check/board_enable.c =================================================================== --- flashrom-rom_decode_check/board_enable.c (Revision 753) +++ flashrom-rom_decode_check/board_enable.c (Arbeitskopie) @@ -804,16 +804,24 @@ }
/** - * Suited for: - * - Shuttle AK38N: VIA KT333CF + VIA VT8235 + ITE IT8705F - * - Elitegroup K7VTA3: VIA Apollo KT266/A/333 + VIA VT8235 + ITE IT8705F + * Suited for: Elitegroup K7VTA3: VIA Apollo KT266/A/333 + VIA VT8235 + ITE IT8705F */ -static int it8705f_write_enable_2e(const char *name) +static int elitegroup_k7vta3(const char *name) { + max_rom_decode.parallel = 256 * 1024; return it8705f_write_enable(0x2e, name); }
/** + * Suited for: Shuttle AK38N: VIA KT333CF + VIA VT8235 + ITE IT8705F + */ +static int shuttle_ak38n(const char *name) +{ + max_rom_decode.parallel = 256 * 1024; + return it8705f_write_enable(0x2e, name); +} + +/** * Find the runtime registers of an SMSC Super I/O, after verifying its * chip ID. * @@ -1079,7 +1087,7 @@ {0x10DE, 0x0030, 0x1043, 0x818a, 0x8086, 0x100E, 0x1043, 0x80EE, NULL, NULL, "ASUS", "P5ND2-SLI Deluxe", board_asus_p5nd2_sli}, {0x1106, 0x3149, 0x1565, 0x3206, 0x1106, 0x3344, 0x1565, 0x1202, NULL, NULL, "Biostar", "P4M80-M4", it8705_rom_write_enable}, {0x8086, 0x3590, 0x1028, 0x016c, 0x1000, 0x0030, 0x1028, 0x016c, NULL, NULL, "Dell", "PowerEdge 1850", ich5_gpio23_raise}, - {0x1106, 0x3038, 0x1019, 0x0996, 0x1106, 0x3177, 0x1019, 0x0996, NULL, NULL, "Elitegroup", "K7VTA3", it8705f_write_enable_2e}, + {0x1106, 0x3038, 0x1019, 0x0996, 0x1106, 0x3177, 0x1019, 0x0996, NULL, NULL, "Elitegroup", "K7VTA3", elitegroup_k7vta3}, {0x1106, 0x3177, 0x1106, 0x3177, 0x1106, 0x3059, 0x1695, 0x3005, NULL, NULL, "EPoX", "EP-8K5A2", board_epox_ep_8k5a2}, {0x10EC, 0x8139, 0x1695, 0x9001, 0x11C1, 0x5811, 0x1695, 0x9015, NULL, NULL, "EPoX", "EP-8RDA3+", board_epox_ep_8rda3plus}, {0x8086, 0x7110, 0, 0, 0x8086, 0x7190, 0, 0, "epox", "ep-bx3", "EPoX", "EP-BX3", board_epox_ep_bx3}, @@ -1105,7 +1113,7 @@ {0x1106, 0x0571, 0x1462, 0x7120, 0, 0, 0, 0, "msi", "kt4v", "MSI", "MS-6712 (KT4V)", board_msi_kt4v}, {0x8086, 0x2658, 0x1462, 0x7046, 0x1106, 0x3044, 0x1462, 0x046d, NULL, NULL, "MSI", "MS-7046", ich6_gpio19_raise}, {0x10de, 0x005e, 0, 0, 0, 0, 0, 0, "msi", "k8n-neo3", "MSI", "MS-7135 (K8N Neo3)", w83627thf_gpio4_4_raise_4e}, - {0x1106, 0x3104, 0x1297, 0xa238, 0x1106, 0x3059, 0x1297, 0xc063, NULL, NULL, "Shuttle", "AK38N", it8705f_write_enable_2e}, + {0x1106, 0x3104, 0x1297, 0xa238, 0x1106, 0x3059, 0x1297, 0xc063, NULL, NULL, "Shuttle", "AK38N", shuttle_ak38n}, {0x10DE, 0x0050, 0x1297, 0x5036, 0x1412, 0x1724, 0x1297, 0x5036, NULL, NULL, "Shuttle", "FN25", board_shuttle_fn25}, {0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x3058, 0x15DD, 0x7609, NULL, NULL, "Soyo", "SY-7VCA", board_soyo_sy_7vca}, {0x8086, 0x1076, 0x8086, 0x1176, 0x1106, 0x3059, 0x10f1, 0x2498, NULL, NULL, "Tyan", "S2498 (Tomcat K7M)", board_asus_a7v8x_mx},