4 Configure devices on the PCI bus
6 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
8 #include <minix/acpi.h>
9 #include <minix/chardriver.h>
10 #include <minix/driver.h>
11 #include <minix/param.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>
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
38 #define BAM_NR 6 /* Number of base-address registers */
40 struct pci_acl pci_acl
[NR_DRIVERS
];
47 int pb_isabridge_type
;
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
);
60 static int nr_pcibus
= 0;
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 *===========================================================================*/
101 pci_inb(u16_t port
) {
104 if ((s
=sys_inb(port
, &value
)) !=OK
)
105 printf("PCI: warning, sys_inb failed: %d\n", s
);
110 pci_inw(u16_t port
) {
113 if ((s
=sys_inw(port
, &value
)) !=OK
)
114 printf("PCI: warning, sys_inw failed: %d\n", s
);
119 pci_inl(u16_t port
) {
122 if ((s
=sys_inl(port
, &value
)) !=OK
)
123 printf("PCI: warning, sys_inl failed: %d\n", s
);
128 pci_outb(u16_t port
, u8_t value
) {
130 if ((s
=sys_outb(port
, value
)) !=OK
)
131 printf("PCI: warning, sys_outb failed: %d\n", s
);
135 pci_outw(u16_t port
, u16_t value
) {
137 if ((s
=sys_outw(port
, value
)) !=OK
)
138 printf("PCI: warning, sys_outw failed: %d\n", s
);
142 pci_outl(u16_t port
, u32_t value
) {
144 if ((s
=sys_outl(port
, value
)) !=OK
)
145 printf("PCI: warning, sys_outl failed: %d\n", s
);
149 pcii_rreg8(int busind
, int devind
, int port
)
154 v
= PCII_RREG8_(pcibus
[busind
].pb_busnr
,
155 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
157 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
158 printf("PCI: warning, sys_outl failed: %d\n", s
);
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
);
169 pcii_rreg16(int busind
, int devind
, int port
)
174 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
,
175 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
177 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
178 printf("PCI: warning, sys_outl failed: %d\n", s
);
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
);
189 pcii_rreg32(int busind
, int devind
, int port
)
194 v
= PCII_RREG32_(pcibus
[busind
].pb_busnr
,
195 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
197 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
198 printf("PCI: warning, sys_outl failed: %d\n", s
);
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
);
209 pcii_wreg8(int busind
, int devind
, int port
, u8_t value
)
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
);
218 PCII_WREG8_(pcibus
[busind
].pb_busnr
,
219 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
221 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
222 printf("PCI: warning, sys_outl failed: %d\n", s
);
226 pcii_wreg16(int busind
, int devind
, int port
, u16_t value
)
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
);
235 PCII_WREG16_(pcibus
[busind
].pb_busnr
,
236 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
238 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
239 printf("PCI: warning, sys_outl failed: %d\n", s
);
243 pcii_wreg32(int busind
, int devind
, int port
, u32_t value
)
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
);
252 PCII_WREG32_(pcibus
[busind
].pb_busnr
,
253 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
255 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
256 printf("PCI: warning, sys_outl failed: %d\n",s
);
259 /*===========================================================================*
261 *===========================================================================*/
263 ntostr(unsigned int n
, char **str
, const char *end
)
277 tmpstr
[i
]= '0' + (n
%10);
296 /*===========================================================================*
298 *===========================================================================*/
300 get_busind(int busnr
)
304 for (i
= 0; i
<nr_pcibus
; i
++)
306 if (pcibus
[i
].pb_busnr
== busnr
)
309 panic("get_busind: can't find bus: %d", busnr
);
312 /*===========================================================================*
313 * Unprotected helper functions *
314 *===========================================================================*/
316 __pci_attr_r8(int devind
, int port
)
320 busnr
= pcidev
[devind
].pd_busnr
;
321 busind
= get_busind(busnr
);
322 return pcibus
[busind
].pb_rreg8(busind
, devind
, port
);
326 __pci_attr_r16(int devind
, int port
)
330 busnr
= pcidev
[devind
].pd_busnr
;
331 busind
= get_busind(busnr
);
332 return pcibus
[busind
].pb_rreg16(busind
, devind
, port
);
336 __pci_attr_r32(int devind
, int port
)
340 busnr
= pcidev
[devind
].pd_busnr
;
341 busind
= get_busind(busnr
);
342 return pcibus
[busind
].pb_rreg32(busind
, devind
, port
);
346 __pci_attr_w8(int devind
, int port
, u8_t value
)
350 busnr
= pcidev
[devind
].pd_busnr
;
351 busind
= get_busind(busnr
);
352 pcibus
[busind
].pb_wreg8(busind
, devind
, port
, value
);
356 __pci_attr_w16(int devind
, int port
, u16_t value
)
360 busnr
= pcidev
[devind
].pd_busnr
;
361 busind
= get_busind(busnr
);
362 pcibus
[busind
].pb_wreg16(busind
, devind
, port
, value
);
366 __pci_attr_w32(int devind
, int port
, u32_t value
)
370 busnr
= pcidev
[devind
].pd_busnr
;
371 busind
= get_busind(busnr
);
372 pcibus
[busind
].pb_wreg32(busind
, devind
, port
, value
);
375 /*===========================================================================*
377 *===========================================================================*/
379 pci_attr_rsts(int devind
)
383 busnr
= pcidev
[devind
].pd_busnr
;
384 busind
= get_busind(busnr
);
385 return pcibus
[busind
].pb_rsts(busind
);
389 pci_attr_wsts(int devind
, u16_t value
)
393 busnr
= pcidev
[devind
].pd_busnr
;
394 busind
= get_busind(busnr
);
395 pcibus
[busind
].pb_wsts(busind
, value
);
399 pcii_rsts(int busind
)
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
);
411 pcii_wsts(int busind
, u16_t value
)
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
);
420 is_duplicate(u8_t busnr
, u8_t dev
, u8_t func
)
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
)
442 for (i
= 0; i
<nr_pcibus
; i
++)
444 if (pcibus
[i
].pb_needinit
)
446 if (pcibus
[i
].pb_type
== PBT_INTEL_HOST
)
448 if (pcibus
[i
].pb_busnr
<= freebus
)
449 freebus
= pcibus
[i
].pb_busnr
+1;
450 printf("get_freebus: should check suboridinate bus number\n");
456 pci_vid_name(u16_t vid
)
458 static char vendor
[PCI_VENDORSTR_LEN
];
459 pci_findvendor(vendor
, sizeof(vendor
), vid
);
466 print_hyper_cap(int devind
, u8_t capptr
)
473 v
= __pci_attr_r32(devind
, capptr
);
474 printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr
);
475 cmd
= (v
>> 16) & 0xffff;
479 printf(" WarmReset");
487 printf(" DevNum %d", (v
& 0x7C0000) >> 18);
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");
501 printf(" Capability Type 0x%x", type1
);
505 printf(" undecoded 0x%x\n", cmd
);
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): ",
519 printf("prim %d", v
& 0xff);
520 printf(", sec %d", (v
>> 8) & 0xff);
521 printf(", sub %d", (v
>> 16) & 0xff);
523 printf(", reserved %d", (v
>> 24) & 0xff);
525 printf("print_hyper_cap: off 24 (type): 0x%x\n",
526 __pci_attr_r32(devind
, capptr
+24));
531 print_capabilities(int devind
)
533 u8_t status
, capptr
, type
, next
, subtype
;
536 /* Check capabilities bit in the device status register */
537 status
= __pci_attr_r16(devind
, PCI_SR
);
538 if (!(status
& PSR_CAPPTR
))
541 capptr
= (__pci_attr_r8(devind
, PCI_CAPPTR
) & PCI_CP_MASK
);
544 type
= __pci_attr_r8(devind
, capptr
+CAP_TYPE
);
545 next
= (__pci_attr_r8(devind
, capptr
+CAP_NEXT
) & PCI_CP_MASK
);
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
);
562 print_hyper_cap(devind
, capptr
);
563 else if (type
== 0x0f)
565 subtype
= (__pci_attr_r8(devind
, capptr
+2) & 0x07);
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
);
579 /*===========================================================================*
580 * ISA Bridge Helpers *
581 *===========================================================================*/
583 update_bridge4dev_io(int devind
, u32_t io_base
, u32_t io_size
)
585 int busnr
, busind
, type
, br_devind
;
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
)
596 "update_bridge4dev_io: not implemented for PCI bridges\n");
599 if (type
!= PBT_CARDBUS
)
600 panic("update_bridge4dev_io: strange bus type: %d", type
);
604 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
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
);
619 int i
, s
, irqrc
, irq
;
620 u32_t elcr1
, elcr2
, elcr
;
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);
632 irqrc
= __pci_attr_r8(devind
, PIIX_PIRQRCA
+i
);
633 if (irqrc
& PIIX_IRQ_DI
)
636 printf("INT%c: disabled\n", 'A'+i
);
640 irq
= irqrc
& PIIX_IRQ_MASK
;
642 printf("INT%c: %d\n", 'A'+i
, irq
);
643 if (!(elcr
& (1 << irq
)))
648 "(warning) IRQ %d is not level triggered\n",
659 do_amd_isabr(int devind
)
661 int i
, busnr
, dev
, func
, xdevind
, irq
, edge
;
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
);
674 pcidev
[xdevind
].pd_busnr
= busnr
;
675 pcidev
[xdevind
].pd_dev
= dev
;
676 pcidev
[xdevind
].pd_func
= func
;
677 pcidev
[xdevind
].pd_inuse
= 1;
680 levmask
= __pci_attr_r8(xdevind
, AMD_ISABR_PCIIRQ_LEV
);
681 pciirq
= __pci_attr_r16(xdevind
, AMD_ISABR_PCIIRQ_ROUTE
);
684 edge
= (levmask
>> i
) & 1;
685 irq
= (pciirq
>> (4*i
)) & 0xf;
689 printf("INT%c: disabled\n", 'A'+i
);
694 printf("INT%c: %d\n", 'A'+i
, irq
);
698 "(warning) IRQ %d is not level triggered\n",
709 do_sis_isabr(int devind
)
716 irq
= __pci_attr_r8(devind
, SIS_ISABR_IRQ_A
+i
);
717 if (irq
& SIS_IRQ_DISABLED
)
720 printf("INT%c: disabled\n", 'A'+i
);
726 printf("INT%c: %d\n", 'A'+i
, irq
);
734 do_via_isabr(int devind
)
739 levmask
= __pci_attr_r8(devind
, VIA_ISABR_EL
);
747 edge
= (levmask
& VIA_ISABR_EL_INTA
);
748 irq
= __pci_attr_r8(devind
, VIA_ISABR_IRQ_R2
) >> 4;
751 edge
= (levmask
& VIA_ISABR_EL_INTB
);
752 irq
= __pci_attr_r8(devind
, VIA_ISABR_IRQ_R2
);
755 edge
= (levmask
& VIA_ISABR_EL_INTC
);
756 irq
= __pci_attr_r8(devind
, VIA_ISABR_IRQ_R3
) >> 4;
759 edge
= (levmask
& VIA_ISABR_EL_INTD
);
760 irq
= __pci_attr_r8(devind
, VIA_ISABR_IRQ_R1
) >> 4;
763 panic("PCI: VIA ISA Bridge IRQ Detection Failed");
769 printf("INT%c: disabled\n", 'A'+i
);
774 printf("INT%c: %d\n", 'A'+i
, irq
);
778 "(warning) IRQ %d is not level triggered\n",
788 do_isabridge(int busind
)
790 int i
, j
, r
, type
, busnr
, unknown_bridge
, bridge_dev
;
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
)
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
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
)
820 if (pci_isabridge
[j
].did
!= did
)
822 if (pci_isabridge
[j
].checkclass
&&
825 /* This part of multifunction device is
832 if (pci_isabridge
[j
].vid
)
839 if (bridge_dev
!= -1)
841 dstr
= _pci_dev_name(vid
, did
);
843 dstr
= "unknown device";
846 printf("found ISA bridge (%04X:%04X) %s\n",
849 pcibus
[busind
].pb_isabridge_dev
= bridge_dev
;
850 type
= pci_isabridge
[j
].type
;
851 pcibus
[busind
].pb_isabridge_type
= type
;
855 r
= do_piix(bridge_dev
);
858 r
= do_via_isabr(bridge_dev
);
861 r
= do_amd_isabr(bridge_dev
);
864 r
= do_sis_isabr(bridge_dev
);
867 panic("unknown ISA bridge type: %d", type
);
872 if (unknown_bridge
== -1)
876 printf("(warning) no ISA bridge found on bus %d\n",
884 "(warning) unsupported ISA bridge %04X:%04X for bus %d\n",
885 pcidev
[unknown_bridge
].pd_vid
,
886 pcidev
[unknown_bridge
].pd_did
, busind
);
892 derive_irq(struct pcidev
* dev
, int pin
)
894 struct pcidev
* parent_bridge
;
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);
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
) {
920 irq
= acpi_get_irq(pcidev
[devind
].pd_busnr
,
921 pcidev
[devind
].pd_dev
, ipr
- 1);
924 irq
= derive_irq(&pcidev
[devind
], ipr
- 1);
928 __pci_attr_w8(devind
, PCI_ILR
, ilr
);
930 printf("PCI: ACPI IRQ %d for "
931 "device %d.%d.%d INT%c\n",
933 pcidev
[devind
].pd_busnr
,
934 pcidev
[devind
].pd_dev
,
935 pcidev
[devind
].pd_func
,
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
,
951 if (ipr
&& first
&& debug
)
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
)
965 printf("\tIRQ %d for INT%c\n", ilr
, 'A' + ipr
-1);
967 else if (ilr
!= PCI_ILR_UNKNOWN
)
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
);
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
)
988 "assigning IRQ %d to Cardbus device\n",
991 __pci_attr_w8(devind
, PCI_ILR
, ilr
);
992 pcidev
[devind
].pd_ilr
= ilr
;
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 /*===========================================================================*
1007 *===========================================================================*/
1009 record_bar(int devind
, int bar_nr
, int last
)
1011 int reg
, prefetch
, type
, dev_bar_nr
, width
;
1015 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
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;
1040 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
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
;
1051 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1057 type
= (bar
& PCI_BAR_TYPE
);
1061 case PCI_TYPE_32_1M
:
1065 /* A 64-bit BAR takes up two consecutive DWORDs. */
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
);
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.
1087 printf("\tbar_%d: (64-bit BAR with"
1088 " high bits set)\n", bar_nr
);
1097 /* Ignore the BAR. */
1100 printf("\tbar_%d: (unknown type %x)\n",
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
);
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
;
1128 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n",
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
;
1141 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1150 record_bars(int devind
, int last_reg
)
1154 for (i
= 0, reg
= PCI_BAR
; reg
<= last_reg
; i
+= width
, reg
+= 4 * width
)
1156 width
= record_bar(devind
, i
, reg
== last_reg
);
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
)
1175 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_PRI_NATIVE
))
1180 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1184 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_SEC_NATIVE
))
1189 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
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 */
1211 continue; /* No need to copy */
1213 pcidev
[devind
].pd_bar
[j
]=
1214 pcidev
[devind
].pd_bar
[i
];
1217 pcidev
[devind
].pd_bar_nr
= j
;
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);
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;
1240 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1244 base
= ((__pci_attr_r16(devind
, PPB_MEMBASE
) & PPB_MEMB_MASK
) << 16);
1246 ((__pci_attr_r16(devind
, PPB_MEMLIMIT
) & PPB_MEML_MASK
) << 16) |
1247 ((~PPB_MEML_MASK
& 0xffff) << 16);
1248 size
= limit
-base
+ 1;
1251 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1255 /* Ignore the upper 32 bits */
1256 base
= ((__pci_attr_r16(devind
, PPB_PFMEMBASE
) & PPB_PFMEMB_MASK
) << 16);
1258 ((__pci_attr_r16(devind
, PPB_PFMEMLIMIT
) &
1259 PPB_PFMEML_MASK
) << 16) |
1260 ((~PPB_PFMEML_MASK
& 0xffff) << 16);
1261 size
= limit
-base
+ 1;
1265 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
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;
1284 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
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;
1294 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
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;
1304 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
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;
1314 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
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
;
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) */
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
)
1347 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
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
;
1362 memgap_low
= base
+size
;
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
);
1382 iogap_high
= 0x10000;
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
))
1392 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1394 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1395 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1396 if (base
>= iogap_high
)
1398 if (base
+size
<= iogap_low
)
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
,
1409 if (base
+size
-iogap_low
< iogap_high
-base
)
1410 iogap_low
= base
+size
;
1416 if (iogap_high
< iogap_low
)
1420 printf("iogap_high too low, should panic\n");
1423 panic("iogap_high too low: %d", iogap_high
);
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
)
1434 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1436 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1437 if (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
);
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
);
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
,
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
))
1465 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
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.
1476 if (base
< iogap_low
)
1477 printf("I/O base too low: %d", 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
);
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
,
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
))
1509 printf("should allocate resources for device %d\n", i
);
1515 /*===========================================================================*
1516 * PCI Bridge Helpers *
1517 *===========================================================================*/
1519 probe_bus(int busind
)
1525 u16_t vid
, did
, sts
, sub_vid
, sub_did
;
1527 u8_t baseclass
, subclass
, infclass
;
1529 const char *s
, *dstr
;
1532 printf("probe_bus(%d)\n", busind
);
1533 if (nr_pcidev
>= NR_PCIDEV
)
1534 panic("too many PCI devices: %d", 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
);
1555 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
1556 vid
, did
, headt
, sts
);
1559 if (vid
== NO_VID
&& did
== NO_VID
)
1562 break; /* Nothing here */
1564 /* Scan all functions of a multifunction
1570 if (sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
))
1572 static int warned
= 0;
1576 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
1577 sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
));
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
);
1590 printf("%d.%lu.%lu: %s (%04X:%04X)\n",
1591 busnr
, (unsigned long)dev
,
1592 (unsigned long)func
, dstr
,
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",
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);
1613 s
= pci_baseclass_name(baseclass
<< 24);
1616 s
= "(unknown class)";
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
))
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;
1644 switch(headt
& PHT_MASK
)
1647 record_bars_normal(devind
);
1650 record_bars_bridge(devind
);
1653 record_bars_cardbus(devind
);
1656 printf("\t%d.%d.%d: unknown header type %d\n",
1662 print_capabilities(devind
);
1665 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
1666 if (t3
== PCI_T3_VGA
|| t3
== PCI_T3_VGA_OLD
)
1670 if (nr_pcidev
>= NR_PCIDEV
)
1671 panic("too many PCI devices: %d", nr_pcidev
);
1674 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
1682 pcibr_std_rsts(int busind
)
1686 devind
= pcibus
[busind
].pb_devind
;
1687 return __pci_attr_r16(devind
, PPB_SSTS
);
1691 pcibr_std_wsts(int busind
, u16_t value
)
1694 devind
= pcibus
[busind
].pb_devind
;
1697 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
1698 busind
, value
, devind
);
1700 __pci_attr_w16(devind
, PPB_SSTS
, value
);
1704 pcibr_cb_rsts(int busind
)
1707 devind
= pcibus
[busind
].pb_devind
;
1709 return __pci_attr_r16(devind
, CBB_SSTS
);
1713 pcibr_cb_wsts(int busind
, u16_t value
)
1716 devind
= pcibus
[busind
].pb_devind
;
1719 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
1720 busind
, value
, devind
);
1722 __pci_attr_w16(devind
, CBB_SSTS
, value
);
1726 pcibr_via_rsts(int busind
)
1732 pcibr_via_wsts(int busind
, u16_t value
)
1736 devind
= pcibus
[busind
].pb_devind
;
1738 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
1739 busind
, value
, devind
);
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
)
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)
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
));
1783 do_pcibridge(int busind
)
1788 u8_t sbusn
, baseclass
, subclass
, infclass
, headt
;
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
)
1798 printf("wrong bus\n");
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
);
1810 if ((headt
& PHT_MASK
) == PHT_BRIDGE
)
1812 else if ((headt
& PHT_MASK
) == PHT_CARDBUS
)
1817 printf("not a bridge\n");
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
)
1831 "Unknown PCI class %02x/%02x/%02x for PCI-to-PCI bridge, device %04X:%04X\n",
1832 baseclass
, subclass
, infclass
,
1836 if (type
== PCI_PPB_CB
&&
1837 t3
!= PCI_T3_CARDBUS
)
1840 "Unknown PCI class %02x/%02x/%02x for Cardbus bridge, device %04X:%04X\n",
1841 baseclass
, subclass
, infclass
,
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
1858 sbusn
= __pci_attr_r8(devind
, PPB_SECBN
);
1860 if (nr_pcibus
>= NR_PCIBUS
)
1861 panic("too many PCI busses: %d", 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
;
1879 pcibus
[ind
].pb_rsts
= pcibr_std_rsts
;
1880 pcibus
[ind
].pb_wsts
= pcibr_std_wsts
;
1883 pcibus
[ind
].pb_type
= PBT_CARDBUS
;
1884 pcibus
[ind
].pb_rsts
= pcibr_cb_rsts
;
1885 pcibus
[ind
].pb_wsts
= pcibr_cb_wsts
;
1888 pcibus
[ind
].pb_rsts
= pcibr_via_rsts
;
1889 pcibus
[ind
].pb_wsts
= pcibr_via_wsts
;
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
);
1902 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1903 ind
, sbusn
, __pci_attr_r8(devind
, PPB_SUBORDBN
));
1907 printf("Secondary bus number not initialized\n");
1910 pcibus
[ind
].pb_needinit
= 0;
1914 /* Look for PCI bridges */
1919 /*===========================================================================*
1921 *===========================================================================*/
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)
1930 u32_t bus
, dev
, func
;
1932 int s
, i
, r
, busind
, busnr
;
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
);
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
);
1965 dstr
= "unknown device";
1968 printf("pci_intel_init: %s (%04X:%04X)\n",
1974 r
= do_isabridge(busind
);
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
)
1984 pcidev
[i
].pd_inuse
= 1;
1989 /* Look for PCI bridges */
1990 do_pcibridge(busind
);
1992 /* Allocate bus numbers for uninitialized bridges */
1995 /* Allocate I/O and memory resources for uninitialized devices */
2000 /*===========================================================================*
2002 *===========================================================================*/
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
;
2014 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
2016 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
)
2018 size
= pcidev
[devind
].pd_bar
[i
].pb_size
;
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
,
2035 /*===========================================================================*
2037 *===========================================================================*/
2039 visible(struct rs_pci
*aclp
, int devind
)
2041 u16_t acl_sub_vid
, acl_sub_did
;
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
))
2065 if (!aclp
->rsp_nr_class
)
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
))
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;
2094 struct rprocpub rprocpub
[NR_BOOT_PROCS
];
2097 env_parse("pci_debug", "d", 0, &v
, 0, 1);
2100 if (sys_getmachine(&machine
)) {
2101 printf("PCI: no machine\n");
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
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
);
2128 case SEF_INIT_FRESH
:
2129 case SEF_INIT_RESTART
:
2130 do_announce_driver
= TRUE
;
2133 do_announce_driver
= FALSE
;
2136 panic("Unknown type of restart");
2140 /* Announce we are up when necessary. */
2141 if (TRUE
== do_announce_driver
) {
2142 chardriver_announce();
2145 /* Initialization completed successfully. */
2149 /*===========================================================================*
2151 *===========================================================================*/
2153 map_service(struct rprocpub
*rpub
)
2155 /* Map a new service by registering a new acl entry if required. */
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) {
2164 /* Find a free acl slot. */
2165 for (i
= 0; i
<NR_DRIVERS
; i
++)
2167 if (!pci_acl
[i
].inuse
)
2170 if (i
>= NR_DRIVERS
)
2172 printf("PCI: map_service: table is full\n");
2176 /* Initialize acl slot. */
2177 pci_acl
[i
].inuse
= 1;
2178 pci_acl
[i
].acl
= rpub
->pci_acl
;
2183 /*===========================================================================*
2185 *===========================================================================*/
2187 _pci_find_dev(u8_t bus
, u8_t dev
, u8_t func
, int *devindp
)
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
)
2201 if (devind
>= nr_pcidev
)
2209 /*===========================================================================*
2211 *===========================================================================*/
2213 _pci_first_dev(struct rs_pci
*aclp
, int *devindp
, u16_t
*vidp
,
2218 for (devind
= 0; devind
< nr_pcidev
; devind
++)
2220 if (!visible(aclp
, devind
))
2224 if (devind
>= nr_pcidev
)
2227 *vidp
= pcidev
[devind
].pd_vid
;
2228 *didp
= pcidev
[devind
].pd_did
;
2232 /*===========================================================================*
2234 *===========================================================================*/
2236 _pci_next_dev(struct rs_pci
*aclp
, int *devindp
, u16_t
*vidp
, u16_t
*didp
)
2240 for (devind
= *devindp
+1; devind
< nr_pcidev
; devind
++)
2242 if (!visible(aclp
, devind
))
2246 if (devind
>= nr_pcidev
)
2249 *vidp
= pcidev
[devind
].pd_vid
;
2250 *didp
= pcidev
[devind
].pd_did
;
2254 /*===========================================================================*
2255 * _pci_grant_access *
2256 *===========================================================================*/
2258 _pci_grant_access(int devind
, endpoint_t proc
)
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
);
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;
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
);
2286 printf("sys_privctl failed for proc %d: %d\n",
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
);
2299 printf("sys_privctl failed for proc %d: %d\n",
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
);
2311 printf("sys_privctl failed for proc %d: %d\n",
2319 /*===========================================================================*
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
);
2330 if (!visible(aclp
, devind
))
2332 printf("pci_reserve_a: %u is not allowed to reserve %d\n",
2337 if(pcidev
[devind
].pd_inuse
&& pcidev
[devind
].pd_proc
!= proc
)
2340 pcidev
[devind
].pd_inuse
= 1;
2341 pcidev
[devind
].pd_proc
= proc
;
2343 return _pci_grant_access(devind
, proc
);
2346 /*===========================================================================*
2348 *===========================================================================*/
2350 _pci_release(endpoint_t proc
)
2354 for (i
= 0; i
<nr_pcidev
; i
++)
2356 if (!pcidev
[i
].pd_inuse
)
2358 if (pcidev
[i
].pd_proc
!= proc
)
2360 pcidev
[i
].pd_inuse
= 0;
2364 /*===========================================================================*
2366 *===========================================================================*/
2368 _pci_ids(int devind
, u16_t
*vidp
, u16_t
*didp
)
2370 if (devind
< 0 || devind
>= nr_pcidev
)
2373 *vidp
= pcidev
[devind
].pd_vid
;
2374 *didp
= pcidev
[devind
].pd_did
;
2378 /*===========================================================================*
2380 *===========================================================================*/
2382 _pci_rescan_bus(u8_t busnr
)
2386 busind
= get_busind(busnr
);
2389 /* Allocate bus numbers for uninitialized bridges */
2392 /* Allocate I/O and memory resources for uninitialized devices */
2396 /*===========================================================================*
2398 *===========================================================================*/
2400 _pci_slot_name(int devind
, char **cpp
)
2402 static char label
[]= "ddd.ddd.ddd.ddd";
2406 if (devind
< 0 || devind
>= nr_pcidev
)
2410 end
= label
+sizeof(label
);
2412 /* FIXME: domain nb is always 0 on 32bit system, but we should
2413 * retrieve it properly, somehow. */
2417 ntostr(pcidev
[devind
].pd_busnr
, &p
, end
);
2420 ntostr(pcidev
[devind
].pd_dev
, &p
, end
);
2423 ntostr(pcidev
[devind
].pd_func
, &p
, end
);
2429 /*===========================================================================*
2431 *===========================================================================*/
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
);
2440 /*===========================================================================*
2442 *===========================================================================*/
2444 _pci_get_bar(int devind
, int port
, u32_t
*base
, u32_t
*size
,
2449 if (devind
< 0 || devind
>= nr_pcidev
)
2452 for (i
= 0; i
< pcidev
[devind
].pd_bar_nr
; i
++)
2454 reg
= PCI_BAR
+4*pcidev
[devind
].pd_bar
[i
].pb_nr
;
2458 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_INCOMPLETE
)
2461 *base
= pcidev
[devind
].pd_bar
[i
].pb_base
;
2462 *size
= pcidev
[devind
].pd_bar
[i
].pb_size
;
2464 !!(pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
);
2471 /*===========================================================================*
2473 *===========================================================================*/
2475 _pci_attr_r8(int devind
, int port
, u8_t
*vp
)
2477 if (devind
< 0 || devind
>= nr_pcidev
)
2479 if (port
< 0 || port
> 256-1)
2482 *vp
= __pci_attr_r8(devind
, port
);
2486 /*===========================================================================*
2488 *===========================================================================*/
2490 _pci_attr_r16(int devind
, int port
, u16_t
*vp
)
2492 if (devind
< 0 || devind
>= nr_pcidev
)
2494 if (port
< 0 || port
> 256-2)
2497 *vp
= __pci_attr_r16(devind
, port
);
2501 /*===========================================================================*
2503 *===========================================================================*/
2505 _pci_attr_r32(int devind
, int port
, u32_t
*vp
)
2507 if (devind
< 0 || devind
>= nr_pcidev
)
2509 if (port
< 0 || port
> 256-4)
2512 *vp
= __pci_attr_r32(devind
, port
);
2516 /*===========================================================================*
2518 *===========================================================================*/
2520 _pci_attr_w8(int devind
, int port
, u8_t value
)
2522 if (devind
< 0 || devind
>= nr_pcidev
)
2524 if (port
< 0 || port
> 256-1)
2527 __pci_attr_w8(devind
, port
, value
);
2531 /*===========================================================================*
2533 *===========================================================================*/
2535 _pci_attr_w16(int devind
, int port
, u16_t value
)
2537 if (devind
< 0 || devind
>= nr_pcidev
)
2539 if (port
< 0 || port
> 256-2)
2542 __pci_attr_w16(devind
, port
, value
);
2546 /*===========================================================================*
2548 *===========================================================================*/
2550 _pci_attr_w32(int devind
, int port
, u32_t value
)
2552 if (devind
< 0 || devind
>= nr_pcidev
)
2554 if (port
< 0 || port
> 256-4)
2557 __pci_attr_w32(devind
, port
, value
);