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