void pchbattach(struct device *parent, struct device *self, void *aux) { struct pchb_softc *sc = (struct pchb_softc *)self; struct pci_attach_args *pa = aux; int has_agp = 0, i, r; switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_AMD: printf("\n"); switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_AMD_AMD64_0F_HT: case PCI_PRODUCT_AMD_AMD64_10_HT: case PCI_PRODUCT_AMD_AMD64_11_HT: for (i = 0; i < AMD64HT_NUM_LDT; i++) pchb_amd64ht_attach(self, pa, i); break; } break; case PCI_VENDOR_INTEL: switch (PCI_PRODUCT(pa->pa_id)) { /* * As for Intel AGP, the host bridge is either in GFX mode * (internal graphics) or in AGP mode. In GFX mode, we pretend * to have AGP because the graphics memory access is very * similar and the AGP GATT code will deal with this. In the * latter case, the pci_get_capability(PCI_CAP_AGP) test below * will fire, so we do no harm by already setting the flag. */ /* AGP only */ case PCI_PRODUCT_INTEL_82915GM_HB: case PCI_PRODUCT_INTEL_82945GM_HB: case PCI_PRODUCT_INTEL_82945GME_HB: case PCI_PRODUCT_INTEL_82G965_HB: case PCI_PRODUCT_INTEL_82Q965_HB: case PCI_PRODUCT_INTEL_82GM965_HB: case PCI_PRODUCT_INTEL_82G33_HB: case PCI_PRODUCT_INTEL_82G35_HB: has_agp = 1; break; /* AGP + RNG */ case PCI_PRODUCT_INTEL_82915G_HB: case PCI_PRODUCT_INTEL_82945G_HB: has_agp = 1; /* FALLTHROUGH */ case PCI_PRODUCT_INTEL_82925X_HB: case PCI_PRODUCT_INTEL_82955X_HB: sc->sc_bt = pa->pa_memt; if (bus_space_map(sc->sc_bt, I82802_IOBASE, I82802_IOSIZE, 0, &sc->sc_bh)) break; /* probe and init rng */ if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST) & I82802_RNG_HWST_PRESENT)) break; /* enable RNG */ bus_space_write_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST, bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST) | I82802_RNG_HWST_ENABLE); /* see if we can read anything */ for (i = 1000; i-- && !(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV); ) DELAY(10); if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV)) break; r = bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_DATA); timeout_set(&sc->sc_rng_to, pchb_rnd, sc); sc->sc_rng_i = 4; pchb_rnd(sc); break; } printf("\n"); break; default: printf("\n"); break; } #if NAGP > 0 /* * If we haven't detected AGP yet (via a product ID), * then check for AGP capability on the device. */ if (has_agp || pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL) != 0) { agp_set_pchb(pa); } #endif }
void pchbattach(struct device *parent, struct device *self, void *aux) { struct pchb_softc *sc = (struct pchb_softc *)self; struct pci_attach_args *pa = aux; struct pcibus_attach_args pba; pcireg_t bcreg, bir; u_char pbnum; pcitag_t tag; int i, r; int doattach = 0; switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_AMD: printf("\n"); switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_AMD_AMD64_0F_HT: case PCI_PRODUCT_AMD_AMD64_10_HT: for (i = 0; i < AMD64HT_NUM_LDT; i++) pchb_amd64ht_attach(self, pa, i); break; } break; case PCI_VENDOR_INTEL: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_INTEL_82915G_HB: case PCI_PRODUCT_INTEL_82945G_HB: case PCI_PRODUCT_INTEL_82925X_HB: case PCI_PRODUCT_INTEL_82955X_HB: sc->sc_bt = pa->pa_memt; if (bus_space_map(sc->sc_bt, I82802_IOBASE, I82802_IOSIZE, 0, &sc->sc_bh)) break; /* probe and init rng */ if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST) & I82802_RNG_HWST_PRESENT)) break; /* enable RNG */ bus_space_write_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST, bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_HWST) | I82802_RNG_HWST_ENABLE); /* see if we can read anything */ for (i = 1000; i-- && !(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV); ) DELAY(10); if (!(bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_RNGST) & I82802_RNG_RNGST_DATAV)) break; r = bus_space_read_1(sc->sc_bt, sc->sc_bh, I82802_RNG_DATA); timeout_set(&sc->sc_rng_to, pchb_rnd, sc); sc->sc_rng_i = 4; pchb_rnd(sc); sc->sc_rng_active = 1; break; } printf("\n"); break; case PCI_VENDOR_VIATECH: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_VIATECH_VT8251_PCIE_0: /* * Bump the host bridge into PCI-PCI bridge * mode by clearing magic bit on the VLINK * device. This allows us to read the bus * number for the PCI bus attached to this * host bridge. */ tag = pci_make_tag(pa->pa_pc, 0, 17, 7); bcreg = pci_conf_read(pa->pa_pc, tag, 0xfc); bcreg &= ~0x00000004; /* XXX Magic */ pci_conf_write(pa->pa_pc, tag, 0xfc, bcreg); bir = pci_conf_read(pa->pa_pc, pa->pa_tag, PPB_REG_BUSINFO); pbnum = PPB_BUSINFO_PRIMARY(bir); if (pbnum > 0) doattach = 1; /* Switch back to host bridge mode. */ bcreg |= 0x00000004; /* XXX Magic */ pci_conf_write(pa->pa_pc, tag, 0xfc, bcreg); break; } printf("\n"); break; default: printf("\n"); break; } #if NAGP > 0 /* * Intel IGD have an odd interface and attach at vga, however, * in that mode they don't have the AGP cap bit, so this * test should be sufficient */ if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL) != 0) { struct agp_attach_args aa; aa.aa_busname = "agp"; aa.aa_pa = pa; config_found(self, &aa, agpdev_print); } #endif /* NAGP > 0 */ if (doattach == 0) return; bzero(&pba, sizeof(pba)); pba.pba_busname = "pci"; pba.pba_iot = pa->pa_iot; pba.pba_memt = pa->pa_memt; pba.pba_dmat = pa->pa_dmat; pba.pba_busex = pa->pa_busex; pba.pba_domain = pa->pa_domain; pba.pba_bus = pbnum; pba.pba_pc = pa->pa_pc; config_found(self, &pba, pchb_print); }