xref: /plan9-contrib/sys/src/9/bcm/pci.c (revision 5c47fe09a0cc86dfb02c0ea4a2b6aec7eda2361f)
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*)&regs[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