3 * Needs a massive rewrite.
6 #include "../port/lib.h"
12 #define DBG if(0) pcilog
14 typedef struct Pci Pci;
23 pcilog(char *fmt, ...)
30 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
33 memmove(PCICONS.output+PCICONS.ptr, buf, n);
45 { /* command register */
64 /* capability list id 0x10 is pci-e */
66 /* pci-compatible config */
67 /* what io.h calls type 0 & type 1 pre-defined header */
71 ulong misc; /* cache line size, latency timer, header type, bist */
72 ulong bar[2]; /* always 0 on tegra 2 */
74 /* types 1 & 2 pre-defined header */
81 /* type 2 pre-defined header only */
83 ulong cfgcapoff; /* offset in cfg. space to cap. list (0x40) */
85 ulong intr; /* PciINT[LP] */
86 /* subsystem capability regs */
95 ulong msimsgaddr[2]; /* little-endian */
99 uchar _pad0[0x80-0x60];
111 /* offsets from soc.pci */
118 Ecfgspace = 0x104000,
131 uchar _padpci[0x1000];
134 uchar _padpads[0x1000];
138 ulong extcfg[0x1000];
141 static Lock pcicfglock;
142 static Lock pcicfginitlock;
143 static int pcicfgmode = -1;
144 static int pcimaxbno = 1; /* was 7; only 2 pci buses; touching 3rd hangs */
145 static int pcimaxdno;
146 static Pcidev* pciroot;
147 static Pcidev* pcilist;
148 static Pcidev* pcitail;
150 static int pcicfgrw8(int, int, int, int);
151 static int pcicfgrw16(int, int, int, int);
152 static int pcicfgrw32(int, int, int, int);
154 static char* bustypes[] = {
182 if((p = malloc(READSTR)) == nil)
183 return fmtstrcpy(fmt, "(tbdfconv)");
187 tbdf = va_arg(fmt->args, int);
188 if(tbdf == BUSUNKNOWN)
189 snprint(p, READSTR, "unknown");
191 type = BUSTYPE(tbdf);
192 if(type < nelem(bustypes))
193 l = snprint(p, READSTR, bustypes[type]);
195 l = snprint(p, READSTR, "%d", type);
196 snprint(p+l, READSTR-l, ".%d.%d.%d",
197 BUSBNO(tbdf), BUSDNO(tbdf), BUSFNO(tbdf));
202 snprint(p, READSTR, "(tbdfconv)");
205 r = fmtstrcpy(fmt, p);
212 pcibarsize(Pcidev *p, int rno)
216 v = pcicfgrw32(p->tbdf, rno, 0, 1);
217 pcicfgrw32(p->tbdf, rno, 0xFFFFFFF0, 0);
218 size = pcicfgrw32(p->tbdf, rno, 0, 1);
221 pcicfgrw32(p->tbdf, rno, v, 0);
223 return -(size & ~0x0F);
227 pcilscan(int bno, Pcidev** list)
229 Pcidev *p, *head, *tail;
230 int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn;
235 for(dno = 0; dno <= pcimaxdno; dno++){
237 for(fno = 0; fno <= maxfno; fno++){
239 * For this possible device, form the
240 * bus+device+function triplet needed to address it
241 * and try to read the vendor and device ID.
242 * If successful, allocate a device struct and
243 * start to fill it in with some useful information
244 * from the device's configuration space.
246 tbdf = MKBUS(BusPCI, bno, dno, fno);
247 l = pcicfgrw32(tbdf, PciVID, 0, 1);
248 if(l == 0xFFFFFFFF || l == 0)
250 p = malloc(sizeof(*p));
252 panic("pcilscan: no memory");
263 p->pcr = pcicfgr16(p, PciPCR);
264 p->rid = pcicfgr8(p, PciRID);
265 p->ccrp = pcicfgr8(p, PciCCRp);
266 p->ccru = pcicfgr8(p, PciCCRu);
267 p->ccrb = pcicfgr8(p, PciCCRb);
268 p->cls = pcicfgr8(p, PciCLS);
269 p->ltr = pcicfgr8(p, PciLTR);
271 p->intl = pcicfgr8(p, PciINTL);
274 * If the device is a multi-function device adjust the
275 * loop count so all possible functions are checked.
277 hdt = pcicfgr8(p, PciHDT);
282 * If appropriate, read the base address registers
283 * and work out the sizes.
286 case 0x03: /* display controller */
288 case 0x01: /* mass storage controller */
289 case 0x02: /* network controller */
290 case 0x04: /* multimedia device */
291 case 0x07: /* simple comm. controllers */
292 case 0x08: /* base system peripherals */
293 case 0x09: /* input devices */
294 case 0x0A: /* docking stations */
295 case 0x0B: /* processors */
296 case 0x0C: /* serial bus controllers */
297 if((hdt & 0x7F) != 0)
300 for(i = 0; i < nelem(p->mem); i++) {
302 p->mem[i].bar = pcicfgr32(p, rno);
303 p->mem[i].size = pcibarsize(p, rno);
308 case 0x05: /* memory controller */
309 case 0x06: /* bridge device */
323 for(p = head; p != nil; p = p->link){
325 * Find PCI-PCI bridges and recursively descend the tree.
327 if(p->ccrb != 0x06 || p->ccru != 0x04)
331 * If the secondary or subordinate bus number is not
332 * initialised try to do what the PCI BIOS should have
333 * done and fill in the numbers as the tree is descended.
334 * On the way down the subordinate bus number is set to
335 * the maximum as it's not known how many buses are behind
336 * this one; the final value is set on the way back up.
338 sbn = pcicfgr8(p, PciSBN);
339 ubn = pcicfgr8(p, PciUBN);
341 if(sbn == 0 || ubn == 0) {
344 * Make sure memory, I/O and master enables are
345 * off, set the primary, secondary and subordinate
346 * bus numbers and clear the secondary status before
347 * attempting to scan the secondary bus.
349 * Initialisation of the bridge should be done here.
351 pcicfgw32(p, PciPCR, 0xFFFF0000);
352 l = (MaxUBN<<16)|(sbn<<8)|bno;
353 pcicfgw32(p, PciPBN, l);
354 pcicfgw16(p, PciSPSR, 0xFFFF);
355 maxubn = pcilscan(sbn, &p->bridge);
356 l = (maxubn<<16)|(sbn<<8)|bno;
358 pcicfgw32(p, PciPBN, l);
363 pcilscan(sbn, &p->bridge);
370 extern void rtl8169interrupt(Ureg*, void* arg);
374 pciintr(Ureg *ureg, void *p)
376 rtl8169interrupt(ureg, p); /* HACK */
383 Pci *pci = (Pci *)soc.pci;
387 lock(&pcicfginitlock);
388 if(pcicfgmode != -1) {
389 unlock(&pcicfginitlock);
394 * TrimSlice # pci 0 1
395 * Scanning PCI devices on bus 0 1
396 * BusDevFun VendorId DeviceId Device Class Sub-Class
397 * _____________________________________________________________
398 * 00.00.00 0x10de 0x0bf0 Bridge device 0x04
399 * 01.00.00 0x10ec 0x8168 Network controller 0x00
401 * thus pci bus 0 has a bridge with, perhaps, an ide/sata ctlr behind,
402 * and pci bus 1 has the realtek 8169 on it:
404 * TrimSlice # pci 1 long
405 * Scanning PCI devices on bus 1
407 * Found PCI device 01.00.00:
410 * command register = 0x0007
411 * status register = 0x0010
413 * class code = 0x02 (Network controller)
414 * sub class code = 0x00
415 * programming interface = 0x00
417 * base address 0 = 0x80400001 config
418 * base address 1 = 0x00000000 (ext. config)
419 * base address 2 = 0xa000000c "downstream"
420 * base address 3 = 0x00000000 (prefetchable)
421 * base address 4 = 0xa000400c not "
422 * base address 5 = 0x00000000 (unused)
425 if (((pci->id & MASK(16)) != Vnvidia || (n != 0xbf0 && n != 0xbf1)) &&
426 (pci->id & MASK(16)) != Vrealtek) {
427 print("no pci controller at %#p\n", pci);
428 unlock(&pcicfginitlock);
432 iprint("pci: %#p: nvidia, rev %#ux class %#6.6lux misc %#8.8lux\n",
433 pci, (uchar)pci->revclass, pci->revclass >> 8,
437 pci->cs |= Memspace | Busmaster;
442 pcimaxdno = 15; /* for trimslice */
444 fmtinstall('T', tbdffmt);
446 if(p = getconf("*pcimaxbno")){
447 n = strtoul(p, 0, 0);
451 if(p = getconf("*pcimaxdno")){
452 n = strtoul(p, 0, 0);
458 /* was bno = 0; trimslice needs to start at 1 */
459 for(bno = 1; bno <= pcimaxbno; bno++) {
460 bno = pcilscan(bno, list);
462 list = &(*list)->link;
464 unlock(&pcicfginitlock);
466 if(getconf("*pcihinv"))
475 pcieintrdone(void) /* dismiss pci-e intr */
479 afi = (ulong *)(soc.pci + Afi);
480 afi[Afiintrcode/sizeof *afi] = 0; /* magic */
485 * whole config space for tbdf should be at (return address - rno).
488 tegracfgaddr(int tbdf, int rno)
492 addr = soc.pci + (rno < 256? Cfgspace: Ecfgspace) + BUSBDF(tbdf) + rno;
493 // if (BUSBNO(tbdf) == 1)
499 pcicfgrw8(int tbdf, int rno, int data, int read)
508 if(BUSDNO(tbdf) > pcimaxdno)
511 addr = tegracfgaddr(tbdf, rno);
517 *(uchar *)addr = data;
524 pcicfgr8(Pcidev* pcidev, int rno)
526 return pcicfgrw8(pcidev->tbdf, rno, 0, 1);
530 pcicfgw8(Pcidev* pcidev, int rno, int data)
532 pcicfgrw8(pcidev->tbdf, rno, data, 0);
536 pcicfgrw16(int tbdf, int rno, int data, int read)
545 if(BUSDNO(tbdf) > pcimaxdno)
548 addr = tegracfgaddr(tbdf, rno);
554 *(ushort *)addr = data;
561 pcicfgr16(Pcidev* pcidev, int rno)
563 return pcicfgrw16(pcidev->tbdf, rno, 0, 1);
567 pcicfgw16(Pcidev* pcidev, int rno, int data)
569 pcicfgrw16(pcidev->tbdf, rno, data, 0);
573 pcicfgrw32(int tbdf, int rno, int data, int read)
583 if(BUSDNO(tbdf) > pcimaxdno)
586 addr = tegracfgaddr(tbdf, rno);
587 v = probeaddr((uintptr)addr);
595 *(ulong *)addr = data;
602 pcicfgr32(Pcidev* pcidev, int rno)
604 return pcicfgrw32(pcidev->tbdf, rno, 0, 1);
608 pcicfgw32(Pcidev* pcidev, int rno, int data)
610 pcicfgrw32(pcidev->tbdf, rno, data, 0);
614 pcimatch(Pcidev* prev, int vid, int did)
625 if((vid == 0 || prev->vid == vid)
626 && (did == 0 || prev->did == did))
634 pcimatchtbdf(int tbdf)
641 for(pcidev = pcilist; pcidev != nil; pcidev = pcidev->list) {
642 if(pcidev->tbdf == tbdf)
655 putstrn(PCICONS.output, PCICONS.ptr);
657 print("bus dev type vid did intl memory\n");
659 for(t = p; t != nil; t = t->link) {
660 print("%d %2d/%d %.2ux %.2ux %.2ux %.4ux %.4ux %3d ",
661 BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf),
662 t->ccrb, t->ccru, t->ccrp, t->vid, t->did, t->intl);
664 for(i = 0; i < nelem(p->mem); i++) {
665 if(t->mem[i].size == 0)
667 print("%d:%.8lux %d ", i,
668 t->mem[i].bar, t->mem[i].size);
671 print("->%d", BUSBNO(t->bridge->tbdf));
686 lock(&pcicfginitlock);
688 unlock(&pcicfginitlock);
699 for(p = pcilist; p != nil; p = p->list) {
700 /* don't mess with the bridges */
711 pcicfgw16(p, PciPCR, p->pcr);
718 pcicfgw16(p, PciPCR, p->pcr);
725 pcicfgw16(p, PciPCR, p->pcr);
732 pcicfgw16(p, PciPCR, p->pcr);
739 pcicfgw16(p, PciPCR, p->pcr);
746 pcicfgw16(p, PciPCR, p->pcr);
750 pcigetpmrb(Pcidev* p)
759 * If there are no extended capabilities implemented,
760 * (bit 4 in the status register) assume there's no standard
761 * power management method.
762 * Find the capabilities pointer based on PCI header type.
764 if(!(pcicfgr16(p, PciPSR) & 0x0010))
766 switch(pcicfgr8(p, PciHDT)){
769 case 0: /* all other */
770 case 1: /* PCI to PCI bridge */
773 case 2: /* CardBus bridge */
777 ptr = pcicfgr32(p, ptr);
781 * Check for validity.
782 * Can't be in standard header and must be double
785 if(ptr < 0x40 || (ptr & ~0xFC))
787 if(pcicfgr8(p, ptr) == 0x01){
792 ptr = pcicfgr8(p, ptr+1);
803 if((ptr = pcigetpmrb(p)) == -1)
807 * Power Management Register Block:
808 * offset 0: Capability ID
809 * 1: next item pointer
812 * 6: bridge support extensions
815 pmcsr = pcicfgr16(p, ptr+4);
817 return pmcsr & 0x0003;
821 pcisetpms(Pcidev* p, int state)
823 int ostate, pmc, pmcsr, ptr;
825 if((ptr = pcigetpmrb(p)) == -1)
828 pmc = pcicfgr16(p, ptr+2);
829 pmcsr = pcicfgr16(p, ptr+4);
830 ostate = pmcsr & 0x0003;
850 pcicfgw16(p, ptr+4, pmcsr);