xf86_pci.c

来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 1,218 行 · 第 1/3 页

C
1,218
字号
	return;    } else {	/* Now try pci config 2 probe (deprecated) */	/* The code here doesn't handle multifunction devices. */    	/* it doesn't seem to handle multiple busses fully either */	int ioaddr = 0xC000 + (cardnum * 0x100);	outb(PCI_MODE2_ENABLE_REG, 0xF1);	outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */	outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */        tmp = inl(ioaddr + reg) & ~mask;	outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */        outl(ioaddr + reg, tmp | (value & mask));	outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */	outb(PCI_MODE2_ENABLE_REG, 0x00);	outb(PCI_MODE2_FORWARD_REG, 0x00);	xf86DisableIOPorts(scrnIndex);	xf86ClearIOPortList(scrnIndex);	return;    }}voidxf86cleanpci(){    int idx = 0;    while (pci_devp[idx])	xfree((Pointer)pci_devp[idx++]);    pci_devp[0] = (pciConfigPtr)NULL;}#else /* USE_OLD_PCI_CODE */	/* } { *//* New PCI code *//* * This is based heavily on the code in FreeBSD-current, which was written * by Wolfgang Stanglmeier, and contains the following copyright: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */static int pciConfigType = 0;static int pciMaxDevice = 0;#if defined(__alpha__)#include <asm/unistd.h>#define BUS(tag) (((tag)>>16)&0xff)#define DFN(tag) (((tag)>>8)&0xff)int pciconfig_read(          unsigned char bus,          unsigned char dfn,          unsigned char off,          unsigned char len,          void * buf){  return __syscall(__NR_pciconfig_read, bus, dfn, off, len, buf);}int pciconfig_write(          unsigned char bus,          unsigned char dfn,          unsigned char off,          unsigned char len,          void * buf){  return __syscall(__NR_pciconfig_write, bus, dfn, off, len, buf);}#endif /* __alpha__ */static BoolpcibusCheck(){    CARD8 device;    for (device = 0; device < pciMaxDevice; device++) {	CARD32 id;	id = pcibusRead(pcibusTag(0, device, 0), 0);	if (id && id != 0xffffffff) {	    return TRUE;	}    }    return 0;}static voidpcibusSetup(){    static Bool setupDone = FALSE;    CARD32 mode1Res1 = 0, mode1Res2 = 0, oldVal1 = 0;    CARD8  mode2Res1 = 0, mode2Res2 = 0, oldVal2 = 0;    int stages = 0;    if (setupDone)	return;    setupDone = TRUE;#if !defined(__alpha__)    switch (xf86PCIFlags) {    case PCIProbe1: /* { */      if (xf86Verbose > 1) {	ErrorF("PCI: Probing config type using method 1\n");      }      oldVal1 = inl(PCI_MODE1_ADDRESS_REG);#ifdef DEBUGPCI      if (xf86Verbose > 2) {	ErrorF("Checking config type 1:\n"		"\tinitial value of MODE1_ADDR_REG is 0x%08x\n", oldVal1);	ErrorF("\tChecking that all bits in mask 0x7f000000 are clear\n");      }#endif      /* Assuming config type 1 to start with */      if ((oldVal1 & 0x7f000000) == 0) {	stages |= 0x01;#ifdef DEBUGPCI	if (xf86Verbose > 2) {	    ErrorF("\tValue indicates possibly config type 1\n");	    ErrorF("\tWriting 32-bit value 0x%08x to MODE1_ADDR_REG\n", PCI_EN);#if 0	    ErrorF("\tWriting 8-bit value 0x00 to MODE1_ADDR_REG + 3\n");#endif	}#endif	pciConfigType = 1;	pciMaxDevice = PCI_CONFIG1_MAXDEV;	outl(PCI_MODE1_ADDRESS_REG, PCI_EN);#if 0	/*	 * This seems to cause some Neptune-based PCI machines to switch	 * from config type 1 to config type 2	 */	outb(PCI_MODE1_ADDRESS_REG + 3, 0);#endif	mode1Res1 = inl(PCI_MODE1_ADDRESS_REG);#ifdef DEBUGPCI	if (xf86Verbose > 2) {	    ErrorF("\tValue read back from MODE1_ADDR_REG is 0x%08x\n",			mode1Res1);	    ErrorF("\tRestoring original contents of MODE1_ADDR_REG\n");	}#endif	outl(PCI_MODE1_ADDRESS_REG, oldVal1);	if (mode1Res1) {	    stages |= 0x02;#ifdef DEBUGPCI	    if (xf86Verbose > 2) {		ErrorF("\tValue read back is non-zero, and indicates possible"			" config type 1\n");	    }#endif	    if (pcibusCheck()) {#ifdef DEBUGPCI		if (xf86Verbose > 2)		    ErrorF("\tBus check Confirms this: ");#endif		if (xf86Verbose > 1) {		    ErrorF("PCI: Config type is 1\n");		}		if (xf86Verbose > 2) {		    ErrorF("PCI: stages = 0x%02x, oldVal1 = 0x%08x, mode1Res1"			   " = 0x%08x\n", stages, oldVal1, mode1Res1);		}		return;	    }#ifdef DEBUGPCI	    if (xf86Verbose > 2) {		ErrorF("\tBus check fails to confirm this, continuing type 1"			" check ...\n");	    }#endif	}	stages |= 0x04;#ifdef DEBUGPCI	if (xf86Verbose > 2) {	    ErrorF("\tWriting 0xff000001 to MODE1_ADDR_REG\n");	}#endif	outl(PCI_MODE1_ADDRESS_REG, 0xff000001);	mode1Res2 = inl(PCI_MODE1_ADDRESS_REG);#ifdef DEBUGPCI	if (xf86Verbose > 2) {	    ErrorF("\tValue read back from MODE1_ADDR_REG is 0x%08x\n",			mode1Res2);	    ErrorF("\tRestoring original contents of MODE1_ADDR_REG\n");	}#endif	outl(PCI_MODE1_ADDRESS_REG, oldVal1);	if ((mode1Res2 & 0x80000001) == 0x80000000) {	    stages |= 0x08;#ifdef DEBUGPCI	    if (xf86Verbose > 2) {		ErrorF("\tValue read back has only the msb set\n"			"\tThis indicates possible config type 1\n");	    }#endif	    if (pcibusCheck()) {#ifdef DEBUGPCI		if (xf86Verbose > 2)		    ErrorF("\tBus check Confirms this: ");#endif		if (xf86Verbose > 1) {		    ErrorF("PCI: Config type is 1\n");		}		if (xf86Verbose > 2) {		    ErrorF("PCI: stages = 0x%02x, oldVal1 = 0x%08x,\n"			   "\tmode1Res1 = 0x%08x, mode1Res2 = 0x%08x\n",			   stages, oldVal1, mode1Res1, mode1Res2);		}		return;	    }#ifdef DEBUGPCI	    if (xf86Verbose > 2) {		ErrorF("\tBus check fails to confirm this.\n");	    }#endif	}      }         if (xf86Verbose > 2) {	ErrorF("PCI: Standard check for type 1 failed.\n");	ErrorF("PCI: stages = 0x%02x, oldVal1 = 0x%08x,\n"	       "\tmode1Res1 = 0x%08x, mode1Res2 = 0x%08x\n",	       stages, oldVal1, mode1Res1, mode1Res2);      }       /* Try config type 2 */      oldVal2 = inb(PCI_MODE2_ENABLE_REG);      if ((oldVal2 & 0xf0) == 0) {	pciConfigType = 2;	pciMaxDevice = PCI_CONFIG2_MAXDEV;	outb(PCI_MODE2_ENABLE_REG, 0x0e);	mode2Res1 = inb(PCI_MODE2_ENABLE_REG);	outb(PCI_MODE2_ENABLE_REG, oldVal2);	if (mode2Res1 == 0x0e) {	    if (pcibusCheck()) {		if (xf86Verbose > 1) {		    ErrorF("PCI: Config type is 2\n");		}		return;	    }	}      }      break; /* } */    case PCIProbe2: /* { */      /* The scanpci-style detection method */      if (xf86Verbose > 1) {	ErrorF("PCI: Probing config type using method 2\n");      }      outb(PCI_MODE2_ENABLE_REG, 0x00);      outb(PCI_MODE2_FORWARD_REG, 0x00);      mode2Res1 = inb(PCI_MODE2_ENABLE_REG);      mode2Res2 = inb(PCI_MODE2_FORWARD_REG);      if (mode2Res1 == 0 && mode2Res2 == 0) {	if (xf86Verbose > 1) {	    ErrorF("PCI: Config type is 2\n");	}	pciConfigType = 2;	pciMaxDevice = PCI_CONFIG2_MAXDEV;	return;      }      oldVal1 = inl(PCI_MODE1_ADDRESS_REG);      outl(PCI_MODE1_ADDRESS_REG, PCI_EN);      mode1Res1 = inl(PCI_MODE1_ADDRESS_REG);      outl(PCI_MODE1_ADDRESS_REG, oldVal1);      if (mode1Res1 == PCI_EN) {	if (xf86Verbose > 1) {	    ErrorF("PCI: Config type is 1\n");	}	pciConfigType = 1;	pciMaxDevice = PCI_CONFIG1_MAXDEV;	return;      }      break; /* } */    case PCIForceConfig1:      if (xf86Verbose > 1) {	ErrorF("PCI: Forcing config type 1\n");      }      pciConfigType = 1;      pciMaxDevice = PCI_CONFIG1_MAXDEV;      return;    case PCIForceConfig2:      if (xf86Verbose > 1) {	ErrorF("PCI: Forcing config type 2\n");      }      pciConfigType = 2;      pciMaxDevice = PCI_CONFIG2_MAXDEV;      return;    }	#else /* !__alpha__ */    pciConfigType = 1;    pciMaxDevice = PCI_CONFIG1_MAXDEV;    if (pcibusCheck()) {      if (xf86Verbose > 1) {	ErrorF("PCI: Config type is 1(axp)\n");      }      return;    }    pciConfigType = 0;    pciMaxDevice = 0;#endif /* !__alpha__ */    /* No PCI found */    pciConfigType = 0;    pciMaxDevice = 0;    if (xf86Verbose > 1) {	ErrorF("PCI: No PCI bus found\n");    }}pciTagRecpcibusTag(CARD8 bus, CARD8 cardnum, CARD8 func){    pciTagRec tag;    tag.cfg1 = 0;    if (func > 7)	return tag;    switch (pciConfigType) {    case 1:	if (cardnum < PCI_CONFIG1_MAXDEV) {	    tag.cfg1 = #if !defined(__alpha__)			PCI_EN |#endif	      		((CARD32)bus << 16) |			((CARD32)cardnum << 11) |

⌨️ 快捷键说明

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