resPtr xf86PciBusAccWindowsFromOS(void) { pciConfigPtr *ppPCI, pPCI; resPtr pRes = NULL; resRange range; unsigned long io_size, mem_size; int domain; if ((ppPCI = xf86scanpci(0))) { for (; (pPCI = *ppPCI); ppPCI++) { if ((pPCI->pci_base_class != PCI_CLASS_BRIDGE) || (pPCI->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST)) continue; domain = xf86GetPciDomain(pPCI->tag); linuxGetSizes(pPCI->tag, &io_size, &mem_size); RANGE(range, 0, (ADDRESS)(mem_size - 1), RANGE_TYPE(ResExcMemBlock, domain)); pRes = xf86AddResToList(pRes, &range, -1); RANGE(range, 0, (IOADDRESS)(io_size - 1), RANGE_TYPE(ResExcIoBlock, domain)); pRes = xf86AddResToList(pRes, &range, -1); if (domain <= 0) break; } } return pRes; }
resPtr xf86AccResFromOS(resPtr pRes) { pciConfigPtr *ppPCI, pPCI; resRange range; unsigned long io_size, mem_size; int domain; if ((ppPCI = xf86scanpci(0))) { for (; (pPCI = *ppPCI); ppPCI++) { if ((pPCI->pci_base_class != PCI_CLASS_BRIDGE) || (pPCI->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST)) continue; domain = xf86GetPciDomain(pPCI->tag); linuxGetSizes(pPCI->tag, &io_size, &mem_size); /* * At minimum, the top and bottom resources must be claimed, so * that resources that are (or appear to be) unallocated can be * relocated. */ RANGE(range, 0x00000000u, 0x0009ffffu, RANGE_TYPE(ResExcMemBlock, domain)); pRes = xf86AddResToList(pRes, &range, -1); RANGE(range, 0x000c0000u, 0x000effffu, RANGE_TYPE(ResExcMemBlock, domain)); pRes = xf86AddResToList(pRes, &range, -1); RANGE(range, 0x000f0000u, 0x000fffffu, RANGE_TYPE(ResExcMemBlock, domain)); pRes = xf86AddResToList(pRes, &range, -1); RANGE(range, (ADDRESS)(mem_size - 1), (ADDRESS)(mem_size - 1), RANGE_TYPE(ResExcMemBlock, domain)); pRes = xf86AddResToList(pRes, &range, -1); RANGE(range, 0x00000000u, 0x00000000u, RANGE_TYPE(ResExcIoBlock, domain)); pRes = xf86AddResToList(pRes, &range, -1); RANGE(range, (IOADDRESS)(io_size - 1), (IOADDRESS)(io_size - 1), RANGE_TYPE(ResExcIoBlock, domain)); pRes = xf86AddResToList(pRes, &range, -1); if (domain <= 0) break; } } return pRes; }
int xf86platformProbe(void) { int i; Bool pci = TRUE; config_odev_probe(xf86PlatformDeviceProbe); if (!xf86scanpci()) { pci = FALSE; } for (i = 0; i < xf86_num_platform_devices; i++) { char *busid = xf86_get_platform_attrib(i, ODEV_ATTRIB_BUSID); if (pci && (strncmp(busid, "pci:", 4) == 0)) { platform_find_pci_info(&xf86_platform_devices[i], busid); } } return 0; }
void xf86PciProbe(void) { int i = 0, k; int num = 0; struct pci_device *info; struct pci_device_iterator *iter; struct pci_device **xf86PciVideoInfo = NULL; if (!xf86scanpci()) { xf86PciVideoInfo = NULL; return; } iter = pci_slot_match_iterator_create(&xf86IsolateDevice); while ((info = pci_device_next(iter)) != NULL) { if (PCIINFOCLASSES(info->device_class)) { num++; xf86PciVideoInfo = xnfreallocarray(xf86PciVideoInfo, num + 1, sizeof(struct pci_device *)); xf86PciVideoInfo[num] = NULL; xf86PciVideoInfo[num - 1] = info; pci_device_probe(info); if (primaryBus.type == BUS_NONE && pci_device_is_boot_vga(info)) { primaryBus.type = BUS_PCI; primaryBus.id.pci = info; } info->user_data = 0; } } free(iter); /* If we haven't found a primary device try a different heuristic */ if (primaryBus.type == BUS_NONE && num) { for (i = 0; i < num; i++) { uint16_t command; info = xf86PciVideoInfo[i]; pci_device_cfg_read_u16(info, &command, 4); if ((command & PCI_CMD_MEM_ENABLE) && ((num == 1) || IS_VGA(info->device_class))) { if (primaryBus.type == BUS_NONE) { primaryBus.type = BUS_PCI; primaryBus.id.pci = info; } else { xf86Msg(X_NOTICE, "More than one possible primary device found\n"); primaryBus.type ^= (BusType) (-1); } } } } /* Print a summary of the video devices found */ for (k = 0; k < num; k++) { const char *prim = " "; Bool memdone = FALSE, iodone = FALSE; info = xf86PciVideoInfo[k]; if (!PCIALWAYSPRINTCLASSES(info->device_class)) continue; if (xf86IsPrimaryPci(info)) prim = "*"; xf86Msg(X_PROBED, "PCI:%s(%u:%u:%u:%u) %04x:%04x:%04x:%04x ", prim, info->domain, info->bus, info->dev, info->func, info->vendor_id, info->device_id, info->subvendor_id, info->subdevice_id); xf86ErrorF("rev %d", info->revision); for (i = 0; i < 6; i++) { struct pci_mem_region *r = &info->regions[i]; if (r->size && !r->is_IO) { if (!memdone) { xf86ErrorF(", Mem @ "); memdone = TRUE; } else xf86ErrorF(", "); xf86ErrorF("0x%08lx/%ld", (long) r->base_addr, (long) r->size); } } for (i = 0; i < 6; i++) { struct pci_mem_region *r = &info->regions[i]; if (r->size && r->is_IO) { if (!iodone) { xf86ErrorF(", I/O @ "); iodone = TRUE; } else xf86ErrorF(", "); xf86ErrorF("0x%08lx/%ld", (long) r->base_addr, (long) r->size); } } if (info->rom_size) { xf86ErrorF(", BIOS @ 0x\?\?\?\?\?\?\?\?/%ld", (long) info->rom_size); } xf86ErrorF("\n"); } free(xf86PciVideoInfo); }
/* This does some 460GX-related processing after the PCI bus scan */ void xf86PostScan460GX(void) { pciConfigPtr pPCI, *ppPCI; pciBusInfo_t *pBusInfo; int i, j, devno; if (cbn_460gx <= 0) return; /* Set up our extra bus functions */ BusFuncs_460gx = *(pciBusInfo[0]->funcs); BusFuncs_460gx.pciControlBridge = Control460GXBridge; BusFuncs_460gx.pciGetBridgeBusses = Get460GXBridgeBusses; BusFuncs_460gx.pciGetBridgeResources = Get460GXBridgeResources; /* * Mark all host bridges so that they are ignored by the upper-level * xf86GetPciBridgeInfo() function. This marking is later clobbered by the * tail end of xf86scanpci() for those bridges that actually have bus * segments associated with them. */ ppPCI = xf86scanpci(0); /* Recursion is only apparent */ while ((pPCI = *ppPCI++)) { if ((pPCI->pci_base_class == PCI_CLASS_BRIDGE) && (pPCI->pci_sub_class == PCI_SUBCLASS_BRIDGE_HOST)) pPCI->businfo = HOST_NO_BUS; } ppPCI = xf86scanpci(0); /* Recursion is only apparent */ j = 0; /* * Fix up CBN bus linkage. This is somewhat arbitrary. The bridge chosen * for this must be a CBN device so that bus CBN can be recognised as the * root segment. It also cannot be any of the bus expanders (devices * CBN:0x10:0 through CBN:0x17:0 nor any of their functions). For now, we * chose the SAC host bridge at CBN:0:0. */ pBusInfo = pciBusInfo[cbn_460gx]; pBusInfo->bridge = pciBusInfo[0]->bridge; /* Just in case */ while ((pPCI = *ppPCI++)) { if (pPCI->busnum < cbn_460gx) continue; if (pPCI->busnum > cbn_460gx) break; if (pPCI->devnum < 0) continue; if (pPCI->devnum > 0) break; if (pPCI->funcnum < 0) continue; if (pPCI->funcnum > 0) break; pBusInfo->bridge = pPCI; pBusInfo->secondary = FALSE; pBusInfo->primary_bus = cbn_460gx; break; } for (i = 0, devno = 0x10; devno <= 0x17; i++, devno++) { /* Restore ERRCMD registers */ if (err_460gx[i] & 0x01) pciWriteByte(PCI_MAKE_TAG(cbn_460gx, devno, 1), ERRCMD, err_460gx[i]); if (!(cbdevs_460gx & (1 << devno))) { while ((pPCI = *ppPCI++)) { if (pPCI->busnum < cbn_460gx) continue; if (pPCI->busnum > cbn_460gx) break; if (pPCI->devnum < devno) continue; if (pPCI->devnum > devno) break; if (pPCI->funcnum < 0) continue; if (pPCI->funcnum > 0) break; if ((pBusInfo = pciBusInfo[busno_460gx[i]])) break; /* Fix bus linkage */ pBusInfo->bridge = pPCI; pBusInfo->secondary = TRUE; pBusInfo->primary_bus = cbn_460gx; /* Plug in chipset routines */ pBusInfo->funcs = &BusFuncs_460gx; break; } } /* Decode IOR registers */ for(; j <= (ior_460gx[i] & 0x0F); j++) iomap_460gx[j] = devno; } /* The bottom 4k of I/O space is always routed to PCI0a */ iomap_460gx[0] = 0x10; /* Decode IORD register */ for (j = 1; j <= 0x0F; j++) if (iord_460gx & (1 << j)) iomap_460gx[j] = 0x10; }
vgaPCIInformation * vgaGetPCIInfo() { vgaPCIInformation *info = NULL; pciConfigPtr pcrp, *pcrpp; Bool found = FALSE; int i = 0; CARD32 membase = 0, membase2 = 0, mmiobase = 0, iobase = 0; pcrpp = xf86scanpci(vga256InfoRec.scrnIndex); if (!pcrpp) return NULL; while (pcrp = pcrpp[i]) { #if !defined(PC98_TGUI) && !defined(PC98_MGA) if ((pcrp->_base_class == PCI_CLASS_PREHISTORIC && pcrp->_sub_class == PCI_SUBCLASS_PREHISTORIC_VGA) || (pcrp->_base_class == PCI_CLASS_DISPLAY && pcrp->_sub_class == PCI_SUBCLASS_DISPLAY_VGA && pcrp->_command & (PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE) == (PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE))) { #else /* PC98 */ #ifdef PC98_TGUI if (pcrp->_base_class == PCI_CLASS_DISPLAY && pcrp->_sub_class == PCI_SUBCLASS_DISPLAY_VGA && pcrp->_vendor == PCI_VENDOR_TRIDENT) { #endif #ifdef PC98_MGA if (pcrp->_base_class == PCI_CLASS_DISPLAY && pcrp->_sub_class == PCI_SUBCLASS_DISPLAY_MISC && pcrp->_vendor == PCI_VENDOR_MATROX) { #endif #endif /* PC98 */ found = TRUE; if ((info = (vgaPCIInformation *) xalloc(sizeof(vgaPCIInformation))) == NULL) return NULL; info->Vendor = pcrp->_vendor; info->ChipType = pcrp->_device; info->ChipRev = pcrp->_rev_id; info->Bus = pcrp->_bus; info->Card = pcrp->_cardnum; info->Func = pcrp->_func; info->AllCards = pcrpp; info->ThisCard = pcrp; info->MemBase = 0; info->MMIOBase = 0; info->IOBase = 0; /* If the alignment is finer than 256k, assume mmio */ if (pcrp->_base0) { if (pcrp->_base0 & 1) iobase = pcrp->_base0 & 0xFFFFFFFC; else if (pcrp->_base0 & 0x3FFF0) mmiobase = pcrp->_base0 & 0xFFFFFFF0; else membase = pcrp->_base0 & 0xFFFFFFF0; } if (pcrp->_base1) { if (pcrp->_base1 & 1) { if (!iobase) iobase = pcrp->_base1 & 0xFFFFFFFC; } else if (pcrp->_base1 & 0x3FFF0) { if (!mmiobase) mmiobase = pcrp->_base1 & 0xFFFFFFF0; } else { if (!membase) membase = pcrp->_base1 & 0xFFFFFFF0; else if (!membase2) membase2 = pcrp->_base1 & 0xFFFFFFF0; } } if (pcrp->_base2) { if (pcrp->_base2 & 1) { if (!iobase) iobase = pcrp->_base2 & 0xFFFFFFFC; } else if (pcrp->_base2 & 0x3FFF0) { if (!mmiobase) mmiobase = pcrp->_base2 & 0xFFFFFFF0; } else { if (!membase) membase = pcrp->_base2 & 0xFFFFFFF0; else if (!membase2) membase2 = pcrp->_base2 & 0xFFFFFFF0; } } if (pcrp->_base3) { if (pcrp->_base3 & 1) { if (!iobase) iobase = pcrp->_base3 & 0xFFFFFFFC; } else if (pcrp->_base3 & 0x3FFF0) { if (!mmiobase) mmiobase = pcrp->_base3 & 0xFFFFFFF0; } else { if (!membase) membase = pcrp->_base3 & 0xFFFFFFF0; else if (!membase2) membase2 = pcrp->_base3 & 0xFFFFFFF0; } } if (pcrp->_base4) { if (pcrp->_base4 & 1) { if (!iobase) iobase = pcrp->_base4 & 0xFFFFFFFC; } else if (pcrp->_base4 & 0x3FFF0) { if (!mmiobase) mmiobase = pcrp->_base4 & 0xFFFFFFF0; } else { if (!membase) membase = pcrp->_base4 & 0xFFFFFFF0; else if (!membase2) membase2 = pcrp->_base4 & 0xFFFFFFF0; } } if (pcrp->_base5) { if (pcrp->_base5 & 1) { if (!iobase) iobase = pcrp->_base5 & 0xFFFFFFFC; } else if (pcrp->_base5 & 0x3FFF0) { if (!mmiobase) mmiobase = pcrp->_base5 & 0xFFFFFFF0; } else { if (!membase) membase = pcrp->_base5 & 0xFFFFFFF0; else if (!membase2) membase2 = pcrp->_base5 & 0xFFFFFFF0; } } break; } i++; } if (found) { int i = 0, j; char *vendorname = NULL, *chipname = NULL; while (xf86PCIVendorInfo[i].VendorName) { if (xf86PCIVendorInfo[i].VendorID == info->Vendor) { j = 0; vendorname = xf86PCIVendorInfo[i].VendorName; while (xf86PCIVendorInfo[i].Device[j].DeviceName) { if (xf86PCIVendorInfo[i].Device[j].DeviceID == info->ChipType) { chipname = xf86PCIVendorInfo[i].Device[j].DeviceName; break; } j++; } break; } i++; } info->MemBase = membase; info->MMIOBase = mmiobase; info->IOBase = iobase; if (xf86Verbose) { ErrorF("%s %s: PCI: ", XCONFIG_PROBED, vga256InfoRec.name); if (vendorname) ErrorF("%s ", vendorname); else ErrorF("Unknown vendor (0x%04x) ", info->Vendor); if (chipname) ErrorF("%s ", chipname); else ErrorF("Unknown chipset (0x%04x) ", info->ChipType); ErrorF("rev %d", info->ChipRev); if (membase) ErrorF(", Memory @ 0x%08x", membase); if (membase2) ErrorF(", 0x%08x", membase2); if (mmiobase) ErrorF(", MMIO @ 0x%08x", mmiobase); if (iobase) ErrorF(", I/O @ 0x%04x", iobase); ErrorF("\n"); } } return info; }
int main(int argc, char *argv[]) { pciConfigPtr pPCI, *pcrpp = NULL; int Verbose = 0; int i = 0; int force = 0; int c; xf86Info.pciFlags = PCIProbe1; while ((c = getopt(argc, argv, "?v12OfV:")) != -1) switch(c) { case 'v': Verbose++; break; case '1': xf86Info.pciFlags = PCIProbe1; break; case '2': xf86Info.pciFlags = PCIProbe2; break; case 'O': xf86Info.pciFlags = PCIOsConfig; break; case 'f': force = 1; break; case 'V': xf86Verbose = atoi(optarg); break; case '?': default: usage(); exit (1); break; } if (force) switch (xf86Info.pciFlags) { case PCIProbe1: xf86Info.pciFlags = PCIForceConfig1; break; case PCIProbe2: xf86Info.pciFlags = PCIForceConfig2; break; default: break; } xf86EnableIO(); pcrpp = xf86scanpci(0); if (!pcrpp) { printf("No PCI devices found\n"); xf86DisableIO(); exit (1); } while ((pPCI = pcrpp[i++])) identify_card(pPCI, Verbose); if (Verbose > 1) { printf("\nPCI bus linkages:\n\n"); for (i = 0; i < MAX_PCI_BUSES; i++) { pciBusInfo_t *pBusInfo; if (!(pBusInfo = pciBusInfo[i])) continue; if ((pPCI = pBusInfo->bridge)) printf("PCI bus 0x%04x has parent bridge 0x%04x:0x%02x:0x%1x\n", i, pPCI->busnum, pPCI->devnum, pPCI->funcnum); else printf("PCI bus 0x%04x has no parent\n", i); } } xf86DisableIO(); exit(0); }