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 * Copyright (c) 2004, Scott Long <scottl@freebsd.org> 6 * 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 unmodified, this list of conditions, and the following 13 * disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include "opt_xbox.h" 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/bus.h> 38 #include <sys/lock.h> 39 #include <sys/mutex.h> 40 #include <sys/malloc.h> 41 #include <sys/queue.h> 42 #include <dev/pci/pcivar.h> 43 #include <dev/pci/pcireg.h> 44 #include <machine/pci_cfgreg.h> 45 #include <machine/pc/bios.h> 46 47 #include <vm/vm.h> 48 #include <vm/vm_param.h> 49 #include <vm/vm_kern.h> 50 #include <vm/vm_extern.h> 51 #include <vm/pmap.h> 52 #include <machine/pmap.h> 53 54 #ifdef XBOX 55 #include <machine/xbox.h> 56 #endif 57 58 #define PRVERB(a) do { \ 59 if (bootverbose) \ 60 printf a ; \ 61 } while(0) 62 63 #define PCIE_CACHE 8 64 struct pcie_cfg_elem { 65 TAILQ_ENTRY(pcie_cfg_elem) elem; 66 vm_offset_t vapage; 67 vm_paddr_t papage; 68 }; 69 70 enum { 71 CFGMECH_NONE = 0, 72 CFGMECH_1, 73 CFGMECH_2, 74 CFGMECH_PCIE, 75 }; 76 77 static TAILQ_HEAD(pcie_cfg_list, pcie_cfg_elem) pcie_list[MAXCPU]; 78 static uint64_t pcie_base; 79 static int pcie_minbus, pcie_maxbus; 80 static int cfgmech; 81 static int devmax; 82 static struct mtx pcicfg_mtx; 83 84 static int pcireg_cfgread(int bus, int slot, int func, int reg, int bytes); 85 static void pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes); 86 #ifndef XEN 87 static int pcireg_cfgopen(void); 88 #endif 89 static int pciereg_cfgread(int bus, unsigned slot, unsigned func, 90 unsigned reg, unsigned bytes); 91 static void pciereg_cfgwrite(int bus, unsigned slot, unsigned func, 92 unsigned reg, int data, unsigned bytes); 93 94 /* 95 * Some BIOS writers seem to want to ignore the spec and put 96 * 0 in the intline rather than 255 to indicate none. Some use 97 * numbers in the range 128-254 to indicate something strange and 98 * apparently undocumented anywhere. Assume these are completely bogus 99 * and map them to 255, which means "none". 100 */ 101 static __inline int 102 pci_i386_map_intline(int line) 103 { 104 if (line == 0 || line >= 128) 105 return (PCI_INVALID_IRQ); 106 return (line); 107 } 108 109 #ifndef XEN 110 static u_int16_t 111 pcibios_get_version(void) 112 { 113 struct bios_regs args; 114 115 if (PCIbios.ventry == 0) { 116 PRVERB(("pcibios: No call entry point\n")); 117 return (0); 118 } 119 args.eax = PCIBIOS_BIOS_PRESENT; 120 if (bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL))) { 121 PRVERB(("pcibios: BIOS_PRESENT call failed\n")); 122 return (0); 123 } 124 if (args.edx != 0x20494350) { 125 PRVERB(("pcibios: BIOS_PRESENT didn't return 'PCI ' in edx\n")); 126 return (0); 127 } 128 return (args.ebx & 0xffff); 129 } 130 #endif 131 132 /* 133 * Initialise access to PCI configuration space 134 */ 135 int 136 pci_cfgregopen(void) 137 { 138 #ifdef XEN 139 return (0); 140 #else 141 static int opened = 0; 142 uint64_t pciebar; 143 u_int16_t vid, did; 144 u_int16_t v; 145 146 if (opened) 147 return (1); 148 149 if (cfgmech == CFGMECH_NONE && pcireg_cfgopen() == 0) 150 return (0); 151 152 v = pcibios_get_version(); 153 if (v > 0) 154 PRVERB(("pcibios: BIOS version %x.%02x\n", (v & 0xff00) >> 8, 155 v & 0xff)); 156 mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN); 157 opened = 1; 158 159 /* $PIR requires PCI BIOS 2.10 or greater. */ 160 if (v >= 0x0210) 161 pci_pir_open(); 162 163 if (cfgmech == CFGMECH_PCIE) 164 return (1); 165 166 /* 167 * Grope around in the PCI config space to see if this is a 168 * chipset that is capable of doing memory-mapped config cycles. 169 * This also implies that it can do PCIe extended config cycles. 170 */ 171 172 /* Check for supported chipsets */ 173 vid = pci_cfgregread(0, 0, 0, PCIR_VENDOR, 2); 174 did = pci_cfgregread(0, 0, 0, PCIR_DEVICE, 2); 175 switch (vid) { 176 case 0x8086: 177 switch (did) { 178 case 0x3590: 179 case 0x3592: 180 /* Intel 7520 or 7320 */ 181 pciebar = pci_cfgregread(0, 0, 0, 0xce, 2) << 16; 182 pcie_cfgregopen(pciebar, 0, 255); 183 break; 184 case 0x2580: 185 case 0x2584: 186 case 0x2590: 187 /* Intel 915, 925, or 915GM */ 188 pciebar = pci_cfgregread(0, 0, 0, 0x48, 4); 189 pcie_cfgregopen(pciebar, 0, 255); 190 break; 191 } 192 } 193 194 return(1); 195 #endif 196 } 197 198 /* 199 * Read configuration space register 200 */ 201 u_int32_t 202 pci_cfgregread(int bus, int slot, int func, int reg, int bytes) 203 { 204 uint32_t line; 205 206 /* 207 * Some BIOS writers seem to want to ignore the spec and put 208 * 0 in the intline rather than 255 to indicate none. The rest of 209 * the code uses 255 as an invalid IRQ. 210 */ 211 if (reg == PCIR_INTLINE && bytes == 1) { 212 line = pcireg_cfgread(bus, slot, func, PCIR_INTLINE, 1); 213 return (pci_i386_map_intline(line)); 214 } 215 return (pcireg_cfgread(bus, slot, func, reg, bytes)); 216 } 217 218 /* 219 * Write configuration space register 220 */ 221 void 222 pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes) 223 { 224 225 pcireg_cfgwrite(bus, slot, func, reg, data, bytes); 226 } 227 228 /* 229 * Configuration space access using direct register operations 230 */ 231 232 /* enable configuration space accesses and return data port address */ 233 static int 234 pci_cfgenable(unsigned bus, unsigned slot, unsigned func, int reg, int bytes) 235 { 236 int dataport = 0; 237 238 #ifdef XBOX 239 if (arch_i386_is_xbox) { 240 /* 241 * The Xbox MCPX chipset is a derivative of the nForce 1 242 * chipset. It almost has the same bus layout; some devices 243 * cannot be used, because they have been removed. 244 */ 245 246 /* 247 * Devices 00:00.1 and 00:00.2 used to be memory controllers on 248 * the nForce chipset, but on the Xbox, using them will lockup 249 * the chipset. 250 */ 251 if (bus == 0 && slot == 0 && (func == 1 || func == 2)) 252 return dataport; 253 254 /* 255 * Bus 1 only contains a VGA controller at 01:00.0. When you try 256 * to probe beyond that device, you only get garbage, which 257 * could cause lockups. 258 */ 259 if (bus == 1 && (slot != 0 || func != 0)) 260 return dataport; 261 262 /* 263 * Bus 2 used to contain the AGP controller, but the Xbox MCPX 264 * doesn't have one. Probing it can cause lockups. 265 */ 266 if (bus >= 2) 267 return dataport; 268 } 269 #endif 270 271 if (bus <= PCI_BUSMAX 272 && slot < devmax 273 && func <= PCI_FUNCMAX 274 && reg <= PCI_REGMAX 275 && bytes != 3 276 && (unsigned) bytes <= 4 277 && (reg & (bytes - 1)) == 0) { 278 switch (cfgmech) { 279 case CFGMECH_1: 280 outl(CONF1_ADDR_PORT, (1 << 31) 281 | (bus << 16) | (slot << 11) 282 | (func << 8) | (reg & ~0x03)); 283 dataport = CONF1_DATA_PORT + (reg & 0x03); 284 break; 285 case CFGMECH_2: 286 outb(CONF2_ENABLE_PORT, 0xf0 | (func << 1)); 287 outb(CONF2_FORWARD_PORT, bus); 288 dataport = 0xc000 | (slot << 8) | reg; 289 break; 290 } 291 } 292 return (dataport); 293 } 294 295 /* disable configuration space accesses */ 296 static void 297 pci_cfgdisable(void) 298 { 299 switch (cfgmech) { 300 case CFGMECH_1: 301 /* 302 * Do nothing for the config mechanism 1 case. 303 * Writing a 0 to the address port can apparently 304 * confuse some bridges and cause spurious 305 * access failures. 306 */ 307 break; 308 case CFGMECH_2: 309 outb(CONF2_ENABLE_PORT, 0); 310 break; 311 } 312 } 313 314 static int 315 pcireg_cfgread(int bus, int slot, int func, int reg, int bytes) 316 { 317 int data = -1; 318 int port; 319 320 if (cfgmech == CFGMECH_PCIE) { 321 data = pciereg_cfgread(bus, slot, func, reg, bytes); 322 return (data); 323 } 324 325 mtx_lock_spin(&pcicfg_mtx); 326 port = pci_cfgenable(bus, slot, func, reg, bytes); 327 if (port != 0) { 328 switch (bytes) { 329 case 1: 330 data = inb(port); 331 break; 332 case 2: 333 data = inw(port); 334 break; 335 case 4: 336 data = inl(port); 337 break; 338 } 339 pci_cfgdisable(); 340 } 341 mtx_unlock_spin(&pcicfg_mtx); 342 return (data); 343 } 344 345 static void 346 pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) 347 { 348 int port; 349 350 if (cfgmech == CFGMECH_PCIE) { 351 pciereg_cfgwrite(bus, slot, func, reg, data, bytes); 352 return; 353 } 354 355 mtx_lock_spin(&pcicfg_mtx); 356 port = pci_cfgenable(bus, slot, func, reg, bytes); 357 if (port != 0) { 358 switch (bytes) { 359 case 1: 360 outb(port, data); 361 break; 362 case 2: 363 outw(port, data); 364 break; 365 case 4: 366 outl(port, data); 367 break; 368 } 369 pci_cfgdisable(); 370 } 371 mtx_unlock_spin(&pcicfg_mtx); 372 } 373 374 #ifndef XEN 375 /* check whether the configuration mechanism has been correctly identified */ 376 static int 377 pci_cfgcheck(int maxdev) 378 { 379 uint32_t id, class; 380 uint8_t header; 381 uint8_t device; 382 int port; 383 384 if (bootverbose) 385 printf("pci_cfgcheck:\tdevice "); 386 387 for (device = 0; device < maxdev; device++) { 388 if (bootverbose) 389 printf("%d ", device); 390 391 port = pci_cfgenable(0, device, 0, 0, 4); 392 id = inl(port); 393 if (id == 0 || id == 0xffffffff) 394 continue; 395 396 port = pci_cfgenable(0, device, 0, 8, 4); 397 class = inl(port) >> 8; 398 if (bootverbose) 399 printf("[class=%06x] ", class); 400 if (class == 0 || (class & 0xf870ff) != 0) 401 continue; 402 403 port = pci_cfgenable(0, device, 0, 14, 1); 404 header = inb(port); 405 if (bootverbose) 406 printf("[hdr=%02x] ", header); 407 if ((header & 0x7e) != 0) 408 continue; 409 410 if (bootverbose) 411 printf("is there (id=%08x)\n", id); 412 413 pci_cfgdisable(); 414 return (1); 415 } 416 if (bootverbose) 417 printf("-- nothing found\n"); 418 419 pci_cfgdisable(); 420 return (0); 421 } 422 423 static int 424 pcireg_cfgopen(void) 425 { 426 uint32_t mode1res, oldval1; 427 uint8_t mode2res, oldval2; 428 429 /* Check for type #1 first. */ 430 oldval1 = inl(CONF1_ADDR_PORT); 431 432 if (bootverbose) { 433 printf("pci_open(1):\tmode 1 addr port (0x0cf8) is 0x%08x\n", 434 oldval1); 435 } 436 437 cfgmech = CFGMECH_1; 438 devmax = 32; 439 440 outl(CONF1_ADDR_PORT, CONF1_ENABLE_CHK); 441 DELAY(1); 442 mode1res = inl(CONF1_ADDR_PORT); 443 outl(CONF1_ADDR_PORT, oldval1); 444 445 if (bootverbose) 446 printf("pci_open(1a):\tmode1res=0x%08x (0x%08lx)\n", mode1res, 447 CONF1_ENABLE_CHK); 448 449 if (mode1res) { 450 if (pci_cfgcheck(32)) 451 return (cfgmech); 452 } 453 454 outl(CONF1_ADDR_PORT, CONF1_ENABLE_CHK1); 455 mode1res = inl(CONF1_ADDR_PORT); 456 outl(CONF1_ADDR_PORT, oldval1); 457 458 if (bootverbose) 459 printf("pci_open(1b):\tmode1res=0x%08x (0x%08lx)\n", mode1res, 460 CONF1_ENABLE_CHK1); 461 462 if ((mode1res & CONF1_ENABLE_MSK1) == CONF1_ENABLE_RES1) { 463 if (pci_cfgcheck(32)) 464 return (cfgmech); 465 } 466 467 /* Type #1 didn't work, so try type #2. */ 468 oldval2 = inb(CONF2_ENABLE_PORT); 469 470 if (bootverbose) { 471 printf("pci_open(2):\tmode 2 enable port (0x0cf8) is 0x%02x\n", 472 oldval2); 473 } 474 475 if ((oldval2 & 0xf0) == 0) { 476 477 cfgmech = CFGMECH_2; 478 devmax = 16; 479 480 outb(CONF2_ENABLE_PORT, CONF2_ENABLE_CHK); 481 mode2res = inb(CONF2_ENABLE_PORT); 482 outb(CONF2_ENABLE_PORT, oldval2); 483 484 if (bootverbose) 485 printf("pci_open(2a):\tmode2res=0x%02x (0x%02x)\n", 486 mode2res, CONF2_ENABLE_CHK); 487 488 if (mode2res == CONF2_ENABLE_RES) { 489 if (bootverbose) 490 printf("pci_open(2a):\tnow trying mechanism 2\n"); 491 492 if (pci_cfgcheck(16)) 493 return (cfgmech); 494 } 495 } 496 497 /* Nothing worked, so punt. */ 498 cfgmech = CFGMECH_NONE; 499 devmax = 0; 500 return (cfgmech); 501 } 502 503 int 504 pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus) 505 { 506 struct pcie_cfg_list *pcielist; 507 struct pcie_cfg_elem *pcie_array, *elem; 508 #ifdef SMP 509 struct pcpu *pc; 510 #endif 511 vm_offset_t va; 512 int i; 513 514 if (minbus != 0) 515 return (0); 516 517 #ifndef PAE 518 if (base >= 0x100000000) { 519 if (bootverbose) 520 printf( 521 "PCI: Memory Mapped PCI configuration area base 0x%jx too high\n", 522 (uintmax_t)base); 523 return (0); 524 } 525 #endif 526 527 if (bootverbose) 528 printf("PCIe: Memory Mapped configuration base @ 0x%jx\n", 529 (uintmax_t)base); 530 531 #ifdef SMP 532 SLIST_FOREACH(pc, &cpuhead, pc_allcpu) 533 #endif 534 { 535 536 pcie_array = malloc(sizeof(struct pcie_cfg_elem) * PCIE_CACHE, 537 M_DEVBUF, M_NOWAIT); 538 if (pcie_array == NULL) 539 return (0); 540 541 va = kmem_alloc_nofault(kernel_map, PCIE_CACHE * PAGE_SIZE); 542 if (va == 0) { 543 free(pcie_array, M_DEVBUF); 544 return (0); 545 } 546 547 #ifdef SMP 548 pcielist = &pcie_list[pc->pc_cpuid]; 549 #else 550 pcielist = &pcie_list[0]; 551 #endif 552 TAILQ_INIT(pcielist); 553 for (i = 0; i < PCIE_CACHE; i++) { 554 elem = &pcie_array[i]; 555 elem->vapage = va + (i * PAGE_SIZE); 556 elem->papage = 0; 557 TAILQ_INSERT_HEAD(pcielist, elem, elem); 558 } 559 } 560 561 pcie_base = base; 562 pcie_minbus = minbus; 563 pcie_maxbus = maxbus; 564 cfgmech = CFGMECH_PCIE; 565 devmax = 32; 566 return (1); 567 } 568 #endif /* !XEN */ 569 570 #define PCIE_PADDR(bar, reg, bus, slot, func) \ 571 ((bar) | \ 572 (((bus) & 0xff) << 20) | \ 573 (((slot) & 0x1f) << 15) | \ 574 (((func) & 0x7) << 12) | \ 575 ((reg) & 0xfff)) 576 577 /* 578 * Find an element in the cache that matches the physical page desired, or 579 * create a new mapping from the least recently used element. 580 * A very simple LRU algorithm is used here, does it need to be more 581 * efficient? 582 */ 583 static __inline struct pcie_cfg_elem * 584 pciereg_findelem(vm_paddr_t papage) 585 { 586 struct pcie_cfg_list *pcielist; 587 struct pcie_cfg_elem *elem; 588 589 pcielist = &pcie_list[PCPU_GET(cpuid)]; 590 TAILQ_FOREACH(elem, pcielist, elem) { 591 if (elem->papage == papage) 592 break; 593 } 594 595 if (elem == NULL) { 596 elem = TAILQ_LAST(pcielist, pcie_cfg_list); 597 if (elem->papage != 0) { 598 pmap_kremove(elem->vapage); 599 invlpg(elem->vapage); 600 } 601 pmap_kenter(elem->vapage, papage); 602 elem->papage = papage; 603 } 604 605 if (elem != TAILQ_FIRST(pcielist)) { 606 TAILQ_REMOVE(pcielist, elem, elem); 607 TAILQ_INSERT_HEAD(pcielist, elem, elem); 608 } 609 return (elem); 610 } 611 612 static int 613 pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg, 614 unsigned bytes) 615 { 616 struct pcie_cfg_elem *elem; 617 volatile vm_offset_t va; 618 vm_paddr_t pa, papage; 619 int data = -1; 620 621 if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 || 622 func > PCI_FUNCMAX || reg >= 0x1000 || bytes > 4 || bytes == 3) 623 return (-1); 624 625 critical_enter(); 626 pa = PCIE_PADDR(pcie_base, reg, bus, slot, func); 627 papage = pa & ~PAGE_MASK; 628 elem = pciereg_findelem(papage); 629 va = elem->vapage | (pa & PAGE_MASK); 630 631 switch (bytes) { 632 case 4: 633 data = *(volatile uint32_t *)(va); 634 break; 635 case 2: 636 data = *(volatile uint16_t *)(va); 637 break; 638 case 1: 639 data = *(volatile uint8_t *)(va); 640 break; 641 } 642 643 critical_exit(); 644 return (data); 645 } 646 647 static void 648 pciereg_cfgwrite(int bus, unsigned slot, unsigned func, unsigned reg, int data, 649 unsigned bytes) 650 { 651 struct pcie_cfg_elem *elem; 652 volatile vm_offset_t va; 653 vm_paddr_t pa, papage; 654 655 if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 || 656 func > PCI_FUNCMAX || reg >= 0x1000) 657 return; 658 659 critical_enter(); 660 pa = PCIE_PADDR(pcie_base, reg, bus, slot, func); 661 papage = pa & ~PAGE_MASK; 662 elem = pciereg_findelem(papage); 663 va = elem->vapage | (pa & PAGE_MASK); 664 665 switch (bytes) { 666 case 4: 667 *(volatile uint32_t *)(va) = data; 668 break; 669 case 2: 670 *(volatile uint16_t *)(va) = data; 671 break; 672 case 1: 673 *(volatile uint8_t *)(va) = data; 674 break; 675 } 676 677 critical_exit(); 678 } 679