1 /* 2 * PCI support code. 3 */ 4 #include "u.h" 5 #include "../port/lib.h" 6 #include "mem.h" 7 #include "dat.h" 8 #include "fns.h" 9 #include "io.h" 10 #include "../port/error.h" 11 12 #define DBG if(0) pcilog 13 14 struct 15 { 16 char output[16384]; 17 int ptr; 18 }PCICONS; 19 20 int 21 pcilog(char *fmt, ...) 22 { 23 int n; 24 va_list arg; 25 char buf[PRINTSIZE]; 26 27 va_start(arg, fmt); 28 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; 29 va_end(arg); 30 31 memmove(PCICONS.output+PCICONS.ptr, buf, n); 32 PCICONS.ptr += n; 33 return n; 34 } 35 36 enum 37 { /* configuration mechanism #1 */ 38 PciADDR = 0xCF8, /* CONFIG_ADDRESS */ 39 PciDATA = 0xCFC, /* CONFIG_DATA */ 40 41 /* configuration mechanism #2 */ 42 PciCSE = 0xCF8, /* configuration space enable */ 43 PciFORWARD = 0xCFA, /* which bus */ 44 45 MaxFNO = 7, 46 MaxUBN = 255, 47 }; 48 49 enum 50 { /* command register */ 51 IOen = (1<<0), 52 MEMen = (1<<1), 53 MASen = (1<<2), 54 MemWrInv = (1<<4), 55 PErrEn = (1<<6), 56 SErrEn = (1<<8), 57 }; 58 59 static Lock pcicfglock; 60 static QLock pcicfginitlock; 61 static int pcicfgmode = -1; 62 static int pcimaxbno = 7; 63 static int pcimaxdno; 64 static Pcidev* pciroot; 65 static Pcidev* pcilist; 66 static Pcidev* pcitail; 67 68 static int pcicfgrw32(int, int, int, int); 69 static int pcicfgrw8(int, int, int, int); 70 71 static char* bustypes[] = { 72 "CBUSI", 73 "CBUSII", 74 "EISA", 75 "FUTURE", 76 "INTERN", 77 "ISA", 78 "MBI", 79 "MBII", 80 "MCA", 81 "MPI", 82 "MPSA", 83 "NUBUS", 84 "PCI", 85 "PCMCIA", 86 "TC", 87 "VL", 88 "VME", 89 "XPRESS", 90 }; 91 92 #pragma varargck type "T" int 93 94 static int 95 tbdffmt(Fmt* fmt) 96 { 97 char *p; 98 int l, r, type, tbdf; 99 100 if((p = malloc(READSTR)) == nil) 101 return fmtstrcpy(fmt, "(tbdfconv)"); 102 103 switch(fmt->r){ 104 case 'T': 105 tbdf = va_arg(fmt->args, int); 106 type = BUSTYPE(tbdf); 107 if(type < nelem(bustypes)) 108 l = snprint(p, READSTR, bustypes[type]); 109 else 110 l = snprint(p, READSTR, "%d", type); 111 snprint(p+l, READSTR-l, ".%d.%d.%d", 112 BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf)); 113 break; 114 115 default: 116 snprint(p, READSTR, "(tbdfconv)"); 117 break; 118 } 119 r = fmtstrcpy(fmt, p); 120 free(p); 121 122 return r; 123 } 124 125 ulong 126 pcibarsize(Pcidev *p, int rno) 127 { 128 ulong v, size; 129 130 v = pcicfgrw32(p->tbdf, rno, 0, 1); 131 pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0); 132 size = pcicfgrw32(p->tbdf, rno, 0, 1); 133 if(v & 1) 134 size |= 0xFFFF0000; 135 pcicfgrw32(p->tbdf, rno, v, 0); 136 137 return -(size & ~0x0F); 138 } 139 140 static int 141 pcisizcmp(void *a, void *b) 142 { 143 Pcisiz *aa, *bb; 144 145 aa = a; 146 bb = b; 147 return aa->siz - bb->siz; 148 } 149 150 static ulong 151 pcimask(ulong v) 152 { 153 ulong m; 154 155 m = BI2BY*sizeof(v); 156 for(m = 1<<(m-1); m != 0; m >>= 1) { 157 if(m & v) 158 break; 159 } 160 161 m--; 162 if((v & m) == 0) 163 return v; 164 165 v |= m; 166 return v+1; 167 } 168 169 static void 170 pcibusmap(Pcidev *root, ulong *pmema, ulong *pioa, int wrreg) 171 { 172 Pcidev *p; 173 int ntb, i, size, rno, hole; 174 ulong v, mema, ioa, sioa, smema, base, limit; 175 Pcisiz *table, *tptr, *mtb, *itb; 176 extern void qsort(void*, long, long, int (*)(void*, void*)); 177 178 ioa = *pioa; 179 mema = *pmema; 180 181 DBG("pcibusmap wr=%d %T mem=%luX io=%luX\n", 182 wrreg, root->tbdf, mema, ioa); 183 184 ntb = 0; 185 for(p = root; p != nil; p = p->link) 186 ntb++; 187 188 ntb *= (PciCIS-PciBAR0)/4; 189 table = malloc(2*ntb*sizeof(Pcisiz)); 190 itb = table; 191 mtb = table+ntb; 192 193 /* 194 * Build a table of sizes 195 */ 196 for(p = root; p != nil; p = p->link) { 197 if(p->ccrb == 0x06) { 198 if(p->ccru == 0x04 && p->bridge != nil) { 199 sioa = ioa; 200 smema = mema; 201 pcibusmap(p->bridge, &smema, &sioa, 0); 202 203 hole = pcimask(smema-mema); 204 if(hole < (1<<20)) 205 hole = 1<<20; 206 p->mema.size = hole; 207 208 hole = pcimask(sioa-ioa); 209 if(hole < (1<<12)) 210 hole = 1<<12; 211 212 p->ioa.size = hole; 213 214 itb->dev = p; 215 itb->bar = -1; 216 itb->siz = p->ioa.size; 217 itb++; 218 219 mtb->dev = p; 220 mtb->bar = -1; 221 mtb->siz = p->mema.size; 222 mtb++; 223 } 224 if((pcicfgr8(p, PciHDT)&0x7f) != 0) 225 continue; 226 } 227 228 for(i = 0; i <= 5; i++) { 229 rno = PciBAR0 + i*4; 230 v = pcicfgrw32(p->tbdf, rno, 0, 1); 231 size = pcibarsize(p, rno); 232 if(size == 0) 233 continue; 234 235 if(v & 1) { 236 itb->dev = p; 237 itb->bar = i; 238 itb->siz = size; 239 itb++; 240 } 241 else { 242 mtb->dev = p; 243 mtb->bar = i; 244 mtb->siz = size; 245 mtb++; 246 } 247 248 p->mem[i].size = size; 249 } 250 } 251 252 /* 253 * Sort both tables IO smallest first, Memory largest 254 */ 255 qsort(table, itb-table, sizeof(Pcisiz), pcisizcmp); 256 tptr = table+ntb; 257 qsort(tptr, mtb-tptr, sizeof(Pcisiz), pcisizcmp); 258 259 /* 260 * Allocate IO address space on this bus 261 */ 262 for(tptr = table; tptr < itb; tptr++) { 263 hole = tptr->siz; 264 if(tptr->bar == -1) 265 hole = 1<<12; 266 ioa = (ioa+hole-1) & ~(hole-1); 267 268 p = tptr->dev; 269 if(tptr->bar == -1) 270 p->ioa.bar = ioa; 271 else { 272 p->pcr |= IOen; 273 p->mem[tptr->bar].bar = ioa|1; 274 if(wrreg) 275 pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), ioa|1, 0); 276 } 277 278 ioa += tptr->siz; 279 } 280 281 /* 282 * Allocate Memory address space on this bus 283 */ 284 for(tptr = table+ntb; tptr < mtb; tptr++) { 285 hole = tptr->siz; 286 if(tptr->bar == -1) 287 hole = 1<<20; 288 mema = (mema+hole-1) & ~(hole-1); 289 290 p = tptr->dev; 291 if(tptr->bar == -1) 292 p->mema.bar = mema; 293 else { 294 p->pcr |= MEMen; 295 p->mem[tptr->bar].bar = mema; 296 if(wrreg) 297 pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), mema, 0); 298 } 299 mema += tptr->siz; 300 } 301 302 *pmema = mema; 303 *pioa = ioa; 304 free(table); 305 306 if(wrreg == 0) 307 return; 308 309 /* 310 * Finally set all the bridge addresses & registers 311 */ 312 for(p = root; p != nil; p = p->link) { 313 if(p->bridge == nil) { 314 pcicfgrw8(p->tbdf, PciLTR, 64, 0); 315 316 p->pcr |= MASen; 317 pcicfgrw32(p->tbdf, PciPCR, p->pcr, 0); 318 continue; 319 } 320 321 base = p->ioa.bar; 322 limit = base+p->ioa.size-1; 323 v = pcicfgrw32(p->tbdf, PciIBR, 0, 1); 324 v = (v&0xFFFF0000)|(limit & 0xF000)|((base & 0xF000)>>8); 325 pcicfgrw32(p->tbdf, PciIBR, v, 0); 326 v = (limit & 0xFFFF0000)|(base>>16); 327 pcicfgrw32(p->tbdf, PciIUBR, v, 0); 328 329 base = p->mema.bar; 330 limit = base+p->mema.size-1; 331 v = (limit & 0xFFF00000)|((base & 0xFFF00000)>>16); 332 pcicfgrw32(p->tbdf, PciMBR, v, 0); 333 334 /* 335 * Disable memory prefetch 336 */ 337 pcicfgrw32(p->tbdf, PciPMBR, 0x0000FFFF, 0); 338 pcicfgrw8(p->tbdf, PciLTR, 64, 0); 339 340 /* 341 * Enable the bridge 342 */ 343 v = 0xFFFF0000 | IOen | MEMen | MASen; 344 pcicfgrw32(p->tbdf, PciPCR, v, 0); 345 346 sioa = p->ioa.bar; 347 smema = p->mema.bar; 348 pcibusmap(p->bridge, &smema, &sioa, 1); 349 } 350 } 351 352 static int 353 pcilscan(int bno, Pcidev** list) 354 { 355 Pcidev *p, *head, *tail; 356 int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn; 357 358 maxubn = bno; 359 head = nil; 360 tail = nil; 361 for(dno = 0; dno <= pcimaxdno; dno++){ 362 maxfno = 0; 363 for(fno = 0; fno <= maxfno; fno++){ 364 /* 365 * For this possible device, form the 366 * bus+device+function triplet needed to address it 367 * and try to read the vendor and device ID. 368 * If successful, allocate a device struct and 369 * start to fill it in with some useful information 370 * from the device's configuration space. 371 */ 372 tbdf = MKBUS(BusPCI, bno, dno, fno); 373 l = pcicfgrw32(tbdf, PciVID, 0, 1); 374 if(l == 0xFFFFFFFF || l == 0) 375 continue; 376 p = malloc(sizeof(*p)); 377 p->tbdf = tbdf; 378 p->vid = l; 379 p->did = l>>16; 380 381 if(pcilist != nil) 382 pcitail->list = p; 383 else 384 pcilist = p; 385 pcitail = p; 386 387 p->rid = pcicfgr8(p, PciRID); 388 p->ccrp = pcicfgr8(p, PciCCRp); 389 p->ccru = pcicfgr8(p, PciCCRu); 390 p->ccrb = pcicfgr8(p, PciCCRb); 391 p->pcr = pcicfgr32(p, PciPCR); 392 393 p->intl = pcicfgr8(p, PciINTL); 394 395 /* 396 * If the device is a multi-function device adjust the 397 * loop count so all possible functions are checked. 398 */ 399 hdt = pcicfgr8(p, PciHDT); 400 if(hdt & 0x80) 401 maxfno = MaxFNO; 402 403 /* 404 * If appropriate, read the base address registers 405 * and work out the sizes. 406 */ 407 switch(p->ccrb) { 408 case 0x01: /* mass storage controller */ 409 case 0x02: /* network controller */ 410 case 0x03: /* display controller */ 411 case 0x04: /* multimedia device */ 412 case 0x06: /* bridge device */ 413 case 0x07: /* simple comm. controllers */ 414 case 0x08: /* base system peripherals */ 415 case 0x09: /* input devices */ 416 case 0x0A: /* docking stations */ 417 case 0x0B: /* processors */ 418 case 0x0C: /* serial bus controllers */ 419 if((hdt & 0x7F) != 0) 420 break; 421 rno = PciBAR0 - 4; 422 for(i = 0; i < nelem(p->mem); i++) { 423 rno += 4; 424 p->mem[i].bar = pcicfgr32(p, rno); 425 p->mem[i].size = pcibarsize(p, rno); 426 } 427 break; 428 429 case 0x00: 430 case 0x05: /* memory controller */ 431 default: 432 break; 433 } 434 435 if(head != nil) 436 tail->link = p; 437 else 438 head = p; 439 tail = p; 440 } 441 } 442 443 *list = head; 444 for(p = head; p != nil; p = p->link){ 445 /* 446 * Find PCI-PCI bridges and recursively descend the tree. 447 */ 448 if(p->ccrb != 0x06 || p->ccru != 0x04) 449 continue; 450 451 /* 452 * If the secondary or subordinate bus number is not 453 * initialised try to do what the PCI BIOS should have 454 * done and fill in the numbers as the tree is descended. 455 * On the way down the subordinate bus number is set to 456 * the maximum as it's not known how many buses are behind 457 * this one; the final value is set on the way back up. 458 */ 459 sbn = pcicfgr8(p, PciSBN); 460 ubn = pcicfgr8(p, PciUBN); 461 462 if(sbn == 0 || ubn == 0) { 463 sbn = maxubn+1; 464 /* 465 * Make sure memory, I/O and master enables are 466 * off, set the primary, secondary and subordinate 467 * bus numbers and clear the secondary status before 468 * attempting to scan the secondary bus. 469 * 470 * Initialisation of the bridge should be done here. 471 */ 472 pcicfgw32(p, PciPCR, 0xFFFF0000); 473 l = (MaxUBN<<16)|(sbn<<8)|bno; 474 pcicfgw32(p, PciPBN, l); 475 pcicfgw16(p, PciSPSR, 0xFFFF); 476 maxubn = pcilscan(sbn, &p->bridge); 477 l = (maxubn<<16)|(sbn<<8)|bno; 478 479 pcicfgw32(p, PciPBN, l); 480 } 481 else { 482 maxubn = ubn; 483 pcilscan(sbn, &p->bridge); 484 } 485 } 486 487 return maxubn; 488 } 489 490 int 491 pciscan(int bno, Pcidev **list) 492 { 493 int ubn; 494 495 qlock(&pcicfginitlock); 496 ubn = pcilscan(bno, list); 497 qunlock(&pcicfginitlock); 498 return ubn; 499 } 500 501 static void 502 pcicfginit(void) 503 { 504 char *p; 505 int bno; 506 Pcidev **list; 507 ulong mema, ioa; 508 509 qlock(&pcicfginitlock); 510 if(pcicfgmode != -1) 511 goto out; 512 513 /* 514 * Try to determine which PCI configuration mode is implemented. 515 * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses 516 * a DWORD at 0xCF8 and another at 0xCFC and will pass through 517 * any non-DWORD accesses as normal I/O cycles. There shouldn't be 518 * a device behind these addresses so if Mode2 accesses fail try 519 * for Mode1 (which is preferred, Mode2 is deprecated). 520 */ 521 outb(PciCSE, 0); 522 if(inb(PciCSE) == 0){ 523 pcicfgmode = 2; 524 pcimaxdno = 15; 525 } 526 else { 527 outl(PciADDR, 0); 528 if(inl(PciADDR) == 0){ 529 pcicfgmode = 1; 530 pcimaxdno = 31; 531 } 532 } 533 534 if(pcicfgmode < 0) 535 goto out; 536 537 fmtinstall('T', tbdffmt); 538 539 if(p = getconf("*pcimaxbno")) 540 pcimaxbno = strtoul(p, 0, 0); 541 if(p = getconf("*pcimaxdno")) 542 pcimaxdno = strtoul(p, 0, 0); 543 544 list = &pciroot; 545 for(bno = 0; bno <= pcimaxbno; bno++) { 546 int sbno = bno; 547 bno = pcilscan(bno, list); 548 549 while(*list) 550 list = &(*list)->link; 551 552 if (sbno == 0) { 553 Pcidev *pci; 554 555 /* 556 * If we have found a PCI-to-Cardbus bridge, make sure 557 * it has no valid mappings anymore. 558 */ 559 pci = pciroot; 560 while (pci) { 561 if (pci->ccrb == 6 && pci->ccru == 7) { 562 ushort bcr; 563 564 /* reset the cardbus */ 565 bcr = pcicfgr16(pci, PciBCR); 566 pcicfgw16(pci, PciBCR, 0x40 | bcr); 567 delay(50); 568 } 569 pci = pci->link; 570 } 571 } 572 } 573 574 if(pciroot == nil) 575 goto out; 576 577 /* 578 * Work out how big the top bus is 579 */ 580 mema = 0; 581 ioa = 0; 582 pcibusmap(pciroot, &mema, &ioa, 0); 583 584 DBG("Sizes: mem=%8.8lux size=%8.8lux io=%8.8lux\n", 585 mema, pcimask(mema), ioa); 586 587 /* 588 * Align the windows and map it 589 */ 590 ioa = 0x1000; 591 mema = 0; 592 593 pcilog("Mask sizes: mem=%lux io=%lux\n", mema, ioa); 594 595 pcibusmap(pciroot, &mema, &ioa, 1); 596 DBG("Sizes2: mem=%lux io=%lux\n", mema, ioa); 597 598 out: 599 qunlock(&pcicfginitlock); 600 } 601 602 static int 603 pcicfgrw8(int tbdf, int rno, int data, int read) 604 { 605 int o, type, x; 606 607 if(pcicfgmode == -1) 608 pcicfginit(); 609 610 if(BUSBNO(tbdf)) 611 type = 0x01; 612 else 613 type = 0x00; 614 x = -1; 615 if(BUSDNO(tbdf) > pcimaxdno) 616 return x; 617 618 lock(&pcicfglock); 619 switch(pcicfgmode){ 620 621 case 1: 622 o = rno & 0x03; 623 rno &= ~0x03; 624 outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 625 if(read) 626 x = inb(PciDATA+o); 627 else 628 outb(PciDATA+o, data); 629 outl(PciADDR, 0); 630 break; 631 632 case 2: 633 outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 634 outb(PciFORWARD, BUSBNO(tbdf)); 635 if(read) 636 x = inb((0xC000|(BUSDNO(tbdf)<<8)) + rno); 637 else 638 outb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 639 outb(PciCSE, 0); 640 break; 641 } 642 unlock(&pcicfglock); 643 644 return x; 645 } 646 647 int 648 pcicfgr8(Pcidev* pcidev, int rno) 649 { 650 return pcicfgrw8(pcidev->tbdf, rno, 0, 1); 651 } 652 653 void 654 pcicfgw8(Pcidev* pcidev, int rno, int data) 655 { 656 pcicfgrw8(pcidev->tbdf, rno, data, 0); 657 } 658 659 static int 660 pcicfgrw16(int tbdf, int rno, int data, int read) 661 { 662 int o, type, x; 663 664 if(pcicfgmode == -1) 665 pcicfginit(); 666 667 if(BUSBNO(tbdf)) 668 type = 0x01; 669 else 670 type = 0x00; 671 x = -1; 672 if(BUSDNO(tbdf) > pcimaxdno) 673 return x; 674 675 lock(&pcicfglock); 676 switch(pcicfgmode){ 677 678 case 1: 679 o = rno & 0x02; 680 rno &= ~0x03; 681 outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 682 if(read) 683 x = ins(PciDATA+o); 684 else 685 outs(PciDATA+o, data); 686 outl(PciADDR, 0); 687 break; 688 689 case 2: 690 outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 691 outb(PciFORWARD, BUSBNO(tbdf)); 692 if(read) 693 x = ins((0xC000|(BUSDNO(tbdf)<<8)) + rno); 694 else 695 outs((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 696 outb(PciCSE, 0); 697 break; 698 } 699 unlock(&pcicfglock); 700 701 return x; 702 } 703 704 int 705 pcicfgr16(Pcidev* pcidev, int rno) 706 { 707 return pcicfgrw16(pcidev->tbdf, rno, 0, 1); 708 } 709 710 void 711 pcicfgw16(Pcidev* pcidev, int rno, int data) 712 { 713 pcicfgrw16(pcidev->tbdf, rno, data, 0); 714 } 715 716 static int 717 pcicfgrw32(int tbdf, int rno, int data, int read) 718 { 719 int type, x; 720 721 if(pcicfgmode == -1) 722 pcicfginit(); 723 724 if(BUSBNO(tbdf)) 725 type = 0x01; 726 else 727 type = 0x00; 728 x = -1; 729 if(BUSDNO(tbdf) > pcimaxdno) 730 return x; 731 732 lock(&pcicfglock); 733 switch(pcicfgmode){ 734 735 case 1: 736 rno &= ~0x03; 737 outl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 738 if(read) 739 x = inl(PciDATA); 740 else 741 outl(PciDATA, data); 742 outl(PciADDR, 0); 743 break; 744 745 case 2: 746 outb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 747 outb(PciFORWARD, BUSBNO(tbdf)); 748 if(read) 749 x = inl((0xC000|(BUSDNO(tbdf)<<8)) + rno); 750 else 751 outl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 752 outb(PciCSE, 0); 753 break; 754 } 755 unlock(&pcicfglock); 756 757 return x; 758 } 759 760 int 761 pcicfgr32(Pcidev* pcidev, int rno) 762 { 763 return pcicfgrw32(pcidev->tbdf, rno, 0, 1); 764 } 765 766 void 767 pcicfgw32(Pcidev* pcidev, int rno, int data) 768 { 769 pcicfgrw32(pcidev->tbdf, rno, data, 0); 770 } 771 772 Pcidev* 773 pcimatch(Pcidev* prev, int vid, int did) 774 { 775 if(pcicfgmode == -1) 776 pcicfginit(); 777 778 if(prev == nil) 779 prev = pcilist; 780 else 781 prev = prev->list; 782 783 while(prev != nil){ 784 if((vid == 0 || prev->vid == vid) 785 && (did == 0 || prev->did == did)) 786 break; 787 prev = prev->list; 788 } 789 return prev; 790 } 791 792 Pcidev* 793 pcimatchtbdf(int tbdf) 794 { 795 Pcidev *pcidev; 796 797 if(pcicfgmode == -1) 798 pcicfginit(); 799 800 for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) { 801 if(pcidev->tbdf == tbdf) 802 break; 803 } 804 return pcidev; 805 } 806 807 uchar 808 pciipin(Pcidev *pci, uchar pin) 809 { 810 if (pci == nil) 811 pci = pcilist; 812 813 while (pci) { 814 uchar intl; 815 816 if (pcicfgr8(pci, PciINTP) == pin && pci->intl != 0 && pci->intl != 0xff) 817 return pci->intl; 818 819 if (pci->bridge && (intl = pciipin(pci->bridge, pin)) != 0) 820 return intl; 821 822 pci = pci->list; 823 } 824 return 0; 825 } 826 827 static void 828 pcilhinv(Pcidev* p) 829 { 830 int i; 831 Pcidev *t; 832 833 if(p == nil) { 834 putstrn(PCICONS.output, PCICONS.ptr); 835 p = pciroot; 836 print("bus dev type vid did intl memory\n"); 837 } 838 for(t = p; t != nil; t = t->link) { 839 print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ", 840 BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf), 841 t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl); 842 843 for(i = 0; i < nelem(p->mem); i++) { 844 if(t->mem[i].size == 0) 845 continue; 846 print("%d:%.8lux %d ", i, 847 t->mem[i].bar, t->mem[i].size); 848 } 849 if(t->ioa.bar || t->ioa.size) 850 print("ioa:%.8lux %d ", t->ioa.bar, t->ioa.size); 851 if(t->mema.bar || t->mema.size) 852 print("mema:%.8lux %d ", t->mema.bar, t->mema.size); 853 if(t->bridge) 854 print("->%d", BUSBNO(t->bridge->tbdf)); 855 print("\n"); 856 } 857 while(p != nil) { 858 if(p->bridge != nil) 859 pcilhinv(p->bridge); 860 p = p->link; 861 } 862 } 863 864 void 865 pcihinv(Pcidev* p) 866 { 867 if(pcicfgmode == -1) 868 pcicfginit(); 869 qlock(&pcicfginitlock); 870 pcilhinv(p); 871 qunlock(&pcicfginitlock); 872 } 873 874 void 875 pcireset(void) 876 { 877 Pcidev *p; 878 int pcr; 879 880 if(pcicfgmode == -1) 881 pcicfginit(); 882 883 for(p = pcilist; p != nil; p = p->list){ 884 pcr = pcicfgr16(p, PciPCR); 885 pcr &= ~0x0004; 886 pcicfgw16(p, PciPCR, pcr); 887 } 888 } 889 890 void 891 pcisetbme(Pcidev* p) 892 { 893 int pcr; 894 895 pcr = pcicfgr16(p, PciPCR); 896 pcr |= MASen; 897 pcicfgw16(p, PciPCR, pcr); 898 } 899 900 void 901 pciclrbme(Pcidev* p) 902 { 903 int pcr; 904 905 pcr = pcicfgr16(p, PciPCR); 906 pcr &= ~MASen; 907 pcicfgw16(p, PciPCR, pcr); 908 } 909