1 /* $OpenBSD: pci.c,v 1.22 2001/08/25 12:48:35 art Exp $ */ 2 /* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1995, 1996 Christopher G. Demetriou. All rights reserved. 6 * Copyright (c) 1994 Charles Hannum. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Charles Hannum. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * PCI bus autoconfiguration. 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/device.h> 41 42 #include <dev/pci/pcireg.h> 43 #include <dev/pci/pcivar.h> 44 #include <dev/pci/pcidevs.h> 45 46 int pcimatch __P((struct device *, void *, void *)); 47 void pciattach __P((struct device *, struct device *, void *)); 48 49 #ifdef USER_PCICONF 50 struct pci_softc { 51 struct device sc_dev; 52 pci_chipset_tag_t sc_pc; 53 }; 54 #endif 55 56 struct cfattach pci_ca = { 57 #ifndef USER_PCICONF 58 sizeof(struct device), pcimatch, pciattach 59 #else 60 sizeof(struct pci_softc), pcimatch, pciattach 61 #endif 62 }; 63 64 struct cfdriver pci_cd = { 65 NULL, "pci", DV_DULL 66 }; 67 68 int pciprint __P((void *, const char *)); 69 int pcisubmatch __P((struct device *, void *, void *)); 70 71 /* 72 * Callback so that ISA/EISA bridges can attach their child busses 73 * after PCI configuration is done. 74 * 75 * This works because: 76 * (1) there can be at most one ISA/EISA bridge per PCI bus, and 77 * (2) any ISA/EISA bridges must be attached to primary PCI 78 * busses (i.e. bus zero). 79 * 80 * That boils down to: there can only be one of these outstanding 81 * at a time, it is cleared when configuring PCI bus 0 before any 82 * subdevices have been found, and it is run after all subdevices 83 * of PCI bus 0 have been found. 84 * 85 * This is needed because there are some (legacy) PCI devices which 86 * can show up as ISA/EISA devices as well (the prime example of which 87 * are VGA controllers). If you attach ISA from a PCI-ISA/EISA bridge, 88 * and the bridge is seen before the video board is, the board can show 89 * up as an ISA device, and that can (bogusly) complicate the PCI device's 90 * attach code, or make the PCI device not be properly attached at all. 91 */ 92 static void (*pci_isa_bridge_callback) __P((void *)); 93 static void *pci_isa_bridge_callback_arg; 94 95 int 96 pcimatch(parent, match, aux) 97 struct device *parent; 98 void *match, *aux; 99 { 100 struct cfdata *cf = match; 101 struct pcibus_attach_args *pba = aux; 102 103 if (strcmp(pba->pba_busname, cf->cf_driver->cd_name)) 104 return (0); 105 106 /* Check the locators */ 107 if (cf->pcibuscf_bus != PCIBUS_UNK_BUS && 108 cf->pcibuscf_bus != pba->pba_bus) 109 return (0); 110 111 /* sanity */ 112 if (pba->pba_bus < 0 || pba->pba_bus > 255) 113 return (0); 114 115 /* 116 * XXX check other (hardware?) indicators 117 */ 118 119 return 1; 120 } 121 122 void 123 pciattach(parent, self, aux) 124 struct device *parent, *self; 125 void *aux; 126 { 127 struct pcibus_attach_args *pba = aux; 128 bus_space_tag_t iot, memt; 129 pci_chipset_tag_t pc; 130 int bus, device, maxndevs, function, nfunctions; 131 #ifdef USER_PCICONF 132 struct pci_softc *sc = (struct pci_softc *)self; 133 #endif 134 #ifdef __PCI_BUS_DEVORDER 135 char devs[32]; 136 int i; 137 #endif 138 #ifdef __PCI_DEV_FUNCORDER 139 char funcs[8]; 140 int j; 141 #endif 142 143 pci_attach_hook(parent, self, pba); 144 printf("\n"); 145 146 iot = pba->pba_iot; 147 memt = pba->pba_memt; 148 pc = pba->pba_pc; 149 bus = pba->pba_bus; 150 maxndevs = pci_bus_maxdevs(pc, bus); 151 152 #ifdef USER_PCICONF 153 sc->sc_pc = pba->pba_pc; 154 #endif 155 156 if (bus == 0) 157 pci_isa_bridge_callback = NULL; 158 159 #ifdef __PCI_BUS_DEVORDER 160 pci_bus_devorder(pc, bus, devs); 161 for (i = 0; (device = devs[i]) < 32 && device >= 0; i++) { 162 #else 163 for (device = 0; device < maxndevs; device++) { 164 #endif 165 pcitag_t tag; 166 pcireg_t id, class, intr, bhlcr; 167 struct pci_attach_args pa; 168 int pin; 169 170 tag = pci_make_tag(pc, bus, device, 0); 171 id = pci_conf_read(pc, tag, PCI_ID_REG); 172 173 /* Invalid vendor ID value? */ 174 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) 175 continue; 176 /* XXX Not invalid, but we've done this ~forever. */ 177 if (PCI_VENDOR(id) == 0) 178 continue; 179 180 bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); 181 nfunctions = PCI_HDRTYPE_MULTIFN(bhlcr) ? 8 : 1; 182 183 #ifdef __PCI_DEV_FUNCORDER 184 pci_dev_funcorder(pc, bus, device, funcs); 185 for (j = 0; (function = funcs[j]) < nfunctions && 186 function >= 0; j++) { 187 #else 188 for (function = 0; function < nfunctions; function++) { 189 #endif 190 tag = pci_make_tag(pc, bus, device, function); 191 id = pci_conf_read(pc, tag, PCI_ID_REG); 192 193 /* Invalid vendor ID value? */ 194 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) 195 continue; 196 /* XXX Not invalid, but we've done this ~forever. */ 197 if (PCI_VENDOR(id) == 0) 198 continue; 199 200 class = pci_conf_read(pc, tag, PCI_CLASS_REG); 201 intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 202 203 pa.pa_iot = iot; 204 pa.pa_memt = memt; 205 pa.pa_dmat = pba->pba_dmat; 206 pa.pa_pc = pc; 207 pa.pa_device = device; 208 pa.pa_function = function; 209 pa.pa_bus = bus; 210 pa.pa_tag = tag; 211 pa.pa_id = id; 212 pa.pa_class = class; 213 214 /* This is a simplification of the NetBSD code. 215 We don't support turning off I/O or memory 216 on broken hardware. <csapuntz@stanford.edu> */ 217 pa.pa_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED; 218 #ifdef __i386__ 219 /* 220 * on i386 we really need to know the device tag 221 * and not the pci bridge tag, in intr_map 222 * to be able to program the device and the 223 * pci interrupt router. 224 */ 225 pa.pa_intrtag = tag; 226 pa.pa_intrswiz = 0; 227 #else 228 if (bus == 0) { 229 pa.pa_intrswiz = 0; 230 pa.pa_intrtag = tag; 231 } else { 232 pa.pa_intrswiz = pba->pba_intrswiz + device; 233 pa.pa_intrtag = pba->pba_intrtag; 234 } 235 #endif 236 pin = PCI_INTERRUPT_PIN(intr); 237 if (pin == PCI_INTERRUPT_PIN_NONE) { 238 /* no interrupt */ 239 pa.pa_intrpin = 0; 240 } else { 241 /* 242 * swizzle it based on the number of 243 * busses we're behind and our device 244 * number. 245 */ 246 pa.pa_intrpin = /* XXX */ 247 ((pin + pa.pa_intrswiz - 1) % 4) + 1; 248 } 249 pa.pa_intrline = PCI_INTERRUPT_LINE(intr); 250 251 config_found_sm(self, &pa, pciprint, pcisubmatch); 252 } 253 } 254 255 if (bus == 0 && pci_isa_bridge_callback != NULL) 256 (*pci_isa_bridge_callback)(pci_isa_bridge_callback_arg); 257 } 258 259 int 260 pciprint(aux, pnp) 261 void *aux; 262 const char *pnp; 263 { 264 register struct pci_attach_args *pa = aux; 265 char devinfo[256]; 266 267 if (pnp) { 268 pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo); 269 printf("%s at %s", devinfo, pnp); 270 } 271 printf(" dev %d function %d", pa->pa_device, pa->pa_function); 272 if (!pnp) { 273 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); 274 printf(" %s", devinfo); 275 } 276 277 return (UNCONF); 278 } 279 280 int 281 pcisubmatch(parent, match, aux) 282 struct device *parent; 283 void *match, *aux; 284 { 285 struct cfdata *cf = match; 286 struct pci_attach_args *pa = aux; 287 int success; 288 289 if (cf->pcicf_dev != PCI_UNK_DEV && 290 cf->pcicf_dev != pa->pa_device) 291 return 0; 292 if (cf->pcicf_function != PCI_UNK_FUNCTION && 293 cf->pcicf_function != pa->pa_function) 294 return 0; 295 296 success = (*cf->cf_attach->ca_match)(parent, match, aux); 297 298 /* My Dell BIOS does not enable certain non-critical PCI devices 299 for IO and memory cycles (e.g. network card). This is 300 the generic approach to fixing this problem. Basically, if 301 we support the card, then we enable its IO cycles. 302 */ 303 if (success) { 304 u_int32_t csr = pci_conf_read(pa->pa_pc, pa->pa_tag, 305 PCI_COMMAND_STATUS_REG); 306 307 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 308 csr | PCI_COMMAND_MASTER_ENABLE | 309 PCI_COMMAND_IO_ENABLE | 310 PCI_COMMAND_MEM_ENABLE); 311 } 312 313 return (success); 314 } 315 316 void 317 set_pci_isa_bridge_callback(fn, arg) 318 void (*fn) __P((void *)); 319 void *arg; 320 { 321 322 if (pci_isa_bridge_callback != NULL) 323 panic("set_pci_isa_bridge_callback"); 324 pci_isa_bridge_callback = fn; 325 pci_isa_bridge_callback_arg = arg; 326 } 327 328 int 329 pci_get_capability(pc, tag, capid, offset, value) 330 pci_chipset_tag_t pc; 331 pcitag_t tag; 332 int capid; 333 int *offset; 334 pcireg_t *value; 335 { 336 pcireg_t reg; 337 unsigned int ofs; 338 339 reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 340 if (!(reg & PCI_STATUS_CAPLIST_SUPPORT)) 341 return (0); 342 343 ofs = PCI_CAPLIST_PTR(pci_conf_read(pc, tag, PCI_CAPLISTPTR_REG)); 344 while (ofs != 0) { 345 #ifdef DIAGNOSTIC 346 if ((ofs & 3) || (ofs < 0x40)) 347 panic("pci_get_capability"); 348 #endif 349 reg = pci_conf_read(pc, tag, ofs); 350 if (PCI_CAPLIST_CAP(reg) == capid) { 351 if (offset) 352 *offset = ofs; 353 if (value) 354 *value = reg; 355 return (1); 356 } 357 ofs = PCI_CAPLIST_NEXT(reg); 358 } 359 360 return (0); 361 } 362 363 #ifdef USER_PCICONF 364 /* 365 * This is the user interface to PCI configuration space. 366 */ 367 368 #include <sys/pciio.h> 369 #include <sys/fcntl.h> 370 371 #ifdef DEBUG 372 #define PCIDEBUG(x) printf x 373 #else 374 #define PCIDEBUG(x) 375 #endif 376 377 378 int pciopen __P((dev_t dev, int oflags, int devtype, struct proc *p)); 379 int pciclose __P((dev_t dev, int flag, int devtype, struct proc *p)); 380 int pciioctl __P((dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)); 381 382 int 383 pciopen(dev_t dev, int oflags, int devtype, struct proc *p) 384 { 385 PCIDEBUG(("pciopen ndevs: %d\n" , pci_cd.cd_ndevs)); 386 387 if ((oflags & FWRITE) && securelevel > 0) { 388 return EPERM; 389 } 390 return 0; 391 } 392 393 int 394 pciclose(dev_t dev, int flag, int devtype, struct proc *p) 395 { 396 PCIDEBUG(("pciclose\n")); 397 return 0; 398 } 399 400 int 401 pciioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 402 { 403 struct pci_io *io; 404 int error; 405 pcitag_t tag; 406 struct pci_softc *pci; 407 pci_chipset_tag_t pc; 408 409 io = (struct pci_io *)data; 410 411 PCIDEBUG(("pciioctl cmd %s", cmd == PCIOCREAD ? "pciocread" 412 : cmd == PCIOCWRITE ? "pciocwrite" : "unknown")); 413 PCIDEBUG((" bus %d dev %d func %d reg %x\n", io->pi_sel.pc_bus, 414 io->pi_sel.pc_dev, io->pi_sel.pc_func, io->pi_reg)); 415 416 if (io->pi_sel.pc_bus >= pci_cd.cd_ndevs) { 417 error = ENXIO; 418 goto done; 419 } 420 pci = pci_cd.cd_devs[io->pi_sel.pc_bus]; 421 if (pci != NULL) { 422 pc = pci->sc_pc; 423 } else { 424 error = ENXIO; 425 goto done; 426 } 427 #ifdef __i386__ 428 /* The i386 pci_make_tag function can panic if called with wrong 429 args, try to avoid that */ 430 if (io->pi_sel.pc_bus >= 256 || 431 io->pi_sel.pc_dev >= pci_bus_maxdevs(pc, io->pi_sel.pc_bus) || 432 io->pi_sel.pc_func >= 8) { 433 error = EINVAL; 434 goto done; 435 } 436 #endif 437 438 tag = pci_make_tag(pc, io->pi_sel.pc_bus, io->pi_sel.pc_dev, 439 io->pi_sel.pc_func); 440 441 switch(cmd) { 442 case PCIOCGETCONF: 443 error = ENODEV; 444 break; 445 446 case PCIOCREAD: 447 switch(io->pi_width) { 448 case 4: 449 /* Make sure the register is properly aligned */ 450 if (io->pi_reg & 0x3) 451 return EINVAL; 452 io->pi_data = pci_conf_read(pc, tag, io->pi_reg); 453 error = 0; 454 break; 455 default: 456 error = ENODEV; 457 break; 458 } 459 break; 460 461 case PCIOCWRITE: 462 if (!(flag & FWRITE)) 463 return EPERM; 464 465 switch(io->pi_width) { 466 case 4: 467 /* Make sure the register is properly aligned */ 468 if (io->pi_reg & 0x3) 469 return EINVAL; 470 pci_conf_write(pc, tag, io->pi_reg, io->pi_data); 471 break; 472 default: 473 error = ENODEV; 474 break; 475 } 476 break; 477 478 default: 479 error = ENOTTY; 480 break; 481 } 482 done: 483 return (error); 484 } 485 486 #endif 487