1 /*
2 * PCI support code.
3 */
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 typedef struct Pci Pci;
13
14 struct Pci {
15 ulong id;
16 ulong cs;
17 ulong revclass;
18 ulong misc; /* cache line size, latency timer, header type, bist */
19 ulong base[6]; /* base addr regs */
20 ulong unused[5];
21 ulong intr;
22 ulong mask[6];
23 ulong trans[6];
24 };
25
26 enum {
27 /* cs bits */
28 CIoEn = (1<<0),
29 CMemEn = (1<<1),
30 CMasEn = (1<<2),
31 CSpcEn = (1<<4),
32 CParEn = (1<<6),
33 CSErrEn = (1<<8),
34
35 SMasTgtAb = (1<<24), /* master target abort */
36 SMasAb = (1<<25), /* master abort */
37 };
38
39 enum {
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 static Lock pcicfglock;
55 static Lock pcicfginitlock;
56 static int pcicfgmode = -1;
57 static int pcimaxbno = 0;
58 static int pcimaxdno;
59 static Pcidev *pciroot;
60 static Pcidev *pcilist;
61 static Pcidev *pcitail;
62 static Pci *pci = (Pci*)PCICFG;
63
64 static int pcicfgrw8(int, int, int, int);
65 static int pcicfgrw16(int, int, int, int);
66 static int pcicfgrw32(int, int, int, int);
67
68 static char* bustypes[] = {
69 "CBUSI",
70 "CBUSII",
71 "EISA",
72 "FUTURE",
73 "INTERN",
74 "ISA",
75 "MBI",
76 "MBII",
77 "MCA",
78 "MPI",
79 "MPSA",
80 "NUBUS",
81 "PCI",
82 "PCMCIA",
83 "TC",
84 "VL",
85 "VME",
86 "XPRESS",
87 };
88
89 static int
tbdffmt(Fmt * fmt)90 tbdffmt(Fmt* fmt)
91 {
92 char *p;
93 int l, r;
94 uint type, tbdf;
95
96 if((p = malloc(READSTR)) == nil)
97 return fmtstrcpy(fmt, "(tbdfconv)");
98
99 switch(fmt->r){
100 case 'T':
101 tbdf = va_arg(fmt->args, int);
102 if(tbdf == BUSUNKNOWN)
103 snprint(p, READSTR, "unknown");
104 else{
105 type = BUSTYPE(tbdf);
106 if(type < nelem(bustypes))
107 l = snprint(p, READSTR, bustypes[type]);
108 else
109 l = snprint(p, READSTR, "%d", type);
110 snprint(p+l, READSTR-l, ".%d.%d.%d",
111 BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
112 }
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
pcibarsize(Pcidev * p,int rno)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
pcilscan(int bno,Pcidev ** list)141 pcilscan(int bno, Pcidev** list)
142 {
143 Pcidev *p, *head, *tail;
144 int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
145
146 maxubn = bno;
147 head = nil;
148 tail = nil;
149 /* dno from 5 due to its address mode */
150 for(dno = 5; dno <= pcimaxdno; dno++){
151 maxfno = 0;
152 for(fno = 0; fno <= maxfno; fno++){
153 /*
154 * For this possible device, form the
155 * bus+device+function triplet needed to address it
156 * and try to read the vendor and device ID.
157 * If successful, allocate a device struct and
158 * start to fill it in with some useful information
159 * from the device's configuration space.
160 */
161 tbdf = MKBUS(BusPCI, bno, dno, fno);
162 l = pcicfgrw32(tbdf, PciVID, 0, 1);
163 if(l == 0xFFFFFFFF || l == 0)
164 continue;
165 p = malloc(sizeof(*p));
166 if(p == nil)
167 panic("pcilscan: no memory");
168 p->tbdf = tbdf;
169 p->vid = l;
170 p->did = l>>16;
171
172 if(pcilist != nil)
173 pcitail->list = p;
174 else
175 pcilist = p;
176 pcitail = p;
177
178 p->pcr = pcicfgr16(p, PciPCR);
179 p->rid = pcicfgr8(p, PciRID);
180 p->ccrp = pcicfgr8(p, PciCCRp);
181 p->ccru = pcicfgr8(p, PciCCRu);
182 p->ccrb = pcicfgr8(p, PciCCRb);
183 p->cls = pcicfgr8(p, PciCLS);
184 p->ltr = pcicfgr8(p, PciLTR);
185
186 p->intl = pcicfgr8(p, PciINTL);
187 p->intp = pcicfgr8(p, PciINTP);
188
189 /*
190 * If the device is a multi-function device adjust the
191 * loop count so all possible functions are checked.
192 */
193 hdt = pcicfgr8(p, PciHDT);
194 if(hdt & 0x80)
195 maxfno = MaxFNO;
196
197 /*
198 * If appropriate, read the base address registers
199 * and work out the sizes.
200 */
201 switch(p->ccrb) {
202 case 0x03: /* display controller */
203 /* fall through */
204 case 0x01: /* mass storage controller */
205 case 0x02: /* network controller */
206 case 0x04: /* multimedia device */
207 case 0x07: /* simple comm. controllers */
208 case 0x08: /* base system peripherals */
209 case 0x09: /* input devices */
210 case 0x0A: /* docking stations */
211 case 0x0B: /* processors */
212 case 0x0C: /* serial bus controllers */
213 if((hdt & 0x7F) != 0)
214 break;
215 rno = PciBAR0 - 4;
216 for(i = 0; i < nelem(p->mem); i++) {
217 rno += 4;
218 p->mem[i].bar = pcicfgr32(p, rno);
219 p->mem[i].size = pcibarsize(p, rno);
220 }
221 break;
222
223 case 0x00:
224 case 0x05: /* memory controller */
225 case 0x06: /* bridge device */
226 default:
227 break;
228 }
229
230 if(head != nil)
231 tail->link = p;
232 else
233 head = p;
234 tail = p;
235 }
236 }
237
238 *list = head;
239 for(p = head; p != nil; p = p->link){
240 /*
241 * Find PCI-PCI bridges and recursively descend the tree.
242 */
243 if(p->ccrb != 0x06 || p->ccru != 0x04)
244 continue;
245
246 /*
247 * If the secondary or subordinate bus number is not
248 * initialised try to do what the PCI BIOS should have
249 * done and fill in the numbers as the tree is descended.
250 * On the way down the subordinate bus number is set to
251 * the maximum as it's not known how many buses are behind
252 * this one; the final value is set on the way back up.
253 */
254 sbn = pcicfgr8(p, PciSBN);
255 ubn = pcicfgr8(p, PciUBN);
256
257 if(sbn == 0 || ubn == 0) {
258 sbn = maxubn+1;
259 /*
260 * Make sure memory, I/O and master enables are
261 * off, set the primary, secondary and subordinate
262 * bus numbers and clear the secondary status before
263 * attempting to scan the secondary bus.
264 *
265 * Initialisation of the bridge should be done here.
266 */
267 pcicfgw32(p, PciPCR, 0xFFFF0000);
268 l = (MaxUBN<<16)|(sbn<<8)|bno;
269 pcicfgw32(p, PciPBN, l);
270 pcicfgw16(p, PciSPSR, 0xFFFF);
271 maxubn = pcilscan(sbn, &p->bridge);
272 l = (maxubn<<16)|(sbn<<8)|bno;
273
274 pcicfgw32(p, PciPBN, l);
275 }
276 else {
277 if(ubn > maxubn)
278 maxubn = ubn;
279 pcilscan(sbn, &p->bridge);
280 }
281 }
282
283 return maxubn;
284 }
285
286 static void
pcicfginit(void)287 pcicfginit(void)
288 {
289 char *p;
290 int n, bno;
291 Pcidev **list;
292
293 lock(&pcicfginitlock);
294 if(pcicfgmode != -1) {
295 unlock(&pcicfginitlock);
296 return;
297 }
298
299 pcicfgmode = 1;
300 pcimaxdno = 19;
301
302 fmtinstall('T', tbdffmt);
303
304 if(p = getconf("*pcimaxbno")){
305 n = strtoul(p, 0, 0);
306 if(n < pcimaxbno)
307 pcimaxbno = n;
308 }
309 if(p = getconf("*pcimaxdno")){
310 n = strtoul(p, 0, 0);
311 if(n < pcimaxdno)
312 pcimaxdno = n;
313 }
314
315 list = &pciroot;
316 for(bno = 0; bno <= pcimaxbno; bno++){
317 bno = pcilscan(bno, list);
318 while(*list)
319 list = &(*list)->link;
320 }
321 unlock(&pcicfginitlock);
322 }
323
324 /* map the devince's cfg space and calculate the address */
325 static void*
pcidevcfgaddr(int tbdf,int rno)326 pcidevcfgaddr(int tbdf, int rno)
327 {
328 ulong addr;
329 ulong b, d, f, type;
330
331 b = BUSBNO(tbdf);
332 d = BUSDNO(tbdf);
333 f = BUSFNO(tbdf);
334 if(b == 0) {
335 /* Type 0 configuration on onboard PCI bus */
336 addr = (1<<(d+11))|(f<<8)|rno;
337 type = 0x00000;
338 } else {
339 /* Type 1 configuration on offboard PCI bus */
340 addr = (b<<16)|(d<<11)|(f<<8)|rno;
341 type = 0x10000;
342 }
343
344 /* clear aborts */
345 pci->cs |= SMasAb | SMasTgtAb;
346
347 /* config map cfg reg to map the device's cfg space */
348 *Pcimapcfg = (addr>>16)|type;
349
350 return (void*)(PCIDEVCFG+(addr&0xffff));
351 }
352
353 static int
pcicfgrw8(int tbdf,int rno,int data,int read)354 pcicfgrw8(int tbdf, int rno, int data, int read)
355 {
356 int x;
357 void *addr;
358
359 if(pcicfgmode == -1)
360 pcicfginit();
361
362 x = -1;
363 if(BUSDNO(tbdf) > pcimaxdno)
364 return x;
365
366 lock(&pcicfglock);
367 addr = pcidevcfgaddr(tbdf, rno);
368 if(read)
369 x = *(uchar*)addr;
370 else
371 *(uchar*)addr = data;
372 unlock(&pcicfglock);
373
374 return x;
375 }
376
377 int
pcicfgr8(Pcidev * pcidev,int rno)378 pcicfgr8(Pcidev* pcidev, int rno)
379 {
380 return pcicfgrw8(pcidev->tbdf, rno, 0, 1);
381 }
382
383 void
pcicfgw8(Pcidev * pcidev,int rno,int data)384 pcicfgw8(Pcidev* pcidev, int rno, int data)
385 {
386 pcicfgrw8(pcidev->tbdf, rno, data, 0);
387 }
388
389 static int
pcicfgrw16(int tbdf,int rno,int data,int read)390 pcicfgrw16(int tbdf, int rno, int data, int read)
391 {
392 int x;
393 void *addr;
394
395 if(pcicfgmode == -1)
396 pcicfginit();
397
398 x = -1;
399 if(BUSDNO(tbdf) > pcimaxdno)
400 return x;
401
402 lock(&pcicfglock);
403 addr = pcidevcfgaddr(tbdf, rno);
404 if(read)
405 x = *(ushort*)addr;
406 else
407 *(ushort*)addr = data;
408 unlock(&pcicfglock);
409
410 return x;
411 }
412
413 int
pcicfgr16(Pcidev * pcidev,int rno)414 pcicfgr16(Pcidev* pcidev, int rno)
415 {
416 return pcicfgrw16(pcidev->tbdf, rno, 0, 1);
417 }
418
419 void
pcicfgw16(Pcidev * pcidev,int rno,int data)420 pcicfgw16(Pcidev* pcidev, int rno, int data)
421 {
422 pcicfgrw16(pcidev->tbdf, rno, data, 0);
423 }
424
425 static int
pcicfgrw32(int tbdf,int rno,int data,int read)426 pcicfgrw32(int tbdf, int rno, int data, int read)
427 {
428 int x;
429 void *addr;
430
431 if(pcicfgmode == -1)
432 pcicfginit();
433
434 x = -1;
435 if(BUSDNO(tbdf) > pcimaxdno)
436 return x;
437
438 lock(&pcicfglock);
439 addr = pcidevcfgaddr(tbdf, rno);
440 if(read)
441 x = *(ulong*)addr;
442 else
443 *(ulong*)addr = data;
444 unlock(&pcicfglock);
445
446 return x;
447 }
448
449 int
pcicfgr32(Pcidev * pcidev,int rno)450 pcicfgr32(Pcidev* pcidev, int rno)
451 {
452 return pcicfgrw32(pcidev->tbdf, rno, 0, 1);
453 }
454
455 void
pcicfgw32(Pcidev * pcidev,int rno,int data)456 pcicfgw32(Pcidev* pcidev, int rno, int data)
457 {
458 pcicfgrw32(pcidev->tbdf, rno, data, 0);
459 }
460
461 Pcidev*
pcimatch(Pcidev * prev,int vid,int did)462 pcimatch(Pcidev* prev, int vid, int did)
463 {
464 if(pcicfgmode == -1)
465 pcicfginit();
466
467 if(prev == nil)
468 prev = pcilist;
469 else
470 prev = prev->list;
471
472 while(prev != nil){
473 if((vid == 0 || prev->vid == vid)
474 && (did == 0 || prev->did == did))
475 break;
476 prev = prev->list;
477 }
478 return prev;
479 }
480
481 Pcidev*
pcimatchtbdf(int tbdf)482 pcimatchtbdf(int tbdf)
483 {
484 Pcidev *pcidev;
485
486 if(pcicfgmode == -1)
487 pcicfginit();
488
489 for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) {
490 if(pcidev->tbdf == tbdf)
491 break;
492 }
493 return pcidev;
494 }
495
496 void
pcireset(void)497 pcireset(void)
498 {
499 Pcidev *p;
500
501 if(pcicfgmode == -1)
502 pcicfginit();
503
504 for(p = pcilist; p != nil; p = p->list) {
505 /* don't mess with the bridges */
506 if(p->ccrb == 0x06)
507 continue;
508 pciclrbme(p);
509 }
510 }
511
512 void
pcisetioe(Pcidev * p)513 pcisetioe(Pcidev* p)
514 {
515 p->pcr |= IOen;
516 pcicfgw16(p, PciPCR, p->pcr);
517 }
518
519 void
pciclrioe(Pcidev * p)520 pciclrioe(Pcidev* p)
521 {
522 p->pcr &= ~IOen;
523 pcicfgw16(p, PciPCR, p->pcr);
524 }
525
526 void
pcisetbme(Pcidev * p)527 pcisetbme(Pcidev* p)
528 {
529 p->pcr |= MASen;
530 pcicfgw16(p, PciPCR, p->pcr);
531 }
532
533 void
pciclrbme(Pcidev * p)534 pciclrbme(Pcidev* p)
535 {
536 p->pcr &= ~MASen;
537 pcicfgw16(p, PciPCR, p->pcr);
538 }
539
540 void
pcisetmwi(Pcidev * p)541 pcisetmwi(Pcidev* p)
542 {
543 p->pcr |= MemWrInv;
544 pcicfgw16(p, PciPCR, p->pcr);
545 }
546
547 void
pciclrmwi(Pcidev * p)548 pciclrmwi(Pcidev* p)
549 {
550 p->pcr &= ~MemWrInv;
551 pcicfgw16(p, PciPCR, p->pcr);
552 }
553
554 static int
pcigetpmrb(Pcidev * p)555 pcigetpmrb(Pcidev* p)
556 {
557 int ptr;
558
559 if(p->pmrb != 0)
560 return p->pmrb;
561 p->pmrb = -1;
562
563 /*
564 * If there are no extended capabilities implemented,
565 * (bit 4 in the status register) assume there's no standard
566 * power management method.
567 * Find the capabilities pointer based on PCI header type.
568 */
569 if(!(pcicfgr16(p, PciPSR) & 0x0010))
570 return -1;
571 switch(pcicfgr8(p, PciHDT)){
572 default:
573 return -1;
574 case 0: /* all other */
575 case 1: /* PCI to PCI bridge */
576 ptr = 0x34;
577 break;
578 case 2: /* CardBus bridge */
579 ptr = 0x14;
580 break;
581 }
582 ptr = pcicfgr32(p, ptr);
583
584 while(ptr != 0){
585 /*
586 * Check for validity.
587 * Can't be in standard header and must be double
588 * word aligned.
589 */
590 if(ptr < 0x40 || (ptr & ~0xFC))
591 return -1;
592 if(pcicfgr8(p, ptr) == 0x01){
593 p->pmrb = ptr;
594 return ptr;
595 }
596
597 ptr = pcicfgr8(p, ptr+1);
598 }
599
600 return -1;
601 }
602
603 int
pcigetpms(Pcidev * p)604 pcigetpms(Pcidev* p)
605 {
606 int pmcsr, ptr;
607
608 if((ptr = pcigetpmrb(p)) == -1)
609 return -1;
610
611 /*
612 * Power Management Register Block:
613 * offset 0: Capability ID
614 * 1: next item pointer
615 * 2: capabilities
616 * 4: control/status
617 * 6: bridge support extensions
618 * 7: data
619 */
620 pmcsr = pcicfgr16(p, ptr+4);
621
622 return pmcsr & 0x0003;
623 }
624
625 int
pcisetpms(Pcidev * p,int state)626 pcisetpms(Pcidev* p, int state)
627 {
628 int ostate, pmc, pmcsr, ptr;
629
630 if((ptr = pcigetpmrb(p)) == -1)
631 return -1;
632
633 pmc = pcicfgr16(p, ptr+2);
634 pmcsr = pcicfgr16(p, ptr+4);
635 ostate = pmcsr & 0x0003;
636 pmcsr &= ~0x0003;
637
638 switch(state){
639 default:
640 return -1;
641 case 0:
642 break;
643 case 1:
644 if(!(pmc & 0x0200))
645 return -1;
646 break;
647 case 2:
648 if(!(pmc & 0x0400))
649 return -1;
650 break;
651 case 3:
652 break;
653 }
654 pmcsr |= state;
655 pcicfgw16(p, ptr+4, pmcsr);
656
657 return ostate;
658 }
659
660 int
pcisubirq(int tbdf)661 pcisubirq(int tbdf)
662 {
663 return Pciintrbase + pcicfgrw8(tbdf, PciINTP, 0, 1);
664 }
665