1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 5 #include "pci.h" 6 #include "vga.h" 7 8 /* 9 * PCI support code. 10 * There really should be a driver for this, it's not terribly safe 11 * without locks or restrictions on what can be poked (e.g. Axil NX801). 12 */ 13 enum { /* configuration mechanism #1 */ 14 PciADDR = 0xCF8, /* CONFIG_ADDRESS */ 15 PciDATA = 0xCFC, /* CONFIG_DATA */ 16 17 /* configuration mechanism #2 */ 18 PciCSE = 0xCF8, /* configuration space enable */ 19 PciFORWARD = 0xCFA, /* which bus */ 20 21 MaxFNO = 7, 22 MaxUBN = 255, 23 }; 24 25 static int pcicfgmode = -1; 26 static int pcimaxdno; 27 static Pcidev* pciroot; 28 static Pcidev* pcilist; 29 static Pcidev* pcitail; 30 31 static int pcicfgrw32(int, int, int, int); 32 33 static int 34 pciscan(int bno, Pcidev** list) 35 { 36 ulong v; 37 Pcidev *p, *head, *tail; 38 int dno, fno, i, hdt, l, maxfno, maxubn, rno, sbn, tbdf, ubn; 39 40 maxubn = bno; 41 head = nil; 42 tail = nil; 43 for(dno = 0; dno <= pcimaxdno; dno++){ 44 maxfno = 0; 45 for(fno = 0; fno <= maxfno; fno++){ 46 /* 47 * For this possible device, form the bus+device+function 48 * triplet needed to address it and try to read the vendor 49 * and device ID. If successful, allocate a device struct 50 * and start to fill it in with some useful information from 51 * the device's configuration space. 52 */ 53 tbdf = MKBUS(BusPCI, bno, dno, fno); 54 l = pcicfgrw32(tbdf, PciVID, 0, 1); 55 if(l == 0xFFFFFFFF || l == 0) 56 continue; 57 p = mallocz(sizeof(*p), 1); 58 p->tbdf = tbdf; 59 p->vid = l; 60 p->did = l>>16; 61 p->rid = pcicfgr8(p, PciRID); 62 63 if(pcilist != nil) 64 pcitail->list = p; 65 else 66 pcilist = p; 67 pcitail = p; 68 69 p->intl = pcicfgr8(p, PciINTL); 70 p->ccru = pcicfgr16(p, PciCCRu); 71 72 /* 73 * If the device is a multi-function device adjust the 74 * loop count so all possible functions are checked. 75 */ 76 hdt = pcicfgr8(p, PciHDT); 77 if(hdt & 0x80) 78 maxfno = MaxFNO; 79 80 /* 81 * If appropriate, read the base address registers 82 * and work out the sizes. 83 */ 84 switch(p->ccru>>8){ 85 86 case 0x01: /* mass storage controller */ 87 case 0x02: /* network controller */ 88 case 0x03: /* display controller */ 89 case 0x04: /* multimedia device */ 90 case 0x07: /* simple communication controllers */ 91 case 0x08: /* base system peripherals */ 92 case 0x09: /* input devices */ 93 case 0x0A: /* docking stations */ 94 case 0x0B: /* processors */ 95 case 0x0C: /* serial bus controllers */ 96 if((hdt & 0x7F) != 0) 97 break; 98 rno = PciBAR0 - 4; 99 for(i = 0; i < nelem(p->mem); i++){ 100 rno += 4; 101 p->mem[i].bar = pcicfgr32(p, rno); 102 pcicfgw32(p, rno, -1); 103 v = pcicfgr32(p, rno); 104 pcicfgw32(p, rno, p->mem[i].bar); 105 p->mem[i].size = -(v & ~0xF); 106 } 107 break; 108 109 case 0x00: 110 case 0x05: /* memory controller */ 111 case 0x06: /* bridge device */ 112 default: 113 break; 114 } 115 116 if(head != nil) 117 tail->link = p; 118 else 119 head = p; 120 tail = p; 121 } 122 } 123 124 *list = head; 125 for(p = head; p != nil; p = p->link){ 126 /* 127 * Find PCI-PCI bridges and recursively descend the tree. 128 */ 129 if(p->ccru != ((0x06<<8)|0x04)) 130 continue; 131 132 /* 133 * If the secondary or subordinate bus number is not initialised 134 * try to do what the PCI BIOS should have done and fill in the 135 * numbers as the tree is descended. On the way down the subordinate 136 * bus number is set to the maximum as it's not known how many 137 * buses are behind this one; the final value is set on the way 138 * back up. 139 */ 140 sbn = pcicfgr8(p, PciSBN); 141 ubn = pcicfgr8(p, PciUBN); 142 if(sbn == 0 || ubn == 0){ 143 sbn = maxubn+1; 144 /* 145 * Make sure memory, I/O and master enables are off, 146 * set the primary, secondary and subordinate bus numbers 147 * and clear the secondary status before attempting to 148 * scan the secondary bus. 149 * 150 * Initialisation of the bridge should be done here. 151 */ 152 pcicfgw32(p, PciPCR, 0xFFFF0000); 153 l = (MaxUBN<<16)|(sbn<<8)|bno; 154 pcicfgw32(p, PciPBN, l); 155 pcicfgw16(p, PciSPSR, 0xFFFF); 156 maxubn = pciscan(sbn, &p->bridge); 157 l = (maxubn<<16)|(sbn<<8)|bno; 158 pcicfgw32(p, PciPBN, l); 159 } 160 else{ 161 maxubn = ubn; 162 pciscan(sbn, &p->bridge); 163 } 164 } 165 166 return maxubn; 167 } 168 169 static void 170 pcicfginit(void) 171 { 172 #ifdef kernel 173 char *p; 174 #endif /* kernel */ 175 int bno; 176 Pcidev **list; 177 178 if(pcicfgmode == -1){ 179 /* 180 * Try to determine which PCI configuration mode is implemented. 181 * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses 182 * a DWORD at 0xCF8 and another at 0xCFC and will pass through 183 * any non-DWORD accesses as normal I/O cycles. There shouldn't be 184 * a device behind these addresses so if Mode2 accesses fail try 185 * for Mode1 (which is preferred, Mode2 is deprecated). 186 */ 187 outportb(PciCSE, 0); 188 if(inportb(PciCSE) == 0){ 189 pcicfgmode = 2; 190 pcimaxdno = 15; 191 } 192 else{ 193 outportl(PciADDR, 0); 194 if(inportl(PciADDR) == 0){ 195 pcicfgmode = 1; 196 pcimaxdno = 31; 197 } 198 } 199 200 if(pcicfgmode > 0){ 201 list = &pciroot; 202 for(bno = 0; bno < 256; bno++){ 203 bno = pciscan(bno, list); 204 while(*list) 205 list = &(*list)->link; 206 } 207 208 } 209 } 210 } 211 212 static int 213 pcicfgrw8(int tbdf, int rno, int data, int read) 214 { 215 int o, type, x; 216 217 if(pcicfgmode == -1) 218 pcicfginit(); 219 220 if(BUSBNO(tbdf)) 221 type = 0x01; 222 else 223 type = 0x00; 224 x = -1; 225 if(BUSDNO(tbdf) > pcimaxdno) 226 return x; 227 228 switch(pcicfgmode){ 229 230 case 1: 231 o = rno & 0x03; 232 rno &= ~0x03; 233 outportl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 234 if(read) 235 x = inportb(PciDATA+o); 236 else 237 outportb(PciDATA+o, data); 238 outportl(PciADDR, 0); 239 break; 240 241 case 2: 242 outportb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 243 outportb(PciFORWARD, BUSBNO(tbdf)); 244 if(read) 245 x = inportb((0xC000|(BUSDNO(tbdf)<<8)) + rno); 246 else 247 outportb((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 248 outportb(PciCSE, 0); 249 break; 250 } 251 252 return x; 253 } 254 255 int 256 pcicfgr8(Pcidev* pcidev, int rno) 257 { 258 return pcicfgrw8(pcidev->tbdf, rno, 0, 1); 259 } 260 261 void 262 pcicfgw8(Pcidev* pcidev, int rno, int data) 263 { 264 pcicfgrw8(pcidev->tbdf, rno, data, 0); 265 } 266 267 static int 268 pcicfgrw16(int tbdf, int rno, int data, int read) 269 { 270 int o, type, x; 271 272 if(pcicfgmode == -1) 273 pcicfginit(); 274 275 if(BUSBNO(tbdf)) 276 type = 0x01; 277 else 278 type = 0x00; 279 x = -1; 280 if(BUSDNO(tbdf) > pcimaxdno) 281 return x; 282 283 switch(pcicfgmode){ 284 285 case 1: 286 o = rno & 0x02; 287 rno &= ~0x03; 288 outportl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 289 if(read) 290 x = inportw(PciDATA+o); 291 else 292 outportw(PciDATA+o, data); 293 outportl(PciADDR, 0); 294 break; 295 296 case 2: 297 outportb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 298 outportb(PciFORWARD, BUSBNO(tbdf)); 299 if(read) 300 x = inportw((0xC000|(BUSDNO(tbdf)<<8)) + rno); 301 else 302 outportw((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 303 outportb(PciCSE, 0); 304 break; 305 } 306 307 return x; 308 } 309 310 int 311 pcicfgr16(Pcidev* pcidev, int rno) 312 { 313 return pcicfgrw16(pcidev->tbdf, rno, 0, 1); 314 } 315 316 void 317 pcicfgw16(Pcidev* pcidev, int rno, int data) 318 { 319 pcicfgrw16(pcidev->tbdf, rno, data, 0); 320 } 321 322 static int 323 pcicfgrw32(int tbdf, int rno, int data, int read) 324 { 325 int type, x; 326 327 if(pcicfgmode == -1) 328 pcicfginit(); 329 330 if(BUSBNO(tbdf)) 331 type = 0x01; 332 else 333 type = 0x00; 334 x = -1; 335 if(BUSDNO(tbdf) > pcimaxdno) 336 return x; 337 338 switch(pcicfgmode){ 339 340 case 1: 341 rno &= ~0x03; 342 outportl(PciADDR, 0x80000000|BUSBDF(tbdf)|rno|type); 343 if(read) 344 x = inportl(PciDATA); 345 else 346 outportl(PciDATA, data); 347 outportl(PciADDR, 0); 348 break; 349 350 case 2: 351 outportb(PciCSE, 0x80|(BUSFNO(tbdf)<<1)); 352 outportb(PciFORWARD, BUSBNO(tbdf)); 353 if(read) 354 x = inportl((0xC000|(BUSDNO(tbdf)<<8)) + rno); 355 else 356 outportl((0xC000|(BUSDNO(tbdf)<<8)) + rno, data); 357 outportb(PciCSE, 0); 358 break; 359 } 360 361 return x; 362 } 363 364 int 365 pcicfgr32(Pcidev* pcidev, int rno) 366 { 367 return pcicfgrw32(pcidev->tbdf, rno, 0, 1); 368 } 369 370 void 371 pcicfgw32(Pcidev* pcidev, int rno, int data) 372 { 373 pcicfgrw32(pcidev->tbdf, rno, data, 0); 374 } 375 376 Pcidev* 377 pcimatch(Pcidev* prev, int vid, int did) 378 { 379 if(pcicfgmode == -1) 380 pcicfginit(); 381 382 if(prev == nil) 383 prev = pcilist; 384 else 385 prev = prev->list; 386 387 while(prev != nil) { 388 if(prev->vid == vid && (did == 0 || prev->did == did)) 389 break; 390 prev = prev->list; 391 } 392 return prev; 393 } 394 395 void 396 pcihinv(Pcidev* p) 397 { 398 int i; 399 Pcidev *t; 400 401 if(pcicfgmode == -1) 402 pcicfginit(); 403 404 405 if(p == nil) { 406 p = pciroot; 407 Bprint(&stdout, "bus dev type vid did intl memory\n"); 408 } 409 for(t = p; t != nil; t = t->link) { 410 Bprint(&stdout, "%d %2d/%d %.4ux %.4ux %.4ux %2d ", 411 BUSBNO(t->tbdf), BUSDNO(t->tbdf), BUSFNO(t->tbdf), 412 t->ccru, t->vid, t->did, t->intl); 413 414 for(i = 0; i < nelem(p->mem); i++) { 415 if(t->mem[i].size == 0) 416 continue; 417 Bprint(&stdout, "%d:%.8lux %d ", i, 418 t->mem[i].bar, t->mem[i].size); 419 } 420 Bprint(&stdout, "\n"); 421 } 422 while(p != nil) { 423 if(p->bridge != nil) 424 pcihinv(p->bridge); 425 p = p->link; 426 } 427 } 428