1 /* 2 * PCI support code. 3 * Needs a massive rewrite. 4 */ 5 #include "u.h" 6 #include "../port/lib.h" 7 #include "mem.h" 8 #include "dat.h" 9 #include "fns.h" 10 #include "io.h" 11 12 #define DBG if(0) pcilog 13 14 typedef struct Pci Pci; 15 16 struct 17 { 18 char output[PCICONSSIZE]; 19 int ptr; 20 }PCICONS; 21 22 int 23 pcilog(char *fmt, ...) 24 { 25 int n; 26 va_list arg; 27 char buf[PRINTSIZE]; 28 29 va_start(arg, fmt); 30 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; 31 va_end(arg); 32 33 memmove(PCICONS.output+PCICONS.ptr, buf, n); 34 PCICONS.ptr += n; 35 return n; 36 } 37 38 enum 39 { 40 MaxFNO = 7, 41 MaxUBN = 255, 42 }; 43 44 enum 45 { /* command register */ 46 IOen = (1<<0), 47 MEMen = (1<<1), 48 MASen = (1<<2), 49 MemWrInv = (1<<4), 50 PErrEn = (1<<6), 51 SErrEn = (1<<8), 52 }; 53 54 typedef struct { 55 ulong cap; 56 ulong ctl; 57 } Capctl; 58 typedef struct { 59 Capctl dev; 60 Capctl link; 61 Capctl slot; 62 } Devlinkslot; 63 64 /* capability list id 0x10 is pci-e */ 65 struct Pci { 66 /* pci-compatible config */ 67 /* what io.h calls type 0 & type 1 pre-defined header */ 68 ulong id; 69 ulong cs; 70 ulong revclass; 71 ulong misc; /* cache line size, latency timer, header type, bist */ 72 ulong bar[2]; /* always 0 on tegra 2 */ 73 74 /* types 1 & 2 pre-defined header */ 75 ulong bus; 76 ulong ioaddrs; 77 ulong memaddrs; 78 ulong prefmem; 79 ulong prefbasehi; 80 ulong preflimhi; 81 /* type 2 pre-defined header only */ 82 ulong ioaddrhi; 83 ulong cfgcapoff; /* offset in cfg. space to cap. list (0x40) */ 84 ulong rom; 85 ulong intr; /* PciINT[LP] */ 86 /* subsystem capability regs */ 87 ulong subsysid; 88 ulong subsyscap; 89 /* */ 90 91 Capctl pwrmgmt; 92 93 /* msi */ 94 ulong msictlcap; 95 ulong msimsgaddr[2]; /* little-endian */ 96 ulong msimsgdata; 97 98 /* pci-e cap. */ 99 uchar _pad0[0x80-0x60]; 100 ulong pciecap; 101 Devlinkslot port0; 102 ulong rootctl; 103 ulong rootsts; 104 Devlinkslot port1; 105 106 /* 0xbc */ 107 108 }; 109 110 enum { 111 /* offsets from soc.pci */ 112 Port0 = 0, 113 Port1 = 0x1000, 114 Pads = 0x3000, 115 Afi = 0x3800, 116 Aficfg = Afi + 0xac, 117 Cfgspace = 0x4000, 118 Ecfgspace = 0x104000, 119 120 /* cs bits */ 121 Iospace = 1<<0, 122 Memspace = 1<<1, 123 Busmaster = 1<<2, 124 125 /* Aficfg bits */ 126 Fpcion = 1<<0, 127 }; 128 129 struct Pcictlr { 130 union { 131 uchar _padpci[0x1000]; 132 Pci; 133 } ports[2]; 134 uchar _padpads[0x1000]; 135 uchar pads[0x800]; 136 uchar afi[0x800]; 137 ulong cfg[0x1000]; 138 ulong extcfg[0x1000]; 139 }; 140 141 static Lock pcicfglock; 142 static Lock pcicfginitlock; 143 static int pcicfgmode = -1; 144 static int pcimaxbno = 1; /* was 7; only 2 pci buses; touching 3rd hangs */ 145 static int pcimaxdno; 146 static Pcidev* pciroot; 147 static Pcidev* pcilist; 148 static Pcidev* pcitail; 149 150 static int pcicfgrw8(int, int, int, int); 151 static int pcicfgrw16(int, int, int, int); 152 static int pcicfgrw32(int, int, int, int); 153 154 static char* bustypes[] = { 155 "CBUSI", 156 "CBUSII", 157 "EISA", 158 "FUTURE", 159 "INTERN", 160 "ISA", 161 "MBI", 162 "MBII", 163 "MCA", 164 "MPI", 165 "MPSA", 166 "NUBUS", 167 "PCI", 168 "PCMCIA", 169 "TC", 170 "VL", 171 "VME", 172 "XPRESS", 173 }; 174 175 static int 176 tbdffmt(Fmt* fmt) 177 { 178 char *p; 179 int l, r; 180 uint type, tbdf; 181 182 if((p = malloc(READSTR)) == nil) 183 return fmtstrcpy(fmt, "(tbdfconv)"); 184 185 switch(fmt->r){ 186 case 'T': 187 tbdf = va_arg(fmt->args, int); 188 if(tbdf == BUSUNKNOWN) 189 snprint(p, READSTR, "unknown"); 190 else{ 191 type = BUSTYPE(tbdf); 192 if(type < nelem(bustypes)) 193 l = snprint(p, READSTR, bustypes[type]); 194 else 195 l = snprint(p, READSTR, "%d", type); 196 snprint(p+l, READSTR-l, ".%d.%d.%d", 197 BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf)); 198 } 199 break; 200 201 default: 202 snprint(p, READSTR, "(tbdfconv)"); 203 break; 204 } 205 r = fmtstrcpy(fmt, p); 206 free(p); 207 208 return r; 209 } 210 211 ulong 212 pcibarsize(Pcidev *p, int rno) 213 { 214 ulong v, size; 215 216 v = pcicfgrw32(p->tbdf, rno, 0, 1); 217 pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0); 218 size = pcicfgrw32(p->tbdf, rno, 0, 1); 219 if(v & 1) 220 size |= 0xFFFF0000; 221 pcicfgrw32(p->tbdf, rno, v, 0); 222 223 return -(size & ~0x0F); 224 } 225 226 static int 227 pcilscan(int bno, Pcidev** list) 228 { 229 Pcidev *p, *head, *tail; 230 int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn; 231 232 maxubn = bno; 233 head = nil; 234 tail = nil; 235 for(dno = 0; dno <= pcimaxdno; dno++){ 236 maxfno = 0; 237 for(fno = 0; fno <= maxfno; fno++){ 238 /* 239 * For this possible device, form the 240 * bus+device+function triplet needed to address it 241 * and try to read the vendor and device ID. 242 * If successful, allocate a device struct and 243 * start to fill it in with some useful information 244 * from the device's configuration space. 245 */ 246 tbdf = MKBUS(BusPCI, bno, dno, fno); 247 l = pcicfgrw32(tbdf, PciVID, 0, 1); 248 if(l == 0xFFFFFFFF || l == 0) 249 continue; 250 p = malloc(sizeof(*p)); 251 if(p == nil) 252 panic("pcilscan: no memory"); 253 p->tbdf = tbdf; 254 p->vid = l; 255 p->did = l>>16; 256 257 if(pcilist != nil) 258 pcitail->list = p; 259 else 260 pcilist = p; 261 pcitail = p; 262 263 p->pcr = pcicfgr16(p, PciPCR); 264 p->rid = pcicfgr8(p, PciRID); 265 p->ccrp = pcicfgr8(p, PciCCRp); 266 p->ccru = pcicfgr8(p, PciCCRu); 267 p->ccrb = pcicfgr8(p, PciCCRb); 268 p->cls = pcicfgr8(p, PciCLS); 269 p->ltr = pcicfgr8(p, PciLTR); 270 271 p->intl = pcicfgr8(p, PciINTL); 272 273 /* 274 * If the device is a multi-function device adjust the 275 * loop count so all possible functions are checked. 276 */ 277 hdt = pcicfgr8(p, PciHDT); 278 if(hdt & 0x80) 279 maxfno = MaxFNO; 280 281 /* 282 * If appropriate, read the base address registers 283 * and work out the sizes. 284 */ 285 switch(p->ccrb) { 286 case 0x03: /* display controller */ 287 /* fall through */ 288 case 0x01: /* mass storage controller */ 289 case 0x02: /* network controller */ 290 case 0x04: /* multimedia device */ 291 case 0x07: /* simple comm. controllers */ 292 case 0x08: /* base system peripherals */ 293 case 0x09: /* input devices */ 294 case 0x0A: /* docking stations */ 295 case 0x0B: /* processors */ 296 case 0x0C: /* serial bus controllers */ 297 if((hdt & 0x7F) != 0) 298 break; 299 rno = PciBAR0 - 4; 300 for(i = 0; i < nelem(p->mem); i++) { 301 rno += 4; 302 p->mem[i].bar = pcicfgr32(p, rno); 303 p->mem[i].size = pcibarsize(p, rno); 304 } 305 break; 306 307 case 0x00: 308 case 0x05: /* memory controller */ 309 case 0x06: /* bridge device */ 310 default: 311 break; 312 } 313 314 if(head != nil) 315 tail->link = p; 316 else 317 head = p; 318 tail = p; 319 } 320 } 321 322 *list = head; 323 for(p = head; p != nil; p = p->link){ 324 /* 325 * Find PCI-PCI bridges and recursively descend the tree. 326 */ 327 if(p->ccrb != 0x06 || p->ccru != 0x04) 328 continue; 329 330 /* 331 * If the secondary or subordinate bus number is not 332 * initialised try to do what the PCI BIOS should have 333 * done and fill in the numbers as the tree is descended. 334 * On the way down the subordinate bus number is set to 335 * the maximum as it's not known how many buses are behind 336 * this one; the final value is set on the way back up. 337 */ 338 sbn = pcicfgr8(p, PciSBN); 339 ubn = pcicfgr8(p, PciUBN); 340 341 if(sbn == 0 || ubn == 0) { 342 sbn = maxubn+1; 343 /* 344 * Make sure memory, I/O and master enables are 345 * off, set the primary, secondary and subordinate 346 * bus numbers and clear the secondary status before 347 * attempting to scan the secondary bus. 348 * 349 * Initialisation of the bridge should be done here. 350 */ 351 pcicfgw32(p, PciPCR, 0xFFFF0000); 352 l = (MaxUBN<<16)|(sbn<<8)|bno; 353 pcicfgw32(p, PciPBN, l); 354 pcicfgw16(p, PciSPSR, 0xFFFF); 355 maxubn = pcilscan(sbn, &p->bridge); 356 l = (maxubn<<16)|(sbn<<8)|bno; 357 358 pcicfgw32(p, PciPBN, l); 359 } 360 else { 361 if(ubn > maxubn) 362 maxubn = ubn; 363 pcilscan(sbn, &p->bridge); 364 } 365 } 366 367 return maxubn; 368 } 369 370 extern void rtl8169interrupt(Ureg*, void* arg); 371 372 /* not used yet */ 373 static void 374 pciintr(Ureg *ureg, void *p) 375 { 376 rtl8169interrupt(ureg, p); /* HACK */ 377 } 378 379 static void 380 pcicfginit(void) 381 { 382 char *p; 383 Pci *pci = (Pci *)soc.pci; 384 Pcidev **list; 385 int bno, n; 386 387 lock(&pcicfginitlock); 388 if(pcicfgmode != -1) { 389 unlock(&pcicfginitlock); 390 return; 391 } 392 393 /* 394 * TrimSlice # pci 0 1 395 * Scanning PCI devices on bus 0 1 396 * BusDevFun VendorId DeviceId Device Class Sub-Class 397 * _____________________________________________________________ 398 * 00.00.00 0x10de 0x0bf0 Bridge device 0x04 399 * 01.00.00 0x10ec 0x8168 Network controller 0x00 400 * 401 * thus pci bus 0 has a bridge with, perhaps, an ide/sata ctlr behind, 402 * and pci bus 1 has the realtek 8169 on it: 403 * 404 * TrimSlice # pci 1 long 405 * Scanning PCI devices on bus 1 406 * 407 * Found PCI device 01.00.00: 408 * vendor ID = 0x10ec 409 * device ID = 0x8168 410 * command register = 0x0007 411 * status register = 0x0010 412 * revision ID = 0x03 413 * class code = 0x02 (Network controller) 414 * sub class code = 0x00 415 * programming interface = 0x00 416 * cache line = 0x08 417 * base address 0 = 0x80400001 config 418 * base address 1 = 0x00000000 (ext. config) 419 * base address 2 = 0xa000000c "downstream" 420 * base address 3 = 0x00000000 (prefetchable) 421 * base address 4 = 0xa000400c not " 422 * base address 5 = 0x00000000 (unused) 423 */ 424 n = pci->id >> 16; 425 if (((pci->id & MASK(16)) != Vnvidia || (n != 0xbf0 && n != 0xbf1)) && 426 (pci->id & MASK(16)) != Vrealtek) { 427 print("no pci controller at %#p\n", pci); 428 unlock(&pcicfginitlock); 429 return; 430 } 431 if (0) 432 iprint("pci: %#p: nvidia, rev %#ux class %#6.6lux misc %#8.8lux\n", 433 pci, (uchar)pci->revclass, pci->revclass >> 8, 434 pci->misc); 435 436 pci->cs &= Iospace; 437 pci->cs |= Memspace | Busmaster; 438 coherence(); 439 440 pcicfgmode = 1; 441 // pcimaxdno = 31; 442 pcimaxdno = 15; /* for trimslice */ 443 444 fmtinstall('T', tbdffmt); 445 446 if(p = getconf("*pcimaxbno")){ 447 n = strtoul(p, 0, 0); 448 if(n < pcimaxbno) 449 pcimaxbno = n; 450 } 451 if(p = getconf("*pcimaxdno")){ 452 n = strtoul(p, 0, 0); 453 if(n < pcimaxdno) 454 pcimaxdno = n; 455 } 456 457 list = &pciroot; 458 /* was bno = 0; trimslice needs to start at 1 */ 459 for(bno = 1; bno <= pcimaxbno; bno++) { 460 bno = pcilscan(bno, list); 461 while(*list) 462 list = &(*list)->link; 463 } 464 unlock(&pcicfginitlock); 465 466 if(getconf("*pcihinv")) 467 pcihinv(nil); 468 } 469 470 enum { 471 Afiintrcode = 0xb8, 472 }; 473 474 void 475 pcieintrdone(void) /* dismiss pci-e intr */ 476 { 477 ulong *afi; 478 479 afi = (ulong *)(soc.pci + Afi); 480 afi[Afiintrcode/sizeof *afi] = 0; /* magic */ 481 coherence(); 482 } 483 484 /* 485 * whole config space for tbdf should be at (return address - rno). 486 */ 487 static void * 488 tegracfgaddr(int tbdf, int rno) 489 { 490 uintptr addr; 491 492 addr = soc.pci + (rno < 256? Cfgspace: Ecfgspace) + BUSBDF(tbdf) + rno; 493 // if (BUSBNO(tbdf) == 1) 494 // addr += Port1; 495 return (void *)addr; 496 } 497 498 static int 499 pcicfgrw8(int tbdf, int rno, int data, int read) 500 { 501 int x; 502 void *addr; 503 504 if(pcicfgmode == -1) 505 pcicfginit(); 506 507 x = -1; 508 if(BUSDNO(tbdf) > pcimaxdno) 509 return x; 510 511 addr = tegracfgaddr(tbdf, rno); 512 513 lock(&pcicfglock); 514 if(read) 515 x = *(uchar *)addr; 516 else 517 *(uchar *)addr = data; 518 unlock(&pcicfglock); 519 520 return x; 521 } 522 523 int 524 pcicfgr8(Pcidev* pcidev, int rno) 525 { 526 return pcicfgrw8(pcidev->tbdf, rno, 0, 1); 527 } 528 529 void 530 pcicfgw8(Pcidev* pcidev, int rno, int data) 531 { 532 pcicfgrw8(pcidev->tbdf, rno, data, 0); 533 } 534 535 static int 536 pcicfgrw16(int tbdf, int rno, int data, int read) 537 { 538 int x; 539 void *addr; 540 541 if(pcicfgmode == -1) 542 pcicfginit(); 543 544 x = -1; 545 if(BUSDNO(tbdf) > pcimaxdno) 546 return x; 547 548 addr = tegracfgaddr(tbdf, rno); 549 550 lock(&pcicfglock); 551 if(read) 552 x = *(ushort *)addr; 553 else 554 *(ushort *)addr = data; 555 unlock(&pcicfglock); 556 557 return x; 558 } 559 560 int 561 pcicfgr16(Pcidev* pcidev, int rno) 562 { 563 return pcicfgrw16(pcidev->tbdf, rno, 0, 1); 564 } 565 566 void 567 pcicfgw16(Pcidev* pcidev, int rno, int data) 568 { 569 pcicfgrw16(pcidev->tbdf, rno, data, 0); 570 } 571 572 static int 573 pcicfgrw32(int tbdf, int rno, int data, int read) 574 { 575 int x; 576 vlong v; 577 void *addr; 578 579 if(pcicfgmode == -1) 580 pcicfginit(); 581 582 x = -1; 583 if(BUSDNO(tbdf) > pcimaxdno) 584 return x; 585 586 addr = tegracfgaddr(tbdf, rno); 587 v = probeaddr((uintptr)addr); 588 if (v < 0) 589 return -1; 590 591 lock(&pcicfglock); 592 if(read) 593 x = *(ulong *)addr; 594 else 595 *(ulong *)addr = data; 596 unlock(&pcicfglock); 597 598 return x; 599 } 600 601 int 602 pcicfgr32(Pcidev* pcidev, int rno) 603 { 604 return pcicfgrw32(pcidev->tbdf, rno, 0, 1); 605 } 606 607 void 608 pcicfgw32(Pcidev* pcidev, int rno, int data) 609 { 610 pcicfgrw32(pcidev->tbdf, rno, data, 0); 611 } 612 613 Pcidev* 614 pcimatch(Pcidev* prev, int vid, int did) 615 { 616 if(pcicfgmode == -1) 617 pcicfginit(); 618 619 if(prev == nil) 620 prev = pcilist; 621 else 622 prev = prev->list; 623 624 while(prev != nil){ 625 if((vid == 0 || prev->vid == vid) 626 && (did == 0 || prev->did == did)) 627 break; 628 prev = prev->list; 629 } 630 return prev; 631 } 632 633 Pcidev* 634 pcimatchtbdf(int tbdf) 635 { 636 Pcidev *pcidev; 637 638 if(pcicfgmode == -1) 639 pcicfginit(); 640 641 for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) { 642 if(pcidev->tbdf == tbdf) 643 break; 644 } 645 return pcidev; 646 } 647 648 static void 649 pcilhinv(Pcidev* p) 650 { 651 int i; 652 Pcidev *t; 653 654 if(p == nil) { 655 putstrn(PCICONS.output, PCICONS.ptr); 656 p = pciroot; 657 print("bus dev type vid did intl memory\n"); 658 } 659 for(t = p; t != nil; t = t->link) { 660 print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ", 661 BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf), 662 t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl); 663 664 for(i = 0; i < nelem(p->mem); i++) { 665 if(t->mem[i].size == 0) 666 continue; 667 print("%d:%.8lux %d ", i, 668 t->mem[i].bar, t->mem[i].size); 669 } 670 if(t->bridge) 671 print("->%d", BUSBNO(t->bridge->tbdf)); 672 print("\n"); 673 } 674 while(p != nil) { 675 if(p->bridge != nil) 676 pcilhinv(p->bridge); 677 p = p->link; 678 } 679 } 680 681 void 682 pcihinv(Pcidev* p) 683 { 684 if(pcicfgmode == -1) 685 pcicfginit(); 686 lock(&pcicfginitlock); 687 pcilhinv(p); 688 unlock(&pcicfginitlock); 689 } 690 691 void 692 pcireset(void) 693 { 694 Pcidev *p; 695 696 if(pcicfgmode == -1) 697 pcicfginit(); 698 699 for(p = pcilist; p != nil; p = p->list) { 700 /* don't mess with the bridges */ 701 if(p->ccrb == 0x06) 702 continue; 703 pciclrbme(p); 704 } 705 } 706 707 void 708 pcisetioe(Pcidev* p) 709 { 710 p->pcr |= IOen; 711 pcicfgw16(p, PciPCR, p->pcr); 712 } 713 714 void 715 pciclrioe(Pcidev* p) 716 { 717 p->pcr &= ~IOen; 718 pcicfgw16(p, PciPCR, p->pcr); 719 } 720 721 void 722 pcisetbme(Pcidev* p) 723 { 724 p->pcr |= MASen; 725 pcicfgw16(p, PciPCR, p->pcr); 726 } 727 728 void 729 pciclrbme(Pcidev* p) 730 { 731 p->pcr &= ~MASen; 732 pcicfgw16(p, PciPCR, p->pcr); 733 } 734 735 void 736 pcisetmwi(Pcidev* p) 737 { 738 p->pcr |= MemWrInv; 739 pcicfgw16(p, PciPCR, p->pcr); 740 } 741 742 void 743 pciclrmwi(Pcidev* p) 744 { 745 p->pcr &= ~MemWrInv; 746 pcicfgw16(p, PciPCR, p->pcr); 747 } 748 749 static int 750 pcigetpmrb(Pcidev* p) 751 { 752 int ptr; 753 754 if(p->pmrb != 0) 755 return p->pmrb; 756 p->pmrb = -1; 757 758 /* 759 * If there are no extended capabilities implemented, 760 * (bit 4 in the status register) assume there's no standard 761 * power management method. 762 * Find the capabilities pointer based on PCI header type. 763 */ 764 if(!(pcicfgr16(p, PciPSR) & 0x0010)) 765 return -1; 766 switch(pcicfgr8(p, PciHDT)){ 767 default: 768 return -1; 769 case 0: /* all other */ 770 case 1: /* PCI to PCI bridge */ 771 ptr = 0x34; 772 break; 773 case 2: /* CardBus bridge */ 774 ptr = 0x14; 775 break; 776 } 777 ptr = pcicfgr32(p, ptr); 778 779 while(ptr != 0){ 780 /* 781 * Check for validity. 782 * Can't be in standard header and must be double 783 * word aligned. 784 */ 785 if(ptr < 0x40 || (ptr & ~0xFC)) 786 return -1; 787 if(pcicfgr8(p, ptr) == 0x01){ 788 p->pmrb = ptr; 789 return ptr; 790 } 791 792 ptr = pcicfgr8(p, ptr+1); 793 } 794 795 return -1; 796 } 797 798 int 799 pcigetpms(Pcidev* p) 800 { 801 int pmcsr, ptr; 802 803 if((ptr = pcigetpmrb(p)) == -1) 804 return -1; 805 806 /* 807 * Power Management Register Block: 808 * offset 0: Capability ID 809 * 1: next item pointer 810 * 2: capabilities 811 * 4: control/status 812 * 6: bridge support extensions 813 * 7: data 814 */ 815 pmcsr = pcicfgr16(p, ptr+4); 816 817 return pmcsr & 0x0003; 818 } 819 820 int 821 pcisetpms(Pcidev* p, int state) 822 { 823 int ostate, pmc, pmcsr, ptr; 824 825 if((ptr = pcigetpmrb(p)) == -1) 826 return -1; 827 828 pmc = pcicfgr16(p, ptr+2); 829 pmcsr = pcicfgr16(p, ptr+4); 830 ostate = pmcsr & 0x0003; 831 pmcsr &= ~0x0003; 832 833 switch(state){ 834 default: 835 return -1; 836 case 0: 837 break; 838 case 1: 839 if(!(pmc & 0x0200)) 840 return -1; 841 break; 842 case 2: 843 if(!(pmc & 0x0400)) 844 return -1; 845 break; 846 case 3: 847 break; 848 } 849 pmcsr |= state; 850 pcicfgw16(p, ptr+4, pmcsr); 851 852 return ostate; 853 } 854