[flashrom] [PATCH] Add Intel Bay Trail, Rangeley/Avoton and Wildcat Point support.

Stefan Tauner stefan.tauner at alumni.tuwien.ac.at
Sun Jun 22 01:46:05 CEST 2014


The core of this patch to support Bay Trail originally came from the
Chromiumos flashrom repo and was modified by Sage to support the
Rangeley/Avoton parts as well.
Because that was not complicated enough already Stefan Tauner refactored
everything and integrated Chromiumos' support for Wildcat as well.

Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
Signed-off-by: Stefan Tauner <stefan.tauner at alumni.tuwien.ac.at>
---

Martin: please sign off this patch in a reply as well because you
forgot to sign off previouslly.

I have worked pretty hard to reuse much of the existing code and I
think that worked out quite well. I had to dig through quite some code
and datasheets and I'd rather see this tested on real hardware please.
Anyone with affected hardware please test this patch!

 chipset_enable.c | 259 ++++++++++++++++++++++++++++++++++++++++++-------------
 ichspi.c         |  14 +--
 programmer.h     |   2 +
 3 files changed, 209 insertions(+), 66 deletions(-)

diff --git a/chipset_enable.c b/chipset_enable.c
index ec3c12c..d1976ba 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -260,9 +260,13 @@ static int enable_flash_piix4(struct pci_dev *dev, const char *name)
 	return 0;
 }
 
-/* Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, in Poulsbo, Tunnel Creek and other Atom
+/* Handle BIOS_CNTL (aka. BCR). Disable locks and enable writes. The register can either be in PCI config space
+ * at the offset given by 'bios_cntl' or at the memory-mapped address 'addr'.
+ *
+ * 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)
+static int enable_flash_ich_bios_cntl_common(enum ich_chipset ich_generation, void *addr,
+					     struct pci_dev *dev, uint8_t bios_cntl)
 {
 	uint8_t old, new, wanted;
 
@@ -273,8 +277,8 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_
 	case CHIPSET_ICH:
 	case CHIPSET_ICH2345:
 		break;
-	/* Atom chipsets are special: The second byte of BIOS_CNTL (D9h) contains a prefetch bit similar to what
-	 * other SPI-capable chipsets have at DCh.
+	/* Some Atom chipsets are special: The second byte of BIOS_CNTL (D9h) contains a prefetch bit similar to
+	 * what other SPI-capable chipsets have at DCh. Others like Bay Trail use a memmapped register.
 	 * The Tunnel Creek datasheet contains a lot of details about the SPI controller, among other things it
 	 * mentions that the prefetching and caching does only happen for direct memory reads.
 	 * Therefore - at least for Tunnel Creek - it should not matter to flashrom because we use the
@@ -285,9 +289,13 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_
 		old = pci_read_byte(dev, bios_cntl + 1);
 		msg_pdbg("BIOS Prefetch Enable: %sabled, ", (old & 1) ? "en" : "dis");
 		break;
+	case CHIPSET_BAYTRAIL:
 	case CHIPSET_ICH7:
 	default: /* Future version might behave the same */
-		old = (pci_read_byte(dev, bios_cntl) >> 2) & 0x3;
+		if (ich_generation == CHIPSET_BAYTRAIL)
+			old = (mmio_readl(addr) >> 2) & 0x3;
+		else
+			old = (pci_read_byte(dev, bios_cntl) >> 2) & 0x3;
 		msg_pdbg("SPI Read Configuration: ");
 		if (old == 3)
 			msg_pdbg("invalid prefetching/caching settings, ");
@@ -297,7 +305,11 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_
 				     (old & 0x1) ? "dis" : "en");
 	}
 
-	wanted = old = pci_read_byte(dev, bios_cntl);
+	if (ich_generation == CHIPSET_BAYTRAIL)
+		wanted = old = mmio_readl(addr);
+	else
+		wanted = old = pci_read_byte(dev, bios_cntl);
+
 	/*
 	 * Quote from the 6 Series datasheet (Document Number: 324645-004):
 	 * "Bit 5: SMM BIOS Write Protect Disable (SMM_BWP)
@@ -327,8 +339,13 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_
 
 	/* Only write the register if it's necessary */
 	if (wanted != old) {
-		rpci_write_byte(dev, bios_cntl, wanted);
-		new = pci_read_byte(dev, bios_cntl);
+		if (ich_generation == CHIPSET_BAYTRAIL) {
+			rmmio_writel(wanted, addr);
+			new = mmio_readl(addr);
+		} else {
+			rpci_write_byte(dev, bios_cntl, wanted);
+			new = pci_read_byte(dev, bios_cntl);
+		}
 	} else
 		new = old;
 
@@ -349,10 +366,22 @@ static int enable_flash_ich_bios_cntl(struct pci_dev *dev, enum ich_chipset ich_
 	return 0;
 }
 
+static int enable_flash_ich_bios_cntl_config_space(struct pci_dev *dev, enum ich_chipset ich_generation,
+						   uint8_t bios_cntl)
+{
+	return enable_flash_ich_bios_cntl_common(ich_generation, NULL, dev, bios_cntl);
+}
+
+static int enable_flash_ich_bios_cntl_memmapped(enum ich_chipset ich_generation, void *addr)
+{
+	return enable_flash_ich_bios_cntl_common(ich_generation, addr, NULL, 0);
+}
+
 static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich_generation)
 {
 	uint8_t fwh_sel1 = 0, fwh_sel2 = 0, fwh_dec_en_lo = 0, fwh_dec_en_hi = 0; /* silence compilers */
 	bool implemented = 0;
+	void *ilb = NULL; /* Only for Baytrail */
 	switch (ich_generation) {
 	case CHIPSET_ICH:
 		/* FIXME: Unlike later chipsets, ICH and ICH-0 do only support mapping of the top-most 4MB
@@ -373,6 +402,18 @@ static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich
 	case CHIPSET_CENTERTON:
 		/* FIXME: Similar to above FWH_DEC_EN (D4h) and FWH_SEL (D0h). */
 		break;
+	case CHIPSET_BAYTRAIL: {
+		uint32_t ilb_base = pci_read_long(dev, 0x50) & 0xfffffe00; /* bits 31:9 */
+		if (ilb_base == 0) {
+			msg_perr("Error: Invalid ILB_BASE_ADDRESS\n");
+			return ERROR_FATAL;
+		}
+		ilb = rphysmap("BYT IBASE", ilb_base, 512);
+		fwh_sel1 = 0x18;
+		fwh_dec_en_lo = 0xd8;
+		fwh_dec_en_hi = 0xd9;
+		break;
+	}
 	case CHIPSET_ICH6:
 	case CHIPSET_ICH7:
 	default: /* Future version might behave the same */
@@ -397,17 +438,27 @@ static int enable_flash_ich_fwh_decode(struct pci_dev *dev, enum ich_chipset ich
 			msg_perr("Error: fwh_idsel= specified, but value could not be converted.\n");
 			goto idsel_garbage_out;
 		}
-		if (fwh_idsel & 0xffff000000000000ULL) {
+		uint64_t fwh_mask = 0xffffffff;
+		if (fwh_sel2 > 0)
+			fwh_mask |= (0xffffUL << 32);
+		if (fwh_idsel & ~fwh_mask) {
 			msg_perr("Error: fwh_idsel= specified, but value had unused bits set.\n");
 			goto idsel_garbage_out;
 		}
-		uint64_t fwh_idsel_old = pci_read_long(dev, fwh_sel1);
-		fwh_idsel_old <<= 16;
-		fwh_idsel_old |= pci_read_word(dev, fwh_sel2);
-		msg_pdbg("\nSetting IDSEL from 0x%012" PRIx64 " to 0x%012" PRIx64 " for top 16 MB.",
+		uint64_t fwh_idsel_old;
+		if (ich_generation == CHIPSET_BAYTRAIL) {
+			fwh_idsel_old = mmio_readl(ilb + fwh_sel1);
+			rmmio_writel(fwh_idsel, ilb + fwh_sel1);
+		} else {
+			fwh_idsel_old = pci_read_long(dev, fwh_sel1) << 16;
+			rpci_write_long(dev, fwh_sel1, (fwh_idsel >> 16) & 0xffffffff);
+			if (fwh_sel2 > 0) {
+				fwh_idsel_old |= pci_read_word(dev, fwh_sel2);
+				rpci_write_word(dev, fwh_sel2, fwh_idsel & 0xffff);
+			}
+		}
+		msg_pdbg("Setting IDSEL from 0x%012" PRIx64 " to 0x%012" PRIx64 " for top 16 MB.\n",
 			 fwh_idsel_old, fwh_idsel);
-		rpci_write_long(dev, fwh_sel1, (fwh_idsel >> 16) & 0xffffffff);
-		rpci_write_word(dev, fwh_sel2, fwh_idsel & 0xffff);
 		/* FIXME: Decode settings are not changed. */
 	} else if (idsel) {
 		msg_perr("Error: fwh_idsel= specified, but no value given.\n");
@@ -418,7 +469,7 @@ idsel_garbage_out:
 	free(idsel);
 
 	if (!implemented) {
-		msg_pdbg2("FWH IDSEL handling is not implemented on this chipset.");
+		msg_pdbg2("FWH IDSEL handling is not implemented on this chipset.\n");
 		return 0;
 	}
 
@@ -429,12 +480,17 @@ idsel_garbage_out:
 	 */
 	int max_decode_fwh_idsel = 0, max_decode_fwh_decode = 0;
 	bool contiguous = 1;
-	uint32_t fwh_conf = pci_read_long(dev, fwh_sel1);
+	uint32_t fwh_conf;
+	if (ich_generation == CHIPSET_BAYTRAIL)
+		fwh_conf = mmio_readl(ilb + fwh_sel1);
+	else
+		fwh_conf = pci_read_long(dev, fwh_sel1);
+
 	int i;
 	/* FWH_SEL1 */
 	for (i = 7; i >= 0; i--) {
 		int tmp = (fwh_conf >> (i * 4)) & 0xf;
-		msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x",
+		msg_pdbg("0x%08x/0x%08x FWH IDSEL: 0x%x\n",
 			 (0x1ff8 + i) * 0x80000,
 			 (0x1ff0 + i) * 0x80000,
 			 tmp);
@@ -444,28 +500,31 @@ idsel_garbage_out:
 			contiguous = 0;
 		}
 	}
-	/* FWH_SEL2 */
-	fwh_conf = pci_read_word(dev, fwh_sel2);
-	for (i = 3; i >= 0; i--) {
-		int tmp = (fwh_conf >> (i * 4)) & 0xf;
-		msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x",
-			 (0xff4 + i) * 0x100000,
-			 (0xff0 + i) * 0x100000,
-			 tmp);
-		if ((tmp == 0) && contiguous) {
-			max_decode_fwh_idsel = (8 - i) * 0x100000;
-		} else {
-			contiguous = 0;
+
+	if (fwh_sel2 > 0) {
+		/* FWH_SEL2 */
+		fwh_conf = pci_read_word(dev, fwh_sel2);
+		for (i = 3; i >= 0; i--) {
+			int tmp = (fwh_conf >> (i * 4)) & 0xf;
+			msg_pdbg("0x%08x/0x%08x FWH IDSEL: 0x%x\n",
+				 (0xff4 + i) * 0x100000,
+				 (0xff0 + i) * 0x100000,
+				 tmp);
+			if ((tmp == 0) && contiguous) {
+				max_decode_fwh_idsel = (8 - i) * 0x100000;
+			} else {
+				contiguous = 0;
+			}
 		}
+		contiguous = 1;
 	}
-	contiguous = 1;
 	/* FWH_DEC_EN1 */
 	fwh_conf = pci_read_byte(dev, fwh_dec_en_hi);
 	fwh_conf <<= 8;
 	fwh_conf |= pci_read_byte(dev, fwh_dec_en_lo);
 	for (i = 7; i >= 0; i--) {
 		int tmp = (fwh_conf >> (i + 0x8)) & 0x1;
-		msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled",
+		msg_pdbg("0x%08x/0x%08x FWH decode %sabled\n",
 			 (0x1ff8 + i) * 0x80000,
 			 (0x1ff0 + i) * 0x80000,
 			 tmp ? "en" : "dis");
@@ -477,7 +536,7 @@ idsel_garbage_out:
 	}
 	for (i = 3; i >= 0; i--) {
 		int tmp = (fwh_conf >> i) & 0x1;
-		msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled",
+		msg_pdbg("0x%08x/0x%08x FWH decode %sabled\n",
 			 (0xff4 + i) * 0x100000,
 			 (0xff0 + i) * 0x100000,
 			 tmp ? "en" : "dis");
@@ -488,7 +547,7 @@ idsel_garbage_out:
 		}
 	}
 	max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode);
-	msg_pdbg("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh);
+	msg_pdbg("Maximum FWH chip size: 0x%x bytes\n", max_rom_decode.fwh);
 
 	return 0;
 }
@@ -502,7 +561,7 @@ static int enable_flash_ich_fwh(struct pci_dev *dev, enum ich_chipset ich_genera
 		return err;
 
 	internal_buses_supported = BUS_FWH;
-	return enable_flash_ich_bios_cntl(dev, ich_generation, bios_cntl);
+	return enable_flash_ich_bios_cntl_config_space(dev, ich_generation, bios_cntl);
 }
 
 static int enable_flash_ich0(struct pci_dev *dev, const char *name)
@@ -525,14 +584,18 @@ static int enable_flash_poulsbo(struct pci_dev *dev, const char *name)
 	return enable_flash_ich_fwh(dev, CHIPSET_POULSBO, 0xd8);
 }
 
-static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
+static void enable_flash_ich_handle_gcs(struct pci_dev *dev, enum ich_chipset ich_generation, uint32_t gcs, bool top_swap)
 {
+	msg_pdbg("GCS = 0x%x: ", gcs);
+
+	msg_pdbg("BIOS Interface Lock-Down: %sabled, ", (gcs & 0x1) ? "en" : "dis");
+
 	static const char *const straps_names_EP80579[] = { "SPI", "reserved", "reserved", "LPC" };
 	static const char *const straps_names_ich7_nm10[] = { "reserved", "SPI", "PCI", "LPC" };
 	static const char *const straps_names_tunnel_creek[] = { "SPI", "LPC" };
 	static const char *const straps_names_ich8910[] = { "SPI", "SPI", "PCI", "LPC" };
 	static const char *const straps_names_pch567[] = { "LPC", "reserved", "PCI", "SPI" };
-	static const char *const straps_names_pch8[] = { "LPC", "reserved", "reserved", "SPI" };
+	static const char *const straps_names_pch89_baytrail[] = { "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" };
 
@@ -561,7 +624,9 @@ static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_genera
 		straps_names = straps_names_pch567;
 		break;
 	case CHIPSET_8_SERIES_LYNX_POINT:
-		straps_names = straps_names_pch8;
+	case CHIPSET_9_SERIES_WILDCAT_POINT:
+	case CHIPSET_BAYTRAIL:
+		straps_names = straps_names_pch89_baytrail;
 		break;
 	case CHIPSET_8_SERIES_LYNX_POINT_LP:
 		straps_names = straps_names_pch8_lp;
@@ -576,40 +641,40 @@ static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_genera
 		break;
 	}
 
-	/* Get physical address of Root Complex Register Block */
-	uint32_t rcra = pci_read_long(dev, 0xf0) & 0xffffc000;
-	msg_pdbg("Root Complex Register Block address = 0x%x\n", rcra);
-
-	/* Map RCBA to virtual memory */
-	void *rcrb = rphysmap("ICH RCRB", rcra, 0x4000);
-	if (rcrb == ERROR_PTR)
-		return ERROR_FATAL;
-
-	uint32_t 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;
 		break;
 	case CHIPSET_8_SERIES_LYNX_POINT_LP:
-	case CHIPSET_8_SERIES_WELLSBURG: // FIXME: check datasheet
-		/* Lynx Point LP uses a single bit for GCS */
+		/* Lynx Point LP uses a single bit for BBS */
 		bbs = (gcs >> 10) & 0x1;
 		break;
 	default:
-		/* Older chipsets use two bits for GCS */
+		/* Other chipsets use two bits for BBS */
 		bbs = (gcs >> 10) & 0x3;
 		break;
 	}
 	msg_pdbg("Boot BIOS Straps: 0x%x (%s)\n", bbs, straps_names[bbs]);
 
-	if (ich_generation != CHIPSET_TUNNEL_CREEK && ich_generation != CHIPSET_CENTERTON) {
-		uint8_t buc = mmio_readb(rcrb + 0x3414);
-		msg_pdbg("Top Swap : %s\n", (buc & 1) ? "enabled (A16(+) inverted)" : "not enabled");
-	}
+	/* Centerton has its TS bit in [GPE0BLK] + 0x30 while the exact location for Tunnel Creek is unknown. */
+	if (ich_generation != CHIPSET_TUNNEL_CREEK && ich_generation != CHIPSET_CENTERTON)
+		msg_pdbg("Top Swap : %s\n", (top_swap) ? "enabled (A16(+) inverted)" : "not enabled");
+}
+
+static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
+{
+
+	/* Get physical address of Root Complex Register Block */
+	uint32_t rcra = pci_read_long(dev, 0xf0) & 0xffffc000;
+	msg_pdbg("Root Complex Register Block address = 0x%x\n", rcra);
+
+	/* Map RCBA to virtual memory */
+	void *rcrb = rphysmap("ICH RCRB", rcra, 0x4000);
+	if (rcrb == ERROR_PTR)
+		return ERROR_FATAL;
+
+	enable_flash_ich_handle_gcs(dev, ich_generation, mmio_readl(rcrb + 0x3410), mmio_readb(rcrb + 0x3414));
 
 	/* Handle FWH-related parameters and initialization */
 	int ret_fwh = enable_flash_ich_fwh(dev, ich_generation, bios_cntl);
@@ -619,6 +684,7 @@ static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_genera
 	/* SPIBAR is at RCRB+0x3020 for ICH[78], Tunnel Creek and Centerton, and RCRB+0x3800 for ICH9. */
 	uint16_t spibar_offset;
 	switch (ich_generation) {
+	case CHIPSET_BAYTRAIL:
 	case CHIPSET_ICH_UNKNOWN:
 		return ERROR_FATAL;
 	case CHIPSET_ICH7:
@@ -712,6 +778,63 @@ static int enable_flash_pch8_wb(struct pci_dev *dev, const char *name)
 	return enable_flash_ich_spi(dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc);
 }
 
+/* Wildcat Point */
+static int enable_flash_pch9(struct pci_dev *dev, const char *name)
+{
+	return enable_flash_ich_spi(dev, CHIPSET_9_SERIES_WILDCAT_POINT, 0xdc);
+}
+
+/* Silvermont architecture: Bay Trail(-T/-I), Avoton/Rangeley.
+ * These have a distinctly different behavior compared to other Intel chipsets and hence are handled separately.
+ *
+ * Differences include:
+ *	- RCBA at LPC config 0xF0 too but mapped range is only 4 B long instead of 16 kB.
+ *	- GCS at [RCRB] + 0 (instead of [RCRB] + 0x3410).
+ *	- TS (Top Swap) in GCS (instead of [RCRB] + 0x3414).
+ *	- SPIBAR (coined SBASE) at LPC config 0x54 (instead of [RCRB] + 0x3800).
+ *	- BIOS_CNTL (coined BCR) at [SPIBAR] + 0xFC (instead of LPC config 0xDC).
+ */
+static int enable_flash_silvermont(struct pci_dev *dev, const char *name)
+{
+	enum ich_chipset ich_generation = CHIPSET_BAYTRAIL;
+
+	/* Get physical address of Root Complex Register Block */
+	uint32_t rcba = pci_read_long(dev, 0xf0) & 0xfffffc00;
+	msg_pdbg("Root Complex Register Block address = 0x%x\n", rcba);
+
+	/* Handle GCS (in RCRB) */
+	void *rcrb = physmap("BYT RCRB", rcba, 4);
+	uint32_t gcs = mmio_readl(rcrb + 0);
+	enable_flash_ich_handle_gcs(dev, ich_generation, gcs, gcs & 0x2);
+	physunmap(rcrb, 4);
+
+	/* Handle fwh_idsel parameter */
+	int ret = enable_flash_ich_fwh_decode(dev, ich_generation);
+	if (ret != ERROR_FATAL)
+		return ret;
+
+	internal_buses_supported = BUS_FWH;
+
+	/* Get physical address of SPI Base Address and map it */
+	uint32_t sbase = pci_read_long(dev, 0x54) & 0xfffffe00;
+	msg_pdbg("SPI_BASE_ADDRESS = 0x%x\n", sbase);
+	void *spibar = rphysmap("BYT SBASE", sbase, 512); /* Last defined address on Bay Trail is 0x100 */
+
+	/* Enable Flash Writes.
+	 * Silvermont-based: BCR at SBASE + 0xFC (some bits of BCR are also accessible via BC at IBASE + 0x1C).
+	 */
+	enable_flash_ich_bios_cntl_memmapped(ich_generation, spibar + 0xFC);
+
+	int ret_spi = ich_init_spi(dev, spibar, ich_generation);
+	if (ret_spi == ERROR_FATAL)
+		return ret_spi;
+
+	if (ret || ret_spi)
+		return ERROR_NONFATAL;
+
+	return 0;
+}
+
 static int via_no_byte_merge(struct pci_dev *dev, const char *name)
 {
 	uint8_t val;
@@ -1468,6 +1591,10 @@ const struct penable chipset_enables[] = {
 	{0x1166, 0x0205, OK,  "Broadcom", "HT-1000",			enable_flash_ht1000},
 	{0x17f3, 0x6030, OK,  "RDC", "R8610/R3210",			enable_flash_rdc_r8610},
 	{0x8086, 0x0c60, NT,  "Intel", "S12x0",				enable_flash_s12x0},
+	{0x8086, 0x0f1c, NT,  "Intel", "Bay Trail",			enable_flash_silvermont},
+	{0x8086, 0x0f1d, NT,  "Intel", "Bay Trail",			enable_flash_silvermont},
+	{0x8086, 0x0f1e, NT,  "Intel", "Bay Trail",			enable_flash_silvermont},
+	{0x8086, 0x0f1f, NT,  "Intel", "Bay Trail",			enable_flash_silvermont},
 	{0x8086, 0x122e, OK,  "Intel", "PIIX",				enable_flash_piix4},
 	{0x8086, 0x1234, NT,  "Intel", "MPIIX",				enable_flash_piix4},
 	{0x8086, 0x1c44, DEP, "Intel", "Z68",				enable_flash_pch6},
@@ -1502,7 +1629,11 @@ const struct penable chipset_enables[] = {
 	{0x8086, 0x1e5d, NT,  "Intel", "HM75",				enable_flash_pch7},
 	{0x8086, 0x1e5e, NT,  "Intel", "HM70",				enable_flash_pch7},
 	{0x8086, 0x1e5f, DEP, "Intel", "NM70",				enable_flash_pch7},
-	{0x8086, 0x2310, NT,  "Intel", "DH89xxCC",			enable_flash_pch7},
+	{0x8086, 0x1f38, NT,  "Intel", "Avoton/Rangeley",		enable_flash_silvermont},
+	{0x8086, 0x1f39, NT,  "Intel", "Avoton/Rangeley",		enable_flash_silvermont},
+	{0x8086, 0x1f3a, NT,  "Intel", "Avoton/Rangeley",		enable_flash_silvermont},
+	{0x8086, 0x1f3b, NT,  "Intel", "Avoton/Rangeley",		enable_flash_silvermont},
+	{0x8086, 0x2310, NT,  "Intel", "DH89xxCC (Cave Creek)",		enable_flash_pch7},
 	{0x8086, 0x2390, NT,  "Intel", "Coleto Creek",			enable_flash_pch7},
 	{0x8086, 0x2410, OK,  "Intel", "ICH",				enable_flash_ich0},
 	{0x8086, 0x2420, OK,  "Intel", "ICH0",				enable_flash_ich0},
@@ -1564,7 +1695,7 @@ const struct penable chipset_enables[] = {
 	{0x8086, 0x7110, OK,  "Intel", "PIIX4/4E/4M",			enable_flash_piix4},
 	{0x8086, 0x7198, OK,  "Intel", "440MX",				enable_flash_piix4},
 	{0x8086, 0x8119, OK,  "Intel", "SCH Poulsbo",			enable_flash_poulsbo},
-	{0x8086, 0x8186, OK,  "Intel", "Atom E6xx(T)/Tunnel Creek",	enable_flash_tunnelcreek},
+	{0x8086, 0x8186, OK,  "Intel", "Atom E6xx(T) (Tunnel Creek)",	enable_flash_tunnelcreek},
 	{0x8086, 0x8c40, NT,  "Intel", "Lynx Point",			enable_flash_pch8},
 	{0x8086, 0x8c41, NT,  "Intel", "Lynx Point Mobile Eng. Sample",	enable_flash_pch8},
 	{0x8086, 0x8c42, NT,  "Intel", "Lynx Point Desktop Eng. Sample",enable_flash_pch8},
@@ -1633,6 +1764,14 @@ const struct penable chipset_enables[] = {
  	{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},
+	{0x8086, 0x9cc1, NT,  "Intel", "Haswell U Sample",		enable_flash_pch9},
+	{0x8086, 0x9cc2, NT,  "Intel", "Broadwell U Sample",		enable_flash_pch9},
+	{0x8086, 0x9cc3, NT,  "Intel", "Broadwell U Premium",		enable_flash_pch9},
+	{0x8086, 0x9cc5, NT,  "Intel", "Broadwell U Base",		enable_flash_pch9},
+	{0x8086, 0x9cc6, NT,  "Intel", "Broadwell Y Sample",		enable_flash_pch9},
+	{0x8086, 0x9cc7, NT,  "Intel", "Broadwell Y Premium",		enable_flash_pch9},
+	{0x8086, 0x9cc9, NT,  "Intel", "Broadwell Y Base",		enable_flash_pch9},
+	{0x8086, 0x9ccb, NT,  "Intel", "Broadwell H",			enable_flash_pch9},
 #endif
 	{0},
 };
diff --git a/ichspi.c b/ichspi.c
index 190ad5a..1bce06f 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -612,7 +612,8 @@ static void ich_set_bbar(uint32_t min_addr)
 		bbar_off = 0x50;
 		break;
 	case CHIPSET_ICH8:
-		msg_perr("BBAR offset is unknown on ICH8!\n");
+	case CHIPSET_BAYTRAIL:
+		msg_pdbg("BBAR offset is unknown on ICH8!\n");
 		return;
 	case CHIPSET_ICH9:
 	default:		/* Future version might behave the same */
@@ -1731,9 +1732,12 @@ int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_gen)
 			msg_pdbg("VSCC: ");
 			prettyprint_ich_reg_vscc(tmp, MSG_DEBUG);
 		} else {
-			ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR);
-			msg_pdbg("0xA0: 0x%08x (BBAR)\n",
-				     ichspi_bbar);
+			if (ich_generation != CHIPSET_BAYTRAIL && desc_valid) {
+				ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR);
+				msg_pdbg("0xA0: 0x%08x (BBAR)\n",
+					     ichspi_bbar);
+				ich_set_bbar(0);
+			}
 
 			if (desc_valid) {
 				tmp = mmio_readl(ich_spibar + ICH9_REG_LVSCC);
@@ -1749,10 +1753,8 @@ int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_gen)
 				tmp = mmio_readl(ich_spibar + ICH9_REG_FPB);
 				msg_pdbg("0xD0: 0x%08x (FPB)\n", tmp);
 			}
-			ich_set_bbar(0);
 		}
 
-		msg_pdbg("\n");
 		if (desc_valid) {
 			if (read_ich_descriptors_via_fdo(ich_spibar, &desc) ==
 			    ICH_RET_OK)
diff --git a/programmer.h b/programmer.h
index b0df2ba..d6ab254 100644
--- a/programmer.h
+++ b/programmer.h
@@ -594,6 +594,8 @@ enum ich_chipset {
 	CHIPSET_8_SERIES_LYNX_POINT,
 	CHIPSET_8_SERIES_LYNX_POINT_LP,
 	CHIPSET_8_SERIES_WELLSBURG,
+	CHIPSET_9_SERIES_WILDCAT_POINT,
+	CHIPSET_BAYTRAIL, /* Actually all with Silvermont architecture: Bay Trail, Avoton/Rangeley */
 };
 
 /* ichspi.c */
-- 
Kind regards, Stefan Tauner





More information about the flashrom mailing list