5 Configure devices on the PCI bus
7 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
10 #include "../drivers.h"
13 #include <sys/vm_i386.h>
14 #include <minix/com.h>
15 #include <minix/syslib.h>
19 #include "pci_intel.h"
27 #define irq_mode_pci(irq) ((void)0)
33 #include <minix/sysutil.h>
35 #define PBT_INTEL_HOST 1
36 #define PBT_PCIBRIDGE 2
39 #define BAM_NR 6 /* Number of base-address registers */
48 int pb_isabridge_type
;
52 u8_t (*pb_rreg8
)(int busind
, int devind
, int port
);
53 u16_t (*pb_rreg16
)(int busind
, int devind
, int port
);
54 u32_t (*pb_rreg32
)(int busind
, int devind
, int port
);
55 void (*pb_wreg8
)(int busind
, int devind
, int port
, U8_t value
);
56 void (*pb_wreg16
)(int busind
, int devind
, int port
, U16_t value
);
57 void (*pb_wreg32
)(int busind
, int devind
, int port
, u32_t value
);
58 u16_t (*pb_rsts
)(int busind
);
59 void (*pb_wsts
)(int busind
, U16_t value
);
61 PRIVATE
int nr_pcibus
= 0;
88 EXTERN
struct pci_acl pci_acl
[NR_DRIVERS
];
91 #define PBF_IO 1 /* I/O else memory */
92 #define PBF_INCOMPLETE 2 /* not allocated */
94 PRIVATE
int nr_pcidev
= 0;
96 FORWARD
_PROTOTYPE( void pci_intel_init
, (void) );
97 FORWARD
_PROTOTYPE( void probe_bus
, (int busind
) );
98 FORWARD
_PROTOTYPE( int is_duplicate
, (U8_t busnr
, U8_t dev
, U8_t func
) );
99 FORWARD
_PROTOTYPE( void record_irq
, (int devind
) );
100 FORWARD
_PROTOTYPE( void record_bars_normal
, (int devind
) );
101 FORWARD
_PROTOTYPE( void record_bars_bridge
, (int devind
) );
102 FORWARD
_PROTOTYPE( void record_bars_cardbus
, (int devind
) );
103 FORWARD
_PROTOTYPE( void record_bars
, (int devind
, int last_reg
) );
104 FORWARD
_PROTOTYPE( int record_bar
, (int devind
, int bar_nr
, int last
) );
105 FORWARD
_PROTOTYPE( void complete_bridges
, (void) );
106 FORWARD
_PROTOTYPE( void complete_bars
, (void) );
107 FORWARD
_PROTOTYPE( void update_bridge4dev_io
, (int devind
,
108 u32_t io_base
, u32_t io_size
) );
109 FORWARD
_PROTOTYPE( int get_freebus
, (void) );
110 FORWARD
_PROTOTYPE( int do_isabridge
, (int busind
) );
111 FORWARD
_PROTOTYPE( void do_pcibridge
, (int busind
) );
112 FORWARD
_PROTOTYPE( int get_busind
, (int busnr
) );
113 FORWARD
_PROTOTYPE( int do_piix
, (int devind
) );
114 FORWARD
_PROTOTYPE( int do_amd_isabr
, (int devind
) );
115 FORWARD
_PROTOTYPE( int do_sis_isabr
, (int devind
) );
116 FORWARD
_PROTOTYPE( int do_via_isabr
, (int devind
) );
118 FORWARD
_PROTOTYPE( void report_vga
, (int devind
) );
120 FORWARD
_PROTOTYPE( char *pci_vid_name
, (U16_t vid
) );
121 FORWARD
_PROTOTYPE( char *pci_baseclass_name
, (U8_t baseclass
) );
122 FORWARD
_PROTOTYPE( char *pci_subclass_name
, (U8_t baseclass
,
123 U8_t subclass
, U8_t infclass
) );
124 FORWARD
_PROTOTYPE( void ntostr
, (unsigned n
, char **str
, char *end
) );
126 FORWARD
_PROTOTYPE( u8_t pci_attr_r8_u
, (int devind
, int port
) );
127 FORWARD
_PROTOTYPE( u32_t pci_attr_r32_u
, (int devind
, int port
) );
129 FORWARD
_PROTOTYPE( u16_t pci_attr_rsts
, (int devind
) );
130 FORWARD
_PROTOTYPE( void pci_attr_wsts
, (int devind
, U16_t value
) );
131 FORWARD
_PROTOTYPE( u16_t pcibr_std_rsts
, (int busind
) );
132 FORWARD
_PROTOTYPE( void pcibr_std_wsts
, (int busind
, U16_t value
) );
133 FORWARD
_PROTOTYPE( u16_t pcibr_cb_rsts
, (int busind
) );
134 FORWARD
_PROTOTYPE( void pcibr_cb_wsts
, (int busind
, U16_t value
) );
135 FORWARD
_PROTOTYPE( u16_t pcibr_via_rsts
, (int busind
) );
136 FORWARD
_PROTOTYPE( void pcibr_via_wsts
, (int busind
, U16_t value
) );
137 FORWARD
_PROTOTYPE( u8_t pcii_rreg8
, (int busind
, int devind
, int port
) );
138 FORWARD
_PROTOTYPE( u16_t pcii_rreg16
, (int busind
, int devind
,
140 FORWARD
_PROTOTYPE( u32_t pcii_rreg32
, (int busind
, int devind
,
142 FORWARD
_PROTOTYPE( void pcii_wreg8
, (int busind
, int devind
, int port
,
144 FORWARD
_PROTOTYPE( void pcii_wreg16
, (int busind
, int devind
, int port
,
146 FORWARD
_PROTOTYPE( void pcii_wreg32
, (int busind
, int devind
, int port
,
148 FORWARD
_PROTOTYPE( u16_t pcii_rsts
, (int busind
) );
149 FORWARD
_PROTOTYPE( void pcii_wsts
, (int busind
, U16_t value
) );
150 FORWARD
_PROTOTYPE( void print_capabilities
, (int devind
) );
151 FORWARD
_PROTOTYPE( int visible
, (struct rs_pci
*aclp
, int devind
) );
152 FORWARD
_PROTOTYPE( void print_hyper_cap
, (int devind
, U8_t capptr
) );
154 /*===========================================================================*
155 * sef_cb_init_fresh *
156 *===========================================================================*/
157 PUBLIC
int sef_cb_init_fresh(int type
, sef_init_info_t
*info
)
159 /* Initialize the pci driver. */
162 struct rprocpub rprocpub
[NR_BOOT_PROCS
];
165 env_parse("pci_debug", "d", 0, &v
, 0, 1);
168 /* Only Intel (compatible) PCI controllers are supported at the
173 /* Map all the services in the boot image. */
174 if((r
= sys_safecopyfrom(RS_PROC_NR
, info
->rproctab_gid
, 0,
175 (vir_bytes
) rprocpub
, sizeof(rprocpub
), S
)) != OK
) {
176 panic("pci", "sys_safecopyfrom failed", r
);
178 for(i
=0;i
< NR_BOOT_PROCS
;i
++) {
179 if(rprocpub
[i
].in_use
) {
180 if((r
= map_service(&rprocpub
[i
])) != OK
) {
181 panic("pci", "unable to map service", r
);
189 /*===========================================================================*
191 *===========================================================================*/
192 PUBLIC
int map_service(rpub
)
193 struct rprocpub
*rpub
;
195 /* Map a new service by registering a new acl entry if required. */
198 /* Stop right now if no pci device or class is found. */
199 if(rpub
->pci_acl
.rsp_nr_device
== 0
200 && rpub
->pci_acl
.rsp_nr_class
== 0) {
204 /* Find a free acl slot. */
205 for (i
= 0; i
<NR_DRIVERS
; i
++)
207 if (!pci_acl
[i
].inuse
)
212 printf("PCI: map_service: table is full\n");
216 /* Initialize acl slot. */
217 pci_acl
[i
].inuse
= 1;
218 pci_acl
[i
].acl
= rpub
->pci_acl
;
223 /*===========================================================================*
224 * helper functions for I/O *
225 *===========================================================================*/
226 PUBLIC
unsigned pci_inb(U16_t port
) {
229 if ((s
=sys_inb(port
, &value
)) !=OK
)
230 printf("PCI: warning, sys_inb failed: %d\n", s
);
233 PUBLIC
unsigned pci_inw(U16_t port
) {
236 if ((s
=sys_inw(port
, &value
)) !=OK
)
237 printf("PCI: warning, sys_inw failed: %d\n", s
);
240 PUBLIC
unsigned pci_inl(U16_t port
) {
243 if ((s
=sys_inl(port
, &value
)) !=OK
)
244 printf("PCI: warning, sys_inl failed: %d\n", s
);
247 PUBLIC
void pci_outb(U16_t port
, U8_t value
) {
249 if ((s
=sys_outb(port
, value
)) !=OK
)
250 printf("PCI: warning, sys_outb failed: %d\n", s
);
252 PUBLIC
void pci_outw(U16_t port
, U16_t value
) {
254 if ((s
=sys_outw(port
, value
)) !=OK
)
255 printf("PCI: warning, sys_outw failed: %d\n", s
);
257 PUBLIC
void pci_outl(U16_t port
, U32_t value
) {
259 if ((s
=sys_outl(port
, value
)) !=OK
)
260 printf("PCI: warning, sys_outl failed: %d\n", s
);
263 /*===========================================================================*
265 *===========================================================================*/
266 PUBLIC
int pci_find_dev(bus
, dev
, func
, devindp
)
274 for (devind
= 0; devind
< nr_pcidev
; devind
++)
276 if (pcidev
[devind
].pd_busnr
== bus
&&
277 pcidev
[devind
].pd_dev
== dev
&&
278 pcidev
[devind
].pd_func
== func
)
283 if (devind
>= nr_pcidev
)
286 if (pcidev
[devind
].pd_inuse
)
293 /*===========================================================================*
295 *===========================================================================*/
296 PUBLIC
int pci_first_dev_a(aclp
, devindp
, vidp
, didp
)
304 for (devind
= 0; devind
< nr_pcidev
; devind
++)
307 if (pcidev
[devind
].pd_inuse
)
310 if (!visible(aclp
, devind
))
314 if (devind
>= nr_pcidev
)
317 *vidp
= pcidev
[devind
].pd_vid
;
318 *didp
= pcidev
[devind
].pd_did
;
322 /*===========================================================================*
324 *===========================================================================*/
325 PUBLIC
int pci_next_dev_a(aclp
, devindp
, vidp
, didp
)
333 for (devind
= *devindp
+1; devind
< nr_pcidev
; devind
++)
336 if (pcidev
[devind
].pd_inuse
)
339 if (!visible(aclp
, devind
))
343 if (devind
>= nr_pcidev
)
346 *vidp
= pcidev
[devind
].pd_vid
;
347 *didp
= pcidev
[devind
].pd_did
;
351 /*===========================================================================*
353 *===========================================================================*/
354 PUBLIC
int pci_reserve2(devind
, proc
)
363 if (devind
< 0 || devind
>= nr_pcidev
)
365 printf("pci:pci_reserve2: bad devind: %d\n", devind
);
368 if(pcidev
[devind
].pd_inuse
)
370 pcidev
[devind
].pd_inuse
= 1;
371 pcidev
[devind
].pd_proc
= proc
;
373 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
375 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_INCOMPLETE
)
377 printf("pci_reserve3: BAR %d is incomplete\n", i
);
380 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
)
382 ior
.ior_base
= pcidev
[devind
].pd_bar
[i
].pb_base
;
383 ior
.ior_limit
= ior
.ior_base
+
384 pcidev
[devind
].pd_bar
[i
].pb_size
-1;
388 "pci_reserve3: for proc %d, adding I/O range [0x%x..0x%x]\n",
389 proc
, ior
.ior_base
, ior
.ior_limit
);
391 r
= sys_privctl(proc
, SYS_PRIV_ADD_IO
, &ior
);
394 printf("sys_privctl failed for proc %d: %d\n",
400 mr
.mr_base
= pcidev
[devind
].pd_bar
[i
].pb_base
;
401 mr
.mr_limit
= mr
.mr_base
+
402 pcidev
[devind
].pd_bar
[i
].pb_size
-1;
404 r
= sys_privctl(proc
, SYS_PRIV_ADD_MEM
, &mr
);
407 printf("sys_privctl failed for proc %d: %d\n",
412 ilr
= pcidev
[devind
].pd_ilr
;
413 if (ilr
!= PCI_ILR_UNKNOWN
)
415 if(debug
) printf("pci_reserve3: adding IRQ %d\n", ilr
);
416 r
= sys_privctl(proc
, SYS_PRIV_ADD_IRQ
, &ilr
);
419 printf("sys_privctl failed for proc %d: %d\n",
427 /*===========================================================================*
429 *===========================================================================*/
430 PUBLIC
void pci_release(proc
)
435 for (i
= 0; i
<nr_pcidev
; i
++)
437 if (!pcidev
[i
].pd_inuse
)
439 if (pcidev
[i
].pd_proc
!= proc
)
441 pcidev
[i
].pd_inuse
= 0;
445 /*===========================================================================*
447 *===========================================================================*/
448 PUBLIC
int pci_ids_s(devind
, vidp
, didp
)
453 if (devind
< 0 || devind
>= nr_pcidev
)
456 *vidp
= pcidev
[devind
].pd_vid
;
457 *didp
= pcidev
[devind
].pd_did
;
461 /*===========================================================================*
463 *===========================================================================*/
464 PUBLIC
void pci_rescan_bus(busnr
)
469 busind
= get_busind(busnr
);
472 /* Allocate bus numbers for uninitialized bridges */
475 /* Allocate I/O and memory resources for uninitialized devices */
479 /*===========================================================================*
481 *===========================================================================*/
482 PUBLIC
int pci_slot_name_s(devind
, cpp
)
486 static char label
[]= "ddd.ddd.ddd";
490 if (devind
< 0 || devind
>= nr_pcidev
)
494 end
= label
+sizeof(label
);
496 ntostr(pcidev
[devind
].pd_busnr
, &p
, end
);
499 ntostr(pcidev
[devind
].pd_dev
, &p
, end
);
502 ntostr(pcidev
[devind
].pd_func
, &p
, end
);
508 /*===========================================================================*
510 *===========================================================================*/
511 PUBLIC
char *pci_dev_name(vid
, did
)
517 for (i
= 0; pci_device_table
[i
].name
; i
++)
519 if (pci_device_table
[i
].vid
== vid
&&
520 pci_device_table
[i
].did
== did
)
522 return pci_device_table
[i
].name
;
528 /*===========================================================================*
530 *===========================================================================*/
531 PUBLIC
int pci_attr_r8_s(devind
, port
, vp
)
536 if (devind
< 0 || devind
>= nr_pcidev
)
538 if (port
< 0 || port
> 255)
541 *vp
= pci_attr_r8_u(devind
, port
);
545 /*===========================================================================*
547 *===========================================================================*/
548 PRIVATE u8_t
pci_attr_r8_u(devind
, port
)
554 busnr
= pcidev
[devind
].pd_busnr
;
555 busind
= get_busind(busnr
);
556 return pcibus
[busind
].pb_rreg8(busind
, devind
, port
);
559 /*===========================================================================*
561 *===========================================================================*/
562 PUBLIC u16_t
pci_attr_r16(devind
, port
)
568 busnr
= pcidev
[devind
].pd_busnr
;
569 busind
= get_busind(busnr
);
570 return pcibus
[busind
].pb_rreg16(busind
, devind
, port
);
573 /*===========================================================================*
575 *===========================================================================*/
576 PUBLIC
int pci_attr_r32_s(devind
, port
, vp
)
581 if (devind
< 0 || devind
>= nr_pcidev
)
583 if (port
< 0 || port
> 256-4)
586 *vp
= pci_attr_r32_u(devind
, port
);
590 /*===========================================================================*
592 *===========================================================================*/
593 PRIVATE u32_t
pci_attr_r32_u(devind
, port
)
599 busnr
= pcidev
[devind
].pd_busnr
;
600 busind
= get_busind(busnr
);
601 return pcibus
[busind
].pb_rreg32(busind
, devind
, port
);
604 /*===========================================================================*
606 *===========================================================================*/
607 PUBLIC
void pci_attr_w8(devind
, port
, value
)
614 busnr
= pcidev
[devind
].pd_busnr
;
615 busind
= get_busind(busnr
);
616 pcibus
[busind
].pb_wreg8(busind
, devind
, port
, value
);
619 /*===========================================================================*
621 *===========================================================================*/
622 PUBLIC
void pci_attr_w16(devind
, port
, value
)
629 busnr
= pcidev
[devind
].pd_busnr
;
630 busind
= get_busind(busnr
);
631 pcibus
[busind
].pb_wreg16(busind
, devind
, port
, value
);
634 /*===========================================================================*
636 *===========================================================================*/
637 PUBLIC
void pci_attr_w32(devind
, port
, value
)
644 busnr
= pcidev
[devind
].pd_busnr
;
645 busind
= get_busind(busnr
);
646 pcibus
[busind
].pb_wreg32(busind
, devind
, port
, value
);
649 /*===========================================================================*
651 *===========================================================================*/
652 PRIVATE
void pci_intel_init()
654 /* Try to detect a know PCI controller. Read the Vendor ID and
655 * the Device ID for function 0 of device 0.
656 * Two times the value 0xffff suggests a system without a (compatible)
659 u32_t bus
, dev
, func
;
661 int s
, i
, r
, busind
, busnr
;
668 vid
= PCII_RREG16_(bus
, dev
, func
, PCI_VID
);
669 did
= PCII_RREG16_(bus
, dev
, func
, PCI_DID
);
671 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
672 printf("PCI: warning, sys_outl failed: %d\n", s
);
674 outl(PCII_CONFADD
, PCII_UNSEL
);
677 if (vid
== 0xffff && did
== 0xffff)
678 return; /* Nothing here */
681 for (i
= 0; pci_intel_ctrl
[i
].vid
; i
++)
683 if (pci_intel_ctrl
[i
].vid
== vid
&&
684 pci_intel_ctrl
[i
].did
== did
)
690 if (!pci_intel_ctrl
[i
].vid
)
692 printf("pci_intel_init (warning): unknown PCI-controller:\n"
693 "\tvendor %04X (%s), device %04X\n",
694 vid
, pci_vid_name(vid
), did
);
698 if (nr_pcibus
>= NR_PCIBUS
)
699 panic("PCI","too many PCI busses", nr_pcibus
);
702 pcibus
[busind
].pb_type
= PBT_INTEL_HOST
;
703 pcibus
[busind
].pb_needinit
= 0;
704 pcibus
[busind
].pb_isabridge_dev
= -1;
705 pcibus
[busind
].pb_isabridge_type
= 0;
706 pcibus
[busind
].pb_devind
= -1;
707 pcibus
[busind
].pb_busnr
= 0;
708 pcibus
[busind
].pb_rreg8
= pcii_rreg8
;
709 pcibus
[busind
].pb_rreg16
= pcii_rreg16
;
710 pcibus
[busind
].pb_rreg32
= pcii_rreg32
;
711 pcibus
[busind
].pb_wreg8
= pcii_wreg8
;
712 pcibus
[busind
].pb_wreg16
= pcii_wreg16
;
713 pcibus
[busind
].pb_wreg32
= pcii_wreg32
;
714 pcibus
[busind
].pb_rsts
= pcii_rsts
;
715 pcibus
[busind
].pb_wsts
= pcii_wsts
;
717 dstr
= pci_dev_name(vid
, did
);
719 dstr
= "unknown device";
722 printf("pci_intel_init: %s (%04X/%04X)\n",
728 r
= do_isabridge(busind
);
731 busnr
= pcibus
[busind
].pb_busnr
;
733 /* Disable all devices for this bus */
734 for (i
= 0; i
<nr_pcidev
; i
++)
736 if (pcidev
[i
].pd_busnr
!= busnr
)
738 pcidev
[i
].pd_inuse
= 1;
743 /* Look for PCI bridges */
744 do_pcibridge(busind
);
746 /* Allocate bus numbers for uninitialized bridges */
749 /* Allocate I/O and memory resources for uninitialized devices */
753 /*===========================================================================*
755 *===========================================================================*/
756 PRIVATE
void probe_bus(busind
)
762 u8_t baseclass
, subclass
, infclass
;
767 printf("probe_bus(%d)\n", busind
);
769 if (nr_pcidev
>= NR_PCIDEV
)
770 panic("PCI","too many PCI devices", nr_pcidev
);
773 busnr
= pcibus
[busind
].pb_busnr
;
774 for (dev
= 0; dev
<32; dev
++)
777 for (func
= 0; func
< 8; func
++)
779 pcidev
[devind
].pd_busnr
= busnr
;
780 pcidev
[devind
].pd_dev
= dev
;
781 pcidev
[devind
].pd_func
= func
;
783 pci_attr_wsts(devind
,
784 PSR_SSE
|PSR_RMAS
|PSR_RTAS
);
785 vid
= pci_attr_r16(devind
, PCI_VID
);
786 did
= pci_attr_r16(devind
, PCI_DID
);
787 headt
= pci_attr_r8_u(devind
, PCI_HEADT
);
788 sts
= pci_attr_rsts(devind
);
791 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
792 vid
, did
, headt
, sts
);
795 if (vid
== NO_VID
&& did
== NO_VID
)
798 break; /* Nothing here */
800 /* Scan all functions of a multifunction
806 if (sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
))
809 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
810 sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
));
813 dstr
= pci_dev_name(vid
, did
);
818 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
819 busind
, (unsigned long)dev
,
820 (unsigned long)func
, dstr
,
826 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
827 busind
, (unsigned long)dev
,
828 (unsigned long)func
, vid
,
829 pci_vid_name(vid
), did
);
831 printf("Device index: %d\n", devind
);
832 printf("Subsystem: Vid 0x%x, did 0x%x\n",
833 pci_attr_r16(devind
, PCI_SUBVID
),
834 pci_attr_r16(devind
, PCI_SUBDID
));
837 baseclass
= pci_attr_r8_u(devind
, PCI_BCR
);
838 subclass
= pci_attr_r8_u(devind
, PCI_SCR
);
839 infclass
= pci_attr_r8_u(devind
, PCI_PIFR
);
840 s
= pci_subclass_name(baseclass
, subclass
, infclass
);
842 s
= pci_baseclass_name(baseclass
);
845 s
= "(unknown class)";
849 printf("\tclass %s (%X/%X/%X)\n", s
,
850 baseclass
, subclass
, infclass
);
853 if (is_duplicate(busnr
, dev
, func
))
855 printf("\tduplicate!\n");
856 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
863 pcidev
[devind
].pd_baseclass
= baseclass
;
864 pcidev
[devind
].pd_subclass
= subclass
;
865 pcidev
[devind
].pd_infclass
= infclass
;
866 pcidev
[devind
].pd_vid
= vid
;
867 pcidev
[devind
].pd_did
= did
;
868 pcidev
[devind
].pd_inuse
= 0;
869 pcidev
[devind
].pd_bar_nr
= 0;
871 switch(headt
& PHT_MASK
)
874 record_bars_normal(devind
);
877 record_bars_bridge(devind
);
880 record_bars_cardbus(devind
);
883 printf("\t%d.%d.%d: unknown header type %d\n",
889 print_capabilities(devind
);
891 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
893 if (t3
== PCI_T3_VGA
|| t3
== PCI_T3_VGA_OLD
)
897 if (nr_pcidev
>= NR_PCIDEV
)
898 panic("PCI","too many PCI devices", nr_pcidev
);
901 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
907 /*===========================================================================*
909 *===========================================================================*/
910 PRIVATE
int is_duplicate(busnr
, dev
, func
)
917 for (i
= 0; i
<nr_pcidev
; i
++)
919 if (pcidev
[i
].pd_busnr
== busnr
&&
920 pcidev
[i
].pd_dev
== dev
&&
921 pcidev
[i
].pd_func
== func
)
929 /*===========================================================================*
931 *===========================================================================*/
932 PRIVATE
void record_irq(devind
)
935 int ilr
, ipr
, busnr
, busind
, cb_devind
;
937 ilr
= pci_attr_r8_u(devind
, PCI_ILR
);
938 ipr
= pci_attr_r8_u(devind
, PCI_IPR
);
942 if (ipr
&& first
&& debug
)
945 printf("PCI: strange, BIOS assigned IRQ0\n");
947 ilr
= PCI_ILR_UNKNOWN
;
949 pcidev
[devind
].pd_ilr
= ilr
;
950 if (ilr
== PCI_ILR_UNKNOWN
&& !ipr
)
953 else if (ilr
!= PCI_ILR_UNKNOWN
&& ipr
)
956 printf("\tIRQ %d for INT%c\n", ilr
, 'A' + ipr
-1);
958 else if (ilr
!= PCI_ILR_UNKNOWN
)
961 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
962 ilr
, pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
963 pcidev
[devind
].pd_func
);
967 /* Check for cardbus devices */
968 busnr
= pcidev
[devind
].pd_busnr
;
969 busind
= get_busind(busnr
);
970 if (pcibus
[busind
].pb_type
== PBT_CARDBUS
)
972 cb_devind
= pcibus
[busind
].pb_devind
;
973 ilr
= pcidev
[cb_devind
].pd_ilr
;
974 if (ilr
!= PCI_ILR_UNKNOWN
)
979 "assigning IRQ %d to Cardbus device\n",
982 pci_attr_w8(devind
, PCI_ILR
, ilr
);
983 pcidev
[devind
].pd_ilr
= ilr
;
989 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
990 pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
991 pcidev
[devind
].pd_func
, 'A' + ipr
-1);
996 /*===========================================================================*
997 * record_bars_normal *
998 *===========================================================================*/
999 PRIVATE
void record_bars_normal(devind
)
1002 int i
, j
, clear_01
, clear_23
, pb_nr
;
1004 /* The BAR area of normal devices is six DWORDs in size. */
1005 record_bars(devind
, PCI_BAR_6
);
1007 /* Special case code for IDE controllers in compatibility mode */
1008 if (pcidev
[devind
].pd_baseclass
== PCI_BCR_MASS_STORAGE
&&
1009 pcidev
[devind
].pd_subclass
== PCI_MS_IDE
)
1014 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_PRI_NATIVE
))
1019 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1023 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_SEC_NATIVE
))
1028 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
1034 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
1036 pb_nr
= pcidev
[devind
].pd_bar
[i
].pb_nr
;
1037 if ((pb_nr
== 0 || pb_nr
== 1) && clear_01
)
1039 if (debug
) printf("skipping bar %d\n", pb_nr
);
1040 continue; /* Skip */
1042 if ((pb_nr
== 2 || pb_nr
== 3) && clear_23
)
1044 if (debug
) printf("skipping bar %d\n", pb_nr
);
1045 continue; /* Skip */
1050 continue; /* No need to copy */
1052 pcidev
[devind
].pd_bar
[j
]=
1053 pcidev
[devind
].pd_bar
[i
];
1056 pcidev
[devind
].pd_bar_nr
= j
;
1060 /*===========================================================================*
1061 * record_bars_bridge *
1062 *===========================================================================*/
1063 PRIVATE
void record_bars_bridge(devind
)
1066 u32_t base
, limit
, size
;
1068 /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
1069 * It may contain up to two 32-bit BARs, or one 64-bit BAR.
1071 record_bars(devind
, PCI_BAR_2
);
1073 base
= ((pci_attr_r8_u(devind
, PPB_IOBASE
) & PPB_IOB_MASK
) << 8) |
1074 (pci_attr_r16(devind
, PPB_IOBASEU16
) << 16);
1076 ((pci_attr_r8_u(devind
, PPB_IOLIMIT
) & PPB_IOL_MASK
) << 8) |
1077 ((~PPB_IOL_MASK
& 0xff) << 8) |
1078 (pci_attr_r16(devind
, PPB_IOLIMITU16
) << 16);
1079 size
= limit
-base
+ 1;
1082 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1086 base
= ((pci_attr_r16(devind
, PPB_MEMBASE
) & PPB_MEMB_MASK
) << 16);
1088 ((pci_attr_r16(devind
, PPB_MEMLIMIT
) & PPB_MEML_MASK
) << 16) |
1089 ((~PPB_MEML_MASK
& 0xffff) << 16);
1090 size
= limit
-base
+ 1;
1093 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1097 /* Ignore the upper 32 bits */
1098 base
= ((pci_attr_r16(devind
, PPB_PFMEMBASE
) & PPB_PFMEMB_MASK
) << 16);
1100 ((pci_attr_r16(devind
, PPB_PFMEMLIMIT
) &
1101 PPB_PFMEML_MASK
) << 16) |
1102 ((~PPB_PFMEML_MASK
& 0xffff) << 16);
1103 size
= limit
-base
+ 1;
1107 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1112 /*===========================================================================*
1113 * record_bars_cardbus *
1114 *===========================================================================*/
1115 PRIVATE
void record_bars_cardbus(devind
)
1118 u32_t base
, limit
, size
;
1120 /* The generic BAR area of CardBus devices is one DWORD in size. */
1121 record_bars(devind
, PCI_BAR
);
1123 base
= pci_attr_r32_u(devind
, CBB_MEMBASE_0
);
1124 limit
= pci_attr_r32_u(devind
, CBB_MEMLIMIT_0
) |
1125 (~CBB_MEML_MASK
& 0xffffffff);
1126 size
= limit
-base
+ 1;
1129 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1133 base
= pci_attr_r32_u(devind
, CBB_MEMBASE_1
);
1134 limit
= pci_attr_r32_u(devind
, CBB_MEMLIMIT_1
) |
1135 (~CBB_MEML_MASK
& 0xffffffff);
1136 size
= limit
-base
+ 1;
1139 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1143 base
= pci_attr_r32_u(devind
, CBB_IOBASE_0
);
1144 limit
= pci_attr_r32_u(devind
, CBB_IOLIMIT_0
) |
1145 (~CBB_IOL_MASK
& 0xffffffff);
1146 size
= limit
-base
+ 1;
1149 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1153 base
= pci_attr_r32_u(devind
, CBB_IOBASE_1
);
1154 limit
= pci_attr_r32_u(devind
, CBB_IOLIMIT_1
) |
1155 (~CBB_IOL_MASK
& 0xffffffff);
1156 size
= limit
-base
+ 1;
1159 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1164 /*===========================================================================*
1166 *===========================================================================*/
1167 PRIVATE
void record_bars(devind
, last_reg
)
1171 for (i
= 0, reg
= PCI_BAR
; reg
<= last_reg
; i
+= width
, reg
+= 4 * width
)
1173 width
= record_bar(devind
, i
, reg
== last_reg
);
1177 /*===========================================================================*
1179 *===========================================================================*/
1180 PRIVATE
int record_bar(devind
, bar_nr
, last
)
1185 int reg
, prefetch
, type
, dev_bar_nr
, width
;
1189 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
1192 reg
= PCI_BAR
+4*bar_nr
;
1194 bar
= pci_attr_r32_u(devind
, reg
);
1195 if (bar
& PCI_BAR_IO
)
1197 /* Disable I/O access before probing for BAR's size */
1198 cmd
= pci_attr_r16(devind
, PCI_CR
);
1199 pci_attr_w16(devind
, PCI_CR
, cmd
& ~PCI_CR_IO_EN
);
1201 /* Probe BAR's size */
1202 pci_attr_w32(devind
, reg
, 0xffffffff);
1203 bar2
= pci_attr_r32_u(devind
, reg
);
1205 /* Restore original state */
1206 pci_attr_w32(devind
, reg
, bar
);
1207 pci_attr_w16(devind
, PCI_CR
, cmd
);
1209 bar
&= ~(u32_t
)3; /* Clear non-address bits */
1211 bar2
= (~bar2
& 0xffff)+1;
1214 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1218 dev_bar_nr
= pcidev
[devind
].pd_bar_nr
++;
1219 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
= PBF_IO
;
1220 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_base
= bar
;
1221 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_size
= bar2
;
1222 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_nr
= bar_nr
;
1225 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1231 type
= (bar
& PCI_BAR_TYPE
);
1235 case PCI_TYPE_32_1M
:
1239 /* A 64-bit BAR takes up two consecutive DWORDs. */
1242 printf("PCI: device %d.%d.%d BAR %d extends"
1243 " beyond designated area\n",
1244 pcidev
[devind
].pd_busnr
,
1245 pcidev
[devind
].pd_dev
,
1246 pcidev
[devind
].pd_func
, bar_nr
);
1252 bar2
= pci_attr_r32_u(devind
, reg
+4);
1254 /* If the upper 32 bits of the BAR are not zero, the
1255 * memory is inaccessible to us; ignore the BAR.
1261 printf("\tbar_%d: (64-bit BAR with"
1262 " high bits set)\n", bar_nr
);
1271 /* Ignore the BAR. */
1274 printf("\tbar_%d: (unknown type %x)\n",
1281 /* Disable mem access before probing for BAR's size */
1282 cmd
= pci_attr_r16(devind
, PCI_CR
);
1283 pci_attr_w16(devind
, PCI_CR
, cmd
& ~PCI_CR_MEM_EN
);
1285 /* Probe BAR's size */
1286 pci_attr_w32(devind
, reg
, 0xffffffff);
1287 bar2
= pci_attr_r32_u(devind
, reg
);
1289 /* Restore original values */
1290 pci_attr_w32(devind
, reg
, bar
);
1291 pci_attr_w16(devind
, PCI_CR
, cmd
);
1294 return width
; /* Reg. is not implemented */
1296 prefetch
= !!(bar
& PCI_BAR_PREFETCH
);
1297 bar
&= ~(u32_t
)0xf; /* Clear non-address bits */
1298 bar2
&= ~(u32_t
)0xf;
1302 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n",
1304 prefetch
? " prefetchable" : "",
1305 type
== PCI_TYPE_64
? ", 64-bit" : "");
1308 dev_bar_nr
= pcidev
[devind
].pd_bar_nr
++;
1309 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
= 0;
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
|=
1323 /*===========================================================================*
1324 * complete_bridges *
1325 *===========================================================================*/
1326 PRIVATE
void complete_bridges()
1328 int i
, freebus
, devind
, prim_busnr
;
1330 for (i
= 0; i
<nr_pcibus
; i
++)
1332 if (!pcibus
[i
].pb_needinit
)
1334 printf("should allocate bus number for bus %d\n", i
);
1335 freebus
= get_freebus();
1336 printf("got bus number %d\n", freebus
);
1338 devind
= pcibus
[i
].pb_devind
;
1340 prim_busnr
= pcidev
[devind
].pd_busnr
;
1341 if (prim_busnr
!= 0)
1344 "complete_bridge: updating subordinate bus number not implemented\n");
1347 pcibus
[i
].pb_needinit
= 0;
1348 pcibus
[i
].pb_busnr
= freebus
;
1350 printf("devind = %d\n", devind
);
1351 printf("prim_busnr= %d\n", prim_busnr
);
1353 pci_attr_w8(devind
, PPB_PRIMBN
, prim_busnr
);
1354 pci_attr_w8(devind
, PPB_SECBN
, freebus
);
1355 pci_attr_w8(devind
, PPB_SUBORDBN
, freebus
);
1357 printf("CR = 0x%x\n", pci_attr_r16(devind
, PCI_CR
));
1358 printf("SECBLT = 0x%x\n", pci_attr_r8_u(devind
, PPB_SECBLT
));
1359 printf("BRIDGECTRL = 0x%x\n",
1360 pci_attr_r16(devind
, PPB_BRIDGECTRL
));
1364 /*===========================================================================*
1366 *===========================================================================*/
1367 PRIVATE
void complete_bars(void)
1369 int i
, j
, r
, bar_nr
, reg
;
1370 u32_t memgap_low
, memgap_high
, iogap_low
, iogap_high
, io_high
,
1371 base
, size
, v32
, diff1
, diff2
;
1375 r
= env_get_param("memory", memstr
, sizeof(memstr
));
1377 panic("pci", "env_get_param failed", r
);
1379 /* Set memgap_low to just above physical memory */
1384 base
= strtoul(cp
, &next
, 16);
1385 if (!(*next
) || next
== cp
|| *next
!= ':')
1386 goto bad_mem_string
;
1388 size
= strtoul(cp
, &next
, 16);
1389 if (next
== cp
|| (*next
!= ',' && *next
!= '\0'))
1391 goto bad_mem_string
;
1392 if (base
+size
> memgap_low
)
1393 memgap_low
= base
+size
;
1401 memgap_high
= 0xfe000000; /* Leave space for the CPU (APIC) */
1405 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1406 memgap_low
, memgap_high
);
1409 /* Find the lowest memory base */
1410 for (i
= 0; i
<nr_pcidev
; i
++)
1412 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1414 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
)
1416 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1418 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1419 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1421 if (base
>= memgap_high
)
1422 continue; /* Not in the gap */
1423 if (base
+size
<= memgap_low
)
1424 continue; /* Not in the gap */
1426 /* Reduce the gap by the smallest amount */
1427 diff1
= base
+size
-memgap_low
;
1428 diff2
= memgap_high
-base
;
1431 memgap_low
= base
+size
;
1439 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1440 memgap_low
, memgap_high
);
1443 /* Should check main memory size */
1444 if (memgap_high
< memgap_low
)
1446 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1447 memgap_low
, memgap_high
);
1448 panic(NULL
, NULL
, NO_NUM
);
1451 iogap_high
= 0x10000;
1454 /* Find the free I/O space */
1455 for (i
= 0; i
<nr_pcidev
; i
++)
1457 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1459 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
))
1461 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1463 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1464 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1465 if (base
>= iogap_high
)
1467 if (base
+size
<= iogap_low
)
1473 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
1474 i
, pcidev
[i
].pd_vid
, pcidev
[i
].pd_did
,
1478 if (base
+size
-iogap_low
< iogap_high
-base
)
1479 iogap_low
= base
+size
;
1485 if (iogap_high
< iogap_low
)
1489 printf("iogap_high too low, should panic\n");
1492 panic("pci", "iogap_high too low", iogap_high
);
1495 printf("I/O range = [0x%x..0x%x>\n", iogap_low
, iogap_high
);
1497 for (i
= 0; i
<nr_pcidev
; i
++)
1499 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1501 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
)
1503 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1505 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1506 if (size
< I386_PAGE_SIZE
)
1507 size
= I386_PAGE_SIZE
;
1508 base
= memgap_high
-size
;
1509 base
&= ~(u32_t
)(size
-1);
1510 if (base
< memgap_low
)
1511 panic("pci", "memory base too low", base
);
1513 bar_nr
= pcidev
[i
].pd_bar
[j
].pb_nr
;
1514 reg
= PCI_BAR
+ 4*bar_nr
;
1515 v32
= pci_attr_r32_u(i
, reg
);
1516 pci_attr_w32(i
, reg
, v32
| base
);
1520 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1521 base
, size
, pcidev
[i
].pd_busnr
,
1522 pcidev
[i
].pd_dev
, pcidev
[i
].pd_func
,
1525 pcidev
[i
].pd_bar
[j
].pb_base
= base
;
1526 pcidev
[i
].pd_bar
[j
].pb_flags
&= ~PBF_INCOMPLETE
;
1529 io_high
= iogap_high
;
1530 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1532 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
))
1534 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1536 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1537 base
= iogap_high
-size
;
1538 base
&= ~(u32_t
)(size
-1);
1540 /* Assume that ISA compatibility is required. Only
1541 * use the lowest 256 bytes out of every 1024 bytes.
1545 if (base
< iogap_low
)
1546 panic("pci", "I/O base too low", base
);
1549 bar_nr
= pcidev
[i
].pd_bar
[j
].pb_nr
;
1550 reg
= PCI_BAR
+ 4*bar_nr
;
1551 v32
= pci_attr_r32_u(i
, reg
);
1552 pci_attr_w32(i
, reg
, v32
| base
);
1556 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1557 base
, size
, pcidev
[i
].pd_busnr
,
1558 pcidev
[i
].pd_dev
, pcidev
[i
].pd_func
,
1561 pcidev
[i
].pd_bar
[j
].pb_base
= base
;
1562 pcidev
[i
].pd_bar
[j
].pb_flags
&= ~PBF_INCOMPLETE
;
1565 if (iogap_high
!= io_high
)
1567 update_bridge4dev_io(i
, iogap_high
,
1568 io_high
-iogap_high
);
1572 for (i
= 0; i
<nr_pcidev
; i
++)
1574 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1576 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1578 printf("should allocate resources for device %d\n", i
);
1584 printf("PCI: bad memory environment string '%s'\n", memstr
);
1585 panic(NULL
, NULL
, NO_NUM
);
1588 /*===========================================================================*
1589 * update_bridge4dev_io *
1590 *===========================================================================*/
1591 PRIVATE
void update_bridge4dev_io(devind
, io_base
, io_size
)
1596 int busnr
, busind
, type
, br_devind
;
1599 busnr
= pcidev
[devind
].pd_busnr
;
1600 busind
= get_busind(busnr
);
1601 type
= pcibus
[busind
].pb_type
;
1602 if (type
== PBT_INTEL_HOST
)
1603 return; /* Nothing to do for host controller */
1604 if (type
== PBT_PCIBRIDGE
)
1607 "update_bridge4dev_io: not implemented for PCI bridges\n");
1610 if (type
!= PBT_CARDBUS
)
1611 panic("pci", "update_bridge4dev_io: strange bus type", type
);
1615 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1618 br_devind
= pcibus
[busind
].pb_devind
;
1619 pci_attr_w32(br_devind
, CBB_IOLIMIT_0
, io_base
+io_size
-1);
1620 pci_attr_w32(br_devind
, CBB_IOBASE_0
, io_base
);
1622 /* Enable I/O access. Enable busmaster access as well. */
1623 v16
= pci_attr_r16(devind
, PCI_CR
);
1624 pci_attr_w16(devind
, PCI_CR
, v16
| PCI_CR_IO_EN
| PCI_CR_MAST_EN
);
1627 /*===========================================================================*
1629 *===========================================================================*/
1630 PRIVATE
int get_freebus()
1635 for (i
= 0; i
<nr_pcibus
; i
++)
1637 if (pcibus
[i
].pb_needinit
)
1639 if (pcibus
[i
].pb_type
== PBT_INTEL_HOST
)
1641 if (pcibus
[i
].pb_busnr
<= freebus
)
1642 freebus
= pcibus
[i
].pb_busnr
+1;
1643 printf("get_freebus: should check suboridinate bus number\n");
1648 /*===========================================================================*
1650 *===========================================================================*/
1651 PRIVATE
int do_isabridge(busind
)
1654 int i
, j
, r
, type
, busnr
, unknown_bridge
, bridge_dev
;
1662 vid
= did
= 0; /* lint */
1663 busnr
= pcibus
[busind
].pb_busnr
;
1664 for (i
= 0; i
< nr_pcidev
; i
++)
1666 if (pcidev
[i
].pd_busnr
!= busnr
)
1668 t3
= ((pcidev
[i
].pd_baseclass
<< 16) |
1669 (pcidev
[i
].pd_subclass
<< 8) | pcidev
[i
].pd_infclass
);
1670 if (t3
== PCI_T3_ISA
)
1672 /* ISA bridge. Report if no supported bridge is
1678 vid
= pcidev
[i
].pd_vid
;
1679 did
= pcidev
[i
].pd_did
;
1680 for (j
= 0; pci_isabridge
[j
].vid
!= 0; j
++)
1682 if (pci_isabridge
[j
].vid
!= vid
)
1684 if (pci_isabridge
[j
].did
!= did
)
1686 if (pci_isabridge
[j
].checkclass
&&
1687 unknown_bridge
!= i
)
1689 /* This part of multifunction device is
1696 if (pci_isabridge
[j
].vid
)
1703 if (bridge_dev
!= -1)
1705 dstr
= pci_dev_name(vid
, did
);
1707 dstr
= "unknown device";
1710 printf("found ISA bridge (%04X/%04X) %s\n",
1713 pcibus
[busind
].pb_isabridge_dev
= bridge_dev
;
1714 type
= pci_isabridge
[j
].type
;
1715 pcibus
[busind
].pb_isabridge_type
= type
;
1719 r
= do_piix(bridge_dev
);
1722 r
= do_via_isabr(bridge_dev
);
1725 r
= do_amd_isabr(bridge_dev
);
1728 r
= do_sis_isabr(bridge_dev
);
1731 panic("PCI","unknown ISA bridge type", type
);
1736 if (unknown_bridge
== -1)
1740 printf("(warning) no ISA bridge found on bus %d\n",
1748 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
1749 pcidev
[unknown_bridge
].pd_vid
,
1750 pcidev
[unknown_bridge
].pd_did
, busind
);
1755 /*===========================================================================*
1757 *===========================================================================*/
1758 PRIVATE
void do_pcibridge(busind
)
1761 int i
, devind
, busnr
;
1764 u8_t sbusn
, baseclass
, subclass
, infclass
, headt
;
1767 vid
= did
= 0; /* lint */
1768 busnr
= pcibus
[busind
].pb_busnr
;
1769 for (devind
= 0; devind
< nr_pcidev
; devind
++)
1772 printf("do_pcibridge: trying %u.%u.%u\n",
1773 pcidev
[devind
].pd_busind
, pcidev
[devind
].pd_dev
,
1774 pcidev
[devind
].pd_func
);
1777 if (pcidev
[devind
].pd_busnr
!= busnr
)
1780 printf("wrong bus\n");
1785 vid
= pcidev
[devind
].pd_vid
;
1786 did
= pcidev
[devind
].pd_did
;
1787 for (i
= 0; pci_pcibridge
[i
].vid
!= 0; i
++)
1789 if (pci_pcibridge
[i
].vid
!= vid
)
1791 if (pci_pcibridge
[i
].did
!= did
)
1795 type
= pci_pcibridge
[i
].type
;
1796 if (pci_pcibridge
[i
].vid
== 0)
1798 headt
= pci_attr_r8_u(devind
, PCI_HEADT
);
1800 if ((headt
& PHT_MASK
) == PHT_BRIDGE
)
1802 else if ((headt
& PHT_MASK
) == PHT_CARDBUS
)
1807 printf("not a bridge\n");
1809 continue; /* Not a bridge */
1812 baseclass
= pci_attr_r8_u(devind
, PCI_BCR
);
1813 subclass
= pci_attr_r8_u(devind
, PCI_SCR
);
1814 infclass
= pci_attr_r8_u(devind
, PCI_PIFR
);
1815 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
1816 if (type
== PCI_PPB_STD
&&
1817 t3
!= PCI_T3_PCI2PCI
&&
1818 t3
!= PCI_T3_PCI2PCI_SUBTR
)
1821 "Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
1822 baseclass
, subclass
, infclass
,
1826 if (type
== PCI_PPB_CB
&&
1827 t3
!= PCI_T3_CARDBUS
)
1830 "Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
1831 baseclass
, subclass
, infclass
,
1839 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
1840 pcidev
[devind
].pd_busnr
,
1841 pcidev
[devind
].pd_dev
,
1842 pcidev
[devind
].pd_func
, vid
, did
);
1845 /* Assume that the BIOS initialized the secondary bus
1848 sbusn
= pci_attr_r8_u(devind
, PPB_SECBN
);
1850 if (nr_pcibus
>= NR_PCIBUS
)
1851 panic("PCI","too many PCI busses", nr_pcibus
);
1854 pcibus
[ind
].pb_type
= PBT_PCIBRIDGE
;
1855 pcibus
[ind
].pb_needinit
= 1;
1856 pcibus
[ind
].pb_isabridge_dev
= -1;
1857 pcibus
[ind
].pb_isabridge_type
= 0;
1858 pcibus
[ind
].pb_devind
= devind
;
1859 pcibus
[ind
].pb_busnr
= sbusn
;
1860 pcibus
[ind
].pb_rreg8
= pcibus
[busind
].pb_rreg8
;
1861 pcibus
[ind
].pb_rreg16
= pcibus
[busind
].pb_rreg16
;
1862 pcibus
[ind
].pb_rreg32
= pcibus
[busind
].pb_rreg32
;
1863 pcibus
[ind
].pb_wreg8
= pcibus
[busind
].pb_wreg8
;
1864 pcibus
[ind
].pb_wreg16
= pcibus
[busind
].pb_wreg16
;
1865 pcibus
[ind
].pb_wreg32
= pcibus
[busind
].pb_wreg32
;
1869 pcibus
[ind
].pb_rsts
= pcibr_std_rsts
;
1870 pcibus
[ind
].pb_wsts
= pcibr_std_wsts
;
1873 pcibus
[ind
].pb_type
= PBT_CARDBUS
;
1874 pcibus
[ind
].pb_rsts
= pcibr_cb_rsts
;
1875 pcibus
[ind
].pb_wsts
= pcibr_cb_wsts
;
1878 pcibus
[ind
].pb_rsts
= pcibr_via_rsts
;
1879 pcibus
[ind
].pb_wsts
= pcibr_via_wsts
;
1882 panic("PCI","unknown PCI-PCI bridge type", type
);
1887 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1888 ind
, sbusn
, pci_attr_r8_u(devind
, PPB_SUBORDBN
));
1892 printf("Secondary bus number not initialized\n");
1895 pcibus
[ind
].pb_needinit
= 0;
1899 /* Look for PCI bridges */
1904 /*===========================================================================*
1906 *===========================================================================*/
1907 PRIVATE
int get_busind(busnr
)
1912 for (i
= 0; i
<nr_pcibus
; i
++)
1914 if (pcibus
[i
].pb_busnr
== busnr
)
1917 panic("pci", "get_busind: can't find bus", busnr
);
1920 /*===========================================================================*
1922 *===========================================================================*/
1923 PRIVATE
int do_piix(devind
)
1926 int i
, s
, dev
, func
, irqrc
, irq
;
1927 u32_t elcr1
, elcr2
, elcr
;
1930 printf("in piix\n");
1932 dev
= pcidev
[devind
].pd_dev
;
1933 func
= pcidev
[devind
].pd_func
;
1935 if (OK
!= (s
=sys_inb(PIIX_ELCR1
, &elcr1
)))
1936 printf("Warning, sys_inb failed: %d\n", s
);
1937 if (OK
!= (s
=sys_inb(PIIX_ELCR2
, &elcr2
)))
1938 printf("Warning, sys_inb failed: %d\n", s
);
1940 elcr1
= inb(PIIX_ELCR1
);
1941 elcr2
= inb(PIIX_ELCR2
);
1943 elcr
= elcr1
| (elcr2
<< 8);
1944 for (i
= 0; i
<4; i
++)
1946 irqrc
= pci_attr_r8_u(devind
, PIIX_PIRQRCA
+i
);
1947 if (irqrc
& PIIX_IRQ_DI
)
1950 printf("INT%c: disabled\n", 'A'+i
);
1954 irq
= irqrc
& PIIX_IRQ_MASK
;
1956 printf("INT%c: %d\n", 'A'+i
, irq
);
1957 if (!(elcr
& (1 << irq
)))
1962 "(warning) IRQ %d is not level triggered\n",
1972 /*===========================================================================*
1974 *===========================================================================*/
1975 PRIVATE
int do_amd_isabr(devind
)
1978 int i
, busnr
, dev
, func
, xdevind
, irq
, edge
;
1982 /* Find required function */
1983 func
= AMD_ISABR_FUNC
;
1984 busnr
= pcidev
[devind
].pd_busnr
;
1985 dev
= pcidev
[devind
].pd_dev
;
1987 /* Fake a device with the required function */
1988 if (nr_pcidev
>= NR_PCIDEV
)
1989 panic("PCI","too many PCI devices", nr_pcidev
);
1991 pcidev
[xdevind
].pd_busnr
= busnr
;
1992 pcidev
[xdevind
].pd_dev
= dev
;
1993 pcidev
[xdevind
].pd_func
= func
;
1994 pcidev
[xdevind
].pd_inuse
= 1;
1997 levmask
= pci_attr_r8_u(xdevind
, AMD_ISABR_PCIIRQ_LEV
);
1998 pciirq
= pci_attr_r16(xdevind
, AMD_ISABR_PCIIRQ_ROUTE
);
1999 for (i
= 0; i
<4; i
++)
2001 edge
= (levmask
>> i
) & 1;
2002 irq
= (pciirq
>> (4*i
)) & 0xf;
2006 printf("INT%c: disabled\n", 'A'+i
);
2011 printf("INT%c: %d\n", 'A'+i
, irq
);
2015 "(warning) IRQ %d is not level triggered\n",
2025 /*===========================================================================*
2027 *===========================================================================*/
2028 PRIVATE
int do_sis_isabr(devind
)
2031 int i
, dev
, func
, irq
;
2033 dev
= pcidev
[devind
].pd_dev
;
2034 func
= pcidev
[devind
].pd_func
;
2036 for (i
= 0; i
<4; i
++)
2038 irq
= pci_attr_r8_u(devind
, SIS_ISABR_IRQ_A
+i
);
2039 if (irq
& SIS_IRQ_DISABLED
)
2042 printf("INT%c: disabled\n", 'A'+i
);
2046 irq
&= SIS_IRQ_MASK
;
2048 printf("INT%c: %d\n", 'A'+i
, irq
);
2055 /*===========================================================================*
2057 *===========================================================================*/
2058 PRIVATE
int do_via_isabr(devind
)
2061 int i
, dev
, func
, irq
, edge
;
2064 dev
= pcidev
[devind
].pd_dev
;
2065 func
= pcidev
[devind
].pd_func
;
2066 levmask
= pci_attr_r8_u(devind
, VIA_ISABR_EL
);
2069 for (i
= 0; i
<4; i
++)
2074 edge
= (levmask
& VIA_ISABR_EL_INTA
);
2075 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R2
) >> 4;
2078 edge
= (levmask
& VIA_ISABR_EL_INTB
);
2079 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R2
);
2082 edge
= (levmask
& VIA_ISABR_EL_INTC
);
2083 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R3
) >> 4;
2086 edge
= (levmask
& VIA_ISABR_EL_INTD
);
2087 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R1
) >> 4;
2096 printf("INT%c: disabled\n", 'A'+i
);
2101 printf("INT%c: %d\n", 'A'+i
, irq
);
2105 "(warning) IRQ %d is not level triggered\n",
2116 /*===========================================================================*
2118 *===========================================================================*/
2119 PRIVATE
void report_vga(devind
)
2122 /* Report the amount of video memory. This is needed by the X11R6
2123 * postinstall script to chmem the X server. Hopefully this can be
2124 * removed when we get virtual memory.
2126 size_t amount
, size
;
2130 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
2132 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
)
2134 size
= pcidev
[devind
].pd_bar
[i
].pb_size
;
2141 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
2142 pcidev
[devind
].pd_busnr
,
2143 pcidev
[devind
].pd_dev
,
2144 pcidev
[devind
].pd_func
,
2151 /*===========================================================================*
2153 *===========================================================================*/
2154 PRIVATE
char *pci_vid_name(vid
)
2159 for (i
= 0; pci_vendor_table
[i
].name
; i
++)
2161 if (pci_vendor_table
[i
].vid
== vid
)
2162 return pci_vendor_table
[i
].name
;
2167 /*===========================================================================*
2168 * pci_baseclass_name *
2169 *===========================================================================*/
2170 PRIVATE
char *pci_baseclass_name(baseclass
)
2175 for (i
= 0; pci_baseclass_table
[i
].name
; i
++)
2177 if (pci_baseclass_table
[i
].baseclass
== baseclass
)
2178 return pci_baseclass_table
[i
].name
;
2183 /*===========================================================================*
2184 * pci_subclass_name *
2185 *===========================================================================*/
2186 PRIVATE
char *pci_subclass_name(baseclass
, subclass
, infclass
)
2193 for (i
= 0; pci_subclass_table
[i
].name
; i
++)
2195 if (pci_subclass_table
[i
].baseclass
!= baseclass
)
2197 if (pci_subclass_table
[i
].subclass
!= subclass
)
2199 if (pci_subclass_table
[i
].infclass
!= infclass
&&
2200 pci_subclass_table
[i
].infclass
!= (u16_t
)-1)
2204 return pci_subclass_table
[i
].name
;
2209 /*===========================================================================*
2211 *===========================================================================*/
2212 PRIVATE
void ntostr(n
, str
, end
)
2229 tmpstr
[i
]= '0' + (n
%10);
2248 /*===========================================================================*
2250 *===========================================================================*/
2251 PRIVATE u16_t
pci_attr_rsts(devind
)
2256 busnr
= pcidev
[devind
].pd_busnr
;
2257 busind
= get_busind(busnr
);
2258 return pcibus
[busind
].pb_rsts(busind
);
2262 /*===========================================================================*
2264 *===========================================================================*/
2265 PRIVATE u16_t
pcibr_std_rsts(busind
)
2270 devind
= pcibus
[busind
].pb_devind
;
2271 return pci_attr_r16(devind
, PPB_SSTS
);
2274 /*===========================================================================*
2276 *===========================================================================*/
2277 PRIVATE
void pcibr_std_wsts(busind
, value
)
2282 devind
= pcibus
[busind
].pb_devind
;
2285 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2286 busind
, value
, devind
);
2288 pci_attr_w16(devind
, PPB_SSTS
, value
);
2291 /*===========================================================================*
2293 *===========================================================================*/
2294 PRIVATE u16_t
pcibr_cb_rsts(busind
)
2298 devind
= pcibus
[busind
].pb_devind
;
2300 return pci_attr_r16(devind
, CBB_SSTS
);
2303 /*===========================================================================*
2305 *===========================================================================*/
2306 PRIVATE
void pcibr_cb_wsts(busind
, value
)
2311 devind
= pcibus
[busind
].pb_devind
;
2314 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2315 busind
, value
, devind
);
2317 pci_attr_w16(devind
, CBB_SSTS
, value
);
2320 /*===========================================================================*
2322 *===========================================================================*/
2323 PRIVATE u16_t
pcibr_via_rsts(busind
)
2327 devind
= pcibus
[busind
].pb_devind
;
2332 /*===========================================================================*
2334 *===========================================================================*/
2335 PRIVATE
void pcibr_via_wsts(busind
, value
)
2340 devind
= pcibus
[busind
].pb_devind
;
2343 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2344 busind
, value
, devind
);
2348 /*===========================================================================*
2350 *===========================================================================*/
2351 PRIVATE
void pci_attr_wsts(devind
, value
)
2357 busnr
= pcidev
[devind
].pd_busnr
;
2358 busind
= get_busind(busnr
);
2359 pcibus
[busind
].pb_wsts(busind
, value
);
2363 /*===========================================================================*
2365 *===========================================================================*/
2366 PRIVATE u8_t
pcii_rreg8(busind
, devind
, port
)
2374 v
= PCII_RREG8_(pcibus
[busind
].pb_busnr
,
2375 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2378 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2379 printf("PCI: warning, sys_outl failed: %d\n", s
);
2381 outl(PCII_CONFADD
, PCII_UNSEL
);
2384 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2385 busind
, devind
, port
,
2386 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2387 pcidev
[devind
].pd_func
, v
);
2392 /*===========================================================================*
2394 *===========================================================================*/
2395 PRIVATE u16_t
pcii_rreg16(busind
, devind
, port
)
2403 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
,
2404 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2407 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2408 printf("PCI: warning, sys_outl failed: %d\n");
2410 outl(PCII_CONFADD
, PCII_UNSEL
);
2413 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2414 busind
, devind
, port
,
2415 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2416 pcidev
[devind
].pd_func
, v
);
2421 /*===========================================================================*
2423 *===========================================================================*/
2424 PRIVATE u32_t
pcii_rreg32(busind
, devind
, port
)
2432 v
= PCII_RREG32_(pcibus
[busind
].pb_busnr
,
2433 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2436 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2437 printf("PCI: warning, sys_outl failed: %d\n", s
);
2439 outl(PCII_CONFADD
, PCII_UNSEL
);
2442 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2443 busind
, devind
, port
,
2444 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2445 pcidev
[devind
].pd_func
, v
);
2450 /*===========================================================================*
2452 *===========================================================================*/
2453 PRIVATE
void pcii_wreg8(busind
, devind
, port
, value
)
2461 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2462 busind
, devind
, port
, value
,
2463 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2464 pcidev
[devind
].pd_func
);
2466 PCII_WREG8_(pcibus
[busind
].pb_busnr
,
2467 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2470 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2471 printf("PCI: warning, sys_outl failed: %d\n", s
);
2473 outl(PCII_CONFADD
, PCII_UNSEL
);
2477 /*===========================================================================*
2479 *===========================================================================*/
2480 PRIVATE
void pcii_wreg16(busind
, devind
, port
, value
)
2488 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2489 busind
, devind
, port
, value
,
2490 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2491 pcidev
[devind
].pd_func
);
2493 PCII_WREG16_(pcibus
[busind
].pb_busnr
,
2494 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2497 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2498 printf("PCI: warning, sys_outl failed: %d\n", s
);
2500 outl(PCII_CONFADD
, PCII_UNSEL
);
2504 /*===========================================================================*
2506 *===========================================================================*/
2507 PRIVATE
void pcii_wreg32(busind
, devind
, port
, value
)
2515 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2516 busind
, devind
, port
, value
,
2517 pcibus
[busind
].pb_busnr
, pcidev
[devind
].pd_dev
,
2518 pcidev
[devind
].pd_func
);
2520 PCII_WREG32_(pcibus
[busind
].pb_busnr
,
2521 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2524 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2525 printf("PCI: warning, sys_outl failed: %d\n");
2527 outl(PCII_CONFADD
, PCII_UNSEL
);
2531 /*===========================================================================*
2533 *===========================================================================*/
2534 PRIVATE u16_t
pcii_rsts(busind
)
2540 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
, 0, 0, PCI_SR
);
2542 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2543 printf("PCI: warning, sys_outl failed: %d\n", s
);
2545 outl(PCII_CONFADD
, PCII_UNSEL
);
2550 /*===========================================================================*
2552 *===========================================================================*/
2553 PRIVATE
void pcii_wsts(busind
, value
)
2558 PCII_WREG16_(pcibus
[busind
].pb_busnr
, 0, 0, PCI_SR
, value
);
2560 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2561 printf("PCI: warning, sys_outl failed: %d\n", s
);
2563 outl(PCII_CONFADD
, PCII_UNSEL
);
2568 /*===========================================================================*
2569 * print_capabilities *
2570 *===========================================================================*/
2571 PRIVATE
void print_capabilities(devind
)
2574 u8_t status
, capptr
, type
, next
, subtype
;
2577 /* Check capabilities bit in the device status register */
2578 status
= pci_attr_r16(devind
, PCI_SR
);
2579 if (!(status
& PSR_CAPPTR
))
2582 capptr
= (pci_attr_r8_u(devind
, PCI_CAPPTR
) & PCI_CP_MASK
);
2585 type
= pci_attr_r8_u(devind
, capptr
+CAP_TYPE
);
2586 next
= (pci_attr_r8_u(devind
, capptr
+CAP_NEXT
) & PCI_CP_MASK
);
2589 case 1: str
= "PCI Power Management"; break;
2590 case 2: str
= "AGP"; break;
2591 case 3: str
= "Vital Product Data"; break;
2592 case 4: str
= "Slot Identification"; break;
2593 case 5: str
= "Message Signaled Interrupts"; break;
2594 case 6: str
= "CompactPCI Hot Swap"; break;
2595 case 8: str
= "AMD HyperTransport"; break;
2596 case 0xf: str
= "Secure Device"; break;
2597 default: str
= "(unknown type)"; break;
2600 printf(" @0x%x (0x%08x): capability type 0x%x: %s",
2601 capptr
, pci_attr_r32_u(devind
, capptr
), type
, str
);
2603 print_hyper_cap(devind
, capptr
);
2604 else if (type
== 0x0f)
2606 subtype
= (pci_attr_r8_u(devind
, capptr
+2) & 0x07);
2609 case 0: str
= "Device Exclusion Vector"; break;
2610 case 3: str
= "IOMMU"; break;
2611 default: str
= "(unknown type)"; break;
2613 printf(", sub type 0%o: %s", subtype
, str
);
2621 /*===========================================================================*
2623 *===========================================================================*/
2624 PRIVATE
int visible(aclp
, devind
)
2625 struct rs_pci
*aclp
;
2632 return TRUE
; /* Should be changed when ACLs become
2635 /* Check whether the caller is allowed to get this device. */
2636 for (i
= 0; i
<aclp
->rsp_nr_device
; i
++)
2638 if (aclp
->rsp_device
[i
].vid
== pcidev
[devind
].pd_vid
&&
2639 aclp
->rsp_device
[i
].did
== pcidev
[devind
].pd_did
)
2644 if (!aclp
->rsp_nr_class
)
2647 class_id
= (pcidev
[devind
].pd_baseclass
<< 16) |
2648 (pcidev
[devind
].pd_subclass
<< 8) |
2649 pcidev
[devind
].pd_infclass
;
2650 for (i
= 0; i
<aclp
->rsp_nr_class
; i
++)
2652 if (aclp
->rsp_class
[i
].class ==
2653 (class_id
& aclp
->rsp_class
[i
].mask
))
2662 /*===========================================================================*
2664 *===========================================================================*/
2665 PRIVATE
void print_hyper_cap(devind
, capptr
)
2674 v
= pci_attr_r32_u(devind
, capptr
);
2675 printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr
);
2676 cmd
= (v
>> 16) & 0xffff;
2680 printf(" WarmReset");
2685 printf(" DblEnded");
2688 printf(" DevNum %d", (v
& 0x7C0000) >> 18);
2691 type0
= (cmd
& 0xE000) >> 13;
2692 type1
= (cmd
& 0xF800) >> 11;
2693 if (type0
== 0 || type0
== 1)
2695 printf("Capability Type: %s\n",
2696 type0
== 0 ? "Slave or Primary Interface" :
2697 "Host or Secondary Interface");
2702 printf(" Capability Type 0x%x", type1
);
2706 printf(" undecoded 0x%x\n", cmd
);
2709 printf("print_hyper_cap: off 4 (ctl): 0x%x\n",
2710 pci_attr_r32_u(devind
, capptr
+4));
2711 printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n",
2712 pci_attr_r32_u(devind
, capptr
+8));
2713 printf("print_hyper_cap: off 12 (cap): 0x%x\n",
2714 pci_attr_r32_u(devind
, capptr
+12));
2715 printf("print_hyper_cap: off 16 (buf count): 0x%x\n",
2716 pci_attr_r32_u(devind
, capptr
+16));
2717 v
= pci_attr_r32_u(devind
, capptr
+20);
2718 printf("print_hyper_cap: @0x%x, off 20 (bus nr): ",
2720 printf("prim %d", v
& 0xff);
2721 printf(", sec %d", (v
>> 8) & 0xff);
2722 printf(", sub %d", (v
>> 16) & 0xff);
2724 printf(", reserved %d", (v
>> 24) & 0xff);
2726 printf("print_hyper_cap: off 24 (type): 0x%x\n",
2727 pci_attr_r32_u(devind
, capptr
+24));
2732 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $