2 #include "../port/lib.h"
7 #include "../port/pci.h"
20 /* capability list id 0x10 is pci-e */
21 typedef struct Pci Pci;
23 /* pci-compatible config */
24 /* what io.h calls type 0 & type 1 pre-defined header */
28 ulong misc; /* cache line size, latency timer, header type, bist */
29 ulong bar[2]; /* always 0 on tegra 2 */
31 /* types 1 & 2 pre-defined header */
38 /* type 2 pre-defined header only */
40 ulong cfgcapoff; /* offset in cfg. space to cap. list (0x40) */
42 ulong intr; /* PciINT[LP] */
43 /* subsystem capability regs */
52 ulong msimsgaddr[2]; /* little-endian */
56 uchar _pad0[0x80-0x60];
68 /* offsets from soc.pci */
88 uchar _padpci[0x1000];
91 uchar _padpads[0x1000];
98 static int pcicfgmode = -1;
99 static int pcimaxbno = 1; /* was 7; only 2 pci buses; touching 3rd hangs */
100 static Pcidev* pciroot;
102 extern void rtl8169interrupt(Ureg*, void* arg);
106 pciintr(Ureg *ureg, void *p)
108 rtl8169interrupt(ureg, p); /* HACK */
115 Pci *pci = (Pci *)soc.pci;
120 * TrimSlice # pci 0 1
121 * Scanning PCI devices on bus 0 1
122 * BusDevFun VendorId DeviceId Device Class Sub-Class
123 * _____________________________________________________________
124 * 00.00.00 0x10de 0x0bf0 Bridge device 0x04
125 * 01.00.00 0x10ec 0x8168 Network controller 0x00
127 * thus pci bus 0 has a bridge with, perhaps, an ide/sata ctlr behind,
128 * and pci bus 1 has the realtek 8169 on it:
130 * TrimSlice # pci 1 long
131 * Scanning PCI devices on bus 1
133 * Found PCI device 01.00.00:
136 * command register = 0x0007
137 * status register = 0x0010
139 * class code = 0x02 (Network controller)
140 * sub class code = 0x00
141 * programming interface = 0x00
143 * base address 0 = 0x80400001 config
144 * base address 1 = 0x00000000 (ext. config)
145 * base address 2 = 0xa000000c "downstream"
146 * base address 3 = 0x00000000 (prefetchable)
147 * base address 4 = 0xa000400c not "
148 * base address 5 = 0x00000000 (unused)
151 if (((pci->id & MASK(16)) != Vnvidia || (n != 0xbf0 && n != 0xbf1)) &&
152 (pci->id & MASK(16)) != Vrealtek) {
153 print("no pci controller at %#p\n", pci);
157 iprint("pci: %#p: nvidia, rev %#ux class %#6.6lux misc %#8.8lux\n",
158 pci, (uchar)pci->revclass, pci->revclass >> 8,
162 pci->cs |= Memspace | Busmaster;
166 pcimaxdno = 15; /* for trimslice */
168 fmtinstall('T', tbdffmt);
170 if(p = getconf("*pcimaxbno")){
171 n = strtoul(p, 0, 0);
175 if(p = getconf("*pcimaxdno")){
176 n = strtoul(p, 0, 0);
182 /* was bno = 0; trimslice needs to start at 1 */
183 for(bno = 1; bno <= pcimaxbno; bno++) {
184 bno = pciscan(bno, list);
186 list = &(*list)->link;
189 if(getconf("*pcihinv"))
198 pcieintrdone(void) /* dismiss pci-e intr */
202 afi = (ulong *)(soc.pci + Afi);
203 afi[Afiintrcode/sizeof *afi] = 0; /* magic */
208 * whole config space for tbdf should be at (return address - rno).
211 tegracfgaddr(int tbdf, int rno)
215 addr = soc.pci + (rno < 256? Cfgspace: Ecfgspace) + BUSBDF(tbdf) + rno;
216 // if (BUSBNO(tbdf) == 1)
222 pcicfgrw8(int tbdf, int rno, int data, int read)
226 addr = tegracfgaddr(tbdf, rno);
228 data = *(uchar *)addr;
230 *(uchar *)addr = data;
235 pcicfgrw16(int tbdf, int rno, int data, int read)
239 addr = tegracfgaddr(tbdf, rno);
241 data = *(ushort *)addr;
243 *(ushort *)addr = data;
248 pcicfgrw32(int tbdf, int rno, int data, int read)
253 addr = tegracfgaddr(tbdf, rno);
254 v = probeaddr((uintptr)addr);
258 data = *(ulong *)addr;
260 *(ulong *)addr = data;