Remove building with NOCRYPTO option
[minix.git] / minix / drivers / bus / pci / pci.c
blob833e4615622e7409c97d281b5b1a4fc8efee91ae
1 /*
2 pci.c
4 Configure devices on the PCI bus
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>
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>
21 #include <dev/pci/pci_verbose.h>
23 #include <pci.h>
24 #include <stdlib.h>
25 #include <stdio.h>
27 #include "pci.h"
29 #define PCI_VENDORSTR_LEN 64
30 #define PCI_PRODUCTSTR_LEN 64
32 #define irq_mode_pci(irq) ((void)0)
34 #define PBT_INTEL_HOST 1
35 #define PBT_PCIBRIDGE 2
36 #define PBT_CARDBUS 3
38 #define BAM_NR 6 /* Number of base-address registers */
40 struct pci_acl pci_acl[NR_DRIVERS];
42 static struct pcibus
44 int pb_type;
45 int pb_needinit;
46 int pb_isabridge_dev;
47 int pb_isabridge_type;
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;
62 static struct pcidev
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;
76 u8_t pd_inuse;
77 endpoint_t pd_proc;
79 struct bar
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];
89 /* pb_flags */
90 #define PBF_IO 1 /* I/O else memory */
91 #define PBF_INCOMPLETE 2 /* not allocated */
93 static int nr_pcidev= 0;
95 static struct machine machine;
97 /*===========================================================================*
98 * helper functions for I/O *
99 *===========================================================================*/
100 static unsigned
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;
109 static unsigned
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;
118 static unsigned
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;
127 static void
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);
134 static void
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);
141 static void
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);
148 static u8_t
149 pcii_rreg8(int busind, int devind, int port)
151 u8_t v;
152 int s;
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;
168 static u16_t
169 pcii_rreg16(int busind, int devind, int port)
171 u16_t v;
172 int s;
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;
188 static u32_t
189 pcii_rreg32(int busind, int devind, int port)
191 u32_t v;
192 int s;
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;
208 static void
209 pcii_wreg8(int busind, int devind, int port, u8_t value)
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);
225 static void
226 pcii_wreg16(int busind, int devind, int port, u16_t value)
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);
242 static void
243 pcii_wreg32(int busind, int devind, int port, u32_t value)
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);
259 /*===========================================================================*
260 * ntostr *
261 *===========================================================================*/
262 static void
263 ntostr(unsigned int n, char **str, const char *end)
265 char tmpstr[20];
266 int i;
268 if (n == 0)
270 tmpstr[0]= '0';
271 i= 1;
273 else
275 for (i= 0; n; i++)
277 tmpstr[i]= '0' + (n%10);
278 n /= 10;
281 for (; i>0; i--)
283 if (*str == end)
285 break;
287 **str= tmpstr[i-1];
288 (*str)++;
290 if (*str == end)
291 (*str)[-1]= '\0';
292 else
293 **str= '\0';
296 /*===========================================================================*
297 * get_busind *
298 *===========================================================================*/
299 static int
300 get_busind(int busnr)
302 int i;
304 for (i= 0; i<nr_pcibus; i++)
306 if (pcibus[i].pb_busnr == busnr)
307 return i;
309 panic("get_busind: can't find bus: %d", busnr);
312 /*===========================================================================*
313 * Unprotected helper functions *
314 *===========================================================================*/
315 static u8_t
316 __pci_attr_r8(int devind, int port)
318 int busnr, busind;
320 busnr= pcidev[devind].pd_busnr;
321 busind= get_busind(busnr);
322 return pcibus[busind].pb_rreg8(busind, devind, port);
325 static u16_t
326 __pci_attr_r16(int devind, int port)
328 int busnr, busind;
330 busnr= pcidev[devind].pd_busnr;
331 busind= get_busind(busnr);
332 return pcibus[busind].pb_rreg16(busind, devind, port);
335 static u32_t
336 __pci_attr_r32(int devind, int port)
338 int busnr, busind;
340 busnr= pcidev[devind].pd_busnr;
341 busind= get_busind(busnr);
342 return pcibus[busind].pb_rreg32(busind, devind, port);
345 static void
346 __pci_attr_w8(int devind, int port, u8_t value)
348 int busnr, busind;
350 busnr= pcidev[devind].pd_busnr;
351 busind= get_busind(busnr);
352 pcibus[busind].pb_wreg8(busind, devind, port, value);
355 static void
356 __pci_attr_w16(int devind, int port, u16_t value)
358 int busnr, busind;
360 busnr= pcidev[devind].pd_busnr;
361 busind= get_busind(busnr);
362 pcibus[busind].pb_wreg16(busind, devind, port, value);
365 static void
366 __pci_attr_w32(int devind, int port, u32_t value)
368 int busnr, busind;
370 busnr= pcidev[devind].pd_busnr;
371 busind= get_busind(busnr);
372 pcibus[busind].pb_wreg32(busind, devind, port, value);
375 /*===========================================================================*
376 * helpers *
377 *===========================================================================*/
378 static u16_t
379 pci_attr_rsts(int devind)
381 int busnr, busind;
383 busnr= pcidev[devind].pd_busnr;
384 busind= get_busind(busnr);
385 return pcibus[busind].pb_rsts(busind);
388 static void
389 pci_attr_wsts(int devind, u16_t value)
391 int busnr, busind;
393 busnr= pcidev[devind].pd_busnr;
394 busind= get_busind(busnr);
395 pcibus[busind].pb_wsts(busind, value);
398 static u16_t
399 pcii_rsts(int busind)
401 u16_t v;
402 int s;
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;
410 static void
411 pcii_wsts(int busind, u16_t value)
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);
419 static int
420 is_duplicate(u8_t busnr, u8_t dev, u8_t func)
422 int i;
424 for (i= 0; i<nr_pcidev; i++)
426 if (pcidev[i].pd_busnr == busnr &&
427 pcidev[i].pd_dev == dev &&
428 pcidev[i].pd_func == func)
430 return 1;
433 return 0;
436 static int
437 get_freebus(void)
439 int i, freebus;
441 freebus= 1;
442 for (i= 0; i<nr_pcibus; i++)
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");
452 return freebus;
455 static const char *
456 pci_vid_name(u16_t vid)
458 static char vendor[PCI_VENDORSTR_LEN];
459 pci_findvendor(vendor, sizeof(vendor), vid);
461 return vendor;
465 static void
466 print_hyper_cap(int devind, u8_t capptr)
468 u32_t v;
469 u16_t cmd;
470 int type0, type1;
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)
479 printf(" WarmReset");
480 v &= ~0x10000;
482 if (v & 0x20000)
484 printf(" DblEnded");
485 v &= ~0x20000;
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)
494 printf("Capability Type: %s\n",
495 type0 == 0 ? "Slave or Primary Interface" :
496 "Host or Secondary Interface");
497 cmd &= ~0xE000;
499 else
501 printf(" Capability Type 0x%x", type1);
502 cmd &= ~0xF800;
504 if (cmd)
505 printf(" undecoded 0x%x\n", cmd);
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
530 static void
531 print_capabilities(int devind)
533 u8_t status, capptr, type, next, subtype;
534 const char *str;
536 /* Check capabilities bit in the device status register */
537 status= __pci_attr_r16(devind, PCI_SR);
538 if (!(status & PSR_CAPPTR))
539 return;
541 capptr= (__pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK);
542 while (capptr != 0)
544 type = __pci_attr_r8(devind, capptr+CAP_TYPE);
545 next= (__pci_attr_r8(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
546 switch(type)
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;
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)
565 subtype= (__pci_attr_r8(devind, capptr+2) & 0x07);
566 switch(subtype)
568 case 0: str= "Device Exclusion Vector"; break;
569 case 3: str= "IOMMU"; break;
570 default: str= "(unknown type)"; break;
572 printf(", sub type 0%o: %s", subtype, str);
574 printf("\n");
575 capptr= next;
579 /*===========================================================================*
580 * ISA Bridge Helpers *
581 *===========================================================================*/
582 static void
583 update_bridge4dev_io(int devind, u32_t io_base, u32_t io_size)
585 int busnr, busind, type, br_devind;
586 u16_t v16;
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)
595 printf(
596 "update_bridge4dev_io: not implemented for PCI bridges\n");
597 return;
599 if (type != PBT_CARDBUS)
600 panic("update_bridge4dev_io: strange bus type: %d", type);
602 if (debug)
604 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
605 io_size, io_base);
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);
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);
616 static int
617 do_piix(int devind)
619 int i, s, irqrc, irq;
620 u32_t elcr1, elcr2, elcr;
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++)
632 irqrc= __pci_attr_r8(devind, PIIX_PIRQRCA+i);
633 if (irqrc & PIIX_IRQ_DI)
635 if (debug)
636 printf("INT%c: disabled\n", 'A'+i);
638 else
640 irq= irqrc & PIIX_IRQ_MASK;
641 if (debug)
642 printf("INT%c: %d\n", 'A'+i, irq);
643 if (!(elcr & (1 << irq)))
645 if (debug)
647 printf(
648 "(warning) IRQ %d is not level triggered\n",
649 irq);
652 irq_mode_pci(irq);
655 return 0;
658 static int
659 do_amd_isabr(int devind)
661 int i, busnr, dev, func, xdevind, irq, edge;
662 u8_t levmask;
663 u16_t pciirq;
665 /* Find required function */
666 func= AMD_ISABR_FUNC;
667 busnr= pcidev[devind].pd_busnr;
668 dev= pcidev[devind].pd_dev;
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++;
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++)
684 edge= (levmask >> i) & 1;
685 irq= (pciirq >> (4*i)) & 0xf;
686 if (!irq)
688 if (debug)
689 printf("INT%c: disabled\n", 'A'+i);
691 else
693 if (debug)
694 printf("INT%c: %d\n", 'A'+i, irq);
695 if (edge && debug)
697 printf(
698 "(warning) IRQ %d is not level triggered\n",
699 irq);
701 irq_mode_pci(irq);
704 nr_pcidev--;
705 return 0;
708 static int
709 do_sis_isabr(int devind)
711 int i, irq;
713 irq= 0; /* lint */
714 for (i= 0; i<4; i++)
716 irq= __pci_attr_r8(devind, SIS_ISABR_IRQ_A+i);
717 if (irq & SIS_IRQ_DISABLED)
719 if (debug)
720 printf("INT%c: disabled\n", 'A'+i);
722 else
724 irq &= SIS_IRQ_MASK;
725 if (debug)
726 printf("INT%c: %d\n", 'A'+i, irq);
727 irq_mode_pci(irq);
730 return 0;
733 static int
734 do_via_isabr(int devind)
736 int i, irq, edge;
737 u8_t levmask;
739 levmask= __pci_attr_r8(devind, VIA_ISABR_EL);
740 irq= 0; /* lint */
741 edge= 0; /* lint */
742 for (i= 0; i<4; i++)
744 switch(i)
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");
765 irq &= 0xf;
766 if (!irq)
768 if (debug)
769 printf("INT%c: disabled\n", 'A'+i);
771 else
773 if (debug)
774 printf("INT%c: %d\n", 'A'+i, irq);
775 if (edge && debug)
777 printf(
778 "(warning) IRQ %d is not level triggered\n",
779 irq);
781 irq_mode_pci(irq);
784 return 0;
787 static int
788 do_isabridge(int busind)
790 int i, j, r, type, busnr, unknown_bridge, bridge_dev;
791 u16_t vid, did;
792 u32_t t3;
793 const char *dstr;
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++)
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)
808 /* ISA bridge. Report if no supported bridge is
809 * found.
811 unknown_bridge= i;
814 vid= pcidev[i].pd_vid;
815 did= pcidev[i].pd_did;
816 for (j= 0; pci_isabridge[j].vid != 0; j++)
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)
825 /* This part of multifunction device is
826 * not the bridge.
828 continue;
830 break;
832 if (pci_isabridge[j].vid)
834 bridge_dev= i;
835 break;
839 if (bridge_dev != -1)
841 dstr= _pci_dev_name(vid, did);
842 if (!dstr)
843 dstr= "unknown device";
844 if (debug)
846 printf("found ISA bridge (%04X:%04X) %s\n",
847 vid, did, dstr);
849 pcibus[busind].pb_isabridge_dev= bridge_dev;
850 type= pci_isabridge[j].type;
851 pcibus[busind].pb_isabridge_type= type;
852 switch(type)
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);
869 return r;
872 if (unknown_bridge == -1)
874 if (debug)
876 printf("(warning) no ISA bridge found on bus %d\n",
877 busind);
879 return 0;
881 if (debug)
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);
888 return 0;
891 static int
892 derive_irq(struct pcidev * dev, int pin)
894 struct pcidev * parent_bridge;
895 int slot;
897 parent_bridge = &pcidev[pcibus[get_busind(dev->pd_busnr)].pb_devind];
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
903 slot = ((dev->pd_func) >> 3) & 0x1f;
905 return acpi_get_irq(parent_bridge->pd_busnr,
906 parent_bridge->pd_dev, (pin + slot) % 4);
909 static void
910 record_irq(int devind)
912 int ilr, ipr, busnr, busind, cb_devind;
914 ilr= __pci_attr_r8(devind, PCI_ILR);
915 ipr= __pci_attr_r8(devind, PCI_IPR);
917 if (ipr && machine.apic_enabled) {
918 int irq;
920 irq = acpi_get_irq(pcidev[devind].pd_busnr,
921 pcidev[devind].pd_dev, ipr - 1);
923 if (irq < 0)
924 irq = derive_irq(&pcidev[devind], ipr - 1);
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);
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);
948 if (ilr == 0)
950 static int first= 1;
951 if (ipr && first && debug)
953 first= 0;
954 printf("PCI: strange, BIOS assigned IRQ0\n");
956 ilr= PCI_ILR_UNKNOWN;
958 pcidev[devind].pd_ilr= ilr;
959 if (ilr == PCI_ILR_UNKNOWN && !ipr)
962 else if (ilr != PCI_ILR_UNKNOWN && ipr)
964 if (debug)
965 printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
967 else if (ilr != PCI_ILR_UNKNOWN)
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);
974 else
976 /* Check for cardbus devices */
977 busnr= pcidev[devind].pd_busnr;
978 busind= get_busind(busnr);
979 if (pcibus[busind].pb_type == PBT_CARDBUS)
981 cb_devind= pcibus[busind].pb_devind;
982 ilr= pcidev[cb_devind].pd_ilr;
983 if (ilr != PCI_ILR_UNKNOWN)
985 if (debug)
987 printf(
988 "assigning IRQ %d to Cardbus device\n",
989 ilr);
991 __pci_attr_w8(devind, PCI_ILR, ilr);
992 pcidev[devind].pd_ilr= ilr;
993 return;
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);
1005 /*===========================================================================*
1006 * BAR helpers *
1007 *===========================================================================*/
1008 static int
1009 record_bar(int devind, int bar_nr, int last)
1011 int reg, prefetch, type, dev_bar_nr, width;
1012 u32_t bar, bar2;
1013 u16_t cmd;
1015 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
1016 width = 1;
1018 reg= PCI_BAR+4*bar_nr;
1020 bar= __pci_attr_r32(devind, reg);
1021 if (bar & PCI_BAR_IO)
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);
1027 /* Probe BAR's size */
1028 __pci_attr_w32(devind, reg, 0xffffffff);
1029 bar2= __pci_attr_r32(devind, reg);
1031 /* Restore original state */
1032 __pci_attr_w32(devind, reg, bar);
1033 __pci_attr_w16(devind, PCI_CR, cmd);
1035 bar &= PCI_BAR_IO_MASK; /* Clear non-address bits */
1036 bar2 &= PCI_BAR_IO_MASK;
1037 bar2= (~bar2 & 0xffff)+1;
1038 if (debug)
1040 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1041 bar_nr, bar2, bar);
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)
1051 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1052 PBF_INCOMPLETE;
1055 else
1057 type= (bar & PCI_BAR_TYPE);
1059 switch(type) {
1060 case PCI_TYPE_32:
1061 case PCI_TYPE_32_1M:
1062 break;
1064 case PCI_TYPE_64:
1065 /* A 64-bit BAR takes up two consecutive DWORDs. */
1066 if (last)
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);
1074 return width;
1076 width++;
1078 bar2= __pci_attr_r32(devind, reg+4);
1080 /* If the upper 32 bits of the BAR are not zero, the
1081 * memory is inaccessible to us; ignore the BAR.
1083 if (bar2 != 0)
1085 if (debug)
1087 printf("\tbar_%d: (64-bit BAR with"
1088 " high bits set)\n", bar_nr);
1091 return width;
1094 break;
1096 default:
1097 /* Ignore the BAR. */
1098 if (debug)
1100 printf("\tbar_%d: (unknown type %x)\n",
1101 bar_nr, type);
1104 return width;
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);
1111 /* Probe BAR's size */
1112 __pci_attr_w32(devind, reg, 0xffffffff);
1113 bar2= __pci_attr_r32(devind, reg);
1115 /* Restore original values */
1116 __pci_attr_w32(devind, reg, bar);
1117 __pci_attr_w16(devind, PCI_CR, cmd);
1119 if (bar2 == 0)
1120 return width; /* Reg. is not implemented */
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)
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" : "");
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)
1141 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1142 PBF_INCOMPLETE;
1146 return width;
1149 static void
1150 record_bars(int devind, int last_reg)
1152 int i, reg, width;
1154 for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width)
1156 width = record_bar(devind, i, reg == last_reg);
1160 static void
1161 record_bars_normal(int devind)
1163 int i, j, clear_01, clear_23, pb_nr;
1165 /* The BAR area of normal devices is six DWORDs in size. */
1166 record_bars(devind, PCI_BAR_6);
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)
1172 /* IDE device */
1173 clear_01= 0;
1174 clear_23= 0;
1175 if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
1177 if (debug)
1179 printf(
1180 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1182 clear_01= 1;
1184 if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
1186 if (debug)
1188 printf(
1189 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
1191 clear_23= 1;
1194 j= 0;
1195 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
1197 pb_nr= pcidev[devind].pd_bar[i].pb_nr;
1198 if ((pb_nr == 0 || pb_nr == 1) && clear_01)
1200 if (debug) printf("skipping bar %d\n", pb_nr);
1201 continue; /* Skip */
1203 if ((pb_nr == 2 || pb_nr == 3) && clear_23)
1205 if (debug) printf("skipping bar %d\n", pb_nr);
1206 continue; /* Skip */
1208 if (i == j)
1210 j++;
1211 continue; /* No need to copy */
1213 pcidev[devind].pd_bar[j]=
1214 pcidev[devind].pd_bar[i];
1215 j++;
1217 pcidev[devind].pd_bar_nr= j;
1221 static void
1222 record_bars_bridge(int devind)
1224 u32_t base, limit, size;
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.
1229 record_bars(devind, PCI_BAR_2);
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)
1240 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1241 base, limit, size);
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)
1251 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1252 base, limit, size);
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)
1264 printf(
1265 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1266 base, limit, size);
1270 static void
1271 record_bars_cardbus(int devind)
1273 u32_t base, limit, size;
1275 /* The generic BAR area of CardBus devices is one DWORD in size. */
1276 record_bars(devind, PCI_BAR);
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)
1284 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1285 base, limit, size);
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)
1294 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1295 base, limit, size);
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)
1304 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1305 base, limit, size);
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)
1314 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1315 base, limit, size);
1319 static void
1320 complete_bars(void)
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;
1327 if(OK != sys_getkinfo(&kinfo))
1328 panic("can't get kinfo");
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) */
1334 if (debug)
1336 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1337 memgap_low, memgap_high);
1340 /* Find the lowest memory base */
1341 for (i= 0; i<nr_pcidev; i++)
1343 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
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;
1352 if (base >= memgap_high)
1353 continue; /* Not in the gap */
1354 if (base+size <= memgap_low)
1355 continue; /* Not in the gap */
1357 /* Reduce the gap by the smallest amount */
1358 diff1= base+size-memgap_low;
1359 diff2= memgap_high-base;
1361 if (diff1 < diff2)
1362 memgap_low= base+size;
1363 else
1364 memgap_high= base;
1368 if (debug)
1370 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1371 memgap_low, memgap_high);
1374 /* Should check main memory size */
1375 if (memgap_high < memgap_low)
1377 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1378 memgap_low, memgap_high);
1379 panic(NULL);
1382 iogap_high= 0x10000;
1383 iogap_low= 0x400;
1385 /* Find the free I/O space */
1386 for (i= 0; i<nr_pcidev; i++)
1388 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
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)
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);
1408 #endif
1409 if (base+size-iogap_low < iogap_high-base)
1410 iogap_low= base+size;
1411 else
1412 iogap_high= base;
1416 if (iogap_high < iogap_low)
1418 if (debug)
1420 printf("iogap_high too low, should panic\n");
1422 else
1423 panic("iogap_high too low: %d", iogap_high);
1425 if (debug)
1426 printf("I/O range = [0x%x..0x%x>\n", iogap_low, iogap_high);
1428 for (i= 0; i<nr_pcidev; i++)
1430 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
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)
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);
1456 pcidev[i].pd_bar[j].pb_base= base;
1457 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1460 io_high= iogap_high;
1461 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
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);
1471 /* Assume that ISA compatibility is required. Only
1472 * use the lowest 256 bytes out of every 1024 bytes.
1474 base &= 0xfcff;
1476 if (base < iogap_low)
1477 printf("I/O base too low: %d", base);
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)
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);
1492 pcidev[i].pd_bar[j].pb_base= base;
1493 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1496 if (iogap_high != io_high)
1498 update_bridge4dev_io(i, iogap_high,
1499 io_high-iogap_high);
1503 for (i= 0; i<nr_pcidev; i++)
1505 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1507 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1508 continue;
1509 printf("should allocate resources for device %d\n", i);
1512 return;
1515 /*===========================================================================*
1516 * PCI Bridge Helpers *
1517 *===========================================================================*/
1518 static void
1519 probe_bus(int busind)
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;
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;
1537 busnr= pcibus[busind].pb_busnr;
1538 for (dev= 0; dev<32; dev++)
1541 for (func= 0; func < 8; func++)
1543 pcidev[devind].pd_busnr= busnr;
1544 pcidev[devind].pd_dev= dev;
1545 pcidev[devind].pd_func= func;
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);
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
1559 if (vid == NO_VID && did == NO_VID)
1561 if (func == 0)
1562 break; /* Nothing here */
1564 /* Scan all functions of a multifunction
1565 * device.
1567 continue;
1570 if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
1572 static int warned = 0;
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;
1582 sub_vid= __pci_attr_r16(devind, PCI_SUBVID);
1583 sub_did= __pci_attr_r16(devind, PCI_SUBDID);
1585 dstr= _pci_dev_name(vid, did);
1586 if (debug)
1588 if (dstr)
1590 printf("%d.%lu.%lu: %s (%04X:%04X)\n",
1591 busnr, (unsigned long)dev,
1592 (unsigned long)func, dstr,
1593 vid, did);
1595 else
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);
1603 printf("Device index: %d\n", devind);
1604 printf("Subsystem: Vid 0x%x, did 0x%x\n",
1605 sub_vid, sub_did);
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);
1615 if (!s)
1616 s= "(unknown class)";
1618 if (debug)
1620 printf("\tclass %s (%X/%X/%X)\n", s,
1621 baseclass, subclass, infclass);
1624 if (is_duplicate(busnr, dev, func))
1626 printf("\tduplicate!\n");
1627 if (func == 0 && !(headt & PHT_MULTIFUNC))
1628 break;
1629 continue;
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)
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;
1661 if (debug)
1662 print_capabilities(devind);
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
1670 if (nr_pcidev >= NR_PCIDEV)
1671 panic("too many PCI devices: %d", nr_pcidev);
1672 devind= nr_pcidev;
1674 if (func == 0 && !(headt & PHT_MULTIFUNC))
1675 break;
1681 static u16_t
1682 pcibr_std_rsts(int busind)
1684 int devind;
1686 devind= pcibus[busind].pb_devind;
1687 return __pci_attr_r16(devind, PPB_SSTS);
1690 static void
1691 pcibr_std_wsts(int busind, u16_t value)
1693 int devind;
1694 devind= pcibus[busind].pb_devind;
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);
1703 static u16_t
1704 pcibr_cb_rsts(int busind)
1706 int devind;
1707 devind= pcibus[busind].pb_devind;
1709 return __pci_attr_r16(devind, CBB_SSTS);
1712 static void
1713 pcibr_cb_wsts(int busind, u16_t value)
1715 int devind;
1716 devind= pcibus[busind].pb_devind;
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);
1725 static u16_t
1726 pcibr_via_rsts(int busind)
1728 return 0;
1731 static void
1732 pcibr_via_wsts(int busind, u16_t value)
1734 #if 0
1735 int devind;
1736 devind= pcibus[busind].pb_devind;
1738 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
1739 busind, value, devind);
1740 #endif
1743 static void
1744 complete_bridges(void)
1746 int i, freebus, devind, prim_busnr;
1748 for (i= 0; i<nr_pcibus; i++)
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);
1756 devind= pcibus[i].pb_devind;
1758 prim_busnr= pcidev[devind].pd_busnr;
1759 if (prim_busnr != 0)
1761 printf(
1762 "complete_bridge: updating subordinate bus number not implemented\n");
1765 pcibus[i].pb_needinit= 0;
1766 pcibus[i].pb_busnr= freebus;
1768 printf("devind = %d\n", devind);
1769 printf("prim_busnr= %d\n", prim_busnr);
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);
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));
1782 static void
1783 do_pcibridge(int busind)
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;
1791 vid= did= 0; /* lint */
1792 busnr= pcibus[busind].pb_busnr;
1793 for (devind= 0; devind< nr_pcidev; devind++)
1795 if (pcidev[devind].pd_busnr != busnr)
1797 #if 0
1798 printf("wrong bus\n");
1799 #endif
1800 continue;
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) */
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
1816 #if 0
1817 printf("not a bridge\n");
1818 #endif
1819 continue; /* Not a bridge */
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)
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;
1836 if (type == PCI_PPB_CB &&
1837 t3 != PCI_T3_CARDBUS)
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;
1847 if (debug)
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);
1855 /* Assume that the BIOS initialized the secondary bus
1856 * number.
1858 sbusn= __pci_attr_r8(devind, PPB_SECBN);
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)
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);
1895 if (machine.apic_enabled)
1896 acpi_map_bridge(pcidev[devind].pd_busnr,
1897 pcidev[devind].pd_dev, sbusn);
1899 if (debug)
1901 printf(
1902 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1903 ind, sbusn, __pci_attr_r8(devind, PPB_SUBORDBN));
1905 if (sbusn == 0)
1907 printf("Secondary bus number not initialized\n");
1908 continue;
1910 pcibus[ind].pb_needinit= 0;
1912 probe_bus(ind);
1914 /* Look for PCI bridges */
1915 do_pcibridge(ind);
1919 /*===========================================================================*
1920 * pci_intel_init *
1921 *===========================================================================*/
1922 static void
1923 pci_intel_init(void)
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.
1930 u32_t bus, dev, func;
1931 u16_t vid, did;
1932 int s, i, r, busind, busnr;
1933 const char *dstr;
1935 bus= 0;
1936 dev= 0;
1937 func= 0;
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);
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;
1963 dstr= _pci_dev_name(vid, did);
1964 if (!dstr)
1965 dstr= "unknown device";
1966 if (debug)
1968 printf("pci_intel_init: %s (%04X:%04X)\n",
1969 dstr, vid, did);
1972 probe_bus(busind);
1974 r= do_isabridge(busind);
1975 if (r != OK)
1977 busnr= pcibus[busind].pb_busnr;
1979 /* Disable all devices for this bus */
1980 for (i= 0; i<nr_pcidev; i++)
1982 if (pcidev[i].pd_busnr != busnr)
1983 continue;
1984 pcidev[i].pd_inuse= 1;
1986 return;
1989 /* Look for PCI bridges */
1990 do_pcibridge(busind);
1992 /* Allocate bus numbers for uninitialized bridges */
1993 complete_bridges();
1995 /* Allocate I/O and memory resources for uninitialized devices */
1996 complete_bars();
1999 #if 0
2000 /*===========================================================================*
2001 * report_vga *
2002 *===========================================================================*/
2003 static void
2004 report_vga(int devind)
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.
2010 size_t amount, size;
2011 int i;
2013 amount= 0;
2014 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
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;
2023 if (size != 0)
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);
2032 #endif
2035 /*===========================================================================*
2036 * visible *
2037 *===========================================================================*/
2038 static int
2039 visible(struct rs_pci *aclp, int devind)
2041 u16_t acl_sub_vid, acl_sub_did;
2042 int i;
2043 u32_t class_id;
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.
2050 /* Check whether the caller is allowed to get this device. */
2051 for (i= 0; i<aclp->rsp_nr_device; i++)
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))
2062 return TRUE;
2065 if (!aclp->rsp_nr_class)
2066 return FALSE;
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++)
2073 if (aclp->rsp_class[i].pciclass ==
2074 (class_id & aclp->rsp_class[i].mask))
2076 return TRUE;
2080 return FALSE;
2083 /*===========================================================================*
2084 * sef_cb_init_fresh *
2085 *===========================================================================*/
2087 sef_cb_init(int type, sef_init_info_t *info)
2089 /* Initialize the driver. */
2090 int do_announce_driver = -1;
2092 long v;
2093 int i, r;
2094 struct rprocpub rprocpub[NR_BOOT_PROCS];
2096 v= 0;
2097 env_parse("pci_debug", "d", 0, &v, 0, 1);
2098 debug= v;
2100 if (sys_getmachine(&machine)) {
2101 printf("PCI: no machine\n");
2102 return ENODEV;
2104 if (machine.apic_enabled &&
2105 acpi_init() != OK) {
2106 panic("PCI: Cannot use APIC mode without ACPI!\n");
2109 /* Only Intel (compatible) PCI controllers are supported at the
2110 * moment.
2112 pci_intel_init();
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);
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);
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;
2140 /* Announce we are up when necessary. */
2141 if (TRUE == do_announce_driver) {
2142 chardriver_announce();
2145 /* Initialization completed successfully. */
2146 return OK;
2149 /*===========================================================================*
2150 * map_service *
2151 *===========================================================================*/
2153 map_service(struct rprocpub *rpub)
2155 /* Map a new service by registering a new acl entry if required. */
2156 int i;
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);
2164 /* Find a free acl slot. */
2165 for (i= 0; i<NR_DRIVERS; i++)
2167 if (!pci_acl[i].inuse)
2168 break;
2170 if (i >= NR_DRIVERS)
2172 printf("PCI: map_service: table is full\n");
2173 return ENOMEM;
2176 /* Initialize acl slot. */
2177 pci_acl[i].inuse = 1;
2178 pci_acl[i].acl = rpub->pci_acl;
2180 return OK;
2183 /*===========================================================================*
2184 * _pci_find_dev *
2185 *===========================================================================*/
2187 _pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp)
2189 int devind;
2191 for (devind= 0; devind < nr_pcidev; devind++)
2193 if (pcidev[devind].pd_busnr == bus &&
2194 pcidev[devind].pd_dev == dev &&
2195 pcidev[devind].pd_func == func)
2197 break;
2201 if (devind >= nr_pcidev)
2202 return 0;
2204 *devindp= devind;
2206 return 1;
2209 /*===========================================================================*
2210 * _pci_first_dev *
2211 *===========================================================================*/
2213 _pci_first_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp,
2214 u16_t *didp)
2216 int devind;
2218 for (devind= 0; devind < nr_pcidev; devind++)
2220 if (!visible(aclp, devind))
2221 continue;
2222 break;
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;
2232 /*===========================================================================*
2233 * _pci_next_dev *
2234 *===========================================================================*/
2236 _pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp)
2238 int devind;
2240 for (devind= *devindp+1; devind < nr_pcidev; devind++)
2242 if (!visible(aclp, devind))
2243 continue;
2244 break;
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;
2254 /*===========================================================================*
2255 * _pci_grant_access *
2256 *===========================================================================*/
2258 _pci_grant_access(int devind, endpoint_t proc)
2260 int i, ilr;
2261 int r = OK;
2262 struct io_range ior;
2263 struct minix_mem_range mr;
2265 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
2267 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
2269 printf("pci_reserve_a: BAR %d is incomplete\n", i);
2270 continue;
2272 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
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;
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);
2283 r= sys_privctl(proc, SYS_PRIV_ADD_IO, &ior);
2284 if (r != OK)
2286 printf("sys_privctl failed for proc %d: %d\n",
2287 proc, r);
2290 else
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;
2296 r= sys_privctl(proc, SYS_PRIV_ADD_MEM, &mr);
2297 if (r != OK)
2299 printf("sys_privctl failed for proc %d: %d\n",
2300 proc, r);
2304 ilr= pcidev[devind].pd_ilr;
2305 if (ilr != PCI_ILR_UNKNOWN)
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)
2311 printf("sys_privctl failed for proc %d: %d\n",
2312 proc, r);
2316 return r;
2319 /*===========================================================================*
2320 * _pci_reserve *
2321 *===========================================================================*/
2323 _pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
2325 if (devind < 0 || devind >= nr_pcidev)
2327 printf("pci_reserve_a: bad devind: %d\n", devind);
2328 return EINVAL;
2330 if (!visible(aclp, devind))
2332 printf("pci_reserve_a: %u is not allowed to reserve %d\n",
2333 proc, devind);
2334 return EPERM;
2337 if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
2338 return EBUSY;
2340 pcidev[devind].pd_inuse= 1;
2341 pcidev[devind].pd_proc= proc;
2343 return _pci_grant_access(devind, proc);
2346 /*===========================================================================*
2347 * _pci_release *
2348 *===========================================================================*/
2349 void
2350 _pci_release(endpoint_t proc)
2352 int i;
2354 for (i= 0; i<nr_pcidev; i++)
2356 if (!pcidev[i].pd_inuse)
2357 continue;
2358 if (pcidev[i].pd_proc != proc)
2359 continue;
2360 pcidev[i].pd_inuse= 0;
2364 /*===========================================================================*
2365 * _pci_ids *
2366 *===========================================================================*/
2368 _pci_ids(int devind, u16_t *vidp, u16_t *didp)
2370 if (devind < 0 || devind >= nr_pcidev)
2371 return EINVAL;
2373 *vidp= pcidev[devind].pd_vid;
2374 *didp= pcidev[devind].pd_did;
2375 return OK;
2378 /*===========================================================================*
2379 * _pci_rescan_bus *
2380 *===========================================================================*/
2381 void
2382 _pci_rescan_bus(u8_t busnr)
2384 int busind;
2386 busind= get_busind(busnr);
2387 probe_bus(busind);
2389 /* Allocate bus numbers for uninitialized bridges */
2390 complete_bridges();
2392 /* Allocate I/O and memory resources for uninitialized devices */
2393 complete_bars();
2396 /*===========================================================================*
2397 * _pci_slot_name *
2398 *===========================================================================*/
2400 _pci_slot_name(int devind, char **cpp)
2402 static char label[]= "ddd.ddd.ddd.ddd";
2403 char *end;
2404 char *p;
2406 if (devind < 0 || devind >= nr_pcidev)
2407 return EINVAL;
2409 p= label;
2410 end= label+sizeof(label);
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++= '.';
2417 ntostr(pcidev[devind].pd_busnr, &p, end);
2418 *p++= '.';
2420 ntostr(pcidev[devind].pd_dev, &p, end);
2421 *p++= '.';
2423 ntostr(pcidev[devind].pd_func, &p, end);
2425 *cpp= label;
2426 return OK;
2429 /*===========================================================================*
2430 * _pci_dev_name *
2431 *===========================================================================*/
2432 const char *
2433 _pci_dev_name(u16_t vid, u16_t did)
2435 static char product[PCI_PRODUCTSTR_LEN];
2436 pci_findproduct(product, sizeof(product), vid, did);
2437 return product;
2440 /*===========================================================================*
2441 * _pci_get_bar *
2442 *===========================================================================*/
2444 _pci_get_bar(int devind, int port, u32_t *base, u32_t *size,
2445 int *ioflag)
2447 int i, reg;
2449 if (devind < 0 || devind >= nr_pcidev)
2450 return EINVAL;
2452 for (i= 0; i < pcidev[devind].pd_bar_nr; i++)
2454 reg= PCI_BAR+4*pcidev[devind].pd_bar[i].pb_nr;
2456 if (reg == port)
2458 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
2459 return EINVAL;
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;
2468 return EINVAL;
2471 /*===========================================================================*
2472 * _pci_attr_r8 *
2473 *===========================================================================*/
2475 _pci_attr_r8(int devind, int port, u8_t *vp)
2477 if (devind < 0 || devind >= nr_pcidev)
2478 return EINVAL;
2479 if (port < 0 || port > 256-1)
2480 return EINVAL;
2482 *vp= __pci_attr_r8(devind, port);
2483 return OK;
2486 /*===========================================================================*
2487 * _pci_attr_r16 *
2488 *===========================================================================*/
2490 _pci_attr_r16(int devind, int port, u16_t *vp)
2492 if (devind < 0 || devind >= nr_pcidev)
2493 return EINVAL;
2494 if (port < 0 || port > 256-2)
2495 return EINVAL;
2497 *vp= __pci_attr_r16(devind, port);
2498 return OK;
2501 /*===========================================================================*
2502 * _pci_attr_r32 *
2503 *===========================================================================*/
2505 _pci_attr_r32(int devind, int port, u32_t *vp)
2507 if (devind < 0 || devind >= nr_pcidev)
2508 return EINVAL;
2509 if (port < 0 || port > 256-4)
2510 return EINVAL;
2512 *vp= __pci_attr_r32(devind, port);
2513 return OK;
2516 /*===========================================================================*
2517 * _pci_attr_w8 *
2518 *===========================================================================*/
2520 _pci_attr_w8(int devind, int port, u8_t value)
2522 if (devind < 0 || devind >= nr_pcidev)
2523 return EINVAL;
2524 if (port < 0 || port > 256-1)
2525 return EINVAL;
2527 __pci_attr_w8(devind, port, value);
2528 return OK;
2531 /*===========================================================================*
2532 * _pci_attr_w16 *
2533 *===========================================================================*/
2535 _pci_attr_w16(int devind, int port, u16_t value)
2537 if (devind < 0 || devind >= nr_pcidev)
2538 return EINVAL;
2539 if (port < 0 || port > 256-2)
2540 return EINVAL;
2542 __pci_attr_w16(devind, port, value);
2543 return OK;
2546 /*===========================================================================*
2547 * _pci_attr_w32 *
2548 *===========================================================================*/
2550 _pci_attr_w32(int devind, int port, u32_t value)
2552 if (devind < 0 || devind >= nr_pcidev)
2553 return EINVAL;
2554 if (port < 0 || port > 256-4)
2555 return EINVAL;
2557 __pci_attr_w32(devind, port, value);
2558 return OK;