11368987aSJohn Baldwin /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3ebf5747bSPedro F. Giffuni * 41368987aSJohn Baldwin * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 51368987aSJohn Baldwin * All rights reserved. 61368987aSJohn Baldwin * 71368987aSJohn Baldwin * Redistribution and use in source and binary forms, with or without 81368987aSJohn Baldwin * modification, are permitted provided that the following conditions 91368987aSJohn Baldwin * are met: 101368987aSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 111368987aSJohn Baldwin * notice unmodified, this list of conditions, and the following 121368987aSJohn Baldwin * disclaimer. 131368987aSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 141368987aSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 151368987aSJohn Baldwin * documentation and/or other materials provided with the distribution. 161368987aSJohn Baldwin * 171368987aSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 181368987aSJohn Baldwin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 191368987aSJohn Baldwin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 201368987aSJohn Baldwin * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 211368987aSJohn Baldwin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 221368987aSJohn Baldwin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231368987aSJohn Baldwin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241368987aSJohn Baldwin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251368987aSJohn Baldwin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 261368987aSJohn Baldwin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271368987aSJohn Baldwin */ 281368987aSJohn Baldwin 291368987aSJohn Baldwin #include <sys/cdefs.h> 301368987aSJohn Baldwin #include "opt_cpu.h" 311368987aSJohn Baldwin 321368987aSJohn Baldwin #include <sys/param.h> 331368987aSJohn Baldwin #include <sys/systm.h> 341368987aSJohn Baldwin #include <sys/bus.h> 351368987aSJohn Baldwin #include <sys/kernel.h> 361368987aSJohn Baldwin #include <sys/malloc.h> 371368987aSJohn Baldwin #include <sys/module.h> 381368987aSJohn Baldwin #include <sys/rman.h> 391368987aSJohn Baldwin #include <sys/sysctl.h> 401368987aSJohn Baldwin 411368987aSJohn Baldwin #include <dev/pci/pcivar.h> 421368987aSJohn Baldwin #include <dev/pci/pcireg.h> 431368987aSJohn Baldwin #include <dev/pci/pcib_private.h> 441368987aSJohn Baldwin #include <isa/isavar.h> 451368987aSJohn Baldwin #ifdef CPU_ELAN 461368987aSJohn Baldwin #include <machine/md_var.h> 471368987aSJohn Baldwin #endif 48435803f3SJohn Baldwin #include <x86/legacyvar.h> 491368987aSJohn Baldwin #include <machine/pci_cfgreg.h> 501368987aSJohn Baldwin #include <machine/resource.h> 511368987aSJohn Baldwin 521368987aSJohn Baldwin #include "pcib_if.h" 531368987aSJohn Baldwin 541368987aSJohn Baldwin int 551368987aSJohn Baldwin legacy_pcib_maxslots(device_t dev) 561368987aSJohn Baldwin { 571368987aSJohn Baldwin return 31; 581368987aSJohn Baldwin } 591368987aSJohn Baldwin 601368987aSJohn Baldwin /* read configuration space register */ 611368987aSJohn Baldwin 621368987aSJohn Baldwin uint32_t 631368987aSJohn Baldwin legacy_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, 641368987aSJohn Baldwin u_int reg, int bytes) 651368987aSJohn Baldwin { 661587a9dbSJohn Baldwin return(pci_cfgregread(0, bus, slot, func, reg, bytes)); 671368987aSJohn Baldwin } 681368987aSJohn Baldwin 691368987aSJohn Baldwin /* write configuration space register */ 701368987aSJohn Baldwin 711368987aSJohn Baldwin void 721368987aSJohn Baldwin legacy_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func, 731368987aSJohn Baldwin u_int reg, uint32_t data, int bytes) 741368987aSJohn Baldwin { 751587a9dbSJohn Baldwin pci_cfgregwrite(0, bus, slot, func, reg, data, bytes); 761368987aSJohn Baldwin } 771368987aSJohn Baldwin 781368987aSJohn Baldwin /* route interrupt */ 791368987aSJohn Baldwin 801368987aSJohn Baldwin static int 811368987aSJohn Baldwin legacy_pcib_route_interrupt(device_t pcib, device_t dev, int pin) 821368987aSJohn Baldwin { 831368987aSJohn Baldwin 841368987aSJohn Baldwin #ifdef __HAVE_PIR 851368987aSJohn Baldwin return (pci_pir_route_interrupt(pci_get_bus(dev), pci_get_slot(dev), 861368987aSJohn Baldwin pci_get_function(dev), pin)); 871368987aSJohn Baldwin #else 881368987aSJohn Baldwin /* No routing possible */ 891368987aSJohn Baldwin return (PCI_INVALID_IRQ); 901368987aSJohn Baldwin #endif 911368987aSJohn Baldwin } 921368987aSJohn Baldwin 931368987aSJohn Baldwin /* Pass MSI requests up to the nexus. */ 941368987aSJohn Baldwin 9584ca9aadSJohn Baldwin int 961368987aSJohn Baldwin legacy_pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, 971368987aSJohn Baldwin int *irqs) 981368987aSJohn Baldwin { 991368987aSJohn Baldwin device_t bus; 1001368987aSJohn Baldwin 1011368987aSJohn Baldwin bus = device_get_parent(pcib); 1021368987aSJohn Baldwin return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount, 1031368987aSJohn Baldwin irqs)); 1041368987aSJohn Baldwin } 1051368987aSJohn Baldwin 10684ca9aadSJohn Baldwin int 1071368987aSJohn Baldwin legacy_pcib_alloc_msix(device_t pcib, device_t dev, int *irq) 1081368987aSJohn Baldwin { 1091368987aSJohn Baldwin device_t bus; 1101368987aSJohn Baldwin 1111368987aSJohn Baldwin bus = device_get_parent(pcib); 1121368987aSJohn Baldwin return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq)); 1131368987aSJohn Baldwin } 1141368987aSJohn Baldwin 1150d95597cSJohn Baldwin int 1161368987aSJohn Baldwin legacy_pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, 1171368987aSJohn Baldwin uint32_t *data) 1181368987aSJohn Baldwin { 1190d95597cSJohn Baldwin device_t bus, hostb; 1200d95597cSJohn Baldwin int error, func, slot; 1211368987aSJohn Baldwin 1221368987aSJohn Baldwin bus = device_get_parent(pcib); 1230d95597cSJohn Baldwin error = PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data); 1240d95597cSJohn Baldwin if (error) 1250d95597cSJohn Baldwin return (error); 1260d95597cSJohn Baldwin 1270d95597cSJohn Baldwin slot = legacy_get_pcislot(pcib); 1280d95597cSJohn Baldwin func = legacy_get_pcifunc(pcib); 1290d95597cSJohn Baldwin if (slot == -1 || func == -1) 1300d95597cSJohn Baldwin return (0); 1310d95597cSJohn Baldwin hostb = pci_find_bsf(0, slot, func); 1320d95597cSJohn Baldwin KASSERT(hostb != NULL, ("%s: missing hostb for 0:%d:%d", __func__, 1330d95597cSJohn Baldwin slot, func)); 1340d95597cSJohn Baldwin pci_ht_map_msi(hostb, *addr); 1350d95597cSJohn Baldwin return (0); 1361368987aSJohn Baldwin } 1371368987aSJohn Baldwin 1381368987aSJohn Baldwin static const char * 1391368987aSJohn Baldwin legacy_pcib_is_host_bridge(int bus, int slot, int func, 1401368987aSJohn Baldwin uint32_t id, uint8_t class, uint8_t subclass, 1411368987aSJohn Baldwin uint8_t *busnum) 1421368987aSJohn Baldwin { 1431368987aSJohn Baldwin #ifdef __i386__ 1441368987aSJohn Baldwin const char *s = NULL; 1451368987aSJohn Baldwin static uint8_t pxb[4]; /* hack for 450nx */ 1461368987aSJohn Baldwin 1471368987aSJohn Baldwin *busnum = 0; 1481368987aSJohn Baldwin 1491368987aSJohn Baldwin switch (id) { 1501368987aSJohn Baldwin case 0x12258086: 1511368987aSJohn Baldwin s = "Intel 824?? host to PCI bridge"; 1521368987aSJohn Baldwin /* XXX This is a guess */ 1531368987aSJohn Baldwin /* *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x41, 1); */ 1541368987aSJohn Baldwin *busnum = bus; 1551368987aSJohn Baldwin break; 1561368987aSJohn Baldwin case 0x71208086: 1571368987aSJohn Baldwin s = "Intel 82810 (i810 GMCH) Host To Hub bridge"; 1581368987aSJohn Baldwin break; 1591368987aSJohn Baldwin case 0x71228086: 1601368987aSJohn Baldwin s = "Intel 82810-DC100 (i810-DC100 GMCH) Host To Hub bridge"; 1611368987aSJohn Baldwin break; 1621368987aSJohn Baldwin case 0x71248086: 1631368987aSJohn Baldwin s = "Intel 82810E (i810E GMCH) Host To Hub bridge"; 1641368987aSJohn Baldwin break; 1651368987aSJohn Baldwin case 0x11308086: 1661368987aSJohn Baldwin s = "Intel 82815 (i815 GMCH) Host To Hub bridge"; 1671368987aSJohn Baldwin break; 1681368987aSJohn Baldwin case 0x71808086: 1691368987aSJohn Baldwin s = "Intel 82443LX (440 LX) host to PCI bridge"; 1701368987aSJohn Baldwin break; 1711368987aSJohn Baldwin case 0x71908086: 1721368987aSJohn Baldwin s = "Intel 82443BX (440 BX) host to PCI bridge"; 1731368987aSJohn Baldwin break; 1741368987aSJohn Baldwin case 0x71928086: 1751368987aSJohn Baldwin s = "Intel 82443BX host to PCI bridge (AGP disabled)"; 1761368987aSJohn Baldwin break; 1771368987aSJohn Baldwin case 0x71948086: 1781368987aSJohn Baldwin s = "Intel 82443MX host to PCI bridge"; 1791368987aSJohn Baldwin break; 1801368987aSJohn Baldwin case 0x71a08086: 1811368987aSJohn Baldwin s = "Intel 82443GX host to PCI bridge"; 1821368987aSJohn Baldwin break; 1831368987aSJohn Baldwin case 0x71a18086: 1841368987aSJohn Baldwin s = "Intel 82443GX host to AGP bridge"; 1851368987aSJohn Baldwin break; 1861368987aSJohn Baldwin case 0x71a28086: 1871368987aSJohn Baldwin s = "Intel 82443GX host to PCI bridge (AGP disabled)"; 1881368987aSJohn Baldwin break; 1891368987aSJohn Baldwin case 0x84c48086: 1901368987aSJohn Baldwin s = "Intel 82454KX/GX (Orion) host to PCI bridge"; 1911368987aSJohn Baldwin *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x4a, 1); 1921368987aSJohn Baldwin break; 1931368987aSJohn Baldwin case 0x84ca8086: 1941368987aSJohn Baldwin /* 1951368987aSJohn Baldwin * For the 450nx chipset, there is a whole bundle of 1961368987aSJohn Baldwin * things pretending to be host bridges. The MIOC will 1971368987aSJohn Baldwin * be seen first and isn't really a pci bridge (the 198db4fcadfSConrad Meyer * actual buses are attached to the PXB's). We need to 1991368987aSJohn Baldwin * read the registers of the MIOC to figure out the 2001368987aSJohn Baldwin * bus numbers for the PXB channels. 2011368987aSJohn Baldwin * 2021368987aSJohn Baldwin * Since the MIOC doesn't have a pci bus attached, we 2031368987aSJohn Baldwin * pretend it wasn't there. 2041368987aSJohn Baldwin */ 2051368987aSJohn Baldwin pxb[0] = legacy_pcib_read_config(0, bus, slot, func, 2061368987aSJohn Baldwin 0xd0, 1); /* BUSNO[0] */ 2071368987aSJohn Baldwin pxb[1] = legacy_pcib_read_config(0, bus, slot, func, 2081368987aSJohn Baldwin 0xd1, 1) + 1; /* SUBA[0]+1 */ 2091368987aSJohn Baldwin pxb[2] = legacy_pcib_read_config(0, bus, slot, func, 2101368987aSJohn Baldwin 0xd3, 1); /* BUSNO[1] */ 2111368987aSJohn Baldwin pxb[3] = legacy_pcib_read_config(0, bus, slot, func, 2121368987aSJohn Baldwin 0xd4, 1) + 1; /* SUBA[1]+1 */ 2131368987aSJohn Baldwin return NULL; 2141368987aSJohn Baldwin case 0x84cb8086: 2151368987aSJohn Baldwin switch (slot) { 2161368987aSJohn Baldwin case 0x12: 2171368987aSJohn Baldwin s = "Intel 82454NX PXB#0, Bus#A"; 2181368987aSJohn Baldwin *busnum = pxb[0]; 2191368987aSJohn Baldwin break; 2201368987aSJohn Baldwin case 0x13: 2211368987aSJohn Baldwin s = "Intel 82454NX PXB#0, Bus#B"; 2221368987aSJohn Baldwin *busnum = pxb[1]; 2231368987aSJohn Baldwin break; 2241368987aSJohn Baldwin case 0x14: 2251368987aSJohn Baldwin s = "Intel 82454NX PXB#1, Bus#A"; 2261368987aSJohn Baldwin *busnum = pxb[2]; 2271368987aSJohn Baldwin break; 2281368987aSJohn Baldwin case 0x15: 2291368987aSJohn Baldwin s = "Intel 82454NX PXB#1, Bus#B"; 2301368987aSJohn Baldwin *busnum = pxb[3]; 2311368987aSJohn Baldwin break; 2321368987aSJohn Baldwin } 2331368987aSJohn Baldwin break; 2341368987aSJohn Baldwin case 0x1A308086: 2351368987aSJohn Baldwin s = "Intel 82845 Host to PCI bridge"; 2361368987aSJohn Baldwin break; 2371368987aSJohn Baldwin 2381368987aSJohn Baldwin /* AMD -- vendor 0x1022 */ 2391368987aSJohn Baldwin case 0x30001022: 2401368987aSJohn Baldwin s = "AMD Elan SC520 host to PCI bridge"; 2411368987aSJohn Baldwin #ifdef CPU_ELAN 2421368987aSJohn Baldwin init_AMD_Elan_sc520(); 2431368987aSJohn Baldwin #else 2441368987aSJohn Baldwin printf( 2451368987aSJohn Baldwin "*** WARNING: missing CPU_ELAN -- timekeeping may be wrong\n"); 2461368987aSJohn Baldwin #endif 2471368987aSJohn Baldwin break; 2481368987aSJohn Baldwin case 0x70061022: 2491368987aSJohn Baldwin s = "AMD-751 host to PCI bridge"; 2501368987aSJohn Baldwin break; 2511368987aSJohn Baldwin case 0x700e1022: 2521368987aSJohn Baldwin s = "AMD-761 host to PCI bridge"; 2531368987aSJohn Baldwin break; 2541368987aSJohn Baldwin 2551368987aSJohn Baldwin /* SiS -- vendor 0x1039 */ 2561368987aSJohn Baldwin case 0x04961039: 2571368987aSJohn Baldwin s = "SiS 85c496"; 2581368987aSJohn Baldwin break; 2591368987aSJohn Baldwin case 0x04061039: 2601368987aSJohn Baldwin s = "SiS 85c501"; 2611368987aSJohn Baldwin break; 2621368987aSJohn Baldwin case 0x06011039: 2631368987aSJohn Baldwin s = "SiS 85c601"; 2641368987aSJohn Baldwin break; 2651368987aSJohn Baldwin case 0x55911039: 2661368987aSJohn Baldwin s = "SiS 5591 host to PCI bridge"; 2671368987aSJohn Baldwin break; 2681368987aSJohn Baldwin case 0x00011039: 2691368987aSJohn Baldwin s = "SiS 5591 host to AGP bridge"; 2701368987aSJohn Baldwin break; 2711368987aSJohn Baldwin 2721368987aSJohn Baldwin /* VLSI -- vendor 0x1004 */ 2731368987aSJohn Baldwin case 0x00051004: 2741368987aSJohn Baldwin s = "VLSI 82C592 Host to PCI bridge"; 2751368987aSJohn Baldwin break; 2761368987aSJohn Baldwin 2771368987aSJohn Baldwin /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */ 2781368987aSJohn Baldwin /* totally. Please let me know if anything wrong. -F */ 2791368987aSJohn Baldwin /* XXX need info on the MVP3 -- any takers? */ 2801368987aSJohn Baldwin case 0x05981106: 2811368987aSJohn Baldwin s = "VIA 82C598MVP (Apollo MVP3) host bridge"; 2821368987aSJohn Baldwin break; 2831368987aSJohn Baldwin 2841368987aSJohn Baldwin /* AcerLabs -- vendor 0x10b9 */ 2851368987aSJohn Baldwin /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */ 2861368987aSJohn Baldwin /* id is '10b9" but the register always shows "10b9". -Foxfair */ 2871368987aSJohn Baldwin case 0x154110b9: 2881368987aSJohn Baldwin s = "AcerLabs M1541 (Aladdin-V) PCI host bridge"; 2891368987aSJohn Baldwin break; 2901368987aSJohn Baldwin 2911368987aSJohn Baldwin /* OPTi -- vendor 0x1045 */ 2921368987aSJohn Baldwin case 0xc7011045: 2931368987aSJohn Baldwin s = "OPTi 82C700 host to PCI bridge"; 2941368987aSJohn Baldwin break; 2951368987aSJohn Baldwin case 0xc8221045: 2961368987aSJohn Baldwin s = "OPTi 82C822 host to PCI Bridge"; 2971368987aSJohn Baldwin break; 2981368987aSJohn Baldwin 2991368987aSJohn Baldwin /* ServerWorks -- vendor 0x1166 */ 3001368987aSJohn Baldwin case 0x00051166: 3011368987aSJohn Baldwin s = "ServerWorks NB6536 2.0HE host to PCI bridge"; 3021368987aSJohn Baldwin *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 3031368987aSJohn Baldwin break; 3041368987aSJohn Baldwin 3051368987aSJohn Baldwin case 0x00061166: 3061368987aSJohn Baldwin /* FALLTHROUGH */ 3071368987aSJohn Baldwin case 0x00081166: 3081368987aSJohn Baldwin /* FALLTHROUGH */ 3091368987aSJohn Baldwin case 0x02011166: 3101368987aSJohn Baldwin /* FALLTHROUGH */ 3111368987aSJohn Baldwin case 0x010f1014: /* IBM re-badged ServerWorks chipset */ 3121368987aSJohn Baldwin s = "ServerWorks host to PCI bridge"; 3131368987aSJohn Baldwin *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 3141368987aSJohn Baldwin break; 3151368987aSJohn Baldwin 3161368987aSJohn Baldwin case 0x00091166: 3171368987aSJohn Baldwin s = "ServerWorks NB6635 3.0LE host to PCI bridge"; 3181368987aSJohn Baldwin *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 3191368987aSJohn Baldwin break; 3201368987aSJohn Baldwin 3211368987aSJohn Baldwin case 0x00101166: 3221368987aSJohn Baldwin s = "ServerWorks CIOB30 host to PCI bridge"; 3231368987aSJohn Baldwin *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 3241368987aSJohn Baldwin break; 3251368987aSJohn Baldwin 3261368987aSJohn Baldwin case 0x00111166: 3271368987aSJohn Baldwin /* FALLTHROUGH */ 3281368987aSJohn Baldwin case 0x03021014: /* IBM re-badged ServerWorks chipset */ 3291368987aSJohn Baldwin s = "ServerWorks CMIC-HE host to PCI-X bridge"; 3301368987aSJohn Baldwin *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 3311368987aSJohn Baldwin break; 3321368987aSJohn Baldwin 3331368987aSJohn Baldwin /* XXX unknown chipset, but working */ 3341368987aSJohn Baldwin case 0x00171166: 3351368987aSJohn Baldwin /* FALLTHROUGH */ 3361368987aSJohn Baldwin case 0x01011166: 3371368987aSJohn Baldwin case 0x01101166: 3381368987aSJohn Baldwin case 0x02251166: 3391368987aSJohn Baldwin s = "ServerWorks host to PCI bridge(unknown chipset)"; 3401368987aSJohn Baldwin *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1); 3411368987aSJohn Baldwin break; 3421368987aSJohn Baldwin 3431368987aSJohn Baldwin /* Compaq/HP -- vendor 0x0e11 */ 3441368987aSJohn Baldwin case 0x60100e11: 3451368987aSJohn Baldwin s = "Compaq/HP Model 6010 HotPlug PCI Bridge"; 3461368987aSJohn Baldwin *busnum = legacy_pcib_read_config(0, bus, slot, func, 0xc8, 1); 3471368987aSJohn Baldwin break; 3481368987aSJohn Baldwin 3491368987aSJohn Baldwin /* Integrated Micro Solutions -- vendor 0x10e0 */ 3501368987aSJohn Baldwin case 0x884910e0: 3511368987aSJohn Baldwin s = "Integrated Micro Solutions VL Bridge"; 3521368987aSJohn Baldwin break; 3531368987aSJohn Baldwin 3541368987aSJohn Baldwin default: 3551368987aSJohn Baldwin if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST) 3561368987aSJohn Baldwin s = "Host to PCI bridge"; 3571368987aSJohn Baldwin break; 3581368987aSJohn Baldwin } 3591368987aSJohn Baldwin 3601368987aSJohn Baldwin return s; 3611368987aSJohn Baldwin #else 3621368987aSJohn Baldwin const char *s = NULL; 3631368987aSJohn Baldwin 3641368987aSJohn Baldwin *busnum = 0; 3651368987aSJohn Baldwin if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST) 3661368987aSJohn Baldwin s = "Host to PCI bridge"; 3671368987aSJohn Baldwin return s; 3681368987aSJohn Baldwin #endif 3691368987aSJohn Baldwin } 3701368987aSJohn Baldwin 3711368987aSJohn Baldwin /* 3721368987aSJohn Baldwin * Scan the first pci bus for host-pci bridges and add pcib instances 3731368987aSJohn Baldwin * to the nexus for each bridge. 3741368987aSJohn Baldwin */ 3751368987aSJohn Baldwin static void 3761368987aSJohn Baldwin legacy_pcib_identify(driver_t *driver, device_t parent) 3771368987aSJohn Baldwin { 3781368987aSJohn Baldwin int bus, slot, func; 3791368987aSJohn Baldwin uint8_t hdrtype; 3801368987aSJohn Baldwin int found = 0; 3811368987aSJohn Baldwin int pcifunchigh; 3821368987aSJohn Baldwin int found824xx = 0; 3831368987aSJohn Baldwin int found_orion = 0; 3841368987aSJohn Baldwin device_t child; 3851368987aSJohn Baldwin devclass_t pci_devclass; 3861368987aSJohn Baldwin 3871368987aSJohn Baldwin if (pci_cfgregopen() == 0) 3881368987aSJohn Baldwin return; 3891368987aSJohn Baldwin /* 3901368987aSJohn Baldwin * Check to see if we haven't already had a PCI bus added 3911368987aSJohn Baldwin * via some other means. If we have, bail since otherwise 3921368987aSJohn Baldwin * we're going to end up duplicating it. 3931368987aSJohn Baldwin */ 3941368987aSJohn Baldwin if ((pci_devclass = devclass_find("pci")) && 3951368987aSJohn Baldwin devclass_get_device(pci_devclass, 0)) 3961368987aSJohn Baldwin return; 3971368987aSJohn Baldwin 3981368987aSJohn Baldwin bus = 0; 3991368987aSJohn Baldwin retry: 4001368987aSJohn Baldwin for (slot = 0; slot <= PCI_SLOTMAX; slot++) { 4011368987aSJohn Baldwin func = 0; 4021368987aSJohn Baldwin hdrtype = legacy_pcib_read_config(0, bus, slot, func, 4031368987aSJohn Baldwin PCIR_HDRTYPE, 1); 4041368987aSJohn Baldwin /* 4051368987aSJohn Baldwin * When enumerating bus devices, the standard says that 4061368987aSJohn Baldwin * one should check the header type and ignore the slots whose 4071368987aSJohn Baldwin * header types that the software doesn't know about. We use 4081368987aSJohn Baldwin * this to filter out devices. 4091368987aSJohn Baldwin */ 4101368987aSJohn Baldwin if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) 4111368987aSJohn Baldwin continue; 4121368987aSJohn Baldwin if ((hdrtype & PCIM_MFDEV) && 4131368987aSJohn Baldwin (!found_orion || hdrtype != 0xff)) 4141368987aSJohn Baldwin pcifunchigh = PCI_FUNCMAX; 4151368987aSJohn Baldwin else 4161368987aSJohn Baldwin pcifunchigh = 0; 4171368987aSJohn Baldwin for (func = 0; func <= pcifunchigh; func++) { 4181368987aSJohn Baldwin /* 4191368987aSJohn Baldwin * Read the IDs and class from the device. 4201368987aSJohn Baldwin */ 4211368987aSJohn Baldwin uint32_t id; 4221368987aSJohn Baldwin uint8_t class, subclass, busnum; 4231368987aSJohn Baldwin const char *s; 4241368987aSJohn Baldwin device_t *devs; 4251368987aSJohn Baldwin int ndevs, i; 4261368987aSJohn Baldwin 4271368987aSJohn Baldwin id = legacy_pcib_read_config(0, bus, slot, func, 4281368987aSJohn Baldwin PCIR_DEVVENDOR, 4); 4291368987aSJohn Baldwin if (id == -1) 4301368987aSJohn Baldwin continue; 4311368987aSJohn Baldwin class = legacy_pcib_read_config(0, bus, slot, func, 4321368987aSJohn Baldwin PCIR_CLASS, 1); 4331368987aSJohn Baldwin subclass = legacy_pcib_read_config(0, bus, slot, func, 4341368987aSJohn Baldwin PCIR_SUBCLASS, 1); 4351368987aSJohn Baldwin 4361368987aSJohn Baldwin s = legacy_pcib_is_host_bridge(bus, slot, func, 4371368987aSJohn Baldwin id, class, subclass, 4381368987aSJohn Baldwin &busnum); 4391368987aSJohn Baldwin if (s == NULL) 4401368987aSJohn Baldwin continue; 4411368987aSJohn Baldwin 4421368987aSJohn Baldwin /* 4431368987aSJohn Baldwin * Check to see if the physical bus has already 4441368987aSJohn Baldwin * been seen. Eg: hybrid 32 and 64 bit host 4451368987aSJohn Baldwin * bridges to the same logical bus. 4461368987aSJohn Baldwin */ 4471368987aSJohn Baldwin if (device_get_children(parent, &devs, &ndevs) == 0) { 4481368987aSJohn Baldwin for (i = 0; s != NULL && i < ndevs; i++) { 4491368987aSJohn Baldwin if (strcmp(device_get_name(devs[i]), 4501368987aSJohn Baldwin "pcib") != 0) 4511368987aSJohn Baldwin continue; 4521368987aSJohn Baldwin if (legacy_get_pcibus(devs[i]) == busnum) 4531368987aSJohn Baldwin s = NULL; 4541368987aSJohn Baldwin } 4551368987aSJohn Baldwin free(devs, M_TEMP); 4561368987aSJohn Baldwin } 4571368987aSJohn Baldwin 4581368987aSJohn Baldwin if (s == NULL) 4591368987aSJohn Baldwin continue; 4601368987aSJohn Baldwin /* 4611368987aSJohn Baldwin * Add at priority 100 to make sure we 4621368987aSJohn Baldwin * go after any motherboard resources 4631368987aSJohn Baldwin */ 4641368987aSJohn Baldwin child = BUS_ADD_CHILD(parent, 100, 4651368987aSJohn Baldwin "pcib", busnum); 4661368987aSJohn Baldwin device_set_desc(child, s); 4671368987aSJohn Baldwin legacy_set_pcibus(child, busnum); 4680d95597cSJohn Baldwin legacy_set_pcislot(child, slot); 4690d95597cSJohn Baldwin legacy_set_pcifunc(child, func); 4701368987aSJohn Baldwin 4711368987aSJohn Baldwin found = 1; 4721368987aSJohn Baldwin if (id == 0x12258086) 4731368987aSJohn Baldwin found824xx = 1; 4741368987aSJohn Baldwin if (id == 0x84c48086) 4751368987aSJohn Baldwin found_orion = 1; 4761368987aSJohn Baldwin } 4771368987aSJohn Baldwin } 4781368987aSJohn Baldwin if (found824xx && bus == 0) { 4791368987aSJohn Baldwin bus++; 4801368987aSJohn Baldwin goto retry; 4811368987aSJohn Baldwin } 4821368987aSJohn Baldwin 4831368987aSJohn Baldwin /* 4841368987aSJohn Baldwin * Make sure we add at least one bridge since some old 4851368987aSJohn Baldwin * hardware doesn't actually have a host-pci bridge device. 4861368987aSJohn Baldwin * Note that pci_cfgregopen() thinks we have PCI devices.. 4871368987aSJohn Baldwin */ 4881368987aSJohn Baldwin if (!found) { 4892297a163SColin Percival #ifndef NO_LEGACY_PCIB 4901368987aSJohn Baldwin if (bootverbose) 4911368987aSJohn Baldwin printf( 4921368987aSJohn Baldwin "legacy_pcib_identify: no bridge found, adding pcib0 anyway\n"); 4931368987aSJohn Baldwin child = BUS_ADD_CHILD(parent, 100, "pcib", 0); 4941368987aSJohn Baldwin legacy_set_pcibus(child, 0); 4952297a163SColin Percival #endif 4961368987aSJohn Baldwin } 4971368987aSJohn Baldwin } 4981368987aSJohn Baldwin 4991368987aSJohn Baldwin static int 5001368987aSJohn Baldwin legacy_pcib_probe(device_t dev) 5011368987aSJohn Baldwin { 5021368987aSJohn Baldwin 5031368987aSJohn Baldwin if (pci_cfgregopen() == 0) 5041368987aSJohn Baldwin return ENXIO; 5051368987aSJohn Baldwin return -100; 5061368987aSJohn Baldwin } 5071368987aSJohn Baldwin 5081368987aSJohn Baldwin static int 5091368987aSJohn Baldwin legacy_pcib_attach(device_t dev) 5101368987aSJohn Baldwin { 5111368987aSJohn Baldwin #ifdef __HAVE_PIR 5121368987aSJohn Baldwin device_t pir; 5131368987aSJohn Baldwin int bus; 5141368987aSJohn Baldwin 5151368987aSJohn Baldwin bus = pcib_get_bus(dev); 5161368987aSJohn Baldwin /* 5171368987aSJohn Baldwin * Look for a PCI BIOS interrupt routing table as that will be 5181368987aSJohn Baldwin * our method of routing interrupts if we have one. 5191368987aSJohn Baldwin */ 5201368987aSJohn Baldwin if (pci_pir_probe(bus, 0)) { 5211368987aSJohn Baldwin pir = BUS_ADD_CHILD(device_get_parent(dev), 0, "pir", 0); 5221368987aSJohn Baldwin if (pir != NULL) 5231368987aSJohn Baldwin device_probe_and_attach(pir); 5241368987aSJohn Baldwin } 5251368987aSJohn Baldwin #endif 5265b56413dSWarner Losh device_add_child(dev, "pci", DEVICE_UNIT_ANY); 527*18250ec6SJohn Baldwin bus_attach_children(dev); 528*18250ec6SJohn Baldwin return (0); 5291368987aSJohn Baldwin } 5301368987aSJohn Baldwin 5311368987aSJohn Baldwin int 5321368987aSJohn Baldwin legacy_pcib_read_ivar(device_t dev, device_t child, int which, 5331368987aSJohn Baldwin uintptr_t *result) 5341368987aSJohn Baldwin { 5351368987aSJohn Baldwin 5361368987aSJohn Baldwin switch (which) { 5371368987aSJohn Baldwin case PCIB_IVAR_DOMAIN: 5381368987aSJohn Baldwin *result = 0; 5391368987aSJohn Baldwin return 0; 5401368987aSJohn Baldwin case PCIB_IVAR_BUS: 5411368987aSJohn Baldwin *result = legacy_get_pcibus(dev); 5421368987aSJohn Baldwin return 0; 5431368987aSJohn Baldwin } 5441368987aSJohn Baldwin return ENOENT; 5451368987aSJohn Baldwin } 5461368987aSJohn Baldwin 5471368987aSJohn Baldwin int 5481368987aSJohn Baldwin legacy_pcib_write_ivar(device_t dev, device_t child, int which, 5491368987aSJohn Baldwin uintptr_t value) 5501368987aSJohn Baldwin { 5511368987aSJohn Baldwin 5521368987aSJohn Baldwin switch (which) { 5531368987aSJohn Baldwin case PCIB_IVAR_DOMAIN: 5541368987aSJohn Baldwin return EINVAL; 5551368987aSJohn Baldwin case PCIB_IVAR_BUS: 5561368987aSJohn Baldwin legacy_set_pcibus(dev, value); 5571368987aSJohn Baldwin return 0; 5581368987aSJohn Baldwin } 5591368987aSJohn Baldwin return ENOENT; 5601368987aSJohn Baldwin } 5611368987aSJohn Baldwin 5621368987aSJohn Baldwin /* 5631368987aSJohn Baldwin * Helper routine for x86 Host-PCI bridge driver resource allocation. 5641368987aSJohn Baldwin * This is used to adjust the start address of wildcard allocation 5651368987aSJohn Baldwin * requests to avoid low addresses that are known to be problematic. 5661368987aSJohn Baldwin * 5671368987aSJohn Baldwin * If no memory preference is given, use upper 32MB slot most BIOSes 5681368987aSJohn Baldwin * use for their memory window. This is typically only used on older 569db4fcadfSConrad Meyer * laptops that don't have PCI buses behind a PCI bridge, so assuming 5701368987aSJohn Baldwin * > 32MB is likely OK. 5711368987aSJohn Baldwin * 5721368987aSJohn Baldwin * However, this can cause problems for other chipsets, so we make 5731368987aSJohn Baldwin * this tunable by hw.pci.host_mem_start. 5741368987aSJohn Baldwin */ 5751368987aSJohn Baldwin SYSCTL_DECL(_hw_pci); 5761368987aSJohn Baldwin 5771368987aSJohn Baldwin static unsigned long host_mem_start = 0x80000000; 5781368987aSJohn Baldwin SYSCTL_ULONG(_hw_pci, OID_AUTO, host_mem_start, CTLFLAG_RDTUN, &host_mem_start, 5791368987aSJohn Baldwin 0, "Limit the host bridge memory to being above this address."); 5801368987aSJohn Baldwin 5812dd1bdf1SJustin Hibbits rman_res_t 5822dd1bdf1SJustin Hibbits hostb_alloc_start(int type, rman_res_t start, rman_res_t end, rman_res_t count) 5831368987aSJohn Baldwin { 5841368987aSJohn Baldwin 5851368987aSJohn Baldwin if (start + count - 1 != end) { 5861368987aSJohn Baldwin if (type == SYS_RES_MEMORY && start < host_mem_start) 5871368987aSJohn Baldwin start = host_mem_start; 5881368987aSJohn Baldwin if (type == SYS_RES_IOPORT && start < 0x1000) 5891368987aSJohn Baldwin start = 0x1000; 5901368987aSJohn Baldwin } 5911368987aSJohn Baldwin return (start); 5921368987aSJohn Baldwin } 5931368987aSJohn Baldwin 5941368987aSJohn Baldwin struct resource * 5951368987aSJohn Baldwin legacy_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, 5962dd1bdf1SJustin Hibbits rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 5971368987aSJohn Baldwin { 5981368987aSJohn Baldwin 5994edef187SJohn Baldwin if (type == PCI_RES_BUS) 6004edef187SJohn Baldwin return (pci_domain_alloc_bus(0, child, rid, start, end, count, 6014edef187SJohn Baldwin flags)); 6021368987aSJohn Baldwin start = hostb_alloc_start(type, start, end, count); 6031368987aSJohn Baldwin return (bus_generic_alloc_resource(dev, child, type, rid, start, end, 6041368987aSJohn Baldwin count, flags)); 6051368987aSJohn Baldwin } 6061368987aSJohn Baldwin 6074edef187SJohn Baldwin int 608fef01f04SJohn Baldwin legacy_pcib_adjust_resource(device_t dev, device_t child, 6092dd1bdf1SJustin Hibbits struct resource *r, rman_res_t start, rman_res_t end) 6104edef187SJohn Baldwin { 6114edef187SJohn Baldwin 612fef01f04SJohn Baldwin if (rman_get_type(r) == PCI_RES_BUS) 6134edef187SJohn Baldwin return (pci_domain_adjust_bus(0, child, r, start, end)); 614fef01f04SJohn Baldwin return (bus_generic_adjust_resource(dev, child, r, start, end)); 6154edef187SJohn Baldwin } 6164edef187SJohn Baldwin 6174edef187SJohn Baldwin int 6189dbf5b0eSJohn Baldwin legacy_pcib_release_resource(device_t dev, device_t child, struct resource *r) 6194edef187SJohn Baldwin { 6204edef187SJohn Baldwin 6219dbf5b0eSJohn Baldwin if (rman_get_type(r) == PCI_RES_BUS) 6229dbf5b0eSJohn Baldwin return (pci_domain_release_bus(0, child, r)); 6239dbf5b0eSJohn Baldwin return (bus_generic_release_resource(dev, child, r)); 6244edef187SJohn Baldwin } 62531e15e53SJohn Baldwin 62631e15e53SJohn Baldwin int 6272baed46eSJohn Baldwin legacy_pcib_activate_resource(device_t dev, device_t child, struct resource *r) 62831e15e53SJohn Baldwin { 6292baed46eSJohn Baldwin if (rman_get_type(r) == PCI_RES_BUS) 6302baed46eSJohn Baldwin return (pci_domain_activate_bus(0, child, r)); 6312baed46eSJohn Baldwin return (bus_generic_activate_resource(dev, child, r)); 63231e15e53SJohn Baldwin } 63331e15e53SJohn Baldwin 63431e15e53SJohn Baldwin int 6352baed46eSJohn Baldwin legacy_pcib_deactivate_resource(device_t dev, device_t child, 63631e15e53SJohn Baldwin struct resource *r) 63731e15e53SJohn Baldwin { 6382baed46eSJohn Baldwin if (rman_get_type(r) == PCI_RES_BUS) 6392baed46eSJohn Baldwin return (pci_domain_deactivate_bus(0, child, r)); 6402baed46eSJohn Baldwin return (bus_generic_deactivate_resource(dev, child, r)); 64131e15e53SJohn Baldwin } 6424edef187SJohn Baldwin 6431368987aSJohn Baldwin static device_method_t legacy_pcib_methods[] = { 6441368987aSJohn Baldwin /* Device interface */ 6451368987aSJohn Baldwin DEVMETHOD(device_identify, legacy_pcib_identify), 6461368987aSJohn Baldwin DEVMETHOD(device_probe, legacy_pcib_probe), 6471368987aSJohn Baldwin DEVMETHOD(device_attach, legacy_pcib_attach), 6481368987aSJohn Baldwin DEVMETHOD(device_shutdown, bus_generic_shutdown), 6491368987aSJohn Baldwin DEVMETHOD(device_suspend, bus_generic_suspend), 6501368987aSJohn Baldwin DEVMETHOD(device_resume, bus_generic_resume), 6511368987aSJohn Baldwin 6521368987aSJohn Baldwin /* Bus interface */ 6531368987aSJohn Baldwin DEVMETHOD(bus_read_ivar, legacy_pcib_read_ivar), 6541368987aSJohn Baldwin DEVMETHOD(bus_write_ivar, legacy_pcib_write_ivar), 6551368987aSJohn Baldwin DEVMETHOD(bus_alloc_resource, legacy_pcib_alloc_resource), 6564edef187SJohn Baldwin DEVMETHOD(bus_adjust_resource, legacy_pcib_adjust_resource), 6574edef187SJohn Baldwin DEVMETHOD(bus_release_resource, legacy_pcib_release_resource), 65831e15e53SJohn Baldwin DEVMETHOD(bus_activate_resource, legacy_pcib_activate_resource), 65931e15e53SJohn Baldwin DEVMETHOD(bus_deactivate_resource, legacy_pcib_deactivate_resource), 6601368987aSJohn Baldwin DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 6611368987aSJohn Baldwin DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 6621368987aSJohn Baldwin 6631368987aSJohn Baldwin /* pcib interface */ 6641368987aSJohn Baldwin DEVMETHOD(pcib_maxslots, legacy_pcib_maxslots), 6651368987aSJohn Baldwin DEVMETHOD(pcib_read_config, legacy_pcib_read_config), 6661368987aSJohn Baldwin DEVMETHOD(pcib_write_config, legacy_pcib_write_config), 6671368987aSJohn Baldwin DEVMETHOD(pcib_route_interrupt, legacy_pcib_route_interrupt), 6681368987aSJohn Baldwin DEVMETHOD(pcib_alloc_msi, legacy_pcib_alloc_msi), 6691368987aSJohn Baldwin DEVMETHOD(pcib_release_msi, pcib_release_msi), 6701368987aSJohn Baldwin DEVMETHOD(pcib_alloc_msix, legacy_pcib_alloc_msix), 6711368987aSJohn Baldwin DEVMETHOD(pcib_release_msix, pcib_release_msix), 6721368987aSJohn Baldwin DEVMETHOD(pcib_map_msi, legacy_pcib_map_msi), 67328586889SWarner Losh DEVMETHOD(pcib_request_feature, pcib_request_feature_allow), 6741368987aSJohn Baldwin 6754b7ec270SMarius Strobl DEVMETHOD_END 6761368987aSJohn Baldwin }; 6771368987aSJohn Baldwin 6781368987aSJohn Baldwin DEFINE_CLASS_0(pcib, legacy_pcib_driver, legacy_pcib_methods, 1); 67980d2b3deSJohn Baldwin DRIVER_MODULE(pcib, legacy, legacy_pcib_driver, 0, 0); 6801368987aSJohn Baldwin 6811368987aSJohn Baldwin /* 6821368987aSJohn Baldwin * Install placeholder to claim the resources owned by the 6831368987aSJohn Baldwin * PCI bus interface. This could be used to extract the 6841368987aSJohn Baldwin * config space registers in the extreme case where the PnP 6851368987aSJohn Baldwin * ID is available and the PCI BIOS isn't, but for now we just 6861368987aSJohn Baldwin * eat the PnP ID and do nothing else. 6871368987aSJohn Baldwin * 688d6b66397SWarner Losh * we silence this probe, as it will generally confuse people. 6891368987aSJohn Baldwin */ 6901368987aSJohn Baldwin static struct isa_pnp_id pcibus_pnp_ids[] = { 6911368987aSJohn Baldwin { 0x030ad041 /* PNP0A03 */, "PCI Bus" }, 6921368987aSJohn Baldwin { 0x080ad041 /* PNP0A08 */, "PCIe Bus" }, 6931368987aSJohn Baldwin { 0 } 6941368987aSJohn Baldwin }; 6951368987aSJohn Baldwin 6961368987aSJohn Baldwin static int 6971368987aSJohn Baldwin pcibus_pnp_probe(device_t dev) 6981368987aSJohn Baldwin { 6991368987aSJohn Baldwin int result; 7001368987aSJohn Baldwin 7011368987aSJohn Baldwin if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, pcibus_pnp_ids)) <= 0) 7021368987aSJohn Baldwin device_quiet(dev); 7031368987aSJohn Baldwin return(result); 7041368987aSJohn Baldwin } 7051368987aSJohn Baldwin 7061368987aSJohn Baldwin static int 7071368987aSJohn Baldwin pcibus_pnp_attach(device_t dev) 7081368987aSJohn Baldwin { 7091368987aSJohn Baldwin return(0); 7101368987aSJohn Baldwin } 7111368987aSJohn Baldwin 7121368987aSJohn Baldwin static device_method_t pcibus_pnp_methods[] = { 7131368987aSJohn Baldwin /* Device interface */ 7141368987aSJohn Baldwin DEVMETHOD(device_probe, pcibus_pnp_probe), 7151368987aSJohn Baldwin DEVMETHOD(device_attach, pcibus_pnp_attach), 7161368987aSJohn Baldwin { 0, 0 } 7171368987aSJohn Baldwin }; 7181368987aSJohn Baldwin 7191368987aSJohn Baldwin DEFINE_CLASS_0(pcibus_pnp, pcibus_pnp_driver, pcibus_pnp_methods, 1); 72080d2b3deSJohn Baldwin DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, 0, 0); 7211368987aSJohn Baldwin 7221368987aSJohn Baldwin #ifdef __HAVE_PIR 7231368987aSJohn Baldwin /* 724db4fcadfSConrad Meyer * Provide a PCI-PCI bridge driver for PCI buses behind PCI-PCI bridges 7251368987aSJohn Baldwin * that appear in the PCIBIOS Interrupt Routing Table to use the routing 7261368987aSJohn Baldwin * table for interrupt routing when possible. 7271368987aSJohn Baldwin */ 7281368987aSJohn Baldwin static int pcibios_pcib_probe(device_t bus); 7291368987aSJohn Baldwin 7301368987aSJohn Baldwin static device_method_t pcibios_pcib_pci_methods[] = { 7311368987aSJohn Baldwin /* Device interface */ 7321368987aSJohn Baldwin DEVMETHOD(device_probe, pcibios_pcib_probe), 7331368987aSJohn Baldwin 7341368987aSJohn Baldwin /* pcib interface */ 7351368987aSJohn Baldwin DEVMETHOD(pcib_route_interrupt, legacy_pcib_route_interrupt), 7361368987aSJohn Baldwin {0, 0} 7371368987aSJohn Baldwin }; 7381368987aSJohn Baldwin 7391368987aSJohn Baldwin DEFINE_CLASS_1(pcib, pcibios_pcib_driver, pcibios_pcib_pci_methods, 7401368987aSJohn Baldwin sizeof(struct pcib_softc), pcib_driver); 74180d2b3deSJohn Baldwin DRIVER_MODULE(pcibios_pcib, pci, pcibios_pcib_driver, 0, 0); 742d6b66397SWarner Losh ISA_PNP_INFO(pcibus_pnp_ids); 7431368987aSJohn Baldwin 7441368987aSJohn Baldwin static int 7451368987aSJohn Baldwin pcibios_pcib_probe(device_t dev) 7461368987aSJohn Baldwin { 7471368987aSJohn Baldwin int bus; 7481368987aSJohn Baldwin 7491368987aSJohn Baldwin if ((pci_get_class(dev) != PCIC_BRIDGE) || 7501368987aSJohn Baldwin (pci_get_subclass(dev) != PCIS_BRIDGE_PCI)) 7511368987aSJohn Baldwin return (ENXIO); 7521368987aSJohn Baldwin bus = pci_read_config(dev, PCIR_SECBUS_1, 1); 7531368987aSJohn Baldwin if (bus == 0) 7541368987aSJohn Baldwin return (ENXIO); 7551368987aSJohn Baldwin if (!pci_pir_probe(bus, 1)) 7561368987aSJohn Baldwin return (ENXIO); 7571368987aSJohn Baldwin device_set_desc(dev, "PCIBIOS PCI-PCI bridge"); 7581368987aSJohn Baldwin return (-2000); 7591368987aSJohn Baldwin } 7601368987aSJohn Baldwin #endif 761