⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcisets.c

📁 Linux下操作Bios的驱动
💻 C
字号:
/* * BIOS/Flashrom driver for Linux * * Copyright (C) 1998-2002 Stefan Reinauer <stepan@suse.de> * */#include <linux/config.h>#include <linux/pci.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/vmalloc.h>#include <linux/ioport.h>#include <linux/fcntl.h>#include <linux/init.h>#include <asm/io.h>#include <asm/delay.h>#include <linux/delay.h>#include <asm/uaccess.h>#include "bios.h"#include "pcisets.h"#if defined(__i386__) || defined(__ia64__) || defined(__alpha__)static void intel4x0_activate(void), intel4x0_deactivate(void);static void intel8x0_activate(void), intel8x0_deactivate(void);static void amd7xx_activate(void), amd7xx_deactivate(void);static void umc_activate(void), umc_deactivate(void);static void sis_activate(void), sis_deactivate(void);static void cs5530_activate(void), cs5530_deactivate(void);static void reliance_activate(void), reliance_deactivate(void);static void default_activate(void), default_deactivate(void);const struct functions pci_functions[] = {  /* Intel 4x0 chipsets */  { (int[]) { 0x8086122d, 0x80861235, 0x80861237, 0x80861250, 0x80867030,	      0x80867100, 0x80867180, 0x808684c4, 0x80867190, 0x80867192,	      0x808671A0, 0x808671A2, 0 },    (int[]) { 0x8086122e, 0x80861234, 0x80867000, 0x80867110, 0 },    intel4x0_activate, intel4x0_deactivate },  /* Intel 8x0 chipsets */  { (int[]) { 0x80861A30, 0x80862500, 0x80862531, 0x80863575, 0x80867120, 	      0x80867124, 0x808684e0, 0 },    (int[]) { 0x80862410, 0x80862420, 0x80862440, 0x8086244c, 0x8086248c,	      0x80867600, 0 },    intel8x0_activate, intel8x0_deactivate },      /* Irongate 75x, AMD-76xMP(X), VIA (M)VP3, VT8231/3 */  { (int[]) { 0x10227006, 0x1022700c, 0x1022700e, 0x11060576, 0x11060585,	      0x11060595, 0x11060597, 0x11068597, 0x11060598, 0x11060685,	      0x11060501, 0x11060691, 0x11060693, 0x11060601, 0x11060605,	      0x11060391, 0x11060305, 0x11063099, 0x11063091, 0x11063101,	      0x11063102, 0x11063103, 0x11063112, 0x11063133, 0 },    (int[]) { 0x10227408, 0x10227410, 0x10227440, 0x11060686, 0x11060586, 	      0x11060596, 0x11068231, 0x11063074, 0 },    amd7xx_activate, amd7xx_deactivate },    /* UMC 486 */  { (int[]) { 0x10608881, 0x10600881, 0x1060e881, 0 },    (int[]) { 0x1060886a, 0x10600886, 0x1060e886, 0x10608886, 0 },    umc_activate, umc_deactivate },  /* UMC Pentium */  { (int[]) { 0x10608891, 0x1060e891, 0x10600891, 0 },    (int[]) { 0x1060886a, 0x10600886, 0x1060e886, 0x10608886, 0 },    default_activate, default_deactivate },  /* SiS */  { (int[]) { 0x10390496, 0x10395597, 0x10390530, 0 },    (int[]) { 0x10390008, 0x10390018, 0 },    sis_activate, sis_deactivate },  /* OPTi */  { (int[]) { 0x1045c557, 0 },    (int[]) { 0x1045c558, 0 },    default_activate, default_deactivate },  /* CS5530(A) */  { (int[]) { 0x10780001, 0 },    (int[]) { 0x10780100, 0 },    cs5530_activate, cs5530_deactivate },   /* Reliance/ServerWorks NB6xxx */  { (int[]) { 0x11660007, 0x11660008, 0x11660009, 0 },    (int[]) { 0x11660200, 0 },    reliance_activate, reliance_deactivate },  { (int[]) { 0x0 },    (int[]) { 0x0 },    default_activate, default_deactivate },};#endifint chipset=0;#if defined(__i386__) || defined(__ia64__) || defined(__alpha__)unsigned char pci_dummy[4];struct pci_dev *isabridge=NULL, *hostbridge=NULL;int chipset_init(void);#endifchar flash_readb(unsigned int offset);void flash_writeb(unsigned int offset, char data);/* * ****************************************** * *   own pci/shadow handling; We can't use  *   the PCI bios here as it would sweep *   itself out! * * ******************************************  */static int pci_read(struct pci_dev *dev, unsigned char where){	if (!dev) return 0;		outl((0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | 	      						(where & ~3)), 0xCF8);	mb();	return inb(0xCFC + (where&3));}static void pci_write(struct pci_dev *dev, unsigned char where, unsigned char value){	if (!dev) return;	outl((0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) |	      						(where & ~3)), 0xCF8);	mb();	outb(value, 0xCFC + (where&3));}/* ****************************************** * *    PCI Chipset specific routines. * * ******************************************  *//* This function detects the isa bridge and host bridge and * selects the correct chipset class for the pci_functions  * structure. */#if defined(__i386__) || defined(__ia64__) || defined(__alpha__)#define HOST(x) pci_functions[chipset].hostbridges[x]#define ISA(x)  pci_functions[chipset].isabridges[x]int chipset_init(void){	unsigned int i=0;		/* look for a host bridge. Ruffians hide this one. */	hostbridge = pci_find_class(PCI_CLASS_BRIDGE_HOST<<8,NULL);	/* Look for an ISA bridge */	isabridge = pci_find_class(PCI_CLASS_BRIDGE_ISA<<8,NULL);#ifdef DEBUG	if (hostbridge) 		printk (KERN_DEBUG "BIOS: host bridge is %x, %x, %x\n",		  hostbridge->vendor, hostbridge->device, hostbridge->devfn);	if (isabridge)		printk (KERN_DEBUG "BIOS: isa bridge is %x, %x, %x\n",		  isabridge->vendor, isabridge->device, isabridge->devfn);#endif#ifdef __i386__	/* We do need to have a host bridge that is in the list	 * as long as there are chipset drivers using hostbridge	 * access.	 */	if (!hostbridge) {	  	printk(KERN_ERR "BIOS: No hostbridge found.\n");		return -ENOMEDIUM;	}		for (chipset=0; HOST(0); chipset++ ) {		for (i=0; HOST(i) && HOST(i) != pci_id(hostbridge); i++) ;		if (HOST(i))			break;	}			/* If we did not find an isa bridge, we look for a	 * device known to have the functionality we want.	 */	if (!HOST(i)) {		printk(KERN_ERR "BIOS: hostbridge not supported.\n");		return -ENOMEDIUM;	}	if(!isabridge) {		for (i=0; ISA(i) && (isabridge = 			(pci_find_device(ISA(i)>>16,ISA(i)&0xffff,					 NULL))) == NULL; i++) ;		/* Without any supported device we can't find a flash chip */ 		if (!isabridge) {		 	printk(KERN_ERR "BIOS: No isa bridge found.\n");			return -ENOMEDIUM;		}	}#ifdef DEBUG	else {		for (i=0; ISA(i) && ISA(i)!= pci_id(isabridge); i++) ;		if (!ISA(i))			printk ( KERN_DEBUG "BIOS: Unknown isa bridge.\n");	}#endif#else	if (!isabridge) {	  	printk(KERN_ERR "BIOS: No isa bridge found.\n");		return -ENOMEDIUM;	}		for (chipset=0; ISA(0); chipset++ ) {		for (i=0; ISA(i) && ISA(i) != pci_id(isabridge); i++) ;		if (ISA(i))			break;	}		if (!ISA(i)) {	  	printk(KERN_ERR "BIOS: isa bridge not supported.\n");		return -ENOMEDIUM;	}#endif	return 0;}#undef HOST#undef ISA/* Intel 430, 440, 450 PCI Chipsets */static void intel4x0_activate(void){	pci_dummy[0]=pci_read(isabridge, 0x4e);	pci_dummy[1]=pci_read(isabridge, 0x4f);		/* Write and 128k enable */	pci_dummy[2]=0x44;	if (isabridge->device < 0x7000) {		/* enable 512k */		pci_dummy[2]|=0x80;	} else {		/* enable 1M */		pci_write(isabridge, 0x4f, pci_dummy[1] | 0x02);	}		pci_write(isabridge, 0x4e, pci_dummy[0] | pci_dummy[2]);	// printk(KERN_DEBUG "BIOS: isa bridge cfg is 0x%02x\n", pci_dummy[0]);}static void intel4x0_deactivate(void){	pci_write(isabridge, 0x4e, pci_dummy[0]);	pci_write(isabridge, 0x4f, pci_dummy[1]);}/* preliminary support for Intel 830 mobile chipset. untested!! */static void intel8x0_activate(void){	pci_dummy[0]=pci_read(isabridge, 0x4e);	pci_dummy[1]=pci_read(isabridge, 0xe3);	pci_write(isabridge, 0x4e, pci_dummy[0] | 0x01);	pci_write(isabridge, 0xe3, pci_dummy[1] | 0xC0);	// We don't have to change FWH_DEC_EN1, as it decodes	// all memory areas to the FWH per default. 	// We try it anyways.	// FWH_DEC_EN1: isabridge, 0xe3,  8bit, default 0xff.	// FWH_SEL1:    isabridge, 0xe8, 32bit, default 0x00112233 (??)	//printk(KERN_DEBUG "BIOS: BIOS_CNTL is 0x%02x\n", pci_dummy[0]);	//printk(KERN_DEBUG "BIOS: FWH_DEC_EN1 is 0x%02x\n", pci_dummy[1]);}static void intel8x0_deactivate(void){	pci_write(isabridge, 0x4e, pci_dummy[0]);	pci_write(isabridge, 0xe3, pci_dummy[1]);}/* AMD 760/756/751 & VIA (M)VP3  */static void amd7xx_activate(void){	pci_dummy[0]=pci_read(isabridge, 0x40); /* IO Control 1 */	pci_dummy[1]=pci_read(isabridge, 0x43); /* SEGEN */		pci_write(isabridge, 0x40, pci_dummy[0] | 0x01);	pci_write(isabridge, 0x43, pci_dummy[1] | 0x80);}static void amd7xx_deactivate(void){	pci_write(isabridge, 0x43, pci_dummy[1]);	pci_write(isabridge, 0x40, pci_dummy[0]);}/* SiS works with 530/5595 chipsets */static void sis_activate(void) {	pci_dummy[0]=pci_read(hostbridge, 0x76);	pci_dummy[1]=readb(0x51);		/* disable shadow */	pci_write(hostbridge, 0x76, 0x00);	/* disable cache */	writeb(pci_dummy[1] & 0x7f, 0x51);	/* enable flash write enable */	pci_write(isabridge, 0x45, 0x44);}static void sis_deactivate(void) {	/* disable flash write */	pci_write(isabridge, 0x45, 0x60);	/* shadow restore to original */	pci_write(hostbridge, 0x76, pci_dummy[0]);	/* restore cache to original status */	writeb(pci_dummy[1], 0x51);}/* UMC 486 Chipset 8881/886a */static void umc_activate(void){        pci_dummy[0]=pci_read(hostbridge, 0x54);	pci_dummy[1]=pci_read(hostbridge, 0x55);        pci_write(hostbridge, 0x54, 0x00);        pci_write(hostbridge, 0x55, 0x40);	pci_write(isabridge,0x47, pci_read(isabridge,0x47) & ~0x40);}static void umc_deactivate(void){	pci_write(isabridge, 0x47, pci_read(isabridge,0x47) | 0x40);        pci_write(hostbridge, 0x54, pci_dummy[0]);        pci_write(hostbridge, 0x55, pci_dummy[1]);}/* CS5530 functions */static void cs5530_activate(void){	/* Save modified registers for later reset */	pci_dummy[0]=pci_read(isabridge,0x52);	pci_dummy[1]=pci_read(isabridge,0x5b);	/* enable rom write access */	pci_write(isabridge, 0x52, pci_dummy[0]|0x06);	/* enable rom positive decode */	// pci_write(isabridge,0x5b, pci_dummy[1]|0x20);	// pci_write(isabridge,0x52, pci_read(isabridge,0x52)|0x01);}static void cs5530_deactivate(void){        pci_write(isabridge, 0x52, pci_dummy[0]);        // pci_write(isabridge, 0x5b, pci_dummy[1]);}/* Reliance / ServerWorks */static void reliance_activate(void){	pci_dummy[0]=pci_read(isabridge,0x41);	pci_dummy[1]=pci_read(isabridge,0x70);	pci_dummy[2]=inb(0xc6f);		/* Enable 512k */	pci_write(isabridge, 0x41, pci_dummy[0] | 0x02);	/* Enable 4MB */	pci_write(isabridge, 0x70, pci_dummy[1] | 0x80);	/* Enable flash write */	outb(pci_dummy[2] | 0x40, 0xc6f);} static void reliance_deactivate(void){	pci_write(isabridge, 0x41, pci_dummy[0]);	pci_write(isabridge, 0x70, pci_dummy[1]);	outb(pci_dummy[2], 0xc6f);}/* Default routines. Use these if nothing else works */static void default_activate(void){	printk(KERN_ERR "BIOS: Could not handle your PCI Chipset. Please report!\n");}static void default_deactivate(void){	/* not possible */}#endif	/* (__i386__) || (__ia64__) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -