📄 atiprobe.c
字号:
{ outb(VGA_DAC_MASK, 0xA5U); if (inb(IBM_DAC_MASK) == 0xA5U) pATI->VGAAdapter = ATI_ADAPTER_VGA; outb(VGA_DAC_MASK, OldDACMask); } if (ClockSel & DISABPASSTHRU) outw(CLOCK_SEL, ClockSel); } break; case ATI_ADAPTER_MACH32: { CARD16 ClockSel = inw(CLOCK_SEL), MiscOptions = inw(MISC_OPTIONS); if (ClockSel & DISABPASSTHRU) outw(CLOCK_SEL, ClockSel & ~DISABPASSTHRU); if (MiscOptions & (DISABLE_VGA | DISABLE_DAC)) outw(MISC_OPTIONS, MiscOptions & ~(DISABLE_VGA | DISABLE_DAC)); ProbeWaitIdleEmpty(); OldDACMask = inb(VGA_DAC_MASK); if (inb(IBM_DAC_MASK) == OldDACMask) { outb(VGA_DAC_MASK, 0xA5U); if (inb(IBM_DAC_MASK) == 0xA5U) pATI->VGAAdapter = ATI_ADAPTER_MACH32; outb(VGA_DAC_MASK, OldDACMask); } if (ClockSel & DISABPASSTHRU) outw(CLOCK_SEL, ClockSel); if (MiscOptions & (DISABLE_VGA | DISABLE_DAC)) outw(MISC_OPTIONS, MiscOptions); } break; case ATI_ADAPTER_MACH64: { CARD32 DACCntl = inr(DAC_CNTL); if (!(DACCntl & DAC_VGA_ADR_EN)) outr(DAC_CNTL, DACCntl | DAC_VGA_ADR_EN); OldDACMask = inb(VGA_DAC_MASK); if (in8(M64_DAC_MASK) == OldDACMask) { outb(VGA_DAC_MASK, 0xA5U); if (in8(M64_DAC_MASK) == 0xA5U) pATI->VGAAdapter = ATI_ADAPTER_MACH64; outb(VGA_DAC_MASK, OldDACMask); } if (!(DACCntl & DAC_VGA_ADR_EN)) outr(DAC_CNTL, DACCntl); } break; default: break; } if (pATI->VGAAdapter == ATI_ADAPTER_NONE) { pATI->CPIO_VGAWonder = 0; return; } if (pATI->CPIO_VGAWonder) { ATIVGAWonderProbe(pVideo, pATI, p8514, ProbeFlags); if (!pATI->CPIO_VGAWonder) { /* * Some adapters are reputed to append ATI extended VGA registers * to the VGA Graphics controller registers. In particular, 0x01CE * cannot, in general, be used in a PCI environment due to routing * of I/O through the bus tree. */ pATI->CPIO_VGAWonder = GRAX; ATIVGAWonderProbe(pVideo, pATI, p8514, ProbeFlags); } } if (pATI == pVGA) { pATI->SharedVGA = TRUE; return; } /* Assign the VGA to this adapter */ xfree(pVGA); *ppVGA = pATI; xf86MsgVerb(X_INFO, 3, ATI_NAME ": VGA assigned to this adapter.\n");}#ifndef AVOID_NON_PCI/* * ATIClaimVGA -- * * Attempt to assign a non-shareable VGA to an accelerator. If successful, * update ProbeFlags array. */static voidATIClaimVGA( pciVideoPtr pVideo, ATIPtr *ppVGA, ATIPtr pATI, ATIPtr p8514, CARD8 *ProbeFlags, int Detected){ ATIAssignVGA(pVideo, ppVGA, pATI, p8514, ProbeFlags); if (pATI->VGAAdapter == ATI_ADAPTER_NONE) return; ATIClaimSparseIOBases(ProbeFlags, MonochromeIOBase, 48, Detected); if (!pATI->CPIO_VGAWonder) return; ATIClaimSparseIOBases(ProbeFlags, pATI->CPIO_VGAWonder, 2, Detected);}#endif /* AVOID_NON_PCI *//* * ATIFindVGA -- * * This function determines if a VGA associated with an ATI PCI adapter is * shareable. */static voidATIFindVGA( pciVideoPtr pVideo, ATIPtr *ppVGA, ATIPtr *ppATI, ATIPtr p8514, CARD8 *ProbeFlags){ ATIPtr pATI = *ppATI; if (!*ppVGA) { /* * An ATI PCI adapter has been detected at this point, and its VGA, if * any, is shareable. Ensure the VGA isn't in sleep mode. */ outb(GENENA, 0x16U); outb(GENVS, 0x01U); outb(GENENA, 0x0EU); pATI = ATIVGAProbe(pATI); if (pATI->VGAAdapter == ATI_ADAPTER_NONE) return; ppVGA = ppATI; } ATIAssignVGA(pVideo, ppVGA, pATI, p8514, ProbeFlags);}#endif /* AVOID_CPIO *//* * ATIProbe -- * * This function is called once, at the start of the first server generation to * do a minimal probe for supported hardware. */BoolATIProbe( DriverPtr pDriver, int flags){ ATIPtr pATI, *ATIPtrs = NULL; GDevPtr *GDevs, pGDev; pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo(); ATIGDev *ATIGDevs = NULL, *pATIGDev; ScrnInfoPtr pScreenInfo; Bool ProbeSuccess = FALSE; Bool DoRage128 = FALSE, DoRadeon = FALSE; int i, j, k; int nGDev, nATIGDev = -1, nATIPtr = 0; int Chipset; ATIChipType Chip;#if !defined(AVOID_NON_PCI) || !defined(AVOID_CPIO) pciConfigPtr pPCI; CARD32 PciReg;#endif /* AVOID_NON_PCI || AVOID_CPIO */#ifndef AVOID_NON_PCI ATIPtr pMach64[3] = {NULL, NULL, NULL};#endif#ifndef AVOID_CPIO ATIPtr pVGA = NULL, p8514 = NULL; pciConfigPtr *xf86PciInfo = xf86GetPciConfigInfo(); PortPtr PCIPorts = NULL; int nPCIPort = 0; CARD8 fChipsets[ATI_CHIPSET_MAX]; static const IOADDRESS Mach64SparseIOBases[] = {0x02ECU, 0x01CCU, 0x01C8U}; CARD8 ProbeFlags[LongPort(SPARSE_IO_BASE) + 1]; unsigned long BIOSBase; static const CARD8 ATISignature[] = " 761295520";# define SignatureSize 10# define PrefixSize 0x50U# define BIOSSignature 0x30U CARD8 BIOS[PrefixSize];# define BIOSWord(_n) (BIOS[_n] | (BIOS[(_n) + 1] << 8))#endif /* AVOID_CPIO */# define AddAdapter(_p) \ do \ { \ nATIPtr++; \ ATIPtrs = (ATIPtr *)xnfrealloc(ATIPtrs, SizeOf(ATIPtr) * nATIPtr); \ ATIPtrs[nATIPtr - 1] = (_p); \ (_p)->iEntity = -2; \ } while (0)#ifndef AVOID_CPIO (void)memset(fChipsets, FALSE, SizeOf(fChipsets));#endif /* AVOID_CPIO */ if (!(flags & PROBE_DETECT)) { /* * Get a list of XF86Config device sections whose "Driver" is either * not specified, or specified as this driver. From this list, * eliminate those device sections that specify a "Chipset" or a * "ChipID" not recognised by the driver. Those device sections that * specify a "ChipRev" without a "ChipID" are also weeded out. */ nATIGDev = 0; if ((nGDev = xf86MatchDevice(ATI_NAME, &GDevs)) > 0) { ATIGDevs = (ATIGDevPtr)xnfcalloc(nGDev, SizeOf(ATIGDev)); for (i = 0, pATIGDev = ATIGDevs; i < nGDev; i++) { pGDev = GDevs[i]; Chipset = ATIIdentProbe(pGDev->chipset); if (Chipset == -1) continue; if ((pGDev->chipID > (int)((CARD16)(-1))) || (pGDev->chipRev > (int)((CARD8)(-1)))) continue; if (pGDev->chipID >= 0) { if (ATIChipID(pGDev->chipID, 0) == ATI_CHIP_Mach64) continue; } else { if (pGDev->chipRev >= 0) continue; } pATIGDev->pGDev = pGDev; pATIGDev->Chipset = Chipset; nATIGDev++; pATIGDev++; xf86MsgVerb(X_INFO, 3, ATI_NAME ": Candidate \"Device\" section \"%s\".\n", pGDev->identifier);#ifndef AVOID_CPIO fChipsets[Chipset] = TRUE;#endif /* AVOID_CPIO */ } xfree(GDevs); if (!nATIGDev) { xfree(ATIGDevs); ATIGDevs = NULL; } } if (xf86MatchDevice(R128_NAME, NULL) > 0) DoRage128 = TRUE; if (xf86MatchDevice(RADEON_NAME, NULL) > 0) DoRadeon = TRUE; }#ifndef AVOID_CPIO /* * Collect hardware information. This must be done with care to avoid * lockups due to overlapping I/O port assignments. * * First, scan PCI configuration space for registered I/O ports (which will * be block I/O bases). Each such port is used to generate a list of * sparse I/O bases it precludes. This list is then used to decide whether * or not certain sparse I/O probes are done. Unfortunately, this assumes * that any registered I/O base actually reserves upto the full 256 ports * allowed by the PCI specification. This assumption holds true for PCI * Mach64, but probably doesn't for other device types. For some things, * such as video devices, the number of ports a base represents is * determined by the server's PCI probe, but, for other devices, this * cannot be done by a user-level process without jeopardizing system * integrity. This information should ideally be retrieved from the OS's * own PCI probe (if any), but there's currently no portable way of doing * so. The following allows sparse I/O probes to be forced in certain * circumstances when an appropriate chipset specification is used in any * XF86Config Device section. * * Note that this is not bullet-proof. Lockups can still occur, but they * will usually be due to devices that are misconfigured to respond to the * same I/O ports as 8514/A's or ATI sparse I/O devices without registering * them in PCI configuration space. */ if (nATIGDev) { if (xf86PciVideoInfo) { for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) { if ((pVideo->vendor == PCI_VENDOR_ATI) || !(pPCI = pVideo->thisCard)) continue; ATIScanPCIBases(&PCIPorts, &nPCIPort, &pPCI->pci_base0, pVideo->size, (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & PCI_CMD_IO_ENABLE) ? 0 : Allowed); } } /* Check non-video PCI devices for I/O bases */ if (xf86PciInfo) { for (i = 0; (pPCI = xf86PciInfo[i++]); ) { if ((pPCI->pci_vendor == PCI_VENDOR_ATI) || (pPCI->pci_base_class == PCI_CLASS_BRIDGE) || (pPCI->pci_header_type & ~GetByte(PCI_HEADER_MULTIFUNCTION, 2))) continue; ATIScanPCIBases(&PCIPorts, &nPCIPort, &pPCI->pci_base0, pPCI->basesize, (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & PCI_CMD_IO_ENABLE) ? 0 : Allowed); } } /* Generate ProbeFlags array from list of registered PCI I/O bases */ (void)memset(ProbeFlags, Allowed | DoProbe, SizeOf(ProbeFlags)); for (i = 0; i < nPCIPort; i++) { CARD32 Base = PCIPorts[i].Base; CARD16 Count = (1 << PCIPorts[i].Size) - 1; CARD8 ProbeFlag = PCIPorts[i].Flag; /* * The following reduction of Count is based on the assumption that * PCI-registered I/O port ranges do not overlap. */ for (j = 0; j < nPCIPort; j++) { CARD32 Base2 = PCIPorts[j].Base; if (Base < Base2) while ((Base + Count) >= Base2) Count >>= 1; } Base = LongPort(Base); Count = LongPort((Count | IO_BYTE_SELECT) + 1); while (Count--) ProbeFlags[Base++] &= ProbeFlag; } xfree(PCIPorts);#ifndef AVOID_NON_PCI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -