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 + -
显示快捷键?