2 * OpenBIOS - free your system!
3 * ( firmware/flash device driver for Linux )
5 * pcisets.c - support functions to map flash devices to kernel space
7 * This program is part of a free implementation of the IEEE 1275-1994
8 * Standard for Boot (Initialization Configuration) Firmware.
10 * Copyright (C) 1998-2004 Stefan Reinauer, <stepan@openbios.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 2 of the License.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
27 #include <linux/config.h>
28 #include <linux/version.h>
29 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
31 #include <linux/modversions.h>
34 #include <linux/pci.h>
35 #include <linux/types.h>
36 #include <linux/ioport.h>
39 #include <asm/hwrpb.h>
43 #include "flashchips.h"
45 #include "programming.h"
48 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
49 #define pci_find_class pci_get_class
52 #define pci_id(dev) ((dev->vendor<<16) | (dev->device))
53 struct pci_dev
*hostbridge
=NULL
;
54 static unsigned char pci_dummy
[4];
57 * ******************************************
59 * own pci/shadow handling; We can't use
60 * the PCI bios here as it would sweep
63 * ******************************************
66 static int pci_read(struct pci_dev
*dev
, unsigned char where
)
70 outl((0x80000000 | (dev
->bus
->number
<< 16) | (dev
->devfn
<< 8) |
71 (where
& ~3)), 0xCF8);
73 return inb(0xCFC + (where
&3));
76 static void pci_write(struct pci_dev
*dev
, unsigned char where
, unsigned char value
)
79 outl((0x80000000 | (dev
->bus
->number
<< 16) | (dev
->devfn
<< 8) |
80 (where
& ~3)), 0xCF8);
82 outb(value
, 0xCFC + (where
&3));
86 * standard system firmware adress emitter
89 static int system_memarea(unsigned long *address
, unsigned long *size
,
92 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
93 const struct pci_driver
*drv
;
94 drv
= pci_dev_driver(dev
);
100 *address
=0xfffffffffc000000;
103 printk(KERN_INFO
"BIOS: Probing system firmware with "
104 "%ldk rom area @0x%lx (%04x:%04x)\n",
105 (*size
>>10), *address
, dev
->vendor
, dev
->device
);
106 #ifdef CONFIG_PCI_NAMES
107 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
108 if (drv
) printk(KERN_INFO
"BIOS: System device is %s\n", drv
->name
);
110 printk(KERN_INFO
"BIOS: System device is %s\n", dev
->name
);
116 static int memarea_256k(unsigned long *address
, unsigned long *size
,
119 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
120 const struct pci_driver
*drv
;
121 drv
= pci_dev_driver(dev
);
125 printk(KERN_INFO
"BIOS: Probing system firmware with "
126 "%ldk rom area @0x%lx (%04x:%04x)\n",
127 (*size
>>10), *address
, dev
->vendor
, dev
->device
);
128 #ifdef CONFIG_PCI_NAMES
129 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
130 if (drv
) printk(KERN_INFO
"BIOS: System device is %s\n", drv
->name
);
132 printk(KERN_INFO
"BIOS: System device is %s\n", dev
->name
);
139 * standard address emitter for normal pci devices
142 static int default_memarea(unsigned long *address
, unsigned long *size
,
145 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
146 *address
=dev
->resource
[PCI_ROM_RESOURCE
].start
;
147 *size
=dev
->resource
[PCI_ROM_RESOURCE
].end
- *address
+ 1;
152 if (*address
&& (signed long)*address
!=-1 ) {
153 printk (KERN_DEBUG
"BIOS: Probing PCI device %02x:%02x.%01x "
154 "with %ldk rom area @ 0x%lx\n",
155 dev
->bus
->number
, PCI_SLOT(dev
->devfn
),
156 PCI_FUNC(dev
->devfn
),
157 (*size
>>10), *address
);
166 void probe_alphafw(void)
168 switch(hwrpb
->sys_type
) {
173 /* case ST_DEC_TSUNAMI: // This crashes for whatever reason */
177 printk(KERN_INFO
"BIOS: unsupported alpha motherboard.\n");
181 /* LX164 has system variation 0x2000 */
182 if (hwrpb
->sys_variation
== 0x2000)
183 printk(KERN_INFO
"BIOS: LX164 detected\n");
185 printk(KERN_INFO
"BIOS: EB164 board detected. Sys_var=0x%lx\n",
186 hwrpb
->sys_variation
);
188 flashdevices
[flashcount
].data
=(void *)0xfff80000;
189 flash_probe_area(0xfff80000, 512*1024, 0);
193 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
194 #define pci_for_each_dev(dev) \
195 for(dev = pci_devices->next; dev != pci_devices; dev = dev->next)
197 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,74)
198 #define pci_for_each_dev(dev) \
199 while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
202 #define DEVICE(x) devices[g].pcidevs[x]
203 void probe_pcibus(void)
205 struct pci_dev
*dev
=NULL
;
206 unsigned int g
=0, d
, map_always
=0;
207 unsigned long addr
, size
;
209 /* Look whether we find something supported */
210 pci_for_each_dev(dev
) {
211 /* Search all device groups */
212 for (g
=0; DEVICE(0); g
++ ) {
213 /* Search all devices in group */
214 for (d
=0; DEVICE(d
) && DEVICE(d
) != pci_id(dev
); d
++);
215 if(DEVICE(d
) == pci_id(dev
))
219 flashdevices
[flashcount
].idx
=g
;
220 flashdevices
[flashcount
].data
=dev
;
222 map_always
=devices
[g
].memarea(&addr
, &size
, dev
);
224 printk(KERN_INFO
"BIOS: device=%x, cs=%d addr=%lx, size=%ld\n",
225 pci_id(dev
),g
, addr
,size
);
230 flash_probe_area(addr
, size
, map_always
);
235 /* Intel 430, 440, 450 PCI Chipsets */
237 #define CURRENT ((struct pci_dev *)flashdevices[currflash].data)
238 static int gporeg_save
;
239 static void intel4x0_activate(void)
241 #ifdef __ABIT_BE6II_v11__
243 #define GPOREG_OFFSET 0x34
244 register unsigned int gporeg
;
245 /* Read Bus 0, Dev 7, Func 3, Reg 40-44 (Power Managment Base Address) */
246 outl (0x80003B40, 0x0CF8);
247 /* calc General Purpose Output Register I/O port address */
248 gporeg
= (0xFFFFFFFE & inl (0x0CFC)) + GPOREG_OFFSET
;
251 gporeg_save
=inl(gporeg
);
252 printk(KERN_DEBUG
"BIOS: GPOREG=0x%08x, mask=0x%x, new=0x%x\n",gporeg_save
, (~(1<<GPONUM
)), gporeg_save
&(~(1<<GPONUM
)));
253 outl (gporeg_save
&(~(1<<GPONUM
)), gporeg
);
257 pci_dummy
[0]=pci_read(CURRENT
, 0x4e);
258 pci_dummy
[1]=pci_read(CURRENT
, 0x4f);
260 /* Write and 128k enable */
261 pci_dummy
[2]=0x44; //0xC4
263 if (CURRENT
->device
< 0x7000) {
268 pci_write(CURRENT
, 0x4f, pci_dummy
[1] | 0x02);
271 pci_write(CURRENT
, 0x4e, pci_dummy
[0] | pci_dummy
[2]);
273 // printk(KERN_DEBUG "BIOS: isa bridge cfg is 0x%02x\n", pci_dummy[0]);
276 static void intel4x0_deactivate(void)
278 #ifdef __ABIT_BE6II_v11__
279 #define GPOREG_OFFSET 0x34
280 register unsigned long gporeg
;
282 /* Read Bus 0, Dev 7, Func 3, Reg 40-44 (Power Managment Base Address) */
283 outl (0x80003B40, 0x0CF8);
284 /* calc General Purpose Output Register I/O port address */
285 gporeg
= (0xFFFFFFFE & inl (0x0CFC)) + GPOREG_OFFSET
;
288 outl (gporeg_save
, gporeg
);
291 pci_write(CURRENT
, 0x4e, pci_dummy
[0]);
292 pci_write(CURRENT
, 0x4f, pci_dummy
[1]);
295 /* preliminary support for Intel 830 mobile chipset. untested!! */
297 static void intel8x0_activate(void)
299 pci_dummy
[0]=pci_read(CURRENT
, 0x4e);
300 pci_dummy
[1]=pci_read(CURRENT
, 0xe3);
301 pci_write(CURRENT
, 0x4e, pci_dummy
[0] | 0x01);
302 pci_write(CURRENT
, 0xe3, pci_dummy
[1] | 0xC0);
304 // We don't have to change FWH_DEC_EN1, as it decodes
305 // all memory areas to the FWH per default.
306 // We try it anyways.
308 // FWH_DEC_EN1: isabridge, 0xe3, 8bit, default 0xff.
309 // FWH_SEL1: isabridge, 0xe8, 32bit, default 0x00112233 (??)
311 //printk(KERN_DEBUG "BIOS: BIOS_CNTL is 0x%02x\n", pci_dummy[0]);
312 //printk(KERN_DEBUG "BIOS: FWH_DEC_EN1 is 0x%02x\n", pci_dummy[1]);
315 static void intel8x0_deactivate(void)
317 pci_write(CURRENT
, 0x4e, pci_dummy
[0]);
318 pci_write(CURRENT
, 0xe3, pci_dummy
[1]);
321 /* AMD 760/756/751 & VIA (M)VP3 */
323 static void amd7xx_activate(void)
325 pci_dummy
[0]=pci_read(CURRENT
, 0x40); /* IO Control 1 */
326 pci_dummy
[1]=pci_read(CURRENT
, 0x43); /* SEGEN */
328 pci_write(CURRENT
, 0x40, pci_dummy
[0] | 0x01);
329 pci_write(CURRENT
, 0x43, pci_dummy
[1] | 0x80);
332 static void amd7xx_deactivate(void)
334 pci_write(CURRENT
, 0x43, pci_dummy
[1]);
335 pci_write(CURRENT
, 0x40, pci_dummy
[0]);
338 static void viamvp3_activate(void)
340 hostbridge
= pci_find_class(PCI_CLASS_BRIDGE_HOST
<<8,NULL
);
343 pci_dummy
[0]=pci_read(hostbridge
,0x52);
344 pci_write(hostbridge
, 0x52, pci_dummy
[0] & 0xcf);
345 pci_dummy
[1]=pci_read(hostbridge
, 0x63);
346 pci_write(hostbridge
, 0x63, pci_dummy
[1] & 0x0f);
347 pci_dummy
[2]=pci_read(CURRENT
,0x43);
348 pci_write(CURRENT
, 0x43, pci_dummy
[2] |0xF8);
350 pci_write(CURRENT
, 0x40, pci_read(CURRENT
,0x40) | 0x01);
353 static void viamvp3_deactivate(void)
357 pci_write(CURRENT
, 0x40, pci_read(CURRENT
,0x40) & 0xfe);
358 pci_write(hostbridge
, 0x63, pci_dummy
[1]);
359 pci_write(hostbridge
, 0x52, pci_dummy
[0]);
360 pci_write(CURRENT
, 0x43, pci_dummy
[2]);
363 /* SiS works with 530/5595 chipsets */
365 static void sis_activate(void)
368 hostbridge
= pci_find_class(PCI_CLASS_BRIDGE_HOST
<<8,NULL
);
372 pci_dummy
[0]=pci_read(hostbridge
, 0x76);
373 pci_dummy
[1]=readb(0x51);
374 pci_dummy
[2]=pci_read(CURRENT
, 0x40);
375 pci_dummy
[3]=pci_read(CURRENT
, 0x45);
378 pci_write(hostbridge
, 0x76, 0x00);
380 writeb(pci_dummy
[1] & 0x7f, 0x51);
382 /* Enable 0xFFF8000~0xFFFF0000 decoding on SiS 540/630 */
383 pci_write(CURRENT
, 0x40, pci_dummy
[2]|0x0b);
384 /* Flash write enable on SiS 540/630 */
385 pci_write(CURRENT
, 0x45, pci_dummy
[3]|0x40);
387 /* The same thing on SiS 950 SuperIO side */
392 if (inb(0x2f) != 0x87) {
393 /* printf("Can not access SiS 950\n"); */
398 b
= inb(0x2f) | 0xfc;
405 static void sis_deactivate(void)
410 /* Restore PCI Registers */
411 pci_write(hostbridge
, 0x76, pci_dummy
[0]);
412 pci_write(CURRENT
, 0x45, pci_dummy
[2]);
413 pci_write(CURRENT
, 0x45, pci_dummy
[3]);
414 /* restore cache to original status */
415 writeb(pci_dummy
[1], 0x51);
418 /* UMC 486 Chipset 8881/886a */
420 static void umc_activate(void)
422 hostbridge
= pci_find_class(PCI_CLASS_BRIDGE_HOST
<<8,NULL
);
426 pci_dummy
[0]=pci_read(hostbridge
, 0x54);
427 pci_dummy
[1]=pci_read(hostbridge
, 0x55);
429 pci_write(hostbridge
, 0x54, 0x00);
430 pci_write(hostbridge
, 0x55, 0x40);
432 pci_write(CURRENT
,0x47, pci_read(CURRENT
,0x47) & ~0x40);
435 static void umc_deactivate(void)
440 pci_write(CURRENT
, 0x47, pci_read(CURRENT
,0x47) | 0x40);
442 pci_write(hostbridge
, 0x54, pci_dummy
[0]);
443 pci_write(hostbridge
, 0x55, pci_dummy
[1]);
446 /* CS5530 functions */
448 static void cs5530_activate(void)
450 /* Save modified registers for later reset */
451 pci_dummy
[0]=pci_read(CURRENT
,0x52);
452 pci_dummy
[1]=pci_read(CURRENT
,0x5b);
454 /* enable rom write access */
455 pci_write(CURRENT
, 0x52, pci_dummy
[0]|0x06);
457 /* enable rom positive decode */
458 // pci_write(CURRENT,0x5b, pci_dummy[1]|0x20);
459 // pci_write(CURRENT,0x52, pci_read(CURRENT,0x52)|0x01);
462 static void cs5530_deactivate(void)
464 pci_write(CURRENT
, 0x52, pci_dummy
[0]);
465 // pci_write(CURRENT, 0x5b, pci_dummy[1]);
468 /* Reliance / ServerWorks */
470 static void reliance_activate(void)
472 pci_dummy
[0]=pci_read(CURRENT
,0x41);
473 pci_dummy
[1]=pci_read(CURRENT
,0x70);
474 pci_dummy
[2]=inb(0xc6f);
477 pci_write(CURRENT
, 0x41, pci_dummy
[0] | 0x02);
479 pci_write(CURRENT
, 0x70, pci_dummy
[1] | 0x80);
480 /* Enable flash write */
481 outb(pci_dummy
[2] | 0x40, 0xc6f);
484 static void reliance_deactivate(void)
486 pci_write(CURRENT
, 0x41, pci_dummy
[0]);
487 pci_write(CURRENT
, 0x70, pci_dummy
[1]);
488 outb(pci_dummy
[2], 0xc6f);
491 /* ALi Methods - untested */
492 static void ali_activate(void)
494 pci_dummy
[0]=pci_read(CURRENT
, 0x47);
495 pci_dummy
[1]=pci_read(CURRENT
, 0x79);
496 pci_dummy
[2]=pci_read(CURRENT
, 0x7f);
498 /* write enable, 256k enable */
500 pci_write(CURRENT
, 0x47, pci_dummy
[0]|0x47);
502 pci_write(CURRENT
, 0x47, pci_dummy
[0]|0x43);
505 /* M1543C rev B1 supports 512k. Register reserved before */
507 pci_write(CURRENT
, 0x79, pci_dummy
[1]|0x10);
508 pci_write(CURRENT
, 0x7f, pci_dummy
[2]|0x01);
510 pci_write(CURRENT
, 0x7b, pci_dummy
[1]|0x10);
514 static void ali_deactivate(void)
516 pci_write(CURRENT
, 0x47, pci_dummy
[0]);
517 pci_write(CURRENT
, 0x79, pci_dummy
[1]);
518 pci_write(CURRENT
, 0x7f, pci_dummy
[2]);
521 /* Default routines. Use these if nothing else works */
523 static unsigned int def_addr
;
525 static void default_activate(void)
527 #if 0 && LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)
530 r
=&CURRENT
->resource
[PCI_ROM_RESOURCE
];
532 r
->flags
|= PCI_ROM_ADDRESS_ENABLE
;
533 r
->flags
&= ~(IORESOURCE_READONLY
|IORESOURCE_CACHEABLE
);
534 pci_read_config_dword(CURRENT
, CURRENT
->rom_base_reg
, &def_addr
);
536 pci_write_config_dword (CURRENT
, CURRENT
->rom_base_reg
,
537 def_addr
|PCI_ROM_ADDRESS_ENABLE
);
539 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
542 if (pci_enable_device(CURRENT
))
545 pci_write_config_dword (CURRENT
, CURRENT
->rom_base_reg
,
546 pci_resource_start(CURRENT
, PCI_ROM_RESOURCE
)|
547 PCI_ROM_ADDRESS_ENABLE
);
549 ret
=(long)request_mem_region( pci_resource_start(CURRENT
,
550 PCI_ROM_RESOURCE
), pci_resource_len(CURRENT
,
551 PCI_ROM_RESOURCE
), "Firmware memory");
553 printk (KERN_ERR
"BIOS: cannot reserve MMROM region "
555 pci_resource_start(CURRENT
, PCI_ROM_RESOURCE
),
556 pci_resource_len(CURRENT
, PCI_ROM_RESOURCE
));
558 printk (KERN_INFO
"BIOS: mapped rom region to 0x%lx\n", ret
);
562 static void default_deactivate(void)
564 #if 0 && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
566 r
=&CURRENT
->resource
[PCI_ROM_RESOURCE
];
567 r
->flags
&= ~PCI_ROM_ADDRESS_ENABLE
;
568 r
->flags
|= (IORESOURCE_READONLY
|IORESOURCE_CACHEABLE
);
569 pci_write_config_dword (CURRENT
, CURRENT
->rom_base_reg
, def_addr
);
571 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
572 release_mem_region(pci_resource_start(CURRENT
, PCI_ROM_RESOURCE
),
573 pci_resource_len(CURRENT
, PCI_ROM_RESOURCE
));
577 const struct flashdev devices
[] = {
578 /* Intel 4x0 chipsets */
579 { (int[]) { 0x8086122e, 0x80861234, 0x80867000, 0x80867110,
581 intel4x0_activate
, intel4x0_deactivate
, system_memarea
},
583 /* Intel 8x0 chipsets */
584 { (int[]) { 0x80862410, 0x80862420, 0x80862440, 0x8086244c,
585 0x80862480, 0x8086248c, 0x80867600, 0 },
586 intel8x0_activate
, intel8x0_deactivate
, system_memarea
},
588 /* Irongate 75x, AMD-76xMP(X), VT8231/3 */
589 { (int[]) { 0x10227400, 0x10227408, 0x10227410, 0x10227440,
590 0x11068231, 0x11063074, 0 },
591 amd7xx_activate
, amd7xx_deactivate
, system_memarea
},
593 /* AMD Hammer (thor chipset) */
594 { (int[]) { 0x10227468, 0 },
595 amd7xx_activate
, amd7xx_deactivate
, system_memarea
},
597 /* VIA (M)VP3, VT82C686 [Apollo Super South] */
598 { (int[]) { 0x11060586, 0x11060596, 0x11060686, 0 },
599 viamvp3_activate
, viamvp3_deactivate
, memarea_256k
},
602 { (int[]) { 0x1060886a, 0x10600886, 0x1060e886, 0x10608886, 0 },
603 umc_activate
, umc_deactivate
, system_memarea
},
606 { (int[]) { 0x10390008, 0x10390018, 0 },
607 sis_activate
, sis_deactivate
, system_memarea
},
610 { (int[]) { 0x1045c558, 0 },
611 default_activate
, default_deactivate
, system_memarea
},
614 { (int[]) { 0x10780100, 0 },
615 cs5530_activate
, cs5530_deactivate
, memarea_256k
},
617 /* Reliance/ServerWorks NB6xxx */
618 { (int[]) { 0x11660200, 0 },
619 reliance_activate
, reliance_deactivate
, system_memarea
},
622 { (int[]) { 0x10b91523, 0x10b91533, 0x10b91543, 0 },
623 ali_activate
, ali_deactivate
, system_memarea
},
625 { (int[]) { 0x00000000 },
626 default_activate
, default_deactivate
, default_memarea
}
629 #endif /* CONFIG_PCI */