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