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-23 20:28:04.215385000 +0530 @@ -535,6 +535,16 @@ static const char *const straps_names_pch8[] = { "LPC", "reserved", "reserved", "SPI" }; static const char *const straps_names_pch8_lp[] = { "SPI", "LPC" }; static const char *const straps_names_unknown[] = { "unknown", "unknown", "unknown", "unknown" }; +#ifdef AVOTON_SUPPORT + static const char *const straps_names_avoton[] = { "LPC", "reserved", "reserved", "SPI" }; + uint32_t gcs, tmp; + uint8_t bbs; + int ret_fwh = 0; + void *spibar; +#if 1 + uint32_t new, old; +#endif +#endif const char *const *straps_names; switch (ich_generation) { @@ -570,6 +580,11 @@ case CHIPSET_CENTERTON: // FIXME: Datasheet does not mention GCS at all straps_names = straps_names_unknown; break; +#ifdef AVOTON_SUPPORT + case CHIPSET_AVOTON: + straps_names = straps_names_avoton; + break; +#endif default: msg_gerr("%s: unknown ICH generation. Please report!\n", __func__); straps_names = straps_names_unknown; @@ -585,11 +600,13 @@ if (rcrb == ERROR_PTR) return ERROR_FATAL; - uint32_t gcs = mmio_readl(rcrb + 0x3410); +#ifdef AVOTON_SUPPORT + if (ich_generation != CHIPSET_AVOTON) { +#endif + gcs = mmio_readl(rcrb + 0x3410); msg_pdbg("GCS = 0x%x: ", gcs); msg_pdbg("BIOS Interface Lock-Down: %sabled, ", (gcs & 0x1) ? "en" : "dis"); - uint8_t bbs; switch (ich_generation) { case CHIPSET_TUNNEL_CREEK: bbs = (gcs >> 1) & 0x1; @@ -612,7 +629,7 @@ } /* Handle FWH-related parameters and initialization */ - int ret_fwh = enable_flash_ich_fwh(dev, ich_generation, bios_cntl); + ret_fwh = enable_flash_ich_fwh(dev, ich_generation, bios_cntl); if (ret_fwh == ERROR_FATAL) return ret_fwh; @@ -633,8 +650,74 @@ break; } msg_pdbg("SPIBAR = 0x%0*" PRIxPTR " + 0x%04x\n", PRIxPTR_WIDTH, (uintptr_t)rcrb, spibar_offset); - void *spibar = rcrb + spibar_offset; + spibar = rcrb + spibar_offset; +#ifdef AVOTON_SUPPORT + } else { +#if 1 +#if 0 + 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 | BUS_FWH; + } else { + msg_perr("Unsupported BUS!\n"); + return ERROR_FATAL; + } + + msg_pdbg("Top Swap : %s\n", + (gcs & 0x2) ? "enabled (A16 inverted)" : "not enabled"); +#endif + tmp = pci_read_long(dev, 0x54) & 0xFFFFFE00; + spibar = rphysmap("ICH SPIBAR", tmp, 0x4000); + msg_pdbg("SPIBAR = 0x%x\n", tmp); + +#if 1 + /* BIOS Control Register */ + tmp = mmio_readl(spibar + bios_cntl); + 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 + bios_cntl)); + } + tmp = mmio_readl(spibar + bios_cntl); + 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 */ + } +#endif + 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; + } +#else + tmp = pci_read_long(dev, 0x54) & 0xFFFFFE00; + spibar = rphysmap("ICH SPIBAR", tmp, 0x4000); +#endif + } +#endif /* This adds BUS_SPI */ int ret_spi = ich_init_spi(dev, spibar, ich_generation); if (ret_spi == ERROR_FATAL) @@ -676,6 +759,13 @@ return enable_flash_ich_spi(dev, CHIPSET_ICH10, 0xdc); } +#ifdef AVOTON_SUPPORT +static int enable_flash_c2000(struct pci_dev *dev, const char *name) +{ + return enable_flash_ich_spi(dev, CHIPSET_AVOTON, 0xfc); +} +#endif + /* Ibex Peak aka. 5 series & 3400 series */ static int enable_flash_pch5(struct pci_dev *dev, const char *name) { @@ -1644,6 +1734,9 @@ {0x8086, 0x8d5d, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, {0x8086, 0x8d5e, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, {0x8086, 0x8d5f, NT, "Intel", "Wellsburg", enable_flash_pch8_wb}, +#ifdef AVOTON_SUPPORT + {0x8086, 0x1f38, OK, "Intel", "C2000", enable_flash_c2000}, +#endif #endif {0}, }; diff -Naur flashrom-0.9.7-r1769/dmi.c flashrom-0.9.7-r1769-mod/dmi.c --- flashrom-0.9.7-r1769/dmi.c 2014-03-05 05:46:16.000000000 +0530 +++ flashrom-0.9.7-r1769-mod/dmi.c 2014-04-23 20:23:43.993793000 +0530 @@ -84,6 +84,15 @@ {0x18, 0, "Sealed-case PC"}, /* used by Supermicro (X8SIE) */ }; +#ifdef AVOTON_SUPPORT +size_t strnlen(const char *str, size_t n) +{ + size_t i; + for (i = 0; i < n && str[i] != '\0'; i++) + ; + return i; +} +#endif #if CONFIG_INTERNAL_DMI == 1 #ifdef __DJGPP__ /* There is no strnlen in DJGPP. FIXME: Move this to a common utility file. */ size_t strnlen(const char *str, size_t n) 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-23 20:24:29.218593000 +0530 @@ -9485,6 +9485,44 @@ .voltage = {2700, 3600}, }, +#ifdef AVOTON_SUPPORT + { + .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 = { {64 * 1024, 256} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {4 * 1024, 4096} }, + .block_erase = spi_block_erase_20, + }, { + .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}, + }, +#endif + { .vendor = "SST", .name = "SST25LF040A", 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-23 20:28:04.243113000 +0530 @@ -612,6 +612,9 @@ bbar_off = 0x50; break; case CHIPSET_ICH8: +#ifdef AVOTON_SUPPORT + case CHIPSET_AVOTON: +#endif msg_perr("BBAR offset is unknown on ICH8!\n"); return; case CHIPSET_ICH9: @@ -1608,6 +1611,9 @@ register_spi_programmer(&spi_programmer_ich7); break; case CHIPSET_ICH8: +#ifdef AVOTON_SUPPORT + case CHIPSET_AVOTON: +#endif default: /* Future version might behave the same */ arg = extract_programmer_param("ich_spi_mode"); if (arg && !strcmp(arg, "hwseq")) { @@ -1732,10 +1738,15 @@ msg_pdbg("VSCC: "); prettyprint_ich_reg_vscc(tmp, MSG_DEBUG); } else { +#ifdef AVOTON_SUPPORT + if (ich_generation != CHIPSET_AVOTON) { +#endif ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR); msg_pdbg("0xA0: 0x%08x (BBAR)\n", ichspi_bbar); - +#ifdef AVOTON_SUPPORT + } +#endif if (desc_valid) { tmp = mmio_readl(ich_spibar + ICH9_REG_LVSCC); msg_pdbg("0xC4: 0x%08x (LVSCC)\n", tmp); diff -Naur flashrom-0.9.7-r1769/Makefile flashrom-0.9.7-r1769-mod/Makefile --- flashrom-0.9.7-r1769/Makefile 2014-03-19 22:47:09.000000000 +0530 +++ flashrom-0.9.7-r1769-mod/Makefile 2014-04-23 20:28:55.311459000 +0530 @@ -699,7 +699,7 @@ TAROPTIONS = $(shell LC_ALL=C tar --version|grep -q GNU && echo "--owner=root --group=root") %.o: %.c .features - $(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FLASHROM_CFLAGS) $(FEATURE_CFLAGS) $(SVNDEF) -o $@ -c $< + $(CC) -MMD $(CFLAGS) $(CPPFLAGS) $(FLASHROM_CFLAGS) $(FEATURE_CFLAGS) $(SVNDEF) -DAVOTON_SUPPORT -o $@ -c $< # Make sure to add all names of generated binaries here. # This includes all frontends and libflashrom. diff -Naur flashrom-0.9.7-r1769/programmer.h flashrom-0.9.7-r1769-mod/programmer.h --- flashrom-0.9.7-r1769/programmer.h 2014-03-05 05:46:16.000000000 +0530 +++ flashrom-0.9.7-r1769-mod/programmer.h 2014-04-23 20:28:04.257625000 +0530 @@ -558,6 +558,9 @@ /* The following enum is needed by ich_descriptor_tool and ich* code as well as in chipset_enable.c. */ enum ich_chipset { CHIPSET_ICH_UNKNOWN, +#ifdef AVOTON_SUPPORT + CHIPSET_AVOTON, +#endif CHIPSET_ICH, CHIPSET_ICH2345, CHIPSET_ICH6, diff -Naur flashrom-0.9.7-r1769/spi25.c flashrom-0.9.7-r1769-mod/spi25.c --- flashrom-0.9.7-r1769/spi25.c 2013-06-29 02:59:51.000000000 +0530 +++ flashrom-0.9.7-r1769-mod/spi25.c 2014-04-23 20:26:39.120703000 +0530 @@ -548,6 +548,10 @@ .readarr = NULL, }}; +#ifdef AVOTON_SUPPORT + msg_cerr("\n%s erasing address 0x%x, blocklen: %u\n", + __func__, addr, blocklen); +#endif result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", @@ -558,7 +562,7 @@ * This usually takes 100-4000 ms, so wait in 100 ms steps. */ while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(100 * 1000); + programmer_delay(1000 * 1000); /* FIXME: Check the status register for errors. */ return 0; } @@ -677,6 +681,10 @@ .readarr = NULL, }}; +#ifdef AVOTON_SUPPORT + msg_cerr("%s erasing address 0x%x, blocklen: %u\n", + __func__, addr, blocklen); +#endif result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n",