Flashrom

Flashrom Svn Source Tree

Root/trunk/chipset_enable.c

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 <uwe@hermann-uwe.de>
7 * Copyright (C) 2007,2008,2009 Carl-Daniel Hailfinger
8 * Copyright (C) 2009 Kontron Modular Computers GmbH
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24/*
25 * Contains the chipset specific flash enables.
26 */
27
28#define _LARGEFILE64_SOURCE
29
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33#include <inttypes.h>
34#include <errno.h>
35#include "flash.h"
36#include "programmer.h"
37
38#define NOT_DONE_YET 1
39
40#if defined(__i386__) || defined(__x86_64__)
41
42static int enable_flash_ali_m1533(struct pci_dev *dev, const char *name)
43{
44uint8_t tmp;
45
46/*
47 * ROM Write enable, 0xFFFC0000-0xFFFDFFFF and
48 * 0xFFFE0000-0xFFFFFFFF ROM select enable.
49 */
50tmp = pci_read_byte(dev, 0x47);
51tmp |= 0x46;
52rpci_write_byte(dev, 0x47, tmp);
53
54return 0;
55}
56
57static int enable_flash_rdc_r8610(struct pci_dev *dev, const char *name)
58{
59uint8_t tmp;
60
61/* enable ROMCS for writes */
62tmp = pci_read_byte(dev, 0x43);
63tmp |= 0x80;
64pci_write_byte(dev, 0x43, tmp);
65
66/* read the bootstrapping register */
67tmp = pci_read_byte(dev, 0x40) & 0x3;
68switch (tmp) {
69case 3:
70internal_buses_supported = BUS_FWH;
71break;
72case 2:
73internal_buses_supported = BUS_LPC;
74break;
75default:
76internal_buses_supported = BUS_PARALLEL;
77break;
78}
79
80return 0;
81}
82
83static int enable_flash_sis85c496(struct pci_dev *dev, const char *name)
84{
85uint8_t tmp;
86
87tmp = pci_read_byte(dev, 0xd0);
88tmp |= 0xf8;
89rpci_write_byte(dev, 0xd0, tmp);
90
91return 0;
92}
93
94static int enable_flash_sis_mapping(struct pci_dev *dev, const char *name)
95{
96uint8_t new, newer;
97
98/* Extended BIOS enable = 1, Lower BIOS Enable = 1 */
99/* This is 0xFFF8000~0xFFFF0000 decoding on SiS 540/630. */
100new = pci_read_byte(dev, 0x40);
101new &= (~0x04); /* No idea why we clear bit 2. */
102new |= 0xb; /* 0x3 for some chipsets, bit 7 seems to be don't care. */
103rpci_write_byte(dev, 0x40, new);
104newer = pci_read_byte(dev, 0x40);
105if (newer != new) {
106msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
107 "(WARNING ONLY).\n", 0x40, new, name);
108msg_pinfo("Stuck at 0x%x\n", newer);
109return -1;
110}
111return 0;
112}
113
114static struct pci_dev *find_southbridge(uint16_t vendor, const char *name)
115{
116struct pci_dev *sbdev;
117
118sbdev = pci_dev_find_vendorclass(vendor, 0x0601);
119if (!sbdev)
120sbdev = pci_dev_find_vendorclass(vendor, 0x0680);
121if (!sbdev)
122sbdev = pci_dev_find_vendorclass(vendor, 0x0000);
123if (!sbdev)
124msg_perr("No southbridge found for %s!\n", name);
125if (sbdev)
126msg_pdbg("Found southbridge %04x:%04x at %02x:%02x:%01x\n",
127 sbdev->vendor_id, sbdev->device_id,
128 sbdev->bus, sbdev->dev, sbdev->func);
129return sbdev;
130}
131
132static int enable_flash_sis501(struct pci_dev *dev, const char *name)
133{
134uint8_t tmp;
135int ret = 0;
136struct pci_dev *sbdev;
137
138sbdev = find_southbridge(dev->vendor_id, name);
139if (!sbdev)
140return -1;
141
142ret = enable_flash_sis_mapping(sbdev, name);
143
144tmp = sio_read(0x22, 0x80);
145tmp &= (~0x20);
146tmp |= 0x4;
147sio_write(0x22, 0x80, tmp);
148
149tmp = sio_read(0x22, 0x70);
150tmp &= (~0x20);
151tmp |= 0x4;
152sio_write(0x22, 0x70, tmp);
153
154return ret;
155}
156
157static int enable_flash_sis5511(struct pci_dev *dev, const char *name)
158{
159uint8_t tmp;
160int ret = 0;
161struct pci_dev *sbdev;
162
163sbdev = find_southbridge(dev->vendor_id, name);
164if (!sbdev)
165return -1;
166
167ret = enable_flash_sis_mapping(sbdev, name);
168
169tmp = sio_read(0x22, 0x50);
170tmp &= (~0x20);
171tmp |= 0x4;
172sio_write(0x22, 0x50, tmp);
173
174return ret;
175}
176
177static int enable_flash_sis530(struct pci_dev *dev, const char *name)
178{
179uint8_t new, newer;
180int ret = 0;
181struct pci_dev *sbdev;
182
183sbdev = find_southbridge(dev->vendor_id, name);
184if (!sbdev)
185return -1;
186
187ret = enable_flash_sis_mapping(sbdev, name);
188
189new = pci_read_byte(sbdev, 0x45);
190new &= (~0x20);
191new |= 0x4;
192rpci_write_byte(sbdev, 0x45, new);
193newer = pci_read_byte(sbdev, 0x45);
194if (newer != new) {
195msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
196 "(WARNING ONLY).\n", 0x45, new, name);
197msg_pinfo("Stuck at 0x%x\n", newer);
198ret = -1;
199}
200
201return ret;
202}
203
204static int enable_flash_sis540(struct pci_dev *dev, const char *name)
205{
206uint8_t new, newer;
207int ret = 0;
208struct pci_dev *sbdev;
209
210sbdev = find_southbridge(dev->vendor_id, name);
211if (!sbdev)
212return -1;
213
214ret = enable_flash_sis_mapping(sbdev, name);
215
216new = pci_read_byte(sbdev, 0x45);
217new &= (~0x80);
218new |= 0x40;
219rpci_write_byte(sbdev, 0x45, new);
220newer = pci_read_byte(sbdev, 0x45);
221if (newer != new) {
222msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
223 "(WARNING ONLY).\n", 0x45, new, name);
224msg_pinfo("Stuck at 0x%x\n", newer);
225ret = -1;
226}
227
228return ret;
229}
230
231/* Datasheet:
232 * - Name: 82371AB PCI-TO-ISA / IDE XCELERATOR (PIIX4)
233 * - URL: http://www.intel.com/design/intarch/datashts/290562.htm
234 * - PDF: http://www.intel.com/design/intarch/datashts/29056201.pdf
235 * - Order Number: 290562-001
236 */
237static int enable_flash_piix4(struct pci_dev *dev, const char *name)
238{
239uint16_t old, new;
240uint16_t xbcs = 0x4e;/* X-Bus Chip Select register. */
241
242internal_buses_supported = BUS_PARALLEL;
243
244old = pci_read_word(dev, xbcs);
245
246/* Set bit 9: 1-Meg Extended BIOS Enable (PCI master accesses to
247 * FFF00000-FFF7FFFF are forwarded to ISA).
248 * Note: This bit is reserved on PIIX/PIIX3/MPIIX.
249 * Set bit 7: Extended BIOS Enable (PCI master accesses to
250 * FFF80000-FFFDFFFF are forwarded to ISA).
251 * Set bit 6: Lower BIOS Enable (PCI master, or ISA master accesses to
252 * the lower 64-Kbyte BIOS block (E0000-EFFFF) at the top
253 * of 1 Mbyte, or the aliases at the top of 4 Gbyte
254 * (FFFE0000-FFFEFFFF) result in the generation of BIOSCS#.
255 * Note: Accesses to FFFF0000-FFFFFFFF are always forwarded to ISA.
256 * Set bit 2: BIOSCS# Write Enable (1=enable, 0=disable).
257 */
258if (dev->device_id == 0x122e || dev->device_id == 0x7000
259 || dev->device_id == 0x1234)
260new = old | 0x00c4; /* PIIX/PIIX3/MPIIX: Bit 9 is reserved. */
261else
262new = old | 0x02c4;
263
264if (new == old)
265return 0;
266
267rpci_write_word(dev, xbcs, new);
268
269if (pci_read_word(dev, xbcs) != new) {
270msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
271 "(WARNING ONLY).\n", xbcs, new, name);
272return -1;
273}
274
275return 0;
276}
277
278/*
279 * See ie. page 375 of "Intel I/O Controller Hub 7 (ICH7) Family Datasheet"
280 * http://download.intel.com/design/chipsets/datashts/30701303.pdf
281 */
282static int enable_flash_ich(struct pci_dev *dev, const char *name,
283 int bios_cntl)
284{
285uint8_t old, new, wanted;
286
287/*
288 * Note: the ICH0-ICH5 BIOS_CNTL register is actually 16 bit wide, but
289 * just treating it as 8 bit wide seems to work fine in practice.
290 */
291old = pci_read_byte(dev, bios_cntl);
292
293msg_pdbg("\nBIOS Lock Enable: %sabled, ",
294 (old & (1 << 1)) ? "en" : "dis");
295msg_pdbg("BIOS Write Enable: %sabled, ",
296 (old & (1 << 0)) ? "en" : "dis");
297msg_pdbg("BIOS_CNTL is 0x%x\n", old);
298
299/*
300 * Quote from the 6 Series datasheet (Document Number: 324645-004):
301 * "Bit 5: SMM BIOS Write Protect Disable (SMM_BWP)
302 * 1 = BIOS region SMM protection is enabled.
303 * The BIOS Region is not writable unless all processors are in SMM."
304 * In earlier chipsets this bit is reserved.
305 */
306if (old & (1 << 5))
307msg_pinfo("WARNING: BIOS region SMM protection is enabled!\n");
308
309wanted = old | 1;
310if (wanted == old)
311return 0;
312
313rpci_write_byte(dev, bios_cntl, wanted);
314
315if ((new = pci_read_byte(dev, bios_cntl)) != wanted) {
316msg_pinfo("WARNING: Setting 0x%x from 0x%x to 0x%x on %s "
317 "failed. New value is 0x%x.\n",
318 bios_cntl, old, wanted, name, new);
319return -1;
320}
321
322return 0;
323}
324
325static int enable_flash_ich_4e(struct pci_dev *dev, const char *name)
326{
327/*
328 * Note: ICH5 has registers similar to FWH_SEL1, FWH_SEL2 and
329 * FWH_DEC_EN1, but they are called FB_SEL1, FB_SEL2, FB_DEC_EN1 and
330 * FB_DEC_EN2.
331 */
332internal_buses_supported = BUS_FWH;
333return enable_flash_ich(dev, name, 0x4e);
334}
335
336static int enable_flash_ich_dc(struct pci_dev *dev, const char *name)
337{
338uint32_t fwh_conf;
339int i, tmp;
340char *idsel = NULL;
341int max_decode_fwh_idsel = 0, max_decode_fwh_decode = 0;
342int contiguous = 1;
343
344idsel = extract_programmer_param("fwh_idsel");
345if (idsel && strlen(idsel)) {
346uint64_t fwh_idsel_old, fwh_idsel;
347errno = 0;
348/* Base 16, nothing else makes sense. */
349fwh_idsel = (uint64_t)strtoull(idsel, NULL, 16);
350if (errno) {
351msg_perr("Error: fwh_idsel= specified, but value could "
352 "not be converted.\n");
353goto idsel_garbage_out;
354}
355if (fwh_idsel & 0xffff000000000000ULL) {
356msg_perr("Error: fwh_idsel= specified, but value had "
357 "unused bits set.\n");
358goto idsel_garbage_out;
359}
360fwh_idsel_old = pci_read_long(dev, 0xd0);
361fwh_idsel_old <<= 16;
362fwh_idsel_old |= pci_read_word(dev, 0xd4);
363msg_pdbg("\nSetting IDSEL from 0x%012" PRIx64 " to "
364 "0x%012" PRIx64 " for top 16 MB.", fwh_idsel_old,
365 fwh_idsel);
366rpci_write_long(dev, 0xd0, (fwh_idsel >> 16) & 0xffffffff);
367rpci_write_word(dev, 0xd4, fwh_idsel & 0xffff);
368/* FIXME: Decode settings are not changed. */
369} else if (idsel) {
370msg_perr("Error: fwh_idsel= specified, but no value given.\n");
371idsel_garbage_out:
372free(idsel);
373return ERROR_FATAL;
374}
375free(idsel);
376
377/* Ignore all legacy ranges below 1 MB.
378 * We currently only support flashing the chip which responds to
379 * IDSEL=0. To support IDSEL!=0, flashbase and decode size calculations
380 * have to be adjusted.
381 */
382/* FWH_SEL1 */
383fwh_conf = pci_read_long(dev, 0xd0);
384for (i = 7; i >= 0; i--) {
385tmp = (fwh_conf >> (i * 4)) & 0xf;
386msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x",
387 (0x1ff8 + i) * 0x80000,
388 (0x1ff0 + i) * 0x80000,
389 tmp);
390if ((tmp == 0) && contiguous) {
391max_decode_fwh_idsel = (8 - i) * 0x80000;
392} else {
393contiguous = 0;
394}
395}
396/* FWH_SEL2 */
397fwh_conf = pci_read_word(dev, 0xd4);
398for (i = 3; i >= 0; i--) {
399tmp = (fwh_conf >> (i * 4)) & 0xf;
400msg_pdbg("\n0x%08x/0x%08x FWH IDSEL: 0x%x",
401 (0xff4 + i) * 0x100000,
402 (0xff0 + i) * 0x100000,
403 tmp);
404if ((tmp == 0) && contiguous) {
405max_decode_fwh_idsel = (8 - i) * 0x100000;
406} else {
407contiguous = 0;
408}
409}
410contiguous = 1;
411/* FWH_DEC_EN1 */
412fwh_conf = pci_read_word(dev, 0xd8);
413for (i = 7; i >= 0; i--) {
414tmp = (fwh_conf >> (i + 0x8)) & 0x1;
415msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled",
416 (0x1ff8 + i) * 0x80000,
417 (0x1ff0 + i) * 0x80000,
418 tmp ? "en" : "dis");
419if ((tmp == 1) && contiguous) {
420max_decode_fwh_decode = (8 - i) * 0x80000;
421} else {
422contiguous = 0;
423}
424}
425for (i = 3; i >= 0; i--) {
426tmp = (fwh_conf >> i) & 0x1;
427msg_pdbg("\n0x%08x/0x%08x FWH decode %sabled",
428 (0xff4 + i) * 0x100000,
429 (0xff0 + i) * 0x100000,
430 tmp ? "en" : "dis");
431if ((tmp == 1) && contiguous) {
432max_decode_fwh_decode = (8 - i) * 0x100000;
433} else {
434contiguous = 0;
435}
436}
437max_rom_decode.fwh = min(max_decode_fwh_idsel, max_decode_fwh_decode);
438msg_pdbg("\nMaximum FWH chip size: 0x%x bytes", max_rom_decode.fwh);
439
440/* If we're called by enable_flash_ich_dc_spi, it will override
441 * internal_buses_supported anyway.
442 */
443internal_buses_supported = BUS_FWH;
444return enable_flash_ich(dev, name, 0xdc);
445}
446
447static int enable_flash_poulsbo(struct pci_dev *dev, const char *name)
448{
449uint16_t old, new;
450int err;
451
452if ((err = enable_flash_ich(dev, name, 0xd8)) != 0)
453return err;
454
455old = pci_read_byte(dev, 0xd9);
456msg_pdbg("BIOS Prefetch Enable: %sabled, ",
457 (old & 1) ? "en" : "dis");
458new = old & ~1;
459
460if (new != old)
461rpci_write_byte(dev, 0xd9, new);
462
463internal_buses_supported = BUS_FWH;
464return 0;
465}
466
467static int enable_flash_tunnelcreek(struct pci_dev *dev, const char *name)
468{
469uint16_t old, new;
470uint32_t tmp, bnt;
471void *rcrb;
472int ret;
473
474/* Enable Flash Writes */
475ret = enable_flash_ich(dev, name, 0xd8);
476if (ret == ERROR_FATAL)
477return ret;
478
479/* Make sure BIOS prefetch mechanism is disabled */
480old = pci_read_byte(dev, 0xd9);
481msg_pdbg("BIOS Prefetch Enable: %sabled, ", (old & 1) ? "en" : "dis");
482new = old & ~1;
483if (new != old)
484rpci_write_byte(dev, 0xd9, new);
485
486/* Get physical address of Root Complex Register Block */
487tmp = pci_read_long(dev, 0xf0) & 0xffffc000;
488msg_pdbg("\nRoot Complex Register Block address = 0x%x\n", tmp);
489
490/* Map RCBA to virtual memory */
491rcrb = physmap("ICH RCRB", tmp, 0x4000);
492
493/* Test Boot BIOS Strap Status */
494bnt = mmio_readl(rcrb + 0x3410);
495if (bnt & 0x02) {
496/* If strapped to LPC, no SPI initialization is required */
497internal_buses_supported = BUS_FWH;
498return 0;
499}
500
501/* This adds BUS_SPI */
502if (ich_init_spi(dev, tmp, rcrb, 7) != 0) {
503if (!ret)
504ret = ERROR_NONFATAL;
505}
506
507return ret;
508}
509
510static int enable_flash_vt8237s_spi(struct pci_dev *dev, const char *name)
511{
512/* Do we really need no write enable? */
513return via_init_spi(dev);
514}
515
516static int enable_flash_ich_dc_spi(struct pci_dev *dev, const char *name,
517 enum ich_chipset ich_generation)
518{
519int ret, ret_spi;
520uint8_t bbs, buc;
521uint32_t tmp, gcs;
522void *rcrb;
523const char *const *straps_names;
524
525static const char *const straps_names_EP80579[] = { "SPI", "reserved", "reserved", "LPC" };
526static const char *const straps_names_ich7_nm10[] = { "reserved", "SPI", "PCI", "LPC" };
527static const char *const straps_names_ich8910[] = { "SPI", "SPI", "PCI", "LPC" };
528static const char *const straps_names_pch56[] = { "LPC", "reserved", "PCI", "SPI" };
529static const char *const straps_names_unknown[] = { "unknown", "unknown", "unknown", "unknown" };
530
531switch (ich_generation) {
532case CHIPSET_ICH7:
533/* EP80579 may need further changes, but this is the least
534 * intrusive way to get correct BOOT Strap printing without
535 * changing the rest of its code path). */
536if (strcmp(name, "EP80579") == 0)
537straps_names = straps_names_EP80579;
538else
539straps_names = straps_names_ich7_nm10;
540break;
541case CHIPSET_ICH8:
542case CHIPSET_ICH9:
543case CHIPSET_ICH10:
544straps_names = straps_names_ich8910;
545break;
546case CHIPSET_5_SERIES_IBEX_PEAK:
547case CHIPSET_6_SERIES_COUGAR_POINT:
548straps_names = straps_names_pch56;
549break;
550default:
551msg_gerr("%s: unknown ICH generation. Please report!\n",
552 __func__);
553straps_names = straps_names_unknown;
554break;
555}
556
557/* Enable Flash Writes */
558ret = enable_flash_ich_dc(dev, name);
559if (ret == ERROR_FATAL)
560return ret;
561
562/* Get physical address of Root Complex Register Block */
563tmp = pci_read_long(dev, 0xf0) & 0xffffc000;
564msg_pdbg("Root Complex Register Block address = 0x%x\n", tmp);
565
566/* Map RCBA to virtual memory */
567rcrb = physmap("ICH RCRB", tmp, 0x4000);
568
569gcs = mmio_readl(rcrb + 0x3410);
570msg_pdbg("GCS = 0x%x: ", gcs);
571msg_pdbg("BIOS Interface Lock-Down: %sabled, ",
572 (gcs & 0x1) ? "en" : "dis");
573bbs = (gcs >> 10) & 0x3;
574msg_pdbg("Boot BIOS Straps: 0x%x (%s)\n", bbs, straps_names[bbs]);
575
576buc = mmio_readb(rcrb + 0x3414);
577msg_pdbg("Top Swap : %s\n",
578 (buc & 1) ? "enabled (A16 inverted)" : "not enabled");
579
580/* It seems the ICH7 does not support SPI and LPC chips at the same
581 * time. At least not with our current code. So we prevent searching
582 * on ICH7 when the southbridge is strapped to LPC
583 */
584internal_buses_supported = BUS_FWH;
585if (ich_generation == CHIPSET_ICH7) {
586if (bbs == 0x03) {
587/* If strapped to LPC, no further SPI initialization is
588 * required. */
589return ret;
590} else {
591/* Disable LPC/FWH if strapped to PCI or SPI */
592internal_buses_supported = BUS_NONE;
593}
594}
595
596/* This adds BUS_SPI */
597ret_spi = ich_init_spi(dev, tmp, rcrb, ich_generation);
598if (ret_spi == ERROR_FATAL)
599return ret_spi;
600
601if (ret || ret_spi)
602ret = ERROR_NONFATAL;
603
604return ret;
605}
606
607static int enable_flash_ich7(struct pci_dev *dev, const char *name)
608{
609return enable_flash_ich_dc_spi(dev, name, CHIPSET_ICH7);
610}
611
612static int enable_flash_ich8(struct pci_dev *dev, const char *name)
613{
614return enable_flash_ich_dc_spi(dev, name, CHIPSET_ICH8);
615}
616
617static int enable_flash_ich9(struct pci_dev *dev, const char *name)
618{
619return enable_flash_ich_dc_spi(dev, name, CHIPSET_ICH9);
620}
621
622static int enable_flash_ich10(struct pci_dev *dev, const char *name)
623{
624return enable_flash_ich_dc_spi(dev, name, CHIPSET_ICH10);
625}
626
627/* Ibex Peak aka. 5 series & 3400 series */
628static int enable_flash_pch5(struct pci_dev *dev, const char *name)
629{
630return enable_flash_ich_dc_spi(dev, name, CHIPSET_5_SERIES_IBEX_PEAK);
631}
632
633/* Cougar Point aka. 6 series & c200 series */
634static int enable_flash_pch6(struct pci_dev *dev, const char *name)
635{
636return enable_flash_ich_dc_spi(dev, name, CHIPSET_6_SERIES_COUGAR_POINT);
637}
638
639static int via_no_byte_merge(struct pci_dev *dev, const char *name)
640{
641uint8_t val;
642
643val = pci_read_byte(dev, 0x71);
644if (val & 0x40) {
645msg_pdbg("Disabling byte merging\n");
646val &= ~0x40;
647rpci_write_byte(dev, 0x71, val);
648}
649return NOT_DONE_YET;/* need to find south bridge, too */
650}
651
652static int enable_flash_vt823x(struct pci_dev *dev, const char *name)
653{
654uint8_t val;
655
656/* Enable ROM decode range (1MB) FFC00000 - FFFFFFFF. */
657rpci_write_byte(dev, 0x41, 0x7f);
658
659/* ROM write enable */
660val = pci_read_byte(dev, 0x40);
661val |= 0x10;
662rpci_write_byte(dev, 0x40, val);
663
664if (pci_read_byte(dev, 0x40) != val) {
665msg_pinfo("\nWARNING: Failed to enable flash write on \"%s\"\n",
666 name);
667return -1;
668}
669
670if (dev->device_id == 0x3227) { /* VT8237R */
671/* All memory cycles, not just ROM ones, go to LPC. */
672val = pci_read_byte(dev, 0x59);
673val &= ~0x80;
674rpci_write_byte(dev, 0x59, val);
675}
676
677return 0;
678}
679
680static int enable_flash_cs5530(struct pci_dev *dev, const char *name)
681{
682uint8_t reg8;
683
684#define DECODE_CONTROL_REG20x5b/* F0 index 0x5b */
685#define ROM_AT_LOGIC_CONTROL_REG0x52/* F0 index 0x52 */
686#define CS5530_RESET_CONTROL_REG0x44/* F0 index 0x44 */
687#define CS5530_USB_SHADOW_REG0x43/* F0 index 0x43 */
688
689#define LOWER_ROM_ADDRESS_RANGE(1 << 0)
690#define ROM_WRITE_ENABLE(1 << 1)
691#define UPPER_ROM_ADDRESS_RANGE(1 << 2)
692#define BIOS_ROM_POSITIVE_DECODE(1 << 5)
693#define CS5530_ISA_MASTER(1 << 7)
694#define CS5530_ENABLE_SA2320(1 << 2)
695#define CS5530_ENABLE_SA20(1 << 6)
696
697internal_buses_supported = BUS_PARALLEL;
698/* Decode 0x000E0000-0x000FFFFF (128 kB), not just 64 kB, and
699 * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 kB.
700 * FIXME: Should we really touch the low mapping below 1 MB? Flashrom
701 * ignores that region completely.
702 * Make the configured ROM areas writable.
703 */
704reg8 = pci_read_byte(dev, ROM_AT_LOGIC_CONTROL_REG);
705reg8 |= LOWER_ROM_ADDRESS_RANGE;
706reg8 |= UPPER_ROM_ADDRESS_RANGE;
707reg8 |= ROM_WRITE_ENABLE;
708rpci_write_byte(dev, ROM_AT_LOGIC_CONTROL_REG, reg8);
709
710/* Set positive decode on ROM. */
711reg8 = pci_read_byte(dev, DECODE_CONTROL_REG2);
712reg8 |= BIOS_ROM_POSITIVE_DECODE;
713rpci_write_byte(dev, DECODE_CONTROL_REG2, reg8);
714
715reg8 = pci_read_byte(dev, CS5530_RESET_CONTROL_REG);
716if (reg8 & CS5530_ISA_MASTER) {
717/* We have A0-A23 available. */
718max_rom_decode.parallel = 16 * 1024 * 1024;
719} else {
720reg8 = pci_read_byte(dev, CS5530_USB_SHADOW_REG);
721if (reg8 & CS5530_ENABLE_SA2320) {
722/* We have A0-19, A20-A23 available. */
723max_rom_decode.parallel = 16 * 1024 * 1024;
724} else if (reg8 & CS5530_ENABLE_SA20) {
725/* We have A0-19, A20 available. */
726max_rom_decode.parallel = 2 * 1024 * 1024;
727} else {
728/* A20 and above are not active. */
729max_rom_decode.parallel = 1024 * 1024;
730}
731}
732
733return 0;
734}
735
736/*
737 * Geode systems write protect the BIOS via RCONFs (cache settings similar
738 * to MTRRs). To unlock, change MSR 0x1808 top byte to 0x22.
739 *
740 * Geode systems also write protect the NOR flash chip itself via MSR_NORF_CTL.
741 * To enable write to NOR Boot flash for the benefit of systems that have such
742 * a setup, raise MSR 0x51400018 WE_CS3 (write enable Boot Flash Chip Select).
743 */
744static int enable_flash_cs5536(struct pci_dev *dev, const char *name)
745{
746#define MSR_RCONF_DEFAULT0x1808
747#define MSR_NORF_CTL0x51400018
748
749msr_t msr;
750
751/* Geode only has a single core */
752if (setup_cpu_msr(0))
753return -1;
754
755msr = rdmsr(MSR_RCONF_DEFAULT);
756if ((msr.hi >> 24) != 0x22) {
757msr.hi &= 0xfbffffff;
758wrmsr(MSR_RCONF_DEFAULT, msr);
759}
760
761msr = rdmsr(MSR_NORF_CTL);
762/* Raise WE_CS3 bit. */
763msr.lo |= 0x08;
764wrmsr(MSR_NORF_CTL, msr);
765
766cleanup_cpu_msr();
767
768#undef MSR_RCONF_DEFAULT
769#undef MSR_NORF_CTL
770return 0;
771}
772
773static int enable_flash_sc1100(struct pci_dev *dev, const char *name)
774{
775uint8_t new;
776
777rpci_write_byte(dev, 0x52, 0xee);
778
779new = pci_read_byte(dev, 0x52);
780
781if (new != 0xee) {
782msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
783 "(WARNING ONLY).\n", 0x52, new, name);
784return -1;
785}
786
787return 0;
788}
789
790/* Works for AMD-8111, VIA VT82C586A/B, VIA VT82C686A/B. */
791static int enable_flash_amd8111(struct pci_dev *dev, const char *name)
792{
793uint8_t old, new;
794
795/* Enable decoding at 0xffb00000 to 0xffffffff. */
796old = pci_read_byte(dev, 0x43);
797new = old | 0xC0;
798if (new != old) {
799rpci_write_byte(dev, 0x43, new);
800if (pci_read_byte(dev, 0x43) != new) {
801msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
802 "(WARNING ONLY).\n", 0x43, new, name);
803}
804}
805
806/* Enable 'ROM write' bit. */
807old = pci_read_byte(dev, 0x40);
808new = old | 0x01;
809if (new == old)
810return 0;
811rpci_write_byte(dev, 0x40, new);
812
813if (pci_read_byte(dev, 0x40) != new) {
814msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
815 "(WARNING ONLY).\n", 0x40, new, name);
816return -1;
817}
818
819return 0;
820}
821
822static int enable_flash_sb600(struct pci_dev *dev, const char *name)
823{
824uint32_t prot;
825uint8_t reg;
826int ret;
827
828/* Clear ROM protect 0-3. */
829for (reg = 0x50; reg < 0x60; reg += 4) {
830prot = pci_read_long(dev, reg);
831/* No protection flags for this region?*/
832if ((prot & 0x3) == 0)
833continue;
834msg_pinfo("SB600 %s%sprotected from 0x%08x to 0x%08x\n",
835 (prot & 0x1) ? "write " : "",
836 (prot & 0x2) ? "read " : "",
837 (prot & 0xfffff800),
838 (prot & 0xfffff800) + (((prot & 0x7fc) << 8) | 0x3ff));
839prot &= 0xfffffffc;
840rpci_write_byte(dev, reg, prot);
841prot = pci_read_long(dev, reg);
842if (prot & 0x3)
843msg_perr("SB600 %s%sunprotect failed from 0x%08x to 0x%08x\n",
844 (prot & 0x1) ? "write " : "",
845 (prot & 0x2) ? "read " : "",
846 (prot & 0xfffff800),
847 (prot & 0xfffff800) + (((prot & 0x7fc) << 8) | 0x3ff));
848}
849
850internal_buses_supported = BUS_LPC | BUS_FWH;
851
852ret = sb600_probe_spi(dev);
853
854/* Read ROM strap override register. */
855OUTB(0x8f, 0xcd6);
856reg = INB(0xcd7);
857reg &= 0x0e;
858msg_pdbg("ROM strap override is %sactive", (reg & 0x02) ? "" : "not ");
859if (reg & 0x02) {
860switch ((reg & 0x0c) >> 2) {
861case 0x00:
862msg_pdbg(": LPC");
863break;
864case 0x01:
865msg_pdbg(": PCI");
866break;
867case 0x02:
868msg_pdbg(": FWH");
869break;
870case 0x03:
871msg_pdbg(": SPI");
872break;
873}
874}
875msg_pdbg("\n");
876
877/* Force enable SPI ROM in SB600 PM register.
878 * If we enable SPI ROM here, we have to disable it after we leave.
879 * But how can we know which ROM we are going to handle? So we have
880 * to trade off. We only access LPC ROM if we boot via LPC ROM. And
881 * only SPI ROM if we boot via SPI ROM. If you want to access SPI on
882 * boards with LPC straps, you have to use the code below.
883 */
884/*
885OUTB(0x8f, 0xcd6);
886OUTB(0x0e, 0xcd7);
887*/
888
889return ret;
890}
891
892static int enable_flash_nvidia_nforce2(struct pci_dev *dev, const char *name)
893{
894uint8_t tmp;
895
896rpci_write_byte(dev, 0x92, 0);
897
898tmp = pci_read_byte(dev, 0x6d);
899tmp |= 0x01;
900rpci_write_byte(dev, 0x6d, tmp);
901
902return 0;
903}
904
905static int enable_flash_ck804(struct pci_dev *dev, const char *name)
906{
907uint8_t old, new;
908
909pci_write_byte(dev, 0x92, 0x00);
910if (pci_read_byte(dev, 0x92) != 0x00) {
911msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
912 "(WARNING ONLY).\n", 0x92, 0x00, name);
913}
914
915old = pci_read_byte(dev, 0x88);
916new = old | 0xc0;
917if (new != old) {
918rpci_write_byte(dev, 0x88, new);
919if (pci_read_byte(dev, 0x88) != new) {
920msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
921 "(WARNING ONLY).\n", 0x88, new, name);
922}
923}
924
925old = pci_read_byte(dev, 0x6d);
926new = old | 0x01;
927if (new == old)
928return 0;
929rpci_write_byte(dev, 0x6d, new);
930
931if (pci_read_byte(dev, 0x6d) != new) {
932msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
933 "(WARNING ONLY).\n", 0x6d, new, name);
934return -1;
935}
936
937return 0;
938}
939
940static int enable_flash_osb4(struct pci_dev *dev, const char *name)
941{
942uint8_t tmp;
943
944internal_buses_supported = BUS_PARALLEL;
945
946tmp = INB(0xc06);
947tmp |= 0x1;
948OUTB(tmp, 0xc06);
949
950tmp = INB(0xc6f);
951tmp |= 0x40;
952OUTB(tmp, 0xc6f);
953
954return 0;
955}
956
957/* ATI Technologies Inc IXP SB400 PCI-ISA Bridge (rev 80) */
958static int enable_flash_sb400(struct pci_dev *dev, const char *name)
959{
960uint8_t tmp;
961struct pci_dev *smbusdev;
962
963/* Look for the SMBus device. */
964smbusdev = pci_dev_find(0x1002, 0x4372);
965
966if (!smbusdev) {
967msg_perr("ERROR: SMBus device not found. Aborting.\n");
968return ERROR_FATAL;
969}
970
971/* Enable some SMBus stuff. */
972tmp = pci_read_byte(smbusdev, 0x79);
973tmp |= 0x01;
974rpci_write_byte(smbusdev, 0x79, tmp);
975
976/* Change southbridge. */
977tmp = pci_read_byte(dev, 0x48);
978tmp |= 0x21;
979rpci_write_byte(dev, 0x48, tmp);
980
981/* Now become a bit silly. */
982tmp = INB(0xc6f);
983OUTB(tmp, 0xeb);
984OUTB(tmp, 0xeb);
985tmp |= 0x40;
986OUTB(tmp, 0xc6f);
987OUTB(tmp, 0xeb);
988OUTB(tmp, 0xeb);
989
990return 0;
991}
992
993static int enable_flash_mcp55(struct pci_dev *dev, const char *name)
994{
995uint8_t old, new, val;
996uint16_t wordval;
997
998/* Set the 0-16 MB enable bits. */
999val = pci_read_byte(dev, 0x88);
1000val |= 0xff;/* 256K */
1001rpci_write_byte(dev, 0x88, val);
1002val = pci_read_byte(dev, 0x8c);
1003val |= 0xff;/* 1M */
1004rpci_write_byte(dev, 0x8c, val);
1005wordval = pci_read_word(dev, 0x90);
1006wordval |= 0x7fff;/* 16M */
1007rpci_write_word(dev, 0x90, wordval);
1008
1009old = pci_read_byte(dev, 0x6d);
1010new = old | 0x01;
1011if (new == old)
1012return 0;
1013rpci_write_byte(dev, 0x6d, new);
1014
1015if (pci_read_byte(dev, 0x6d) != new) {
1016msg_pinfo("Setting register 0x%x to 0x%x on %s failed "
1017 "(WARNING ONLY).\n", 0x6d, new, name);
1018return -1;
1019}
1020
1021return 0;
1022}
1023
1024/*
1025 * The MCP6x/MCP7x code is based on cleanroom reverse engineering.
1026 * It is assumed that LPC chips need the MCP55 code and SPI chips need the
1027 * code provided in enable_flash_mcp6x_7x_common.
1028 */
1029static int enable_flash_mcp6x_7x(struct pci_dev *dev, const char *name)
1030{
1031int ret = 0, want_spi = 0;
1032uint8_t val;
1033
1034msg_pinfo("This chipset is not really supported yet. Guesswork...\n");
1035
1036/* dev is the ISA bridge. No idea what the stuff below does. */
1037val = pci_read_byte(dev, 0x8a);
1038msg_pdbg("ISA/LPC bridge reg 0x8a contents: 0x%02x, bit 6 is %i, bit 5 "
1039 "is %i\n", val, (val >> 6) & 0x1, (val >> 5) & 0x1);
1040
1041switch ((val >> 5) & 0x3) {
1042case 0x0:
1043ret = enable_flash_mcp55(dev, name);
1044internal_buses_supported = BUS_LPC;
1045msg_pdbg("Flash bus type is LPC\n");
1046break;
1047case 0x2:
1048want_spi = 1;
1049/* SPI is added in mcp6x_spi_init if it works.
1050 * Do we really want to disable LPC in this case?
1051 */
1052internal_buses_supported = BUS_NONE;
1053msg_pdbg("Flash bus type is SPI\n");
1054msg_pinfo("SPI on this chipset is WIP. Please report any "
1055 "success or failure by mailing us the verbose "
1056 "output to flashrom@flashrom.org, thanks!\n");
1057break;
1058default:
1059/* Should not happen. */
1060internal_buses_supported = BUS_NONE;
1061msg_pdbg("Flash bus type is unknown (none)\n");
1062msg_pinfo("Something went wrong with bus type detection.\n");
1063goto out_msg;
1064break;
1065}
1066
1067/* Force enable SPI and disable LPC? Not a good idea. */
1068#if 0
1069val |= (1 << 6);
1070val &= ~(1 << 5);
1071rpci_write_byte(dev, 0x8a, val);
1072#endif
1073
1074if (mcp6x_spi_init(want_spi))
1075ret = 1;
1076
1077out_msg:
1078msg_pinfo("Please send the output of \"flashrom -V\" to "
1079 "flashrom@flashrom.org with\n"
1080 "your board name: flashrom -V as the subject to help us "
1081 "finish support for your\n"
1082 "chipset. Thanks.\n");
1083
1084return ret;
1085}
1086
1087static int enable_flash_ht1000(struct pci_dev *dev, const char *name)
1088{
1089uint8_t val;
1090
1091/* Set the 4MB enable bit. */
1092val = pci_read_byte(dev, 0x41);
1093val |= 0x0e;
1094rpci_write_byte(dev, 0x41, val);
1095
1096val = pci_read_byte(dev, 0x43);
1097val |= (1 << 4);
1098rpci_write_byte(dev, 0x43, val);
1099
1100return 0;
1101}
1102
1103/*
1104 * Usually on the x86 architectures (and on other PC-like platforms like some
1105 * Alphas or Itanium) the system flash is mapped right below 4G. On the AMD
1106 * Elan SC520 only a small piece of the system flash is mapped there, but the
1107 * complete flash is mapped somewhere below 1G. The position can be determined
1108 * by the BOOTCS PAR register.
1109 */
1110static int get_flashbase_sc520(struct pci_dev *dev, const char *name)
1111{
1112int i, bootcs_found = 0;
1113uint32_t parx = 0;
1114void *mmcr;
1115
1116/* 1. Map MMCR */
1117mmcr = physmap("Elan SC520 MMCR", 0xfffef000, getpagesize());
1118
1119/* 2. Scan PAR0 (0x88) - PAR15 (0xc4) for
1120 * BOOTCS region (PARx[31:29] = 100b)e
1121 */
1122for (i = 0x88; i <= 0xc4; i += 4) {
1123parx = mmio_readl(mmcr + i);
1124if ((parx >> 29) == 4) {
1125bootcs_found = 1;
1126break; /* BOOTCS found */
1127}
1128}
1129
1130/* 3. PARx[25] = 1b --> flashbase[29:16] = PARx[13:0]
1131 * PARx[25] = 0b --> flashbase[29:12] = PARx[17:0]
1132 */
1133if (bootcs_found) {
1134if (parx & (1 << 25)) {
1135parx &= (1 << 14) - 1; /* Mask [13:0] */
1136flashbase = parx << 16;
1137} else {
1138parx &= (1 << 18) - 1; /* Mask [17:0] */
1139flashbase = parx << 12;
1140}
1141} else {
1142msg_pinfo("AMD Elan SC520 detected, but no BOOTCS. "
1143 "Assuming flash at 4G.\n");
1144}
1145
1146/* 4. Clean up */
1147physunmap(mmcr, getpagesize());
1148return 0;
1149}
1150
1151#endif
1152
1153/* Please keep this list numerically sorted by vendor/device ID. */
1154const struct penable chipset_enables[] = {
1155#if defined(__i386__) || defined(__x86_64__)
1156{0x1002, 0x4377, OK, "ATI", "SB400",enable_flash_sb400},
1157{0x1002, 0x438d, OK, "AMD", "SB600",enable_flash_sb600},
1158{0x1002, 0x439d, OK, "AMD", "SB700/SB710/SB750/SB850", enable_flash_sb600},
1159{0x100b, 0x0510, NT, "AMD", "SC1100",enable_flash_sc1100},
1160{0x1022, 0x2080, OK, "AMD", "CS5536",enable_flash_cs5536},
1161{0x1022, 0x2090, OK, "AMD", "CS5536",enable_flash_cs5536},
1162{0x1022, 0x3000, OK, "AMD", "Elan SC520",get_flashbase_sc520},
1163{0x1022, 0x7440, OK, "AMD", "AMD-768",enable_flash_amd8111},
1164{0x1022, 0x7468, OK, "AMD", "AMD8111",enable_flash_amd8111},
1165{0x1022, 0x780e, OK, "AMD", "Hudson",enable_flash_sb600},
1166{0x1039, 0x0406, NT, "SiS", "501/5101/5501",enable_flash_sis501},
1167{0x1039, 0x0496, NT, "SiS", "85C496+497",enable_flash_sis85c496},
1168{0x1039, 0x0530, OK, "SiS", "530",enable_flash_sis530},
1169{0x1039, 0x0540, NT, "SiS", "540",enable_flash_sis540},
1170{0x1039, 0x0620, NT, "SiS", "620",enable_flash_sis530},
1171{0x1039, 0x0630, NT, "SiS", "630",enable_flash_sis540},
1172{0x1039, 0x0635, NT, "SiS", "635",enable_flash_sis540},
1173{0x1039, 0x0640, NT, "SiS", "640",enable_flash_sis540},
1174{0x1039, 0x0645, NT, "SiS", "645",enable_flash_sis540},
1175{0x1039, 0x0646, OK, "SiS", "645DX",enable_flash_sis540},
1176{0x1039, 0x0648, NT, "SiS", "648",enable_flash_sis540},
1177{0x1039, 0x0650, NT, "SiS", "650",enable_flash_sis540},
1178{0x1039, 0x0651, OK, "SiS", "651",enable_flash_sis540},
1179{0x1039, 0x0655, NT, "SiS", "655",enable_flash_sis540},
1180{0x1039, 0x0661, OK, "SiS", "661",enable_flash_sis540},
1181{0x1039, 0x0730, NT, "SiS", "730",enable_flash_sis540},
1182{0x1039, 0x0733, NT, "SiS", "733",enable_flash_sis540},
1183{0x1039, 0x0735, OK, "SiS", "735",enable_flash_sis540},
1184{0x1039, 0x0740, NT, "SiS", "740",enable_flash_sis540},
1185{0x1039, 0x0741, OK, "SiS", "741",enable_flash_sis540},
1186{0x1039, 0x0745, OK, "SiS", "745",enable_flash_sis540},
1187{0x1039, 0x0746, NT, "SiS", "746",enable_flash_sis540},
1188{0x1039, 0x0748, NT, "SiS", "748",enable_flash_sis540},
1189{0x1039, 0x0755, NT, "SiS", "755",enable_flash_sis540},
1190{0x1039, 0x5511, NT, "SiS", "5511",enable_flash_sis5511},
1191{0x1039, 0x5571, NT, "SiS", "5571",enable_flash_sis530},
1192{0x1039, 0x5591, NT, "SiS", "5591/5592",enable_flash_sis530},
1193{0x1039, 0x5596, NT, "SiS", "5596",enable_flash_sis5511},
1194{0x1039, 0x5597, NT, "SiS", "5597/5598/5581/5120", enable_flash_sis530},
1195{0x1039, 0x5600, NT, "SiS", "600",enable_flash_sis530},
1196{0x1078, 0x0100, OK, "AMD", "CS5530(A)",enable_flash_cs5530},
1197{0x10b9, 0x1533, OK, "ALi", "M1533",enable_flash_ali_m1533},
1198{0x10de, 0x0030, OK, "NVIDIA", "nForce4/MCP4",enable_flash_nvidia_nforce2},
1199{0x10de, 0x0050, OK, "NVIDIA", "CK804",enable_flash_ck804}, /* LPC */
1200{0x10de, 0x0051, OK, "NVIDIA", "CK804",enable_flash_ck804}, /* Pro */
1201{0x10de, 0x0060, OK, "NVIDIA", "NForce2",enable_flash_nvidia_nforce2},
1202{0x10de, 0x00e0, OK, "NVIDIA", "NForce3",enable_flash_nvidia_nforce2},
1203/* Slave, should not be here, to fix known bug for A01. */
1204{0x10de, 0x00d3, OK, "NVIDIA", "CK804",enable_flash_ck804},
1205{0x10de, 0x0260, OK, "NVIDIA", "MCP51",enable_flash_ck804},
1206{0x10de, 0x0261, NT, "NVIDIA", "MCP51",enable_flash_ck804},
1207{0x10de, 0x0262, NT, "NVIDIA", "MCP51",enable_flash_ck804},
1208{0x10de, 0x0263, NT, "NVIDIA", "MCP51",enable_flash_ck804},
1209{0x10de, 0x0360, OK, "NVIDIA", "MCP55",enable_flash_mcp55}, /* M57SLI*/
1210/* 10de:0361 is present in Tyan S2915 OEM systems, but not connected to
1211 * the flash chip. Instead, 10de:0364 is connected to the flash chip.
1212 * Until we have PCI device class matching or some fallback mechanism,
1213 * this is needed to get flashrom working on Tyan S2915 and maybe other
1214 * dual-MCP55 boards.
1215 */
1216#if 0
1217{0x10de, 0x0361, NT, "NVIDIA", "MCP55",enable_flash_mcp55}, /* LPC */
1218#endif
1219{0x10de, 0x0362, OK, "NVIDIA", "MCP55",enable_flash_mcp55}, /* LPC */
1220{0x10de, 0x0363, OK, "NVIDIA", "MCP55",enable_flash_mcp55}, /* LPC */
1221{0x10de, 0x0364, OK, "NVIDIA", "MCP55",enable_flash_mcp55}, /* LPC */
1222{0x10de, 0x0365, OK, "NVIDIA", "MCP55",enable_flash_mcp55}, /* LPC */
1223{0x10de, 0x0366, OK, "NVIDIA", "MCP55",enable_flash_mcp55}, /* LPC */
1224{0x10de, 0x0367, OK, "NVIDIA", "MCP55",enable_flash_mcp55}, /* Pro */
1225{0x10de, 0x03e0, NT, "NVIDIA", "MCP61",enable_flash_mcp6x_7x},
1226{0x10de, 0x03e1, OK, "NVIDIA", "MCP61",enable_flash_mcp6x_7x},
1227{0x10de, 0x03e2, NT, "NVIDIA", "MCP61",enable_flash_mcp6x_7x},
1228{0x10de, 0x03e3, NT, "NVIDIA", "MCP61",enable_flash_mcp6x_7x},
1229{0x10de, 0x0440, NT, "NVIDIA", "MCP65",enable_flash_mcp6x_7x},
1230{0x10de, 0x0441, NT, "NVIDIA", "MCP65",enable_flash_mcp6x_7x},
1231{0x10de, 0x0442, NT, "NVIDIA", "MCP65",enable_flash_mcp6x_7x},
1232{0x10de, 0x0443, NT, "NVIDIA", "MCP65",enable_flash_mcp6x_7x},
1233{0x10de, 0x0548, OK, "NVIDIA", "MCP67",enable_flash_mcp6x_7x},
1234{0x10de, 0x075c, NT, "NVIDIA", "MCP78S",enable_flash_mcp6x_7x},
1235{0x10de, 0x075d, OK, "NVIDIA", "MCP78S",enable_flash_mcp6x_7x},
1236{0x10de, 0x07d7, NT, "NVIDIA", "MCP73",enable_flash_mcp6x_7x},
1237{0x10de, 0x0aac, NT, "NVIDIA", "MCP79",enable_flash_mcp6x_7x},
1238{0x10de, 0x0aad, NT, "NVIDIA", "MCP79",enable_flash_mcp6x_7x},
1239{0x10de, 0x0aae, NT, "NVIDIA", "MCP79",enable_flash_mcp6x_7x},
1240{0x10de, 0x0aaf, NT, "NVIDIA", "MCP79",enable_flash_mcp6x_7x},
1241/* VIA northbridges */
1242{0x1106, 0x0585, NT, "VIA", "VT82C585VPX",via_no_byte_merge},
1243{0x1106, 0x0595, NT, "VIA", "VT82C595",via_no_byte_merge},
1244{0x1106, 0x0597, NT, "VIA", "VT82C597",via_no_byte_merge},
1245{0x1106, 0x0601, NT, "VIA", "VT8601/VT8601A",via_no_byte_merge},
1246{0x1106, 0x0691, NT, "VIA", "VT82C69x",via_no_byte_merge}, /* 691, 693a, 694t, 694x checked */
1247{0x1106, 0x8601, NT, "VIA", "VT8601T",via_no_byte_merge},
1248/* VIA southbridges */
1249{0x1106, 0x0586, OK, "VIA", "VT82C586A/B",enable_flash_amd8111},
1250{0x1106, 0x0596, OK, "VIA", "VT82C596",enable_flash_amd8111},
1251{0x1106, 0x0686, NT, "VIA", "VT82C686A/B",enable_flash_amd8111},
1252{0x1106, 0x3074, OK, "VIA", "VT8233",enable_flash_vt823x},
1253{0x1106, 0x3147, OK, "VIA", "VT8233A",enable_flash_vt823x},
1254{0x1106, 0x3177, OK, "VIA", "VT8235",enable_flash_vt823x},
1255{0x1106, 0x3227, OK, "VIA", "VT8237",enable_flash_vt823x},
1256{0x1106, 0x3337, OK, "VIA", "VT8237A",enable_flash_vt823x},
1257{0x1106, 0x3372, OK, "VIA", "VT8237S",enable_flash_vt8237s_spi},
1258{0x1106, 0x8231, NT, "VIA", "VT8231",enable_flash_vt823x},
1259{0x1106, 0x8324, OK, "VIA", "CX700",enable_flash_vt823x},
1260{0x1106, 0x8353, OK, "VIA", "VX800/VX820",enable_flash_vt8237s_spi},
1261{0x1106, 0x8409, OK, "VIA", "VX855/VX875",enable_flash_vt823x},
1262{0x1166, 0x0200, OK, "Broadcom", "OSB4",enable_flash_osb4},
1263{0x1166, 0x0205, OK, "Broadcom", "HT-1000",enable_flash_ht1000},
1264{0x17f3, 0x6030, OK, "RDC", "R8610/R3210",enable_flash_rdc_r8610},
1265{0x8086, 0x122e, OK, "Intel", "PIIX",enable_flash_piix4},
1266{0x8086, 0x1234, NT, "Intel", "MPIIX",enable_flash_piix4},
1267{0x8086, 0x1c44, OK, "Intel", "Z68",enable_flash_pch6},
1268{0x8086, 0x1c46, OK, "Intel", "P67",enable_flash_pch6},
1269{0x8086, 0x1c47, NT, "Intel", "UM67",enable_flash_pch6},
1270{0x8086, 0x1c49, NT, "Intel", "HM65",enable_flash_pch6},
1271{0x8086, 0x1c4a, OK, "Intel", "H67",enable_flash_pch6},
1272{0x8086, 0x1c4b, NT, "Intel", "HM67",enable_flash_pch6},
1273{0x8086, 0x1c4c, NT, "Intel", "Q65",enable_flash_pch6},
1274{0x8086, 0x1c4d, NT, "Intel", "QS67",enable_flash_pch6},
1275{0x8086, 0x1c4e, NT, "Intel", "Q67",enable_flash_pch6},
1276{0x8086, 0x1c4f, NT, "Intel", "QM67",enable_flash_pch6},
1277{0x8086, 0x1c50, NT, "Intel", "B65",enable_flash_pch6},
1278{0x8086, 0x1c52, NT, "Intel", "C202",enable_flash_pch6},
1279{0x8086, 0x1c54, NT, "Intel", "C204",enable_flash_pch6},
1280{0x8086, 0x1c56, NT, "Intel", "C206",enable_flash_pch6},
1281{0x8086, 0x1c5c, NT, "Intel", "H61",enable_flash_pch6},
1282{0x8086, 0x1d40, OK, "Intel", "X79",enable_flash_ich10}, /* FIXME: when datasheet is available */
1283{0x8086, 0x1d41, NT, "Intel", "X79",enable_flash_ich10}, /* FIXME: when datasheet is available */
1284{0x8086, 0x2410, OK, "Intel", "ICH",enable_flash_ich_4e},
1285{0x8086, 0x2420, OK, "Intel", "ICH0",enable_flash_ich_4e},
1286{0x8086, 0x2440, OK, "Intel", "ICH2",enable_flash_ich_4e},
1287{0x8086, 0x244c, OK, "Intel", "ICH2-M",enable_flash_ich_4e},
1288{0x8086, 0x2450, NT, "Intel", "C-ICH",enable_flash_ich_4e},
1289{0x8086, 0x2480, OK, "Intel", "ICH3-S",enable_flash_ich_4e},
1290{0x8086, 0x248c, OK, "Intel", "ICH3-M",enable_flash_ich_4e},
1291{0x8086, 0x24c0, OK, "Intel", "ICH4/ICH4-L",enable_flash_ich_4e},
1292{0x8086, 0x24cc, OK, "Intel", "ICH4-M",enable_flash_ich_4e},
1293{0x8086, 0x24d0, OK, "Intel", "ICH5/ICH5R",enable_flash_ich_4e},
1294{0x8086, 0x25a1, OK, "Intel", "6300ESB",enable_flash_ich_4e},
1295{0x8086, 0x2640, OK, "Intel", "ICH6/ICH6R",enable_flash_ich_dc},
1296{0x8086, 0x2641, OK, "Intel", "ICH6-M",enable_flash_ich_dc},
1297{0x8086, 0x2642, NT, "Intel", "ICH6W/ICH6RW",enable_flash_ich_dc},
1298{0x8086, 0x2670, OK, "Intel", "631xESB/632xESB/3100", enable_flash_ich_dc},
1299{0x8086, 0x27b0, OK, "Intel", "ICH7DH",enable_flash_ich7},
1300{0x8086, 0x27b8, OK, "Intel", "ICH7/ICH7R",enable_flash_ich7},
1301{0x8086, 0x27b9, OK, "Intel", "ICH7M",enable_flash_ich7},
1302{0x8086, 0x27bc, OK, "Intel", "NM10",enable_flash_ich7},
1303{0x8086, 0x27bd, OK, "Intel", "ICH7MDH",enable_flash_ich7},
1304{0x8086, 0x2810, OK, "Intel", "ICH8/ICH8R",enable_flash_ich8},
1305{0x8086, 0x2811, OK, "Intel", "ICH8M-E",enable_flash_ich8},
1306{0x8086, 0x2812, OK, "Intel", "ICH8DH",enable_flash_ich8},
1307{0x8086, 0x2814, OK, "Intel", "ICH8DO",enable_flash_ich8},
1308{0x8086, 0x2815, OK, "Intel", "ICH8M",enable_flash_ich8},
1309{0x8086, 0x2910, OK, "Intel", "ICH9 Engineering Sample", enable_flash_ich9},
1310{0x8086, 0x2912, OK, "Intel", "ICH9DH",enable_flash_ich9},
1311{0x8086, 0x2914, OK, "Intel", "ICH9DO",enable_flash_ich9},
1312{0x8086, 0x2916, OK, "Intel", "ICH9R",enable_flash_ich9},
1313{0x8086, 0x2917, OK, "Intel", "ICH9M-E",enable_flash_ich9},
1314{0x8086, 0x2918, OK, "Intel", "ICH9",enable_flash_ich9},
1315{0x8086, 0x2919, OK, "Intel", "ICH9M",enable_flash_ich9},
1316{0x8086, 0x3a10, NT, "Intel", "ICH10R Engineering Sample", enable_flash_ich10},
1317{0x8086, 0x3a14, OK, "Intel", "ICH10DO",enable_flash_ich10},
1318{0x8086, 0x3a16, OK, "Intel", "ICH10R",enable_flash_ich10},
1319{0x8086, 0x3a18, OK, "Intel", "ICH10",enable_flash_ich10},
1320{0x8086, 0x3a1a, OK, "Intel", "ICH10D",enable_flash_ich10},
1321{0x8086, 0x3a1e, NT, "Intel", "ICH10 Engineering Sample", enable_flash_ich10},
1322{0x8086, 0x3b00, NT, "Intel", "3400 Desktop",enable_flash_pch5},
1323{0x8086, 0x3b01, NT, "Intel", "3400 Mobile",enable_flash_pch5},
1324{0x8086, 0x3b02, NT, "Intel", "P55",enable_flash_pch5},
1325{0x8086, 0x3b03, NT, "Intel", "PM55",enable_flash_pch5},
1326{0x8086, 0x3b06, OK, "Intel", "H55",enable_flash_pch5},
1327{0x8086, 0x3b07, OK, "Intel", "QM57",enable_flash_pch5},
1328{0x8086, 0x3b08, NT, "Intel", "H57",enable_flash_pch5},
1329{0x8086, 0x3b09, NT, "Intel", "HM55",enable_flash_pch5},
1330{0x8086, 0x3b0a, NT, "Intel", "Q57",enable_flash_pch5},
1331{0x8086, 0x3b0b, NT, "Intel", "HM57",enable_flash_pch5},
1332{0x8086, 0x3b0d, NT, "Intel", "3400 Mobile SFF", enable_flash_pch5},
1333{0x8086, 0x3b0e, NT, "Intel", "B55",enable_flash_pch5},
1334{0x8086, 0x3b0f, OK, "Intel", "QS57",enable_flash_pch5},
1335{0x8086, 0x3b12, NT, "Intel", "3400",enable_flash_pch5},
1336{0x8086, 0x3b14, NT, "Intel", "3420",enable_flash_pch5},
1337{0x8086, 0x3b16, NT, "Intel", "3450",enable_flash_pch5},
1338{0x8086, 0x3b1e, NT, "Intel", "B55",enable_flash_pch5},
1339{0x8086, 0x5031, OK, "Intel", "EP80579",enable_flash_ich7},
1340{0x8086, 0x7000, OK, "Intel", "PIIX3",enable_flash_piix4},
1341{0x8086, 0x7110, OK, "Intel", "PIIX4/4E/4M",enable_flash_piix4},
1342{0x8086, 0x7198, OK, "Intel", "440MX",enable_flash_piix4},
1343{0x8086, 0x8119, OK, "Intel", "SCH Poulsbo",enable_flash_poulsbo},
1344{0x8086, 0x8186, OK, "Intel", "Atom E6xx(T)/Tunnel Creek", enable_flash_tunnelcreek},
1345#endif
1346{},
1347};
1348
1349int chipset_flash_enable(void)
1350{
1351struct pci_dev *dev = NULL;
1352int ret = -2;/* Nothing! */
1353int i;
1354
1355/* Now let's try to find the chipset we have... */
1356for (i = 0; chipset_enables[i].vendor_name != NULL; i++) {
1357dev = pci_dev_find(chipset_enables[i].vendor_id,
1358 chipset_enables[i].device_id);
1359if (!dev)
1360continue;
1361if (ret != -2) {
1362msg_pinfo("WARNING: unexpected second chipset match: "
1363 "\"%s %s\"\n"
1364 "ignoring, please report lspci and board URL "
1365 "to flashrom@flashrom.org\n"
1366 "with \'CHIPSET: your board name\' in the "
1367 "subject line.\n",
1368chipset_enables[i].vendor_name,
1369chipset_enables[i].device_name);
1370continue;
1371}
1372msg_pinfo("Found chipset \"%s %s\"",
1373 chipset_enables[i].vendor_name,
1374 chipset_enables[i].device_name);
1375msg_pdbg(" with PCI ID %04x:%04x",
1376 chipset_enables[i].vendor_id,
1377 chipset_enables[i].device_id);
1378msg_pinfo(". ");
1379
1380if (chipset_enables[i].status == NT) {
1381msg_pinfo("\nThis chipset is marked as untested. If "
1382 "you are using an up-to-date version\nof "
1383 "flashrom please email a report to "
1384 "flashrom@flashrom.org including a\nverbose "
1385 "(-V) log. Thank you!\n");
1386}
1387msg_pinfo("Enabling flash write... ");
1388ret = chipset_enables[i].doit(dev,
1389 chipset_enables[i].device_name);
1390if (ret == NOT_DONE_YET) {
1391ret = -2;
1392msg_pinfo("OK - searching further chips.\n");
1393} else if (ret < 0)
1394msg_pinfo("FAILED!\n");
1395else if (ret == 0)
1396msg_pinfo("OK.\n");
1397else if (ret == ERROR_NONFATAL)
1398msg_pinfo("PROBLEMS, continuing anyway\n");
1399if (ret == ERROR_FATAL) {
1400msg_perr("FATAL ERROR!\n");
1401return ret;
1402}
1403}
1404
1405return ret;
1406}
1407

Archive Download this file

Revision: HEAD