4 Configure devices on the PCI bus
6 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
10 #include <machine/pci.h>
11 #include <machine/vm.h>
12 #include <machine/vmparam.h>
13 #include <minix/com.h>
15 #include <minix/syslib.h>
16 #include <minix/param.h>
19 #include <machine/pci_amd.h>
20 #include <machine/pci_intel.h>
21 #include <machine/pci_sis.h>
22 #include <machine/pci_via.h>
28 #define irq_mode_pci(irq) ((void)0)
33 #include <minix/sysutil.h>
34 #include <minix/acpi.h>
36 #define PBT_INTEL_HOST 1
37 #define PBT_PCIBRIDGE 2
40 #define BAM_NR 6 /* Number of base-address registers */
49 int pb_isabridge_type
;
53 u8_t (*pb_rreg8
)(int busind
, int devind
, int port
);
54 u16_t (*pb_rreg16
)(int busind
, int devind
, int port
);
55 u32_t (*pb_rreg32
)(int busind
, int devind
, int port
);
56 void (*pb_wreg8
)(int busind
, int devind
, int port
, u8_t value
);
57 void (*pb_wreg16
)(int busind
, int devind
, int port
, u16_t value
);
58 void (*pb_wreg32
)(int busind
, int devind
, int port
, u32_t value
);
59 u16_t (*pb_rsts
)(int busind
);
60 void (*pb_wsts
)(int busind
, u16_t value
);
62 static int nr_pcibus
= 0;
91 EXTERN
struct pci_acl pci_acl
[NR_DRIVERS
];
94 #define PBF_IO 1 /* I/O else memory */
95 #define PBF_INCOMPLETE 2 /* not allocated */
97 static int nr_pcidev
= 0;
99 static void pci_intel_init(void);
100 static void probe_bus(int busind
);
101 static int is_duplicate(u8_t busnr
, u8_t dev
, u8_t func
);
102 static void record_irq(int devind
);
103 static void record_bars_normal(int devind
);
104 static void record_bars_bridge(int devind
);
105 static void record_bars_cardbus(int devind
);
106 static void record_bars(int devind
, int last_reg
);
107 static int record_bar(int devind
, int bar_nr
, int last
);
108 static void complete_bridges(void);
109 static void complete_bars(void);
110 static void update_bridge4dev_io(int devind
, u32_t io_base
, u32_t
112 static int get_freebus(void);
113 static int do_isabridge(int busind
);
114 static void do_pcibridge(int busind
);
115 static int get_busind(int busnr
);
116 static int do_piix(int devind
);
117 static int do_amd_isabr(int devind
);
118 static int do_sis_isabr(int devind
);
119 static int do_via_isabr(int devind
);
121 static void report_vga(int devind
);
123 static char *pci_vid_name(u16_t vid
);
124 static char *pci_baseclass_name(u8_t baseclass
);
125 static char *pci_subclass_name(u8_t baseclass
, u8_t subclass
, u8_t
127 static void ntostr(unsigned n
, char **str
, const char *end
);
129 static u8_t
pci_attr_r8_u(int devind
, int port
);
130 static u32_t
pci_attr_r32_u(int devind
, int port
);
132 static u16_t
pci_attr_rsts(int devind
);
133 static void pci_attr_wsts(int devind
, u16_t value
);
134 static u16_t
pcibr_std_rsts(int busind
);
135 static void pcibr_std_wsts(int busind
, u16_t value
);
136 static u16_t
pcibr_cb_rsts(int busind
);
137 static void pcibr_cb_wsts(int busind
, u16_t value
);
138 static u16_t
pcibr_via_rsts(int busind
);
139 static void pcibr_via_wsts(int busind
, u16_t value
);
140 static u8_t
pcii_rreg8(int busind
, int devind
, int port
);
141 static u16_t
pcii_rreg16(int busind
, int devind
, int port
);
142 static u32_t
pcii_rreg32(int busind
, int devind
, int port
);
143 static void pcii_wreg8(int busind
, int devind
, int port
, u8_t value
);
144 static void pcii_wreg16(int busind
, int devind
, int port
, u16_t value
);
145 static void pcii_wreg32(int busind
, int devind
, int port
, u32_t value
);
146 static u16_t
pcii_rsts(int busind
);
147 static void pcii_wsts(int busind
, u16_t value
);
148 static void print_capabilities(int devind
);
149 static int visible(struct rs_pci
*aclp
, int devind
);
150 static void print_hyper_cap(int devind
, u8_t capptr
);
152 static struct machine machine
;
153 static endpoint_t acpi_ep
;
155 /*===========================================================================*
156 * sef_cb_init_fresh *
157 *===========================================================================*/
158 int sef_cb_init_fresh(int type
, sef_init_info_t
*info
)
160 /* Initialize the pci driver. */
163 struct rprocpub rprocpub
[NR_BOOT_PROCS
];
166 env_parse("pci_debug", "d", 0, &v
, 0, 1);
169 if (sys_getmachine(&machine
)) {
170 printf("PCI: no machine\n");
173 if (machine
.apic_enabled
&&
174 ds_retrieve_label_endpt("acpi", &acpi_ep
) != OK
) {
175 panic("PCI: Cannot use APIC mode without ACPI!\n");
178 /* Only Intel (compatible) PCI controllers are supported at the
183 /* Map all the services in the boot image. */
184 if((r
= sys_safecopyfrom(RS_PROC_NR
, info
->rproctab_gid
, 0,
185 (vir_bytes
) rprocpub
, sizeof(rprocpub
))) != OK
) {
186 panic("sys_safecopyfrom failed: %d", r
);
188 for(i
=0;i
< NR_BOOT_PROCS
;i
++) {
189 if(rprocpub
[i
].in_use
) {
190 if((r
= map_service(&rprocpub
[i
])) != OK
) {
191 panic("unable to map service: %d", r
);
199 /*===========================================================================*
201 *===========================================================================*/
202 int map_service(rpub
)
203 struct rprocpub
*rpub
;
205 /* Map a new service by registering a new acl entry if required. */
208 /* Stop right now if no pci device or class is found. */
209 if(rpub
->pci_acl
.rsp_nr_device
== 0
210 && rpub
->pci_acl
.rsp_nr_class
== 0) {
214 /* Find a free acl slot. */
215 for (i
= 0; i
<NR_DRIVERS
; i
++)
217 if (!pci_acl
[i
].inuse
)
222 printf("PCI: map_service: table is full\n");
226 /* Initialize acl slot. */
227 pci_acl
[i
].inuse
= 1;
228 pci_acl
[i
].acl
= rpub
->pci_acl
;
233 /*===========================================================================*
234 * helper functions for I/O *
235 *===========================================================================*/
236 unsigned pci_inb(u16_t port
) {
239 if ((s
=sys_inb(port
, &value
)) !=OK
)
240 printf("PCI: warning, sys_inb failed: %d\n", s
);
243 unsigned pci_inw(u16_t port
) {
246 if ((s
=sys_inw(port
, &value
)) !=OK
)
247 printf("PCI: warning, sys_inw failed: %d\n", s
);
250 unsigned pci_inl(u16_t port
) {
253 if ((s
=sys_inl(port
, &value
)) !=OK
)
254 printf("PCI: warning, sys_inl failed: %d\n", s
);
257 void pci_outb(u16_t port
, u8_t value
) {
259 if ((s
=sys_outb(port
, value
)) !=OK
)
260 printf("PCI: warning, sys_outb failed: %d\n", s
);
262 void pci_outw(u16_t port
, u16_t value
) {
264 if ((s
=sys_outw(port
, value
)) !=OK
)
265 printf("PCI: warning, sys_outw failed: %d\n", s
);
267 void pci_outl(u16_t port
, u32_t value
) {
269 if ((s
=sys_outl(port
, value
)) !=OK
)
270 printf("PCI: warning, sys_outl failed: %d\n", s
);
273 /*===========================================================================*
275 *===========================================================================*/
276 int pci_find_dev(u8_t bus
, u8_t dev
, u8_t func
, int *devindp
)
280 for (devind
= 0; devind
< nr_pcidev
; devind
++)
282 if (pcidev
[devind
].pd_busnr
== bus
&&
283 pcidev
[devind
].pd_dev
== dev
&&
284 pcidev
[devind
].pd_func
== func
)
289 if (devind
>= nr_pcidev
)
292 if (pcidev
[devind
].pd_inuse
)
299 /*===========================================================================*
301 *===========================================================================*/
311 for (devind
= 0; devind
< nr_pcidev
; devind
++)
314 if (pcidev
[devind
].pd_inuse
)
317 if (!visible(aclp
, devind
))
321 if (devind
>= nr_pcidev
)
324 *vidp
= pcidev
[devind
].pd_vid
;
325 *didp
= pcidev
[devind
].pd_did
;
329 /*===========================================================================*
331 *===========================================================================*/
341 for (devind
= *devindp
+1; devind
< nr_pcidev
; devind
++)
344 if (pcidev
[devind
].pd_inuse
)
347 if (!visible(aclp
, devind
))
351 if (devind
>= nr_pcidev
)
354 *vidp
= pcidev
[devind
].pd_vid
;
355 *didp
= pcidev
[devind
].pd_did
;
359 /*===========================================================================*
361 *===========================================================================*/
362 int pci_reserve_a(devind
, proc
, aclp
)
370 struct minix_mem_range mr
;
372 if (devind
< 0 || devind
>= nr_pcidev
)
374 printf("pci_reserve_a: bad devind: %d\n", devind
);
377 if (!visible(aclp
, devind
))
379 printf("pci_reserve_a: %u is not allowed to reserve %d\n",
384 if(pcidev
[devind
].pd_inuse
&& pcidev
[devind
].pd_proc
!= proc
)
386 pcidev
[devind
].pd_inuse
= 1;
387 pcidev
[devind
].pd_proc
= proc
;
389 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
391 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_INCOMPLETE
)
393 printf("pci_reserve_a: BAR %d is incomplete\n", i
);
396 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
)
398 ior
.ior_base
= pcidev
[devind
].pd_bar
[i
].pb_base
;
399 ior
.ior_limit
= ior
.ior_base
+
400 pcidev
[devind
].pd_bar
[i
].pb_size
-1;
404 "pci_reserve_a: for proc %d, adding I/O range [0x%x..0x%x]\n",
405 proc
, ior
.ior_base
, ior
.ior_limit
);
407 r
= sys_privctl(proc
, SYS_PRIV_ADD_IO
, &ior
);
410 printf("sys_privctl failed for proc %d: %d\n",
416 mr
.mr_base
= pcidev
[devind
].pd_bar
[i
].pb_base
;
417 mr
.mr_limit
= mr
.mr_base
+
418 pcidev
[devind
].pd_bar
[i
].pb_size
-1;
420 r
= sys_privctl(proc
, SYS_PRIV_ADD_MEM
, &mr
);
423 printf("sys_privctl failed for proc %d: %d\n",
428 ilr
= pcidev
[devind
].pd_ilr
;
429 if (ilr
!= PCI_ILR_UNKNOWN
)
431 if(debug
) printf("pci_reserve_a: adding IRQ %d\n", ilr
);
432 r
= sys_privctl(proc
, SYS_PRIV_ADD_IRQ
, &ilr
);
435 printf("sys_privctl failed for proc %d: %d\n",
443 /*===========================================================================*
445 *===========================================================================*/
446 void pci_release(proc
)
451 for (i
= 0; i
<nr_pcidev
; i
++)
453 if (!pcidev
[i
].pd_inuse
)
455 if (pcidev
[i
].pd_proc
!= proc
)
457 pcidev
[i
].pd_inuse
= 0;
461 /*===========================================================================*
463 *===========================================================================*/
464 int pci_ids_s(int devind
, u16_t
*vidp
, u16_t
*didp
)
466 if (devind
< 0 || devind
>= nr_pcidev
)
469 *vidp
= pcidev
[devind
].pd_vid
;
470 *didp
= pcidev
[devind
].pd_did
;
474 /*===========================================================================*
476 *===========================================================================*/
477 void pci_rescan_bus(u8_t busnr
)
481 busind
= get_busind(busnr
);
484 /* Allocate bus numbers for uninitialized bridges */
487 /* Allocate I/O and memory resources for uninitialized devices */
491 /*===========================================================================*
493 *===========================================================================*/
494 int pci_slot_name_s(devind
, cpp
)
498 static char label
[]= "ddd.ddd.ddd";
502 if (devind
< 0 || devind
>= nr_pcidev
)
506 end
= label
+sizeof(label
);
508 ntostr(pcidev
[devind
].pd_busnr
, &p
, end
);
511 ntostr(pcidev
[devind
].pd_dev
, &p
, end
);
514 ntostr(pcidev
[devind
].pd_func
, &p
, end
);
520 /*===========================================================================*
522 *===========================================================================*/
523 char *pci_dev_name(u16_t vid
, u16_t did
)
527 for (i
= 0; pci_device_table
[i
].name
; i
++)
529 if (pci_device_table
[i
].vid
== vid
&&
530 pci_device_table
[i
].did
== did
)
532 return pci_device_table
[i
].name
;
538 /*===========================================================================*
540 *===========================================================================*/
541 int pci_get_bar_s(int devind
, int port
, u32_t
*base
, u32_t
*size
,
546 if (devind
< 0 || devind
>= nr_pcidev
)
549 for (i
= 0; i
< pcidev
[devind
].pd_bar_nr
; i
++)
551 reg
= PCI_BAR
+4*pcidev
[devind
].pd_bar
[i
].pb_nr
;
555 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_INCOMPLETE
)
558 *base
= pcidev
[devind
].pd_bar
[i
].pb_base
;
559 *size
= pcidev
[devind
].pd_bar
[i
].pb_size
;
561 !!(pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
);
568 /*===========================================================================*
570 *===========================================================================*/
571 int pci_attr_r8_s(int devind
, int port
, u8_t
*vp
)
573 if (devind
< 0 || devind
>= nr_pcidev
)
575 if (port
< 0 || port
> 255)
578 *vp
= pci_attr_r8_u(devind
, port
);
582 /*===========================================================================*
584 *===========================================================================*/
585 static u8_t
pci_attr_r8_u(devind
, port
)
591 busnr
= pcidev
[devind
].pd_busnr
;
592 busind
= get_busind(busnr
);
593 return pcibus
[busind
].pb_rreg8(busind
, devind
, port
);
596 /*===========================================================================*
598 *===========================================================================*/
599 u16_t
pci_attr_r16(devind
, port
)
605 busnr
= pcidev
[devind
].pd_busnr
;
606 busind
= get_busind(busnr
);
607 return pcibus
[busind
].pb_rreg16(busind
, devind
, port
);
610 /*===========================================================================*
612 *===========================================================================*/
613 int pci_attr_r32_s(int devind
, int port
, u32_t
*vp
)
615 if (devind
< 0 || devind
>= nr_pcidev
)
617 if (port
< 0 || port
> 256-4)
620 *vp
= pci_attr_r32_u(devind
, port
);
624 /*===========================================================================*
626 *===========================================================================*/
627 static u32_t
pci_attr_r32_u(devind
, port
)
633 busnr
= pcidev
[devind
].pd_busnr
;
634 busind
= get_busind(busnr
);
635 return pcibus
[busind
].pb_rreg32(busind
, devind
, port
);
638 /*===========================================================================*
640 *===========================================================================*/
641 void pci_attr_w8(int devind
, int port
, u8_t value
)
645 busnr
= pcidev
[devind
].pd_busnr
;
646 busind
= get_busind(busnr
);
647 pcibus
[busind
].pb_wreg8(busind
, devind
, port
, value
);
650 /*===========================================================================*
652 *===========================================================================*/
653 void pci_attr_w16(int devind
, int port
, u16_t value
)
657 busnr
= pcidev
[devind
].pd_busnr
;
658 busind
= get_busind(busnr
);
659 pcibus
[busind
].pb_wreg16(busind
, devind
, port
, value
);
662 /*===========================================================================*
664 *===========================================================================*/
665 void pci_attr_w32(int devind
, int port
, u32_t value
)
669 busnr
= pcidev
[devind
].pd_busnr
;
670 busind
= get_busind(busnr
);
671 pcibus
[busind
].pb_wreg32(busind
, devind
, port
, value
);
674 /*===========================================================================*
676 *===========================================================================*/
677 static void pci_intel_init()
679 /* Try to detect a know PCI controller. Read the Vendor ID and
680 * the Device ID for function 0 of device 0.
681 * Two times the value 0xffff suggests a system without a (compatible)
684 u32_t bus
, dev
, func
;
686 int s
, i
, r
, busind
, busnr
;
693 vid
= PCII_RREG16_(bus
, dev
, func
, PCI_VID
);
694 did
= PCII_RREG16_(bus
, dev
, func
, PCI_DID
);
695 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
696 printf("PCI: warning, sys_outl failed: %d\n", s
);
699 if (vid
== 0xffff && did
== 0xffff)
700 return; /* Nothing here */
702 for (i
= 0; pci_intel_ctrl
[i
].vid
; i
++)
704 if (pci_intel_ctrl
[i
].vid
== vid
&&
705 pci_intel_ctrl
[i
].did
== did
)
711 if (!pci_intel_ctrl
[i
].vid
)
713 printf("pci_intel_init (warning): unknown PCI-controller:\n"
714 "\tvendor %04X (%s), device %04X\n",
715 vid
, pci_vid_name(vid
), did
);
719 if (nr_pcibus
>= NR_PCIBUS
)
720 panic("too many PCI busses: %d", nr_pcibus
);
723 pcibus
[busind
].pb_type
= PBT_INTEL_HOST
;
724 pcibus
[busind
].pb_needinit
= 0;
725 pcibus
[busind
].pb_isabridge_dev
= -1;
726 pcibus
[busind
].pb_isabridge_type
= 0;
727 pcibus
[busind
].pb_devind
= -1;
728 pcibus
[busind
].pb_busnr
= 0;
729 pcibus
[busind
].pb_rreg8
= pcii_rreg8
;
730 pcibus
[busind
].pb_rreg16
= pcii_rreg16
;
731 pcibus
[busind
].pb_rreg32
= pcii_rreg32
;
732 pcibus
[busind
].pb_wreg8
= pcii_wreg8
;
733 pcibus
[busind
].pb_wreg16
= pcii_wreg16
;
734 pcibus
[busind
].pb_wreg32
= pcii_wreg32
;
735 pcibus
[busind
].pb_rsts
= pcii_rsts
;
736 pcibus
[busind
].pb_wsts
= pcii_wsts
;
738 dstr
= pci_dev_name(vid
, did
);
740 dstr
= "unknown device";
743 printf("pci_intel_init: %s (%04X:%04X)\n",
749 r
= do_isabridge(busind
);
752 busnr
= pcibus
[busind
].pb_busnr
;
754 /* Disable all devices for this bus */
755 for (i
= 0; i
<nr_pcidev
; i
++)
757 if (pcidev
[i
].pd_busnr
!= busnr
)
759 pcidev
[i
].pd_inuse
= 1;
764 /* Look for PCI bridges */
765 do_pcibridge(busind
);
767 /* Allocate bus numbers for uninitialized bridges */
770 /* Allocate I/O and memory resources for uninitialized devices */
774 /*===========================================================================*
776 *===========================================================================*/
777 static void probe_bus(int busind
)
780 u16_t vid
, did
, sts
, sub_vid
, sub_did
;
782 u8_t baseclass
, subclass
, infclass
;
787 printf("probe_bus(%d)\n", busind
);
788 if (nr_pcidev
>= NR_PCIDEV
)
789 panic("too many PCI devices: %d", nr_pcidev
);
792 busnr
= pcibus
[busind
].pb_busnr
;
793 for (dev
= 0; dev
<32; dev
++)
796 for (func
= 0; func
< 8; func
++)
798 pcidev
[devind
].pd_busnr
= busnr
;
799 pcidev
[devind
].pd_dev
= dev
;
800 pcidev
[devind
].pd_func
= func
;
802 pci_attr_wsts(devind
,
803 PSR_SSE
|PSR_RMAS
|PSR_RTAS
);
804 vid
= pci_attr_r16(devind
, PCI_VID
);
805 did
= pci_attr_r16(devind
, PCI_DID
);
806 headt
= pci_attr_r8_u(devind
, PCI_HEADT
);
807 sts
= pci_attr_rsts(devind
);
810 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
811 vid
, did
, headt
, sts
);
814 if (vid
== NO_VID
&& did
== NO_VID
)
817 break; /* Nothing here */
819 /* Scan all functions of a multifunction
825 if (sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
))
827 static int warned
= 0;
831 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
832 sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
));
837 sub_vid
= pci_attr_r16(devind
, PCI_SUBVID
);
838 sub_did
= pci_attr_r16(devind
, PCI_SUBDID
);
840 dstr
= pci_dev_name(vid
, did
);
845 printf("%d.%lu.%lu: %s (%04X:%04X)\n",
846 busnr
, (unsigned long)dev
,
847 (unsigned long)func
, dstr
,
853 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
854 busnr
, (unsigned long)dev
,
855 (unsigned long)func
, vid
,
856 pci_vid_name(vid
), did
);
858 printf("Device index: %d\n", devind
);
859 printf("Subsystem: Vid 0x%x, did 0x%x\n",
863 baseclass
= pci_attr_r8_u(devind
, PCI_BCR
);
864 subclass
= pci_attr_r8_u(devind
, PCI_SCR
);
865 infclass
= pci_attr_r8_u(devind
, PCI_PIFR
);
866 s
= pci_subclass_name(baseclass
, subclass
, infclass
);
868 s
= pci_baseclass_name(baseclass
);
871 s
= "(unknown class)";
875 printf("\tclass %s (%X/%X/%X)\n", s
,
876 baseclass
, subclass
, infclass
);
879 if (is_duplicate(busnr
, dev
, func
))
881 printf("\tduplicate!\n");
882 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
889 pcidev
[devind
].pd_baseclass
= baseclass
;
890 pcidev
[devind
].pd_subclass
= subclass
;
891 pcidev
[devind
].pd_infclass
= infclass
;
892 pcidev
[devind
].pd_vid
= vid
;
893 pcidev
[devind
].pd_did
= did
;
894 pcidev
[devind
].pd_sub_vid
= sub_vid
;
895 pcidev
[devind
].pd_sub_did
= sub_did
;
896 pcidev
[devind
].pd_inuse
= 0;
897 pcidev
[devind
].pd_bar_nr
= 0;
899 switch(headt
& PHT_MASK
)
902 record_bars_normal(devind
);
905 record_bars_bridge(devind
);
908 record_bars_cardbus(devind
);
911 printf("\t%d.%d.%d: unknown header type %d\n",
917 print_capabilities(devind
);
919 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
921 if (t3
== PCI_T3_VGA
|| t3
== PCI_T3_VGA_OLD
)
925 if (nr_pcidev
>= NR_PCIDEV
)
926 panic("too many PCI devices: %d", nr_pcidev
);
929 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
935 /*===========================================================================*
937 *===========================================================================*/
938 static int is_duplicate(u8_t busnr
, u8_t dev
, u8_t func
)
942 for (i
= 0; i
<nr_pcidev
; i
++)
944 if (pcidev
[i
].pd_busnr
== busnr
&&
945 pcidev
[i
].pd_dev
== dev
&&
946 pcidev
[i
].pd_func
== func
)
954 static int acpi_get_irq(unsigned bus
, unsigned dev
, unsigned pin
)
959 ((struct acpi_get_irq_req
*)&m
)->hdr
.request
= ACPI_REQ_GET_IRQ
;
960 ((struct acpi_get_irq_req
*)&m
)->bus
= bus
;
961 ((struct acpi_get_irq_req
*)&m
)->dev
= dev
;
962 ((struct acpi_get_irq_req
*)&m
)->pin
= pin
;
964 if ((err
= ipc_sendrec(acpi_ep
, &m
)) != OK
)
965 panic("PCI: error %d while receiveing from ACPI\n", err
);
967 return ((struct acpi_get_irq_resp
*)&m
)->irq
;
970 static int derive_irq(struct pcidev
* dev
, int pin
)
972 struct pcidev
* parent_bridge
;
975 parent_bridge
= &pcidev
[pcibus
[get_busind(dev
->pd_busnr
)].pb_devind
];
978 * We don't support PCI-Express, no ARI, decode the slot of the device
979 * and mangle the pin as the device is behind a bridge
981 slot
= ((dev
->pd_func
) >> 3) & 0x1f;
983 return acpi_get_irq(parent_bridge
->pd_busnr
,
984 parent_bridge
->pd_dev
, (pin
+ slot
) % 4);
987 /*===========================================================================*
989 *===========================================================================*/
990 static void record_irq(devind
)
993 int ilr
, ipr
, busnr
, busind
, cb_devind
;
995 ilr
= pci_attr_r8_u(devind
, PCI_ILR
);
996 ipr
= pci_attr_r8_u(devind
, PCI_IPR
);
998 if (ipr
&& machine
.apic_enabled
) {
1001 irq
= acpi_get_irq(pcidev
[devind
].pd_busnr
,
1002 pcidev
[devind
].pd_dev
, ipr
- 1);
1005 irq
= derive_irq(&pcidev
[devind
], ipr
- 1);
1009 pci_attr_w8(devind
, PCI_ILR
, ilr
);
1011 printf("PCI: ACPI IRQ %d for "
1012 "device %d.%d.%d INT%c\n",
1014 pcidev
[devind
].pd_busnr
,
1015 pcidev
[devind
].pd_dev
,
1016 pcidev
[devind
].pd_func
,
1020 printf("PCI: no ACPI IRQ routing for "
1021 "device %d.%d.%d INT%c\n",
1022 pcidev
[devind
].pd_busnr
,
1023 pcidev
[devind
].pd_dev
,
1024 pcidev
[devind
].pd_func
,
1031 static int first
= 1;
1032 if (ipr
&& first
&& debug
)
1035 printf("PCI: strange, BIOS assigned IRQ0\n");
1037 ilr
= PCI_ILR_UNKNOWN
;
1039 pcidev
[devind
].pd_ilr
= ilr
;
1040 if (ilr
== PCI_ILR_UNKNOWN
&& !ipr
)
1043 else if (ilr
!= PCI_ILR_UNKNOWN
&& ipr
)
1046 printf("\tIRQ %d for INT%c\n", ilr
, 'A' + ipr
-1);
1048 else if (ilr
!= PCI_ILR_UNKNOWN
)
1051 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
1052 ilr
, pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
1053 pcidev
[devind
].pd_func
);
1057 /* Check for cardbus devices */
1058 busnr
= pcidev
[devind
].pd_busnr
;
1059 busind
= get_busind(busnr
);
1060 if (pcibus
[busind
].pb_type
== PBT_CARDBUS
)
1062 cb_devind
= pcibus
[busind
].pb_devind
;
1063 ilr
= pcidev
[cb_devind
].pd_ilr
;
1064 if (ilr
!= PCI_ILR_UNKNOWN
)
1069 "assigning IRQ %d to Cardbus device\n",
1072 pci_attr_w8(devind
, PCI_ILR
, ilr
);
1073 pcidev
[devind
].pd_ilr
= ilr
;
1079 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
1080 pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
1081 pcidev
[devind
].pd_func
, 'A' + ipr
-1);
1086 /*===========================================================================*
1087 * record_bars_normal *
1088 *===========================================================================*/
1089 static void record_bars_normal(devind
)
1092 int i
, j
, clear_01
, clear_23
, pb_nr
;
1094 /* The BAR area of normal devices is six DWORDs in size. */
1095 record_bars(devind
, PCI_BAR_6
);
1097 /* Special case code for IDE controllers in compatibility mode */
1098 if (pcidev
[devind
].pd_baseclass
== PCI_BCR_MASS_STORAGE
&&
1099 pcidev
[devind
].pd_subclass
== PCI_MS_IDE
)
1104 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_PRI_NATIVE
))
1109 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1113 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_SEC_NATIVE
))
1118 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
1124 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
1126 pb_nr
= pcidev
[devind
].pd_bar
[i
].pb_nr
;
1127 if ((pb_nr
== 0 || pb_nr
== 1) && clear_01
)
1129 if (debug
) printf("skipping bar %d\n", pb_nr
);
1130 continue; /* Skip */
1132 if ((pb_nr
== 2 || pb_nr
== 3) && clear_23
)
1134 if (debug
) printf("skipping bar %d\n", pb_nr
);
1135 continue; /* Skip */
1140 continue; /* No need to copy */
1142 pcidev
[devind
].pd_bar
[j
]=
1143 pcidev
[devind
].pd_bar
[i
];
1146 pcidev
[devind
].pd_bar_nr
= j
;
1150 /*===========================================================================*
1151 * record_bars_bridge *
1152 *===========================================================================*/
1153 static void record_bars_bridge(devind
)
1156 u32_t base
, limit
, size
;
1158 /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
1159 * It may contain up to two 32-bit BARs, or one 64-bit BAR.
1161 record_bars(devind
, PCI_BAR_2
);
1163 base
= ((pci_attr_r8_u(devind
, PPB_IOBASE
) & PPB_IOB_MASK
) << 8) |
1164 (pci_attr_r16(devind
, PPB_IOBASEU16
) << 16);
1166 ((pci_attr_r8_u(devind
, PPB_IOLIMIT
) & PPB_IOL_MASK
) << 8) |
1167 ((~PPB_IOL_MASK
& 0xff) << 8) |
1168 (pci_attr_r16(devind
, PPB_IOLIMITU16
) << 16);
1169 size
= limit
-base
+ 1;
1172 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1176 base
= ((pci_attr_r16(devind
, PPB_MEMBASE
) & PPB_MEMB_MASK
) << 16);
1178 ((pci_attr_r16(devind
, PPB_MEMLIMIT
) & PPB_MEML_MASK
) << 16) |
1179 ((~PPB_MEML_MASK
& 0xffff) << 16);
1180 size
= limit
-base
+ 1;
1183 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1187 /* Ignore the upper 32 bits */
1188 base
= ((pci_attr_r16(devind
, PPB_PFMEMBASE
) & PPB_PFMEMB_MASK
) << 16);
1190 ((pci_attr_r16(devind
, PPB_PFMEMLIMIT
) &
1191 PPB_PFMEML_MASK
) << 16) |
1192 ((~PPB_PFMEML_MASK
& 0xffff) << 16);
1193 size
= limit
-base
+ 1;
1197 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1202 /*===========================================================================*
1203 * record_bars_cardbus *
1204 *===========================================================================*/
1205 static void record_bars_cardbus(devind
)
1208 u32_t base
, limit
, size
;
1210 /* The generic BAR area of CardBus devices is one DWORD in size. */
1211 record_bars(devind
, PCI_BAR
);
1213 base
= pci_attr_r32_u(devind
, CBB_MEMBASE_0
);
1214 limit
= pci_attr_r32_u(devind
, CBB_MEMLIMIT_0
) |
1215 (~CBB_MEML_MASK
& 0xffffffff);
1216 size
= limit
-base
+ 1;
1219 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1223 base
= pci_attr_r32_u(devind
, CBB_MEMBASE_1
);
1224 limit
= pci_attr_r32_u(devind
, CBB_MEMLIMIT_1
) |
1225 (~CBB_MEML_MASK
& 0xffffffff);
1226 size
= limit
-base
+ 1;
1229 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1233 base
= pci_attr_r32_u(devind
, CBB_IOBASE_0
);
1234 limit
= pci_attr_r32_u(devind
, CBB_IOLIMIT_0
) |
1235 (~CBB_IOL_MASK
& 0xffffffff);
1236 size
= limit
-base
+ 1;
1239 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1243 base
= pci_attr_r32_u(devind
, CBB_IOBASE_1
);
1244 limit
= pci_attr_r32_u(devind
, CBB_IOLIMIT_1
) |
1245 (~CBB_IOL_MASK
& 0xffffffff);
1246 size
= limit
-base
+ 1;
1249 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1254 /*===========================================================================*
1256 *===========================================================================*/
1257 static void record_bars(int devind
, int last_reg
)
1261 for (i
= 0, reg
= PCI_BAR
; reg
<= last_reg
; i
+= width
, reg
+= 4 * width
)
1263 width
= record_bar(devind
, i
, reg
== last_reg
);
1267 /*===========================================================================*
1269 *===========================================================================*/
1270 static int record_bar(devind
, bar_nr
, last
)
1275 int reg
, prefetch
, type
, dev_bar_nr
, width
;
1279 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
1282 reg
= PCI_BAR
+4*bar_nr
;
1284 bar
= pci_attr_r32_u(devind
, reg
);
1285 if (bar
& PCI_BAR_IO
)
1287 /* Disable I/O access before probing for BAR's size */
1288 cmd
= pci_attr_r16(devind
, PCI_CR
);
1289 pci_attr_w16(devind
, PCI_CR
, cmd
& ~PCI_CR_IO_EN
);
1291 /* Probe BAR's size */
1292 pci_attr_w32(devind
, reg
, 0xffffffff);
1293 bar2
= pci_attr_r32_u(devind
, reg
);
1295 /* Restore original state */
1296 pci_attr_w32(devind
, reg
, bar
);
1297 pci_attr_w16(devind
, PCI_CR
, cmd
);
1299 bar
&= PCI_BAR_IO_MASK
; /* Clear non-address bits */
1300 bar2
&= PCI_BAR_IO_MASK
;
1301 bar2
= (~bar2
& 0xffff)+1;
1304 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1308 dev_bar_nr
= pcidev
[devind
].pd_bar_nr
++;
1309 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
= PBF_IO
;
1310 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_base
= bar
;
1311 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_size
= bar2
;
1312 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_nr
= bar_nr
;
1315 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1321 type
= (bar
& PCI_BAR_TYPE
);
1325 case PCI_TYPE_32_1M
:
1329 /* A 64-bit BAR takes up two consecutive DWORDs. */
1332 printf("PCI: device %d.%d.%d BAR %d extends"
1333 " beyond designated area\n",
1334 pcidev
[devind
].pd_busnr
,
1335 pcidev
[devind
].pd_dev
,
1336 pcidev
[devind
].pd_func
, bar_nr
);
1342 bar2
= pci_attr_r32_u(devind
, reg
+4);
1344 /* If the upper 32 bits of the BAR are not zero, the
1345 * memory is inaccessible to us; ignore the BAR.
1351 printf("\tbar_%d: (64-bit BAR with"
1352 " high bits set)\n", bar_nr
);
1361 /* Ignore the BAR. */
1364 printf("\tbar_%d: (unknown type %x)\n",
1371 /* Disable mem access before probing for BAR's size */
1372 cmd
= pci_attr_r16(devind
, PCI_CR
);
1373 pci_attr_w16(devind
, PCI_CR
, cmd
& ~PCI_CR_MEM_EN
);
1375 /* Probe BAR's size */
1376 pci_attr_w32(devind
, reg
, 0xffffffff);
1377 bar2
= pci_attr_r32_u(devind
, reg
);
1379 /* Restore original values */
1380 pci_attr_w32(devind
, reg
, bar
);
1381 pci_attr_w16(devind
, PCI_CR
, cmd
);
1384 return width
; /* Reg. is not implemented */
1386 prefetch
= !!(bar
& PCI_BAR_PREFETCH
);
1387 bar
&= PCI_BAR_MEM_MASK
; /* Clear non-address bits */
1388 bar2
&= PCI_BAR_MEM_MASK
;
1392 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n",
1394 prefetch
? " prefetchable" : "",
1395 type
== PCI_TYPE_64
? ", 64-bit" : "");
1398 dev_bar_nr
= pcidev
[devind
].pd_bar_nr
++;
1399 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
= 0;
1400 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_base
= bar
;
1401 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_size
= bar2
;
1402 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_nr
= bar_nr
;
1405 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1413 /*===========================================================================*
1414 * complete_bridges *
1415 *===========================================================================*/
1416 static void complete_bridges()
1418 int i
, freebus
, devind
, prim_busnr
;
1420 for (i
= 0; i
<nr_pcibus
; i
++)
1422 if (!pcibus
[i
].pb_needinit
)
1424 printf("should allocate bus number for bus %d\n", i
);
1425 freebus
= get_freebus();
1426 printf("got bus number %d\n", freebus
);
1428 devind
= pcibus
[i
].pb_devind
;
1430 prim_busnr
= pcidev
[devind
].pd_busnr
;
1431 if (prim_busnr
!= 0)
1434 "complete_bridge: updating subordinate bus number not implemented\n");
1437 pcibus
[i
].pb_needinit
= 0;
1438 pcibus
[i
].pb_busnr
= freebus
;
1440 printf("devind = %d\n", devind
);
1441 printf("prim_busnr= %d\n", prim_busnr
);
1443 pci_attr_w8(devind
, PPB_PRIMBN
, prim_busnr
);
1444 pci_attr_w8(devind
, PPB_SECBN
, freebus
);
1445 pci_attr_w8(devind
, PPB_SUBORDBN
, freebus
);
1447 printf("CR = 0x%x\n", pci_attr_r16(devind
, PCI_CR
));
1448 printf("SECBLT = 0x%x\n", pci_attr_r8_u(devind
, PPB_SECBLT
));
1449 printf("BRIDGECTRL = 0x%x\n",
1450 pci_attr_r16(devind
, PPB_BRIDGECTRL
));
1454 /*===========================================================================*
1456 *===========================================================================*/
1457 static void complete_bars(void)
1459 int i
, j
, bar_nr
, reg
;
1460 u32_t memgap_low
, memgap_high
, iogap_low
, iogap_high
, io_high
,
1461 base
, size
, v32
, diff1
, diff2
;
1464 if(OK
!= sys_getkinfo(&kinfo
))
1465 panic("can't get kinfo");
1467 /* Set memgap_low to just above physical memory */
1468 memgap_low
= kinfo
.mem_high_phys
;
1469 memgap_high
= 0xfe000000; /* Leave space for the CPU (APIC) */
1473 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1474 memgap_low
, memgap_high
);
1477 /* Find the lowest memory base */
1478 for (i
= 0; i
<nr_pcidev
; i
++)
1480 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1482 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
)
1484 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1486 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1487 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1489 if (base
>= memgap_high
)
1490 continue; /* Not in the gap */
1491 if (base
+size
<= memgap_low
)
1492 continue; /* Not in the gap */
1494 /* Reduce the gap by the smallest amount */
1495 diff1
= base
+size
-memgap_low
;
1496 diff2
= memgap_high
-base
;
1499 memgap_low
= base
+size
;
1507 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1508 memgap_low
, memgap_high
);
1511 /* Should check main memory size */
1512 if (memgap_high
< memgap_low
)
1514 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1515 memgap_low
, memgap_high
);
1519 iogap_high
= 0x10000;
1522 /* Find the free I/O space */
1523 for (i
= 0; i
<nr_pcidev
; i
++)
1525 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1527 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
))
1529 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1531 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1532 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1533 if (base
>= iogap_high
)
1535 if (base
+size
<= iogap_low
)
1541 "pci device %d (%04x:%04x), bar %d: base 0x%x, size 0x%x\n",
1542 i
, pcidev
[i
].pd_vid
, pcidev
[i
].pd_did
,
1546 if (base
+size
-iogap_low
< iogap_high
-base
)
1547 iogap_low
= base
+size
;
1553 if (iogap_high
< iogap_low
)
1557 printf("iogap_high too low, should panic\n");
1560 panic("iogap_high too low: %d", iogap_high
);
1563 printf("I/O range = [0x%x..0x%x>\n", iogap_low
, iogap_high
);
1565 for (i
= 0; i
<nr_pcidev
; i
++)
1567 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1569 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
)
1571 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1573 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1574 if (size
< PAGE_SIZE
)
1576 base
= memgap_high
-size
;
1577 base
&= ~(u32_t
)(size
-1);
1578 if (base
< memgap_low
)
1579 panic("memory base too low: %d", base
);
1581 bar_nr
= pcidev
[i
].pd_bar
[j
].pb_nr
;
1582 reg
= PCI_BAR
+ 4*bar_nr
;
1583 v32
= pci_attr_r32_u(i
, reg
);
1584 pci_attr_w32(i
, reg
, v32
| base
);
1588 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1589 base
, size
, pcidev
[i
].pd_busnr
,
1590 pcidev
[i
].pd_dev
, pcidev
[i
].pd_func
,
1593 pcidev
[i
].pd_bar
[j
].pb_base
= base
;
1594 pcidev
[i
].pd_bar
[j
].pb_flags
&= ~PBF_INCOMPLETE
;
1597 io_high
= iogap_high
;
1598 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1600 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
))
1602 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1604 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1605 base
= iogap_high
-size
;
1606 base
&= ~(u32_t
)(size
-1);
1608 /* Assume that ISA compatibility is required. Only
1609 * use the lowest 256 bytes out of every 1024 bytes.
1613 if (base
< iogap_low
)
1614 panic("I/O base too low: %d", base
);
1617 bar_nr
= pcidev
[i
].pd_bar
[j
].pb_nr
;
1618 reg
= PCI_BAR
+ 4*bar_nr
;
1619 v32
= pci_attr_r32_u(i
, reg
);
1620 pci_attr_w32(i
, reg
, v32
| base
);
1624 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1625 base
, size
, pcidev
[i
].pd_busnr
,
1626 pcidev
[i
].pd_dev
, pcidev
[i
].pd_func
,
1629 pcidev
[i
].pd_bar
[j
].pb_base
= base
;
1630 pcidev
[i
].pd_bar
[j
].pb_flags
&= ~PBF_INCOMPLETE
;
1633 if (iogap_high
!= io_high
)
1635 update_bridge4dev_io(i
, iogap_high
,
1636 io_high
-iogap_high
);
1640 for (i
= 0; i
<nr_pcidev
; i
++)
1642 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1644 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1646 printf("should allocate resources for device %d\n", i
);
1652 /*===========================================================================*
1653 * update_bridge4dev_io *
1654 *===========================================================================*/
1655 static void update_bridge4dev_io(
1661 int busnr
, busind
, type
, br_devind
;
1664 busnr
= pcidev
[devind
].pd_busnr
;
1665 busind
= get_busind(busnr
);
1666 type
= pcibus
[busind
].pb_type
;
1667 if (type
== PBT_INTEL_HOST
)
1668 return; /* Nothing to do for host controller */
1669 if (type
== PBT_PCIBRIDGE
)
1672 "update_bridge4dev_io: not implemented for PCI bridges\n");
1675 if (type
!= PBT_CARDBUS
)
1676 panic("update_bridge4dev_io: strange bus type: %d", type
);
1680 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1683 br_devind
= pcibus
[busind
].pb_devind
;
1684 pci_attr_w32(br_devind
, CBB_IOLIMIT_0
, io_base
+io_size
-1);
1685 pci_attr_w32(br_devind
, CBB_IOBASE_0
, io_base
);
1687 /* Enable I/O access. Enable busmaster access as well. */
1688 v16
= pci_attr_r16(devind
, PCI_CR
);
1689 pci_attr_w16(devind
, PCI_CR
, v16
| PCI_CR_IO_EN
| PCI_CR_MAST_EN
);
1692 /*===========================================================================*
1694 *===========================================================================*/
1695 static int get_freebus()
1700 for (i
= 0; i
<nr_pcibus
; i
++)
1702 if (pcibus
[i
].pb_needinit
)
1704 if (pcibus
[i
].pb_type
== PBT_INTEL_HOST
)
1706 if (pcibus
[i
].pb_busnr
<= freebus
)
1707 freebus
= pcibus
[i
].pb_busnr
+1;
1708 printf("get_freebus: should check suboridinate bus number\n");
1713 /*===========================================================================*
1715 *===========================================================================*/
1716 static int do_isabridge(busind
)
1719 int i
, j
, r
, type
, busnr
, unknown_bridge
, bridge_dev
;
1727 vid
= did
= 0; /* lint */
1728 busnr
= pcibus
[busind
].pb_busnr
;
1729 for (i
= 0; i
< nr_pcidev
; i
++)
1731 if (pcidev
[i
].pd_busnr
!= busnr
)
1733 t3
= ((pcidev
[i
].pd_baseclass
<< 16) |
1734 (pcidev
[i
].pd_subclass
<< 8) | pcidev
[i
].pd_infclass
);
1735 if (t3
== PCI_T3_ISA
)
1737 /* ISA bridge. Report if no supported bridge is
1743 vid
= pcidev
[i
].pd_vid
;
1744 did
= pcidev
[i
].pd_did
;
1745 for (j
= 0; pci_isabridge
[j
].vid
!= 0; j
++)
1747 if (pci_isabridge
[j
].vid
!= vid
)
1749 if (pci_isabridge
[j
].did
!= did
)
1751 if (pci_isabridge
[j
].checkclass
&&
1752 unknown_bridge
!= i
)
1754 /* This part of multifunction device is
1761 if (pci_isabridge
[j
].vid
)
1768 if (bridge_dev
!= -1)
1770 dstr
= pci_dev_name(vid
, did
);
1772 dstr
= "unknown device";
1775 printf("found ISA bridge (%04X:%04X) %s\n",
1778 pcibus
[busind
].pb_isabridge_dev
= bridge_dev
;
1779 type
= pci_isabridge
[j
].type
;
1780 pcibus
[busind
].pb_isabridge_type
= type
;
1784 r
= do_piix(bridge_dev
);
1787 r
= do_via_isabr(bridge_dev
);
1790 r
= do_amd_isabr(bridge_dev
);
1793 r
= do_sis_isabr(bridge_dev
);
1796 panic("unknown ISA bridge type: %d", type
);
1801 if (unknown_bridge
== -1)
1805 printf("(warning) no ISA bridge found on bus %d\n",
1813 "(warning) unsupported ISA bridge %04X:%04X for bus %d\n",
1814 pcidev
[unknown_bridge
].pd_vid
,
1815 pcidev
[unknown_bridge
].pd_did
, busind
);
1821 * tells acpi which two busses are connected by this bridge. The primary bus
1822 * (pbnr) must be already known to acpi and it must map dev as the connection to
1823 * the secondary (sbnr) bus
1825 static void acpi_map_bridge(unsigned pbnr
, unsigned dev
, unsigned sbnr
)
1830 ((struct acpi_map_bridge_req
*)&m
)->hdr
.request
= ACPI_REQ_MAP_BRIDGE
;
1831 ((struct acpi_map_bridge_req
*)&m
)->primary_bus
= pbnr
;
1832 ((struct acpi_map_bridge_req
*)&m
)->secondary_bus
= sbnr
;
1833 ((struct acpi_map_bridge_req
*)&m
)->device
= dev
;
1835 if ((err
= ipc_sendrec(acpi_ep
, &m
)) != OK
)
1836 panic("PCI: error %d while receiveing from ACPI\n", err
);
1838 if (((struct acpi_map_bridge_resp
*)&m
)->err
!= OK
)
1839 printf("PCI: acpi failed to map pci (%d) to pci (%d) bridge\n",
1843 /*===========================================================================*
1845 *===========================================================================*/
1846 static void do_pcibridge(busind
)
1849 int i
, devind
, busnr
;
1852 u8_t sbusn
, baseclass
, subclass
, infclass
, headt
;
1855 vid
= did
= 0; /* lint */
1856 busnr
= pcibus
[busind
].pb_busnr
;
1857 for (devind
= 0; devind
< nr_pcidev
; devind
++)
1860 printf("do_pcibridge: trying %u.%u.%u\n",
1861 pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
1862 pcidev
[devind
].pd_func
);
1865 if (pcidev
[devind
].pd_busnr
!= busnr
)
1868 printf("wrong bus\n");
1873 vid
= pcidev
[devind
].pd_vid
;
1874 did
= pcidev
[devind
].pd_did
;
1875 for (i
= 0; pci_pcibridge
[i
].vid
!= 0; i
++)
1877 if (pci_pcibridge
[i
].vid
!= vid
)
1879 if (pci_pcibridge
[i
].did
!= did
)
1883 type
= pci_pcibridge
[i
].type
;
1884 if (pci_pcibridge
[i
].vid
== 0)
1886 headt
= pci_attr_r8_u(devind
, PCI_HEADT
);
1888 if ((headt
& PHT_MASK
) == PHT_BRIDGE
)
1890 else if ((headt
& PHT_MASK
) == PHT_CARDBUS
)
1895 printf("not a bridge\n");
1897 continue; /* Not a bridge */
1900 baseclass
= pci_attr_r8_u(devind
, PCI_BCR
);
1901 subclass
= pci_attr_r8_u(devind
, PCI_SCR
);
1902 infclass
= pci_attr_r8_u(devind
, PCI_PIFR
);
1903 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
1904 if (type
== PCI_PPB_STD
&&
1905 t3
!= PCI_T3_PCI2PCI
&&
1906 t3
!= PCI_T3_PCI2PCI_SUBTR
)
1909 "Unknown PCI class %02x/%02x/%02x for PCI-to-PCI bridge, device %04X:%04X\n",
1910 baseclass
, subclass
, infclass
,
1914 if (type
== PCI_PPB_CB
&&
1915 t3
!= PCI_T3_CARDBUS
)
1918 "Unknown PCI class %02x/%02x/%02x for Cardbus bridge, device %04X:%04X\n",
1919 baseclass
, subclass
, infclass
,
1927 printf("%u.%u.%u: PCI-to-PCI bridge: %04X:%04X\n",
1928 pcidev
[devind
].pd_busnr
,
1929 pcidev
[devind
].pd_dev
,
1930 pcidev
[devind
].pd_func
, vid
, did
);
1933 /* Assume that the BIOS initialized the secondary bus
1936 sbusn
= pci_attr_r8_u(devind
, PPB_SECBN
);
1938 if (nr_pcibus
>= NR_PCIBUS
)
1939 panic("too many PCI busses: %d", nr_pcibus
);
1942 pcibus
[ind
].pb_type
= PBT_PCIBRIDGE
;
1943 pcibus
[ind
].pb_needinit
= 1;
1944 pcibus
[ind
].pb_isabridge_dev
= -1;
1945 pcibus
[ind
].pb_isabridge_type
= 0;
1946 pcibus
[ind
].pb_devind
= devind
;
1947 pcibus
[ind
].pb_busnr
= sbusn
;
1948 pcibus
[ind
].pb_rreg8
= pcibus
[busind
].pb_rreg8
;
1949 pcibus
[ind
].pb_rreg16
= pcibus
[busind
].pb_rreg16
;
1950 pcibus
[ind
].pb_rreg32
= pcibus
[busind
].pb_rreg32
;
1951 pcibus
[ind
].pb_wreg8
= pcibus
[busind
].pb_wreg8
;
1952 pcibus
[ind
].pb_wreg16
= pcibus
[busind
].pb_wreg16
;
1953 pcibus
[ind
].pb_wreg32
= pcibus
[busind
].pb_wreg32
;
1957 pcibus
[ind
].pb_rsts
= pcibr_std_rsts
;
1958 pcibus
[ind
].pb_wsts
= pcibr_std_wsts
;
1961 pcibus
[ind
].pb_type
= PBT_CARDBUS
;
1962 pcibus
[ind
].pb_rsts
= pcibr_cb_rsts
;
1963 pcibus
[ind
].pb_wsts
= pcibr_cb_wsts
;
1966 pcibus
[ind
].pb_rsts
= pcibr_via_rsts
;
1967 pcibus
[ind
].pb_wsts
= pcibr_via_wsts
;
1970 panic("unknown PCI-PCI bridge type: %d", type
);
1973 if (machine
.apic_enabled
)
1974 acpi_map_bridge(pcidev
[devind
].pd_busnr
,
1975 pcidev
[devind
].pd_dev
, sbusn
);
1980 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1981 ind
, sbusn
, pci_attr_r8_u(devind
, PPB_SUBORDBN
));
1985 printf("Secondary bus number not initialized\n");
1988 pcibus
[ind
].pb_needinit
= 0;
1992 /* Look for PCI bridges */
1997 /*===========================================================================*
1999 *===========================================================================*/
2000 static int get_busind(busnr
)
2005 for (i
= 0; i
<nr_pcibus
; i
++)
2007 if (pcibus
[i
].pb_busnr
== busnr
)
2010 panic("get_busind: can't find bus: %d", busnr
);
2013 /*===========================================================================*
2015 *===========================================================================*/
2016 static int do_piix(int devind
)
2018 int i
, s
, irqrc
, irq
;
2019 u32_t elcr1
, elcr2
, elcr
;
2022 printf("in piix\n");
2024 if (OK
!= (s
=sys_inb(PIIX_ELCR1
, &elcr1
)))
2025 printf("Warning, sys_inb failed: %d\n", s
);
2026 if (OK
!= (s
=sys_inb(PIIX_ELCR2
, &elcr2
)))
2027 printf("Warning, sys_inb failed: %d\n", s
);
2028 elcr
= elcr1
| (elcr2
<< 8);
2029 for (i
= 0; i
<4; i
++)
2031 irqrc
= pci_attr_r8_u(devind
, PIIX_PIRQRCA
+i
);
2032 if (irqrc
& PIIX_IRQ_DI
)
2035 printf("INT%c: disabled\n", 'A'+i
);
2039 irq
= irqrc
& PIIX_IRQ_MASK
;
2041 printf("INT%c: %d\n", 'A'+i
, irq
);
2042 if (!(elcr
& (1 << irq
)))
2047 "(warning) IRQ %d is not level triggered\n",
2057 /*===========================================================================*
2059 *===========================================================================*/
2060 static int do_amd_isabr(int devind
)
2062 int i
, busnr
, dev
, func
, xdevind
, irq
, edge
;
2066 /* Find required function */
2067 func
= AMD_ISABR_FUNC
;
2068 busnr
= pcidev
[devind
].pd_busnr
;
2069 dev
= pcidev
[devind
].pd_dev
;
2071 /* Fake a device with the required function */
2072 if (nr_pcidev
>= NR_PCIDEV
)
2073 panic("too many PCI devices: %d", nr_pcidev
);
2075 pcidev
[xdevind
].pd_busnr
= busnr
;
2076 pcidev
[xdevind
].pd_dev
= dev
;
2077 pcidev
[xdevind
].pd_func
= func
;
2078 pcidev
[xdevind
].pd_inuse
= 1;
2081 levmask
= pci_attr_r8_u(xdevind
, AMD_ISABR_PCIIRQ_LEV
);
2082 pciirq
= pci_attr_r16(xdevind
, AMD_ISABR_PCIIRQ_ROUTE
);
2083 for (i
= 0; i
<4; i
++)
2085 edge
= (levmask
>> i
) & 1;
2086 irq
= (pciirq
>> (4*i
)) & 0xf;
2090 printf("INT%c: disabled\n", 'A'+i
);
2095 printf("INT%c: %d\n", 'A'+i
, irq
);
2099 "(warning) IRQ %d is not level triggered\n",
2109 /*===========================================================================*
2111 *===========================================================================*/
2112 static int do_sis_isabr(int devind
)
2117 for (i
= 0; i
<4; i
++)
2119 irq
= pci_attr_r8_u(devind
, SIS_ISABR_IRQ_A
+i
);
2120 if (irq
& SIS_IRQ_DISABLED
)
2123 printf("INT%c: disabled\n", 'A'+i
);
2127 irq
&= SIS_IRQ_MASK
;
2129 printf("INT%c: %d\n", 'A'+i
, irq
);
2136 /*===========================================================================*
2138 *===========================================================================*/
2139 static int do_via_isabr(int devind
)
2144 levmask
= pci_attr_r8_u(devind
, VIA_ISABR_EL
);
2147 for (i
= 0; i
<4; i
++)
2152 edge
= (levmask
& VIA_ISABR_EL_INTA
);
2153 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R2
) >> 4;
2156 edge
= (levmask
& VIA_ISABR_EL_INTB
);
2157 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R2
);
2160 edge
= (levmask
& VIA_ISABR_EL_INTC
);
2161 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R3
) >> 4;
2164 edge
= (levmask
& VIA_ISABR_EL_INTD
);
2165 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R1
) >> 4;
2174 printf("INT%c: disabled\n", 'A'+i
);
2179 printf("INT%c: %d\n", 'A'+i
, irq
);
2183 "(warning) IRQ %d is not level triggered\n",
2194 /*===========================================================================*
2196 *===========================================================================*/
2197 static void report_vga(devind
)
2200 /* Report the amount of video memory. This is needed by the X11R6
2201 * postinstall script to chmem the X server. Hopefully this can be
2202 * removed when we get virtual memory.
2204 size_t amount
, size
;
2208 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
2210 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
)
2212 size
= pcidev
[devind
].pd_bar
[i
].pb_size
;
2219 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
2220 pcidev
[devind
].pd_busnr
,
2221 pcidev
[devind
].pd_dev
,
2222 pcidev
[devind
].pd_func
,
2229 /*===========================================================================*
2231 *===========================================================================*/
2232 static char *pci_vid_name(u16_t vid
)
2236 for (i
= 0; pci_vendor_table
[i
].name
; i
++)
2238 if (pci_vendor_table
[i
].vid
== vid
)
2239 return pci_vendor_table
[i
].name
;
2244 /*===========================================================================*
2245 * pci_baseclass_name *
2246 *===========================================================================*/
2247 static char *pci_baseclass_name(u8_t baseclass
)
2251 for (i
= 0; pci_baseclass_table
[i
].name
; i
++)
2253 if (pci_baseclass_table
[i
].baseclass
== baseclass
)
2254 return pci_baseclass_table
[i
].name
;
2259 /*===========================================================================*
2260 * pci_subclass_name *
2261 *===========================================================================*/
2262 static char *pci_subclass_name(u8_t baseclass
, u8_t subclass
, u8_t infclass
)
2266 for (i
= 0; pci_subclass_table
[i
].name
; i
++)
2268 if (pci_subclass_table
[i
].baseclass
!= baseclass
)
2270 if (pci_subclass_table
[i
].subclass
!= subclass
)
2272 if (pci_subclass_table
[i
].infclass
!= infclass
&&
2273 pci_subclass_table
[i
].infclass
!= (u16_t
)-1)
2277 return pci_subclass_table
[i
].name
;
2282 /*===========================================================================*
2284 *===========================================================================*/
2285 static void ntostr(n
, str
, end
)
2302 tmpstr
[i
]= '0' + (n
%10);
2321 /*===========================================================================*
2323 *===========================================================================*/
2324 static u16_t
pci_attr_rsts(devind
)
2329 busnr
= pcidev
[devind
].pd_busnr
;
2330 busind
= get_busind(busnr
);
2331 return pcibus
[busind
].pb_rsts(busind
);
2335 /*===========================================================================*
2337 *===========================================================================*/
2338 static u16_t
pcibr_std_rsts(busind
)
2343 devind
= pcibus
[busind
].pb_devind
;
2344 return pci_attr_r16(devind
, PPB_SSTS
);
2347 /*===========================================================================*
2349 *===========================================================================*/
2350 static void pcibr_std_wsts(int busind
, u16_t value
)
2353 devind
= pcibus
[busind
].pb_devind
;
2356 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2357 busind
, value
, devind
);
2359 pci_attr_w16(devind
, PPB_SSTS
, value
);
2362 /*===========================================================================*
2364 *===========================================================================*/
2365 static u16_t
pcibr_cb_rsts(busind
)
2369 devind
= pcibus
[busind
].pb_devind
;
2371 return pci_attr_r16(devind
, CBB_SSTS
);
2374 /*===========================================================================*
2376 *===========================================================================*/
2377 static void pcibr_cb_wsts(int busind
, u16_t value
)
2380 devind
= pcibus
[busind
].pb_devind
;
2383 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2384 busind
, value
, devind
);
2386 pci_attr_w16(devind
, CBB_SSTS
, value
);
2389 /*===========================================================================*
2391 *===========================================================================*/
2392 static u16_t
pcibr_via_rsts(int busind
)
2397 /*===========================================================================*
2399 *===========================================================================*/
2400 static void pcibr_via_wsts(int busind
, u16_t value
)
2403 devind
= pcibus
[busind
].pb_devind
;
2406 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2407 busind
, value
, devind
);
2411 /*===========================================================================*
2413 *===========================================================================*/
2414 static void pci_attr_wsts(int devind
, u16_t value
)
2418 busnr
= pcidev
[devind
].pd_busnr
;
2419 busind
= get_busind(busnr
);
2420 pcibus
[busind
].pb_wsts(busind
, value
);
2424 /*===========================================================================*
2426 *===========================================================================*/
2427 static u8_t
pcii_rreg8(busind
, devind
, port
)
2435 v
= PCII_RREG8_(pcibus
[busind
].pb_busnr
,
2436 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2438 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2439 printf("PCI: warning, sys_outl failed: %d\n", s
);
2441 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2442 busind
, devind
, port
,
2443 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2444 pcidev
[devind
].pd_func
, v
);
2449 /*===========================================================================*
2451 *===========================================================================*/
2452 static u16_t
pcii_rreg16(int busind
, int devind
, int port
)
2457 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
,
2458 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2460 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2461 printf("PCI: warning, sys_outl failed: %d\n", s
);
2463 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2464 busind
, devind
, port
,
2465 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2466 pcidev
[devind
].pd_func
, v
);
2471 /*===========================================================================*
2473 *===========================================================================*/
2474 static u32_t
pcii_rreg32(int busind
, int devind
, int port
)
2479 v
= PCII_RREG32_(pcibus
[busind
].pb_busnr
,
2480 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2482 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2483 printf("PCI: warning, sys_outl failed: %d\n", s
);
2485 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2486 busind
, devind
, port
,
2487 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2488 pcidev
[devind
].pd_func
, v
);
2493 /*===========================================================================*
2495 *===========================================================================*/
2496 static void pcii_wreg8(
2505 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2506 busind
, devind
, port
, value
,
2507 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2508 pcidev
[devind
].pd_func
);
2510 PCII_WREG8_(pcibus
[busind
].pb_busnr
,
2511 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2513 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2514 printf("PCI: warning, sys_outl failed: %d\n", s
);
2517 /*===========================================================================*
2519 *===========================================================================*/
2520 static void pcii_wreg16(
2529 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2530 busind
, devind
, port
, value
,
2531 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2532 pcidev
[devind
].pd_func
);
2534 PCII_WREG16_(pcibus
[busind
].pb_busnr
,
2535 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2537 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2538 printf("PCI: warning, sys_outl failed: %d\n", s
);
2541 /*===========================================================================*
2543 *===========================================================================*/
2544 static void pcii_wreg32(
2553 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2554 busind
, devind
, port
, value
,
2555 pcibus
[busind
].pb_busnr
, pcidev
[devind
].pd_dev
,
2556 pcidev
[devind
].pd_func
);
2558 PCII_WREG32_(pcibus
[busind
].pb_busnr
,
2559 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2561 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2562 printf("PCI: warning, sys_outl failed: %d\n",s
);
2565 /*===========================================================================*
2567 *===========================================================================*/
2568 static u16_t
pcii_rsts(int busind
)
2573 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
, 0, 0, PCI_SR
);
2574 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2575 printf("PCI: warning, sys_outl failed: %d\n", s
);
2579 /*===========================================================================*
2581 *===========================================================================*/
2582 static void pcii_wsts(int busind
, u16_t value
)
2585 PCII_WREG16_(pcibus
[busind
].pb_busnr
, 0, 0, PCI_SR
, value
);
2586 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2587 printf("PCI: warning, sys_outl failed: %d\n", s
);
2591 /*===========================================================================*
2592 * print_capabilities *
2593 *===========================================================================*/
2594 static void print_capabilities(int devind
)
2596 u8_t status
, capptr
, type
, next
, subtype
;
2599 /* Check capabilities bit in the device status register */
2600 status
= pci_attr_r16(devind
, PCI_SR
);
2601 if (!(status
& PSR_CAPPTR
))
2604 capptr
= (pci_attr_r8_u(devind
, PCI_CAPPTR
) & PCI_CP_MASK
);
2607 type
= pci_attr_r8_u(devind
, capptr
+CAP_TYPE
);
2608 next
= (pci_attr_r8_u(devind
, capptr
+CAP_NEXT
) & PCI_CP_MASK
);
2611 case 1: str
= "PCI Power Management"; break;
2612 case 2: str
= "AGP"; break;
2613 case 3: str
= "Vital Product Data"; break;
2614 case 4: str
= "Slot Identification"; break;
2615 case 5: str
= "Message Signaled Interrupts"; break;
2616 case 6: str
= "CompactPCI Hot Swap"; break;
2617 case 8: str
= "AMD HyperTransport"; break;
2618 case 0xf: str
= "Secure Device"; break;
2619 default: str
= "(unknown type)"; break;
2622 printf(" @0x%x (0x%08x): capability type 0x%x: %s",
2623 capptr
, pci_attr_r32_u(devind
, capptr
), type
, str
);
2625 print_hyper_cap(devind
, capptr
);
2626 else if (type
== 0x0f)
2628 subtype
= (pci_attr_r8_u(devind
, capptr
+2) & 0x07);
2631 case 0: str
= "Device Exclusion Vector"; break;
2632 case 3: str
= "IOMMU"; break;
2633 default: str
= "(unknown type)"; break;
2635 printf(", sub type 0%o: %s", subtype
, str
);
2643 /*===========================================================================*
2645 *===========================================================================*/
2646 static int visible(aclp
, devind
)
2647 struct rs_pci
*aclp
;
2650 u16_t acl_sub_vid
, acl_sub_did
;
2655 return TRUE
; /* Should be changed when ACLs become
2656 * mandatory. Do note that procfs relies
2657 * on being able to see all devices.
2659 /* Check whether the caller is allowed to get this device. */
2660 for (i
= 0; i
<aclp
->rsp_nr_device
; i
++)
2662 acl_sub_vid
= aclp
->rsp_device
[i
].sub_vid
;
2663 acl_sub_did
= aclp
->rsp_device
[i
].sub_did
;
2664 if (aclp
->rsp_device
[i
].vid
== pcidev
[devind
].pd_vid
&&
2665 aclp
->rsp_device
[i
].did
== pcidev
[devind
].pd_did
&&
2666 (acl_sub_vid
== NO_SUB_VID
||
2667 acl_sub_vid
== pcidev
[devind
].pd_sub_vid
) &&
2668 (acl_sub_did
== NO_SUB_DID
||
2669 acl_sub_did
== pcidev
[devind
].pd_sub_did
))
2674 if (!aclp
->rsp_nr_class
)
2677 class_id
= (pcidev
[devind
].pd_baseclass
<< 16) |
2678 (pcidev
[devind
].pd_subclass
<< 8) |
2679 pcidev
[devind
].pd_infclass
;
2680 for (i
= 0; i
<aclp
->rsp_nr_class
; i
++)
2682 if (aclp
->rsp_class
[i
].pciclass
==
2683 (class_id
& aclp
->rsp_class
[i
].mask
))
2692 /*===========================================================================*
2694 *===========================================================================*/
2695 static void print_hyper_cap(int devind
, u8_t capptr
)
2702 v
= pci_attr_r32_u(devind
, capptr
);
2703 printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr
);
2704 cmd
= (v
>> 16) & 0xffff;
2708 printf(" WarmReset");
2713 printf(" DblEnded");
2716 printf(" DevNum %d", (v
& 0x7C0000) >> 18);
2719 type0
= (cmd
& 0xE000) >> 13;
2720 type1
= (cmd
& 0xF800) >> 11;
2721 if (type0
== 0 || type0
== 1)
2723 printf("Capability Type: %s\n",
2724 type0
== 0 ? "Slave or Primary Interface" :
2725 "Host or Secondary Interface");
2730 printf(" Capability Type 0x%x", type1
);
2734 printf(" undecoded 0x%x\n", cmd
);
2737 printf("print_hyper_cap: off 4 (ctl): 0x%x\n",
2738 pci_attr_r32_u(devind
, capptr
+4));
2739 printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n",
2740 pci_attr_r32_u(devind
, capptr
+8));
2741 printf("print_hyper_cap: off 12 (cap): 0x%x\n",
2742 pci_attr_r32_u(devind
, capptr
+12));
2743 printf("print_hyper_cap: off 16 (buf count): 0x%x\n",
2744 pci_attr_r32_u(devind
, capptr
+16));
2745 v
= pci_attr_r32_u(devind
, capptr
+20);
2746 printf("print_hyper_cap: @0x%x, off 20 (bus nr): ",
2748 printf("prim %d", v
& 0xff);
2749 printf(", sec %d", (v
>> 8) & 0xff);
2750 printf(", sub %d", (v
>> 16) & 0xff);
2752 printf(", reserved %d", (v
>> 24) & 0xff);
2754 printf("print_hyper_cap: off 24 (type): 0x%x\n",
2755 pci_attr_r32_u(devind
, capptr
+24));
2760 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $