1 /*
2 * from 9front
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 #include "pci.h"
12
13 #define PCIWIN 0x0600000000ULL
14
15 /* bcmstb PCIe controller registers */
16 enum{
17 RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 = 0x0188/4,
18 RC_CFG_PRIV1_ID_VAL3 = 0x043c/4,
19 RC_DL_MDIO_ADDR = 0x1100/4,
20 RC_DL_MDIO_WR_DATA = 0x1104/4,
21 RC_DL_MDIO_RD_DATA = 0x1108/4,
22 MISC_MISC_CTRL = 0x4008/4,
23 MISC_CPU_2_PCIE_MEM_WIN0_LO = 0x400c/4,
24 MISC_CPU_2_PCIE_MEM_WIN0_HI = 0x4010/4,
25 MISC_RC_BAR1_CONFIG_LO = 0x402c/4,
26 MISC_RC_BAR2_CONFIG_LO = 0x4034/4,
27 MISC_RC_BAR2_CONFIG_HI = 0x4038/4,
28 MISC_RC_BAR3_CONFIG_LO = 0x403c/4,
29 MISC_MSI_BAR_CONFIG_LO = 0x4044/4,
30 MISC_MSI_BAR_CONFIG_HI = 0x4048/4,
31 MISC_MSI_DATA_CONFIG = 0x404c/4,
32 MISC_EOI_CTRL = 0x4060/4,
33 MISC_PCIE_CTRL = 0x4064/4,
34 MISC_PCIE_STATUS = 0x4068/4,
35 MISC_REVISION = 0x406c/4,
36 MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT = 0x4070/4,
37 MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI = 0x4080/4,
38 MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI = 0x4084/4,
39 MISC_HARD_PCIE_HARD_DEBUG = 0x4204/4,
40
41 INTR2_CPU_BASE = 0x4300/4,
42 MSI_INTR2_BASE = 0x4500/4,
43 INTR_STATUS = 0,
44 INTR_SET,
45 INTR_CLR,
46 INTR_MASK_STATUS,
47 INTR_MASK_SET,
48 INTR_MASK_CLR,
49
50 EXT_CFG_INDEX = 0x9000/4,
51 RGR1_SW_INIT_1 = 0x9210/4,
52 EXT_CFG_DATA = 0x8000/4,
53
54 };
55
56 #define MSI_TARGET_ADDR 0xFFFFFFFFCULL
57
58 static u32int *regs = (u32int*)(VIRTIO + 0x500000);
59
60 static Lock pcicfglock;
61 static int pcimaxbno = 0;
62 static int pcimaxdno = 0;
63 static Pcidev* pciroot;
64 static Pcidev* pcilist;
65 static Pcidev* pcitail;
66
67 typedef struct Pcisiz Pcisiz;
68 struct Pcisiz
69 {
70 Pcidev* dev;
71 int siz;
72 int bar;
73 };
74
75 enum
76 {
77 MaxFNO = 7,
78 MaxUBN = 255,
79 };
80
81 static char* bustypes[] = {
82 "CBUSI",
83 "CBUSII",
84 "EISA",
85 "FUTURE",
86 "INTERN",
87 "ISA",
88 "MBI",
89 "MBII",
90 "MCA",
91 "MPI",
92 "MPSA",
93 "NUBUS",
94 "PCI",
95 "PCMCIA",
96 "TC",
97 "VL",
98 "VME",
99 "XPRESS",
100 };
101
102 static int
tbdffmt(Fmt * fmt)103 tbdffmt(Fmt* fmt)
104 {
105 char *p;
106 int l, r;
107 uint type, tbdf;
108
109 if((p = malloc(READSTR)) == nil)
110 return fmtstrcpy(fmt, "(tbdfconv)");
111
112 switch(fmt->r){
113 case 'T':
114 tbdf = va_arg(fmt->args, int);
115 if(tbdf == BUSUNKNOWN)
116 snprint(p, READSTR, "unknown");
117 else{
118 type = BUSTYPE(tbdf);
119 if(type < nelem(bustypes))
120 l = snprint(p, READSTR, bustypes[type]);
121 else
122 l = snprint(p, READSTR, "%d", type);
123 snprint(p+l, READSTR-l, ".%d.%d.%d",
124 BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
125 }
126 break;
127
128 default:
129 snprint(p, READSTR, "(tbdfconv)");
130 break;
131 }
132 r = fmtstrcpy(fmt, p);
133 free(p);
134
135 return r;
136 }
137
138 static void pcicfginit(void);
139
140 static void*
cfgaddr(int tbdf,int rno)141 cfgaddr(int tbdf, int rno)
142 {
143 if(BUSBNO(tbdf) == 0 && BUSDNO(tbdf) == 0)
144 return (uchar*)regs + rno;
145 regs[EXT_CFG_INDEX] = BUSBNO(tbdf) << 20 | BUSDNO(tbdf) << 15 | BUSFNO(tbdf) << 12;
146 coherence();
147 return ((uchar*)®s[EXT_CFG_DATA]) + rno;
148 }
149
150 static int
pcicfgrw32(int tbdf,int rno,int data,int read)151 pcicfgrw32(int tbdf, int rno, int data, int read)
152 {
153 int x = -1;
154 u32int *p;
155
156 ilock(&pcicfglock);
157 if((p = cfgaddr(tbdf, rno & ~3)) != nil){
158 if(read)
159 x = *p;
160 else
161 *p = data;
162 }
163 iunlock(&pcicfglock);
164 return x;
165 }
166 static int
pcicfgrw16(int tbdf,int rno,int data,int read)167 pcicfgrw16(int tbdf, int rno, int data, int read)
168 {
169 int x = -1;
170 u16int *p;
171
172 ilock(&pcicfglock);
173 if((p = cfgaddr(tbdf, rno & ~1)) != nil){
174 if(read)
175 x = *p;
176 else
177 *p = data;
178 }
179 iunlock(&pcicfglock);
180 return x;
181 }
182 static int
pcicfgrw8(int tbdf,int rno,int data,int read)183 pcicfgrw8(int tbdf, int rno, int data, int read)
184 {
185 int x = -1;
186 u8int *p;
187
188 ilock(&pcicfglock);
189 if((p = cfgaddr(tbdf, rno)) != nil){
190 if(read)
191 x = *p;
192 else
193 *p = data;
194 }
195 iunlock(&pcicfglock);
196 return x;
197 }
198
199 int
pcicfgr32(Pcidev * pcidev,int rno)200 pcicfgr32(Pcidev* pcidev, int rno)
201 {
202 return pcicfgrw32(pcidev->tbdf, rno, 0, 1);
203 }
204 void
pcicfgw32(Pcidev * pcidev,int rno,int data)205 pcicfgw32(Pcidev* pcidev, int rno, int data)
206 {
207 pcicfgrw32(pcidev->tbdf, rno, data, 0);
208 }
209 int
pcicfgr16(Pcidev * pcidev,int rno)210 pcicfgr16(Pcidev* pcidev, int rno)
211 {
212 return pcicfgrw16(pcidev->tbdf, rno, 0, 1);
213 }
214 void
pcicfgw16(Pcidev * pcidev,int rno,int data)215 pcicfgw16(Pcidev* pcidev, int rno, int data)
216 {
217 pcicfgrw16(pcidev->tbdf, rno, data, 0);
218 }
219 int
pcicfgr8(Pcidev * pcidev,int rno)220 pcicfgr8(Pcidev* pcidev, int rno)
221 {
222 return pcicfgrw8(pcidev->tbdf, rno, 0, 1);
223 }
224 void
pcicfgw8(Pcidev * pcidev,int rno,int data)225 pcicfgw8(Pcidev* pcidev, int rno, int data)
226 {
227 pcicfgrw8(pcidev->tbdf, rno, data, 0);
228 }
229
230 Pcidev*
pcimatch(Pcidev * prev,int vid,int did)231 pcimatch(Pcidev* prev, int vid, int did)
232 {
233 if(prev == nil)
234 prev = pcilist;
235 else
236 prev = prev->list;
237
238 while(prev != nil){
239 if((vid == 0 || prev->vid == vid)
240 && (did == 0 || prev->did == did))
241 break;
242 prev = prev->list;
243 }
244 return prev;
245 }
246
247 Pcidev*
pcimatchtbdf(int tbdf)248 pcimatchtbdf(int tbdf)
249 {
250 Pcidev *pcidev;
251
252 for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) {
253 if(pcidev->tbdf == tbdf)
254 break;
255 }
256 return pcidev;
257 }
258
259 static u32int
pcibarsize(Pcidev * p,int rno)260 pcibarsize(Pcidev *p, int rno)
261 {
262 u32int v, size;
263
264 v = pcicfgrw32(p->tbdf, rno, 0, 1);
265 pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0);
266 size = pcicfgrw32(p->tbdf, rno, 0, 1);
267 if(v & 1)
268 size |= 0xFFFF0000;
269 pcicfgrw32(p->tbdf, rno, v, 0);
270
271 return -(size & ~0x0F);
272 }
273
274 static int
pcisizcmp(void * a,void * b)275 pcisizcmp(void *a, void *b)
276 {
277 Pcisiz *aa, *bb;
278
279 aa = a;
280 bb = b;
281 return aa->siz - bb->siz;
282 }
283
284 static ulong
pcimask(ulong v)285 pcimask(ulong v)
286 {
287 ulong m;
288
289 m = BI2BY*sizeof(v);
290 for(m = 1<<(m-1); m != 0; m >>= 1) {
291 if(m & v)
292 break;
293 }
294
295 m--;
296 if((v & m) == 0)
297 return v;
298
299 v |= m;
300 return v+1;
301 }
302
303 static void
pcibusmap(Pcidev * root,uintpci * pmema,uintpci * pioa,int wrreg)304 pcibusmap(Pcidev *root, uintpci *pmema, uintpci *pioa, int wrreg)
305 {
306 Pcidev *p;
307 int ntb, i, size, rno, hole;
308 uintpci v, mema, ioa, sioa, smema, base, limit;
309 Pcisiz *table, *tptr, *mtb, *itb;
310
311 ioa = *pioa;
312 mema = *pmema;
313
314 ntb = 0;
315 for(p = root; p != nil; p = p->link)
316 ntb++;
317
318 ntb *= (PciCIS-PciBAR0)/4;
319 table = malloc(2*ntb*sizeof(Pcisiz));
320 if(table == nil)
321 panic("pcibusmap: can't allocate memory");
322 itb = table;
323 mtb = table+ntb;
324
325 /*
326 * Build a table of sizes
327 */
328 for(p = root; p != nil; p = p->link) {
329 if(p->ccrb == 0x06) {
330 if(p->ccru != 0x04 || p->bridge == nil)
331 continue;
332
333 sioa = ioa;
334 smema = mema;
335 pcibusmap(p->bridge, &smema, &sioa, 0);
336
337 hole = pcimask(smema-mema);
338 if(hole < (1<<20))
339 hole = 1<<20;
340 p->mema.size = hole;
341
342 hole = pcimask(sioa-ioa);
343 if(hole < (1<<12))
344 hole = 1<<12;
345
346 p->ioa.size = hole;
347
348 itb->dev = p;
349 itb->bar = -1;
350 itb->siz = p->ioa.size;
351 itb++;
352
353 mtb->dev = p;
354 mtb->bar = -1;
355 mtb->siz = p->mema.size;
356 mtb++;
357 continue;
358 }
359
360 for(i = 0; i <= 5; i++) {
361 rno = PciBAR0 + i*4;
362 v = pcicfgrw32(p->tbdf, rno, 0, 1);
363 size = pcibarsize(p, rno);
364 if(size == 0)
365 continue;
366
367 p->mem[i].size = size;
368 if(v & 1) {
369 itb->dev = p;
370 itb->bar = i;
371 itb->siz = size;
372 itb++;
373 }
374 else {
375 mtb->dev = p;
376 mtb->bar = i;
377 mtb->siz = size;
378 mtb++;
379
380 if((v & 7) == 4)
381 i++;
382 }
383 }
384 }
385
386 /*
387 * Sort both tables IO smallest first, Memory largest
388 */
389 qsort(table, itb-table, sizeof(Pcisiz), pcisizcmp);
390 tptr = table+ntb;
391 qsort(tptr, mtb-tptr, sizeof(Pcisiz), pcisizcmp);
392
393 /*
394 * Allocate IO address space on this bus
395 */
396 for(tptr = table; tptr < itb; tptr++) {
397 hole = tptr->siz;
398 if(tptr->bar == -1)
399 hole = 1<<12;
400 ioa = (ioa+hole-1) & ~(hole-1);
401
402 p = tptr->dev;
403 if(tptr->bar == -1)
404 p->ioa.bar = ioa;
405 else {
406 p->pcr |= IOen;
407 p->mem[tptr->bar].bar = ioa|1;
408 if(wrreg)
409 pcicfgrw32(p->tbdf, PciBAR0+(tptr->bar*4), ioa|1, 0);
410 }
411
412 ioa += tptr->siz;
413 }
414
415 /*
416 * Allocate Memory address space on this bus
417 */
418 for(tptr = table+ntb; tptr < mtb; tptr++) {
419 hole = tptr->siz;
420 if(tptr->bar == -1)
421 hole = 1<<20;
422 mema = (mema+hole-1) & ~(hole-1);
423
424 p = tptr->dev;
425 if(tptr->bar == -1)
426 p->mema.bar = mema;
427 else {
428 p->pcr |= MEMen;
429 p->mem[tptr->bar].bar = mema;
430 if(wrreg){
431 rno = PciBAR0+(tptr->bar*4);
432 if((mema >> 32) != 0){
433 pcicfgrw32(p->tbdf, rno, mema|4, 0);
434 pcicfgrw32(p->tbdf, rno+4, mema >> 32, 0);
435 } else {
436 pcicfgrw32(p->tbdf, rno, mema, 0);
437 }
438 }
439 }
440 mema += tptr->siz;
441 }
442
443 *pmema = mema;
444 *pioa = ioa;
445 free(table);
446
447 if(wrreg == 0)
448 return;
449
450 /*
451 * Finally set all the bridge addresses & registers
452 */
453 for(p = root; p != nil; p = p->link) {
454 if(p->bridge == nil) {
455 if(p->cls == 0){
456 p->cls = 64;
457 pcicfgw8(p, PciCLS, p->cls);
458 }
459 pcicfgrw8(p->tbdf, PciLTR, 64, 0);
460 p->pcr |= MASen;
461 pcicfgrw16(p->tbdf, PciPCR, p->pcr, 0);
462 continue;
463 }
464
465 if(p == pciroot){
466 base = p->mema.bar;
467 limit = base+p->mema.size-1;
468 regs[MISC_CPU_2_PCIE_MEM_WIN0_LO] = base;
469 regs[MISC_CPU_2_PCIE_MEM_WIN0_HI] = base >> 32;
470 base >>= 20, limit >>= 20;
471 regs[MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT] = (base & 0xFFF) << 4 | (limit & 0xFFF) << 20;
472 regs[MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI] = base >> 12;
473 regs[MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI] = limit >> 12;
474 }
475
476 base = p->ioa.bar;
477 limit = base+p->ioa.size-1;
478 v = pcicfgrw32(p->tbdf, PciIBR, 0, 1);
479 v = (v&0xFFFF0000)|(limit & 0xF000)|((base & 0xF000)>>8);
480 pcicfgrw32(p->tbdf, PciIBR, v, 0);
481 v = (limit & 0xFFFF0000)|(base>>16);
482 pcicfgrw32(p->tbdf, PciIUBR, v, 0);
483
484 base = p->mema.bar;
485 limit = base+p->mema.size-1;
486 v = (limit & 0xFFF00000)|((base & 0xFFF00000)>>16);
487 pcicfgrw32(p->tbdf, PciMBR, v, 0);
488
489 /*
490 * Disable memory prefetch
491 */
492 pcicfgrw32(p->tbdf, PciPMBR, 0x0000FFFF, 0);
493 pcicfgrw8(p->tbdf, PciLTR, 64, 0);
494
495 /*
496 * Enable the bridge
497 */
498 p->pcr |= IOen|MEMen|MASen;
499 pcicfgrw32(p->tbdf, PciPCR, 0xFFFF0000|p->pcr, 0);
500
501 sioa = p->ioa.bar;
502 smema = p->mema.bar;
503 pcibusmap(p->bridge, &smema, &sioa, 1);
504 }
505 }
506
507 static int
pcilscan(int bno,Pcidev ** list,Pcidev * parent)508 pcilscan(int bno, Pcidev** list, Pcidev *parent)
509 {
510 Pcidev *p, *head, *tail;
511 int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
512
513 maxubn = bno;
514 head = nil;
515 tail = nil;
516 for(dno = 0; dno <= pcimaxdno; dno++){
517 maxfno = 0;
518 for(fno = 0; fno <= maxfno; fno++){
519 /*
520 * For this possible device, form the
521 * bus+device+function triplet needed to address it
522 * and try to read the vendor and device ID.
523 * If successful, allocate a device struct and
524 * start to fill it in with some useful information
525 * from the device's configuration space.
526 */
527 tbdf = MKBUS(BusPCI, bno, dno, fno);
528 l = pcicfgrw32(tbdf, PciVID, 0, 1);
529 if(l == 0xFFFFFFFF || l == 0)
530 continue;
531 p = malloc(sizeof(*p));
532 if(p == nil)
533 panic("pcilscan: no memory");
534 p->tbdf = tbdf;
535 p->vid = l;
536 p->did = l>>16;
537
538 if(pcilist != nil)
539 pcitail->list = p;
540 else
541 pcilist = p;
542 pcitail = p;
543
544 p->pcr = pcicfgr16(p, PciPCR);
545 p->rid = pcicfgr8(p, PciRID);
546 p->ccrp = pcicfgr8(p, PciCCRp);
547 p->ccru = pcicfgr8(p, PciCCRu);
548 p->ccrb = pcicfgr8(p, PciCCRb);
549 p->cls = pcicfgr8(p, PciCLS);
550 p->ltr = pcicfgr8(p, PciLTR);
551
552 p->intl = pcicfgr8(p, PciINTL);
553
554 /*
555 * If the device is a multi-function device adjust the
556 * loop count so all possible functions are checked.
557 */
558 hdt = pcicfgr8(p, PciHDT);
559 if(hdt & 0x80)
560 maxfno = MaxFNO;
561
562 /*
563 * If appropriate, read the base address registers
564 * and work out the sizes.
565 */
566 switch(p->ccrb) {
567 case 0x00: /* prehistoric */
568 case 0x01: /* mass storage controller */
569 case 0x02: /* network controller */
570 case 0x03: /* display controller */
571 case 0x04: /* multimedia device */
572 case 0x07: /* simple comm. controllers */
573 case 0x08: /* base system peripherals */
574 case 0x09: /* input devices */
575 case 0x0A: /* docking stations */
576 case 0x0B: /* processors */
577 case 0x0C: /* serial bus controllers */
578 case 0x0D: /* wireless controllers */
579 case 0x0E: /* intelligent I/O controllers */
580 case 0x0F: /* sattelite communication controllers */
581 case 0x10: /* encryption/decryption controllers */
582 case 0x11: /* signal processing controllers */
583 if((hdt & 0x7F) != 0)
584 break;
585 rno = PciBAR0;
586 for(i = 0; i <= 5; i++) {
587 p->mem[i].bar = pcicfgr32(p, rno);
588 p->mem[i].size = pcibarsize(p, rno);
589 if((p->mem[i].bar & 7) == 4 && i < 5){
590 rno += 4;
591 p->mem[i].bar |= (uintpci)pcicfgr32(p, rno) << 32;
592 i++;
593 }
594 rno += 4;
595 }
596 break;
597
598 case 0x05: /* memory controller */
599 case 0x06: /* bridge device */
600 default:
601 break;
602 }
603
604 p->parent = parent;
605 if(head != nil)
606 tail->link = p;
607 else
608 head = p;
609 tail = p;
610 }
611 }
612
613 *list = head;
614 for(p = head; p != nil; p = p->link){
615 /*
616 * Find PCI-PCI bridges and recursively descend the tree.
617 */
618 if(p->ccrb != 0x06 || p->ccru != 0x04)
619 continue;
620
621 /*
622 * If the secondary or subordinate bus number is not
623 * initialised try to do what the PCI BIOS should have
624 * done and fill in the numbers as the tree is descended.
625 * On the way down the subordinate bus number is set to
626 * the maximum as it's not known how many buses are behind
627 * this one; the final value is set on the way back up.
628 */
629 sbn = pcicfgr8(p, PciSBN);
630 ubn = pcicfgr8(p, PciUBN);
631
632 if(sbn == 0 || ubn == 0) {
633 sbn = maxubn+1;
634 /*
635 * Make sure memory, I/O and master enables are
636 * off, set the primary, secondary and subordinate
637 * bus numbers and clear the secondary status before
638 * attempting to scan the secondary bus.
639 *
640 * Initialisation of the bridge should be done here.
641 */
642 pcicfgw32(p, PciPCR, 0xFFFF0000);
643 l = (MaxUBN<<16)|(sbn<<8)|bno;
644 pcicfgw32(p, PciPBN, l);
645 pcicfgw16(p, PciSPSR, 0xFFFF);
646 maxubn = pcilscan(sbn, &p->bridge, p);
647 l = (maxubn<<16)|(sbn<<8)|bno;
648
649 pcicfgw32(p, PciPBN, l);
650 }
651 else {
652 if(ubn > maxubn)
653 maxubn = ubn;
654 pcilscan(sbn, &p->bridge, p);
655 }
656 }
657
658 return maxubn;
659 }
660
661 static void
pcicfginit(void)662 pcicfginit(void)
663 {
664 uintpci mema, ioa;
665
666 fmtinstall('T', tbdffmt);
667
668 pcilscan(0, &pciroot, nil);
669
670 /*
671 * Work out how big the top bus is
672 */
673 ioa = 0;
674 mema = 0;
675 pcibusmap(pciroot, &mema, &ioa, 0);
676
677 /*
678 * Align the windows and map it
679 */
680 ioa = 0;
681 mema = PCIWIN;
682 pcibusmap(pciroot, &mema, &ioa, 1);
683 }
684
685 static void
pcilhinv(Pcidev * p)686 pcilhinv(Pcidev* p)
687 {
688 int i;
689 Pcidev *t;
690
691 if(p == nil) {
692 p = pciroot;
693 print("pci dev type vid did intl memory\n");
694 }
695 for(t = p; t != nil; t = t->link) {
696 print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ",
697 BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf),
698 t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl);
699
700 for(i = 0; i < nelem(p->mem); i++) {
701 if(t->mem[i].size == 0)
702 continue;
703 print("%d:%llux %d ", i,
704 (uvlong)t->mem[i].bar, t->mem[i].size);
705 }
706 if(t->bridge)
707 print("->%d", BUSBNO(t->bridge->tbdf));
708 print("\n");
709 }
710 while(p != nil) {
711 if(p->bridge != nil)
712 pcilhinv(p->bridge);
713 p = p->link;
714 }
715 }
716
717 static void
pcihinv(Pcidev * p)718 pcihinv(Pcidev* p)
719 {
720 pcilhinv(p);
721 }
722
723 void
pcisetioe(Pcidev * p)724 pcisetioe(Pcidev* p)
725 {
726 p->pcr |= IOen;
727 pcicfgw16(p, PciPCR, p->pcr);
728 }
729
730 void
pciclrioe(Pcidev * p)731 pciclrioe(Pcidev* p)
732 {
733 p->pcr &= ~IOen;
734 pcicfgw16(p, PciPCR, p->pcr);
735 }
736
737 void
pcisetbme(Pcidev * p)738 pcisetbme(Pcidev* p)
739 {
740 p->pcr |= MASen;
741 pcicfgw16(p, PciPCR, p->pcr);
742 }
743
744 void
pciclrbme(Pcidev * p)745 pciclrbme(Pcidev* p)
746 {
747 p->pcr &= ~MASen;
748 pcicfgw16(p, PciPCR, p->pcr);
749 }
750
751 void
pcisetmwi(Pcidev * p)752 pcisetmwi(Pcidev* p)
753 {
754 p->pcr |= MemWrInv;
755 pcicfgw16(p, PciPCR, p->pcr);
756 }
757
758 void
pciclrmwi(Pcidev * p)759 pciclrmwi(Pcidev* p)
760 {
761 p->pcr &= ~MemWrInv;
762 pcicfgw16(p, PciPCR, p->pcr);
763 }
764
765 static int
enumcaps(Pcidev * p,int (* fmatch)(Pcidev *,int,int,int),int arg)766 enumcaps(Pcidev *p, int (*fmatch)(Pcidev*, int, int, int), int arg)
767 {
768 int i, r, cap, off;
769
770 /* status register bit 4 has capabilities */
771 if((pcicfgr16(p, PciPSR) & 1<<4) == 0)
772 return -1;
773 switch(pcicfgr8(p, PciHDT) & 0x7F){
774 default:
775 return -1;
776 case 0: /* etc */
777 case 1: /* pci to pci bridge */
778 off = 0x34;
779 break;
780 case 2: /* cardbus bridge */
781 off = 0x14;
782 break;
783 }
784 for(i = 48; i--;){
785 off = pcicfgr8(p, off);
786 if(off < 0x40 || (off & 3))
787 break;
788 off &= ~3;
789 cap = pcicfgr8(p, off);
790 if(cap == 0xff)
791 break;
792 r = (*fmatch)(p, cap, off, arg);
793 if(r < 0)
794 break;
795 if(r == 0)
796 return off;
797 off++;
798 }
799 return -1;
800 }
801
802 static int
matchcap(Pcidev *,int cap,int,int arg)803 matchcap(Pcidev *, int cap, int, int arg)
804 {
805 return cap != arg;
806 }
807
808 static int
matchhtcap(Pcidev * p,int cap,int off,int arg)809 matchhtcap(Pcidev *p, int cap, int off, int arg)
810 {
811 int mask;
812
813 if(cap != PciCapHTC)
814 return 1;
815 if(arg == 0x00 || arg == 0x20)
816 mask = 0xE0;
817 else
818 mask = 0xF8;
819 cap = pcicfgr8(p, off+3);
820 return (cap & mask) != arg;
821 }
822
823 int
pcicap(Pcidev * p,int cap)824 pcicap(Pcidev *p, int cap)
825 {
826 return enumcaps(p, matchcap, cap);
827 }
828
829 int
pcinextcap(Pcidev * pci,int offset)830 pcinextcap(Pcidev *pci, int offset)
831 {
832 if(offset == 0) {
833 if((pcicfgr16(pci, PciPSR) & (1<<4)) == 0)
834 return 0; /* no capabilities */
835 offset = PciCAP-1;
836 }
837 return pcicfgr8(pci, offset+1) & ~3;
838 }
839
840 int
pcihtcap(Pcidev * p,int cap)841 pcihtcap(Pcidev *p, int cap)
842 {
843 return enumcaps(p, matchhtcap, cap);
844 }
845
846 static int
pcigetpmrb(Pcidev * p)847 pcigetpmrb(Pcidev* p)
848 {
849 if(p->pmrb != 0)
850 return p->pmrb;
851 return p->pmrb = pcicap(p, PciCapPMG);
852 }
853
854 int
pcigetpms(Pcidev * p)855 pcigetpms(Pcidev* p)
856 {
857 int pmcsr, ptr;
858
859 if((ptr = pcigetpmrb(p)) == -1)
860 return -1;
861
862 /*
863 * Power Management Register Block:
864 * offset 0: Capability ID
865 * 1: next item pointer
866 * 2: capabilities
867 * 4: control/status
868 * 6: bridge support extensions
869 * 7: data
870 */
871 pmcsr = pcicfgr16(p, ptr+4);
872
873 return pmcsr & 0x0003;
874 }
875
876 int
pcisetpms(Pcidev * p,int state)877 pcisetpms(Pcidev* p, int state)
878 {
879 int ostate, pmc, pmcsr, ptr;
880
881 if((ptr = pcigetpmrb(p)) == -1)
882 return -1;
883
884 pmc = pcicfgr16(p, ptr+2);
885 pmcsr = pcicfgr16(p, ptr+4);
886 ostate = pmcsr & 0x0003;
887 pmcsr &= ~0x0003;
888
889 switch(state){
890 default:
891 return -1;
892 case 0:
893 break;
894 case 1:
895 if(!(pmc & 0x0200))
896 return -1;
897 break;
898 case 2:
899 if(!(pmc & 0x0400))
900 return -1;
901 break;
902 case 3:
903 break;
904 }
905 pmcsr |= state;
906 pcicfgw16(p, ptr+4, pmcsr);
907
908 return ostate;
909 }
910
911 void
pcienable(Pcidev * p)912 pcienable(Pcidev *p)
913 {
914 uint pcr;
915 int i;
916
917 if(p == nil)
918 return;
919
920 pcienable(p->parent);
921
922 switch(pcisetpms(p, 0)){
923 case 1:
924 print("pcienable %T: wakeup from D1\n", p->tbdf);
925 break;
926 case 2:
927 print("pcienable %T: wakeup from D2\n", p->tbdf);
928 if(p->bridge != nil)
929 delay(100); /* B2: minimum delay 50ms */
930 else
931 delay(1); /* D2: minimum delay 200µs */
932 break;
933 case 3:
934 print("pcienable %T: wakeup from D3\n", p->tbdf);
935 delay(100); /* D3: minimum delay 50ms */
936
937 /* restore registers */
938 for(i = 0; i < 6; i++)
939 pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
940 pcicfgw8(p, PciINTL, p->intl);
941 pcicfgw8(p, PciLTR, p->ltr);
942 pcicfgw8(p, PciCLS, p->cls);
943 pcicfgw16(p, PciPCR, p->pcr);
944 break;
945 }
946
947 if(p->bridge != nil)
948 pcr = IOen|MEMen|MASen;
949 else {
950 pcr = 0;
951 for(i = 0; i < 6; i++){
952 if(p->mem[i].size == 0)
953 continue;
954 if(p->mem[i].bar & 1)
955 pcr |= IOen;
956 else
957 pcr |= MEMen;
958 }
959 }
960
961 if((p->pcr & pcr) != pcr){
962 print("pcienable %T: pcr %ux->%ux\n", p->tbdf, p->pcr, p->pcr|pcr);
963 p->pcr |= pcr;
964 pcicfgrw32(p->tbdf, PciPCR, 0xFFFF0000|p->pcr, 0);
965 }
966 }
967
968 void
pcidisable(Pcidev * p)969 pcidisable(Pcidev *p)
970 {
971 if(p == nil)
972 return;
973 pciclrbme(p);
974 }
975
976 enum {
977 MSICtrl = 0x02, /* message control register (16 bit) */
978 MSIAddr = 0x04, /* message address register (64 bit) */
979 MSIData32 = 0x08, /* message data register for 32 bit MSI (16 bit) */
980 MSIData64 = 0x0C, /* message data register for 64 bit MSI (16 bit) */
981 };
982
983 typedef struct Pciisr Pciisr;
984 struct Pciisr {
985 void (*f)(Ureg*, void*);
986 void *a;
987 Pcidev *p;
988 };
989
990 static Pciisr pciisr[32];
991 static Lock pciisrlk;
992
993 void
pciintrenable(int tbdf,void (* f)(Ureg *,void *),void * a)994 pciintrenable(int tbdf, void (*f)(Ureg*, void*), void *a)
995 {
996 int cap, ok64;
997 u32int dat;
998 u64int adr;
999 Pcidev *p;
1000 Pciisr *isr;
1001
1002 if((p = pcimatchtbdf(tbdf)) == nil){
1003 print("pciintrenable: %T: unknown device\n", tbdf);
1004 return;
1005 }
1006 if((cap = pcicap(p, PciCapMSI)) < 0){
1007 print("pciintrenable: %T: no MSI cap\n", tbdf);
1008 return;
1009 }
1010
1011 lock(&pciisrlk);
1012 for(isr = pciisr; isr < &pciisr[nelem(pciisr)]; isr++){
1013 if(isr->p == p){
1014 isr->p = nil;
1015 regs[MSI_INTR2_BASE + INTR_MASK_SET] = 1 << (isr-pciisr);
1016 break;
1017 }
1018 }
1019 for(isr = pciisr; isr < &pciisr[nelem(pciisr)]; isr++){
1020 if(isr->p == nil){
1021 isr->p = p;
1022 isr->a = a;
1023 isr->f = f;
1024 regs[MSI_INTR2_BASE + INTR_CLR] = 1 << (isr-pciisr);
1025 regs[MSI_INTR2_BASE + INTR_MASK_CLR] = 1 << (isr-pciisr);
1026 break;
1027 }
1028 }
1029 unlock(&pciisrlk);
1030
1031 if(isr >= &pciisr[nelem(pciisr)]){
1032 print("pciintrenable: %T: out of isr slots\n", tbdf);
1033 return;
1034 }
1035
1036 adr = MSI_TARGET_ADDR;
1037 ok64 = (pcicfgr16(p, cap + MSICtrl) & (1<<7)) != 0;
1038 pcicfgw32(p, cap + MSIAddr, adr);
1039 if(ok64) pcicfgw32(p, cap + MSIAddr + 4, adr>>32);
1040 dat = regs[MISC_MSI_DATA_CONFIG];
1041 dat = ((dat >> 16) & (dat & 0xFFFF)) | (isr-pciisr);
1042 pcicfgw16(p, cap + (ok64 ? MSIData64 : MSIData32), dat);
1043 pcicfgw16(p, cap + MSICtrl, 1);
1044 }
1045
1046 void
pciintrdisable(int tbdf,void (* f)(Ureg *,void *),void * a)1047 pciintrdisable(int tbdf, void (*f)(Ureg*, void*), void *a)
1048 {
1049 Pciisr *isr;
1050
1051 lock(&pciisrlk);
1052 for(isr = pciisr; isr < &pciisr[nelem(pciisr)]; isr++){
1053 if(isr->p != nil && isr->p->tbdf == tbdf && isr->f == f && isr->a == a){
1054 regs[MSI_INTR2_BASE + INTR_MASK_SET] = 1 << (isr-pciisr);
1055 isr->p = nil;
1056 isr->f = nil;
1057 isr->a = nil;
1058 break;
1059 }
1060 }
1061 unlock(&pciisrlk);
1062 }
1063
1064 static void
pciinterrupt(Ureg * ureg,void *)1065 pciinterrupt(Ureg *ureg, void*)
1066 {
1067 Pciisr *isr;
1068 u32int sts;
1069
1070 sts = regs[MSI_INTR2_BASE + INTR_STATUS];
1071 if(sts == 0)
1072 return;
1073 regs[MSI_INTR2_BASE + INTR_CLR] = sts;
1074 for(isr = pciisr; sts != 0 && isr < &pciisr[nelem(pciisr)]; isr++, sts>>=1){
1075 if((sts & 1) != 0 && isr->f != nil)
1076 (*isr->f)(ureg, isr->a);
1077 }
1078 regs[MISC_EOI_CTRL] = 1;
1079 }
1080
1081 void
pcilink(void)1082 pcilink(void)
1083 {
1084 int log2dmasize = 30; // 1GB
1085
1086 regs[RGR1_SW_INIT_1] |= 3;
1087 delay(200);
1088 regs[RGR1_SW_INIT_1] &= ~2;
1089 regs[MISC_PCIE_CTRL] &= ~5;
1090 delay(200);
1091
1092 regs[MISC_HARD_PCIE_HARD_DEBUG] &= ~0x08000000;
1093 delay(200);
1094
1095 regs[MSI_INTR2_BASE + INTR_CLR] = -1;
1096 regs[MSI_INTR2_BASE + INTR_MASK_SET] = -1;
1097
1098 regs[MISC_CPU_2_PCIE_MEM_WIN0_LO] = 0;
1099 regs[MISC_CPU_2_PCIE_MEM_WIN0_HI] = 0;
1100 regs[MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT] = 0;
1101 regs[MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI] = 0;
1102 regs[MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI] = 0;
1103
1104 // SCB_ACCESS_EN, CFG_READ_UR_MODE, MAX_BURST_SIZE_128, SCB0SIZE
1105 regs[MISC_MISC_CTRL] = 1<<12 | 1<<13 | 0<<20 | (log2dmasize-15)<<27;
1106
1107 regs[MISC_RC_BAR2_CONFIG_LO] = (log2dmasize-15);
1108 regs[MISC_RC_BAR2_CONFIG_HI] = 0;
1109
1110 regs[MISC_RC_BAR1_CONFIG_LO] = 0;
1111 regs[MISC_RC_BAR3_CONFIG_LO] = 0;
1112
1113 regs[MISC_MSI_BAR_CONFIG_LO] = MSI_TARGET_ADDR | 1;
1114 regs[MISC_MSI_BAR_CONFIG_HI] = MSI_TARGET_ADDR>>32;
1115 regs[MISC_MSI_DATA_CONFIG] = 0xFFF86540;
1116 intrenable(IRQpci, pciinterrupt, nil, BUSUNKNOWN, "pci");
1117
1118 // force to GEN2
1119 regs[(0xAC + 12)/4] = (regs[(0xAC + 12)/4] & ~15) | 2; // linkcap
1120 regs[(0xAC + 48)/4] = (regs[(0xAC + 48)/4] & ~15) | 2; // linkctl2
1121
1122 regs[RGR1_SW_INIT_1] &= ~1;
1123 delay(500);
1124
1125 if((regs[MISC_PCIE_STATUS] & 0x30) != 0x30){
1126 print("pcireset: phy link is down\n");
1127 return;
1128 }
1129
1130 regs[RC_CFG_PRIV1_ID_VAL3] = 0x060400;
1131 regs[RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1] &= ~0xC;
1132 regs[MISC_HARD_PCIE_HARD_DEBUG] |= 2;
1133
1134 pcicfginit();
1135 pcihinv(nil);
1136 }
1137