pci.c revision 26186
1/* 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $Id: pci.c,v 1.72 1997/05/26 15:08:34 se Exp $ 27 * 28 */ 29 30#include "pci.h" 31#if NPCI > 0 32 33#include <stddef.h> 34 35#include <sys/types.h> 36#include <sys/param.h> 37#include <sys/time.h> 38#include <sys/systm.h> 39#include <sys/malloc.h> 40#include <sys/fcntl.h> 41#include <sys/conf.h> 42#include <sys/kernel.h> 43#ifdef DEVFS 44#include <sys/devfsext.h> 45#endif /* DEVFS */ 46 47#include <vm/vm.h> 48#include <vm/pmap.h> 49 50#include <pci/pcireg.h> 51#include <pci/pcivar.h> 52#include <pci/pci_ioctl.h> 53 54/* return highest PCI bus number known to be used, or -1 if none */ 55 56static int 57pci_bushigh(void) 58{ 59 if (pci_cfgopen() == 0) 60 return (-1); 61 return (0); 62} 63 64/* return base address of memory or port map */ 65 66static int 67pci_mapbase(unsigned mapreg) 68{ 69 int mask = 0x03; 70 if ((mapreg & 0x01) == 0) 71 mask = 0x0f; 72 return (mapreg & ~mask); 73} 74 75/* return map type of memory or port map */ 76 77static int 78pci_maptype(unsigned mapreg) 79{ 80 static u_int8_t maptype[0x10] = { 81 PCI_MAPMEM, PCI_MAPPORT, 82 PCI_MAPMEM, 0, 83 PCI_MAPMEM, PCI_MAPPORT, 84 0, 0, 85 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT, 86 PCI_MAPMEM|PCI_MAPMEMP, 0, 87 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT, 88 0, 0, 89 }; 90 91 return maptype[mapreg & 0x0f]; 92} 93 94/* return log2 of map size decoded for memory or port map */ 95 96static int 97pci_mapsize(unsigned testval) 98{ 99 int ln2size; 100 101 testval = pci_mapbase(testval); 102 ln2size = 32; 103 while ((testval & 0x80000000) != 0) 104 { 105 ln2size--; 106 testval <<= 1; 107 } 108 return (ln2size); 109} 110 111/* return log2 of address range supported by map register */ 112 113static int 114pci_maprange(unsigned mapreg) 115{ 116 int ln2range = 0; 117 switch (mapreg & 0x07) { 118 case 0x00: 119 case 0x01: 120 case 0x05: 121 ln2range = 32; 122 break; 123 case 0x02: 124 ln2range = 20; 125 break; 126 case 0x04: 127 ln2range = 64; 128 break; 129 } 130 return (ln2range); 131} 132 133/* extract map parameters into newly allocated array of pcimap structures */ 134 135static pcimap * 136pci_readmaps(pcicfgregs *cfg, int maxmaps) 137{ 138 int i; 139 pcimap *map; 140 int map64 = 0; 141 142 while (maxmaps > 0 143 && pci_cfgread(cfg, PCIR_MAPS + (maxmaps -1) *4, 4) == 0) 144 maxmaps--; 145 146 map = malloc(maxmaps * sizeof (pcimap), M_DEVBUF, M_WAITOK); 147 if (map != NULL) { 148 bzero(map, sizeof(pcimap) * maxmaps); 149 150 for (i = 0; i < maxmaps; i++) { 151 int reg = PCIR_MAPS + i*4; 152 u_int32_t base; 153 u_int32_t testval; 154 155 base = pci_cfgread(cfg, reg, 4); 156 157 if (map64 == 0) { 158 pci_cfgwrite(cfg, reg, 0xffffffff, 4); 159 testval = pci_cfgread(cfg, reg, 4); 160 pci_cfgwrite(cfg, reg, base, 4); 161 162 map[i].base = pci_mapbase(base); 163 map[i].type = pci_maptype(base); 164 map[i].ln2size = pci_mapsize(testval); 165 map[i].ln2range = pci_maprange(testval); 166 map64 = map[i].ln2range == 64; 167 } else { 168 /* only fill in base, other fields are 0 */ 169 map[i].base = base; 170 map64 = 0; 171 } 172 if (map[i].type == 0) { 173 /* 174 * This indicates, that some config space register 175 * was mistaken to contain a map, while it in fact 176 * contains unrelated information! 177 * Ignore this map and all that might have been 178 * expected to follow ... 179 */ 180 maxmaps = i; 181 } 182 } 183 cfg->nummaps = maxmaps; 184 } 185 return (map); 186} 187 188/* adjust some values from PCI 1.0 devices to match 2.0 standards ... */ 189 190static void 191pci_fixancient(pcicfgregs *cfg) 192{ 193 if (cfg->hdrtype != 0) 194 return; 195 196 /* PCI to PCI bridges use header type 1 */ 197 if (cfg->class == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI) 198 cfg->hdrtype = 1; 199} 200 201/* read config data specific to header type 1 device (PCI to PCI bridge) */ 202 203static void * 204pci_readppb(pcicfgregs *cfg) 205{ 206 pcih1cfgregs *p; 207 208 p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK); 209 if (p == NULL) 210 return (NULL); 211 212 bzero(p, sizeof *p); 213 214 p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2); 215 p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2); 216 217 p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1); 218 219 p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2), 220 pci_cfgread(cfg, PCIR_IOBASEL_1, 1)); 221 p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2), 222 pci_cfgread(cfg, PCIR_IOLIMITL_1, 1)); 223 224 p->membase = PCI_PPBMEMBASE (0, 225 pci_cfgread(cfg, PCIR_MEMBASE_1, 2)); 226 p->memlimit = PCI_PPBMEMLIMIT (0, 227 pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2)); 228 229 p->pmembase = PCI_PPBMEMBASE ( 230 (pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4), 231 pci_cfgread(cfg, PCIR_PMBASEL_1, 2)); 232 233 p->pmemlimit = PCI_PPBMEMLIMIT ( 234 (pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4), 235 pci_cfgread(cfg, PCIR_PMLIMITL_1, 2)); 236 return (p); 237} 238 239/* read config data specific to header type 2 device (PCI to CardBus bridge) */ 240 241static void * 242pci_readpcb(pcicfgregs *cfg) 243{ 244 pcih2cfgregs *p; 245 246 p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK); 247 if (p == NULL) 248 return (NULL); 249 250 bzero(p, sizeof *p); 251 252 p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2); 253 p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2); 254 255 p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1); 256 257 p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4); 258 p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4); 259 p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4); 260 p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4); 261 262 p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4); 263 p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4); 264 p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4); 265 p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4); 266 267 p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4); 268 return p; 269} 270 271/* extract header type specific config data */ 272 273static void 274pci_hdrtypedata(pcicfgregs *cfg) 275{ 276 switch (cfg->hdrtype) { 277 case 0: 278 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_0, 2); 279 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_0, 2); 280 cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_0); 281 break; 282 case 1: 283 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_1, 2); 284 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_1, 2); 285 cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_1, 1); 286 cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1); 287 cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_1); 288 cfg->hdrspec = pci_readppb(cfg); 289 break; 290 case 2: 291 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_2, 2); 292 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_2, 2); 293 cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_2, 1); 294 cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1); 295 cfg->map = pci_readmaps(cfg, PCI_MAXMAPS_2); 296 cfg->hdrspec = pci_readpcb(cfg); 297 break; 298 } 299} 300 301/* read configuration header into pcicfgrect structure */ 302 303static pcicfgregs * 304pci_readcfg(pcicfgregs *probe) 305{ 306 pcicfgregs *cfg = NULL; 307 308 if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) { 309 cfg = malloc(sizeof (pcicfgregs), M_DEVBUF, M_WAITOK); 310 if (cfg == NULL) 311 return (cfg); 312 313 bzero(cfg, sizeof *cfg); 314 315 cfg->bus = probe->bus; 316 cfg->slot = probe->slot; 317 cfg->func = probe->func; 318 cfg->parent = probe->parent; 319 320 cfg->vendor = pci_cfgread(cfg, PCIR_VENDOR, 2); 321 cfg->device = pci_cfgread(cfg, PCIR_DEVICE, 2); 322 cfg->cmdreg = pci_cfgread(cfg, PCIR_COMMAND, 2); 323 cfg->statreg = pci_cfgread(cfg, PCIR_STATUS, 2); 324 cfg->class = pci_cfgread(cfg, PCIR_CLASS, 1); 325 cfg->subclass = pci_cfgread(cfg, PCIR_SUBCLASS, 1); 326 cfg->progif = pci_cfgread(cfg, PCIR_PROGIF, 1); 327 cfg->revid = pci_cfgread(cfg, PCIR_REVID, 1); 328 cfg->hdrtype = pci_cfgread(cfg, PCIR_HEADERTYPE, 1); 329 cfg->cachelnsz = pci_cfgread(cfg, PCIR_CACHELNSZ, 1); 330 cfg->lattimer = pci_cfgread(cfg, PCIR_LATTIMER, 1); 331 cfg->intpin = pci_cfgread(cfg, PCIR_INTPIN, 1); 332 cfg->intline = pci_cfgread(cfg, PCIR_INTLINE, 1); 333 334#ifdef APIC_IO 335 if (cfg->intline && (cfg->intline != 0xff)) { 336 u_char airq = 0xff; 337 u_char rirq = 0xff; 338 339 airq = get_pci_apic_irq(cfg->bus, 340 cfg->slot, cfg->intpin); 341 342 if (airq != 0xff) { /* APIC IRQ exists */ 343 rirq = cfg->intline; /* 're-directed' IRQ */ 344 cfg->intline = airq; /* use APIC IRQ */ 345 pci_cfgwrite(cfg, PCIR_INTLINE, airq, 1); 346 undirect_pci_irq(rirq); 347 } 348 } 349#endif /* APIC_IO */ 350 351 cfg->mingnt = pci_cfgread(cfg, PCIR_MINGNT, 1); 352 cfg->maxlat = pci_cfgread(cfg, PCIR_MAXLAT, 1); 353 354 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; 355 cfg->hdrtype &= ~PCIM_MFDEV; 356 357 pci_fixancient(cfg); 358 pci_hdrtypedata(cfg); 359 } 360 return (cfg); 361} 362 363/* free pcicfgregs structure and all depending data structures */ 364 365static int 366pci_freecfg(pcicfgregs *cfg) 367{ 368 if (cfg->hdrspec != NULL) 369 free(cfg->hdrspec, M_DEVBUF); 370 if (cfg->map != NULL) 371 free(cfg->map, M_DEVBUF); 372 free(cfg, M_DEVBUF); 373 return (0); 374} 375 376static void 377pci_addcfg(pcicfgregs *cfg) 378{ 379#ifdef PCI_DEBUG 380 if (bootverbose) { 381 int i; 382 printf("new pci: vendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 383 cfg->vendor, cfg->device, cfg->revid); 384 printf("\t cmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", 385 cfg->cmdreg, cfg->statreg, cfg->cachelnsz); 386 printf("\t class=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", 387 cfg->class, cfg->subclass, cfg->progif, cfg->hdrtype, cfg->mfdev); 388 printf("\t lattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n", 389 cfg->lattimer, cfg->lattimer * 30, 390 cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250); 391 392 if (cfg->intpin > 0) 393 printf("\t intpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline); 394 395 for (i = 0; i < cfg->nummaps; i++) { 396 pcimap *m = &cfg->map[i]; 397 printf("\t map[%d]: type %x, range %2d, base %08x, size %2d\n", 398 i, m->type, m->ln2range, m->base, m->ln2size); 399 } 400 } 401#endif /* PCI_DEBUG */ 402 pci_drvattach(cfg); /* XXX currently defined in pci_compat.c */ 403} 404 405/* return pointer to device that is a bridge to this bus */ 406 407static pcicfgregs * 408pci_bridgeto(int bus) 409{ 410 return (NULL); /* XXX not yet implemented */ 411} 412 413/* scan one PCI bus for devices */ 414 415static int 416pci_probebus(int bus) 417{ 418 pcicfgregs probe; 419 int bushigh = bus; 420 421 bzero(&probe, sizeof probe); 422 probe.parent = pci_bridgeto(bus); 423 probe.bus = bus; 424 for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { 425 int pcifunchigh = 0; 426 for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) { 427 pcicfgregs *cfg = pci_readcfg(&probe); 428 if (cfg != NULL) { 429 if (cfg->mfdev) 430 pcifunchigh = 7; 431 432 if (bushigh < cfg->subordinatebus) 433 bushigh = cfg->subordinatebus; 434 435 pci_addcfg(cfg); 436 cfg = NULL; /* we don't own this anymore ... */ 437 } 438 } 439 } 440 return (bushigh); 441} 442 443/* scan a PCI bus tree reached through one PCI attachment point */ 444 445int 446pci_probe(pciattach *parent) 447{ 448 int bushigh; 449 int bus = 0; 450 451 bushigh = pci_bushigh(); 452 while (bus <= bushigh) { 453 int newbushigh; 454 455 printf("Probing for devices on PCI bus %d:\n", bus); 456 newbushigh = pci_probebus(bus); 457 458 if (bushigh < newbushigh) 459 bushigh = newbushigh; 460 bus++; 461 } 462 return (bushigh); 463} 464 465/* 466 * This is the user interface to PCI configuration space. 467 */ 468 469static int 470pci_open(dev_t dev, int oflags, int devtype, struct proc *p) 471{ 472 if ((oflags & FWRITE) && securelevel > 0) { 473 return EPERM; 474 } 475 return 0; 476} 477 478static int 479pci_close(dev_t dev, int flag, int devtype, struct proc *p) 480{ 481 return 0; 482} 483 484static int 485pci_ioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) 486{ 487 struct pci_conf_io *cio; 488 struct pci_io *io; 489 size_t iolen; 490 int error; 491 492 if (cmd != PCIOCGETCONF && !(flag & FWRITE)) 493 return EPERM; 494 495 switch(cmd) { 496 case PCIOCGETCONF: 497#ifdef NOTYET 498static struct pci_conf *pci_dev_list; 499static unsigned pci_dev_list_count; 500static unsigned pci_dev_list_size; 501 502 cio = (struct pci_conf_io *)data; 503 iolen = min(cio->pci_len, 504 pci_dev_list_count * sizeof(struct pci_conf)); 505 cio->pci_len = pci_dev_list_count * sizeof(struct pci_conf); 506 507 error = copyout(pci_dev_list, cio->pci_buf, iolen); 508#else 509 error = ENODEV; 510#endif 511 break; 512 513 case PCIOCREAD: 514 io = (struct pci_io *)data; 515 switch(io->pi_width) { 516 pcicfgregs probe; 517 case 4: 518 case 2: 519 case 1: 520 probe.bus = io->pi_sel.pc_bus; 521 probe.slot = io->pi_sel.pc_dev; 522 probe.func = io->pi_sel.pc_func; 523 io->pi_data = pci_cfgread(&probe, 524 io->pi_reg, io->pi_width); 525 error = 0; 526 break; 527 default: 528 error = ENODEV; 529 break; 530 } 531 break; 532 533 case PCIOCWRITE: 534 io = (struct pci_io *)data; 535 switch(io->pi_width) { 536 pcicfgregs probe; 537 case 4: 538 case 2: 539 case 1: 540 probe.bus = io->pi_sel.pc_bus; 541 probe.slot = io->pi_sel.pc_dev; 542 probe.func = io->pi_sel.pc_func; 543 pci_cfgwrite(&probe, 544 io->pi_reg, io->pi_data, io->pi_width); 545 error = 0; 546 break; 547 default: 548 error = ENODEV; 549 break; 550 } 551 break; 552 553 default: 554 error = ENOTTY; 555 break; 556 } 557 558 return (error); 559} 560 561#define PCI_CDEV 78 562 563static struct cdevsw pcicdev = { 564 pci_open, pci_close, noread, nowrite, pci_ioctl, nostop, noreset, 565 nodevtotty, noselect, nommap, nostrategy, "pci", 0, PCI_CDEV 566}; 567 568#ifdef DEVFS 569static void *pci_devfs_token; 570#endif 571 572static void 573pci_cdevinit(void *dummy) 574{ 575 dev_t dev; 576 577 dev = makedev(PCI_CDEV, 0); 578 cdevsw_add(&dev, &pcicdev, NULL); 579#ifdef DEVFS 580 pci_devfs_token = devfs_add_devswf(&pcicdev, 0, DV_CHR, 581 UID_ROOT, GID_WHEEL, 0644, "pci"); 582#endif 583} 584 585SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL); 586 587#endif /* NPCI > 0 */ 588