1*0dbe859dSJohn Baldwin /*- 2*0dbe859dSJohn Baldwin * Copyright (c) 2011 Advanced Computing Technologies LLC 3*0dbe859dSJohn Baldwin * Written by: John H. Baldwin <jhb@FreeBSD.org> 4*0dbe859dSJohn Baldwin * All rights reserved. 5*0dbe859dSJohn Baldwin * 6*0dbe859dSJohn Baldwin * Redistribution and use in source and binary forms, with or without 7*0dbe859dSJohn Baldwin * modification, are permitted provided that the following conditions 8*0dbe859dSJohn Baldwin * are met: 9*0dbe859dSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 10*0dbe859dSJohn Baldwin * notice, this list of conditions and the following disclaimer. 11*0dbe859dSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 12*0dbe859dSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 13*0dbe859dSJohn Baldwin * documentation and/or other materials provided with the distribution. 14*0dbe859dSJohn Baldwin * 15*0dbe859dSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*0dbe859dSJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*0dbe859dSJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*0dbe859dSJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*0dbe859dSJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*0dbe859dSJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*0dbe859dSJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*0dbe859dSJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*0dbe859dSJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*0dbe859dSJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*0dbe859dSJohn Baldwin * SUCH DAMAGE. 26*0dbe859dSJohn Baldwin */ 27*0dbe859dSJohn Baldwin 28*0dbe859dSJohn Baldwin #include <sys/cdefs.h> 29*0dbe859dSJohn Baldwin __FBSDID("$FreeBSD$"); 30*0dbe859dSJohn Baldwin 31*0dbe859dSJohn Baldwin /* 32*0dbe859dSJohn Baldwin * Support APIs for Host to PCI bridge drivers and drivers that 33*0dbe859dSJohn Baldwin * provide PCI domains. 34*0dbe859dSJohn Baldwin */ 35*0dbe859dSJohn Baldwin 36*0dbe859dSJohn Baldwin #include <sys/types.h> 37*0dbe859dSJohn Baldwin #include <sys/bus.h> 38*0dbe859dSJohn Baldwin #include <sys/rman.h> 39*0dbe859dSJohn Baldwin 40*0dbe859dSJohn Baldwin #include <dev/pci/pcireg.h> 41*0dbe859dSJohn Baldwin #include <dev/pci/pcivar.h> 42*0dbe859dSJohn Baldwin #include <dev/pci/pcib_private.h> 43*0dbe859dSJohn Baldwin 44*0dbe859dSJohn Baldwin /* 45*0dbe859dSJohn Baldwin * Try to read the bus number of a host-PCI bridge using appropriate config 46*0dbe859dSJohn Baldwin * registers. 47*0dbe859dSJohn Baldwin */ 48*0dbe859dSJohn Baldwin int 49*0dbe859dSJohn Baldwin host_pcib_get_busno(pci_read_config_fn read_config, int bus, int slot, int func, 50*0dbe859dSJohn Baldwin uint8_t *busnum) 51*0dbe859dSJohn Baldwin { 52*0dbe859dSJohn Baldwin uint32_t id; 53*0dbe859dSJohn Baldwin 54*0dbe859dSJohn Baldwin id = read_config(bus, slot, func, PCIR_DEVVENDOR, 4); 55*0dbe859dSJohn Baldwin if (id == 0xffffffff) 56*0dbe859dSJohn Baldwin return (0); 57*0dbe859dSJohn Baldwin 58*0dbe859dSJohn Baldwin switch (id) { 59*0dbe859dSJohn Baldwin case 0x12258086: 60*0dbe859dSJohn Baldwin /* Intel 824?? */ 61*0dbe859dSJohn Baldwin /* XXX This is a guess */ 62*0dbe859dSJohn Baldwin /* *busnum = read_config(bus, slot, func, 0x41, 1); */ 63*0dbe859dSJohn Baldwin *busnum = bus; 64*0dbe859dSJohn Baldwin break; 65*0dbe859dSJohn Baldwin case 0x84c48086: 66*0dbe859dSJohn Baldwin /* Intel 82454KX/GX (Orion) */ 67*0dbe859dSJohn Baldwin *busnum = read_config(bus, slot, func, 0x4a, 1); 68*0dbe859dSJohn Baldwin break; 69*0dbe859dSJohn Baldwin case 0x84ca8086: 70*0dbe859dSJohn Baldwin /* 71*0dbe859dSJohn Baldwin * For the 450nx chipset, there is a whole bundle of 72*0dbe859dSJohn Baldwin * things pretending to be host bridges. The MIOC will 73*0dbe859dSJohn Baldwin * be seen first and isn't really a pci bridge (the 74*0dbe859dSJohn Baldwin * actual busses are attached to the PXB's). We need to 75*0dbe859dSJohn Baldwin * read the registers of the MIOC to figure out the 76*0dbe859dSJohn Baldwin * bus numbers for the PXB channels. 77*0dbe859dSJohn Baldwin * 78*0dbe859dSJohn Baldwin * Since the MIOC doesn't have a pci bus attached, we 79*0dbe859dSJohn Baldwin * pretend it wasn't there. 80*0dbe859dSJohn Baldwin */ 81*0dbe859dSJohn Baldwin return (0); 82*0dbe859dSJohn Baldwin case 0x84cb8086: 83*0dbe859dSJohn Baldwin switch (slot) { 84*0dbe859dSJohn Baldwin case 0x12: 85*0dbe859dSJohn Baldwin /* Intel 82454NX PXB#0, Bus#A */ 86*0dbe859dSJohn Baldwin *busnum = read_config(bus, 0x10, func, 0xd0, 1); 87*0dbe859dSJohn Baldwin break; 88*0dbe859dSJohn Baldwin case 0x13: 89*0dbe859dSJohn Baldwin /* Intel 82454NX PXB#0, Bus#B */ 90*0dbe859dSJohn Baldwin *busnum = read_config(bus, 0x10, func, 0xd1, 1) + 1; 91*0dbe859dSJohn Baldwin break; 92*0dbe859dSJohn Baldwin case 0x14: 93*0dbe859dSJohn Baldwin /* Intel 82454NX PXB#1, Bus#A */ 94*0dbe859dSJohn Baldwin *busnum = read_config(bus, 0x10, func, 0xd3, 1); 95*0dbe859dSJohn Baldwin break; 96*0dbe859dSJohn Baldwin case 0x15: 97*0dbe859dSJohn Baldwin /* Intel 82454NX PXB#1, Bus#B */ 98*0dbe859dSJohn Baldwin *busnum = read_config(bus, 0x10, func, 0xd4, 1) + 1; 99*0dbe859dSJohn Baldwin break; 100*0dbe859dSJohn Baldwin } 101*0dbe859dSJohn Baldwin break; 102*0dbe859dSJohn Baldwin 103*0dbe859dSJohn Baldwin /* ServerWorks -- vendor 0x1166 */ 104*0dbe859dSJohn Baldwin case 0x00051166: 105*0dbe859dSJohn Baldwin case 0x00061166: 106*0dbe859dSJohn Baldwin case 0x00081166: 107*0dbe859dSJohn Baldwin case 0x00091166: 108*0dbe859dSJohn Baldwin case 0x00101166: 109*0dbe859dSJohn Baldwin case 0x00111166: 110*0dbe859dSJohn Baldwin case 0x00171166: 111*0dbe859dSJohn Baldwin case 0x01011166: 112*0dbe859dSJohn Baldwin case 0x010f1014: 113*0dbe859dSJohn Baldwin case 0x01101166: 114*0dbe859dSJohn Baldwin case 0x02011166: 115*0dbe859dSJohn Baldwin case 0x02251166: 116*0dbe859dSJohn Baldwin case 0x03021014: 117*0dbe859dSJohn Baldwin *busnum = read_config(bus, slot, func, 0x44, 1); 118*0dbe859dSJohn Baldwin break; 119*0dbe859dSJohn Baldwin 120*0dbe859dSJohn Baldwin /* Compaq/HP -- vendor 0x0e11 */ 121*0dbe859dSJohn Baldwin case 0x60100e11: 122*0dbe859dSJohn Baldwin *busnum = read_config(bus, slot, func, 0xc8, 1); 123*0dbe859dSJohn Baldwin break; 124*0dbe859dSJohn Baldwin default: 125*0dbe859dSJohn Baldwin /* Don't know how to read bus number. */ 126*0dbe859dSJohn Baldwin return 0; 127*0dbe859dSJohn Baldwin } 128*0dbe859dSJohn Baldwin 129*0dbe859dSJohn Baldwin return 1; 130*0dbe859dSJohn Baldwin } 131