diff -Naur flashrom-0.9.7-r1769/chipset_enable.c flashrom-0.9.7-r1769-mod/chipset_enable.c --- flashrom-0.9.7-r1769/chipset_enable.c 2013-10-25 06:03:37.000000000 +0530 +++ flashrom-0.9.7-r1769-mod/chipset_enable.c 2014-04-22 19:49:06.631285000 +0530 @@ -260,6 +260,49 @@ return 0; } +static int enable_flash_ich_spi_decode(struct pci_dev *dev, const char *name) +{ + uint32_t bde_conf; + int i, tmp; + int max_decode_spi_decode = 0; + int contiguous = 1; + + bde_conf = pci_read_word(dev, 0xd8); + for (i = 7; i >= 0; i--) { + tmp = (bde_conf >> (i + 0x8)) & 0x1; + msg_pdbg("\n0x%08x/0x%08x BIOS decode %sabled", + (0x1ff8 + i) * 0x80000, + (0x1ff0 + i) * 0x80000, + tmp ? "en" : "dis"); + if ((tmp == 1) && contiguous) { + max_decode_spi_decode = (8 - i) * 0x80000; + } else { + contiguous = 0; + } + } + for (i = 3; i >= 0; i--) { + tmp = (bde_conf >> i) & 0x1; + msg_pdbg("\n0x%08x/0x%08x BIOS decode %sabled", + (0xff4 + i) * 0x100000, + (0xff0 + i) * 0x100000, + tmp ? "en" : "dis"); + if ((tmp == 1) && contiguous) { + max_decode_spi_decode = (8 - i) * 0x100000; + } else { + contiguous = 0; + } + } + max_rom_decode.spi = max_decode_spi_decode; + msg_pdbg("\nMaximum SPI chip size: 0x%x bytes", max_rom_decode.spi); + + internal_buses_supported = BUS_SPI; + return 0; +} +#endif + /* Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, in Poulsbo, Tunnel Creek and other Atom * chipsets/SoCs it is even 32b, but just treating it as 8 bit wide seems to work fine in practice. */ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl) @@ -651,6 +694,113 @@ return enable_flash_ich_spi(dev, CHIPSET_TUNNEL_CREEK, 0xd8); } +static int enable_flash_ich_c2000(struct pci_dev *dev, const char *name, + enum ich_chipset ich_generation) +{ + int ret = 0, ret_spi = 0; + uint8_t bbs; + uint32_t tmp, gcs; + void *rcrb; + const char *const *straps_names; + uint32_t new, old; + + static const char *const straps_names_avoton[] = { "LPC", "reserved", "reserved", "SPI" }; + static const char *const straps_names_unknown[] = { "unknown", "unknown", "unknown", "unknown" }; + + switch (ich_generation) { + case CHIPSET_AVOTON: + straps_names = straps_names_avoton; + break; + default: + msg_gerr("%s: unknown ICH generation. Please report!\n", + __func__); + straps_names = straps_names_unknown; + return ERROR_FATAL; + } + +#if 0 + /* Enable Flash Writes */ + ret = enable_flash_ich_spi_decode(dev, name); + if (ret == ERROR_FATAL) + return ret; +#endif + /* Get physical address of Root Complex Register Block */ + tmp = pci_read_long(dev, 0xf0) & 0xffffc000; + msg_pdbg("Root Complex Register Block address = 0x%x\n", tmp); + + /* Map RCBA to virtual memory */ + rcrb = rphysmap("ICH RCRB", tmp, 0x4000); + + gcs = mmio_readl(rcrb + 0x0); + msg_pdbg("GCS = 0x%x: ", gcs); + msg_pdbg("BIOS Interface Lock-Down: %sabled, ", + (gcs & 0x1) ? "en" : "dis"); + + bbs = (gcs >> 10) & 0x3; + msg_pdbg("Boot BIOS Straps: 0x%x (%s)\n", bbs, straps_names[bbs]); + if (bbs == 0x3) { + internal_buses_supported = BUS_SPI; + } else { + msg_perr("Unsupported BUS!\n"); + return ERROR_FATAL; + } + + msg_pdbg("Top Swap : %s\n", + (gcs & 0x2) ? "enabled (A16 inverted)" : "not enabled"); + + tmp = pci_read_long(dev, 0x54) & 0xFFFFFE00; + void *spibar = rphysmap("ICH SPIBAR", tmp, 0x4000); + msg_pdbg("SPIBAR = 0x%x\n", tmp); + + /* BIOS Control Register */ + tmp = mmio_readl(spibar + 0xFC); + msg_pdbg("0xFC: 0x%08x (BIOS_CONTROL_REGISTER_BIOS : BCR)\n", tmp); + msg_pdbg("BIOS Write Protect Disable : %sabled, ", + (tmp & (1 << 0)) ? "en" : "dis"); + msg_pdbg("\nBIOS Lock Enable: %sabled, ", + (tmp & (1 << 1)) ? "en" : "dis"); + if (tmp != 1) { + mmio_writel(0x1, (spibar + 0xFC)); + } + tmp = mmio_readl(spibar + 0xFC); + msg_pdbg("0xFC: 0x%08x (BIOS_CONTROL_REGISTER_BIOS : BCR)\n", tmp); + msg_pdbg("BIOS Write Protect Disable : %sabled, ", + (tmp & (1 << 0)) ? "en" : "dis"); + if (tmp != 1) { + msg_pdbg("Reboot and change BIOS-> IntelRCSetup -> Relax Security Config -> Disabled to Enabled\n"); + return ERROR_FATAL; /* Signal error */ + } + + old = mmio_readb(spibar + 0xFC); + msg_pdbg("SPI Read Configuration: "); + new = (old >> 2) & 0x3; + switch (new) { + case 0: + case 1: + case 2: + msg_pdbg("prefetching %sabled, caching %sabled, ", + (new & 0x2) ? "en" : "dis", + (new & 0x1) ? "dis" : "en"); + break; + default: + msg_pdbg("invalid prefetching/caching settings, "); + break; + } + + /* This adds BUS_SPI */ + ret_spi = ich_init_spi(dev, spibar, ich_generation); + if (ret_spi == ERROR_FATAL) + return ret_spi; + + if (ret || ret_spi) + ret = ERROR_NONFATAL; + + return ret; + +} + static int enable_flash_s12x0(struct pci_dev *dev, const char *name) { return enable_flash_ich_spi(dev, CHIPSET_CENTERTON, 0xd8); @@ -676,6 +826,13 @@ return enable_flash_ich_spi(dev, CHIPSET_ICH10, 0xdc); } +static int enable_flash_c2000(struct pci_dev *dev, const char *name) +{ + return enable_flash_ich_c2000(dev, name, CHIPSET_AVOTON); +} + /* Ibex Peak aka. 5 series & 3400 series */ static int enable_flash_pch5(struct pci_dev *dev, const char *name) { @@ -1513,6 +1670,9 @@ {0x8086, 0x1e5d, NT, "Intel", "HM75", enable_flash_pch7}, {0x8086, 0x1e5e, NT, "Intel", "HM70", enable_flash_pch7}, {0x8086, 0x1e5f, NT, "Intel", "NM70", enable_flash_pch7}, + {0x8086, 0x1f38, OK, "Intel", "C2000", enable_flash_c2000}, {0x8086, 0x2310, NT, "Intel", "DH89xxCC", enable_flash_pch7}, {0x8086, 0x2390, NT, "Intel", "Coleto Creek", enable_flash_pch7}, {0x8086, 0x2410, OK, "Intel", "ICH", enable_flash_ich0}, diff -Naur flashrom-0.9.7-r1769/flashchips.c flashrom-0.9.7-r1769-mod/flashchips.c --- flashrom-0.9.7-r1769/flashchips.c 2013-10-20 04:39:16.000000000 +0530 +++ flashrom-0.9.7-r1769-mod/flashchips.c 2014-04-22 20:02:59.937906000 +0530 @@ -9484,6 +9484,57 @@ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2700, 3600}, }, + { + .vendor = "Spansion", + .name = "S25FL256", /* uniform 256kB sectors */ + .bustype = BUS_SPI, + .manufacture_id = SPANSION_ID, + .model_id = SPANSION_S25FL256, + .total_size = 16384, + .page_size = 256, + /* supports 4B addressing */ + /* OTP: 1024B total, 32B reserved; read 0x4B; write 0x42 */ + .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + .tested = TEST_OK_PREW, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = { + { + .eraseblocks = { {4 * 1024, 4096} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {256 * 1024, 64} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { { 16384 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { { 16384 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .printlock = spi_prettyprint_status_register_bp2_ep_srwd, /* TODO: SR2 and many others */ + .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: various other locks */ + .write = spi_chip_write_256, /* Multi I/O supported */ + .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ + .voltage = {2700, 3600}, + }, { .vendor = "SST", diff -Naur flashrom-0.9.7-r1769/ichspi.c flashrom-0.9.7-r1769-mod/ichspi.c --- flashrom-0.9.7-r1769/ichspi.c 2013-10-25 06:03:37.000000000 +0530 +++ flashrom-0.9.7-r1769-mod/ichspi.c 2014-04-22 19:50:09.561339000 +0530 @@ -611,6 +611,9 @@ case CHIPSET_CENTERTON: bbar_off = 0x50; break; + case CHIPSET_AVOTON: case CHIPSET_ICH8: msg_perr("BBAR offset is unknown on ICH8!\n"); return; @@ -823,11 +826,17 @@ @@ -1608,6 +1623,9 @@ register_spi_programmer(&spi_programmer_ich7); break; case CHIPSET_ICH8: + case CHIPSET_AVOTON: default: /* Future version might behave the same */ arg = extract_programmer_param("ich_spi_mode"); if (arg && !strcmp(arg, "hwseq")) { @@ -1732,10 +1750,17 @@ msg_pdbg("VSCC: "); prettyprint_ich_reg_vscc(tmp, MSG_DEBUG); } else { + if (ich_generation != CHIPSET_AVOTON) { + ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR); msg_pdbg("0xA0: 0x%08x (BBAR)\n", ichspi_bbar); + } if (desc_valid) { tmp = mmio_readl(ich_spibar + ICH9_REG_LVSCC); msg_pdbg("0xC4: 0x%08x (LVSCC)\n", tmp);