1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * PCI configuration space access routines 29 */ 30 31 #include <sys/systm.h> 32 #include <sys/psw.h> 33 #include <sys/bootconf.h> 34 #include <sys/reboot.h> 35 #include <sys/pci_impl.h> 36 #include <sys/pci_cfgspace.h> 37 #include <sys/pci_cfgspace_impl.h> 38 #if defined(__xpv) 39 #include <sys/hypervisor.h> 40 int pci_max_nbus = 0xFE; 41 #endif 42 43 44 int pci_bios_cfg_type = PCI_MECHANISM_UNKNOWN; 45 int pci_bios_maxbus; 46 int pci_bios_mech; 47 int pci_bios_vers; 48 49 /* 50 * These two variables can be used to force a configuration mechanism or 51 * to force which function is used to probe for the presence of the PCI bus. 52 */ 53 int PCI_CFG_TYPE = 0; 54 int PCI_PROBE_TYPE = 0; 55 56 /* 57 * These function pointers lead to the actual implementation routines 58 * for configuration space access. Normally they lead to either the 59 * pci_mech1_* or pci_mech2_* routines, but they can also lead to 60 * routines that work around chipset bugs. 61 */ 62 uint8_t (*pci_getb_func)(int bus, int dev, int func, int reg); 63 uint16_t (*pci_getw_func)(int bus, int dev, int func, int reg); 64 uint32_t (*pci_getl_func)(int bus, int dev, int func, int reg); 65 void (*pci_putb_func)(int bus, int dev, int func, int reg, uint8_t val); 66 void (*pci_putw_func)(int bus, int dev, int func, int reg, uint16_t val); 67 void (*pci_putl_func)(int bus, int dev, int func, int reg, uint32_t val); 68 69 /* 70 * Internal routines 71 */ 72 static int pci_check(void); 73 74 #if !defined(__xpv) 75 static int pci_check_bios(void); 76 static int pci_get_cfg_type(void); 77 #endif 78 79 /* all config-space access routines share this one... */ 80 kmutex_t pcicfg_mutex; 81 82 /* ..except Orion and Neptune, which have to have their own */ 83 kmutex_t pcicfg_chipset_mutex; 84 85 void 86 pci_cfgspace_init(void) 87 { 88 mutex_init(&pcicfg_mutex, NULL, MUTEX_SPIN, 89 (ddi_iblock_cookie_t)ipltospl(15)); 90 mutex_init(&pcicfg_chipset_mutex, NULL, MUTEX_SPIN, 91 (ddi_iblock_cookie_t)ipltospl(15)); 92 if (!pci_check()) { 93 mutex_destroy(&pcicfg_mutex); 94 mutex_destroy(&pcicfg_chipset_mutex); 95 } 96 } 97 98 /* 99 * This code determines if this system supports PCI and which 100 * type of configuration access method is used 101 */ 102 103 static int 104 pci_check(void) 105 { 106 /* 107 * Only do this once. NB: If this is not a PCI system, and we 108 * get called twice, we can't detect it and will probably die 109 * horribly when we try to ask the BIOS whether PCI is present. 110 * This code is safe *ONLY* during system startup when the 111 * BIOS is still available. 112 */ 113 if (pci_bios_cfg_type != PCI_MECHANISM_UNKNOWN) 114 return (TRUE); 115 116 #if defined(__xpv) 117 /* 118 * only support PCI config mechanism 1 in i86xpv. This should be fine 119 * since the other ones are workarounds for old broken H/W which won't 120 * be supported in i86xpv anyway. 121 */ 122 if (DOMAIN_IS_INITDOMAIN(xen_info)) { 123 pci_bios_cfg_type = PCI_MECHANISM_1; 124 pci_getb_func = pci_mech1_getb; 125 pci_getw_func = pci_mech1_getw; 126 pci_getl_func = pci_mech1_getl; 127 pci_putb_func = pci_mech1_putb; 128 pci_putw_func = pci_mech1_putw; 129 pci_putl_func = pci_mech1_putl; 130 131 /* 132 * Since we can't get the BIOS info in i86xpv, we will do an 133 * exhaustive search of all PCI buses. We have to do this until 134 * we start using the PCI information in ACPI. 135 */ 136 pci_bios_maxbus = pci_max_nbus; 137 } 138 139 return (TRUE); 140 #else /* !__xpv */ 141 142 pci_bios_cfg_type = pci_check_bios(); 143 144 if (pci_bios_cfg_type == PCI_MECHANISM_NONE) 145 pci_bios_cfg_type = PCI_MECHANISM_1; /* default to mech 1 */ 146 147 switch (pci_get_cfg_type()) { 148 case PCI_MECHANISM_1: 149 if (pci_is_broken_orion()) { 150 pci_getb_func = pci_orion_getb; 151 pci_getw_func = pci_orion_getw; 152 pci_getl_func = pci_orion_getl; 153 pci_putb_func = pci_orion_putb; 154 pci_putw_func = pci_orion_putw; 155 pci_putl_func = pci_orion_putl; 156 } else { 157 pci_getb_func = pci_mech1_getb; 158 pci_getw_func = pci_mech1_getw; 159 pci_getl_func = pci_mech1_getl; 160 pci_putb_func = pci_mech1_putb; 161 pci_putw_func = pci_mech1_putw; 162 pci_putl_func = pci_mech1_putl; 163 } 164 break; 165 166 case PCI_MECHANISM_2: 167 if (pci_check_neptune()) { 168 /* 169 * The BIOS for some systems with the Intel 170 * Neptune chipset seem to default to #2 even 171 * though the chipset can do #1. Override 172 * the BIOS so that MP systems will work 173 * correctly. 174 */ 175 176 pci_getb_func = pci_neptune_getb; 177 pci_getw_func = pci_neptune_getw; 178 pci_getl_func = pci_neptune_getl; 179 pci_putb_func = pci_neptune_putb; 180 pci_putw_func = pci_neptune_putw; 181 pci_putl_func = pci_neptune_putl; 182 } else { 183 pci_getb_func = pci_mech2_getb; 184 pci_getw_func = pci_mech2_getw; 185 pci_getl_func = pci_mech2_getl; 186 pci_putb_func = pci_mech2_putb; 187 pci_putw_func = pci_mech2_putw; 188 pci_putl_func = pci_mech2_putl; 189 } 190 break; 191 192 default: 193 return (FALSE); 194 } 195 196 return (TRUE); 197 #endif /* __xpv */ 198 } 199 200 #if !defined(__xpv) 201 202 static int 203 pci_check_bios(void) 204 { 205 struct bop_regs regs; 206 uint32_t carryflag; 207 uint16_t ax, dx; 208 209 bzero(®s, sizeof (regs)); 210 regs.eax.word.ax = (PCI_FUNCTION_ID << 8) | PCI_BIOS_PRESENT; 211 212 BOP_DOINT(bootops, 0x1a, ®s); 213 carryflag = regs.eflags & PS_C; 214 ax = regs.eax.word.ax; 215 dx = regs.edx.word.dx; 216 217 /* the carry flag must not be set */ 218 if (carryflag != 0) 219 return (PCI_MECHANISM_NONE); 220 221 if (dx != ('P' | 'C'<<8)) 222 return (PCI_MECHANISM_NONE); 223 224 /* ah (the high byte of ax) must be zero */ 225 if ((ax & 0xff00) != 0) 226 return (PCI_MECHANISM_NONE); 227 228 pci_bios_mech = (ax & 0x3); 229 pci_bios_vers = regs.ebx.word.bx; 230 pci_bios_maxbus = (regs.ecx.word.cx & 0xff); 231 232 switch (pci_bios_mech) { 233 default: /* ?!? */ 234 case 0: /* supports neither? */ 235 return (PCI_MECHANISM_NONE); 236 237 case 1: 238 case 3: /* supports both */ 239 return (PCI_MECHANISM_1); 240 241 case 2: 242 return (PCI_MECHANISM_2); 243 } 244 } 245 246 static int 247 pci_get_cfg_type(void) 248 { 249 /* Check to see if the config mechanism has been set in /etc/system */ 250 switch (PCI_CFG_TYPE) { 251 default: 252 case 0: 253 break; 254 case 1: 255 return (PCI_MECHANISM_1); 256 case 2: 257 return (PCI_MECHANISM_2); 258 case -1: 259 return (PCI_MECHANISM_NONE); 260 } 261 262 /* call one of the PCI detection algorithms */ 263 switch (PCI_PROBE_TYPE) { 264 default: 265 case 0: 266 /* From pci_check() and pci_check_bios() */ 267 return (pci_bios_cfg_type); 268 case -1: 269 return (PCI_MECHANISM_NONE); 270 } 271 } 272 273 #endif /* __xpv */ 274