xref: /aosp_15_r20/external/flashrom/chipset_enable.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1 /*
2  * This file is part of the flashrom project.
3  *
4  * Copyright (C) 2000 Silicon Integrated System Corporation
5  * Copyright (C) 2005-2009 coresystems GmbH
6  * Copyright (C) 2006 Uwe Hermann <[email protected]>
7  * Copyright (C) 2007,2008,2009 Carl-Daniel Hailfinger
8  * Copyright (C) 2009 Kontron Modular Computers GmbH
9  * Copyright (C) 2011, 2012 Stefan Tauner
10  * Copyright (C) 2017 secunet Security Networks AG
11  * (Written by Nico Huber <[email protected]> for secunet)
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; version 2 of the License.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  */
22 
23 /*
24  * Contains the chipset specific flash enables.
25  */
26 
27 #include <stdbool.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <inttypes.h>
32 #include <errno.h>
33 #include "flash.h"
34 #include "programmer.h"
35 #include "hwaccess_physmap.h"
36 #include "platform/pci.h"
37 
38 #define NOT_DONE_YET 1
39 
40 #if defined(__i386__) || defined(__x86_64__)
41 
42 #include "hwaccess_x86_io.h"
43 #include "hwaccess_x86_msr.h"
44 
enable_flash_ali_m1533(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)45 static int enable_flash_ali_m1533(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
46 {
47 	uint8_t tmp;
48 
49 	/*
50 	 * ROM Write enable, 0xFFFC0000-0xFFFDFFFF and
51 	 * 0xFFFE0000-0xFFFFFFFF ROM select enable.
52 	 */
53 	tmp = pci_read_byte(dev, 0x47);
54 	tmp |= 0x46;
55 	rpci_write_byte(dev, 0x47, tmp);
56 
57 	return 0;
58 }
59 
enable_flash_rdc_r8610(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)60 static int enable_flash_rdc_r8610(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
61 {
62 	uint8_t tmp;
63 
64 	/* enable ROMCS for writes */
65 	tmp = pci_read_byte(dev, 0x43);
66 	tmp |= 0x80;
67 	pci_write_byte(dev, 0x43, tmp);
68 
69 	/* read the bootstrapping register */
70 	tmp = pci_read_byte(dev, 0x40) & 0x3;
71 	switch (tmp) {
72 	case 3:
73 		internal_buses_supported &= BUS_FWH;
74 		break;
75 	case 2:
76 		internal_buses_supported &= BUS_LPC;
77 		break;
78 	default:
79 		internal_buses_supported &= BUS_PARALLEL;
80 		break;
81 	}
82 
83 	return 0;
84 }
85 
enable_flash_sis85c496(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)86 static int enable_flash_sis85c496(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
87 {
88 	uint8_t tmp;
89 
90 	tmp = pci_read_byte(dev, 0xd0);
91 	tmp |= 0xf8;
92 	rpci_write_byte(dev, 0xd0, tmp);
93 
94 	return 0;
95 }
96 
enable_flash_sis_mapping(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)97 static int enable_flash_sis_mapping(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
98 {
99 	#define SIS_MAPREG 0x40
100 	uint8_t new, newer;
101 
102 	/* Extended BIOS enable = 1, Lower BIOS Enable = 1 */
103 	/* This is 0xFFF8000~0xFFFF0000 decoding on SiS 540/630. */
104 	new = pci_read_byte(dev, SIS_MAPREG);
105 	new &= (~0x04); /* No idea why we clear bit 2. */
106 	new |= 0xb; /* 0x3 for some chipsets, bit 7 seems to be don't care. */
107 	rpci_write_byte(dev, SIS_MAPREG, new);
108 	newer = pci_read_byte(dev, SIS_MAPREG);
109 	if (newer != new) { /* FIXME: share this with other code? */
110 		msg_pinfo("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n",
111 			  SIS_MAPREG, new, name);
112 		msg_pinfo("Stuck at 0x%02x.\n", newer);
113 		return -1;
114 	}
115 	return 0;
116 }
117 
find_southbridge(uint16_t vendor,const char * name)118 static struct pci_dev *find_southbridge(uint16_t vendor, const char *name)
119 {
120 	struct pci_dev *sbdev;
121 
122 	sbdev = pcidev_find_vendorclass(vendor, 0x0601);
123 	if (!sbdev)
124 		sbdev = pcidev_find_vendorclass(vendor, 0x0680);
125 	if (!sbdev)
126 		sbdev = pcidev_find_vendorclass(vendor, 0x0000);
127 	if (!sbdev)
128 		msg_perr("No southbridge found for %s!\n", name);
129 	if (sbdev)
130 		msg_pdbg("Found southbridge %04x:%04x at %02x:%02x:%01x\n",
131 			 sbdev->vendor_id, sbdev->device_id,
132 			 sbdev->bus, sbdev->dev, sbdev->func);
133 	return sbdev;
134 }
135 
enable_flash_sis501(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)136 static int enable_flash_sis501(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
137 {
138 	uint8_t tmp;
139 	int ret = 0;
140 	struct pci_dev *sbdev;
141 
142 	sbdev = find_southbridge(dev->vendor_id, name);
143 	if (!sbdev)
144 		return -1;
145 
146 	ret = enable_flash_sis_mapping(cfg, sbdev, name);
147 
148 	tmp = sio_read(0x22, 0x80);
149 	tmp &= (~0x20);
150 	tmp |= 0x4;
151 	sio_write(0x22, 0x80, tmp);
152 
153 	tmp = sio_read(0x22, 0x70);
154 	tmp &= (~0x20);
155 	tmp |= 0x4;
156 	sio_write(0x22, 0x70, tmp);
157 
158 	return ret;
159 }
160 
enable_flash_sis5511(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)161 static int enable_flash_sis5511(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
162 {
163 	uint8_t tmp;
164 	int ret = 0;
165 	struct pci_dev *sbdev;
166 
167 	sbdev = find_southbridge(dev->vendor_id, name);
168 	if (!sbdev)
169 		return -1;
170 
171 	ret = enable_flash_sis_mapping(cfg, sbdev, name);
172 
173 	tmp = sio_read(0x22, 0x50);
174 	tmp &= (~0x20);
175 	tmp |= 0x4;
176 	sio_write(0x22, 0x50, tmp);
177 
178 	return ret;
179 }
180 
enable_flash_sis5x0(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name,uint8_t dis_mask,uint8_t en_mask)181 static int enable_flash_sis5x0(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name, uint8_t dis_mask, uint8_t en_mask)
182 {
183 	#define SIS_REG 0x45
184 	uint8_t new, newer;
185 	int ret = 0;
186 	struct pci_dev *sbdev;
187 
188 	sbdev = find_southbridge(dev->vendor_id, name);
189 	if (!sbdev)
190 		return -1;
191 
192 	ret = enable_flash_sis_mapping(cfg, sbdev, name);
193 
194 	new = pci_read_byte(sbdev, SIS_REG);
195 	new &= (~dis_mask);
196 	new |= en_mask;
197 	rpci_write_byte(sbdev, SIS_REG, new);
198 	newer = pci_read_byte(sbdev, SIS_REG);
199 	if (newer != new) { /* FIXME: share this with other code? */
200 		msg_pinfo("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n", SIS_REG, new, name);
201 		msg_pinfo("Stuck at 0x%02x\n", newer);
202 		ret = -1;
203 	}
204 
205 	return ret;
206 }
207 
enable_flash_sis530(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)208 static int enable_flash_sis530(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
209 {
210 	return enable_flash_sis5x0(cfg, dev, name, 0x20, 0x04);
211 }
212 
enable_flash_sis540(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)213 static int enable_flash_sis540(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
214 {
215 	return enable_flash_sis5x0(cfg, dev, name, 0x80, 0x40);
216 }
217 
218 /* Datasheet:
219  *   - Name: 82371AB PCI-TO-ISA / IDE XCELERATOR (PIIX4)
220  *   - URL: http://www.intel.com/design/intarch/datashts/290562.htm
221  *   - PDF: http://www.intel.com/design/intarch/datashts/29056201.pdf
222  *   - Order Number: 290562-001
223  */
enable_flash_piix4(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)224 static int enable_flash_piix4(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
225 {
226 	uint16_t old, new;
227 	uint16_t xbcs = 0x4e;	/* X-Bus Chip Select register. */
228 
229 	internal_buses_supported &= BUS_PARALLEL;
230 
231 	old = pci_read_word(dev, xbcs);
232 
233 	/* Set bit 9: 1-Meg Extended BIOS Enable (PCI master accesses to
234 	 *            FFF00000-FFF7FFFF are forwarded to ISA).
235 	 *            Note: This bit is reserved on PIIX/PIIX3/MPIIX.
236 	 * Set bit 7: Extended BIOS Enable (PCI master accesses to
237 	 *            FFF80000-FFFDFFFF are forwarded to ISA).
238 	 * Set bit 6: Lower BIOS Enable (PCI master, or ISA master accesses to
239 	 *            the lower 64-Kbyte BIOS block (E0000-EFFFF) at the top
240 	 *            of 1 Mbyte, or the aliases at the top of 4 Gbyte
241 	 *            (FFFE0000-FFFEFFFF) result in the generation of BIOSCS#.
242 	 * Note: Accesses to FFFF0000-FFFFFFFF are always forwarded to ISA.
243 	 * Set bit 2: BIOSCS# Write Enable (1=enable, 0=disable).
244 	 */
245 	if (dev->device_id == 0x122e || dev->device_id == 0x7000
246 	    || dev->device_id == 0x1234)
247 		new = old | 0x00c4; /* PIIX/PIIX3/MPIIX: Bit 9 is reserved. */
248 	else
249 		new = old | 0x02c4;
250 
251 	if (new == old)
252 		return 0;
253 
254 	rpci_write_word(dev, xbcs, new);
255 
256 	if (pci_read_word(dev, xbcs) != new) { /* FIXME: share this with other code? */
257 		msg_pinfo("Setting register 0x%04x to 0x%04x on %s failed (WARNING ONLY).\n", xbcs, new, name);
258 		return -1;
259 	}
260 
261 	return 0;
262 }
263 
264 /* Handle BIOS_CNTL (aka. BCR). Disable locks and enable writes. The register can either be in PCI config space
265  * at the offset given by 'bios_cntl' or at the memory-mapped address 'addr'.
266  *
267  * Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, in Poulsbo, Tunnel Creek and other Atom
268  * chipsets/SoCs it is even 32b, but just treating it as 8 bit wide seems to work fine in practice. */
enable_flash_ich_bios_cntl_common(enum ich_chipset ich_generation,void * addr,struct pci_dev * dev,uint8_t bios_cntl)269 static int enable_flash_ich_bios_cntl_common(enum ich_chipset ich_generation, void *addr,
270 					     struct pci_dev *dev, uint8_t bios_cntl)
271 {
272 	uint8_t old, new, wanted;
273 
274 	switch (ich_generation) {
275 	case CHIPSET_ICH_UNKNOWN:
276 		return ERROR_FLASHROM_FATAL;
277 	/* Non-SPI-capable */
278 	case CHIPSET_ICH:
279 	case CHIPSET_ICH2345:
280 		break;
281 	/* Some Atom chipsets are special: The second byte of BIOS_CNTL (D9h) contains a prefetch bit similar to
282 	 * what other SPI-capable chipsets have at DCh. Others like Bay Trail use a memmapped register.
283 	 * The Tunnel Creek datasheet contains a lot of details about the SPI controller, among other things it
284 	 * mentions that the prefetching and caching does only happen for direct memory reads.
285 	 * Therefore - at least for Tunnel Creek - it should not matter to flashrom because we use the
286 	 * programmed access only and not memory mapping. */
287 	case CHIPSET_TUNNEL_CREEK:
288 	case CHIPSET_POULSBO:
289 	case CHIPSET_CENTERTON:
290 		old = pci_read_byte(dev, bios_cntl + 1);
291 		msg_pdbg("BIOS Prefetch Enable: %sabled, ", (old & 1) ? "en" : "dis");
292 		break;
293 	case CHIPSET_BAYTRAIL:
294 	case CHIPSET_ICH7:
295 	default: /* Future version might behave the same */
296 		if (ich_generation == CHIPSET_BAYTRAIL)
297 			old = (mmio_readl(addr) >> 2) & 0x3;
298 		else
299 			old = (pci_read_byte(dev, bios_cntl) >> 2) & 0x3;
300 		msg_pdbg("SPI Read Configuration: ");
301 		if (old == 3)
302 			msg_pdbg("invalid prefetching/caching settings, ");
303 		else
304 			msg_pdbg("prefetching %sabled, caching %sabled, ",
305 				     (old & 0x2) ? "en" : "dis",
306 				     (old & 0x1) ? "dis" : "en");
307 	}
308 
309 	if (ich_generation == CHIPSET_BAYTRAIL)
310 		wanted = old = mmio_readl(addr);
311 	else
312 		wanted = old = pci_read_byte(dev, bios_cntl);
313 
314 	/*
315 	 * Quote from the 6 Series datasheet (Document Number: 324645-004):
316 	 * "Bit 5: SMM BIOS Write Protect Disable (SMM_BWP)
317 	 * 1 = BIOS region SMM protection is enabled.
318 	 * The BIOS Region is not writable unless all processors are in SMM."
319 	 * In earlier chipsets this bit is reserved.
320 	 *
321 	 * Try to unset it in any case.
322 	 * It won't hurt and makes sense in some cases according to Stefan Reinauer.
323 	 *
324 	 * At least in Centerton aforementioned bit is located at bit 7. It is unspecified in all other Atom
325 	 * and Desktop chipsets before Ibex Peak/5 Series, but we reset bit 5 anyway.
326 	 */
327 	int smm_bwp_bit;
328 	if (ich_generation == CHIPSET_CENTERTON)
329 		smm_bwp_bit = 7;
330 	else
331 		smm_bwp_bit = 5;
332 	wanted &= ~(1 << smm_bwp_bit);
333 
334 	/* Tunnel Creek has a cache disable at bit 2 of the lowest BIOS_CNTL byte. */
335 	if (ich_generation == CHIPSET_TUNNEL_CREEK)
336 		wanted |= (1 << 2);
337 
338 	wanted |= (1 << 0); /* Set BIOS Write Enable */
339 	wanted &= ~(1 << 1); /* Disable lock (futile) */
340 
341 	/* Only write the register if it's necessary */
342 	if (wanted != old) {
343 		if (ich_generation == CHIPSET_BAYTRAIL) {
344 			rmmio_writel(wanted, addr);
345 			new = mmio_readl(addr);
346 		} else {
347 			rpci_write_byte(dev, bios_cntl, wanted);
348 			new = pci_read_byte(dev, bios_cntl);
349 		}
350 	} else
351 		new = old;
352 
353 	msg_pdbg("\nBIOS_CNTL = 0x%02x: ", new);
354 	msg_pdbg("BIOS Lock Enable: %sabled, ", (new & (1 << 1)) ? "en" : "dis");
355 	msg_pdbg("BIOS Write Enable: %sabled\n", (new & (1 << 0)) ? "en" : "dis");
356 	if (new & (1 << smm_bwp_bit))
357 		msg_pwarn("Warning: BIOS region SMM protection is enabled!\n");
358 
359 	if (new != wanted)
360 		msg_pwarn("Warning: Setting BIOS Control at 0x%x from 0x%02x to 0x%02x failed.\n"
361 			  "New value is 0x%02x.\n", bios_cntl, old, wanted, new);
362 
363 	/* Return an error if we could not set the write enable only. */
364 	if (!(new & (1 << 0)))
365 		return -1;
366 
367 	return 0;
368 }
369 
enable_flash_ich_bios_cntl_config_space(struct pci_dev * dev,enum ich_chipset ich_generation,uint8_t bios_cntl)370 static int enable_flash_ich_bios_cntl_config_space(struct pci_dev *dev, enum ich_chipset ich_generation,
371 						   uint8_t bios_cntl)
372 {
373 	return enable_flash_ich_bios_cntl_common(ich_generation, NULL, dev, bios_cntl);
374 }
375 
enable_flash_ich_bios_cntl_memmapped(enum ich_chipset ich_generation,void * addr)376 static int enable_flash_ich_bios_cntl_memmapped(enum ich_chipset ich_generation, void *addr)
377 {
378 	return enable_flash_ich_bios_cntl_common(ich_generation, addr, NULL, 0);
379 }
380 
enable_flash_ich_fwh_decode(const struct programmer_cfg * cfg,struct pci_dev * dev,enum ich_chipset ich_generation)381 static int enable_flash_ich_fwh_decode(const struct programmer_cfg *cfg, struct pci_dev *dev, enum ich_chipset ich_generation)
382 {
383 	uint8_t fwh_sel1 = 0, fwh_sel2 = 0, fwh_dec_en_lo = 0, fwh_dec_en_hi = 0; /* silence compilers */
384 	bool implemented = 0;
385 	void *ilb = NULL; /* Only for Baytrail */
386 	switch (ich_generation) {
387 	case CHIPSET_ICH:
388 		/* FIXME: Unlike later chipsets, ICH and ICH-0 do only support mapping of the top-most 4MB
389 		 * and therefore do only feature FWH_DEC_EN (E3h, different default too) and FWH_SEL (E8h). */
390 		break;
391 	case CHIPSET_ICH2345:
392 		fwh_sel1 = 0xe8;
393 		fwh_sel2 = 0xee;
394 		fwh_dec_en_lo = 0xf0;
395 		fwh_dec_en_hi = 0xe3;
396 		implemented = 1;
397 		break;
398 	case CHIPSET_POULSBO:
399 	case CHIPSET_TUNNEL_CREEK:
400 		/* FIXME: Similar to ICH and ICH-0, Tunnel Creek and Poulsbo do only feature one register each,
401 		 * FWH_DEC_EN (D7h) and FWH_SEL (D0h). */
402 		break;
403 	case CHIPSET_CENTERTON:
404 		/* FIXME: Similar to above FWH_DEC_EN (D4h) and FWH_SEL (D0h). */
405 		break;
406 	case CHIPSET_BAYTRAIL: {
407 		uint32_t ilb_base = pci_read_long(dev, 0x50) & 0xfffffe00; /* bits 31:9 */
408 		if (ilb_base == 0) {
409 			msg_perr("Error: Invalid ILB_BASE_ADDRESS\n");
410 			return ERROR_FLASHROM_FATAL;
411 		}
412 		ilb = rphysmap("BYT IBASE", ilb_base, 512);
413 		fwh_sel1 = 0x18;
414 		fwh_dec_en_lo = 0xd8;
415 		fwh_dec_en_hi = 0xd9;
416 		implemented = 1;
417 		break;
418 	}
419 	case CHIPSET_ICH6:
420 	case CHIPSET_ICH7:
421 	default: /* Future version might behave the same */
422 		fwh_sel1 = 0xd0;
423 		fwh_sel2 = 0xd4;
424 		fwh_dec_en_lo = 0xd8;
425 		fwh_dec_en_hi = 0xd9;
426 		implemented = 1;
427 		break;
428 	}
429 
430 	char *idsel = extract_programmer_param_str(cfg, "fwh_idsel");
431 	if (idsel && strlen(idsel)) {
432 		if (!implemented) {
433 			msg_perr("Error: fwh_idsel= specified, but (yet) unsupported on this chipset.\n");
434 			goto idsel_garbage_out;
435 		}
436 		errno = 0;
437 		/* Base 16, nothing else makes sense. */
438 		uint64_t fwh_idsel = (uint64_t)strtoull(idsel, NULL, 16);
439 		if (errno) {
440 			msg_perr("Error: fwh_idsel= specified, but value could not be converted.\n");
441 			goto idsel_garbage_out;
442 		}
443 		uint64_t fwh_mask = 0xffffffff;
444 		if (fwh_sel2 > 0)
445 			fwh_mask |= (0xffffULL << 32);
446 		if (fwh_idsel & ~fwh_mask) {
447 			msg_perr("Error: fwh_idsel= specified, but value had unused bits set.\n");
448 			goto idsel_garbage_out;
449 		}
450 		uint64_t fwh_idsel_old;
451 		if (ich_generation == CHIPSET_BAYTRAIL) {
452 			fwh_idsel_old = mmio_readl(ilb + fwh_sel1);
453 			rmmio_writel(fwh_idsel, ilb + fwh_sel1);
454 		} else {
455 			fwh_idsel_old = (uint64_t)pci_read_long(dev, fwh_sel1) << 16;
456 			rpci_write_long(dev, fwh_sel1, (fwh_idsel >> 16) & 0xffffffff);
457 			if (fwh_sel2 > 0) {
458 				fwh_idsel_old |= pci_read_word(dev, fwh_sel2);
459 				rpci_write_word(dev, fwh_sel2, fwh_idsel & 0xffff);
460 			}
461 		}
462 		msg_pdbg("Setting IDSEL from 0x%012" PRIx64 " to 0x%012" PRIx64 " for top 16 MB.\n",
463 			 fwh_idsel_old, fwh_idsel);
464 		/* FIXME: Decode settings are not changed. */
465 	} else if (idsel) {
466 		msg_perr("Error: fwh_idsel= specified, but no value given.\n");
467 idsel_garbage_out:
468 		free(idsel);
469 		return ERROR_FLASHROM_FATAL;
470 	}
471 	free(idsel);
472 
473 	if (!implemented) {
474 		msg_pdbg2("FWH IDSEL handling is not implemented on this chipset.\n");
475 		return 0;
476 	}
477 
478 	/* Ignore all legacy ranges below 1 MB.
479 	 * We currently only support flashing the chip which responds to
480 	 * IDSEL=0. To support IDSEL!=0, flashbase and decode size calculations
481 	 * have to be adjusted.
482 	 */
483 	int max_decode_fwh_idsel = 0, max_decode_fwh_decode = 0;
484 	bool contiguous = 1;
485 	uint32_t fwh_conf;
486 	if (ich_generation == CHIPSET_BAYTRAIL)
487 		fwh_conf = mmio_readl(ilb + fwh_sel1);
488 	else
489 		fwh_conf = pci_read_long(dev, fwh_sel1);
490 
491 	int i;
492 	/* FWH_SEL1 */
493 	for (i = 7; i >= 0; i--) {
494 		int tmp = (fwh_conf >> (i * 4)) & 0xf;
495 		msg_pdbg("0x%08x/0x%08x FWH IDSEL: 0x%x\n",
496 			 (0x1ff8 + i) * 0x80000,
497 			 (0x1ff0 + i) * 0x80000,
498 			 tmp);
499 		if ((tmp == 0) && contiguous) {
500 			max_decode_fwh_idsel = (8 - i) * 0x80000;
501 		} else {
502 			contiguous = 0;
503 		}
504 	}
505 	if (fwh_sel2 > 0) {
506 		/* FWH_SEL2 */
507 		fwh_conf = pci_read_word(dev, fwh_sel2);
508 		for (i = 3; i >= 0; i--) {
509 			int tmp = (fwh_conf >> (i * 4)) & 0xf;
510 			msg_pdbg("0x%08x/0x%08x FWH IDSEL: 0x%x\n",
511 				 (0xff4 + i) * 0x100000,
512 				 (0xff0 + i) * 0x100000,
513 				 tmp);
514 			if ((tmp == 0) && contiguous) {
515 				max_decode_fwh_idsel = (8 - i) * 0x100000;
516 			} else {
517 				contiguous = 0;
518 			}
519 		}
520 	}
521 	contiguous = 1;
522 	/* FWH_DEC_EN1 */
523 	fwh_conf = pci_read_byte(dev, fwh_dec_en_hi);
524 	fwh_conf <<= 8;
525 	fwh_conf |= pci_read_byte(dev, fwh_dec_en_lo);
526 	for (i = 7; i >= 0; i--) {
527 		int tmp = (fwh_conf >> (i + 0x8)) & 0x1;
528 		msg_pdbg("0x%08x/0x%08x FWH decode %sabled\n",
529 			 (0x1ff8 + i) * 0x80000,
530 			 (0x1ff0 + i) * 0x80000,
531 			 tmp ? "en" : "dis");
532 		if ((tmp == 1) && contiguous) {
533 			max_decode_fwh_decode = (8 - i) * 0x80000;
534 		} else {
535 			contiguous = 0;
536 		}
537 	}
538 	for (i = 3; i >= 0; i--) {
539 		int tmp = (fwh_conf >> i) & 0x1;
540 		msg_pdbg("0x%08x/0x%08x FWH decode %sabled\n",
541 			 (0xff4 + i) * 0x100000,
542 			 (0xff0 + i) * 0x100000,
543 			 tmp ? "en" : "dis");
544 		if ((tmp == 1) && contiguous) {
545 			max_decode_fwh_decode = (8 - i) * 0x100000;
546 		} else {
547 			contiguous = 0;
548 		}
549 	}
550 	max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode);
551 	msg_pdbg("Maximum FWH chip size: 0x%"PRIx32" bytes\n", max_rom_decode.fwh);
552 
553 	return 0;
554 }
555 
enable_flash_ich_fwh(const struct programmer_cfg * cfg,struct pci_dev * dev,enum ich_chipset ich_generation,uint8_t bios_cntl)556 static int enable_flash_ich_fwh(const struct programmer_cfg *cfg, struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
557 {
558 	int err;
559 
560 	/* Configure FWH IDSEL decoder maps. */
561 	if ((err = enable_flash_ich_fwh_decode(cfg, dev, ich_generation)) != 0)
562 		return err;
563 
564 	internal_buses_supported &= BUS_FWH;
565 	return enable_flash_ich_bios_cntl_config_space(dev, ich_generation, bios_cntl);
566 }
567 
enable_flash_ich0(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)568 static int enable_flash_ich0(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
569 {
570 	return enable_flash_ich_fwh(cfg, dev, CHIPSET_ICH, 0x4e);
571 }
572 
enable_flash_ich2345(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)573 static int enable_flash_ich2345(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
574 {
575 	return enable_flash_ich_fwh(cfg, dev, CHIPSET_ICH2345, 0x4e);
576 }
577 
enable_flash_ich6(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)578 static int enable_flash_ich6(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
579 {
580 	return enable_flash_ich_fwh(cfg, dev, CHIPSET_ICH6, 0xdc);
581 }
582 
enable_flash_poulsbo(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)583 static int enable_flash_poulsbo(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
584 {
585 	return enable_flash_ich_fwh(cfg, dev, CHIPSET_POULSBO, 0xd8);
586 }
587 
enable_flash_ich_report_gcs(struct pci_dev * const dev,const enum ich_chipset ich_generation,const uint8_t * const rcrb)588 static enum chipbustype enable_flash_ich_report_gcs(
589 		struct pci_dev *const dev, const enum ich_chipset ich_generation, const uint8_t *const rcrb)
590 {
591 	uint32_t gcs;
592 	const char *reg_name;
593 	bool bild, top_swap;
594 
595 	switch (ich_generation) {
596 	case CHIPSET_BAYTRAIL:
597 		reg_name = "GCS";
598 		gcs = mmio_readl(rcrb + 0);
599 		bild = gcs & 1;
600 		top_swap = (gcs & 2) >> 1;
601 		break;
602 	case CHIPSET_100_SERIES_SUNRISE_POINT:
603 	case CHIPSET_C620_SERIES_LEWISBURG:
604 	case CHIPSET_C740_SERIES_EMMITSBURG:
605 	case CHIPSET_300_SERIES_CANNON_POINT:
606 	case CHIPSET_400_SERIES_COMET_POINT:
607 	case CHIPSET_500_SERIES_TIGER_POINT:
608 	case CHIPSET_600_SERIES_ALDER_POINT:
609 	case CHIPSET_700_SERIES_RAPTOR_POINT:
610 	case CHIPSET_METEOR_LAKE:
611 	case CHIPSET_PANTHER_LAKE:
612 	case CHIPSET_ELKHART_LAKE:
613 	case CHIPSET_APOLLO_LAKE:
614 	case CHIPSET_GEMINI_LAKE:
615 	case CHIPSET_JASPER_LAKE:
616 		reg_name = "BIOS_SPI_BC";
617 		gcs = pci_read_long(dev, 0xdc);
618 		bild = (gcs >> 7) & 1;
619 		top_swap = (gcs >> 4) & 1;
620 		break;
621 	default:
622 		reg_name = "GCS";
623 		gcs = mmio_readl(rcrb + 0x3410);
624 		bild = gcs & 1;
625 		top_swap = mmio_readb(rcrb + 0x3414) & 1;
626 		break;
627 	}
628 
629 	msg_pdbg("%s = 0x%"PRIx32": ", reg_name, gcs);
630 	msg_pdbg("BIOS Interface Lock-Down: %sabled, ", bild ? "en" : "dis");
631 
632 	struct boot_straps {
633 		const char *name;
634 		enum chipbustype bus;
635 	};
636 	static const struct boot_straps boot_straps_EP80579[] =
637 		{ { "SPI", BUS_SPI },
638 		  { "reserved", BUS_NONE },
639 		  { "reserved", BUS_NONE },
640 		  { "LPC", BUS_LPC | BUS_FWH } };
641 	static const struct boot_straps boot_straps_ich7_nm10[] =
642 		{ { "reserved", BUS_NONE },
643 		  { "SPI", BUS_SPI },
644 		  { "PCI", BUS_NONE },
645 		  { "LPC", BUS_LPC | BUS_FWH } };
646 	static const struct boot_straps boot_straps_tunnel_creek[] =
647 		{ { "SPI", BUS_SPI },
648 		  { "LPC", BUS_LPC | BUS_FWH } };
649 	static const struct boot_straps boot_straps_ich8910[] =
650 		{ { "SPI", BUS_SPI },
651 		  { "SPI", BUS_SPI },
652 		  { "PCI", BUS_NONE },
653 		  { "LPC", BUS_LPC | BUS_FWH } };
654 	static const struct boot_straps boot_straps_pch567[] =
655 		{ { "LPC", BUS_LPC | BUS_FWH },
656 		  { "reserved", BUS_NONE },
657 		  { "PCI", BUS_NONE },
658 		  { "SPI", BUS_SPI } };
659 	static const struct boot_straps boot_straps_pch89_baytrail[] =
660 		{ { "LPC", BUS_LPC | BUS_FWH },
661 		  { "reserved", BUS_NONE },
662 		  { "reserved", BUS_NONE },
663 		  { "SPI", BUS_SPI } };
664 	static const struct boot_straps boot_straps_pch8_lp[] =
665 		{ { "SPI", BUS_SPI },
666 		  { "LPC", BUS_LPC | BUS_FWH } };
667 	static const struct boot_straps boot_straps_pch500[] =
668 		{ { "SPI", BUS_SPI },
669 		  { "eSPI", BUS_NONE } };
670 	static const struct boot_straps boot_straps_apl[] =
671 		{ { "SPI", BUS_SPI },
672 		  { "reserved", BUS_NONE } };
673 	static const struct boot_straps boot_straps_unknown[] =
674 		{ { "unknown", BUS_NONE },
675 		  { "unknown", BUS_NONE },
676 		  { "unknown", BUS_NONE },
677 		  { "unknown", BUS_NONE } };
678 
679 	const struct boot_straps *boot_straps;
680 	switch (ich_generation) {
681 	case CHIPSET_ICH7:
682 		/* EP80579 may need further changes, but this is the least
683 		 * intrusive way to get correct BOOT Strap printing without
684 		 * changing the rest of its code path). */
685 		if (dev->device_id == 0x5031)
686 			boot_straps = boot_straps_EP80579;
687 		else
688 			boot_straps = boot_straps_ich7_nm10;
689 		break;
690 	case CHIPSET_ICH8:
691 	case CHIPSET_ICH9:
692 	case CHIPSET_ICH10:
693 		boot_straps = boot_straps_ich8910;
694 		break;
695 	case CHIPSET_TUNNEL_CREEK:
696 		boot_straps = boot_straps_tunnel_creek;
697 		break;
698 	case CHIPSET_5_SERIES_IBEX_PEAK:
699 	case CHIPSET_6_SERIES_COUGAR_POINT:
700 	case CHIPSET_7_SERIES_PANTHER_POINT:
701 		boot_straps = boot_straps_pch567;
702 		break;
703 	case CHIPSET_8_SERIES_LYNX_POINT:
704 	case CHIPSET_9_SERIES_WILDCAT_POINT:
705 	case CHIPSET_BAYTRAIL:
706 		boot_straps = boot_straps_pch89_baytrail;
707 		break;
708 	case CHIPSET_8_SERIES_LYNX_POINT_LP:
709 	case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
710 	case CHIPSET_100_SERIES_SUNRISE_POINT:
711 	case CHIPSET_C620_SERIES_LEWISBURG:
712 	case CHIPSET_300_SERIES_CANNON_POINT:
713 	case CHIPSET_400_SERIES_COMET_POINT:
714 		boot_straps = boot_straps_pch8_lp;
715 		break;
716 	case CHIPSET_500_SERIES_TIGER_POINT:
717 	case CHIPSET_600_SERIES_ALDER_POINT:
718 	case CHIPSET_700_SERIES_RAPTOR_POINT:
719 	case CHIPSET_C740_SERIES_EMMITSBURG:
720 	case CHIPSET_METEOR_LAKE:
721 	case CHIPSET_PANTHER_LAKE:
722 		boot_straps = boot_straps_pch500;
723 		break;
724 	case CHIPSET_APOLLO_LAKE:
725 	case CHIPSET_GEMINI_LAKE:
726 	case CHIPSET_JASPER_LAKE:
727 	case CHIPSET_ELKHART_LAKE:
728 		boot_straps = boot_straps_apl;
729 		break;
730 	case CHIPSET_8_SERIES_WELLSBURG: // FIXME: check datasheet
731 	case CHIPSET_CENTERTON: // FIXME: Datasheet does not mention GCS at all
732 		boot_straps = boot_straps_unknown;
733 		break;
734 	default:
735 		msg_gerr("%s: unknown ICH generation. Please report!\n", __func__);
736 		boot_straps = boot_straps_unknown;
737 		break;
738 	}
739 
740 	uint8_t bbs;
741 	switch (ich_generation) {
742 	case CHIPSET_TUNNEL_CREEK:
743 		bbs = (gcs >> 1) & 0x1;
744 		break;
745 	case CHIPSET_8_SERIES_LYNX_POINT_LP:
746 	case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
747 		/* LP PCHs use a single bit for BBS */
748 		bbs = (gcs >> 10) & 0x1;
749 		break;
750 	case CHIPSET_100_SERIES_SUNRISE_POINT:
751 	case CHIPSET_C620_SERIES_LEWISBURG:
752 	case CHIPSET_300_SERIES_CANNON_POINT:
753 	case CHIPSET_400_SERIES_COMET_POINT:
754 	case CHIPSET_500_SERIES_TIGER_POINT:
755 	case CHIPSET_600_SERIES_ALDER_POINT:
756 	case CHIPSET_700_SERIES_RAPTOR_POINT:
757 	case CHIPSET_METEOR_LAKE:
758 	case CHIPSET_PANTHER_LAKE:
759 	case CHIPSET_APOLLO_LAKE:
760 	case CHIPSET_GEMINI_LAKE:
761 	case CHIPSET_JASPER_LAKE:
762 	case CHIPSET_ELKHART_LAKE:
763 		bbs = (gcs >> 6) & 0x1;
764 		break;
765 	default:
766 		/* Other chipsets use two bits for BBS */
767 		bbs = (gcs >> 10) & 0x3;
768 		break;
769 	}
770 	msg_pdbg("Boot BIOS Straps: 0x%x (%s)\n", bbs, boot_straps[bbs].name);
771 
772 	/* Centerton has its TS bit in [GPE0BLK] + 0x30 while the exact location for Tunnel Creek is unknown. */
773 	if (ich_generation != CHIPSET_TUNNEL_CREEK && ich_generation != CHIPSET_CENTERTON)
774 		msg_pdbg("Top Swap: %s\n", (top_swap) ? "enabled (A16(+) inverted)" : "not enabled");
775 
776 	return boot_straps[bbs].bus;
777 }
778 
enable_flash_ich_spi(const struct programmer_cfg * cfg,struct pci_dev * dev,enum ich_chipset ich_generation,uint8_t bios_cntl)779 static int enable_flash_ich_spi(const struct programmer_cfg *cfg, struct pci_dev *dev, enum ich_chipset ich_generation, uint8_t bios_cntl)
780 {
781 	/* Get physical address of Root Complex Register Block */
782 	uint32_t rcra = pci_read_long(dev, 0xf0) & 0xffffc000;
783 	msg_pdbg("Root Complex Register Block address = 0x%"PRIx32"\n", rcra);
784 
785 	/* Map RCBA to virtual memory */
786 	void *rcrb = rphysmap("ICH RCRB", rcra, 0x4000);
787 	if (rcrb == ERROR_PTR)
788 		return ERROR_FLASHROM_FATAL;
789 
790 	const enum chipbustype boot_buses = enable_flash_ich_report_gcs(dev, ich_generation, rcrb);
791 
792 	/* Handle FWH-related parameters and initialization */
793 	int ret_fwh = enable_flash_ich_fwh(cfg, dev, ich_generation, bios_cntl);
794 	if (ret_fwh == ERROR_FLASHROM_FATAL)
795 		return ret_fwh;
796 
797 	/*
798 	 * It seems that the ICH7 does not support SPI and LPC chips at the same time. When booted
799 	 * from LPC, the SCIP bit will never clear, which causes long delays and many error messages.
800 	 * To avoid this, we will not enable SPI on ICH7 when the southbridge is strapped to LPC.
801 	 */
802 	if (ich_generation == CHIPSET_ICH7 && (boot_buses & BUS_LPC))
803 		return 0;
804 
805 	/* SPIBAR is at RCRB+0x3020 for ICH[78], Tunnel Creek and Centerton, and RCRB+0x3800 for ICH9. */
806 	uint16_t spibar_offset;
807 	switch (ich_generation) {
808 	case CHIPSET_BAYTRAIL:
809 	case CHIPSET_ICH_UNKNOWN:
810 		return ERROR_FLASHROM_FATAL;
811 	case CHIPSET_ICH7:
812 	case CHIPSET_ICH8:
813 	case CHIPSET_TUNNEL_CREEK:
814 	case CHIPSET_CENTERTON:
815 		spibar_offset = 0x3020;
816 		break;
817 	case CHIPSET_ICH9:
818 	default:		/* Future version might behave the same */
819 		spibar_offset = 0x3800;
820 		break;
821 	}
822 	msg_pdbg("SPIBAR = 0x%0*" PRIxPTR " + 0x%04x\n", PRIxPTR_WIDTH, (uintptr_t)rcrb, spibar_offset);
823 	void *spibar = rcrb + spibar_offset;
824 
825 	/* This adds BUS_SPI */
826 	int ret_spi = ich_init_spi(cfg, spibar, ich_generation);
827 	if (ret_spi == ERROR_FLASHROM_FATAL)
828 		return ret_spi;
829 
830 	if (((boot_buses & BUS_FWH) && ret_fwh) || ((boot_buses & BUS_SPI) && ret_spi))
831 		return ERROR_FLASHROM_NONFATAL;
832 
833 	/* Suppress unknown laptop warning if we booted from SPI. */
834 	if (boot_buses & BUS_SPI)
835 		cfg->bcfg->laptop_ok = true;
836 
837 	return 0;
838 }
839 
enable_flash_tunnelcreek(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)840 static int enable_flash_tunnelcreek(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
841 {
842 	return enable_flash_ich_spi(cfg, dev, CHIPSET_TUNNEL_CREEK, 0xd8);
843 }
844 
enable_flash_s12x0(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)845 static int enable_flash_s12x0(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
846 {
847 	return enable_flash_ich_spi(cfg, dev, CHIPSET_CENTERTON, 0xd8);
848 }
849 
enable_flash_ich7(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)850 static int enable_flash_ich7(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
851 {
852 	return enable_flash_ich_spi(cfg, dev, CHIPSET_ICH7, 0xdc);
853 }
854 
enable_flash_ich8(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)855 static int enable_flash_ich8(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
856 {
857 	return enable_flash_ich_spi(cfg, dev, CHIPSET_ICH8, 0xdc);
858 }
859 
enable_flash_ich9(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)860 static int enable_flash_ich9(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
861 {
862 	return enable_flash_ich_spi(cfg, dev, CHIPSET_ICH9, 0xdc);
863 }
864 
enable_flash_ich10(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)865 static int enable_flash_ich10(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
866 {
867 	return enable_flash_ich_spi(cfg, dev, CHIPSET_ICH10, 0xdc);
868 }
869 
870 /* Ibex Peak aka. 5 series & 3400 series */
enable_flash_pch5(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)871 static int enable_flash_pch5(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
872 {
873 	return enable_flash_ich_spi(cfg, dev, CHIPSET_5_SERIES_IBEX_PEAK, 0xdc);
874 }
875 
876 /* Cougar Point aka. 6 series & c200 series */
enable_flash_pch6(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)877 static int enable_flash_pch6(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
878 {
879 	return enable_flash_ich_spi(cfg, dev, CHIPSET_6_SERIES_COUGAR_POINT, 0xdc);
880 }
881 
882 /* Panther Point aka. 7 series */
enable_flash_pch7(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)883 static int enable_flash_pch7(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
884 {
885 	return enable_flash_ich_spi(cfg, dev, CHIPSET_7_SERIES_PANTHER_POINT, 0xdc);
886 }
887 
888 /* Lynx Point aka. 8 series */
enable_flash_pch8(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)889 static int enable_flash_pch8(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
890 {
891 	return enable_flash_ich_spi(cfg, dev, CHIPSET_8_SERIES_LYNX_POINT, 0xdc);
892 }
893 
894 /* Lynx Point LP aka. 8 series low-power */
enable_flash_pch8_lp(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)895 static int enable_flash_pch8_lp(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
896 {
897 	return enable_flash_ich_spi(cfg, dev, CHIPSET_8_SERIES_LYNX_POINT_LP, 0xdc);
898 }
899 
900 /* Wellsburg (for Haswell-EP Xeons) */
enable_flash_pch8_wb(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)901 static int enable_flash_pch8_wb(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
902 {
903 	return enable_flash_ich_spi(cfg, dev, CHIPSET_8_SERIES_WELLSBURG, 0xdc);
904 }
905 
906 /* Wildcat Point */
enable_flash_pch9(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)907 static int enable_flash_pch9(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
908 {
909 	return enable_flash_ich_spi(cfg, dev, CHIPSET_9_SERIES_WILDCAT_POINT, 0xdc);
910 }
911 
912 /* Wildcat Point LP */
enable_flash_pch9_lp(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)913 static int enable_flash_pch9_lp(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
914 {
915 	return enable_flash_ich_spi(cfg, dev, CHIPSET_9_SERIES_WILDCAT_POINT_LP, 0xdc);
916 }
917 
918 /* Sunrise Point */
enable_flash_pch100_shutdown(void * const pci_acc)919 static int enable_flash_pch100_shutdown(void *const pci_acc)
920 {
921 	pci_cleanup(pci_acc);
922 	return 0;
923 }
924 
enable_flash_pch100_or_c620(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name,const int slot,const int func,const enum ich_chipset pch_generation)925 static int enable_flash_pch100_or_c620(const struct programmer_cfg *cfg,
926 		struct pci_dev *const dev, const char *const name,
927 		const int slot, const int func, const enum ich_chipset pch_generation)
928 {
929 	int ret = ERROR_FLASHROM_FATAL;
930 
931 	/*
932 	 * The SPI PCI device is usually hidden (by hiding PCI vendor
933 	 * and device IDs). So we need a PCI access method that works
934 	 * even when the OS doesn't know the PCI device. We can't use
935 	 * this method globally since it would bring along other con-
936 	 * straints (e.g. on PCI domains, extended PCIe config space).
937 	 */
938 	struct pci_access *const pci_acc = pci_alloc();
939 	struct pci_access *const saved_pacc = pacc;
940 	if (!pci_acc) {
941 		msg_perr("Can't allocate PCI accessor.\n");
942 		return ret;
943 	}
944 #if CONFIG_USE_LIBPCI_ECAM == 1
945 	pci_acc->method = PCI_ACCESS_ECAM;
946 	msg_pdbg("Using libpci PCI_ACCESS_ECAM\n");
947 #else
948 	pci_acc->method = PCI_ACCESS_I386_TYPE1;
949 	msg_pdbg("Using libpci PCI_ACCESS_I386_TYPE1\n");
950 #endif
951 	pci_init(pci_acc);
952 	register_shutdown(enable_flash_pch100_shutdown, pci_acc);
953 
954 	struct pci_dev *const spi_dev = pci_get_dev(pci_acc, dev->domain, dev->bus, slot, func);
955 	if (!spi_dev) {
956 		msg_perr("Can't allocate PCI device.\n");
957 		return ret;
958 	}
959 
960 	/* Modify pacc so the rpci_write can register the undo callback with a
961 	 * device using the correct pci_access */
962 	pacc = pci_acc;
963 	const enum chipbustype boot_buses = enable_flash_ich_report_gcs(spi_dev, pch_generation, NULL);
964 
965 	const int ret_bc = enable_flash_ich_bios_cntl_config_space(spi_dev, pch_generation, 0xdc);
966 	if (ret_bc == ERROR_FLASHROM_FATAL)
967 		goto _freepci_ret;
968 
969 	const uint32_t phys_spibar = pci_read_long(spi_dev, PCI_BASE_ADDRESS_0) & 0xfffff000;
970 	void *const spibar = rphysmap("SPIBAR", phys_spibar, 0x1000);
971 	if (spibar == ERROR_PTR)
972 		goto _freepci_ret;
973 	msg_pdbg("SPIBAR = 0x%0*" PRIxPTR " (phys = 0x%08"PRIx32")\n", PRIxPTR_WIDTH, (uintptr_t)spibar, phys_spibar);
974 
975 	/* This adds BUS_SPI */
976 	const int ret_spi = ich_init_spi(cfg, spibar, pch_generation);
977 	if (ret_spi != ERROR_FLASHROM_FATAL) {
978 		if (ret_bc || ret_spi)
979 			ret = ERROR_FLASHROM_NONFATAL;
980 		else
981 			ret = 0;
982 	}
983 
984 	/* Suppress unknown laptop warning if we booted from SPI. */
985 	if (!ret && (boot_buses & BUS_SPI))
986 		cfg->bcfg->laptop_ok = true;
987 
988 _freepci_ret:
989 	pci_free_dev(spi_dev);
990 	pacc = saved_pacc;
991 	return ret;
992 }
993 
enable_flash_pch100(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)994 static int enable_flash_pch100(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
995 {
996 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_100_SERIES_SUNRISE_POINT);
997 }
998 
enable_flash_c620(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)999 static int enable_flash_c620(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1000 {
1001 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_C620_SERIES_LEWISBURG);
1002 }
1003 
enable_flash_c740(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1004 static int enable_flash_c740(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1005 {
1006 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_C740_SERIES_EMMITSBURG);
1007 }
1008 
enable_flash_pch300(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1009 static int enable_flash_pch300(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1010 {
1011 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_300_SERIES_CANNON_POINT);
1012 }
1013 
enable_flash_pch400(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1014 static int enable_flash_pch400(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1015 {
1016 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_400_SERIES_COMET_POINT);
1017 }
1018 
enable_flash_pch500(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1019 static int enable_flash_pch500(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1020 {
1021 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_500_SERIES_TIGER_POINT);
1022 }
1023 
enable_flash_pch600(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1024 static int enable_flash_pch600(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1025 {
1026 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_600_SERIES_ALDER_POINT);
1027 }
1028 
enable_flash_pch700(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1029 static int enable_flash_pch700(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1030 {
1031 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_700_SERIES_RAPTOR_POINT);
1032 }
1033 
enable_flash_mtl(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1034 static int enable_flash_mtl(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1035 {
1036 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_METEOR_LAKE);
1037 }
1038 
enable_flash_ptl(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1039 static int enable_flash_ptl(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1040 {
1041 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_PANTHER_LAKE);
1042 }
1043 
enable_flash_mcc(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1044 static int enable_flash_mcc(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1045 {
1046 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_ELKHART_LAKE);
1047 }
1048 
enable_flash_jsl(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1049 static int enable_flash_jsl(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1050 {
1051 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x1f, 5, CHIPSET_JASPER_LAKE);
1052 }
1053 
enable_flash_apl(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1054 static int enable_flash_apl(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1055 {
1056 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x0d, 2, CHIPSET_APOLLO_LAKE);
1057 }
1058 
enable_flash_glk(const struct programmer_cfg * cfg,struct pci_dev * const dev,const char * const name)1059 static int enable_flash_glk(const struct programmer_cfg *cfg, struct pci_dev *const dev, const char *const name)
1060 {
1061 	return enable_flash_pch100_or_c620(cfg, dev, name, 0x0d, 2, CHIPSET_GEMINI_LAKE);
1062 }
1063 
1064 /* Silvermont architecture: Bay Trail(-T/-I), Avoton/Rangeley.
1065  * These have a distinctly different behavior compared to other Intel chipsets and hence are handled separately.
1066  *
1067  * Differences include:
1068  *	- RCBA at LPC config 0xF0 too but mapped range is only 4 B long instead of 16 kB.
1069  *	- GCS at [RCRB] + 0 (instead of [RCRB] + 0x3410).
1070  *	- TS (Top Swap) in GCS (instead of [RCRB] + 0x3414).
1071  *	- SPIBAR (coined SBASE) at LPC config 0x54 (instead of [RCRB] + 0x3800).
1072  *	- BIOS_CNTL (coined BCR) at [SPIBAR] + 0xFC (instead of LPC config 0xDC).
1073  */
enable_flash_silvermont(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1074 static int enable_flash_silvermont(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1075 {
1076 	enum ich_chipset ich_generation = CHIPSET_BAYTRAIL;
1077 
1078 	/* Get physical address of Root Complex Register Block */
1079 	uint32_t rcba = pci_read_long(dev, 0xf0) & 0xfffffc00;
1080 	msg_pdbg("Root Complex Register Block address = 0x%"PRIx32"\n", rcba);
1081 
1082 	/* Handle GCS (in RCRB) */
1083 	void *rcrb = physmap("BYT RCRB", rcba, 4);
1084 	if (rcrb == ERROR_PTR)
1085 		return ERROR_FLASHROM_FATAL;
1086 	const enum chipbustype boot_buses = enable_flash_ich_report_gcs(dev, ich_generation, rcrb);
1087 	physunmap(rcrb, 4);
1088 
1089 	/* Handle fwh_idsel parameter */
1090 	int ret_fwh = enable_flash_ich_fwh_decode(cfg, dev, ich_generation);
1091 	if (ret_fwh == ERROR_FLASHROM_FATAL)
1092 		return ret_fwh;
1093 
1094 	internal_buses_supported &= BUS_FWH;
1095 
1096 	/* Get physical address of SPI Base Address and map it */
1097 	uint32_t sbase = pci_read_long(dev, 0x54) & 0xfffffe00;
1098 	msg_pdbg("SPI_BASE_ADDRESS = 0x%"PRIx32"\n", sbase);
1099 	void *spibar = rphysmap("BYT SBASE", sbase, 512); /* Last defined address on Bay Trail is 0x100 */
1100 	if (spibar == ERROR_PTR)
1101 		return ERROR_FLASHROM_FATAL;
1102 
1103 	/* Enable Flash Writes.
1104 	 * Silvermont-based: BCR at SBASE + 0xFC (some bits of BCR are also accessible via BC at IBASE + 0x1C).
1105 	 */
1106 	enable_flash_ich_bios_cntl_memmapped(ich_generation, spibar + 0xFC);
1107 
1108 	int ret_spi = ich_init_spi(cfg, spibar, ich_generation);
1109 	if (ret_spi == ERROR_FLASHROM_FATAL)
1110 		return ret_spi;
1111 
1112 	if (((boot_buses & BUS_FWH) && ret_fwh) || ((boot_buses & BUS_SPI) && ret_spi))
1113 		return ERROR_FLASHROM_NONFATAL;
1114 
1115 	/* Suppress unknown laptop warning if we booted from SPI. */
1116 	if (boot_buses & BUS_SPI)
1117 		cfg->bcfg->laptop_ok = true;
1118 
1119 	return 0;
1120 }
1121 
via_no_byte_merge(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1122 static int via_no_byte_merge(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1123 {
1124 	uint8_t val;
1125 
1126 	val = pci_read_byte(dev, 0x71);
1127 	if (val & 0x40) {
1128 		msg_pdbg("Disabling byte merging\n");
1129 		val &= ~0x40;
1130 		rpci_write_byte(dev, 0x71, val);
1131 	}
1132 	return NOT_DONE_YET;	/* need to find south bridge, too */
1133 }
1134 
enable_flash_vt823x(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1135 static int enable_flash_vt823x(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1136 {
1137 	uint8_t val;
1138 
1139 	/* Enable ROM decode range (1MB) FFC00000 - FFFFFFFF. */
1140 	rpci_write_byte(dev, 0x41, 0x7f);
1141 
1142 	/* ROM write enable */
1143 	val = pci_read_byte(dev, 0x40);
1144 	val |= 0x10;
1145 	rpci_write_byte(dev, 0x40, val);
1146 
1147 	if (pci_read_byte(dev, 0x40) != val) {
1148 		msg_pwarn("\nWarning: Failed to enable flash write on \"%s\"\n", name);
1149 		return -1;
1150 	}
1151 
1152 	if (dev->device_id == 0x3227) { /* VT8237/VT8237R */
1153 		/* All memory cycles, not just ROM ones, go to LPC. */
1154 		val = pci_read_byte(dev, 0x59);
1155 		val &= ~0x80;
1156 		rpci_write_byte(dev, 0x59, val);
1157 	}
1158 
1159 	return 0;
1160 }
1161 
enable_flash_vt_vx(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1162 static int enable_flash_vt_vx(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1163 {
1164 	struct pci_dev *south_north = pcidev_find(0x1106, 0xa353);
1165 	if (south_north == NULL) {
1166 		msg_perr("Could not find South-North Module Interface Control device!\n");
1167 		return ERROR_FLASHROM_FATAL;
1168 	}
1169 
1170 	msg_pdbg("Strapped to ");
1171 	if ((pci_read_byte(south_north, 0x56) & 0x01) == 0) {
1172 		msg_pdbg("LPC.\n");
1173 		return enable_flash_vt823x(cfg, dev, name);
1174 	}
1175 	msg_pdbg("SPI.\n");
1176 
1177 	uint32_t mmio_base;
1178 	void *mmio_base_physmapped;
1179 	uint32_t spi_cntl;
1180 	#define SPI_CNTL_LEN 0x08
1181 	uint32_t spi0_mm_base = 0;
1182 	switch(dev->device_id) {
1183 		case 0x8353: /* VX800/VX820 */
1184 			spi0_mm_base = pci_read_long(dev, 0xbc) << 8;
1185 			if (spi0_mm_base == 0x0) {
1186 				msg_pdbg ("MMIO not enabled!\n");
1187 				return ERROR_FLASHROM_FATAL;
1188 			}
1189 			break;
1190 		case 0x8409: /* VX855/VX875 */
1191 		case 0x8410: /* VX900 */
1192 			mmio_base = pci_read_long(dev, 0xbc) << 8;
1193 			if (mmio_base == 0x0) {
1194 				msg_pdbg ("MMIO not enabled!\n");
1195 				return ERROR_FLASHROM_FATAL;
1196 			}
1197 			mmio_base_physmapped = physmap("VIA VX MMIO register", mmio_base, SPI_CNTL_LEN);
1198 			if (mmio_base_physmapped == ERROR_PTR)
1199 				return ERROR_FLASHROM_FATAL;
1200 
1201 			/* Offset 0 - Bit 0 holds SPI Bus0 Enable Bit. */
1202 			spi_cntl = mmio_readl(mmio_base_physmapped) + 0x00;
1203 			if ((spi_cntl & 0x01) == 0) {
1204 				msg_pdbg ("SPI Bus0 disabled!\n");
1205 				physunmap(mmio_base_physmapped, SPI_CNTL_LEN);
1206 				return ERROR_FLASHROM_FATAL;
1207 			}
1208 			/* Offset 1-3 has  SPI Bus Memory Map Base Address: */
1209 			spi0_mm_base = spi_cntl & 0xFFFFFF00;
1210 
1211 			/* Offset 4 - Bit 0 holds SPI Bus1 Enable Bit. */
1212 			spi_cntl = mmio_readl(mmio_base_physmapped) + 0x04;
1213 			if ((spi_cntl & 0x01) == 1)
1214 				msg_pdbg2("SPI Bus1 is enabled too.\n");
1215 
1216 			physunmap(mmio_base_physmapped, SPI_CNTL_LEN);
1217 			break;
1218 		default:
1219 			msg_perr("%s: Unsupported chipset %x:%x!\n", __func__, dev->vendor_id, dev->device_id);
1220 			return ERROR_FLASHROM_FATAL;
1221 	}
1222 
1223 	return via_init_spi(spi0_mm_base);
1224 }
1225 
enable_flash_vt8237s_spi(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1226 static int enable_flash_vt8237s_spi(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1227 {
1228 	return via_init_spi(pci_read_long(dev, 0xbc) << 8);
1229 }
1230 
enable_flash_cs5530(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1231 static int enable_flash_cs5530(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1232 {
1233 	uint8_t reg8;
1234 
1235 #define DECODE_CONTROL_REG2		0x5b	/* F0 index 0x5b */
1236 #define ROM_AT_LOGIC_CONTROL_REG	0x52	/* F0 index 0x52 */
1237 #define CS5530_RESET_CONTROL_REG	0x44	/* F0 index 0x44 */
1238 #define CS5530_USB_SHADOW_REG		0x43	/* F0 index 0x43 */
1239 
1240 #define LOWER_ROM_ADDRESS_RANGE		(1 << 0)
1241 #define ROM_WRITE_ENABLE		(1 << 1)
1242 #define UPPER_ROM_ADDRESS_RANGE		(1 << 2)
1243 #define BIOS_ROM_POSITIVE_DECODE	(1 << 5)
1244 #define CS5530_ISA_MASTER		(1 << 7)
1245 #define CS5530_ENABLE_SA2320		(1 << 2)
1246 #define CS5530_ENABLE_SA20		(1 << 6)
1247 
1248 	internal_buses_supported &= BUS_PARALLEL;
1249 	/* Decode 0x000E0000-0x000FFFFF (128 kB), not just 64 kB, and
1250 	 * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 kB.
1251 	 * FIXME: Should we really touch the low mapping below 1 MB? Flashrom
1252 	 * ignores that region completely.
1253 	 * Make the configured ROM areas writable.
1254 	 */
1255 	reg8 = pci_read_byte(dev, ROM_AT_LOGIC_CONTROL_REG);
1256 	reg8 |= LOWER_ROM_ADDRESS_RANGE;
1257 	reg8 |= UPPER_ROM_ADDRESS_RANGE;
1258 	reg8 |= ROM_WRITE_ENABLE;
1259 	rpci_write_byte(dev, ROM_AT_LOGIC_CONTROL_REG, reg8);
1260 
1261 	/* Set positive decode on ROM. */
1262 	reg8 = pci_read_byte(dev, DECODE_CONTROL_REG2);
1263 	reg8 |= BIOS_ROM_POSITIVE_DECODE;
1264 	rpci_write_byte(dev, DECODE_CONTROL_REG2, reg8);
1265 
1266 	reg8 = pci_read_byte(dev, CS5530_RESET_CONTROL_REG);
1267 	if (reg8 & CS5530_ISA_MASTER) {
1268 		/* We have A0-A23 available. */
1269 		max_rom_decode.parallel = 16 * 1024 * 1024;
1270 	} else {
1271 		reg8 = pci_read_byte(dev, CS5530_USB_SHADOW_REG);
1272 		if (reg8 & CS5530_ENABLE_SA2320) {
1273 			/* We have A0-19, A20-A23 available. */
1274 			max_rom_decode.parallel = 16 * 1024 * 1024;
1275 		} else if (reg8 & CS5530_ENABLE_SA20) {
1276 			/* We have A0-19, A20 available. */
1277 			max_rom_decode.parallel = 2 * 1024 * 1024;
1278 		} else {
1279 			/* A20 and above are not active. */
1280 			max_rom_decode.parallel = 1024 * 1024;
1281 		}
1282 	}
1283 
1284 	return 0;
1285 }
1286 
1287 /*
1288  * Geode systems write protect the BIOS via RCONFs (cache settings similar
1289  * to MTRRs). To unlock, change MSR 0x1808 top byte to 0x22.
1290  *
1291  * Geode systems also write protect the NOR flash chip itself via MSR_NORF_CTL.
1292  * To enable write to NOR Boot flash for the benefit of systems that have such
1293  * a setup, raise MSR 0x51400018 WE_CS3 (write enable Boot Flash Chip Select).
1294  */
enable_flash_cs5536(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1295 static int enable_flash_cs5536(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1296 {
1297 #define MSR_RCONF_DEFAULT	0x1808
1298 #define MSR_NORF_CTL		0x51400018
1299 
1300 	msr_t msr;
1301 
1302 	/* Geode only has a single core */
1303 	if (msr_setup(0))
1304 		return -1;
1305 
1306 	msr = msr_read(MSR_RCONF_DEFAULT);
1307 	if ((msr.hi >> 24) != 0x22) {
1308 		msr.hi &= 0xfbffffff;
1309 		msr_write(MSR_RCONF_DEFAULT, msr);
1310 	}
1311 
1312 	msr = msr_read(MSR_NORF_CTL);
1313 	/* Raise WE_CS3 bit. */
1314 	msr.lo |= 0x08;
1315 	msr_write(MSR_NORF_CTL, msr);
1316 
1317 	msr_cleanup();
1318 
1319 #undef MSR_RCONF_DEFAULT
1320 #undef MSR_NORF_CTL
1321 	return 0;
1322 }
1323 
enable_flash_sc1100(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1324 static int enable_flash_sc1100(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1325 {
1326 	#define SC_REG 0x52
1327 	uint8_t new;
1328 
1329 	rpci_write_byte(dev, SC_REG, 0xee);
1330 
1331 	new = pci_read_byte(dev, SC_REG);
1332 
1333 	if (new != 0xee) { /* FIXME: share this with other code? */
1334 		msg_pinfo("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n", SC_REG, new, name);
1335 		return -1;
1336 	}
1337 
1338 	return 0;
1339 }
1340 
1341 /* Works for AMD-768, AMD-8111, VIA VT82C586A/B, VIA VT82C596, VIA VT82C686A/B.
1342  *
1343  * ROM decode control register matrix
1344  *	AMD-768			AMD-8111	VT82C586A/B		VT82C596		VT82C686A/B
1345  * 7	FFC0_0000h–FFFF_FFFFh	<-		FFFE0000h-FFFEFFFFh	<-			<-
1346  * 6	FFB0_0000h–FFBF_FFFFh	<-		FFF80000h-FFFDFFFFh	<-			<-
1347  * 5	00E8...			<-		<-			FFF00000h-FFF7FFFFh	<-
1348  */
enable_flash_amd_via(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name,uint8_t decode_val)1349 static int enable_flash_amd_via(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name, uint8_t decode_val)
1350 {
1351 	#define AMD_MAPREG 0x43
1352 	#define AMD_ENREG 0x40
1353 	uint8_t old, new;
1354 
1355 	old = pci_read_byte(dev, AMD_MAPREG);
1356 	new = old | decode_val;
1357 	if (new != old) {
1358 		rpci_write_byte(dev, AMD_MAPREG, new);
1359 		if (pci_read_byte(dev, AMD_MAPREG) != new) {
1360 			msg_pwarn("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n",
1361 				  AMD_MAPREG, new, name);
1362 		} else
1363 			msg_pdbg("Changed ROM decode range to 0x%02x successfully.\n", new);
1364 	}
1365 
1366 	/* Enable 'ROM write' bit. */
1367 	old = pci_read_byte(dev, AMD_ENREG);
1368 	new = old | 0x01;
1369 	if (new == old)
1370 		return 0;
1371 	rpci_write_byte(dev, AMD_ENREG, new);
1372 
1373 	if (pci_read_byte(dev, AMD_ENREG) != new) {
1374 		msg_pwarn("Setting register 0x%x to 0x%02x on %s failed (WARNING ONLY).\n",
1375 			  AMD_ENREG, new, name);
1376 		return ERROR_FLASHROM_NONFATAL;
1377 	}
1378 	msg_pdbg2("Set ROM enable bit successfully.\n");
1379 
1380 	return 0;
1381 }
1382 
enable_flash_amd_768_8111(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1383 static int enable_flash_amd_768_8111(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1384 {
1385 	/* Enable decoding of 0xFFB00000 to 0xFFFFFFFF (5 MB). */
1386 	max_rom_decode.lpc = 5 * 1024 * 1024;
1387 	return enable_flash_amd_via(cfg, dev, name, 0xC0);
1388 }
1389 
enable_flash_vt82c586(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1390 static int enable_flash_vt82c586(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1391 {
1392 	/* Enable decoding of 0xFFF80000 to 0xFFFFFFFF. (512 kB) */
1393 	max_rom_decode.parallel = 512 * 1024;
1394 	return enable_flash_amd_via(cfg, dev, name, 0xC0);
1395 }
1396 
1397 /* Works for VT82C686A/B too. */
enable_flash_vt82c596(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1398 static int enable_flash_vt82c596(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1399 {
1400 	/* Enable decoding of 0xFFF00000 to 0xFFFFFFFF. (1 MB) */
1401 	max_rom_decode.parallel = 1024 * 1024;
1402 	return enable_flash_amd_via(cfg, dev, name, 0xE0);
1403 }
1404 
enable_flash_sb600(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1405 static int enable_flash_sb600(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1406 {
1407 	uint32_t prot;
1408 	uint8_t reg;
1409 	int ret;
1410 
1411 	/* Clear ROM protect 0-3. */
1412 	for (reg = 0x50; reg < 0x60; reg += 4) {
1413 		prot = pci_read_long(dev, reg);
1414 		/* No protection flags for this region?*/
1415 		if ((prot & 0x3) == 0)
1416 			continue;
1417 		msg_pdbg("Chipset %s%sprotected flash from 0x%08"PRIx32" to 0x%08"PRIx32", unlocking...",
1418 			  (prot & 0x2) ? "read " : "",
1419 			  (prot & 0x1) ? "write " : "",
1420 			  (prot & 0xfffff800),
1421 			  (prot & 0xfffff800) + (((prot & 0x7fc) << 8) | 0x3ff));
1422 		prot &= 0xfffffffc;
1423 		rpci_write_byte(dev, reg, prot);
1424 		prot = pci_read_long(dev, reg);
1425 		if ((prot & 0x3) != 0) {
1426 			msg_perr("Disabling %s%sprotection of flash addresses from 0x%08"PRIx32" to 0x%08"PRIx32" failed.\n",
1427 				 (prot & 0x2) ? "read " : "",
1428 				 (prot & 0x1) ? "write " : "",
1429 				 (prot & 0xfffff800),
1430 				 (prot & 0xfffff800) + (((prot & 0x7fc) << 8) | 0x3ff));
1431 			continue;
1432 		}
1433 		msg_pdbg("done.\n");
1434 	}
1435 
1436 	internal_buses_supported &= BUS_LPC | BUS_FWH;
1437 
1438 	ret = sb600_probe_spi(cfg, dev);
1439 
1440 	/* Read ROM strap override register. */
1441 	OUTB(0x8f, 0xcd6);
1442 	reg = INB(0xcd7);
1443 	reg &= 0x0e;
1444 	msg_pdbg("ROM strap override is %sactive", (reg & 0x02) ? "" : "not ");
1445 	if (reg & 0x02) {
1446 		switch ((reg & 0x0c) >> 2) {
1447 		case 0x00:
1448 			msg_pdbg(": LPC");
1449 			break;
1450 		case 0x01:
1451 			msg_pdbg(": PCI");
1452 			break;
1453 		case 0x02:
1454 			msg_pdbg(": FWH");
1455 			break;
1456 		case 0x03:
1457 			msg_pdbg(": SPI");
1458 			break;
1459 		}
1460 	}
1461 	msg_pdbg("\n");
1462 
1463 	/* Force enable SPI ROM in SB600 PM register.
1464 	 * If we enable SPI ROM here, we have to disable it after we leave.
1465 	 * But how can we know which ROM we are going to handle? So we have
1466 	 * to trade off. We only access LPC ROM if we boot via LPC ROM. And
1467 	 * only SPI ROM if we boot via SPI ROM. If you want to access SPI on
1468 	 * boards with LPC straps, you have to use the code below.
1469 	 */
1470 	/*
1471 	OUTB(0x8f, 0xcd6);
1472 	OUTB(0x0e, 0xcd7);
1473 	*/
1474 
1475 	return ret;
1476 }
1477 
1478 /* sets bit 0 in 0x6d */
enable_flash_nvidia_common(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1479 static int enable_flash_nvidia_common(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1480 {
1481 	uint8_t old, new;
1482 
1483 	old = pci_read_byte(dev, 0x6d);
1484 	new = old | 0x01;
1485 	if (new == old)
1486 		return 0;
1487 
1488 	rpci_write_byte(dev, 0x6d, new);
1489 	if (pci_read_byte(dev, 0x6d) != new) {
1490 		msg_pinfo("Setting register 0x6d to 0x%02x on %s failed.\n", new, name);
1491 		return 1;
1492 	}
1493 	return 0;
1494 }
1495 
enable_flash_nvidia_nforce2(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1496 static int enable_flash_nvidia_nforce2(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1497 {
1498 	rpci_write_byte(dev, 0x92, 0);
1499 	if (enable_flash_nvidia_common(cfg, dev, name))
1500 		return ERROR_FLASHROM_NONFATAL;
1501 	else
1502 		return 0;
1503 }
1504 
enable_flash_ck804(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1505 static int enable_flash_ck804(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1506 {
1507 	uint32_t segctrl;
1508 	uint8_t reg, old, new;
1509 	unsigned int err = 0;
1510 
1511 	/* 0x8A is special: it is a single byte and only one nibble is touched. */
1512 	reg = 0x8A;
1513 	segctrl = pci_read_byte(dev, reg);
1514 	if ((segctrl & 0x3) != 0x0) {
1515 		if ((segctrl & 0xC) != 0x0) {
1516 			msg_pinfo("Can not unlock existing protection in register 0x%02x.\n", reg);
1517 			err++;
1518 		} else {
1519 			msg_pdbg("Unlocking protection in register 0x%02x... ", reg);
1520 			rpci_write_byte(dev, reg, segctrl & 0xF0);
1521 
1522 			segctrl = pci_read_byte(dev, reg);
1523 			if ((segctrl & 0x3) != 0x0) {
1524 				msg_pinfo("Could not unlock protection in register 0x%02x (new value: 0x%"PRIx32").\n",
1525 					  reg, segctrl);
1526 				err++;
1527 			} else
1528 				msg_pdbg("OK\n");
1529 		}
1530 	}
1531 
1532 	for (reg = 0x8C; reg <= 0x94; reg += 4) {
1533 		segctrl = pci_read_long(dev, reg);
1534 		if ((segctrl & 0x33333333) == 0x00000000) {
1535 			/* reads and writes are unlocked */
1536 			continue;
1537 		}
1538 		if ((segctrl & 0xCCCCCCCC) != 0x00000000) {
1539 			msg_pinfo("Can not unlock existing protection in register 0x%02x.\n", reg);
1540 			err++;
1541 			continue;
1542 		}
1543 		msg_pdbg("Unlocking protection in register 0x%02x... ", reg);
1544 		rpci_write_long(dev, reg, 0x00000000);
1545 
1546 		segctrl = pci_read_long(dev, reg);
1547 		if ((segctrl & 0x33333333) != 0x00000000) {
1548 			msg_pinfo("Could not unlock protection in register 0x%02x (new value: 0x%08"PRIx32").\n",
1549 				  reg, segctrl);
1550 			err++;
1551 		} else
1552 			msg_pdbg("OK\n");
1553 	}
1554 
1555 	if (err > 0) {
1556 		msg_pinfo("%d locks could not be disabled, disabling writes (reads may also fail).\n", err);
1557 		programmer_may_write = false;
1558 	}
1559 
1560 	reg = 0x88;
1561 	old = pci_read_byte(dev, reg);
1562 	new = old | 0xC0;
1563 	if (new != old) {
1564 		rpci_write_byte(dev, reg, new);
1565 		if (pci_read_byte(dev, reg) != new) { /* FIXME: share this with other code? */
1566 			msg_pinfo("Setting register 0x%02x to 0x%02x on %s failed.\n", reg, new, name);
1567 			err++;
1568 		}
1569 	}
1570 
1571 	if (enable_flash_nvidia_common(cfg, dev, name))
1572 		err++;
1573 
1574 	if (err > 0)
1575 		return ERROR_FLASHROM_NONFATAL;
1576 	else
1577 		return 0;
1578 }
1579 
enable_flash_osb4(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1580 static int enable_flash_osb4(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1581 {
1582 	uint8_t tmp;
1583 
1584 	internal_buses_supported &= BUS_PARALLEL;
1585 
1586 	tmp = INB(0xc06);
1587 	tmp |= 0x1;
1588 	OUTB(tmp, 0xc06);
1589 
1590 	tmp = INB(0xc6f);
1591 	tmp |= 0x40;
1592 	OUTB(tmp, 0xc6f);
1593 
1594 	return 0;
1595 }
1596 
1597 /* ATI Technologies Inc IXP SB400 PCI-ISA Bridge (rev 80) */
enable_flash_sb400(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1598 static int enable_flash_sb400(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1599 {
1600 	uint8_t tmp;
1601 	struct pci_dev *smbusdev;
1602 
1603 	/* Look for the SMBus device. */
1604 	smbusdev = pcidev_find(0x1002, 0x4372);
1605 
1606 	if (!smbusdev) {
1607 		msg_perr("ERROR: SMBus device not found. Aborting.\n");
1608 		return ERROR_FLASHROM_FATAL;
1609 	}
1610 
1611 	/* Enable some SMBus stuff. */
1612 	tmp = pci_read_byte(smbusdev, 0x79);
1613 	tmp |= 0x01;
1614 	rpci_write_byte(smbusdev, 0x79, tmp);
1615 
1616 	/* Change southbridge. */
1617 	tmp = pci_read_byte(dev, 0x48);
1618 	tmp |= 0x21;
1619 	rpci_write_byte(dev, 0x48, tmp);
1620 
1621 	/* Now become a bit silly. */
1622 	tmp = INB(0xc6f);
1623 	OUTB(tmp, 0xeb);
1624 	OUTB(tmp, 0xeb);
1625 	tmp |= 0x40;
1626 	OUTB(tmp, 0xc6f);
1627 	OUTB(tmp, 0xeb);
1628 	OUTB(tmp, 0xeb);
1629 
1630 	return 0;
1631 }
1632 
enable_flash_mcp55(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1633 static int enable_flash_mcp55(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1634 {
1635 	uint8_t val;
1636 	uint16_t wordval;
1637 
1638 	/* Set the 0-16 MB enable bits. */
1639 	val = pci_read_byte(dev, 0x88);
1640 	val |= 0xff;		/* 256K */
1641 	rpci_write_byte(dev, 0x88, val);
1642 	val = pci_read_byte(dev, 0x8c);
1643 	val |= 0xff;		/* 1M */
1644 	rpci_write_byte(dev, 0x8c, val);
1645 	wordval = pci_read_word(dev, 0x90);
1646 	wordval |= 0x7fff;	/* 16M */
1647 	rpci_write_word(dev, 0x90, wordval);
1648 
1649 	if (enable_flash_nvidia_common(cfg, dev, name))
1650 		return ERROR_FLASHROM_NONFATAL;
1651 	else
1652 		return 0;
1653 }
1654 
1655 /*
1656  * The MCP6x/MCP7x code is based on cleanroom reverse engineering.
1657  * It is assumed that LPC chips need the MCP55 code and SPI chips need the
1658  * code provided in enable_flash_mcp6x_7x_common.
1659  */
enable_flash_mcp6x_7x(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1660 static int enable_flash_mcp6x_7x(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1661 {
1662 	int ret = 0, want_spi = 0;
1663 	uint8_t val;
1664 
1665 	/* dev is the ISA bridge. No idea what the stuff below does. */
1666 	val = pci_read_byte(dev, 0x8a);
1667 	msg_pdbg("ISA/LPC bridge reg 0x8a contents: 0x%02x, bit 6 is %i, bit 5 "
1668 		 "is %i\n", val, (val >> 6) & 0x1, (val >> 5) & 0x1);
1669 
1670 	switch ((val >> 5) & 0x3) {
1671 	case 0x0:
1672 		ret = enable_flash_mcp55(cfg, dev, name);
1673 		internal_buses_supported &= BUS_LPC;
1674 		msg_pdbg("Flash bus type is LPC\n");
1675 		break;
1676 	case 0x2:
1677 		want_spi = 1;
1678 		/* SPI is added in mcp6x_spi_init if it works.
1679 		 * Do we really want to disable LPC in this case?
1680 		 */
1681 		internal_buses_supported = BUS_NONE;
1682 		msg_pdbg("Flash bus type is SPI\n");
1683 		break;
1684 	default:
1685 		/* Should not happen. */
1686 		internal_buses_supported = BUS_NONE;
1687 		msg_pwarn("Flash bus type is unknown (none)\n");
1688 		msg_pinfo("Please send the log files created by \"flashrom -p internal -o logfile\" to\n"
1689 			  "[email protected] with \"your board name: flashrom -V\" as the subject to\n"
1690 			  "help us finish support for your chipset. Thanks.\n");
1691 		return ERROR_FLASHROM_NONFATAL;
1692 	}
1693 
1694 	/* Force enable SPI and disable LPC? Not a good idea. */
1695 #if 0
1696 	val |= (1 << 6);
1697 	val &= ~(1 << 5);
1698 	rpci_write_byte(dev, 0x8a, val);
1699 #endif
1700 
1701 	if (mcp6x_spi_init(want_spi))
1702 		ret = 1;
1703 
1704 	/* Suppress unknown laptop warning if we booted from SPI. */
1705 	if (!ret && want_spi)
1706 		cfg->bcfg->laptop_ok = true;
1707 
1708 	return ret;
1709 }
1710 
enable_flash_ht1000(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1711 static int enable_flash_ht1000(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1712 {
1713 	uint8_t val;
1714 
1715 	/* Set the 4MB enable bit. */
1716 	val = pci_read_byte(dev, 0x41);
1717 	val |= 0x0e;
1718 	rpci_write_byte(dev, 0x41, val);
1719 
1720 	val = pci_read_byte(dev, 0x43);
1721 	val |= (1 << 4);
1722 	rpci_write_byte(dev, 0x43, val);
1723 
1724 	return 0;
1725 }
1726 
1727 /*
1728  * Usually on the x86 architectures (and on other PC-like platforms like some
1729  * Alphas or Itanium) the system flash is mapped right below 4G. On the AMD
1730  * Elan SC520 only a small piece of the system flash is mapped there, but the
1731  * complete flash is mapped somewhere below 1G. The position can be determined
1732  * by the BOOTCS PAR register.
1733  */
get_flashbase_sc520(const struct programmer_cfg * cfg,struct pci_dev * dev,const char * name)1734 static int get_flashbase_sc520(const struct programmer_cfg *cfg, struct pci_dev *dev, const char *name)
1735 {
1736 	int i, bootcs_found = 0;
1737 	uint32_t parx = 0;
1738 	void *mmcr;
1739 
1740 	/* 1. Map MMCR */
1741 	mmcr = physmap("Elan SC520 MMCR", 0xfffef000, getpagesize());
1742 	if (mmcr == ERROR_PTR)
1743 		return ERROR_FLASHROM_FATAL;
1744 
1745 	/* 2. Scan PAR0 (0x88) - PAR15 (0xc4) for
1746 	 *    BOOTCS region (PARx[31:29] = 100b)e
1747 	 */
1748 	for (i = 0x88; i <= 0xc4; i += 4) {
1749 		parx = mmio_readl(mmcr + i);
1750 		if ((parx >> 29) == 4) {
1751 			bootcs_found = 1;
1752 			break; /* BOOTCS found */
1753 		}
1754 	}
1755 
1756 	/* 3. PARx[25] = 1b --> flashbase[29:16] = PARx[13:0]
1757 	 *    PARx[25] = 0b --> flashbase[29:12] = PARx[17:0]
1758 	 */
1759 	if (bootcs_found) {
1760 		if (parx & (1 << 25)) {
1761 			parx &= (1 << 14) - 1; /* Mask [13:0] */
1762 			flashbase = parx << 16;
1763 		} else {
1764 			parx &= (1 << 18) - 1; /* Mask [17:0] */
1765 			flashbase = parx << 12;
1766 		}
1767 	} else {
1768 		msg_pinfo("AMD Elan SC520 detected, but no BOOTCS. "
1769 			  "Assuming flash at 4G.\n");
1770 	}
1771 
1772 	/* 4. Clean up */
1773 	physunmap(mmcr, getpagesize());
1774 	return 0;
1775 }
1776 
1777 #endif
1778 
1779 #define B_P	(BUS_PARALLEL)
1780 #define B_PFL	(BUS_NONSPI)
1781 #define B_PFLS	(BUS_NONSPI | BUS_SPI)
1782 #define B_FL	(BUS_FWH | BUS_LPC)
1783 #define B_FLS	(BUS_FWH | BUS_LPC | BUS_SPI)
1784 #define B_FS	(BUS_FWH | BUS_SPI)
1785 #define B_L	(BUS_LPC)
1786 #define B_LS	(BUS_LPC | BUS_SPI)
1787 #define B_S	(BUS_SPI)
1788 
1789 /* Please keep this list numerically sorted by vendor/device ID. */
1790 const struct penable chipset_enables[] = {
1791 #if defined(__i386__) || defined(__x86_64__)
1792 	{0x1002, 0x4377, B_PFL,  OK,  "ATI", "SB400",				enable_flash_sb400},
1793 	{0x1002, 0x438d, B_FLS,  OK,  "AMD", "SB600",				enable_flash_sb600},
1794 	{0x1002, 0x439d, B_FLS,  OK,  "AMD", "SB7x0/SB8x0/SB9x0",		enable_flash_sb600},
1795 	{0x100b, 0x0510, B_PFL,  NT,  "AMD", "SC1100",				enable_flash_sc1100},
1796 	{0x1022, 0x2080, B_PFL,  OK,  "AMD", "CS5536",				enable_flash_cs5536},
1797 	{0x1022, 0x2090, B_PFL,  OK,  "AMD", "CS5536",				enable_flash_cs5536},
1798 	{0x1022, 0x3000, B_PFL,  OK,  "AMD", "Elan SC520",			get_flashbase_sc520},
1799 	{0x1022, 0x7440, B_PFL,  OK,  "AMD", "AMD-768",				enable_flash_amd_768_8111},
1800 	{0x1022, 0x7468, B_PFL,  OK,  "AMD", "AMD-8111",			enable_flash_amd_768_8111},
1801 	{0x1022, 0x780e, B_FLS,  OK,  "AMD", "FCH",				enable_flash_sb600},
1802 	{0x1022, 0x790e, B_FLS,  OK,  "AMD", "FP4",				enable_flash_sb600},
1803 	{0x1039, 0x0406, B_PFL,  NT,  "SiS", "501/5101/5501",			enable_flash_sis501},
1804 	{0x1039, 0x0496, B_PFL,  NT,  "SiS", "85C496+497",			enable_flash_sis85c496},
1805 	{0x1039, 0x0530, B_PFL,  OK,  "SiS", "530",				enable_flash_sis530},
1806 	{0x1039, 0x0540, B_PFL,  NT,  "SiS", "540",				enable_flash_sis540},
1807 	{0x1039, 0x0620, B_PFL,  NT,  "SiS", "620",				enable_flash_sis530},
1808 	{0x1039, 0x0630, B_PFL,  OK,  "SiS", "630",				enable_flash_sis540},
1809 	{0x1039, 0x0635, B_PFL,  NT,  "SiS", "635",				enable_flash_sis540},
1810 	{0x1039, 0x0640, B_PFL,  NT,  "SiS", "640",				enable_flash_sis540},
1811 	{0x1039, 0x0645, B_PFL,  NT,  "SiS", "645",				enable_flash_sis540},
1812 	{0x1039, 0x0646, B_PFL,  OK,  "SiS", "645DX",				enable_flash_sis540},
1813 	{0x1039, 0x0648, B_PFL,  OK,  "SiS", "648",				enable_flash_sis540},
1814 	{0x1039, 0x0650, B_PFL,  OK,  "SiS", "650",				enable_flash_sis540},
1815 	{0x1039, 0x0651, B_PFL,  OK,  "SiS", "651",				enable_flash_sis540},
1816 	{0x1039, 0x0655, B_PFL,  NT,  "SiS", "655",				enable_flash_sis540},
1817 	{0x1039, 0x0661, B_PFL,  OK,  "SiS", "661",				enable_flash_sis540},
1818 	{0x1039, 0x0730, B_PFL,  OK,  "SiS", "730",				enable_flash_sis540},
1819 	{0x1039, 0x0733, B_PFL,  NT,  "SiS", "733",				enable_flash_sis540},
1820 	{0x1039, 0x0735, B_PFL,  OK,  "SiS", "735",				enable_flash_sis540},
1821 	{0x1039, 0x0740, B_PFL,  NT,  "SiS", "740",				enable_flash_sis540},
1822 	{0x1039, 0x0741, B_PFL,  OK,  "SiS", "741",				enable_flash_sis540},
1823 	{0x1039, 0x0745, B_PFL,  OK,  "SiS", "745",				enable_flash_sis540},
1824 	{0x1039, 0x0746, B_PFL,  NT,  "SiS", "746",				enable_flash_sis540},
1825 	{0x1039, 0x0748, B_PFL,  NT,  "SiS", "748",				enable_flash_sis540},
1826 	{0x1039, 0x0755, B_PFL,  OK,  "SiS", "755",				enable_flash_sis540},
1827 	{0x1039, 0x5511, B_PFL,  NT,  "SiS", "5511",				enable_flash_sis5511},
1828 	{0x1039, 0x5571, B_PFL,  NT,  "SiS", "5571",				enable_flash_sis530},
1829 	{0x1039, 0x5591, B_PFL,  NT,  "SiS", "5591/5592",			enable_flash_sis530},
1830 	{0x1039, 0x5596, B_PFL,  NT,  "SiS", "5596",				enable_flash_sis5511},
1831 	{0x1039, 0x5597, B_PFL,  NT,  "SiS", "5597/5598/5581/5120",		enable_flash_sis530},
1832 	{0x1039, 0x5600, B_PFL,  NT,  "SiS", "600",				enable_flash_sis530},
1833 	{0x1078, 0x0100, B_P,    OK,  "AMD", "CS5530(A)",			enable_flash_cs5530},
1834 	{0x10b9, 0x1533, B_PFL,  OK,  "ALi", "M1533",				enable_flash_ali_m1533},
1835 	{0x10de, 0x0030, B_PFL,  OK,  "NVIDIA", "nForce4/MCP4",			enable_flash_nvidia_nforce2},
1836 	{0x10de, 0x0050, B_PFL,  OK,  "NVIDIA", "CK804",			enable_flash_ck804}, /* LPC */
1837 	{0x10de, 0x0051, B_PFL,  OK,  "NVIDIA", "CK804",			enable_flash_ck804}, /* Pro */
1838 	{0x10de, 0x0060, B_PFL,  OK,  "NVIDIA", "NForce2",			enable_flash_nvidia_nforce2},
1839 	{0x10de, 0x00e0, B_PFL,  OK,  "NVIDIA", "NForce3",			enable_flash_nvidia_nforce2},
1840 	/* Slave, should not be here, to fix known bug for A01. */
1841 	{0x10de, 0x00d3, B_PFL,  OK,  "NVIDIA", "CK804",			enable_flash_ck804},
1842 	{0x10de, 0x0260, B_PFL,  OK,  "NVIDIA", "MCP51",			enable_flash_ck804},
1843 	{0x10de, 0x0261, B_PFL,  OK,  "NVIDIA", "MCP51",			enable_flash_ck804},
1844 	{0x10de, 0x0262, B_PFL,  NT,  "NVIDIA", "MCP51",			enable_flash_ck804},
1845 	{0x10de, 0x0263, B_PFL,  NT,  "NVIDIA", "MCP51",			enable_flash_ck804},
1846 	{0x10de, 0x0360, B_L,    OK,  "NVIDIA", "MCP55",			enable_flash_mcp55}, /* M57SLI*/
1847 	/* 10de:0361 is present in Tyan S2915 OEM systems, but not connected to
1848 	 * the flash chip. Instead, 10de:0364 is connected to the flash chip.
1849 	 * Until we have PCI device class matching or some fallback mechanism,
1850 	 * this is needed to get flashrom working on Tyan S2915 and maybe other
1851 	 * dual-MCP55 boards.
1852 	 */
1853 #if 0
1854 	{0x10de, 0x0361, B_L,    NT,  "NVIDIA", "MCP55",			enable_flash_mcp55}, /* LPC */
1855 #endif
1856 	{0x10de, 0x0362, B_L,    OK,  "NVIDIA", "MCP55",			enable_flash_mcp55}, /* LPC */
1857 	{0x10de, 0x0363, B_L,    OK,  "NVIDIA", "MCP55",			enable_flash_mcp55}, /* LPC */
1858 	{0x10de, 0x0364, B_L,    OK,  "NVIDIA", "MCP55",			enable_flash_mcp55}, /* LPC */
1859 	{0x10de, 0x0365, B_L,    OK,  "NVIDIA", "MCP55",			enable_flash_mcp55}, /* LPC */
1860 	{0x10de, 0x0366, B_L,    OK,  "NVIDIA", "MCP55",			enable_flash_mcp55}, /* LPC */
1861 	{0x10de, 0x0367, B_L,    OK,  "NVIDIA", "MCP55",			enable_flash_mcp55}, /* Pro */
1862 	{0x10de, 0x03e0, B_LS,   OK,  "NVIDIA", "MCP61",			enable_flash_mcp6x_7x},
1863 	{0x10de, 0x03e1, B_LS,   OK,  "NVIDIA", "MCP61",			enable_flash_mcp6x_7x},
1864 	{0x10de, 0x03e3, B_LS,   NT,  "NVIDIA", "MCP61",			enable_flash_mcp6x_7x},
1865 	{0x10de, 0x0440, B_LS,   NT,  "NVIDIA", "MCP65",			enable_flash_mcp6x_7x},
1866 	{0x10de, 0x0441, B_LS,   NT,  "NVIDIA", "MCP65",			enable_flash_mcp6x_7x},
1867 	{0x10de, 0x0442, B_LS,   NT,  "NVIDIA", "MCP65",			enable_flash_mcp6x_7x},
1868 	{0x10de, 0x0443, B_LS,   NT,  "NVIDIA", "MCP65",			enable_flash_mcp6x_7x},
1869 	{0x10de, 0x0548, B_LS,   OK,  "NVIDIA", "MCP67",			enable_flash_mcp6x_7x},
1870 	{0x10de, 0x075c, B_LS,   OK,  "NVIDIA", "MCP78S",			enable_flash_mcp6x_7x},
1871 	{0x10de, 0x075d, B_LS,   OK,  "NVIDIA", "MCP78S",			enable_flash_mcp6x_7x},
1872 	{0x10de, 0x07d7, B_LS,   OK,  "NVIDIA", "MCP73",			enable_flash_mcp6x_7x},
1873 	{0x10de, 0x0aac, B_LS,   OK,  "NVIDIA", "MCP79",			enable_flash_mcp6x_7x},
1874 	{0x10de, 0x0aad, B_LS,   NT,  "NVIDIA", "MCP79",			enable_flash_mcp6x_7x},
1875 	{0x10de, 0x0aae, B_LS,   NT,  "NVIDIA", "MCP79",			enable_flash_mcp6x_7x},
1876 	{0x10de, 0x0aaf, B_LS,   NT,  "NVIDIA", "MCP79",			enable_flash_mcp6x_7x},
1877 	{0x10de, 0x0d80, B_LS,   NT,  "NVIDIA", "MCP89",			enable_flash_mcp6x_7x},
1878 	/* VIA northbridges */
1879 	{0x1106, 0x0585, B_PFLS, NT,  "VIA", "VT82C585VPX",			via_no_byte_merge},
1880 	{0x1106, 0x0595, B_PFLS, NT,  "VIA", "VT82C595",			via_no_byte_merge},
1881 	{0x1106, 0x0597, B_PFLS, NT,  "VIA", "VT82C597",			via_no_byte_merge},
1882 	{0x1106, 0x0601, B_PFLS, NT,  "VIA", "VT8601/VT8601A",			via_no_byte_merge},
1883 	{0x1106, 0x0691, B_PFLS, OK,  "VIA", "VT82C69x",			via_no_byte_merge},
1884 	{0x1106, 0x8601, B_PFLS, NT,  "VIA", "VT8601T",				via_no_byte_merge},
1885 	/* VIA southbridges */
1886 	{0x1106, 0x0586, B_PFL,  OK,  "VIA", "VT82C586A/B",			enable_flash_vt82c586},
1887 	{0x1106, 0x0596, B_PFL,  OK,  "VIA", "VT82C596",			enable_flash_vt82c596},
1888 	{0x1106, 0x0686, B_PFL,  OK,  "VIA", "VT82C686A/B",			enable_flash_vt82c596},
1889 	{0x1106, 0x3074, B_FL,   OK,  "VIA", "VT8233",				enable_flash_vt823x},
1890 	{0x1106, 0x3147, B_FL,   OK,  "VIA", "VT8233A",				enable_flash_vt823x},
1891 	{0x1106, 0x3177, B_FL,   OK,  "VIA", "VT8235",				enable_flash_vt823x},
1892 	{0x1106, 0x3227, B_FL,   OK,  "VIA", "VT8237(R)",			enable_flash_vt823x},
1893 	{0x1106, 0x3287, B_FL,   OK,  "VIA", "VT8251",				enable_flash_vt823x},
1894 	{0x1106, 0x3337, B_FL,   OK,  "VIA", "VT8237A",				enable_flash_vt823x},
1895 	{0x1106, 0x3372, B_LS,   OK,  "VIA", "VT8237S",				enable_flash_vt8237s_spi},
1896 	{0x1106, 0x8231, B_FL,   NT,  "VIA", "VT8231",				enable_flash_vt823x},
1897 	{0x1106, 0x8324, B_FL,   OK,  "VIA", "CX700",				enable_flash_vt823x},
1898 	{0x1106, 0x8353, B_FLS,  NT,  "VIA", "VX800/VX820",			enable_flash_vt_vx},
1899 	{0x1106, 0x8409, B_FLS,  OK,  "VIA", "VX855/VX875",			enable_flash_vt_vx},
1900 	{0x1106, 0x8410, B_FLS,  OK,  "VIA", "VX900",				enable_flash_vt_vx},
1901 	{0x1166, 0x0200, B_P,    OK,  "Broadcom", "OSB4",			enable_flash_osb4},
1902 	{0x1166, 0x0205, B_PFL,  OK,  "Broadcom", "HT-1000",			enable_flash_ht1000},
1903 	{0x17f3, 0x6030, B_PFL,  OK,  "RDC", "R8610/R3210",			enable_flash_rdc_r8610},
1904 	{0x8086, 0x0c60, B_FS,   NT,  "Intel", "S12x0",				enable_flash_s12x0},
1905 	{0x8086, 0x0f1c, B_FS,   OK,  "Intel", "Bay Trail",			enable_flash_silvermont},
1906 	{0x8086, 0x0f1d, B_FS,   NT,  "Intel", "Bay Trail",			enable_flash_silvermont},
1907 	{0x8086, 0x0f1e, B_FS,   NT,  "Intel", "Bay Trail",			enable_flash_silvermont},
1908 	{0x8086, 0x0f1f, B_FS,   NT,  "Intel", "Bay Trail",			enable_flash_silvermont},
1909 	{0x8086, 0x122e, B_P,    OK,  "Intel", "PIIX",				enable_flash_piix4},
1910 	{0x8086, 0x1234, B_P,    NT,  "Intel", "MPIIX",				enable_flash_piix4},
1911 	{0x8086, 0x1c44, B_FS,   DEP, "Intel", "Z68",				enable_flash_pch6},
1912 	{0x8086, 0x1c46, B_FS,   DEP, "Intel", "P67",				enable_flash_pch6},
1913 	{0x8086, 0x1c47, B_FS,   NT,  "Intel", "UM67",				enable_flash_pch6},
1914 	{0x8086, 0x1c49, B_FS,   DEP, "Intel", "HM65",				enable_flash_pch6},
1915 	{0x8086, 0x1c4a, B_FS,   DEP, "Intel", "H67",				enable_flash_pch6},
1916 	{0x8086, 0x1c4b, B_FS,   NT,  "Intel", "HM67",				enable_flash_pch6},
1917 	{0x8086, 0x1c4c, B_FS,   NT,  "Intel", "Q65",				enable_flash_pch6},
1918 	{0x8086, 0x1c4d, B_FS,   DEP, "Intel", "QS67",				enable_flash_pch6},
1919 	{0x8086, 0x1c4e, B_FS,   DEP, "Intel", "Q67",				enable_flash_pch6},
1920 	{0x8086, 0x1c4f, B_FS,   DEP, "Intel", "QM67",				enable_flash_pch6},
1921 	{0x8086, 0x1c50, B_FS,   NT,  "Intel", "B65",				enable_flash_pch6},
1922 	{0x8086, 0x1c52, B_FS,   NT,  "Intel", "C202",				enable_flash_pch6},
1923 	{0x8086, 0x1c54, B_FS,   DEP, "Intel", "C204",				enable_flash_pch6},
1924 	{0x8086, 0x1c56, B_FS,   NT,  "Intel", "C206",				enable_flash_pch6},
1925 	{0x8086, 0x1c5c, B_FS,   DEP, "Intel", "H61",				enable_flash_pch6},
1926 	{0x8086, 0x1d40, B_FS,   DEP, "Intel", "C60x/X79",			enable_flash_pch6},
1927 	{0x8086, 0x1d41, B_FS,   DEP, "Intel", "C60x/X79",			enable_flash_pch6},
1928 	{0x8086, 0x1e41, B_FS,   DEP, "Intel", "Desktop Sample",		enable_flash_pch7},
1929 	{0x8086, 0x1e42, B_FS,   DEP, "Intel", "Mobile Sample",			enable_flash_pch7},
1930 	{0x8086, 0x1e43, B_FS,   DEP, "Intel", "SFF Sample",			enable_flash_pch7},
1931 	{0x8086, 0x1e44, B_FS,   DEP, "Intel", "Z77",				enable_flash_pch7},
1932 	{0x8086, 0x1e46, B_FS,   NT,  "Intel", "Z75",				enable_flash_pch7},
1933 	{0x8086, 0x1e47, B_FS,   DEP, "Intel", "Q77",				enable_flash_pch7},
1934 	{0x8086, 0x1e48, B_FS,   DEP, "Intel", "Q75",				enable_flash_pch7},
1935 	{0x8086, 0x1e49, B_FS,   DEP, "Intel", "B75",				enable_flash_pch7},
1936 	{0x8086, 0x1e4a, B_FS,   DEP, "Intel", "H77",				enable_flash_pch7},
1937 	{0x8086, 0x1e53, B_FS,   DEP, "Intel", "C216",				enable_flash_pch7},
1938 	{0x8086, 0x1e55, B_FS,   DEP, "Intel", "QM77",				enable_flash_pch7},
1939 	{0x8086, 0x1e56, B_FS,   DEP, "Intel", "QS77",				enable_flash_pch7},
1940 	{0x8086, 0x1e57, B_FS,   DEP, "Intel", "HM77",				enable_flash_pch7},
1941 	{0x8086, 0x1e58, B_FS,   NT,  "Intel", "UM77",				enable_flash_pch7},
1942 	{0x8086, 0x1e59, B_FS,   DEP, "Intel", "HM76",				enable_flash_pch7},
1943 	{0x8086, 0x1e5d, B_FS,   DEP, "Intel", "HM75",				enable_flash_pch7},
1944 	{0x8086, 0x1e5e, B_FS,   NT,  "Intel", "HM70",				enable_flash_pch7},
1945 	{0x8086, 0x1e5f, B_FS,   DEP, "Intel", "NM70",				enable_flash_pch7},
1946 	{0x8086, 0x1f38, B_FS,   DEP, "Intel", "Avoton/Rangeley",		enable_flash_silvermont},
1947 	{0x8086, 0x1f39, B_FS,   NT,  "Intel", "Avoton/Rangeley",		enable_flash_silvermont},
1948 	{0x8086, 0x1f3a, B_FS,   NT,  "Intel", "Avoton/Rangeley",		enable_flash_silvermont},
1949 	{0x8086, 0x1f3b, B_FS,   NT,  "Intel", "Avoton/Rangeley",		enable_flash_silvermont},
1950 	{0x8086, 0x229c, B_FS,   OK,  "Intel", "Braswell",			enable_flash_silvermont},
1951 	{0x8086, 0x2310, B_FS,   NT,  "Intel", "DH89xxCC (Cave Creek)",		enable_flash_pch7},
1952 	{0x8086, 0x2390, B_FS,   NT,  "Intel", "Coleto Creek",			enable_flash_pch7},
1953 	{0x8086, 0x2410, B_FL,   OK,  "Intel", "ICH",				enable_flash_ich0},
1954 	{0x8086, 0x2420, B_FL,   OK,  "Intel", "ICH0",				enable_flash_ich0},
1955 	{0x8086, 0x2440, B_FL,   OK,  "Intel", "ICH2",				enable_flash_ich2345},
1956 	{0x8086, 0x244c, B_FL,   OK,  "Intel", "ICH2-M",			enable_flash_ich2345},
1957 	{0x8086, 0x2450, B_FL,   NT,  "Intel", "C-ICH",				enable_flash_ich2345},
1958 	{0x8086, 0x2480, B_FL,   OK,  "Intel", "ICH3-S",			enable_flash_ich2345},
1959 	{0x8086, 0x248c, B_FL,   OK,  "Intel", "ICH3-M",			enable_flash_ich2345},
1960 	{0x8086, 0x24c0, B_FL,   OK,  "Intel", "ICH4/ICH4-L",			enable_flash_ich2345},
1961 	{0x8086, 0x24cc, B_FL,   OK,  "Intel", "ICH4-M",			enable_flash_ich2345},
1962 	{0x8086, 0x24d0, B_FL,   OK,  "Intel", "ICH5/ICH5R",			enable_flash_ich2345},
1963 	{0x8086, 0x25a1, B_FL,   OK,  "Intel", "6300ESB",			enable_flash_ich2345},
1964 	{0x8086, 0x2640, B_FL,   OK,  "Intel", "ICH6/ICH6R",			enable_flash_ich6},
1965 	{0x8086, 0x2641, B_FL,   OK,  "Intel", "ICH6-M",			enable_flash_ich6},
1966 	{0x8086, 0x2642, B_FL,   NT,  "Intel", "ICH6W/ICH6RW",			enable_flash_ich6},
1967 	{0x8086, 0x2670, B_FL,   OK,  "Intel", "631xESB/632xESB/3100",		enable_flash_ich6},
1968 	{0x8086, 0x27b0, B_FS,   OK,  "Intel", "ICH7DH",			enable_flash_ich7},
1969 	{0x8086, 0x27b8, B_FS,   OK,  "Intel", "ICH7/ICH7R",			enable_flash_ich7},
1970 	{0x8086, 0x27b9, B_FS,   OK,  "Intel", "ICH7M",				enable_flash_ich7},
1971 	{0x8086, 0x27bc, B_FS,   OK,  "Intel", "NM10",				enable_flash_ich7},
1972 	{0x8086, 0x27bd, B_FS,   OK,  "Intel", "ICH7MDH",			enable_flash_ich7},
1973 	{0x8086, 0x2810, B_FS,   DEP, "Intel", "ICH8/ICH8R",			enable_flash_ich8},
1974 	{0x8086, 0x2811, B_FS,   DEP, "Intel", "ICH8M-E",			enable_flash_ich8},
1975 	{0x8086, 0x2812, B_FS,   DEP, "Intel", "ICH8DH",			enable_flash_ich8},
1976 	{0x8086, 0x2814, B_FS,   DEP, "Intel", "ICH8DO",			enable_flash_ich8},
1977 	{0x8086, 0x2815, B_FS,   DEP, "Intel", "ICH8M",				enable_flash_ich8},
1978 	{0x8086, 0x2910, B_FS,   DEP, "Intel", "ICH9 Eng. Sample",		enable_flash_ich9},
1979 	{0x8086, 0x2912, B_FS,   DEP, "Intel", "ICH9DH",			enable_flash_ich9},
1980 	{0x8086, 0x2914, B_FS,   DEP, "Intel", "ICH9DO",			enable_flash_ich9},
1981 	{0x8086, 0x2916, B_FS,   DEP, "Intel", "ICH9R",				enable_flash_ich9},
1982 	{0x8086, 0x2917, B_FS,   DEP, "Intel", "ICH9M-E",			enable_flash_ich9},
1983 	{0x8086, 0x2918, B_FS,   DEP, "Intel", "ICH9",				enable_flash_ich9},
1984 	{0x8086, 0x2919, B_FS,   DEP, "Intel", "ICH9M",				enable_flash_ich9},
1985 	{0x8086, 0x3a10, B_FS,   NT,  "Intel", "ICH10R Eng. Sample",		enable_flash_ich10},
1986 	{0x8086, 0x3a14, B_FS,   DEP, "Intel", "ICH10DO",			enable_flash_ich10},
1987 	{0x8086, 0x3a16, B_FS,   DEP, "Intel", "ICH10R",			enable_flash_ich10},
1988 	{0x8086, 0x3a18, B_FS,   DEP, "Intel", "ICH10",				enable_flash_ich10},
1989 	{0x8086, 0x3a1a, B_FS,   DEP, "Intel", "ICH10D",			enable_flash_ich10},
1990 	{0x8086, 0x3a1e, B_FS,   NT,  "Intel", "ICH10 Eng. Sample",		enable_flash_ich10},
1991 	{0x8086, 0x3b00, B_FS,   NT,  "Intel", "3400 Desktop",			enable_flash_pch5},
1992 	{0x8086, 0x3b01, B_FS,   NT,  "Intel", "3400 Mobile",			enable_flash_pch5},
1993 	{0x8086, 0x3b02, B_FS,   NT,  "Intel", "P55",				enable_flash_pch5},
1994 	{0x8086, 0x3b03, B_FS,   DEP, "Intel", "PM55",				enable_flash_pch5},
1995 	{0x8086, 0x3b06, B_FS,   DEP, "Intel", "H55",				enable_flash_pch5},
1996 	{0x8086, 0x3b07, B_FS,   DEP, "Intel", "QM57",				enable_flash_pch5},
1997 	{0x8086, 0x3b08, B_FS,   NT,  "Intel", "H57",				enable_flash_pch5},
1998 	{0x8086, 0x3b09, B_FS,   DEP, "Intel", "HM55",				enable_flash_pch5},
1999 	{0x8086, 0x3b0a, B_FS,   NT,  "Intel", "Q57",				enable_flash_pch5},
2000 	{0x8086, 0x3b0b, B_FS,   NT,  "Intel", "HM57",				enable_flash_pch5},
2001 	{0x8086, 0x3b0d, B_FS,   NT,  "Intel", "3400 Mobile SFF",		enable_flash_pch5},
2002 	{0x8086, 0x3b0e, B_FS,   NT,  "Intel", "B55",				enable_flash_pch5},
2003 	{0x8086, 0x3b0f, B_FS,   DEP, "Intel", "QS57",				enable_flash_pch5},
2004 	{0x8086, 0x3b12, B_FS,   NT,  "Intel", "3400",				enable_flash_pch5},
2005 	{0x8086, 0x3b14, B_FS,   DEP, "Intel", "3420",				enable_flash_pch5},
2006 	{0x8086, 0x3b16, B_FS,   NT,  "Intel", "3450",				enable_flash_pch5},
2007 	{0x8086, 0x3b1e, B_FS,   NT,  "Intel", "B55",				enable_flash_pch5},
2008 	{0x8086, 0x5031, B_FS,   OK,  "Intel", "EP80579",			enable_flash_ich7},
2009 	{0x8086, 0x7000, B_P,    OK,  "Intel", "PIIX3",				enable_flash_piix4},
2010 	{0x8086, 0x7110, B_P,    OK,  "Intel", "PIIX4/4E/4M",			enable_flash_piix4},
2011 	{0x8086, 0x7198, B_P,    OK,  "Intel", "440MX",				enable_flash_piix4},
2012 	{0x8086, 0x8119, B_FL,   OK,  "Intel", "SCH Poulsbo",			enable_flash_poulsbo},
2013 	{0x8086, 0x8186, B_FS,   OK,  "Intel", "Atom E6xx(T) (Tunnel Creek)",	enable_flash_tunnelcreek},
2014 	{0x8086, 0x8c40, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2015 	{0x8086, 0x8c41, B_FS,   NT,  "Intel", "Lynx Point Mobile Eng. Sample",	enable_flash_pch8},
2016 	{0x8086, 0x8c42, B_FS,   NT,  "Intel", "Lynx Point Desktop Eng. Sample",enable_flash_pch8},
2017 	{0x8086, 0x8c43, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2018 	{0x8086, 0x8c44, B_FS,   DEP, "Intel", "Z87",				enable_flash_pch8},
2019 	{0x8086, 0x8c45, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2020 	{0x8086, 0x8c46, B_FS,   NT,  "Intel", "Z85",				enable_flash_pch8},
2021 	{0x8086, 0x8c47, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2022 	{0x8086, 0x8c48, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2023 	{0x8086, 0x8c49, B_FS,   NT,  "Intel", "HM86",				enable_flash_pch8},
2024 	{0x8086, 0x8c4a, B_FS,   DEP, "Intel", "H87",				enable_flash_pch8},
2025 	{0x8086, 0x8c4b, B_FS,   DEP, "Intel", "HM87",				enable_flash_pch8},
2026 	{0x8086, 0x8c4c, B_FS,   NT,  "Intel", "Q85",				enable_flash_pch8},
2027 	{0x8086, 0x8c4d, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2028 	{0x8086, 0x8c4e, B_FS,   NT,  "Intel", "Q87",				enable_flash_pch8},
2029 	{0x8086, 0x8c4f, B_FS,   NT,  "Intel", "QM87",				enable_flash_pch8},
2030 	{0x8086, 0x8c50, B_FS,   DEP, "Intel", "B85",				enable_flash_pch8},
2031 	{0x8086, 0x8c51, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2032 	{0x8086, 0x8c52, B_FS,   NT,  "Intel", "C222",				enable_flash_pch8},
2033 	{0x8086, 0x8c53, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2034 	{0x8086, 0x8c54, B_FS,   DEP, "Intel", "C224",				enable_flash_pch8},
2035 	{0x8086, 0x8c55, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2036 	{0x8086, 0x8c56, B_FS,   NT,  "Intel", "C226",				enable_flash_pch8},
2037 	{0x8086, 0x8c57, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2038 	{0x8086, 0x8c58, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2039 	{0x8086, 0x8c59, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2040 	{0x8086, 0x8c5a, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2041 	{0x8086, 0x8c5b, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2042 	{0x8086, 0x8c5c, B_FS,   DEP, "Intel", "H81",				enable_flash_pch8},
2043 	{0x8086, 0x8c5d, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2044 	{0x8086, 0x8c5e, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2045 	{0x8086, 0x8c5f, B_FS,   NT,  "Intel", "Lynx Point",			enable_flash_pch8},
2046 	{0x8086, 0x8cc1, B_FS,   NT,  "Intel", "9 Series",			enable_flash_pch9},
2047 	{0x8086, 0x8cc2, B_FS,   NT,  "Intel", "9 Series Engineering Sample",	enable_flash_pch9},
2048 	{0x8086, 0x8cc3, B_FS,   NT,  "Intel", "9 Series",			enable_flash_pch9},
2049 	{0x8086, 0x8cc4, B_FS,   DEP, "Intel", "Z97",				enable_flash_pch9},
2050 	{0x8086, 0x8cc6, B_FS,   DEP,  "Intel", "H97",				enable_flash_pch9},
2051 	{0x8086, 0x8d40, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2052 	{0x8086, 0x8d41, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2053 	{0x8086, 0x8d42, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2054 	{0x8086, 0x8d43, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2055 	{0x8086, 0x8d44, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2056 	{0x8086, 0x8d45, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2057 	{0x8086, 0x8d46, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2058 	{0x8086, 0x8d47, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2059 	{0x8086, 0x8d48, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2060 	{0x8086, 0x8d49, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2061 	{0x8086, 0x8d4a, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2062 	{0x8086, 0x8d4b, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2063 	{0x8086, 0x8d4c, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2064 	{0x8086, 0x8d4d, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2065 	{0x8086, 0x8d4e, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2066 	{0x8086, 0x8d4f, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2067 	{0x8086, 0x8d50, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2068 	{0x8086, 0x8d51, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2069 	{0x8086, 0x8d52, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2070 	{0x8086, 0x8d53, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2071 	{0x8086, 0x8d54, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2072 	{0x8086, 0x8d55, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2073 	{0x8086, 0x8d56, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2074 	{0x8086, 0x8d57, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2075 	{0x8086, 0x8d58, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2076 	{0x8086, 0x8d59, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2077 	{0x8086, 0x8d5a, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2078 	{0x8086, 0x8d5b, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2079 	{0x8086, 0x8d5c, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2080 	{0x8086, 0x8d5d, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2081 	{0x8086, 0x8d5e, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2082 	{0x8086, 0x8d5f, B_FS,   NT,  "Intel", "C610/X99 (Wellsburg)",		enable_flash_pch8_wb},
2083 	{0x8086, 0x9c41, B_FS,   NT,  "Intel", "Lynx Point LP Eng. Sample",	enable_flash_pch8_lp},
2084 	{0x8086, 0x9c43, B_FS,   NT,  "Intel", "Lynx Point LP Premium",		enable_flash_pch8_lp},
2085 	{0x8086, 0x9c45, B_FS,   NT,  "Intel", "Lynx Point LP Mainstream",	enable_flash_pch8_lp},
2086 	{0x8086, 0x9c47, B_FS,   NT,  "Intel", "Lynx Point LP Value",		enable_flash_pch8_lp},
2087 	{0x8086, 0x9cc1, B_FS,   NT,  "Intel", "Haswell U Sample",		enable_flash_pch9_lp},
2088 	{0x8086, 0x9cc2, B_FS,   NT,  "Intel", "Broadwell U Sample",		enable_flash_pch9_lp},
2089 	{0x8086, 0x9cc3, B_FS,   DEP, "Intel", "Broadwell U Premium",		enable_flash_pch9_lp},
2090 	{0x8086, 0x9cc5, B_FS,   DEP, "Intel", "Broadwell U Base",		enable_flash_pch9_lp},
2091 	{0x8086, 0x9cc6, B_FS,   NT,  "Intel", "Broadwell Y Sample",		enable_flash_pch9_lp},
2092 	{0x8086, 0x9cc7, B_FS,   NT,  "Intel", "Broadwell Y Premium",		enable_flash_pch9_lp},
2093 	{0x8086, 0x9cc9, B_FS,   NT,  "Intel", "Broadwell Y Base",		enable_flash_pch9_lp},
2094 	{0x8086, 0x9ccb, B_FS,   NT,  "Intel", "Broadwell H",			enable_flash_pch9},
2095 	{0x8086, 0x9d41, B_S,    NT,  "Intel", "Skylake / Kaby Lake Sample",	enable_flash_pch100},
2096 	{0x8086, 0x9d43, B_S,    NT,  "Intel", "Skylake U Base",		enable_flash_pch100},
2097 	{0x8086, 0x9d46, B_S,    NT,  "Intel", "Skylake Y Premium",		enable_flash_pch100},
2098 	{0x8086, 0x9d48, B_S,    DEP, "Intel", "Skylake U Premium",		enable_flash_pch100},
2099 	{0x8086, 0x9d4b, B_S,    NT,  "Intel", "Kaby Lake Y w/ iHDCP2.2 Prem.",	enable_flash_pch100},
2100 	{0x8086, 0x9d4e, B_S,    DEP, "Intel", "Kaby Lake U w/ iHDCP2.2 Prem.",	enable_flash_pch100},
2101 	{0x8086, 0x9d50, B_S,    NT,  "Intel", "Kaby Lake U w/ iHDCP2.2 Base",	enable_flash_pch100},
2102 	{0x8086, 0x9d51, B_S,    NT,  "Intel", "Kabe Lake w/ iHDCP2.2 Sample",	enable_flash_pch100},
2103 	{0x8086, 0x9d53, B_S,    NT,  "Intel", "Kaby Lake U Base",		enable_flash_pch100},
2104 	{0x8086, 0x9d56, B_S,    NT,  "Intel", "Kaby Lake Y Premium",		enable_flash_pch100},
2105 	{0x8086, 0x9d58, B_S,    NT,  "Intel", "Kaby Lake U Premium",		enable_flash_pch100},
2106 	{0x8086, 0x9d84, B_S,    DEP, "Intel", "Cannon Lake U Premium",		enable_flash_pch300},
2107 	{0x8086, 0x0284, B_S,    DEP, "Intel", "Comet Lake U Premium",		enable_flash_pch400},
2108 	{0x8086, 0x0285, B_S,    DEP, "Intel", "Comet Lake U Base",		enable_flash_pch400},
2109 	{0x8086, 0xa082, B_S,    DEP, "Intel", "Tiger Lake U Premium",		enable_flash_pch500},
2110 	{0x8086, 0xa088, B_S,    DEP, "Intel", "Tiger Lake UP3",		enable_flash_pch500},
2111 	{0x8086, 0xa141, B_S,    NT,  "Intel", "Sunrise Point Desktop Sample",	enable_flash_pch100},
2112 	{0x8086, 0xa142, B_S,    NT,  "Intel", "Sunrise Point Unknown Sample",	enable_flash_pch100},
2113 	{0x8086, 0xa143, B_S,    DEP, "Intel", "H110",				enable_flash_pch100},
2114 	{0x8086, 0xa144, B_S,    NT,  "Intel", "H170",				enable_flash_pch100},
2115 	{0x8086, 0xa145, B_S,    NT,  "Intel", "Z170",				enable_flash_pch100},
2116 	{0x8086, 0xa146, B_S,    NT,  "Intel", "Q170",				enable_flash_pch100},
2117 	{0x8086, 0xa147, B_S,    NT,  "Intel", "Q150",				enable_flash_pch100},
2118 	{0x8086, 0xa148, B_S,    NT,  "Intel", "B150",				enable_flash_pch100},
2119 	{0x8086, 0xa149, B_S,    NT,  "Intel", "C236",				enable_flash_pch100},
2120 	{0x8086, 0xa14a, B_S,    NT,  "Intel", "C232",				enable_flash_pch100},
2121 	{0x8086, 0xa14b, B_S,    NT,  "Intel", "Sunrise Point Server Sample",	enable_flash_pch100},
2122 	{0x8086, 0xa14d, B_S,    NT,  "Intel", "QM170",				enable_flash_pch100},
2123 	{0x8086, 0xa14e, B_S,    NT,  "Intel", "HM170",				enable_flash_pch100},
2124 	{0x8086, 0xa150, B_S,    DEP, "Intel", "CM236",				enable_flash_pch100},
2125 	{0x8086, 0xa151, B_S,    NT,  "Intel", "QMS180",			enable_flash_pch100},
2126 	{0x8086, 0xa152, B_S,    NT,  "Intel", "HM175",				enable_flash_pch100},
2127 	{0x8086, 0xa153, B_S,    NT,  "Intel", "QM175",				enable_flash_pch100},
2128 	{0x8086, 0xa154, B_S,    NT,  "Intel", "CM238",				enable_flash_pch100},
2129 	{0x8086, 0xa155, B_S,    NT,  "Intel", "QMU185",			enable_flash_pch100},
2130 	{0x8086, 0xa1a4, B_S,    DEP, "Intel", "C620 Series Chipset (QS/PRQ)",  enable_flash_c620},
2131 	{0x8086, 0xa1c0, B_S,    NT,  "Intel", "C620 Series Chipset (QS/PRQ)",	enable_flash_c620},
2132 	{0x8086, 0xa1c1, B_S,    NT,  "Intel", "C621 Series Chipset (QS/PRQ)",	enable_flash_c620},
2133 	{0x8086, 0xa1c2, B_S,    NT,  "Intel", "C622 Series Chipset (QS/PRQ)",	enable_flash_c620},
2134 	{0x8086, 0xa1c3, B_S,    NT,  "Intel", "C624 Series Chipset (QS/PRQ)",	enable_flash_c620},
2135 	{0x8086, 0xa1c4, B_S,    NT,  "Intel", "C625 Series Chipset (QS/PRQ)",	enable_flash_c620},
2136 	{0x8086, 0xa1c5, B_S,    NT,  "Intel", "C626 Series Chipset (QS/PRQ)",	enable_flash_c620},
2137 	{0x8086, 0xa1c6, B_S,    NT,  "Intel", "C627 Series Chipset (QS/PRQ)",	enable_flash_c620},
2138 	{0x8086, 0xa1c7, B_S,    NT,  "Intel", "C628 Series Chipset (QS/PRQ)",	enable_flash_c620},
2139 	{0x8086, 0xa1c8, B_S,    NT,  "Intel", "C620 Series Chipset (QS/PRQ)",	enable_flash_c620},
2140 	{0x8086, 0xa1c9, B_S,    NT,  "Intel", "C620 Series Chipset (QS/PRQ)",	enable_flash_c620},
2141 	{0x8086, 0xa1ca, B_S,    NT,  "Intel", "C629 Series Chipset (QS/PRQ)",	enable_flash_c620},
2142 	{0x8086, 0xa1cb, B_S,    NT,  "Intel", "C621A Series Chipset (QS/PRQ)",	enable_flash_c620},
2143 	{0x8086, 0xa1cc, B_S,    NT,  "Intel", "C627A Series Chipset (QS/PRQ)",	enable_flash_c620},
2144 	{0x8086, 0xa1cd, B_S,    NT,  "Intel", "C629A Series Chipset (QS/PRQ)",	enable_flash_c620},
2145 	{0x8086, 0xa240, B_S,    NT,  "Intel", "C620 Series Chipset Supersku",	enable_flash_c620},
2146 	{0x8086, 0xa241, B_S,    NT,  "Intel", "C620 Series Chipset Supersku",	enable_flash_c620},
2147 	{0x8086, 0xa242, B_S,    NT,  "Intel", "C624 Series Chipset Supersku",	enable_flash_c620},
2148 	{0x8086, 0xa243, B_S,    NT,  "Intel", "C627 Series Chipset Supersku",	enable_flash_c620},
2149 	{0x8086, 0xa244, B_S,    NT,  "Intel", "C621 Series Chipset Supersku",	enable_flash_c620},
2150 	{0x8086, 0xa245, B_S,    NT,  "Intel", "C627 Series Chipset Supersku",	enable_flash_c620},
2151 	{0x8086, 0xa246, B_S,    NT,  "Intel", "C628 Series Chipset Supersku",	enable_flash_c620},
2152 	{0x8086, 0xa247, B_S,    NT,  "Intel", "C620 Series Chipset Supersku",	enable_flash_c620},
2153 	{0x8086, 0xa248, B_S,    NT,  "Intel", "C620 Series Chipset Supersku",	enable_flash_c620},
2154 	{0x8086, 0xa249, B_S,    NT,  "Intel", "C620 Series Chipset Supersku",	enable_flash_c620},
2155 	{0x8086, 0x1bca, B_S,    DEP, "Intel", "Emmitsburg Chipset SKU",	enable_flash_c740},
2156 	{0x8086, 0xa2c4, B_S,    NT,  "Intel", "H270",				enable_flash_pch100},
2157 	{0x8086, 0xa2c5, B_S,    NT,  "Intel", "Z270",				enable_flash_pch100},
2158 	{0x8086, 0xa2c6, B_S,    NT,  "Intel", "Q270",				enable_flash_pch100},
2159 	{0x8086, 0xa2c7, B_S,    NT,  "Intel", "Q250",				enable_flash_pch100},
2160 	{0x8086, 0xa2c8, B_S,    NT,  "Intel", "B250",				enable_flash_pch100},
2161 	{0x8086, 0xa2c9, B_S,    NT,  "Intel", "Z370",				enable_flash_pch100},
2162 	{0x8086, 0xa2ca, B_S,    DEP, "Intel", "H310C",				enable_flash_pch100},
2163 	{0x8086, 0xa2cc, B_S,    DEP, "Intel", "B365",				enable_flash_pch100},
2164 	{0x8086, 0xa2d2, B_S,    NT,  "Intel", "X299",				enable_flash_pch100},
2165 	{0x8086, 0x5ae8, B_S,    DEP, "Intel", "Apollo Lake",			enable_flash_apl},
2166 	{0x8086, 0x5af0, B_S,    DEP, "Intel", "Apollo Lake",			enable_flash_apl},
2167 	{0x8086, 0x3197, B_S,    NT,  "Intel", "Gemini Lake",			enable_flash_glk},
2168 	{0x8086, 0x31e8, B_S,    DEP, "Intel", "Gemini Lake",			enable_flash_glk},
2169 	{0x8086, 0x4da4, B_S,    DEP, "Intel", "Jasper Lake",			enable_flash_jsl},
2170 	{0x8086, 0x4b24, B_S,    DEP, "Intel", "Elkhart Lake",			enable_flash_mcc},
2171 	{0x8086, 0xa303, B_S,    NT,  "Intel", "H310",				enable_flash_pch300},
2172 	{0x8086, 0xa304, B_S,    NT,  "Intel", "H370",				enable_flash_pch300},
2173 	{0x8086, 0xa305, B_S,    DEP, "Intel", "Z390",				enable_flash_pch300},
2174 	{0x8086, 0xa306, B_S,    NT,  "Intel", "Q370",				enable_flash_pch300},
2175 	{0x8086, 0xa308, B_S,    NT,  "Intel", "B360",				enable_flash_pch300},
2176 	{0x8086, 0xa309, B_S,    DEP, "Intel", "C246",				enable_flash_pch300},
2177 	{0x8086, 0xa30a, B_S,    NT,  "Intel", "C242",				enable_flash_pch300},
2178 	{0x8086, 0xa30c, B_S,    NT,  "Intel", "QM370",				enable_flash_pch300},
2179 	{0x8086, 0xa30d, B_S,    NT,  "Intel", "HM370",				enable_flash_pch300},
2180 	{0x8086, 0xa30e, B_S,    DEP, "Intel", "CM246",				enable_flash_pch300},
2181 	{0x8086, 0x3482, B_S,    DEP, "Intel", "Ice Lake U Premium",		enable_flash_pch300},
2182 	{0x8086, 0xa3c8, B_S,    OK,  "Intel", "B460",				enable_flash_pch400},
2183 	{0x8086, 0x0684, B_S,    NT,  "Intel", "H470",				enable_flash_pch400},
2184 	{0x8086, 0x0685, B_S,    NT,  "Intel", "Z490",				enable_flash_pch400},
2185 	{0x8086, 0x0687, B_S,    NT,  "Intel", "Q470",				enable_flash_pch400},
2186 	{0x8086, 0x068c, B_S,    NT,  "Intel", "QM480",				enable_flash_pch400},
2187 	{0x8086, 0x068d, B_S,    NT,  "Intel", "HM470",				enable_flash_pch400},
2188 	{0x8086, 0x068e, B_S,    NT,  "Intel", "WM490",				enable_flash_pch400},
2189 	{0x8086, 0x0697, B_S,    NT,  "Intel", "W480",				enable_flash_pch400},
2190 	{0x8086, 0x4384, B_S,    NT,  "Intel", "Q570",				enable_flash_pch500},
2191 	{0x8086, 0x4385, B_S,    NT,  "Intel", "Z590",				enable_flash_pch500},
2192 	{0x8086, 0x4386, B_S,    NT,  "Intel", "H570",				enable_flash_pch500},
2193 	{0x8086, 0x4387, B_S,    NT,  "Intel", "B560",				enable_flash_pch500},
2194 	{0x8086, 0x4388, B_S,    NT,  "Intel", "H510",				enable_flash_pch500},
2195 	{0x8086, 0x438f, B_S,    NT,  "Intel", "W580",				enable_flash_pch500},
2196 	{0x8086, 0x4389, B_S,    NT,  "Intel", "WM590",				enable_flash_pch500},
2197 	{0x8086, 0x438a, B_S,    NT,  "Intel", "QM580",				enable_flash_pch500},
2198 	{0x8086, 0x438b, B_S,    DEP, "Intel", "HM570",				enable_flash_pch500},
2199 	{0x8086, 0x54a4, B_S,    DEP, "Intel", "Alder Lake-N",			enable_flash_pch600},
2200 	{0x8086, 0x51a4, B_S,    DEP, "Intel", "Alder Lake-P",			enable_flash_pch600},
2201 	{0x8086, 0x7a87, B_S,    NT,  "Intel", "H610",				enable_flash_pch600},
2202 	{0x8086, 0x7a86, B_S,    NT,  "Intel", "B660",				enable_flash_pch600},
2203 	{0x8086, 0x7a85, B_S,    NT,  "Intel", "H670",				enable_flash_pch600},
2204 	{0x8086, 0x7a83, B_S,    NT,  "Intel", "Q670",				enable_flash_pch600},
2205 	{0x8086, 0x7a84, B_S,    DEP, "Intel", "Z690",				enable_flash_pch600},
2206 	{0x8086, 0x7a88, B_S,    NT,  "Intel", "W680",				enable_flash_pch600},
2207 	{0x8086, 0x7a8d, B_S,    NT,  "Intel", "WM690",				enable_flash_pch600},
2208 	{0x8086, 0x7a8c, B_S,    NT,  "Intel", "HM670",				enable_flash_pch600},
2209 	{0x8086, 0x7a90, B_S,    NT,  "Intel", "R680E",				enable_flash_pch600},
2210 	{0x8086, 0x7a91, B_S,    NT,  "Intel", "Q670E",				enable_flash_pch600},
2211 	{0x8086, 0x7a92, B_S,    NT,  "Intel", "H610E",				enable_flash_pch600},
2212 	{0x8086, 0x7a8a, B_S,    NT,  "Intel", "W790",				enable_flash_pch700},
2213 	{0x8086, 0x7a04, B_S,    DEP, "Intel", "Z790",				enable_flash_pch700},
2214 	{0x8086, 0x7a05, B_S,    NT,  "Intel", "H770",				enable_flash_pch700},
2215 	{0x8086, 0x7a06, B_S,    NT,  "Intel", "B760",				enable_flash_pch700},
2216 	{0x8086, 0x7a0c, B_S,    NT,  "Intel", "HM770",				enable_flash_pch700},
2217 	{0x8086, 0x7a0d, B_S,    NT,  "Intel", "WM790",				enable_flash_pch700},
2218 	{0x8086, 0x7a14, B_S,    NT,  "Intel", "C262",				enable_flash_pch700},
2219 	{0x8086, 0x7a13, B_S,    NT,  "Intel", "C266",				enable_flash_pch700},
2220 	{0x8086, 0x7e23, B_S,    DEP, "Intel", "Meteor Lake-P/M",		enable_flash_mtl},
2221 	{0x8086, 0xe323, B_S,    DEP, "Intel", "Panther Lake-U/H 12Xe",		enable_flash_ptl},
2222 	{0x8086, 0xe423, B_S,    DEP, "Intel", "Panther Lake-H 4Xe",		enable_flash_ptl},
2223 	/** TODO(b/173164205): Merged with upstream. **/
2224 	{0x8086, 0xa224, B_FS,   OK, "Intel", "Lewisburg",			enable_flash_pch100},
2225 	{0x8086, 0x34a4, B_FS,    OK, "Intel", "Icelake",			enable_flash_pch100},
2226 	{0x8086, 0xa0a4, B_FS,    OK, "Intel", "Tigerlake",			enable_flash_pch100},
2227 	{0x8086, 0x7aa4, B_FS,    OK, "Intel", "Alder Lake-S",			enable_flash_pch600},
2228 	/**/
2229 #endif
2230 	{0},
2231 };
2232 
chipset_flash_enable(const struct programmer_cfg * cfg)2233 int chipset_flash_enable(const struct programmer_cfg *cfg)
2234 {
2235 	struct pci_dev *dev = NULL;
2236 	int ret = -2;		/* Nothing! */
2237 	int i;
2238 
2239 	/* Now let's try to find the chipset we have... */
2240 	for (i = 0; chipset_enables[i].vendor_name != NULL; i++) {
2241 		dev = pcidev_find(chipset_enables[i].vendor_id,
2242 				   chipset_enables[i].device_id);
2243 		if (!dev)
2244 			continue;
2245 		if (ret != -2) {
2246 			msg_pwarn("Warning: unexpected second chipset match: "
2247 				    "\"%s %s\"\n"
2248 				  "ignoring, please report lspci and board URL "
2249 				    "to [email protected]\n"
2250 				  "with \'CHIPSET: your board name\' in the "
2251 				    "subject line.\n",
2252 				chipset_enables[i].vendor_name,
2253 					chipset_enables[i].device_name);
2254 			continue;
2255 		}
2256 		msg_pinfo("Found chipset \"%s %s\"",
2257 			  chipset_enables[i].vendor_name,
2258 			  chipset_enables[i].device_name);
2259 		msg_pdbg(" with PCI ID %04x:%04x",
2260 			 chipset_enables[i].vendor_id,
2261 			 chipset_enables[i].device_id);
2262 		msg_pinfo(".\n");
2263 
2264 		if (chipset_enables[i].status == BAD) {
2265 			msg_perr("ERROR: This chipset is not supported yet.\n");
2266 			return ERROR_FLASHROM_FATAL;
2267 		}
2268 		if (chipset_enables[i].status == NT) {
2269 			msg_pinfo("This chipset is marked as untested. If "
2270 				  "you are using an up-to-date version\nof "
2271 				  "flashrom *and* were (not) able to "
2272 				  "successfully update your firmware with it,\n"
2273 				  "then please email a report to "
2274 				  "[email protected] including a verbose "
2275 				  "(-V) log.\nThank you!\n");
2276 		}
2277 		if (!(chipset_enables[i].buses & (internal_buses_supported | BUS_SPI))) {
2278 			msg_pdbg("Skipping chipset enable: No supported buses enabled.\n");
2279 			continue;
2280 		}
2281 		msg_pinfo("Enabling flash write... ");
2282 		ret = chipset_enables[i].doit(cfg, dev, chipset_enables[i].device_name);
2283 		if (ret == NOT_DONE_YET) {
2284 			ret = -2;
2285 			msg_pinfo("OK - searching further chips.\n");
2286 		} else if (ret < 0)
2287 			msg_pinfo("FAILED!\n");
2288 		else if (ret == 0)
2289 			msg_pinfo("OK.\n");
2290 		else if (ret == ERROR_FLASHROM_NONFATAL)
2291 			msg_pinfo("PROBLEMS, continuing anyway\n");
2292 		if (ret == ERROR_FLASHROM_FATAL) {
2293 			msg_perr("FATAL ERROR!\n");
2294 			return ret;
2295 		}
2296 	}
2297 
2298 	return ret;
2299 }
2300