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 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * PCI configuration space access routines 31 */ 32 33 #include <sys/systm.h> 34 #include <sys/cmn_err.h> 35 #include <sys/psw.h> 36 #include <sys/bootconf.h> 37 #include <sys/reboot.h> 38 #include <sys/pci_impl.h> 39 #include <sys/pci_cfgspace.h> 40 #include <sys/pci_cfgspace_impl.h> 41 42 int pci_bios_cfg_type = PCI_MECHANISM_UNKNOWN; 43 int pci_bios_nbus; 44 int pci_bios_mech; 45 int pci_bios_vers; 46 47 /* 48 * These two variables can be used to force a configuration mechanism or 49 * to force which function is used to probe for the presence of the PCI bus. 50 */ 51 int PCI_CFG_TYPE = 0; 52 int PCI_PROBE_TYPE = 0; 53 54 /* 55 * These function pointers lead to the actual implementation routines 56 * for configuration space access. Normally they lead to either the 57 * pci_mech1_* or pci_mech2_* routines, but they can also lead to 58 * routines that work around chipset bugs. 59 */ 60 uint8_t (*pci_getb_func)(int bus, int dev, int func, int reg); 61 uint16_t (*pci_getw_func)(int bus, int dev, int func, int reg); 62 uint32_t (*pci_getl_func)(int bus, int dev, int func, int reg); 63 void (*pci_putb_func)(int bus, int dev, int func, int reg, uint8_t val); 64 void (*pci_putw_func)(int bus, int dev, int func, int reg, uint16_t val); 65 void (*pci_putl_func)(int bus, int dev, int func, int reg, uint32_t val); 66 67 /* 68 * Internal routines 69 */ 70 static int pci_check(void); 71 static int pci_check_bios(void); 72 static int pci_get_cfg_type(void); 73 74 /* all config-space access routines share this one... */ 75 kmutex_t pcicfg_mutex; 76 77 /* ..except Orion and Neptune, which have to have their own */ 78 kmutex_t pcicfg_chipset_mutex; 79 80 void 81 pci_cfgspace_init(void) 82 { 83 mutex_init(&pcicfg_mutex, NULL, MUTEX_DEFAULT, 0); 84 mutex_init(&pcicfg_chipset_mutex, NULL, MUTEX_DEFAULT, 0); 85 if (!pci_check()) { 86 mutex_destroy(&pcicfg_mutex); 87 mutex_destroy(&pcicfg_chipset_mutex); 88 } 89 } 90 91 /* 92 * This code determines if this system supports PCI and which 93 * type of configuration access method is used 94 */ 95 96 static int 97 pci_check(void) 98 { 99 /* 100 * Only do this once. NB: If this is not a PCI system, and we 101 * get called twice, we can't detect it and will probably die 102 * horribly when we try to ask the BIOS whether PCI is present. 103 * This code is safe *ONLY* during system startup when the 104 * BIOS is still available. 105 */ 106 if (pci_bios_cfg_type != PCI_MECHANISM_UNKNOWN) 107 return (TRUE); 108 109 pci_bios_cfg_type = pci_check_bios(); 110 111 if (pci_bios_cfg_type == PCI_MECHANISM_NONE) 112 return (FALSE); 113 114 switch (pci_get_cfg_type()) { 115 case PCI_MECHANISM_1: 116 if (pci_is_broken_orion()) { 117 pci_getb_func = pci_orion_getb; 118 pci_getw_func = pci_orion_getw; 119 pci_getl_func = pci_orion_getl; 120 pci_putb_func = pci_orion_putb; 121 pci_putw_func = pci_orion_putw; 122 pci_putl_func = pci_orion_putl; 123 } else { 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 break; 132 133 case PCI_MECHANISM_2: 134 if (pci_check_neptune()) { 135 /* 136 * The BIOS for some systems with the Intel 137 * Neptune chipset seem to default to #2 even 138 * though the chipset can do #1. Override 139 * the BIOS so that MP systems will work 140 * correctly. 141 */ 142 143 pci_getb_func = pci_neptune_getb; 144 pci_getw_func = pci_neptune_getw; 145 pci_getl_func = pci_neptune_getl; 146 pci_putb_func = pci_neptune_putb; 147 pci_putw_func = pci_neptune_putw; 148 pci_putl_func = pci_neptune_putl; 149 } else { 150 pci_getb_func = pci_mech2_getb; 151 pci_getw_func = pci_mech2_getw; 152 pci_getl_func = pci_mech2_getl; 153 pci_putb_func = pci_mech2_putb; 154 pci_putw_func = pci_mech2_putw; 155 pci_putl_func = pci_mech2_putl; 156 } 157 break; 158 159 default: 160 /* Not sure what to do here. */ 161 cmn_err(CE_WARN, "pci: Unknown configuration type"); 162 return (FALSE); 163 } 164 165 return (TRUE); 166 } 167 168 169 static int 170 pci_check_bios(void) 171 { 172 struct bop_regs regs; 173 uint32_t carryflag; 174 uint16_t ax, dx; 175 176 bzero(®s, sizeof (regs)); 177 regs.eax.word.ax = (PCI_FUNCTION_ID << 8) | PCI_BIOS_PRESENT; 178 179 BOP_DOINT(bootops, 0x1a, ®s); 180 carryflag = regs.eflags & PS_C; 181 ax = regs.eax.word.ax; 182 dx = regs.edx.word.dx; 183 184 /* the carry flag must not be set */ 185 if (carryflag != 0) 186 return (PCI_MECHANISM_NONE); 187 188 if (dx != ('P' | 'C'<<8)) 189 return (PCI_MECHANISM_NONE); 190 191 /* ah (the high byte of ax) must be zero */ 192 if ((ax & 0xff00) != 0) 193 return (PCI_MECHANISM_NONE); 194 195 pci_bios_mech = (ax & 0x3); 196 pci_bios_vers = regs.ebx.word.bx; 197 pci_bios_nbus = (regs.ecx.word.cx & 0xff); 198 if (boothowto & RB_VERBOSE) 199 cmn_err(CE_CONT, "PCI probe mech %x, version 0x%x, # busses %d", 200 pci_bios_mech, pci_bios_vers, pci_bios_nbus); 201 202 switch (pci_bios_mech) { 203 default: /* ?!? */ 204 case 0: /* supports neither? */ 205 return (PCI_MECHANISM_NONE); 206 207 case 1: 208 case 3: /* supports both */ 209 return (PCI_MECHANISM_1); 210 211 case 2: 212 return (PCI_MECHANISM_2); 213 } 214 } 215 216 static int 217 pci_get_cfg_type(void) 218 { 219 /* Check to see if the config mechanism has been set in /etc/system */ 220 switch (PCI_CFG_TYPE) { 221 default: 222 case 0: 223 break; 224 case 1: 225 return (PCI_MECHANISM_1); 226 case 2: 227 return (PCI_MECHANISM_2); 228 case -1: 229 return (PCI_MECHANISM_NONE); 230 } 231 232 /* call one of the PCI detection algorithms */ 233 switch (PCI_PROBE_TYPE) { 234 default: 235 case 0: 236 /* From pci_check() and pci_check_bios() */ 237 return (pci_bios_cfg_type); 238 case -1: 239 return (PCI_MECHANISM_NONE); 240 } 241 } 242