diff options
Diffstat (limited to 'hw/xfree86/os-support/bus/ix86Pci.c')
-rw-r--r-- | hw/xfree86/os-support/bus/ix86Pci.c | 468 |
1 files changed, 118 insertions, 350 deletions
diff --git a/hw/xfree86/os-support/bus/ix86Pci.c b/hw/xfree86/os-support/bus/ix86Pci.c index e54246355..80bac32bc 100644 --- a/hw/xfree86/os-support/bus/ix86Pci.c +++ b/hw/xfree86/os-support/bus/ix86Pci.c @@ -277,8 +277,8 @@ ix86PciBusCheck(void) return FALSE; } -static -void ix86PciSelectCfgmech(void) +static void +ix86PciSelectCfgmech(void) { static Bool beenhere = FALSE; CARD32 mode1Res1 = 0, mode1Res2 = 0, oldVal1 = 0; @@ -290,429 +290,197 @@ void ix86PciSelectCfgmech(void) beenhere = TRUE; - /* - * Determine if motherboard chipset supports PCI Config Mech 1 or 2 - * We rely on xf86Info.pciFlags to tell which mechanisms to try.... - */ - switch (xf86Info.pciFlags) { - case PCIOsConfig: - case PCIProbe1: - if (!xf86EnableIO()) - return; + /* Determine if motherboard chipset supports PCI Config Mech 1 or 2 */ + do { + if (!xf86EnableIO()) + return; - xf86MsgVerb(X_INFO, 2, - "PCI: Probing config type using method 1\n"); - oldVal1 = inl(PCI_CFGMECH1_ADDRESS_REG); + xf86MsgVerb(X_INFO, 2, + "PCI: Probing config type using method 1\n"); + oldVal1 = inl(PCI_CFGMECH1_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"); - } + 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) { + /* Assuming config type 1 to start with */ + if ((oldVal1 & 0x7f000000) == 0) { - stages |= 0x01; + 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 (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"); + ErrorF("\tWriting 8-bit value 0x00 to MODE1_ADDR_REG + 3\n"); #endif - } + } #endif - ix86Pci0.configMech = PCI_CFG_MECH_1; - ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV; - ix86Pci0.funcs = &ix86Funcs1; + ix86Pci0.configMech = PCI_CFG_MECH_1; + ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV; + ix86Pci0.funcs = &ix86Funcs1; - outl(PCI_CFGMECH1_ADDRESS_REG, PCI_EN); + outl(PCI_CFGMECH1_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_CFGMECH1_ADDRESS_REG + 3, 0); + /* + * This seems to cause some Neptune-based PCI machines to switch + * from config type 1 to config type 2 + */ + outb(PCI_CFGMECH1_ADDRESS_REG + 3, 0); #endif - mode1Res1 = inl(PCI_CFGMECH1_ADDRESS_REG); + mode1Res1 = inl(PCI_CFGMECH1_ADDRESS_REG); #ifdef DEBUGPCI - if (xf86Verbose > 2) { - ErrorF("\tValue read back from MODE1_ADDR_REG is 0x%08x\n", + 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"); - } + ErrorF("\tRestoring original contents of MODE1_ADDR_REG\n"); + } #endif - outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1); + outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1); - if (mode1Res1) { + if (mode1Res1) { - stages |= 0x02; + stages |= 0x02; #ifdef DEBUGPCI - if (xf86Verbose > 2) { - ErrorF("\tValue read back is non-zero, and indicates possible" - " config type 1\n"); - } + if (xf86Verbose > 2) { + ErrorF("\tValue read back is non-zero, and indicates possible" + " config type 1\n"); + } #endif - if (ix86PciBusCheck()) { + if (ix86PciBusCheck()) { #ifdef DEBUGPCI - if (xf86Verbose > 2) - ErrorF("\tBus check Confirms this: "); + if (xf86Verbose > 2) + ErrorF("\tBus check Confirms this: "); #endif - xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n"); - xf86MsgVerb(X_INFO, 3, - "PCI: stages = 0x%02x, oldVal1 = 0x%08lx, mode1Res1" - " = 0x%08lx\n", stages, (unsigned long)oldVal1, - (unsigned long)mode1Res1); - return; - } + xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n"); + xf86MsgVerb(X_INFO, 3, + "PCI: stages = 0x%02x, oldVal1 = 0x%08lx, mode1Res1" + " = 0x%08lx\n", stages, (unsigned long)oldVal1, + (unsigned long)mode1Res1); + return; + } #ifdef DEBUGPCI - if (xf86Verbose > 2) { - ErrorF("\tBus check fails to confirm this, continuing type 1" - " check ...\n"); - } + if (xf86Verbose > 2) { + ErrorF("\tBus check fails to confirm this, continuing type 1" + " check ...\n"); + } #endif - } + } - stages |= 0x04; + stages |= 0x04; #ifdef DEBUGPCI - if (xf86Verbose > 2) { - ErrorF("\tWriting 0xff000001 to MODE1_ADDR_REG\n"); - } + if (xf86Verbose > 2) { + ErrorF("\tWriting 0xff000001 to MODE1_ADDR_REG\n"); + } #endif - outl(PCI_CFGMECH1_ADDRESS_REG, 0xff000001); - mode1Res2 = inl(PCI_CFGMECH1_ADDRESS_REG); + outl(PCI_CFGMECH1_ADDRESS_REG, 0xff000001); + mode1Res2 = inl(PCI_CFGMECH1_ADDRESS_REG); #ifdef DEBUGPCI - if (xf86Verbose > 2) { - ErrorF("\tValue read back from MODE1_ADDR_REG is 0x%08x\n", + 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"); - } + ErrorF("\tRestoring original contents of MODE1_ADDR_REG\n"); + } #endif - outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1); + outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1); - if ((mode1Res2 & 0x80000001) == 0x80000000) { + if ((mode1Res2 & 0x80000001) == 0x80000000) { - stages |= 0x08; + stages |= 0x08; #ifdef DEBUGPCI - if (xf86Verbose > 2) { - ErrorF("\tValue read back has only the msb set\n" - "\tThis indicates possible config type 1\n"); - } + if (xf86Verbose > 2) { + ErrorF("\tValue read back has only the msb set\n" + "\tThis indicates possible config type 1\n"); + } #endif - if (ix86PciBusCheck()) { + if (ix86PciBusCheck()) { #ifdef DEBUGPCI - if (xf86Verbose > 2) - ErrorF("\tBus check Confirms this: "); + if (xf86Verbose > 2) + ErrorF("\tBus check Confirms this: "); #endif - xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n"); - xf86MsgVerb(X_INFO, 3, - "PCI: stages = 0x%02x, oldVal1 = 0x%08lx,\n" - "\tmode1Res1 = 0x%08lx, mode1Res2 = 0x%08lx\n", - stages, (unsigned long)oldVal1, - (unsigned long)mode1Res1, (unsigned long)mode1Res2); - return; - } + xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n"); + xf86MsgVerb(X_INFO, 3, + "PCI: stages = 0x%02x, oldVal1 = 0x%08lx,\n" + "\tmode1Res1 = 0x%08lx, mode1Res2 = 0x%08lx\n", + stages, (unsigned long)oldVal1, + (unsigned long)mode1Res1, (unsigned long)mode1Res2); + return; + } #ifdef DEBUGPCI - if (xf86Verbose > 2) { - ErrorF("\tBus check fails to confirm this.\n"); - } + if (xf86Verbose > 2) { + ErrorF("\tBus check fails to confirm this.\n"); + } #endif - } - } - - xf86MsgVerb(X_INFO, 3, "PCI: Standard check for type 1 failed.\n"); - xf86MsgVerb(X_INFO, 3, "PCI: stages = 0x%02x, oldVal1 = 0x%08lx,\n" - "\tmode1Res1 = 0x%08lx, mode1Res2 = 0x%08lx\n", - stages, (unsigned long)oldVal1, (unsigned long)mode1Res1, - (unsigned long)mode1Res2); - - /* Try config type 2 */ - oldVal2 = inb(PCI_CFGMECH2_ENABLE_REG); - if ((oldVal2 & 0xf0) == 0) { - ix86Pci0.configMech = PCI_CFG_MECH_2; - ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV; - ix86Pci0.funcs = &ix86Funcs2; - - outb(PCI_CFGMECH2_ENABLE_REG, 0x0e); - mode2Res1 = inb(PCI_CFGMECH2_ENABLE_REG); - outb(PCI_CFGMECH2_ENABLE_REG, oldVal2); - - if (mode2Res1 == 0x0e) { - if (ix86PciBusCheck()) { - xf86MsgVerb(X_INFO, 2, "PCI: Config type is 2\n"); - return; } } - } - break; /* } */ - - case PCIProbe2: /* { */ - if (!xf86EnableIO()) - return; - - /* The scanpci-style detection method */ - - xf86MsgVerb(X_INFO, 2, "PCI: Probing config type using method 2\n"); - - outb(PCI_CFGMECH2_ENABLE_REG, 0x00); - outb(PCI_CFGMECH2_FORWARD_REG, 0x00); - mode2Res1 = inb(PCI_CFGMECH2_ENABLE_REG); - mode2Res2 = inb(PCI_CFGMECH2_FORWARD_REG); - - if (mode2Res1 == 0 && mode2Res2 == 0) { - xf86MsgVerb(X_INFO, 2, "PCI: Config type is 2\n"); - ix86Pci0.configMech = PCI_CFG_MECH_2; - ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV; - ix86Pci0.funcs = &ix86Funcs2; - return; - } - - oldVal1 = inl(PCI_CFGMECH1_ADDRESS_REG); - outl(PCI_CFGMECH1_ADDRESS_REG, PCI_EN); - mode1Res1 = inl(PCI_CFGMECH1_ADDRESS_REG); - outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1); - if (mode1Res1 == PCI_EN) { - xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n"); - ix86Pci0.configMech = PCI_CFG_MECH_1; - ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV; - ix86Pci0.funcs = &ix86Funcs1; - return; - } - break; /* } */ - - case PCIForceConfig1: - if (!xf86EnableIO()) - return; - xf86MsgVerb(X_INFO, 2, "PCI: Forcing config type 1\n"); - - ix86Pci0.configMech = PCI_CFG_MECH_1; - ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV; - ix86Pci0.funcs = &ix86Funcs1; - return; - - case PCIForceConfig2: - if (!xf86EnableIO()) - return; - - xf86MsgVerb(X_INFO, 2, "PCI: Forcing config type 2\n"); - - ix86Pci0.configMech = PCI_CFG_MECH_2; - ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV; - ix86Pci0.funcs = &ix86Funcs2; - return; - - case PCIForceNone: + xf86MsgVerb(X_INFO, 3, "PCI: Standard check for type 1 failed.\n"); + xf86MsgVerb(X_INFO, 3, "PCI: stages = 0x%02x, oldVal1 = 0x%08lx,\n" + "\tmode1Res1 = 0x%08lx, mode1Res2 = 0x%08lx\n", + stages, (unsigned long)oldVal1, (unsigned long)mode1Res1, + (unsigned long)mode1Res2); + + /* Try config type 2 */ + oldVal2 = inb(PCI_CFGMECH2_ENABLE_REG); + if ((oldVal2 & 0xf0) == 0) { + ix86Pci0.configMech = PCI_CFG_MECH_2; + ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV; + ix86Pci0.funcs = &ix86Funcs2; + + outb(PCI_CFGMECH2_ENABLE_REG, 0x0e); + mode2Res1 = inb(PCI_CFGMECH2_ENABLE_REG); + outb(PCI_CFGMECH2_ENABLE_REG, oldVal2); + + if (mode2Res1 == 0x0e) { + if (ix86PciBusCheck()) { + xf86MsgVerb(X_INFO, 2, "PCI: Config type is 2\n"); + return; + } + } + } break; - } + } while (0); /* No PCI found */ ix86Pci0.configMech = PCI_CFG_MECH_UNKNOWN; - xf86MsgVerb(X_INFO, 2, "PCI: No PCI bus found or probed for\n"); -} - -#if 0 -static pciTagRec -ix86PcibusTag(CARD8 bus, CARD8 cardnum, CARD8 func) -{ - pciTagRec tag; - - tag.cfg1 = 0; - - if (func > 7 || cardnum >= pciBusInfo[bus]->numDevices) - return tag; - - switch (ix86Pci0.configMech) { - case PCI_CFG_MECH_1: - tag.cfg1 = PCI_EN | ((CARD32)bus << 16) | - ((CARD32)cardnum << 11) | - ((CARD32)func << 8); - break; - - case PCI_CFG_MECH_2: - tag.cfg2.port = 0xc000 | ((CARD16)cardnum << 8); - tag.cfg2.enable = 0xf0 | (func << 1); - tag.cfg2.forward = bus; - break; - } - - return tag; + xf86MsgVerb(X_INFO, 2, "PCI: No PCI bus found\n"); } -#endif - -#if 0 -static CARD32 -ix86PciReadLongSetup(PCITAG Tag, int reg) -{ - ix86PciSelectCfgmech(); - return (*ix86Pci0.funcs->pciReadLong)(Tag,reg); -} - -static CARD32 -ix86PciReadLongCFG1(PCITAG Tag, int reg) -{ - CARD32 addr, data = 0; - -#ifdef DEBUGPCI - ErrorF("ix86PciReadLong 0x%lx, %d\n", Tag, reg); -#endif - - addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg); - outl(PCI_CFGMECH1_ADDRESS_REG, addr); - data = inl(PCI_CFGMECH1_DATA_REG); - outl(PCI_CFGMECH1_ADDRESS_REG, 0); - -#ifdef DEBUGPCI - ErrorF("ix86PciReadLong 0x%lx\n", data); -#endif - - return data; -} - -static CARD32 -ix86PciReadLongCFG2(PCITAG Tag, int reg) -{ - CARD32 addr, data = 0; - CARD8 forward, enable; - -#ifdef DEBUGPCI - ErrorF("ix86PciReadLong 0x%lx, %d\n", Tag, reg); -#endif - - forward = PCI_FORWARD_FROM_TAG(Tag); - enable = PCI_ENABLE_FROM_TAG(Tag); - addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg); - - outb(PCI_CFGMECH2_ENABLE_REG, enable); - outb(PCI_CFGMECH2_FORWARD_REG, forward); - data = inl((CARD16)addr); - outb(PCI_CFGMECH2_ENABLE_REG, 0); - outb(PCI_CFGMECH2_FORWARD_REG, 0); - -#ifdef DEBUGPCI - ErrorF("ix86PciReadLong 0x%lx\n", data); -#endif - - return data; -} - -static void -ix86PciWriteLongSetup(PCITAG Tag, int reg, CARD32 data) -{ - ix86PciSelectCfgmech(); - (*ix86Pci0.funcs->pciWriteLong)(Tag,reg,data); -} - -static void -ix86PciWriteLongCFG1(PCITAG Tag, int reg, CARD32 data) -{ - CARD32 addr; - - addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg); - outl(PCI_CFGMECH1_ADDRESS_REG, addr); - outl(PCI_CFGMECH1_DATA_REG, data); - outl(PCI_CFGMECH1_ADDRESS_REG, 0); -} - -static void -ix86PciWriteLongCFG2(PCITAG Tag, int reg, CARD32 data) -{ - CARD32 addr; - CARD8 forward, enable; - - forward = PCI_FORWARD_FROM_TAG(Tag); - enable = PCI_ENABLE_FROM_TAG(Tag); - addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg); - - outb(PCI_CFGMECH2_ENABLE_REG, enable); - outb(PCI_CFGMECH2_FORWARD_REG, forward); - outl((CARD16)addr, data); - outb(PCI_CFGMECH2_ENABLE_REG, 0); - outb(PCI_CFGMECH2_FORWARD_REG, 0); -} - -static void -ix86PciSetBitsLongSetup(PCITAG Tag, int reg, CARD32 mask, CARD32 val) -{ - ix86PciSelectCfgmech(); - (*ix86Pci0.funcs->pciSetBitsLong)(Tag,reg,mask,val); -} - -static void -ix86PciSetBitsLongCFG1(PCITAG Tag, int reg, CARD32 mask, CARD32 val) -{ - CARD32 addr, data = 0; - -#ifdef DEBUGPCI - ErrorF("ix86PciSetBitsLong 0x%lx, %d\n", Tag, reg); -#endif - - addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg); - outl(PCI_CFGMECH1_ADDRESS_REG, addr); - data = inl(PCI_CFGMECH1_DATA_REG); - data = (data & ~mask) | (val & mask); - outl(PCI_CFGMECH1_DATA_REG, data); - outl(PCI_CFGMECH1_ADDRESS_REG, 0); -} - -static void -ix86PciSetBitsLongCFG2(PCITAG Tag, int reg, CARD32 mask, CARD32 val) -{ - CARD32 addr, data = 0; - CARD8 enable, forward; - -#ifdef DEBUGPCI - ErrorF("ix86PciSetBitsLong 0x%lx, %d\n", Tag, reg); -#endif - - forward = PCI_FORWARD_FROM_TAG(Tag); - enable = PCI_ENABLE_FROM_TAG(Tag); - addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg); - - outb(PCI_CFGMECH2_ENABLE_REG, enable); - outb(PCI_CFGMECH2_FORWARD_REG, forward); - data = inl((CARD16)addr); - data = (data & ~mask) | (val & mask); - outl((CARD16)addr, data); - outb(PCI_CFGMECH2_ENABLE_REG, 0); - outb(PCI_CFGMECH2_FORWARD_REG, 0); -} -#endif void ix86PciInit() { - /* Initialize pciBusInfo[] array and function pointers */ + /* Initialize pciBusInfo */ pciNumBuses = 1; - pciBusInfo[0] = &ix86Pci0; + pciBusInfo = &ix86Pci0; /* Make sure that there is a PCI bus present. */ ix86PciSelectCfgmech(); if (ix86Pci0.configMech == PCI_CFG_MECH_UNKNOWN) { pciNumBuses = 0; - pciBusInfo[0] = NULL; + pciBusInfo = NULL; } } |