1 /*
2 pci.c
3
4 Configure devices on the PCI bus
5
6 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
7 */
8 #include <minix/acpi.h>
9 #include <minix/chardriver.h>
10 #include <minix/driver.h>
11 #include <minix/param.h>
12 #include <minix/rs.h>
13
14 #include <machine/pci.h>
15 #include <machine/pci_amd.h>
16 #include <machine/pci_intel.h>
17 #include <machine/pci_sis.h>
18 #include <machine/pci_via.h>
19 #include <machine/vmparam.h>
20
21 #include <dev/pci/pci_verbose.h>
22
23 #include <pci.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26
27 #include "pci.h"
28
29 #define PCI_VENDORSTR_LEN 64
30 #define PCI_PRODUCTSTR_LEN 64
31
32 #define irq_mode_pci(irq) ((void)0)
33
34 #define PBT_INTEL_HOST 1
35 #define PBT_PCIBRIDGE 2
36 #define PBT_CARDBUS 3
37
38 #define BAM_NR 6 /* Number of base-address registers */
39
40 struct pci_acl pci_acl[NR_DRIVERS];
41
42 static struct pcibus
43 {
44 int pb_type;
45 int pb_needinit;
46 int pb_isabridge_dev;
47 int pb_isabridge_type;
48
49 int pb_devind;
50 int pb_busnr;
51 u8_t (*pb_rreg8)(int busind, int devind, int port);
52 u16_t (*pb_rreg16)(int busind, int devind, int port);
53 u32_t (*pb_rreg32)(int busind, int devind, int port);
54 void (*pb_wreg8)(int busind, int devind, int port, u8_t value);
55 void (*pb_wreg16)(int busind, int devind, int port, u16_t value);
56 void (*pb_wreg32)(int busind, int devind, int port, u32_t value);
57 u16_t (*pb_rsts)(int busind);
58 void (*pb_wsts)(int busind, u16_t value);
59 } pcibus[NR_PCIBUS];
60 static int nr_pcibus= 0;
61
62 static struct pcidev
63 {
64 u8_t pd_busnr;
65 u8_t pd_dev;
66 u8_t pd_func;
67 u8_t pd_baseclass;
68 u8_t pd_subclass;
69 u8_t pd_infclass;
70 u16_t pd_vid;
71 u16_t pd_did;
72 u16_t pd_sub_vid;
73 u16_t pd_sub_did;
74 u8_t pd_ilr;
75
76 u8_t pd_inuse;
77 endpoint_t pd_proc;
78
79 struct bar
80 {
81 int pb_flags;
82 int pb_nr;
83 u32_t pb_base;
84 u32_t pb_size;
85 } pd_bar[BAM_NR];
86 int pd_bar_nr;
87 } pcidev[NR_PCIDEV];
88
89 /* pb_flags */
90 #define PBF_IO 1 /* I/O else memory */
91 #define PBF_INCOMPLETE 2 /* not allocated */
92
93 static int nr_pcidev= 0;
94
95 static struct machine machine;
96
97 /*===========================================================================*
98 * helper functions for I/O *
99 *===========================================================================*/
100 static unsigned
pci_inb(u16_t port)101 pci_inb(u16_t port) {
102 u32_t value;
103 int s;
104 if ((s=sys_inb(port, &value)) !=OK)
105 printf("PCI: warning, sys_inb failed: %d\n", s);
106 return value;
107 }
108
109 static unsigned
pci_inw(u16_t port)110 pci_inw(u16_t port) {
111 u32_t value;
112 int s;
113 if ((s=sys_inw(port, &value)) !=OK)
114 printf("PCI: warning, sys_inw failed: %d\n", s);
115 return value;
116 }
117
118 static unsigned
pci_inl(u16_t port)119 pci_inl(u16_t port) {
120 u32_t value;
121 int s;
122 if ((s=sys_inl(port, &value)) !=OK)
123 printf("PCI: warning, sys_inl failed: %d\n", s);
124 return value;
125 }
126
127 static void
pci_outb(u16_t port,u8_t value)128 pci_outb(u16_t port, u8_t value) {
129 int s;
130 if ((s=sys_outb(port, value)) !=OK)
131 printf("PCI: warning, sys_outb failed: %d\n", s);
132 }
133
134 static void
pci_outw(u16_t port,u16_t value)135 pci_outw(u16_t port, u16_t value) {
136 int s;
137 if ((s=sys_outw(port, value)) !=OK)
138 printf("PCI: warning, sys_outw failed: %d\n", s);
139 }
140
141 static void
pci_outl(u16_t port,u32_t value)142 pci_outl(u16_t port, u32_t value) {
143 int s;
144 if ((s=sys_outl(port, value)) !=OK)
145 printf("PCI: warning, sys_outl failed: %d\n", s);
146 }
147
148 static u8_t
pcii_rreg8(int busind,int devind,int port)149 pcii_rreg8(int busind, int devind, int port)
150 {
151 u8_t v;
152 int s;
153
154 v= PCII_RREG8_(pcibus[busind].pb_busnr,
155 pcidev[devind].pd_dev, pcidev[devind].pd_func,
156 port);
157 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
158 printf("PCI: warning, sys_outl failed: %d\n", s);
159 #if 0
160 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
161 busind, devind, port,
162 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
163 pcidev[devind].pd_func, v);
164 #endif
165 return v;
166 }
167
168 static u16_t
pcii_rreg16(int busind,int devind,int port)169 pcii_rreg16(int busind, int devind, int port)
170 {
171 u16_t v;
172 int s;
173
174 v= PCII_RREG16_(pcibus[busind].pb_busnr,
175 pcidev[devind].pd_dev, pcidev[devind].pd_func,
176 port);
177 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
178 printf("PCI: warning, sys_outl failed: %d\n", s);
179 #if 0
180 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
181 busind, devind, port,
182 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
183 pcidev[devind].pd_func, v);
184 #endif
185 return v;
186 }
187
188 static u32_t
pcii_rreg32(int busind,int devind,int port)189 pcii_rreg32(int busind, int devind, int port)
190 {
191 u32_t v;
192 int s;
193
194 v= PCII_RREG32_(pcibus[busind].pb_busnr,
195 pcidev[devind].pd_dev, pcidev[devind].pd_func,
196 port);
197 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
198 printf("PCI: warning, sys_outl failed: %d\n", s);
199 #if 0
200 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
201 busind, devind, port,
202 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
203 pcidev[devind].pd_func, v);
204 #endif
205 return v;
206 }
207
208 static void
pcii_wreg8(int busind,int devind,int port,u8_t value)209 pcii_wreg8(int busind, int devind, int port, u8_t value)
210 {
211 int s;
212 #if 0
213 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
214 busind, devind, port, value,
215 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
216 pcidev[devind].pd_func);
217 #endif
218 PCII_WREG8_(pcibus[busind].pb_busnr,
219 pcidev[devind].pd_dev, pcidev[devind].pd_func,
220 port, value);
221 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
222 printf("PCI: warning, sys_outl failed: %d\n", s);
223 }
224
225 static void
pcii_wreg16(int busind,int devind,int port,u16_t value)226 pcii_wreg16(int busind, int devind, int port, u16_t value)
227 {
228 int s;
229 #if 0
230 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
231 busind, devind, port, value,
232 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
233 pcidev[devind].pd_func);
234 #endif
235 PCII_WREG16_(pcibus[busind].pb_busnr,
236 pcidev[devind].pd_dev, pcidev[devind].pd_func,
237 port, value);
238 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
239 printf("PCI: warning, sys_outl failed: %d\n", s);
240 }
241
242 static void
pcii_wreg32(int busind,int devind,int port,u32_t value)243 pcii_wreg32(int busind, int devind, int port, u32_t value)
244 {
245 int s;
246 #if 0
247 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
248 busind, devind, port, value,
249 pcibus[busind].pb_busnr, pcidev[devind].pd_dev,
250 pcidev[devind].pd_func);
251 #endif
252 PCII_WREG32_(pcibus[busind].pb_busnr,
253 pcidev[devind].pd_dev, pcidev[devind].pd_func,
254 port, value);
255 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
256 printf("PCI: warning, sys_outl failed: %d\n",s);
257 }
258
259 /*===========================================================================*
260 * ntostr *
261 *===========================================================================*/
262 static void
ntostr(unsigned int n,char ** str,const char * end)263 ntostr(unsigned int n, char **str, const char *end)
264 {
265 char tmpstr[20];
266 int i;
267
268 if (n == 0)
269 {
270 tmpstr[0]= '0';
271 i= 1;
272 }
273 else
274 {
275 for (i= 0; n; i++)
276 {
277 tmpstr[i]= '0' + (n%10);
278 n /= 10;
279 }
280 }
281 for (; i>0; i--)
282 {
283 if (*str == end)
284 {
285 break;
286 }
287 **str= tmpstr[i-1];
288 (*str)++;
289 }
290 if (*str == end)
291 (*str)[-1]= '\0';
292 else
293 **str= '\0';
294 }
295
296 /*===========================================================================*
297 * get_busind *
298 *===========================================================================*/
299 static int
get_busind(int busnr)300 get_busind(int busnr)
301 {
302 int i;
303
304 for (i= 0; i<nr_pcibus; i++)
305 {
306 if (pcibus[i].pb_busnr == busnr)
307 return i;
308 }
309 panic("get_busind: can't find bus: %d", busnr);
310 }
311
312 /*===========================================================================*
313 * Unprotected helper functions *
314 *===========================================================================*/
315 static u8_t
__pci_attr_r8(int devind,int port)316 __pci_attr_r8(int devind, int port)
317 {
318 int busnr, busind;
319
320 busnr= pcidev[devind].pd_busnr;
321 busind= get_busind(busnr);
322 return pcibus[busind].pb_rreg8(busind, devind, port);
323 }
324
325 static u16_t
__pci_attr_r16(int devind,int port)326 __pci_attr_r16(int devind, int port)
327 {
328 int busnr, busind;
329
330 busnr= pcidev[devind].pd_busnr;
331 busind= get_busind(busnr);
332 return pcibus[busind].pb_rreg16(busind, devind, port);
333 }
334
335 static u32_t
__pci_attr_r32(int devind,int port)336 __pci_attr_r32(int devind, int port)
337 {
338 int busnr, busind;
339
340 busnr= pcidev[devind].pd_busnr;
341 busind= get_busind(busnr);
342 return pcibus[busind].pb_rreg32(busind, devind, port);
343 }
344
345 static void
__pci_attr_w8(int devind,int port,u8_t value)346 __pci_attr_w8(int devind, int port, u8_t value)
347 {
348 int busnr, busind;
349
350 busnr= pcidev[devind].pd_busnr;
351 busind= get_busind(busnr);
352 pcibus[busind].pb_wreg8(busind, devind, port, value);
353 }
354
355 static void
__pci_attr_w16(int devind,int port,u16_t value)356 __pci_attr_w16(int devind, int port, u16_t value)
357 {
358 int busnr, busind;
359
360 busnr= pcidev[devind].pd_busnr;
361 busind= get_busind(busnr);
362 pcibus[busind].pb_wreg16(busind, devind, port, value);
363 }
364
365 static void
__pci_attr_w32(int devind,int port,u32_t value)366 __pci_attr_w32(int devind, int port, u32_t value)
367 {
368 int busnr, busind;
369
370 busnr= pcidev[devind].pd_busnr;
371 busind= get_busind(busnr);
372 pcibus[busind].pb_wreg32(busind, devind, port, value);
373 }
374
375 /*===========================================================================*
376 * helpers *
377 *===========================================================================*/
378 static u16_t
pci_attr_rsts(int devind)379 pci_attr_rsts(int devind)
380 {
381 int busnr, busind;
382
383 busnr= pcidev[devind].pd_busnr;
384 busind= get_busind(busnr);
385 return pcibus[busind].pb_rsts(busind);
386 }
387
388 static void
pci_attr_wsts(int devind,u16_t value)389 pci_attr_wsts(int devind, u16_t value)
390 {
391 int busnr, busind;
392
393 busnr= pcidev[devind].pd_busnr;
394 busind= get_busind(busnr);
395 pcibus[busind].pb_wsts(busind, value);
396 }
397
398 static u16_t
pcii_rsts(int busind)399 pcii_rsts(int busind)
400 {
401 u16_t v;
402 int s;
403
404 v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
405 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
406 printf("PCI: warning, sys_outl failed: %d\n", s);
407 return v;
408 }
409
410 static void
pcii_wsts(int busind,u16_t value)411 pcii_wsts(int busind, u16_t value)
412 {
413 int s;
414 PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
415 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
416 printf("PCI: warning, sys_outl failed: %d\n", s);
417 }
418
419 static int
is_duplicate(u8_t busnr,u8_t dev,u8_t func)420 is_duplicate(u8_t busnr, u8_t dev, u8_t func)
421 {
422 int i;
423
424 for (i= 0; i<nr_pcidev; i++)
425 {
426 if (pcidev[i].pd_busnr == busnr &&
427 pcidev[i].pd_dev == dev &&
428 pcidev[i].pd_func == func)
429 {
430 return 1;
431 }
432 }
433 return 0;
434 }
435
436 static int
get_freebus(void)437 get_freebus(void)
438 {
439 int i, freebus;
440
441 freebus= 1;
442 for (i= 0; i<nr_pcibus; i++)
443 {
444 if (pcibus[i].pb_needinit)
445 continue;
446 if (pcibus[i].pb_type == PBT_INTEL_HOST)
447 continue;
448 if (pcibus[i].pb_busnr <= freebus)
449 freebus= pcibus[i].pb_busnr+1;
450 printf("get_freebus: should check suboridinate bus number\n");
451 }
452 return freebus;
453 }
454
455 static const char *
pci_vid_name(u16_t vid)456 pci_vid_name(u16_t vid)
457 {
458 static char vendor[PCI_VENDORSTR_LEN];
459 pci_findvendor(vendor, sizeof(vendor), vid);
460
461 return vendor;
462 }
463
464
465 static void
print_hyper_cap(int devind,u8_t capptr)466 print_hyper_cap(int devind, u8_t capptr)
467 {
468 u32_t v;
469 u16_t cmd;
470 int type0, type1;
471
472 printf("\n");
473 v= __pci_attr_r32(devind, capptr);
474 printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr);
475 cmd= (v >> 16) & 0xffff;
476 #if 0
477 if (v & 0x10000)
478 {
479 printf(" WarmReset");
480 v &= ~0x10000;
481 }
482 if (v & 0x20000)
483 {
484 printf(" DblEnded");
485 v &= ~0x20000;
486 }
487 printf(" DevNum %d", (v & 0x7C0000) >> 18);
488 v &= ~0x7C0000;
489 #endif
490 type0= (cmd & 0xE000) >> 13;
491 type1= (cmd & 0xF800) >> 11;
492 if (type0 == 0 || type0 == 1)
493 {
494 printf("Capability Type: %s\n",
495 type0 == 0 ? "Slave or Primary Interface" :
496 "Host or Secondary Interface");
497 cmd &= ~0xE000;
498 }
499 else
500 {
501 printf(" Capability Type 0x%x", type1);
502 cmd &= ~0xF800;
503 }
504 if (cmd)
505 printf(" undecoded 0x%x\n", cmd);
506
507 #if 0
508 printf("print_hyper_cap: off 4 (ctl): 0x%x\n",
509 __pci_attr_r32(devind, capptr+4));
510 printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n",
511 __pci_attr_r32(devind, capptr+8));
512 printf("print_hyper_cap: off 12 (cap): 0x%x\n",
513 __pci_attr_r32(devind, capptr+12));
514 printf("print_hyper_cap: off 16 (buf count): 0x%x\n",
515 __pci_attr_r32(devind, capptr+16));
516 v= __pci_attr_r32(devind, capptr+20);
517 printf("print_hyper_cap: @0x%x, off 20 (bus nr): ",
518 capptr+20);
519 printf("prim %d", v & 0xff);
520 printf(", sec %d", (v >> 8) & 0xff);
521 printf(", sub %d", (v >> 16) & 0xff);
522 if (v >> 24)
523 printf(", reserved %d", (v >> 24) & 0xff);
524 printf("\n");
525 printf("print_hyper_cap: off 24 (type): 0x%x\n",
526 __pci_attr_r32(devind, capptr+24));
527 #endif
528 }
529
530 static void
print_capabilities(int devind)531 print_capabilities(int devind)
532 {
533 u8_t status, capptr, type, next, subtype;
534 const char *str;
535
536 /* Check capabilities bit in the device status register */
537 status= __pci_attr_r16(devind, PCI_SR);
538 if (!(status & PSR_CAPPTR))
539 return;
540
541 capptr= (__pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK);
542 while (capptr != 0)
543 {
544 type = __pci_attr_r8(devind, capptr+CAP_TYPE);
545 next= (__pci_attr_r8(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
546 switch(type)
547 {
548 case 1: str= "PCI Power Management"; break;
549 case 2: str= "AGP"; break;
550 case 3: str= "Vital Product Data"; break;
551 case 4: str= "Slot Identification"; break;
552 case 5: str= "Message Signaled Interrupts"; break;
553 case 6: str= "CompactPCI Hot Swap"; break;
554 case 8: str= "AMD HyperTransport"; break;
555 case 0xf: str= "Secure Device"; break;
556 default: str= "(unknown type)"; break;
557 }
558
559 printf(" @0x%x (0x%08x): capability type 0x%x: %s",
560 capptr, __pci_attr_r32(devind, capptr), type, str);
561 if (type == 0x08)
562 print_hyper_cap(devind, capptr);
563 else if (type == 0x0f)
564 {
565 subtype= (__pci_attr_r8(devind, capptr+2) & 0x07);
566 switch(subtype)
567 {
568 case 0: str= "Device Exclusion Vector"; break;
569 case 3: str= "IOMMU"; break;
570 default: str= "(unknown type)"; break;
571 }
572 printf(", sub type 0%o: %s", subtype, str);
573 }
574 printf("\n");
575 capptr= next;
576 }
577 }
578
579 /*===========================================================================*
580 * ISA Bridge Helpers *
581 *===========================================================================*/
582 static void
update_bridge4dev_io(int devind,u32_t io_base,u32_t io_size)583 update_bridge4dev_io(int devind, u32_t io_base, u32_t io_size)
584 {
585 int busnr, busind, type, br_devind;
586 u16_t v16;
587
588 busnr= pcidev[devind].pd_busnr;
589 busind= get_busind(busnr);
590 type= pcibus[busind].pb_type;
591 if (type == PBT_INTEL_HOST)
592 return; /* Nothing to do for host controller */
593 if (type == PBT_PCIBRIDGE)
594 {
595 printf(
596 "update_bridge4dev_io: not implemented for PCI bridges\n");
597 return;
598 }
599 if (type != PBT_CARDBUS)
600 panic("update_bridge4dev_io: strange bus type: %d", type);
601
602 if (debug)
603 {
604 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
605 io_size, io_base);
606 }
607 br_devind= pcibus[busind].pb_devind;
608 __pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
609 __pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
610
611 /* Enable I/O access. Enable busmaster access as well. */
612 v16= __pci_attr_r16(devind, PCI_CR);
613 __pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
614 }
615
616 static int
do_piix(int devind)617 do_piix(int devind)
618 {
619 int i, s, irqrc, irq;
620 u32_t elcr1, elcr2, elcr;
621
622 #if DEBUG
623 printf("in piix\n");
624 #endif
625 if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
626 printf("Warning, sys_inb failed: %d\n", s);
627 if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
628 printf("Warning, sys_inb failed: %d\n", s);
629 elcr= elcr1 | (elcr2 << 8);
630 for (i= 0; i<4; i++)
631 {
632 irqrc= __pci_attr_r8(devind, PIIX_PIRQRCA+i);
633 if (irqrc & PIIX_IRQ_DI)
634 {
635 if (debug)
636 printf("INT%c: disabled\n", 'A'+i);
637 }
638 else
639 {
640 irq= irqrc & PIIX_IRQ_MASK;
641 if (debug)
642 printf("INT%c: %d\n", 'A'+i, irq);
643 if (!(elcr & (1 << irq)))
644 {
645 if (debug)
646 {
647 printf(
648 "(warning) IRQ %d is not level triggered\n",
649 irq);
650 }
651 }
652 irq_mode_pci(irq);
653 }
654 }
655 return 0;
656 }
657
658 static int
do_amd_isabr(int devind)659 do_amd_isabr(int devind)
660 {
661 int i, busnr, dev, func, xdevind, irq, edge;
662 u8_t levmask;
663 u16_t pciirq;
664
665 /* Find required function */
666 func= AMD_ISABR_FUNC;
667 busnr= pcidev[devind].pd_busnr;
668 dev= pcidev[devind].pd_dev;
669
670 /* Fake a device with the required function */
671 if (nr_pcidev >= NR_PCIDEV)
672 panic("too many PCI devices: %d", nr_pcidev);
673 xdevind= nr_pcidev;
674 pcidev[xdevind].pd_busnr= busnr;
675 pcidev[xdevind].pd_dev= dev;
676 pcidev[xdevind].pd_func= func;
677 pcidev[xdevind].pd_inuse= 1;
678 nr_pcidev++;
679
680 levmask= __pci_attr_r8(xdevind, AMD_ISABR_PCIIRQ_LEV);
681 pciirq= __pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
682 for (i= 0; i<4; i++)
683 {
684 edge= (levmask >> i) & 1;
685 irq= (pciirq >> (4*i)) & 0xf;
686 if (!irq)
687 {
688 if (debug)
689 printf("INT%c: disabled\n", 'A'+i);
690 }
691 else
692 {
693 if (debug)
694 printf("INT%c: %d\n", 'A'+i, irq);
695 if (edge && debug)
696 {
697 printf(
698 "(warning) IRQ %d is not level triggered\n",
699 irq);
700 }
701 irq_mode_pci(irq);
702 }
703 }
704 nr_pcidev--;
705 return 0;
706 }
707
708 static int
do_sis_isabr(int devind)709 do_sis_isabr(int devind)
710 {
711 int i, irq;
712
713 irq= 0; /* lint */
714 for (i= 0; i<4; i++)
715 {
716 irq= __pci_attr_r8(devind, SIS_ISABR_IRQ_A+i);
717 if (irq & SIS_IRQ_DISABLED)
718 {
719 if (debug)
720 printf("INT%c: disabled\n", 'A'+i);
721 }
722 else
723 {
724 irq &= SIS_IRQ_MASK;
725 if (debug)
726 printf("INT%c: %d\n", 'A'+i, irq);
727 irq_mode_pci(irq);
728 }
729 }
730 return 0;
731 }
732
733 static int
do_via_isabr(int devind)734 do_via_isabr(int devind)
735 {
736 int i, irq, edge;
737 u8_t levmask;
738
739 levmask= __pci_attr_r8(devind, VIA_ISABR_EL);
740 irq= 0; /* lint */
741 edge= 0; /* lint */
742 for (i= 0; i<4; i++)
743 {
744 switch(i)
745 {
746 case 0:
747 edge= (levmask & VIA_ISABR_EL_INTA);
748 irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R2) >> 4;
749 break;
750 case 1:
751 edge= (levmask & VIA_ISABR_EL_INTB);
752 irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R2);
753 break;
754 case 2:
755 edge= (levmask & VIA_ISABR_EL_INTC);
756 irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R3) >> 4;
757 break;
758 case 3:
759 edge= (levmask & VIA_ISABR_EL_INTD);
760 irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R1) >> 4;
761 break;
762 default:
763 panic("PCI: VIA ISA Bridge IRQ Detection Failed");
764 }
765 irq &= 0xf;
766 if (!irq)
767 {
768 if (debug)
769 printf("INT%c: disabled\n", 'A'+i);
770 }
771 else
772 {
773 if (debug)
774 printf("INT%c: %d\n", 'A'+i, irq);
775 if (edge && debug)
776 {
777 printf(
778 "(warning) IRQ %d is not level triggered\n",
779 irq);
780 }
781 irq_mode_pci(irq);
782 }
783 }
784 return 0;
785 }
786
787 static int
do_isabridge(int busind)788 do_isabridge(int busind)
789 {
790 int i, j, r, type, busnr, unknown_bridge, bridge_dev;
791 u16_t vid, did;
792 u32_t t3;
793 const char *dstr;
794
795 unknown_bridge= -1;
796 bridge_dev= -1;
797 j= 0; /* lint */
798 vid= did= 0; /* lint */
799 busnr= pcibus[busind].pb_busnr;
800 for (i= 0; i< nr_pcidev; i++)
801 {
802 if (pcidev[i].pd_busnr != busnr)
803 continue;
804 t3= ((pcidev[i].pd_baseclass << 16) |
805 (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
806 if (t3 == PCI_T3_ISA)
807 {
808 /* ISA bridge. Report if no supported bridge is
809 * found.
810 */
811 unknown_bridge= i;
812 }
813
814 vid= pcidev[i].pd_vid;
815 did= pcidev[i].pd_did;
816 for (j= 0; pci_isabridge[j].vid != 0; j++)
817 {
818 if (pci_isabridge[j].vid != vid)
819 continue;
820 if (pci_isabridge[j].did != did)
821 continue;
822 if (pci_isabridge[j].checkclass &&
823 unknown_bridge != i)
824 {
825 /* This part of multifunction device is
826 * not the bridge.
827 */
828 continue;
829 }
830 break;
831 }
832 if (pci_isabridge[j].vid)
833 {
834 bridge_dev= i;
835 break;
836 }
837 }
838
839 if (bridge_dev != -1)
840 {
841 dstr= _pci_dev_name(vid, did);
842 if (!dstr)
843 dstr= "unknown device";
844 if (debug)
845 {
846 printf("found ISA bridge (%04X:%04X) %s\n",
847 vid, did, dstr);
848 }
849 pcibus[busind].pb_isabridge_dev= bridge_dev;
850 type= pci_isabridge[j].type;
851 pcibus[busind].pb_isabridge_type= type;
852 switch(type)
853 {
854 case PCI_IB_PIIX:
855 r= do_piix(bridge_dev);
856 break;
857 case PCI_IB_VIA:
858 r= do_via_isabr(bridge_dev);
859 break;
860 case PCI_IB_AMD:
861 r= do_amd_isabr(bridge_dev);
862 break;
863 case PCI_IB_SIS:
864 r= do_sis_isabr(bridge_dev);
865 break;
866 default:
867 panic("unknown ISA bridge type: %d", type);
868 }
869 return r;
870 }
871
872 if (unknown_bridge == -1)
873 {
874 if (debug)
875 {
876 printf("(warning) no ISA bridge found on bus %d\n",
877 busind);
878 }
879 return 0;
880 }
881 if (debug)
882 {
883 printf(
884 "(warning) unsupported ISA bridge %04X:%04X for bus %d\n",
885 pcidev[unknown_bridge].pd_vid,
886 pcidev[unknown_bridge].pd_did, busind);
887 }
888 return 0;
889 }
890
891 static int
derive_irq(struct pcidev * dev,int pin)892 derive_irq(struct pcidev * dev, int pin)
893 {
894 struct pcidev * parent_bridge;
895 int slot;
896
897 parent_bridge = &pcidev[pcibus[get_busind(dev->pd_busnr)].pb_devind];
898
899 /*
900 * We don't support PCI-Express, no ARI, decode the slot of the device
901 * and mangle the pin as the device is behind a bridge
902 */
903 slot = ((dev->pd_func) >> 3) & 0x1f;
904
905 return acpi_get_irq(parent_bridge->pd_busnr,
906 parent_bridge->pd_dev, (pin + slot) % 4);
907 }
908
909 static void
record_irq(int devind)910 record_irq(int devind)
911 {
912 int ilr, ipr, busnr, busind, cb_devind;
913
914 ilr= __pci_attr_r8(devind, PCI_ILR);
915 ipr= __pci_attr_r8(devind, PCI_IPR);
916
917 if (ipr && machine.apic_enabled) {
918 int irq;
919
920 irq = acpi_get_irq(pcidev[devind].pd_busnr,
921 pcidev[devind].pd_dev, ipr - 1);
922
923 if (irq < 0)
924 irq = derive_irq(&pcidev[devind], ipr - 1);
925
926 if (irq >= 0) {
927 ilr = irq;
928 __pci_attr_w8(devind, PCI_ILR, ilr);
929 if (debug)
930 printf("PCI: ACPI IRQ %d for "
931 "device %d.%d.%d INT%c\n",
932 irq,
933 pcidev[devind].pd_busnr,
934 pcidev[devind].pd_dev,
935 pcidev[devind].pd_func,
936 'A' + ipr-1);
937 }
938 else if (debug) {
939 printf("PCI: no ACPI IRQ routing for "
940 "device %d.%d.%d INT%c\n",
941 pcidev[devind].pd_busnr,
942 pcidev[devind].pd_dev,
943 pcidev[devind].pd_func,
944 'A' + ipr-1);
945 }
946 }
947
948 if (ilr == 0)
949 {
950 static int first= 1;
951 if (ipr && first && debug)
952 {
953 first= 0;
954 printf("PCI: strange, BIOS assigned IRQ0\n");
955 }
956 ilr= PCI_ILR_UNKNOWN;
957 }
958 pcidev[devind].pd_ilr= ilr;
959 if (ilr == PCI_ILR_UNKNOWN && !ipr)
960 {
961 }
962 else if (ilr != PCI_ILR_UNKNOWN && ipr)
963 {
964 if (debug)
965 printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
966 }
967 else if (ilr != PCI_ILR_UNKNOWN)
968 {
969 printf(
970 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
971 ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
972 pcidev[devind].pd_func);
973 }
974 else
975 {
976 /* Check for cardbus devices */
977 busnr= pcidev[devind].pd_busnr;
978 busind= get_busind(busnr);
979 if (pcibus[busind].pb_type == PBT_CARDBUS)
980 {
981 cb_devind= pcibus[busind].pb_devind;
982 ilr= pcidev[cb_devind].pd_ilr;
983 if (ilr != PCI_ILR_UNKNOWN)
984 {
985 if (debug)
986 {
987 printf(
988 "assigning IRQ %d to Cardbus device\n",
989 ilr);
990 }
991 __pci_attr_w8(devind, PCI_ILR, ilr);
992 pcidev[devind].pd_ilr= ilr;
993 return;
994 }
995 }
996 if(debug) {
997 printf(
998 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
999 pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
1000 pcidev[devind].pd_func, 'A' + ipr-1);
1001 }
1002 }
1003 }
1004
1005 /*===========================================================================*
1006 * BAR helpers *
1007 *===========================================================================*/
1008 static int
record_bar(int devind,int bar_nr,int last)1009 record_bar(int devind, int bar_nr, int last)
1010 {
1011 int reg, prefetch, type, dev_bar_nr, width;
1012 u32_t bar, bar2;
1013 u16_t cmd;
1014
1015 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
1016 width = 1;
1017
1018 reg= PCI_BAR+4*bar_nr;
1019
1020 bar= __pci_attr_r32(devind, reg);
1021 if (bar & PCI_BAR_IO)
1022 {
1023 /* Disable I/O access before probing for BAR's size */
1024 cmd = __pci_attr_r16(devind, PCI_CR);
1025 __pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_IO_EN);
1026
1027 /* Probe BAR's size */
1028 __pci_attr_w32(devind, reg, 0xffffffff);
1029 bar2= __pci_attr_r32(devind, reg);
1030
1031 /* Restore original state */
1032 __pci_attr_w32(devind, reg, bar);
1033 __pci_attr_w16(devind, PCI_CR, cmd);
1034
1035 bar &= PCI_BAR_IO_MASK; /* Clear non-address bits */
1036 bar2 &= PCI_BAR_IO_MASK;
1037 bar2= (~bar2 & 0xffff)+1;
1038 if (debug)
1039 {
1040 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1041 bar_nr, bar2, bar);
1042 }
1043
1044 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1045 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO;
1046 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1047 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1048 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1049 if (bar == 0)
1050 {
1051 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1052 PBF_INCOMPLETE;
1053 }
1054 }
1055 else
1056 {
1057 type= (bar & PCI_BAR_TYPE);
1058
1059 switch(type) {
1060 case PCI_TYPE_32:
1061 case PCI_TYPE_32_1M:
1062 break;
1063
1064 case PCI_TYPE_64:
1065 /* A 64-bit BAR takes up two consecutive DWORDs. */
1066 if (last)
1067 {
1068 printf("PCI: device %d.%d.%d BAR %d extends"
1069 " beyond designated area\n",
1070 pcidev[devind].pd_busnr,
1071 pcidev[devind].pd_dev,
1072 pcidev[devind].pd_func, bar_nr);
1073
1074 return width;
1075 }
1076 width++;
1077
1078 bar2= __pci_attr_r32(devind, reg+4);
1079
1080 /* If the upper 32 bits of the BAR are not zero, the
1081 * memory is inaccessible to us; ignore the BAR.
1082 */
1083 if (bar2 != 0)
1084 {
1085 if (debug)
1086 {
1087 printf("\tbar_%d: (64-bit BAR with"
1088 " high bits set)\n", bar_nr);
1089 }
1090
1091 return width;
1092 }
1093
1094 break;
1095
1096 default:
1097 /* Ignore the BAR. */
1098 if (debug)
1099 {
1100 printf("\tbar_%d: (unknown type %x)\n",
1101 bar_nr, type);
1102 }
1103
1104 return width;
1105 }
1106
1107 /* Disable mem access before probing for BAR's size */
1108 cmd = __pci_attr_r16(devind, PCI_CR);
1109 __pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_MEM_EN);
1110
1111 /* Probe BAR's size */
1112 __pci_attr_w32(devind, reg, 0xffffffff);
1113 bar2= __pci_attr_r32(devind, reg);
1114
1115 /* Restore original values */
1116 __pci_attr_w32(devind, reg, bar);
1117 __pci_attr_w16(devind, PCI_CR, cmd);
1118
1119 if (bar2 == 0)
1120 return width; /* Reg. is not implemented */
1121
1122 prefetch= !!(bar & PCI_BAR_PREFETCH);
1123 bar &= PCI_BAR_MEM_MASK; /* Clear non-address bits */
1124 bar2 &= PCI_BAR_MEM_MASK;
1125 bar2= (~bar2)+1;
1126 if (debug)
1127 {
1128 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n",
1129 bar_nr, bar2, bar,
1130 prefetch ? " prefetchable" : "",
1131 type == PCI_TYPE_64 ? ", 64-bit" : "");
1132 }
1133
1134 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1135 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0;
1136 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1137 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1138 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1139 if (bar == 0)
1140 {
1141 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1142 PBF_INCOMPLETE;
1143 }
1144 }
1145
1146 return width;
1147 }
1148
1149 static void
record_bars(int devind,int last_reg)1150 record_bars(int devind, int last_reg)
1151 {
1152 int i, reg, width;
1153
1154 for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width)
1155 {
1156 width = record_bar(devind, i, reg == last_reg);
1157 }
1158 }
1159
1160 static void
record_bars_normal(int devind)1161 record_bars_normal(int devind)
1162 {
1163 int i, j, clear_01, clear_23, pb_nr;
1164
1165 /* The BAR area of normal devices is six DWORDs in size. */
1166 record_bars(devind, PCI_BAR_6);
1167
1168 /* Special case code for IDE controllers in compatibility mode */
1169 if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
1170 pcidev[devind].pd_subclass == PCI_MS_IDE)
1171 {
1172 /* IDE device */
1173 clear_01= 0;
1174 clear_23= 0;
1175 if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
1176 {
1177 if (debug)
1178 {
1179 printf(
1180 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1181 }
1182 clear_01= 1;
1183 }
1184 if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
1185 {
1186 if (debug)
1187 {
1188 printf(
1189 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
1190 }
1191 clear_23= 1;
1192 }
1193
1194 j= 0;
1195 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
1196 {
1197 pb_nr= pcidev[devind].pd_bar[i].pb_nr;
1198 if ((pb_nr == 0 || pb_nr == 1) && clear_01)
1199 {
1200 if (debug) printf("skipping bar %d\n", pb_nr);
1201 continue; /* Skip */
1202 }
1203 if ((pb_nr == 2 || pb_nr == 3) && clear_23)
1204 {
1205 if (debug) printf("skipping bar %d\n", pb_nr);
1206 continue; /* Skip */
1207 }
1208 if (i == j)
1209 {
1210 j++;
1211 continue; /* No need to copy */
1212 }
1213 pcidev[devind].pd_bar[j]=
1214 pcidev[devind].pd_bar[i];
1215 j++;
1216 }
1217 pcidev[devind].pd_bar_nr= j;
1218 }
1219 }
1220
1221 static void
record_bars_bridge(int devind)1222 record_bars_bridge(int devind)
1223 {
1224 u32_t base, limit, size;
1225
1226 /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
1227 * It may contain up to two 32-bit BARs, or one 64-bit BAR.
1228 */
1229 record_bars(devind, PCI_BAR_2);
1230
1231 base= ((__pci_attr_r8(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
1232 (__pci_attr_r16(devind, PPB_IOBASEU16) << 16);
1233 limit= 0xff |
1234 ((__pci_attr_r8(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
1235 ((~PPB_IOL_MASK & 0xff) << 8) |
1236 (__pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
1237 size= limit-base + 1;
1238 if (debug)
1239 {
1240 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1241 base, limit, size);
1242 }
1243
1244 base= ((__pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
1245 limit= 0xffff |
1246 ((__pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
1247 ((~PPB_MEML_MASK & 0xffff) << 16);
1248 size= limit-base + 1;
1249 if (debug)
1250 {
1251 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1252 base, limit, size);
1253 }
1254
1255 /* Ignore the upper 32 bits */
1256 base= ((__pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
1257 limit= 0xffff |
1258 ((__pci_attr_r16(devind, PPB_PFMEMLIMIT) &
1259 PPB_PFMEML_MASK) << 16) |
1260 ((~PPB_PFMEML_MASK & 0xffff) << 16);
1261 size= limit-base + 1;
1262 if (debug)
1263 {
1264 printf(
1265 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1266 base, limit, size);
1267 }
1268 }
1269
1270 static void
record_bars_cardbus(int devind)1271 record_bars_cardbus(int devind)
1272 {
1273 u32_t base, limit, size;
1274
1275 /* The generic BAR area of CardBus devices is one DWORD in size. */
1276 record_bars(devind, PCI_BAR);
1277
1278 base= __pci_attr_r32(devind, CBB_MEMBASE_0);
1279 limit= __pci_attr_r32(devind, CBB_MEMLIMIT_0) |
1280 (~CBB_MEML_MASK & 0xffffffff);
1281 size= limit-base + 1;
1282 if (debug)
1283 {
1284 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1285 base, limit, size);
1286 }
1287
1288 base= __pci_attr_r32(devind, CBB_MEMBASE_1);
1289 limit= __pci_attr_r32(devind, CBB_MEMLIMIT_1) |
1290 (~CBB_MEML_MASK & 0xffffffff);
1291 size= limit-base + 1;
1292 if (debug)
1293 {
1294 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1295 base, limit, size);
1296 }
1297
1298 base= __pci_attr_r32(devind, CBB_IOBASE_0);
1299 limit= __pci_attr_r32(devind, CBB_IOLIMIT_0) |
1300 (~CBB_IOL_MASK & 0xffffffff);
1301 size= limit-base + 1;
1302 if (debug)
1303 {
1304 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1305 base, limit, size);
1306 }
1307
1308 base= __pci_attr_r32(devind, CBB_IOBASE_1);
1309 limit= __pci_attr_r32(devind, CBB_IOLIMIT_1) |
1310 (~CBB_IOL_MASK & 0xffffffff);
1311 size= limit-base + 1;
1312 if (debug)
1313 {
1314 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1315 base, limit, size);
1316 }
1317 }
1318
1319 static void
complete_bars(void)1320 complete_bars(void)
1321 {
1322 int i, j, bar_nr, reg;
1323 u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
1324 base, size, v32, diff1, diff2;
1325 kinfo_t kinfo;
1326
1327 if(OK != sys_getkinfo(&kinfo))
1328 panic("can't get kinfo");
1329
1330 /* Set memgap_low to just above physical memory */
1331 memgap_low= kinfo.mem_high_phys;
1332 memgap_high= 0xfe000000; /* Leave space for the CPU (APIC) */
1333
1334 if (debug)
1335 {
1336 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1337 memgap_low, memgap_high);
1338 }
1339
1340 /* Find the lowest memory base */
1341 for (i= 0; i<nr_pcidev; i++)
1342 {
1343 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1344 {
1345 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1346 continue;
1347 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1348 continue;
1349 base= pcidev[i].pd_bar[j].pb_base;
1350 size= pcidev[i].pd_bar[j].pb_size;
1351
1352 if (base >= memgap_high)
1353 continue; /* Not in the gap */
1354 if (base+size <= memgap_low)
1355 continue; /* Not in the gap */
1356
1357 /* Reduce the gap by the smallest amount */
1358 diff1= base+size-memgap_low;
1359 diff2= memgap_high-base;
1360
1361 if (diff1 < diff2)
1362 memgap_low= base+size;
1363 else
1364 memgap_high= base;
1365 }
1366 }
1367
1368 if (debug)
1369 {
1370 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1371 memgap_low, memgap_high);
1372 }
1373
1374 /* Should check main memory size */
1375 if (memgap_high < memgap_low)
1376 {
1377 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1378 memgap_low, memgap_high);
1379 panic(NULL);
1380 }
1381
1382 iogap_high= 0x10000;
1383 iogap_low= 0x400;
1384
1385 /* Find the free I/O space */
1386 for (i= 0; i<nr_pcidev; i++)
1387 {
1388 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1389 {
1390 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1391 continue;
1392 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1393 continue;
1394 base= pcidev[i].pd_bar[j].pb_base;
1395 size= pcidev[i].pd_bar[j].pb_size;
1396 if (base >= iogap_high)
1397 continue;
1398 if (base+size <= iogap_low)
1399 continue;
1400 #if 0
1401 if (debug)
1402 {
1403 printf(
1404 "pci device %d (%04x:%04x), bar %d: base 0x%x, size 0x%x\n",
1405 i, pcidev[i].pd_vid, pcidev[i].pd_did,
1406 j, base, size);
1407 }
1408 #endif
1409 if (base+size-iogap_low < iogap_high-base)
1410 iogap_low= base+size;
1411 else
1412 iogap_high= base;
1413 }
1414 }
1415
1416 if (iogap_high < iogap_low)
1417 {
1418 if (debug)
1419 {
1420 printf("iogap_high too low, should panic\n");
1421 }
1422 else
1423 panic("iogap_high too low: %d", iogap_high);
1424 }
1425 if (debug)
1426 printf("I/O range = [0x%x..0x%x>\n", iogap_low, iogap_high);
1427
1428 for (i= 0; i<nr_pcidev; i++)
1429 {
1430 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1431 {
1432 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1433 continue;
1434 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1435 continue;
1436 size= pcidev[i].pd_bar[j].pb_size;
1437 if (size < PAGE_SIZE)
1438 size= PAGE_SIZE;
1439 base= memgap_high-size;
1440 base &= ~(u32_t)(size-1);
1441 if (base < memgap_low)
1442 panic("memory base too low: %d", base);
1443 memgap_high= base;
1444 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1445 reg= PCI_BAR + 4*bar_nr;
1446 v32= __pci_attr_r32(i, reg);
1447 __pci_attr_w32(i, reg, v32 | base);
1448 if (debug)
1449 {
1450 printf(
1451 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1452 base, size, pcidev[i].pd_busnr,
1453 pcidev[i].pd_dev, pcidev[i].pd_func,
1454 bar_nr);
1455 }
1456 pcidev[i].pd_bar[j].pb_base= base;
1457 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1458 }
1459
1460 io_high= iogap_high;
1461 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1462 {
1463 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1464 continue;
1465 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1466 continue;
1467 size= pcidev[i].pd_bar[j].pb_size;
1468 base= iogap_high-size;
1469 base &= ~(u32_t)(size-1);
1470
1471 /* Assume that ISA compatibility is required. Only
1472 * use the lowest 256 bytes out of every 1024 bytes.
1473 */
1474 base &= 0xfcff;
1475
1476 if (base < iogap_low)
1477 printf("I/O base too low: %d", base);
1478
1479 iogap_high= base;
1480 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1481 reg= PCI_BAR + 4*bar_nr;
1482 v32= __pci_attr_r32(i, reg);
1483 __pci_attr_w32(i, reg, v32 | base);
1484 if (debug)
1485 {
1486 printf(
1487 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1488 base, size, pcidev[i].pd_busnr,
1489 pcidev[i].pd_dev, pcidev[i].pd_func,
1490 bar_nr);
1491 }
1492 pcidev[i].pd_bar[j].pb_base= base;
1493 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1494
1495 }
1496 if (iogap_high != io_high)
1497 {
1498 update_bridge4dev_io(i, iogap_high,
1499 io_high-iogap_high);
1500 }
1501 }
1502
1503 for (i= 0; i<nr_pcidev; i++)
1504 {
1505 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1506 {
1507 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1508 continue;
1509 printf("should allocate resources for device %d\n", i);
1510 }
1511 }
1512 return;
1513 }
1514
1515 /*===========================================================================*
1516 * PCI Bridge Helpers *
1517 *===========================================================================*/
1518 static void
probe_bus(int busind)1519 probe_bus(int busind)
1520 {
1521 uint32_t dev, func;
1522 #if 0
1523 uint32_t t3;
1524 #endif
1525 u16_t vid, did, sts, sub_vid, sub_did;
1526 u8_t headt;
1527 u8_t baseclass, subclass, infclass;
1528 int devind, busnr;
1529 const char *s, *dstr;
1530
1531 if (debug)
1532 printf("probe_bus(%d)\n", busind);
1533 if (nr_pcidev >= NR_PCIDEV)
1534 panic("too many PCI devices: %d", nr_pcidev);
1535 devind= nr_pcidev;
1536
1537 busnr= pcibus[busind].pb_busnr;
1538 for (dev= 0; dev<32; dev++)
1539 {
1540
1541 for (func= 0; func < 8; func++)
1542 {
1543 pcidev[devind].pd_busnr= busnr;
1544 pcidev[devind].pd_dev= dev;
1545 pcidev[devind].pd_func= func;
1546
1547 pci_attr_wsts(devind,
1548 PSR_SSE|PSR_RMAS|PSR_RTAS);
1549 vid= __pci_attr_r16(devind, PCI_VID);
1550 did= __pci_attr_r16(devind, PCI_DID);
1551 headt= __pci_attr_r8(devind, PCI_HEADT);
1552 sts= pci_attr_rsts(devind);
1553
1554 #if 0
1555 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
1556 vid, did, headt, sts);
1557 #endif
1558
1559 if (vid == NO_VID && did == NO_VID)
1560 {
1561 if (func == 0)
1562 break; /* Nothing here */
1563
1564 /* Scan all functions of a multifunction
1565 * device.
1566 */
1567 continue;
1568 }
1569
1570 if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
1571 {
1572 static int warned = 0;
1573
1574 if(!warned) {
1575 printf(
1576 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
1577 sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
1578 warned = 1;
1579 }
1580 }
1581
1582 sub_vid= __pci_attr_r16(devind, PCI_SUBVID);
1583 sub_did= __pci_attr_r16(devind, PCI_SUBDID);
1584
1585 dstr= _pci_dev_name(vid, did);
1586 if (debug)
1587 {
1588 if (dstr)
1589 {
1590 printf("%d.%lu.%lu: %s (%04X:%04X)\n",
1591 busnr, (unsigned long)dev,
1592 (unsigned long)func, dstr,
1593 vid, did);
1594 }
1595 else
1596 {
1597 printf(
1598 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
1599 busnr, (unsigned long)dev,
1600 (unsigned long)func, vid,
1601 pci_vid_name(vid), did);
1602 }
1603 printf("Device index: %d\n", devind);
1604 printf("Subsystem: Vid 0x%x, did 0x%x\n",
1605 sub_vid, sub_did);
1606 }
1607
1608 baseclass= __pci_attr_r8(devind, PCI_BCR);
1609 subclass= __pci_attr_r8(devind, PCI_SCR);
1610 infclass= __pci_attr_r8(devind, PCI_PIFR);
1611 s= pci_subclass_name(baseclass << 24 | subclass << 16);
1612 if (!s)
1613 s= pci_baseclass_name(baseclass << 24);
1614 {
1615 if (!s)
1616 s= "(unknown class)";
1617 }
1618 if (debug)
1619 {
1620 printf("\tclass %s (%X/%X/%X)\n", s,
1621 baseclass, subclass, infclass);
1622 }
1623
1624 if (is_duplicate(busnr, dev, func))
1625 {
1626 printf("\tduplicate!\n");
1627 if (func == 0 && !(headt & PHT_MULTIFUNC))
1628 break;
1629 continue;
1630 }
1631
1632 devind= nr_pcidev;
1633 nr_pcidev++;
1634 pcidev[devind].pd_baseclass= baseclass;
1635 pcidev[devind].pd_subclass= subclass;
1636 pcidev[devind].pd_infclass= infclass;
1637 pcidev[devind].pd_vid= vid;
1638 pcidev[devind].pd_did= did;
1639 pcidev[devind].pd_sub_vid= sub_vid;
1640 pcidev[devind].pd_sub_did= sub_did;
1641 pcidev[devind].pd_inuse= 0;
1642 pcidev[devind].pd_bar_nr= 0;
1643 record_irq(devind);
1644 switch(headt & PHT_MASK)
1645 {
1646 case PHT_NORMAL:
1647 record_bars_normal(devind);
1648 break;
1649 case PHT_BRIDGE:
1650 record_bars_bridge(devind);
1651 break;
1652 case PHT_CARDBUS:
1653 record_bars_cardbus(devind);
1654 break;
1655 default:
1656 printf("\t%d.%d.%d: unknown header type %d\n",
1657 busind, dev, func,
1658 headt & PHT_MASK);
1659 break;
1660 }
1661 if (debug)
1662 print_capabilities(devind);
1663
1664 #if 0
1665 t3= ((baseclass << 16) | (subclass << 8) | infclass);
1666 if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
1667 report_vga(devind);
1668 #endif
1669
1670 if (nr_pcidev >= NR_PCIDEV)
1671 panic("too many PCI devices: %d", nr_pcidev);
1672 devind= nr_pcidev;
1673
1674 if (func == 0 && !(headt & PHT_MULTIFUNC))
1675 break;
1676 }
1677 }
1678 }
1679
1680
1681 static u16_t
pcibr_std_rsts(int busind)1682 pcibr_std_rsts(int busind)
1683 {
1684 int devind;
1685
1686 devind= pcibus[busind].pb_devind;
1687 return __pci_attr_r16(devind, PPB_SSTS);
1688 }
1689
1690 static void
pcibr_std_wsts(int busind,u16_t value)1691 pcibr_std_wsts(int busind, u16_t value)
1692 {
1693 int devind;
1694 devind= pcibus[busind].pb_devind;
1695
1696 #if 0
1697 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
1698 busind, value, devind);
1699 #endif
1700 __pci_attr_w16(devind, PPB_SSTS, value);
1701 }
1702
1703 static u16_t
pcibr_cb_rsts(int busind)1704 pcibr_cb_rsts(int busind)
1705 {
1706 int devind;
1707 devind= pcibus[busind].pb_devind;
1708
1709 return __pci_attr_r16(devind, CBB_SSTS);
1710 }
1711
1712 static void
pcibr_cb_wsts(int busind,u16_t value)1713 pcibr_cb_wsts(int busind, u16_t value)
1714 {
1715 int devind;
1716 devind= pcibus[busind].pb_devind;
1717
1718 #if 0
1719 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
1720 busind, value, devind);
1721 #endif
1722 __pci_attr_w16(devind, CBB_SSTS, value);
1723 }
1724
1725 static u16_t
pcibr_via_rsts(int busind)1726 pcibr_via_rsts(int busind)
1727 {
1728 return 0;
1729 }
1730
1731 static void
pcibr_via_wsts(int busind,u16_t value)1732 pcibr_via_wsts(int busind, u16_t value)
1733 {
1734 #if 0
1735 int devind;
1736 devind= pcibus[busind].pb_devind;
1737
1738 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
1739 busind, value, devind);
1740 #endif
1741 }
1742
1743 static void
complete_bridges(void)1744 complete_bridges(void)
1745 {
1746 int i, freebus, devind, prim_busnr;
1747
1748 for (i= 0; i<nr_pcibus; i++)
1749 {
1750 if (!pcibus[i].pb_needinit)
1751 continue;
1752 printf("should allocate bus number for bus %d\n", i);
1753 freebus= get_freebus();
1754 printf("got bus number %d\n", freebus);
1755
1756 devind= pcibus[i].pb_devind;
1757
1758 prim_busnr= pcidev[devind].pd_busnr;
1759 if (prim_busnr != 0)
1760 {
1761 printf(
1762 "complete_bridge: updating subordinate bus number not implemented\n");
1763 }
1764
1765 pcibus[i].pb_needinit= 0;
1766 pcibus[i].pb_busnr= freebus;
1767
1768 printf("devind = %d\n", devind);
1769 printf("prim_busnr= %d\n", prim_busnr);
1770
1771 __pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
1772 __pci_attr_w8(devind, PPB_SECBN, freebus);
1773 __pci_attr_w8(devind, PPB_SUBORDBN, freebus);
1774
1775 printf("CR = 0x%x\n", __pci_attr_r16(devind, PCI_CR));
1776 printf("SECBLT = 0x%x\n", __pci_attr_r8(devind, PPB_SECBLT));
1777 printf("BRIDGECTRL = 0x%x\n",
1778 __pci_attr_r16(devind, PPB_BRIDGECTRL));
1779 }
1780 }
1781
1782 static void
do_pcibridge(int busind)1783 do_pcibridge(int busind)
1784 {
1785 int devind, busnr;
1786 int ind, type;
1787 u16_t vid, did;
1788 u8_t sbusn, baseclass, subclass, infclass, headt;
1789 u32_t t3;
1790
1791 vid= did= 0; /* lint */
1792 busnr= pcibus[busind].pb_busnr;
1793 for (devind= 0; devind< nr_pcidev; devind++)
1794 {
1795 if (pcidev[devind].pd_busnr != busnr)
1796 {
1797 #if 0
1798 printf("wrong bus\n");
1799 #endif
1800 continue;
1801 }
1802
1803 vid= pcidev[devind].pd_vid;
1804 did= pcidev[devind].pd_did;
1805 /* LSC: The table is empty, so always true...
1806 if (pci_pcibridge[i].vid == 0) */
1807 {
1808 headt= __pci_attr_r8(devind, PCI_HEADT);
1809 type= 0;
1810 if ((headt & PHT_MASK) == PHT_BRIDGE)
1811 type= PCI_PPB_STD;
1812 else if ((headt & PHT_MASK) == PHT_CARDBUS)
1813 type= PCI_PPB_CB;
1814 else
1815 {
1816 #if 0
1817 printf("not a bridge\n");
1818 #endif
1819 continue; /* Not a bridge */
1820 }
1821
1822 baseclass= __pci_attr_r8(devind, PCI_BCR);
1823 subclass= __pci_attr_r8(devind, PCI_SCR);
1824 infclass= __pci_attr_r8(devind, PCI_PIFR);
1825 t3= ((baseclass << 16) | (subclass << 8) | infclass);
1826 if (type == PCI_PPB_STD &&
1827 t3 != PCI_T3_PCI2PCI &&
1828 t3 != PCI_T3_PCI2PCI_SUBTR)
1829 {
1830 printf(
1831 "Unknown PCI class %02x/%02x/%02x for PCI-to-PCI bridge, device %04X:%04X\n",
1832 baseclass, subclass, infclass,
1833 vid, did);
1834 continue;
1835 }
1836 if (type == PCI_PPB_CB &&
1837 t3 != PCI_T3_CARDBUS)
1838 {
1839 printf(
1840 "Unknown PCI class %02x/%02x/%02x for Cardbus bridge, device %04X:%04X\n",
1841 baseclass, subclass, infclass,
1842 vid, did);
1843 continue;
1844 }
1845 }
1846
1847 if (debug)
1848 {
1849 printf("%u.%u.%u: PCI-to-PCI bridge: %04X:%04X\n",
1850 pcidev[devind].pd_busnr,
1851 pcidev[devind].pd_dev,
1852 pcidev[devind].pd_func, vid, did);
1853 }
1854
1855 /* Assume that the BIOS initialized the secondary bus
1856 * number.
1857 */
1858 sbusn= __pci_attr_r8(devind, PPB_SECBN);
1859
1860 if (nr_pcibus >= NR_PCIBUS)
1861 panic("too many PCI busses: %d", nr_pcibus);
1862 ind= nr_pcibus;
1863 nr_pcibus++;
1864 pcibus[ind].pb_type= PBT_PCIBRIDGE;
1865 pcibus[ind].pb_needinit= 1;
1866 pcibus[ind].pb_isabridge_dev= -1;
1867 pcibus[ind].pb_isabridge_type= 0;
1868 pcibus[ind].pb_devind= devind;
1869 pcibus[ind].pb_busnr= sbusn;
1870 pcibus[ind].pb_rreg8= pcibus[busind].pb_rreg8;
1871 pcibus[ind].pb_rreg16= pcibus[busind].pb_rreg16;
1872 pcibus[ind].pb_rreg32= pcibus[busind].pb_rreg32;
1873 pcibus[ind].pb_wreg8= pcibus[busind].pb_wreg8;
1874 pcibus[ind].pb_wreg16= pcibus[busind].pb_wreg16;
1875 pcibus[ind].pb_wreg32= pcibus[busind].pb_wreg32;
1876 switch(type)
1877 {
1878 case PCI_PPB_STD:
1879 pcibus[ind].pb_rsts= pcibr_std_rsts;
1880 pcibus[ind].pb_wsts= pcibr_std_wsts;
1881 break;
1882 case PCI_PPB_CB:
1883 pcibus[ind].pb_type= PBT_CARDBUS;
1884 pcibus[ind].pb_rsts= pcibr_cb_rsts;
1885 pcibus[ind].pb_wsts= pcibr_cb_wsts;
1886 break;
1887 case PCI_AGPB_VIA:
1888 pcibus[ind].pb_rsts= pcibr_via_rsts;
1889 pcibus[ind].pb_wsts= pcibr_via_wsts;
1890 break;
1891 default:
1892 panic("unknown PCI-PCI bridge type: %d", type);
1893 }
1894
1895 if (machine.apic_enabled)
1896 acpi_map_bridge(pcidev[devind].pd_busnr,
1897 pcidev[devind].pd_dev, sbusn);
1898
1899 if (debug)
1900 {
1901 printf(
1902 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1903 ind, sbusn, __pci_attr_r8(devind, PPB_SUBORDBN));
1904 }
1905 if (sbusn == 0)
1906 {
1907 printf("Secondary bus number not initialized\n");
1908 continue;
1909 }
1910 pcibus[ind].pb_needinit= 0;
1911
1912 probe_bus(ind);
1913
1914 /* Look for PCI bridges */
1915 do_pcibridge(ind);
1916 }
1917 }
1918
1919 /*===========================================================================*
1920 * pci_intel_init *
1921 *===========================================================================*/
1922 static void
pci_intel_init(void)1923 pci_intel_init(void)
1924 {
1925 /* Try to detect a know PCI controller. Read the Vendor ID and
1926 * the Device ID for function 0 of device 0.
1927 * Two times the value 0xffff suggests a system without a (compatible)
1928 * PCI controller.
1929 */
1930 u32_t bus, dev, func;
1931 u16_t vid, did;
1932 int s, i, r, busind, busnr;
1933 const char *dstr;
1934
1935 bus= 0;
1936 dev= 0;
1937 func= 0;
1938
1939 vid= PCII_RREG16_(bus, dev, func, PCI_VID);
1940 did= PCII_RREG16_(bus, dev, func, PCI_DID);
1941 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
1942 printf("PCI: warning, sys_outl failed: %d\n", s);
1943
1944 if (nr_pcibus >= NR_PCIBUS)
1945 panic("too many PCI busses: %d", nr_pcibus);
1946 busind= nr_pcibus;
1947 nr_pcibus++;
1948 pcibus[busind].pb_type= PBT_INTEL_HOST;
1949 pcibus[busind].pb_needinit= 0;
1950 pcibus[busind].pb_isabridge_dev= -1;
1951 pcibus[busind].pb_isabridge_type= 0;
1952 pcibus[busind].pb_devind= -1;
1953 pcibus[busind].pb_busnr= 0;
1954 pcibus[busind].pb_rreg8= pcii_rreg8;
1955 pcibus[busind].pb_rreg16= pcii_rreg16;
1956 pcibus[busind].pb_rreg32= pcii_rreg32;
1957 pcibus[busind].pb_wreg8= pcii_wreg8;
1958 pcibus[busind].pb_wreg16= pcii_wreg16;
1959 pcibus[busind].pb_wreg32= pcii_wreg32;
1960 pcibus[busind].pb_rsts= pcii_rsts;
1961 pcibus[busind].pb_wsts= pcii_wsts;
1962
1963 dstr= _pci_dev_name(vid, did);
1964 if (!dstr)
1965 dstr= "unknown device";
1966 if (debug)
1967 {
1968 printf("pci_intel_init: %s (%04X:%04X)\n",
1969 dstr, vid, did);
1970 }
1971
1972 probe_bus(busind);
1973
1974 r= do_isabridge(busind);
1975 if (r != OK)
1976 {
1977 busnr= pcibus[busind].pb_busnr;
1978
1979 /* Disable all devices for this bus */
1980 for (i= 0; i<nr_pcidev; i++)
1981 {
1982 if (pcidev[i].pd_busnr != busnr)
1983 continue;
1984 pcidev[i].pd_inuse= 1;
1985 }
1986 return;
1987 }
1988
1989 /* Look for PCI bridges */
1990 do_pcibridge(busind);
1991
1992 /* Allocate bus numbers for uninitialized bridges */
1993 complete_bridges();
1994
1995 /* Allocate I/O and memory resources for uninitialized devices */
1996 complete_bars();
1997 }
1998
1999 #if 0
2000 /*===========================================================================*
2001 * report_vga *
2002 *===========================================================================*/
2003 static void
2004 report_vga(int devind)
2005 {
2006 /* Report the amount of video memory. This is needed by the X11R6
2007 * postinstall script to chmem the X server. Hopefully this can be
2008 * removed when we get virtual memory.
2009 */
2010 size_t amount, size;
2011 int i;
2012
2013 amount= 0;
2014 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
2015 {
2016 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
2017 continue;
2018 size= pcidev[devind].pd_bar[i].pb_size;
2019 if (size < amount)
2020 continue;
2021 amount= size;
2022 }
2023 if (size != 0)
2024 {
2025 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
2026 pcidev[devind].pd_busnr,
2027 pcidev[devind].pd_dev,
2028 pcidev[devind].pd_func,
2029 amount);
2030 }
2031 }
2032 #endif
2033
2034
2035 /*===========================================================================*
2036 * visible *
2037 *===========================================================================*/
2038 static int
visible(struct rs_pci * aclp,int devind)2039 visible(struct rs_pci *aclp, int devind)
2040 {
2041 u16_t acl_sub_vid, acl_sub_did;
2042 int i;
2043 u32_t class_id;
2044
2045 if (!aclp)
2046 return TRUE; /* Should be changed when ACLs become
2047 * mandatory. Do note that procfs relies
2048 * on being able to see all devices.
2049 */
2050 /* Check whether the caller is allowed to get this device. */
2051 for (i= 0; i<aclp->rsp_nr_device; i++)
2052 {
2053 acl_sub_vid = aclp->rsp_device[i].sub_vid;
2054 acl_sub_did = aclp->rsp_device[i].sub_did;
2055 if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
2056 aclp->rsp_device[i].did == pcidev[devind].pd_did &&
2057 (acl_sub_vid == NO_SUB_VID ||
2058 acl_sub_vid == pcidev[devind].pd_sub_vid) &&
2059 (acl_sub_did == NO_SUB_DID ||
2060 acl_sub_did == pcidev[devind].pd_sub_did))
2061 {
2062 return TRUE;
2063 }
2064 }
2065 if (!aclp->rsp_nr_class)
2066 return FALSE;
2067
2068 class_id= (pcidev[devind].pd_baseclass << 16) |
2069 (pcidev[devind].pd_subclass << 8) |
2070 pcidev[devind].pd_infclass;
2071 for (i= 0; i<aclp->rsp_nr_class; i++)
2072 {
2073 if (aclp->rsp_class[i].pciclass ==
2074 (class_id & aclp->rsp_class[i].mask))
2075 {
2076 return TRUE;
2077 }
2078 }
2079
2080 return FALSE;
2081 }
2082
2083 /*===========================================================================*
2084 * sef_cb_init_fresh *
2085 *===========================================================================*/
2086 int
sef_cb_init(int type,sef_init_info_t * info)2087 sef_cb_init(int type, sef_init_info_t *info)
2088 {
2089 /* Initialize the driver. */
2090 int do_announce_driver = -1;
2091
2092 long v;
2093 int i, r;
2094 struct rprocpub rprocpub[NR_BOOT_PROCS];
2095
2096 v= 0;
2097 env_parse("pci_debug", "d", 0, &v, 0, 1);
2098 debug= v;
2099
2100 if (sys_getmachine(&machine)) {
2101 printf("PCI: no machine\n");
2102 return ENODEV;
2103 }
2104 if (machine.apic_enabled &&
2105 acpi_init() != OK) {
2106 panic("PCI: Cannot use APIC mode without ACPI!\n");
2107 }
2108
2109 /* Only Intel (compatible) PCI controllers are supported at the
2110 * moment.
2111 */
2112 pci_intel_init();
2113
2114 /* Map all the services in the boot image. */
2115 if ((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
2116 (vir_bytes) rprocpub, sizeof(rprocpub))) != OK) {
2117 panic("sys_safecopyfrom failed: %d", r);
2118 }
2119 for(i=0;i < NR_BOOT_PROCS;i++) {
2120 if (rprocpub[i].in_use) {
2121 if ((r = map_service(&rprocpub[i])) != OK) {
2122 panic("unable to map service: %d", r);
2123 }
2124 }
2125 }
2126
2127 switch(type) {
2128 case SEF_INIT_FRESH:
2129 case SEF_INIT_RESTART:
2130 do_announce_driver = TRUE;
2131 break;
2132 case SEF_INIT_LU:
2133 do_announce_driver = FALSE;
2134 break;
2135 default:
2136 panic("Unknown type of restart");
2137 break;
2138 }
2139
2140 /* Announce we are up when necessary. */
2141 if (TRUE == do_announce_driver) {
2142 chardriver_announce();
2143 }
2144
2145 /* Initialization completed successfully. */
2146 return OK;
2147 }
2148
2149 /*===========================================================================*
2150 * map_service *
2151 *===========================================================================*/
2152 int
map_service(struct rprocpub * rpub)2153 map_service(struct rprocpub *rpub)
2154 {
2155 /* Map a new service by registering a new acl entry if required. */
2156 int i;
2157
2158 /* Stop right now if no pci device or class is found. */
2159 if(rpub->pci_acl.rsp_nr_device == 0
2160 && rpub->pci_acl.rsp_nr_class == 0) {
2161 return(OK);
2162 }
2163
2164 /* Find a free acl slot. */
2165 for (i= 0; i<NR_DRIVERS; i++)
2166 {
2167 if (!pci_acl[i].inuse)
2168 break;
2169 }
2170 if (i >= NR_DRIVERS)
2171 {
2172 printf("PCI: map_service: table is full\n");
2173 return ENOMEM;
2174 }
2175
2176 /* Initialize acl slot. */
2177 pci_acl[i].inuse = 1;
2178 pci_acl[i].acl = rpub->pci_acl;
2179
2180 return OK;
2181 }
2182
2183 /*===========================================================================*
2184 * _pci_find_dev *
2185 *===========================================================================*/
2186 int
_pci_find_dev(u8_t bus,u8_t dev,u8_t func,int * devindp)2187 _pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp)
2188 {
2189 int devind;
2190
2191 for (devind= 0; devind < nr_pcidev; devind++)
2192 {
2193 if (pcidev[devind].pd_busnr == bus &&
2194 pcidev[devind].pd_dev == dev &&
2195 pcidev[devind].pd_func == func)
2196 {
2197 break;
2198 }
2199 }
2200
2201 if (devind >= nr_pcidev)
2202 return 0;
2203
2204 *devindp= devind;
2205
2206 return 1;
2207 }
2208
2209 /*===========================================================================*
2210 * _pci_first_dev *
2211 *===========================================================================*/
2212 int
_pci_first_dev(struct rs_pci * aclp,int * devindp,u16_t * vidp,u16_t * didp)2213 _pci_first_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp,
2214 u16_t *didp)
2215 {
2216 int devind;
2217
2218 for (devind= 0; devind < nr_pcidev; devind++)
2219 {
2220 if (!visible(aclp, devind))
2221 continue;
2222 break;
2223 }
2224 if (devind >= nr_pcidev)
2225 return 0;
2226 *devindp= devind;
2227 *vidp= pcidev[devind].pd_vid;
2228 *didp= pcidev[devind].pd_did;
2229 return 1;
2230 }
2231
2232 /*===========================================================================*
2233 * _pci_next_dev *
2234 *===========================================================================*/
2235 int
_pci_next_dev(struct rs_pci * aclp,int * devindp,u16_t * vidp,u16_t * didp)2236 _pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp)
2237 {
2238 int devind;
2239
2240 for (devind= *devindp+1; devind < nr_pcidev; devind++)
2241 {
2242 if (!visible(aclp, devind))
2243 continue;
2244 break;
2245 }
2246 if (devind >= nr_pcidev)
2247 return 0;
2248 *devindp= devind;
2249 *vidp= pcidev[devind].pd_vid;
2250 *didp= pcidev[devind].pd_did;
2251 return 1;
2252 }
2253
2254 /*===========================================================================*
2255 * _pci_grant_access *
2256 *===========================================================================*/
2257 int
_pci_grant_access(int devind,endpoint_t proc)2258 _pci_grant_access(int devind, endpoint_t proc)
2259 {
2260 int i, ilr;
2261 int r = OK;
2262 struct io_range ior;
2263 struct minix_mem_range mr;
2264
2265 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
2266 {
2267 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
2268 {
2269 printf("pci_reserve_a: BAR %d is incomplete\n", i);
2270 continue;
2271 }
2272 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
2273 {
2274 ior.ior_base= pcidev[devind].pd_bar[i].pb_base;
2275 ior.ior_limit= ior.ior_base +
2276 pcidev[devind].pd_bar[i].pb_size-1;
2277
2278 if(debug) {
2279 printf(
2280 "pci_reserve_a: for proc %d, adding I/O range [0x%x..0x%x]\n",
2281 proc, ior.ior_base, ior.ior_limit);
2282 }
2283 r= sys_privctl(proc, SYS_PRIV_ADD_IO, &ior);
2284 if (r != OK)
2285 {
2286 printf("sys_privctl failed for proc %d: %d\n",
2287 proc, r);
2288 }
2289 }
2290 else
2291 {
2292 mr.mr_base= pcidev[devind].pd_bar[i].pb_base;
2293 mr.mr_limit= mr.mr_base +
2294 pcidev[devind].pd_bar[i].pb_size-1;
2295
2296 r= sys_privctl(proc, SYS_PRIV_ADD_MEM, &mr);
2297 if (r != OK)
2298 {
2299 printf("sys_privctl failed for proc %d: %d\n",
2300 proc, r);
2301 }
2302 }
2303 }
2304 ilr= pcidev[devind].pd_ilr;
2305 if (ilr != PCI_ILR_UNKNOWN)
2306 {
2307 if(debug) printf("pci_reserve_a: adding IRQ %d\n", ilr);
2308 r= sys_privctl(proc, SYS_PRIV_ADD_IRQ, &ilr);
2309 if (r != OK)
2310 {
2311 printf("sys_privctl failed for proc %d: %d\n",
2312 proc, r);
2313 }
2314 }
2315
2316 return r;
2317 }
2318
2319 /*===========================================================================*
2320 * _pci_reserve *
2321 *===========================================================================*/
2322 int
_pci_reserve(int devind,endpoint_t proc,struct rs_pci * aclp)2323 _pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
2324 {
2325 if (devind < 0 || devind >= nr_pcidev)
2326 {
2327 printf("pci_reserve_a: bad devind: %d\n", devind);
2328 return EINVAL;
2329 }
2330 if (!visible(aclp, devind))
2331 {
2332 printf("pci_reserve_a: %u is not allowed to reserve %d\n",
2333 proc, devind);
2334 return EPERM;
2335 }
2336
2337 if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
2338 return EBUSY;
2339
2340 pcidev[devind].pd_inuse= 1;
2341 pcidev[devind].pd_proc= proc;
2342
2343 return _pci_grant_access(devind, proc);
2344 }
2345
2346 /*===========================================================================*
2347 * _pci_release *
2348 *===========================================================================*/
2349 void
_pci_release(endpoint_t proc)2350 _pci_release(endpoint_t proc)
2351 {
2352 int i;
2353
2354 for (i= 0; i<nr_pcidev; i++)
2355 {
2356 if (!pcidev[i].pd_inuse)
2357 continue;
2358 if (pcidev[i].pd_proc != proc)
2359 continue;
2360 pcidev[i].pd_inuse= 0;
2361 }
2362 }
2363
2364 /*===========================================================================*
2365 * _pci_ids *
2366 *===========================================================================*/
2367 int
_pci_ids(int devind,u16_t * vidp,u16_t * didp)2368 _pci_ids(int devind, u16_t *vidp, u16_t *didp)
2369 {
2370 if (devind < 0 || devind >= nr_pcidev)
2371 return EINVAL;
2372
2373 *vidp= pcidev[devind].pd_vid;
2374 *didp= pcidev[devind].pd_did;
2375 return OK;
2376 }
2377
2378 /*===========================================================================*
2379 * _pci_rescan_bus *
2380 *===========================================================================*/
2381 void
_pci_rescan_bus(u8_t busnr)2382 _pci_rescan_bus(u8_t busnr)
2383 {
2384 int busind;
2385
2386 busind= get_busind(busnr);
2387 probe_bus(busind);
2388
2389 /* Allocate bus numbers for uninitialized bridges */
2390 complete_bridges();
2391
2392 /* Allocate I/O and memory resources for uninitialized devices */
2393 complete_bars();
2394 }
2395
2396 /*===========================================================================*
2397 * _pci_slot_name *
2398 *===========================================================================*/
2399 int
_pci_slot_name(int devind,char ** cpp)2400 _pci_slot_name(int devind, char **cpp)
2401 {
2402 static char label[]= "ddd.ddd.ddd.ddd";
2403 char *end;
2404 char *p;
2405
2406 if (devind < 0 || devind >= nr_pcidev)
2407 return EINVAL;
2408
2409 p= label;
2410 end= label+sizeof(label);
2411
2412 /* FIXME: domain nb is always 0 on 32bit system, but we should
2413 * retrieve it properly, somehow. */
2414 ntostr(0, &p, end);
2415 *p++= '.';
2416
2417 ntostr(pcidev[devind].pd_busnr, &p, end);
2418 *p++= '.';
2419
2420 ntostr(pcidev[devind].pd_dev, &p, end);
2421 *p++= '.';
2422
2423 ntostr(pcidev[devind].pd_func, &p, end);
2424
2425 *cpp= label;
2426 return OK;
2427 }
2428
2429 /*===========================================================================*
2430 * _pci_dev_name *
2431 *===========================================================================*/
2432 const char *
_pci_dev_name(u16_t vid,u16_t did)2433 _pci_dev_name(u16_t vid, u16_t did)
2434 {
2435 static char product[PCI_PRODUCTSTR_LEN];
2436 pci_findproduct(product, sizeof(product), vid, did);
2437 return product;
2438 }
2439
2440 /*===========================================================================*
2441 * _pci_get_bar *
2442 *===========================================================================*/
2443 int
_pci_get_bar(int devind,int port,u32_t * base,u32_t * size,int * ioflag)2444 _pci_get_bar(int devind, int port, u32_t *base, u32_t *size,
2445 int *ioflag)
2446 {
2447 int i, reg;
2448
2449 if (devind < 0 || devind >= nr_pcidev)
2450 return EINVAL;
2451
2452 for (i= 0; i < pcidev[devind].pd_bar_nr; i++)
2453 {
2454 reg= PCI_BAR+4*pcidev[devind].pd_bar[i].pb_nr;
2455
2456 if (reg == port)
2457 {
2458 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
2459 return EINVAL;
2460
2461 *base= pcidev[devind].pd_bar[i].pb_base;
2462 *size= pcidev[devind].pd_bar[i].pb_size;
2463 *ioflag=
2464 !!(pcidev[devind].pd_bar[i].pb_flags & PBF_IO);
2465 return OK;
2466 }
2467 }
2468 return EINVAL;
2469 }
2470
2471 /*===========================================================================*
2472 * _pci_attr_r8 *
2473 *===========================================================================*/
2474 int
_pci_attr_r8(int devind,int port,u8_t * vp)2475 _pci_attr_r8(int devind, int port, u8_t *vp)
2476 {
2477 if (devind < 0 || devind >= nr_pcidev)
2478 return EINVAL;
2479 if (port < 0 || port > 256-1)
2480 return EINVAL;
2481
2482 *vp= __pci_attr_r8(devind, port);
2483 return OK;
2484 }
2485
2486 /*===========================================================================*
2487 * _pci_attr_r16 *
2488 *===========================================================================*/
2489 int
_pci_attr_r16(int devind,int port,u16_t * vp)2490 _pci_attr_r16(int devind, int port, u16_t *vp)
2491 {
2492 if (devind < 0 || devind >= nr_pcidev)
2493 return EINVAL;
2494 if (port < 0 || port > 256-2)
2495 return EINVAL;
2496
2497 *vp= __pci_attr_r16(devind, port);
2498 return OK;
2499 }
2500
2501 /*===========================================================================*
2502 * _pci_attr_r32 *
2503 *===========================================================================*/
2504 int
_pci_attr_r32(int devind,int port,u32_t * vp)2505 _pci_attr_r32(int devind, int port, u32_t *vp)
2506 {
2507 if (devind < 0 || devind >= nr_pcidev)
2508 return EINVAL;
2509 if (port < 0 || port > 256-4)
2510 return EINVAL;
2511
2512 *vp= __pci_attr_r32(devind, port);
2513 return OK;
2514 }
2515
2516 /*===========================================================================*
2517 * _pci_attr_w8 *
2518 *===========================================================================*/
2519 int
_pci_attr_w8(int devind,int port,u8_t value)2520 _pci_attr_w8(int devind, int port, u8_t value)
2521 {
2522 if (devind < 0 || devind >= nr_pcidev)
2523 return EINVAL;
2524 if (port < 0 || port > 256-1)
2525 return EINVAL;
2526
2527 __pci_attr_w8(devind, port, value);
2528 return OK;
2529 }
2530
2531 /*===========================================================================*
2532 * _pci_attr_w16 *
2533 *===========================================================================*/
2534 int
_pci_attr_w16(int devind,int port,u16_t value)2535 _pci_attr_w16(int devind, int port, u16_t value)
2536 {
2537 if (devind < 0 || devind >= nr_pcidev)
2538 return EINVAL;
2539 if (port < 0 || port > 256-2)
2540 return EINVAL;
2541
2542 __pci_attr_w16(devind, port, value);
2543 return OK;
2544 }
2545
2546 /*===========================================================================*
2547 * _pci_attr_w32 *
2548 *===========================================================================*/
2549 int
_pci_attr_w32(int devind,int port,u32_t value)2550 _pci_attr_w32(int devind, int port, u32_t value)
2551 {
2552 if (devind < 0 || devind >= nr_pcidev)
2553 return EINVAL;
2554 if (port < 0 || port > 256-4)
2555 return EINVAL;
2556
2557 __pci_attr_w32(devind, port, value);
2558 return OK;
2559 }
2560