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 #include "../port/error.h" 12 13 #define DBG if(0) pcilog 14 15 struct 16 { 17 char output[16384]; 18 int ptr; 19 }PCICONS; 20 21 int 22 pcilog(char *fmt, ...) 23 { 24 int n; 25 va_list arg; 26 char buf[PRINTSIZE]; 27 28 va_start(arg, fmt); 29 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; 30 va_end(arg); 31 32 memmove(PCICONS.output+PCICONS.ptr, buf, n); 33 PCICONS.ptr += n; 34 return n; 35 } 36 37 enum 38 { /* configuration mechanism #1 */ 39 PciADDR = 0xCF8, /* CONFIG_ADDRESS */ 40 PciDATA = 0xCFC, /* CONFIG_DATA */ 41 42 /* configuration mechanism #2 */ 43 PciCSE = 0xCF8, /* configuration space enable */ 44 PciFORWARD = 0xCFA, /* which bus */ 45 46 MaxFNO = 7, 47 MaxUBN = 255, 48 }; 49 50 enum 51 { /* command register */ 52 IOen = (1<<0), 53 MEMen = (1<<1), 54 MASen = (1<<2), 55 MemWrInv = (1<<4), 56 PErrEn = (1<<6), 57 SErrEn = (1<<8), 58 }; 59 60 static Lock pcicfglock; 61 static Lock pcicfginitlock; 62 static int pcicfgmode = -1; 63 static int pcimaxbno = 7; 64 static int pcimaxdno; 65 static Pcidev* pciroot; 66 static Pcidev* pcilist; 67 static Pcidev* pcitail; 68 static int nobios, nopcirouting; 69 70 static int pcicfgrw32(int, int, int, int); 71 static int pcicfgrw16(int, int, int, int); 72 static int pcicfgrw8(int, int, int, int); 73 74 static char* bustypes[] = { 75 "CBUSI", 76 "CBUSII", 77 "EISA", 78 "FUTURE", 79 "INTERN", 80 "ISA", 81 "MBI", 82 "MBII", 83 "MCA", 84 "MPI", 85 "MPSA", 86 "NUBUS", 87 "PCI", 88 "PCMCIA", 89 "TC", 90 "VL", 91 "VME", 92 "XPRESS", 93 }; 94 95 #pragma varargck type "T" int 96 97 static int 98 tbdffmt(Fmt* fmt) 99 { 100 char *p; 101 int l, r, type, tbdf; 102 103 if((p = malloc(READSTR)) == nil) 104 return fmtstrcpy(fmt, "(tbdfconv)"); 105 106 switch(fmt->r){ 107 case 'T': 108 tbdf = va_arg(fmt->args, int); 109 type = BUSTYPE(tbdf); 110 if(type < nelem(bustypes)) 111 l = snprint(p, READSTR, bustypes[type]); 112 else 113 l = snprint(p, READSTR, "%d", type); 114 snprint(p+l, READSTR-l, ".%d.%d.%d", 115 BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf)); 116 break; 117 118 default: 119 snprint(p, READSTR, "(tbdfconv)"); 120 break; 121 } 122 r = fmtstrcpy(fmt, p); 123 free(p); 124 125 return r; 126 } 127 128 ulong 129 pcibarsize(Pcidev *p, int rno) 130 { 131 ulong v, size; 132 133 v = pcicfgrw32(p->tbdf, rno, 0, 1); 134 pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0); 135 size = pcicfgrw32(p->tbdf, rno, 0, 1); 136 if(v & 1) 137 size |= 0xFFFF0000; 138 pcicfgrw32(p->tbdf, rno, v, 0); 139 140 return -(size & ~0x0F); 141 } 142 143 static int 144 pcisizcmp(void *a, void *b) 145 { 146 Pcisiz *aa, *bb; 147 148 aa = a; 149 bb = b; 150 return aa->siz - bb->siz; 151 } 152 153 static ulong 154 pcimask(ulong v) 155 { 156 ulong m; 157 158 m = BI2BY*sizeof(v); 159 for(m = 1<<(m-1); m != 0; m >>= 1) { 160 if(m & v) 161 break; 162 } 163 164 m--; 165 if((v & m) == 0) 166 return v; 167 168 v |= m; 169 return v+1; 170 } 171 172 static void 173 pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg) 174 { 175 Pcidev *p; 176 int ntb, i, size, rno, hole; 177 ulong v, mema, ioa, sioa, smema, base, limit; 178 Pcisiz *table, *tptr, *mtb, *itb; 179 180 if(!nobios) 181 return; 182 183 ioa = *pioa; 184 mema = *pmema; 185 186 DBG("pcibusmap wr=%d %T mem=%luX io=%luX\n", 187 wrreg, root->tbdf, mema, ioa); 188 189 ntb = 0; 190 for(p = root; p != nil; p = p->link) 191 ntb++; 192 193 ntb *= (PciCIS-PciBAR0)/4; 194 table = malloc(2*ntb*sizeof(Pcisiz)); 195 itb = table; 196 mtb = table+ntb; 197 198 /* 199 * Build a table of sizes 200 */ 201 for(p = root; p != nil; p = p->link) { 202 if(p->ccrb == 0x06) { 203 if(p->ccru != 0x04 || p->bridge == nil) { 204 // DBG("pci: ignored bridge %T\n", p->tbdf); 205 continue; 206 } 207 208 sioa = ioa; 209 smema = mema; 210 pcibusmap(p->bridge, &smema, &sioa, 0); 211 212 hole = pcimask(smema-mema); 213 if(hole < (1<<20)) 214 hole = 1<<20; 215 p->mema.size = hole; 216 217 hole = pcimask(sioa-ioa); 218 if(hole < (1<<12)) 219 hole = 1<<12; 220 221 p->ioa.size = hole; 222 223 itb->dev = p; 224 itb->bar = -1; 225 itb->siz = p->ioa.size; 226 itb++; 227 228 mtb->dev = p; 229 mtb->bar = -1; 230 mtb->siz = p->mema.size; 231 mtb++; 232 continue; 233 } 234 235 for(i = 0; i <= 5; i++) { 236 rno = PciBAR0 + i*4; 237 v = pcicfgrw32(p->tbdf, rno, 0, 1); 238 size = pcibarsize(p, rno); 239 if(size == 0) 240 continue; 241 242 if(v & 1) { 243 itb->dev = p; 244 itb->bar = i; 245 itb->siz = size; 246 itb++; 247 } 248 else { 249 mtb->dev = p; 250 mtb->bar = i; 251 mtb->siz = size; 252 mtb++; 253 } 254 255 p->mem[i].size = size; 256 } 257 } 258 259 /* 260 * Sort both tables IO smallest first, Memory largest 261 */ 262 qsort(table, itb-table, sizeof(Pcisiz), pcisizcmp); 263 tptr = table+ntb; 264 qsort(tptr, mtb-tptr, sizeof(Pcisiz), pcisizcmp); 265 266 /* 267 * Allocate IO address space on this bus 268 */ 269 for(tptr = table; tptr < itb; tptr++) { 270 hole = tptr->siz; 271 if(tptr->bar == -1) 272 hole = 1<<12; 273 ioa = (ioa+hole-1) & ~(hole-1); 274 275 p = tptr->dev; 276 if(tptr->bar == -1) 277 p->ioa.bar = ioa; 278 else { 279 p->pcr |= IOen; 280 p->mem[tptr->bar].bar = ioa|1; 281 if(wrreg) 282 pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), ioa|1, 0); 283 } 284 285 ioa += tptr->siz; 286 } 287 288 /* 289 * Allocate Memory address space on this bus 290 */ 291 for(tptr = table+ntb; tptr < mtb; tptr++) { 292 hole = tptr->siz; 293 if(tptr->bar == -1) 294 hole = 1<<20; 295 mema = (mema+hole-1) & ~(hole-1); 296 297 p = tptr->dev; 298 if(tptr->bar == -1) 299 p->mema.bar = mema; 300 else { 301 p->pcr |= MEMen; 302 p->mem[tptr->bar].bar = mema; 303 if(wrreg) 304 pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), mema, 0); 305 } 306 mema += tptr->siz; 307 } 308 309 *pmema = mema; 310 *pioa = ioa; 311 free(table); 312 313 if(wrreg == 0) 314 return; 315 316 /* 317 * Finally set all the bridge addresses & registers 318 */ 319 for(p = root; p != nil; p = p->link) { 320 if(p->bridge == nil) { 321 pcicfgrw8(p->tbdf, PciLTR, 64, 0); 322 323 p->pcr |= MASen; 324 pcicfgrw16(p->tbdf, PciPCR, p->pcr, 0); 325 continue; 326 } 327 328 base = p->ioa.bar; 329 limit = base+p->ioa.size-1; 330 v = pcicfgrw32(p->tbdf, PciIBR, 0, 1); 331 v = (v&0xFFFF0000)|(limit & 0xF000)|((base & 0xF000)>>8); 332 pcicfgrw32(p->tbdf, PciIBR, v, 0); 333 v = (limit & 0xFFFF0000)|(base>>16); 334 pcicfgrw32(p->tbdf, PciIUBR, v, 0); 335 336 base = p->mema.bar; 337 limit = base+p->mema.size-1; 338 v = (limit & 0xFFF00000)|((base & 0xFFF00000)>>16); 339 pcicfgrw32(p->tbdf, PciMBR, v, 0); 340 341 /* 342 * Disable memory prefetch 343 */ 344 pcicfgrw32(p->tbdf, PciPMBR, 0x0000FFFF, 0); 345 pcicfgrw8(p->tbdf, PciLTR, 64, 0); 346 347 /* 348 * Enable the bridge 349 */ 350 p->pcr |= IOen|MEMen|MASen; 351 pcicfgrw32(p->tbdf, PciPCR, 0xFFFF0000|p->pcr , 0); 352 353 sioa = p->ioa.bar; 354 smema = p->mema.bar; 355 pcibusmap(p->bridge, &smema, &sioa, 1); 356 } 357 } 358 359 static int 360 pcilscan(int bno, Pcidev** list) 361 { 362 Pcidev *p, *head, *tail; 363 int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn; 364 365 maxubn = bno; 366 head = nil; 367 tail = nil; 368 for(dno = 0; dno <= pcimaxdno; dno++){ 369 maxfno = 0; 370 for(fno = 0; fno <= maxfno; fno++){ 371 /* 372 * For this possible device, form the 373 * bus+device+function triplet needed to address it 374 * and try to read the vendor and device ID. 375 * If successful, allocate a device struct and 376 * start to fill it in with some useful information 377 * from the device's configuration space. 378 */ 379 tbdf = MKBUS(BusPCI, bno, dno, fno); 380 l = pcicfgrw32(tbdf, PciVID, 0, 1); 381 if(l == 0xFFFFFFFF || l == 0) 382 continue; 383 p = malloc(sizeof(*p)); 384 p->tbdf = tbdf; 385 p->vid = l; 386 p->did = l>>16; 387 388 if(pcilist != nil) 389 pcitail->list = p; 390 else 391 pcilist = p; 392 pcitail = p; 393 394 p->pcr = pcicfgr16(p, PciPCR); 395 p->rid = pcicfgr8(p, PciRID); 396 p->ccrp = pcicfgr8(p, PciCCRp); 397 p->ccru = pcicfgr8(p, PciCCRu); 398 p->ccrb = pcicfgr8(p, PciCCRb); 399 p->cls = pcicfgr8(p, PciCLS); 400 p->ltr = pcicfgr8(p, PciLTR); 401 402 p->intl = pcicfgr8(p, PciINTL); 403 404 /* 405 * If the device is a multi-function device adjust the 406 * loop count so all possible functions are checked. 407 */ 408 hdt = pcicfgr8(p, PciHDT); 409 if(hdt & 0x80) 410 maxfno = MaxFNO; 411 412 /* 413 * If appropriate, read the base address registers 414 * and work out the sizes. 415 */ 416 switch(p->ccrb) { 417 case 0x01: /* mass storage controller */ 418 case 0x02: /* network controller */ 419 case 0x03: /* display controller */ 420 case 0x04: /* multimedia device */ 421 case 0x07: /* simple comm. controllers */ 422 case 0x08: /* base system peripherals */ 423 case 0x09: /* input devices */ 424 case 0x0A: /* docking stations */ 425 case 0x0B: /* processors */ 426 case 0x0C: /* serial bus controllers */ 427 if((hdt & 0x7F) != 0) 428 break; 429 rno = PciBAR0 - 4; 430 for(i = 0; i < nelem(p->mem); i++) { 431 rno += 4; 432 p->mem[i].bar = pcicfgr32(p, rno); 433 p->mem[i].size = pcibarsize(p, rno); 434 } 435 break; 436 437 case 0x00: 438 case 0x05: /* memory controller */ 439 case 0x06: /* bridge device */ 440 default: 441 break; 442 } 443 444 if(head != nil) 445 tail->link = p; 446 else 447 head = p; 448 tail = p; 449 } 450 } 451 452 *list = head; 453 for(p = head; p != nil; p = p->link){ 454 /* 455 * Find PCI-PCI bridges and recursively descend the tree. 456 */ 457 if(p->ccrb != 0x06 || p->ccru != 0x04) 458 continue; 459 460 /* 461 * If the secondary or subordinate bus number is not 462 * initialised try to do what the PCI BIOS should have 463 * done and fill in the numbers as the tree is descended. 464 * On the way down the subordinate bus number is set to 465 * the maximum as it's not known how many buses are behind 466 * this one; the final value is set on the way back up. 467 */ 468 sbn = pcicfgr8(p, PciSBN); 469 ubn = pcicfgr8(p, PciUBN); 470 471 if(sbn == 0 || ubn == 0 || nobios) { 472 sbn = maxubn+1; 473 /* 474 * Make sure memory, I/O and master enables are 475 * off, set the primary, secondary and subordinate 476 * bus numbers and clear the secondary status before 477 * attempting to scan the secondary bus. 478 * 479 * Initialisation of the bridge should be done here. 480 */ 481 pcicfgw32(p, PciPCR, 0xFFFF0000); 482 l = (MaxUBN<<16)|(sbn<<8)|bno; 483 pcicfgw32(p, PciPBN, l); 484 pcicfgw16(p, PciSPSR, 0xFFFF); 485 maxubn = pcilscan(sbn, &p->bridge); 486 l = (maxubn<<16)|(sbn<<8)|bno; 487 488 pcicfgw32(p, PciPBN, l); 489 } 490 else { 491 if(ubn > maxubn) 492 maxubn = ubn; 493 pcilscan(sbn, &p->bridge); 494 } 495 } 496 497 return maxubn; 498 } 499 500 int 501 pciscan(int bno, Pcidev **list) 502 { 503 int ubn; 504 505 lock(&pcicfginitlock); 506 ubn = pcilscan(bno, list); 507 unlock(&pcicfginitlock); 508 return ubn; 509 } 510 511 static uchar 512 pIIxget(Pcidev *router, uchar link) 513 { 514 uchar pirq; 515 516 /* link should be 0x60, 0x61, 0x62, 0x63 */ 517 pirq = pcicfgr8(router, link); 518 return (pirq < 16)? pirq: 0; 519 } 520 521 static void 522 pIIxset(Pcidev *router, uchar link, uchar irq) 523 { 524 pcicfgw8(router, link, irq); 525 } 526 527 static uchar 528 viaget(Pcidev *router, uchar link) 529 { 530 uchar pirq; 531 532 /* link should be 1, 2, 3, 5 */ 533 pirq = (link < 6)? pcicfgr8(router, 0x55 + (link>>1)): 0; 534 535 return (link & 1)? (pirq >> 4): (pirq & 15); 536 } 537 538 static void 539 viaset(Pcidev *router, uchar link, uchar irq) 540 { 541 uchar pirq; 542 543 pirq = pcicfgr8(router, 0x55 + (link >> 1)); 544 pirq &= (link & 1)? 0x0f: 0xf0; 545 pirq |= (link & 1)? (irq << 4): (irq & 15); 546 pcicfgw8(router, 0x55 + (link>>1), pirq); 547 } 548 549 static uchar 550 optiget(Pcidev *router, uchar link) 551 { 552 uchar pirq = 0; 553 554 /* link should be 0x02, 0x12, 0x22, 0x32 */ 555 if ((link & 0xcf) == 0x02) 556 pirq = pcicfgr8(router, 0xb8 + (link >> 5)); 557 return (link & 0x10)? (pirq >> 4): (pirq & 15); 558 } 559 560 static void 561 optiset(Pcidev *router, uchar link, uchar irq) 562 { 563 uchar pirq; 564 565 pirq = pcicfgr8(router, 0xb8 + (link >> 5)); 566 pirq &= (link & 0x10)? 0x0f : 0xf0; 567 pirq |= (link & 0x10)? (irq << 4): (irq & 15); 568 pcicfgw8(router, 0xb8 + (link >> 5), pirq); 569 } 570 571 static uchar 572 aliget(Pcidev *router, uchar link) 573 { 574 /* No, you're not dreaming */ 575 static const uchar map[] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; 576 uchar pirq; 577 578 /* link should be 0x01..0x08 */ 579 pirq = pcicfgr8(router, 0x48 + ((link-1)>>1)); 580 return (link & 1)? map[pirq&15]: map[pirq>>4]; 581 } 582 583 static void 584 aliset(Pcidev *router, uchar link, uchar irq) 585 { 586 /* Inverse of map in aliget */ 587 static const uchar map[] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; 588 uchar pirq; 589 590 pirq = pcicfgr8(router, 0x48 + ((link-1)>>1)); 591 pirq &= (link & 1)? 0x0f: 0xf0; 592 pirq |= (link & 1)? (map[irq] << 4): (map[irq] & 15); 593 pcicfgw8(router, 0x48 + ((link-1)>>1), pirq); 594 } 595 596 static uchar 597 cyrixget(Pcidev *router, uchar link) 598 { 599 uchar pirq; 600 601 /* link should be 1, 2, 3, 4 */ 602 pirq = pcicfgr8(router, 0x5c + ((link-1)>>1)); 603 return ((link & 1)? pirq >> 4: pirq & 15); 604 } 605 606 static void 607 cyrixset(Pcidev *router, uchar link, uchar irq) 608 { 609 uchar pirq; 610 611 pirq = pcicfgr8(router, 0x5c + (link>>1)); 612 pirq &= (link & 1)? 0x0f: 0xf0; 613 pirq |= (link & 1)? (irq << 4): (irq & 15); 614 pcicfgw8(router, 0x5c + (link>>1), pirq); 615 } 616 617 typedef struct Bridge Bridge; 618 struct Bridge 619 { 620 ushort vid; 621 ushort did; 622 uchar (*get)(Pcidev *, uchar); 623 void (*set)(Pcidev *, uchar, uchar); 624 }; 625 626 static Bridge southbridges[] = { 627 { 0x8086, 0x122e, pIIxget, pIIxset }, // Intel 82371FB 628 { 0x8086, 0x1234, pIIxget, pIIxset }, // Intel 82371MX 629 { 0x8086, 0x7000, pIIxget, pIIxset }, // Intel 82371SB 630 { 0x8086, 0x7110, pIIxget, pIIxset }, // Intel 82371AB 631 { 0x8086, 0x7198, pIIxget, pIIxset }, // Intel 82443MX (fn 1) 632 { 0x8086, 0x2410, pIIxget, pIIxset }, // Intel 82801AA 633 { 0x8086, 0x2420, pIIxget, pIIxset }, // Intel 82801AB 634 { 0x8086, 0x2440, pIIxget, pIIxset }, // Intel 82801BA 635 { 0x8086, 0x244c, pIIxget, pIIxset }, // Intel 82801BAM 636 { 0x8086, 0x248c, pIIxget, pIIxset }, // Intel 82801CAM 637 { 0x8086, 0x24cc, pIIxget, pIIxset }, // Intel 82801DBM 638 { 0x8086, 0x24d0, pIIxget, pIIxset }, // Intel 82801EB 639 { 0x8086, 0x2640, pIIxget, pIIxset }, // Intel 82801FB 640 { 0x1106, 0x0586, viaget, viaset }, // Viatech 82C586 641 { 0x1106, 0x0596, viaget, viaset }, // Viatech 82C596 642 { 0x1106, 0x0686, viaget, viaset }, // Viatech 82C686 643 { 0x1106, 0x3227, viaget, viaset }, // Viatech VT8237 644 { 0x1045, 0xc700, optiget, optiset }, // Opti 82C700 645 { 0x10b9, 0x1533, aliget, aliset }, // Al M1533 646 { 0x1039, 0x0008, pIIxget, pIIxset }, // SI 503 647 { 0x1039, 0x0496, pIIxget, pIIxset }, // SI 496 648 { 0x1078, 0x0100, cyrixget, cyrixset }, // Cyrix 5530 Legacy 649 650 { 0x1022, 0x746B, nil, nil }, // AMD 8111 651 { 0x10DE, 0x00D1, nil, nil }, // NVIDIA nForce 3 652 { 0x1166, 0x0200, nil, nil }, // ServerWorks ServerSet III LE 653 }; 654 655 typedef struct Slot Slot; 656 struct Slot { 657 uchar bus; // Pci bus number 658 uchar dev; // Pci device number 659 uchar maps[12]; // Avoid structs! Link and mask. 660 uchar slot; // Add-in/built-in slot 661 uchar reserved; 662 }; 663 664 typedef struct Router Router; 665 struct Router { 666 uchar signature[4]; // Routing table signature 667 uchar version[2]; // Version number 668 uchar size[2]; // Total table size 669 uchar bus; // Interrupt router bus number 670 uchar devfn; // Router's devfunc 671 uchar pciirqs[2]; // Exclusive PCI irqs 672 uchar compat[4]; // Compatible PCI interrupt router 673 uchar miniport[4]; // Miniport data 674 uchar reserved[11]; 675 uchar checksum; 676 }; 677 678 static ushort pciirqs; // Exclusive PCI irqs 679 static Bridge *southbridge; // Which southbridge to use. 680 681 static void 682 pcirouting(void) 683 { 684 Slot *e; 685 Router *r; 686 int size, i, fn, tbdf; 687 Pcidev *sbpci, *pci; 688 uchar *p, pin, irq, link, *map; 689 690 // Search for PCI interrupt routing table in BIOS 691 for(p = (uchar *)KADDR(0xf0000); p < (uchar *)KADDR(0xfffff); p += 16) 692 if(p[0] == '$' && p[1] == 'P' && p[2] == 'I' && p[3] == 'R') 693 break; 694 695 if(p >= (uchar *)KADDR(0xfffff)) 696 return; 697 698 r = (Router *)p; 699 700 // print("PCI interrupt routing table version %d.%d at %.6uX\n", 701 // r->version[0], r->version[1], (ulong)r & 0xfffff); 702 703 tbdf = (BusPCI << 24)|(r->bus << 16)|(r->devfn << 8); 704 sbpci = pcimatchtbdf(tbdf); 705 if(sbpci == nil) { 706 print("pcirouting: Cannot find south bridge %T\n", tbdf); 707 return; 708 } 709 710 for(i = 0; i != nelem(southbridges); i++) 711 if(sbpci->vid == southbridges[i].vid && sbpci->did == southbridges[i].did) 712 break; 713 714 if(i == nelem(southbridges)) { 715 print("pcirouting: ignoring south bridge %T %.4uX/%.4uX\n", tbdf, sbpci->vid, sbpci->did); 716 return; 717 } 718 southbridge = &southbridges[i]; 719 if(southbridge->get == nil || southbridge->set == nil) 720 return; 721 722 pciirqs = (r->pciirqs[1] << 8)|r->pciirqs[0]; 723 724 size = (r->size[1] << 8)|r->size[0]; 725 for(e = (Slot *)&r[1]; (uchar *)e < p + size; e++) { 726 // print("%.2uX/%.2uX %.2uX: ", e->bus, e->dev, e->slot); 727 // for (i = 0; i != 4; i++) { 728 // uchar *m = &e->maps[i * 3]; 729 // print("[%d] %.2uX %.4uX ", 730 // i, m[0], (m[2] << 8)|m[1]); 731 // } 732 // print("\n"); 733 734 for(fn = 0; fn != 8; fn++) { 735 tbdf = (BusPCI << 24)|(e->bus << 16)|((e->dev | fn) << 8); 736 pci = pcimatchtbdf(tbdf); 737 if(pci == nil) 738 continue; 739 pin = pcicfgr8(pci, PciINTP); 740 if(pin == 0 || pin == 0xff) 741 continue; 742 743 map = &e->maps[(pin - 1) * 3]; 744 link = map[0]; 745 irq = southbridge->get(sbpci, link); 746 if(irq == 0 || irq == pci->intl) 747 continue; 748 if(pci->intl != 0 && pci->intl != 0xFF) { 749 print("pcirouting: BIOS workaround: %T at pin %d link %d irq %d -> %d\n", 750 tbdf, pin, link, irq, pci->intl); 751 southbridge->set(sbpci, link, pci->intl); 752 continue; 753 } 754 print("pcirouting: %T at pin %d link %d irq %d\n", tbdf, pin, link, irq); 755 pcicfgw8(pci, PciINTL, irq); 756 pci->intl = irq; 757 } 758 } 759 } 760 761 static void 762 pcicfginit(void) 763 { 764 char *p; 765 Pcidev **list; 766 ulong mema, ioa; 767 int bno, n, pcibios; 768 769 lock(&pcicfginitlock); 770 if(pcicfgmode != -1) 771 goto out; 772 773 pcibios = 0; 774 if(getconf("*nobios")) 775 nobios = 1; 776 else if(getconf("*pcibios")) 777 pcibios = 1; 778 if(getconf("*nopcirouting")) 779 nopcirouting = 1; 780 781 /* 782 * Try to determine which PCI configuration mode is implemented. 783 * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses 784 * a DWORD at 0xCF8 and another at 0xCFC and will pass through 785 * any non-DWORD accesses as normal I/O cycles. There shouldn't be 786 * a device behind these addresses so if Mode1 accesses fail try 787 * for Mode2 (Mode2 is deprecated). 788 */ 789 if(!pcibios){ 790 /* 791 * Bits [30:24] of PciADDR must be 0, 792 * according to the spec. 793 */ 794 n = inl(PciADDR); 795 if(!(n & 0x7FF00000)){ 796 outl(PciADDR, 0x80000000); 797 outb(PciADDR+3, 0); 798 if(inl(PciADDR) & 0x80000000){ 799 pcicfgmode = 1; 800 pcimaxdno = 31; 801 } 802 } 803 outl(PciADDR, n); 804 805 if(pcicfgmode < 0){ 806 /* 807 * The 'key' part of PciCSE should be 0. 808 */ 809 n = inb(PciCSE); 810 if(!(n & 0xF0)){ 811 outb(PciCSE, 0x0E); 812 if(inb(PciCSE) == 0x0E){ 813 pcicfgmode = 2; 814 pcimaxdno = 15; 815 } 816 } 817 outb(PciCSE, n); 818 } 819 } 820 821 if(pcicfgmode < 0) 822 goto out; 823 824 fmtinstall('T', tbdffmt); 825 826 if(p = getconf("*pcimaxbno")){ 827 n = strtoul(p, 0, 0); 828 if(n < pcimaxbno) 829 pcimaxbno = n; 830 } 831 if(p = getconf("*pcimaxdno")){ 832 n = strtoul(p, 0, 0); 833 if(n < pcimaxdno) 834 pcimaxdno = n; 835 } 836 837 list = &pciroot; 838 for(bno = 0; bno <= pcimaxbno; bno++) { 839 int sbno = bno; 840 bno = pcilscan(bno, list); 841 842 while(*list) 843 list = &(*list)->link; 844 845 if (sbno == 0) { 846 Pcidev *pci; 847 848 /* 849 * If we have found a PCI-to-Cardbus bridge, make sure 850 * it has no valid mappings anymore. 851 */ 852 pci = pciroot; 853 while (pci) { 854 if (pci->ccrb == 6 && pci->ccru == 7) { 855 ushort bcr; 856 857 /* reset the cardbus */ 858 bcr = pcicfgr16(pci, PciBCR); 859 pcicfgw16(pci, PciBCR, 0x40 | bcr); 860 delay(50); 861 } 862 pci = pci->link; 863 } 864 } 865 } 866 867 if(pciroot == nil) 868 goto out; 869 870 if(nobios) { 871 /* 872 * Work out how big the top bus is 873 */ 874 mema = 0; 875 ioa = 0; 876 pcibusmap(pciroot, &mema, &ioa, 0); 877 878 DBG("Sizes: mem=%8.8lux size=%8.8lux io=%8.8lux\n", 879 mema, pcimask(mema), ioa); 880 881 /* 882 * Align the windows and map it 883 */ 884 ioa = 0x1000; 885 mema = 0x90000000; 886 887 pcilog("Mask sizes: mem=%lux io=%lux\n", mema, ioa); 888 889 pcibusmap(pciroot, &mema, &ioa, 1); 890 DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa); 891 892 unlock(&pcicfginitlock); 893 return; 894 } 895 896 if (!nopcirouting) 897 pcirouting(); 898 899 out: 900 unlock(&pcicfginitlock); 901 902 if(getconf("*pcihinv")) 903 pcihinv(nil); 904 } 905 906 static int 907 pcicfgrw8(int tbdf, int rno, int data, int read) 908 { 909 int o, type, x; 910 911 if(pcicfgmode == -1) 912 pcicfginit(); 913 914 if(BUSBNO(tbdf)) 915 type = 0x01; 916 else 917 type = 0x00; 918 x = -1; 919 if(BUSDNO(tbdf) > pcimaxdno) 920 return x; 921 922 lock(&pcicfglock); 923 switch(pcicfgmode){ 924 925 case 1: 926 o = rno & 0x03; 927 rno &= ~0x03; 928 outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 929 if(read) 930 x = inb(PciDATA+o); 931 else 932 outb(PciDATA+o, data); 933 outl(PciADDR, 0); 934 break; 935 936 case 2: 937 outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 938 outb(PciFORWARD, BUSBNO(tbdf)); 939 if(read) 940 x = inb((0xC000|(BUSDNO(tbdf)<<8)) + rno); 941 else 942 outb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 943 outb(PciCSE, 0); 944 break; 945 } 946 unlock(&pcicfglock); 947 948 return x; 949 } 950 951 int 952 pcicfgr8(Pcidev* pcidev, int rno) 953 { 954 return pcicfgrw8(pcidev->tbdf, rno, 0, 1); 955 } 956 957 void 958 pcicfgw8(Pcidev* pcidev, int rno, int data) 959 { 960 pcicfgrw8(pcidev->tbdf, rno, data, 0); 961 } 962 963 static int 964 pcicfgrw16(int tbdf, int rno, int data, int read) 965 { 966 int o, type, x; 967 968 if(pcicfgmode == -1) 969 pcicfginit(); 970 971 if(BUSBNO(tbdf)) 972 type = 0x01; 973 else 974 type = 0x00; 975 x = -1; 976 if(BUSDNO(tbdf) > pcimaxdno) 977 return x; 978 979 lock(&pcicfglock); 980 switch(pcicfgmode){ 981 982 case 1: 983 o = rno & 0x02; 984 rno &= ~0x03; 985 outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 986 if(read) 987 x = ins(PciDATA+o); 988 else 989 outs(PciDATA+o, data); 990 outl(PciADDR, 0); 991 break; 992 993 case 2: 994 outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 995 outb(PciFORWARD, BUSBNO(tbdf)); 996 if(read) 997 x = ins((0xC000|(BUSDNO(tbdf)<<8)) + rno); 998 else 999 outs((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 1000 outb(PciCSE, 0); 1001 break; 1002 } 1003 unlock(&pcicfglock); 1004 1005 return x; 1006 } 1007 1008 int 1009 pcicfgr16(Pcidev* pcidev, int rno) 1010 { 1011 return pcicfgrw16(pcidev->tbdf, rno, 0, 1); 1012 } 1013 1014 void 1015 pcicfgw16(Pcidev* pcidev, int rno, int data) 1016 { 1017 pcicfgrw16(pcidev->tbdf, rno, data, 0); 1018 } 1019 1020 static int 1021 pcicfgrw32(int tbdf, int rno, int data, int read) 1022 { 1023 int type, x; 1024 1025 if(pcicfgmode == -1) 1026 pcicfginit(); 1027 1028 if(BUSBNO(tbdf)) 1029 type = 0x01; 1030 else 1031 type = 0x00; 1032 x = -1; 1033 if(BUSDNO(tbdf) > pcimaxdno) 1034 return x; 1035 1036 lock(&pcicfglock); 1037 switch(pcicfgmode){ 1038 1039 case 1: 1040 rno &= ~0x03; 1041 outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 1042 if(read) 1043 x = inl(PciDATA); 1044 else 1045 outl(PciDATA, data); 1046 outl(PciADDR, 0); 1047 break; 1048 1049 case 2: 1050 outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 1051 outb(PciFORWARD, BUSBNO(tbdf)); 1052 if(read) 1053 x = inl((0xC000|(BUSDNO(tbdf)<<8)) + rno); 1054 else 1055 outl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 1056 outb(PciCSE, 0); 1057 break; 1058 } 1059 unlock(&pcicfglock); 1060 1061 return x; 1062 } 1063 1064 int 1065 pcicfgr32(Pcidev* pcidev, int rno) 1066 { 1067 return pcicfgrw32(pcidev->tbdf, rno, 0, 1); 1068 } 1069 1070 void 1071 pcicfgw32(Pcidev* pcidev, int rno, int data) 1072 { 1073 pcicfgrw32(pcidev->tbdf, rno, data, 0); 1074 } 1075 1076 Pcidev* 1077 pcimatch(Pcidev* prev, int vid, int did) 1078 { 1079 if(pcicfgmode == -1) 1080 pcicfginit(); 1081 1082 if(prev == nil) 1083 prev = pcilist; 1084 else 1085 prev = prev->list; 1086 1087 while(prev != nil){ 1088 if((vid == 0 || prev->vid == vid) 1089 && (did == 0 || prev->did == did)) 1090 break; 1091 prev = prev->list; 1092 } 1093 return prev; 1094 } 1095 1096 Pcidev* 1097 pcimatchtbdf(int tbdf) 1098 { 1099 Pcidev *pcidev; 1100 1101 if(pcicfgmode == -1) 1102 pcicfginit(); 1103 1104 for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) { 1105 if(pcidev->tbdf == tbdf) 1106 break; 1107 } 1108 return pcidev; 1109 } 1110 1111 uchar 1112 pciipin(Pcidev *pci, uchar pin) 1113 { 1114 if (pci == nil) 1115 pci = pcilist; 1116 1117 while (pci) { 1118 uchar intl; 1119 1120 if (pcicfgr8(pci, PciINTP) == pin && pci->intl != 0 && pci->intl != 0xff) 1121 return pci->intl; 1122 1123 if (pci->bridge && (intl = pciipin(pci->bridge, pin)) != 0) 1124 return intl; 1125 1126 pci = pci->list; 1127 } 1128 return 0; 1129 } 1130 1131 static void 1132 pcilhinv(Pcidev* p) 1133 { 1134 int i; 1135 Pcidev *t; 1136 1137 if(p == nil) { 1138 putstrn(PCICONS.output, PCICONS.ptr); 1139 p = pciroot; 1140 print("bus dev type vid did intl memory\n"); 1141 } 1142 for(t = p; t != nil; t = t->link) { 1143 print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ", 1144 BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf), 1145 t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl); 1146 1147 for(i = 0; i < nelem(p->mem); i++) { 1148 if(t->mem[i].size == 0) 1149 continue; 1150 print("%d:%.8lux %d ", i, 1151 t->mem[i].bar, t->mem[i].size); 1152 } 1153 if(t->ioa.bar || t->ioa.size) 1154 print("ioa:%.8lux %d ", t->ioa.bar, t->ioa.size); 1155 if(t->mema.bar || t->mema.size) 1156 print("mema:%.8lux %d ", t->mema.bar, t->mema.size); 1157 if(t->bridge) 1158 print("->%d", BUSBNO(t->bridge->tbdf)); 1159 print("\n"); 1160 } 1161 while(p != nil) { 1162 if(p->bridge != nil) 1163 pcilhinv(p->bridge); 1164 p = p->link; 1165 } 1166 } 1167 1168 void 1169 pcihinv(Pcidev* p) 1170 { 1171 if(pcicfgmode == -1) 1172 pcicfginit(); 1173 lock(&pcicfginitlock); 1174 pcilhinv(p); 1175 unlock(&pcicfginitlock); 1176 } 1177 1178 void 1179 pcireset(void) 1180 { 1181 Pcidev *p; 1182 1183 if(pcicfgmode == -1) 1184 pcicfginit(); 1185 1186 for(p = pcilist; p != nil; p = p->list) { 1187 /* don't mess with the bridges */ 1188 if(p->ccrb == 0x06) 1189 continue; 1190 pciclrbme(p); 1191 } 1192 } 1193 1194 void 1195 pcisetioe(Pcidev* p) 1196 { 1197 p->pcr |= IOen; 1198 pcicfgw16(p, PciPCR, p->pcr); 1199 } 1200 1201 void 1202 pciclrioe(Pcidev* p) 1203 { 1204 p->pcr &= ~IOen; 1205 pcicfgw16(p, PciPCR, p->pcr); 1206 } 1207 1208 void 1209 pcisetbme(Pcidev* p) 1210 { 1211 p->pcr |= MASen; 1212 pcicfgw16(p, PciPCR, p->pcr); 1213 } 1214 1215 void 1216 pciclrbme(Pcidev* p) 1217 { 1218 p->pcr &= ~MASen; 1219 pcicfgw16(p, PciPCR, p->pcr); 1220 } 1221 1222 void 1223 pcisetmwi(Pcidev* p) 1224 { 1225 p->pcr |= MemWrInv; 1226 pcicfgw16(p, PciPCR, p->pcr); 1227 } 1228 1229 void 1230 pciclrmwi(Pcidev* p) 1231 { 1232 p->pcr &= ~MemWrInv; 1233 pcicfgw16(p, PciPCR, p->pcr); 1234 } 1235 1236 static int 1237 pcigetpmrb(Pcidev* p) 1238 { 1239 int ptr; 1240 1241 if(p->pmrb != 0) 1242 return p->pmrb; 1243 p->pmrb = -1; 1244 1245 /* 1246 * If there are no extended capabilities implemented, 1247 * (bit 4 in the status register) assume there's no standard 1248 * power management method. 1249 * Find the capabilities pointer based on PCI header type. 1250 */ 1251 if(!(p->pcr & 0x0010)) 1252 return -1; 1253 switch(pcicfgr8(p, PciHDT)){ 1254 default: 1255 return -1; 1256 case 0: /* all other */ 1257 case 1: /* PCI to PCI bridge */ 1258 ptr = 0x34; 1259 break; 1260 case 2: /* CardBus bridge */ 1261 ptr = 0x14; 1262 break; 1263 } 1264 ptr = pcicfgr32(p, ptr); 1265 1266 while(ptr != 0){ 1267 /* 1268 * Check for validity. 1269 * Can't be in standard header and must be double 1270 * word aligned. 1271 */ 1272 if(ptr < 0x40 || (ptr & ~0xFC)) 1273 return -1; 1274 if(pcicfgr8(p, ptr) == 0x01){ 1275 p->pmrb = ptr; 1276 return ptr; 1277 } 1278 1279 ptr = pcicfgr8(p, ptr+1); 1280 } 1281 1282 return -1; 1283 } 1284 1285 int 1286 pcigetpms(Pcidev* p) 1287 { 1288 int pmcsr, ptr; 1289 1290 if((ptr = pcigetpmrb(p)) == -1) 1291 return -1; 1292 1293 /* 1294 * Power Management Register Block: 1295 * offset 0: Capability ID 1296 * 1: next item pointer 1297 * 2: capabilities 1298 * 4: control/status 1299 * 6: bridge support extensions 1300 * 7: data 1301 */ 1302 pmcsr = pcicfgr16(p, ptr+4); 1303 1304 return pmcsr & 0x0003; 1305 } 1306 1307 int 1308 pcisetpms(Pcidev* p, int state) 1309 { 1310 int ostate, pmc, pmcsr, ptr; 1311 1312 if((ptr = pcigetpmrb(p)) == -1) 1313 return -1; 1314 1315 pmc = pcicfgr16(p, ptr+2); 1316 pmcsr = pcicfgr16(p, ptr+4); 1317 ostate = pmcsr & 0x0003; 1318 pmcsr &= ~0x0003; 1319 1320 switch(state){ 1321 default: 1322 return -1; 1323 case 0: 1324 break; 1325 case 1: 1326 if(!(pmc & 0x0200)) 1327 return -1; 1328 break; 1329 case 2: 1330 if(!(pmc & 0x0400)) 1331 return -1; 1332 break; 1333 case 3: 1334 break; 1335 } 1336 pmcsr |= state; 1337 pcicfgw16(p, ptr+4, pmcsr); 1338 1339 return ostate; 1340 } 1341