1 /* 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000, BSDi 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice unmodified, this list of conditions, and the following 12 * 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 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 * 30 */ 31 32 #include <sys/param.h> /* XXX trim includes */ 33 #include <sys/systm.h> 34 #include <sys/bus.h> 35 #include <sys/kernel.h> 36 #include <sys/module.h> 37 #include <sys/malloc.h> 38 #include <vm/vm.h> 39 #include <vm/pmap.h> 40 #include <machine/md_var.h> 41 #include <pci/pcivar.h> 42 #include <pci/pcireg.h> 43 #include <isa/isavar.h> 44 #include <machine/nexusvar.h> 45 #include <machine/pci_cfgreg.h> 46 #include <machine/segments.h> 47 #include <machine/pc/bios.h> 48 49 #include "pcib_if.h" 50 51 static int cfgmech; 52 static int devmax; 53 static int usebios; 54 55 static int pci_cfgintr_unique(struct PIR_entry *pe, int pin); 56 static int pci_cfgintr_linked(struct PIR_entry *pe, int pin); 57 static int pci_cfgintr_search(struct PIR_entry *pe, int bus, int device, int matchpin, int pin); 58 static int pci_cfgintr_virgin(struct PIR_entry *pe, int pin); 59 60 static int pcibios_cfgread(int bus, int slot, int func, int reg, int bytes); 61 static void pcibios_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes); 62 static int pcibios_cfgopen(void); 63 static int pcireg_cfgread(int bus, int slot, int func, int reg, int bytes); 64 static void pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes); 65 static int pcireg_cfgopen(void); 66 67 static struct PIR_table *pci_route_table; 68 static int pci_route_count; 69 70 /* 71 * Initialise access to PCI configuration space 72 */ 73 int 74 pci_cfgregopen(void) 75 { 76 static int opened = 0; 77 u_long sigaddr; 78 static struct PIR_table *pt; 79 u_int8_t ck, *cv; 80 int i; 81 82 if (opened) 83 return(1); 84 85 if (pcibios_cfgopen() != 0) { 86 usebios = 1; 87 } else if (pcireg_cfgopen() != 0) { 88 usebios = 0; 89 } else { 90 return(0); 91 } 92 93 /* 94 * Look for the interrupt routing table. 95 */ 96 /* XXX use PCI BIOS if it's available */ 97 98 if ((pt == NULL) && ((sigaddr = bios_sigsearch(0, "$PIR", 4, 16, 0)) != 0)) { 99 pt = (struct PIR_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); 100 for (cv = (u_int8_t *)pt, ck = 0, i = 0; i < (pt->pt_header.ph_length); i++) { 101 ck += cv[i]; 102 } 103 if (ck == 0) { 104 pci_route_table = pt; 105 pci_route_count = (pt->pt_header.ph_length - sizeof(struct PIR_header)) / sizeof(struct PIR_entry); 106 printf("Using $PIR table, %d entries at %p\n", pci_route_count, pci_route_table); 107 } 108 } 109 110 opened = 1; 111 return(1); 112 } 113 114 /* 115 * Read configuration space register 116 */ 117 u_int32_t 118 pci_cfgregread(int bus, int slot, int func, int reg, int bytes) 119 { 120 return(usebios ? 121 pcibios_cfgread(bus, slot, func, reg, bytes) : 122 pcireg_cfgread(bus, slot, func, reg, bytes)); 123 } 124 125 /* 126 * Write configuration space register 127 */ 128 void 129 pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes) 130 { 131 return(usebios ? 132 pcibios_cfgwrite(bus, slot, func, reg, data, bytes) : 133 pcireg_cfgwrite(bus, slot, func, reg, data, bytes)); 134 } 135 136 /* 137 * Route a PCI interrupt 138 * 139 * XXX we don't do anything "right" with the function number in the PIR table 140 * (because the consumer isn't currently passing it in). We don't care 141 * anyway, due to the way PCI interrupts are assigned. 142 */ 143 int 144 pci_cfgintr(int bus, int device, int pin) 145 { 146 struct PIR_entry *pe; 147 int i, irq; 148 struct bios_regs args; 149 150 if ((bus < 0) || (bus > 255) || (device < 0) || (device > 255) || 151 (pin < 1) || (pin > 4)) 152 return(255); 153 154 /* 155 * Scan the entry table for a contender 156 */ 157 for (i = 0, pe = &pci_route_table->pt_entry[0]; i < pci_route_count; i++, pe++) { 158 if ((bus != pe->pe_bus) || (device != pe->pe_device)) 159 continue; 160 161 irq = pci_cfgintr_unique(pe, pin); 162 if (irq == 255) 163 irq = pci_cfgintr_linked(pe, pin); 164 if (irq == 255) 165 irq = pci_cfgintr_virgin(pe, pin); 166 167 if (irq == 255) 168 break; 169 170 171 /* 172 * Ask the BIOS to route the interrupt 173 */ 174 args.eax = PCIBIOS_ROUTE_INTERRUPT; 175 args.ebx = (bus << 8) | (device << 3); 176 args.ecx = (irq << 8) | (0xa + pin - 1); /* pin value is 0xa - 0xd */ 177 bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); 178 179 /* 180 * XXX if it fails, we should try to smack the router hardware directly 181 */ 182 183 printf("pci_cfgintr: %d:%d INT%c routed to irq %d\n", 184 bus, device, 'A' + pin - 1, irq); 185 return(irq); 186 } 187 188 printf("pci_cfgintr: can't route an interrupt to %d:%d INT%c\n", bus, device, 'A' + pin - 1); 189 return(255); 190 } 191 192 /* 193 * Look to see if the routing table claims this pin is uniquely routed. 194 */ 195 static int 196 pci_cfgintr_unique(struct PIR_entry *pe, int pin) 197 { 198 int irq; 199 200 if (powerof2(pe->pe_intpin[pin - 1].irqs)) { 201 irq = ffs(pe->pe_intpin[pin - 1].irqs) - 1; 202 printf("pci_cfgintr_unique: hard-routed to irq %d\n", irq); 203 return(irq); 204 } 205 return(255); 206 } 207 208 /* 209 * Look for another device which shares the same link byte and 210 * already has a unique IRQ, or which has had one routed already. 211 */ 212 static int 213 pci_cfgintr_linked(struct PIR_entry *pe, int pin) 214 { 215 struct PIR_entry *oe; 216 struct PIR_intpin *pi; 217 int i, j, irq; 218 219 /* 220 * Scan table slots. 221 */ 222 for (i = 0, oe = &pci_route_table->pt_entry[0]; i < pci_route_count; i++, oe++) { 223 224 /* scan interrupt pins */ 225 for (j = 0, pi = &oe->pe_intpin[0]; j < 4; j++, pi++) { 226 227 /* don't look at the entry we're trying to match with */ 228 if ((pe == oe) && (i == (pin - 1))) 229 continue; 230 231 /* compare link bytes */ 232 if (pi->link != pe->pe_intpin[pin - 1].link) 233 continue; 234 235 /* link destination mapped to a unique interrupt? */ 236 if (powerof2(pi->irqs)) { 237 irq = ffs(pi->irqs) - 1; 238 printf("pci_cfgintr_linked: linked (%x) to hard-routed irq %d\n", 239 pi->link, irq); 240 return(irq); 241 } 242 243 /* look for the real PCI device that matches this table entry */ 244 if ((irq = pci_cfgintr_search(pe, oe->pe_bus, oe->pe_device, j, pin)) != 255) 245 return(irq); 246 } 247 } 248 return(255); 249 } 250 251 /* 252 * Scan for the real PCI device at (bus)/(device) using intpin (matchpin) and 253 * see if it has already been assigned an interrupt. 254 */ 255 static int 256 pci_cfgintr_search(struct PIR_entry *pe, int bus, int device, int matchpin, int pin) 257 { 258 devclass_t pci_devclass; 259 device_t *pci_devices; 260 int pci_count; 261 device_t *pci_children; 262 int pci_childcount; 263 device_t *busp, *childp; 264 int i, j, irq; 265 266 /* 267 * Find all the PCI busses. 268 */ 269 pci_count = 0; 270 if ((pci_devclass = devclass_find("pci")) != NULL) 271 devclass_get_devices(pci_devclass, &pci_devices, &pci_count); 272 273 /* 274 * Scan all the PCI busses/devices looking for this one. 275 */ 276 for (i = 0, busp = pci_devices; i < pci_count; i++, busp++) { 277 pci_childcount = 0; 278 device_get_children(*busp, &pci_children, &pci_childcount); 279 280 for (j = 0, childp = pci_children; j < pci_childcount; j++, childp++) { 281 if ((pci_get_bus(*childp) == bus) && 282 (pci_get_slot(*childp) == device) && 283 (pci_get_intpin(*childp) == matchpin) && 284 ((irq = pci_get_irq(*childp)) != 255)) { 285 printf("pci_cfgintr_search: linked (%x) to configured irq %d at %d:%d:%d\n", 286 irq, pe->pe_intpin[pin - 1].link, 287 pci_get_bus(*childp), pci_get_slot(*childp), pci_get_function(*childp)); 288 return(irq); 289 } 290 } 291 } 292 return(255); 293 } 294 295 /* 296 * Pick a suitable IRQ from those listed as routable to this device. 297 */ 298 static int 299 pci_cfgintr_virgin(struct PIR_entry *pe, int pin) 300 { 301 int irq, ibit; 302 303 /* first scan the set of PCI-only interrupts and see if any of these are routable */ 304 for (irq = 0; irq < 16; irq++) { 305 ibit = (1 << irq); 306 307 /* can we use this interrupt? */ 308 if ((pci_route_table->pt_header.ph_pci_irqs & ibit) && 309 (pe->pe_intpin[pin - 1].irqs & ibit)) { 310 printf("pci_cfgintr_virgin: using routable PCI-only interrupt %d\n", irq); 311 return(irq); 312 } 313 } 314 315 /* life is tough, so just pick an interrupt */ 316 for (irq = 0; irq < 16; irq++) { 317 ibit = (1 << irq); 318 319 if (pe->pe_intpin[pin - 1].irqs & ibit) { 320 printf("pci_cfgintr_virgin: using routable interrupt %d\n", irq); 321 return(irq); 322 } 323 } 324 return(255); 325 } 326 327 328 /* 329 * Config space access using BIOS functions 330 */ 331 static int 332 pcibios_cfgread(int bus, int slot, int func, int reg, int bytes) 333 { 334 struct bios_regs args; 335 u_int mask; 336 337 switch(bytes) { 338 case 1: 339 args.eax = PCIBIOS_READ_CONFIG_BYTE; 340 mask = 0xff; 341 break; 342 case 2: 343 args.eax = PCIBIOS_READ_CONFIG_WORD; 344 mask = 0xffff; 345 break; 346 case 4: 347 args.eax = PCIBIOS_READ_CONFIG_DWORD; 348 mask = 0xffffffff; 349 break; 350 default: 351 return(-1); 352 } 353 args.ebx = (bus << 8) | (slot << 3) | func; 354 args.edi = reg; 355 bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); 356 /* check call results? */ 357 return(args.ecx & mask); 358 } 359 360 static void 361 pcibios_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) 362 { 363 struct bios_regs args; 364 365 switch(bytes) { 366 case 1: 367 args.eax = PCIBIOS_WRITE_CONFIG_BYTE; 368 break; 369 case 2: 370 args.eax = PCIBIOS_WRITE_CONFIG_WORD; 371 break; 372 case 4: 373 args.eax = PCIBIOS_WRITE_CONFIG_DWORD; 374 break; 375 default: 376 return; 377 } 378 args.ebx = (bus << 8) | (slot << 3) | func; 379 args.ecx = data; 380 args.edi = reg; 381 bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); 382 } 383 384 /* 385 * Determine whether there is a PCI BIOS present 386 */ 387 static int 388 pcibios_cfgopen(void) 389 { 390 /* check for a found entrypoint */ 391 return(PCIbios.entry != 0); 392 } 393 394 /* 395 * Configuration space access using direct register operations 396 */ 397 398 /* enable configuration space accesses and return data port address */ 399 static int 400 pci_cfgenable(unsigned bus, unsigned slot, unsigned func, int reg, int bytes) 401 { 402 int dataport = 0; 403 404 if (bus <= PCI_BUSMAX 405 && slot < devmax 406 && func <= PCI_FUNCMAX 407 && reg <= PCI_REGMAX 408 && bytes != 3 409 && (unsigned) bytes <= 4 410 && (reg & (bytes -1)) == 0) { 411 switch (cfgmech) { 412 case 1: 413 outl(CONF1_ADDR_PORT, (1 << 31) 414 | (bus << 16) | (slot << 11) 415 | (func << 8) | (reg & ~0x03)); 416 dataport = CONF1_DATA_PORT + (reg & 0x03); 417 break; 418 case 2: 419 outb(CONF2_ENABLE_PORT, 0xf0 | (func << 1)); 420 outb(CONF2_FORWARD_PORT, bus); 421 dataport = 0xc000 | (slot << 8) | reg; 422 break; 423 } 424 } 425 return (dataport); 426 } 427 428 /* disable configuration space accesses */ 429 static void 430 pci_cfgdisable(void) 431 { 432 switch (cfgmech) { 433 case 1: 434 outl(CONF1_ADDR_PORT, 0); 435 break; 436 case 2: 437 outb(CONF2_ENABLE_PORT, 0); 438 outb(CONF2_FORWARD_PORT, 0); 439 break; 440 } 441 } 442 443 static int 444 pcireg_cfgread(int bus, int slot, int func, int reg, int bytes) 445 { 446 int data = -1; 447 int port; 448 449 port = pci_cfgenable(bus, slot, func, reg, bytes); 450 451 if (port != 0) { 452 switch (bytes) { 453 case 1: 454 data = inb(port); 455 break; 456 case 2: 457 data = inw(port); 458 break; 459 case 4: 460 data = inl(port); 461 break; 462 } 463 pci_cfgdisable(); 464 } 465 return (data); 466 } 467 468 static void 469 pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) 470 { 471 int port; 472 473 port = pci_cfgenable(bus, slot, func, reg, bytes); 474 if (port != 0) { 475 switch (bytes) { 476 case 1: 477 outb(port, data); 478 break; 479 case 2: 480 outw(port, data); 481 break; 482 case 4: 483 outl(port, data); 484 break; 485 } 486 pci_cfgdisable(); 487 } 488 } 489 490 /* check whether the configuration mechanism has been correctly identified */ 491 static int 492 pci_cfgcheck(int maxdev) 493 { 494 u_char device; 495 496 if (bootverbose) 497 printf("pci_cfgcheck:\tdevice "); 498 499 for (device = 0; device < maxdev; device++) { 500 unsigned id, class, header; 501 if (bootverbose) 502 printf("%d ", device); 503 504 id = inl(pci_cfgenable(0, device, 0, 0, 4)); 505 if (id == 0 || id == -1) 506 continue; 507 508 class = inl(pci_cfgenable(0, device, 0, 8, 4)) >> 8; 509 if (bootverbose) 510 printf("[class=%06x] ", class); 511 if (class == 0 || (class & 0xf870ff) != 0) 512 continue; 513 514 header = inb(pci_cfgenable(0, device, 0, 14, 1)); 515 if (bootverbose) 516 printf("[hdr=%02x] ", header); 517 if ((header & 0x7e) != 0) 518 continue; 519 520 if (bootverbose) 521 printf("is there (id=%08x)\n", id); 522 523 pci_cfgdisable(); 524 return (1); 525 } 526 if (bootverbose) 527 printf("-- nothing found\n"); 528 529 pci_cfgdisable(); 530 return (0); 531 } 532 533 static int 534 pcireg_cfgopen(void) 535 { 536 unsigned long mode1res,oldval1; 537 unsigned char mode2res,oldval2; 538 539 oldval1 = inl(CONF1_ADDR_PORT); 540 541 if (bootverbose) { 542 printf("pci_open(1):\tmode 1 addr port (0x0cf8) is 0x%08lx\n", 543 oldval1); 544 } 545 546 if ((oldval1 & CONF1_ENABLE_MSK) == 0) { 547 548 cfgmech = 1; 549 devmax = 32; 550 551 outl(CONF1_ADDR_PORT, CONF1_ENABLE_CHK); 552 outb(CONF1_ADDR_PORT +3, 0); 553 mode1res = inl(CONF1_ADDR_PORT); 554 outl(CONF1_ADDR_PORT, oldval1); 555 556 if (bootverbose) 557 printf("pci_open(1a):\tmode1res=0x%08lx (0x%08lx)\n", 558 mode1res, CONF1_ENABLE_CHK); 559 560 if (mode1res) { 561 if (pci_cfgcheck(32)) 562 return (cfgmech); 563 } 564 565 outl(CONF1_ADDR_PORT, CONF1_ENABLE_CHK1); 566 mode1res = inl(CONF1_ADDR_PORT); 567 outl(CONF1_ADDR_PORT, oldval1); 568 569 if (bootverbose) 570 printf("pci_open(1b):\tmode1res=0x%08lx (0x%08lx)\n", 571 mode1res, CONF1_ENABLE_CHK1); 572 573 if ((mode1res & CONF1_ENABLE_MSK1) == CONF1_ENABLE_RES1) { 574 if (pci_cfgcheck(32)) 575 return (cfgmech); 576 } 577 } 578 579 oldval2 = inb(CONF2_ENABLE_PORT); 580 581 if (bootverbose) { 582 printf("pci_open(2):\tmode 2 enable port (0x0cf8) is 0x%02x\n", 583 oldval2); 584 } 585 586 if ((oldval2 & 0xf0) == 0) { 587 588 cfgmech = 2; 589 devmax = 16; 590 591 outb(CONF2_ENABLE_PORT, CONF2_ENABLE_CHK); 592 mode2res = inb(CONF2_ENABLE_PORT); 593 outb(CONF2_ENABLE_PORT, oldval2); 594 595 if (bootverbose) 596 printf("pci_open(2a):\tmode2res=0x%02x (0x%02x)\n", 597 mode2res, CONF2_ENABLE_CHK); 598 599 if (mode2res == CONF2_ENABLE_RES) { 600 if (bootverbose) 601 printf("pci_open(2a):\tnow trying mechanism 2\n"); 602 603 if (pci_cfgcheck(16)) 604 return (cfgmech); 605 } 606 } 607 608 cfgmech = 0; 609 devmax = 0; 610 return (cfgmech); 611 } 612 613