6 Configure devices on the PCI bus
8 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
11 #include "../drivers.h"
14 #include <sys/vm_i386.h>
15 #include <minix/com.h>
16 #include <minix/syslib.h>
20 #include "pci_intel.h"
28 #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("sys_safecopyfrom failed: %d", 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("unable to map service: %d", 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("too many PCI busses: %d", 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(int busind
)
761 u8_t baseclass
, subclass
, infclass
;
766 printf("probe_bus(%d)\n", busind
);
768 if (nr_pcidev
>= NR_PCIDEV
)
769 panic("too many PCI devices: %d", nr_pcidev
);
772 busnr
= pcibus
[busind
].pb_busnr
;
773 for (dev
= 0; dev
<32; dev
++)
776 for (func
= 0; func
< 8; func
++)
778 pcidev
[devind
].pd_busnr
= busnr
;
779 pcidev
[devind
].pd_dev
= dev
;
780 pcidev
[devind
].pd_func
= func
;
782 pci_attr_wsts(devind
,
783 PSR_SSE
|PSR_RMAS
|PSR_RTAS
);
784 vid
= pci_attr_r16(devind
, PCI_VID
);
785 did
= pci_attr_r16(devind
, PCI_DID
);
786 headt
= pci_attr_r8_u(devind
, PCI_HEADT
);
787 sts
= pci_attr_rsts(devind
);
790 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
791 vid
, did
, headt
, sts
);
794 if (vid
== NO_VID
&& did
== NO_VID
)
797 break; /* Nothing here */
799 /* Scan all functions of a multifunction
805 if (sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
))
808 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
809 sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
));
812 dstr
= pci_dev_name(vid
, did
);
817 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
818 busind
, (unsigned long)dev
,
819 (unsigned long)func
, dstr
,
825 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
826 busind
, (unsigned long)dev
,
827 (unsigned long)func
, vid
,
828 pci_vid_name(vid
), did
);
830 printf("Device index: %d\n", devind
);
831 printf("Subsystem: Vid 0x%x, did 0x%x\n",
832 pci_attr_r16(devind
, PCI_SUBVID
),
833 pci_attr_r16(devind
, PCI_SUBDID
));
836 baseclass
= pci_attr_r8_u(devind
, PCI_BCR
);
837 subclass
= pci_attr_r8_u(devind
, PCI_SCR
);
838 infclass
= pci_attr_r8_u(devind
, PCI_PIFR
);
839 s
= pci_subclass_name(baseclass
, subclass
, infclass
);
841 s
= pci_baseclass_name(baseclass
);
844 s
= "(unknown class)";
848 printf("\tclass %s (%X/%X/%X)\n", s
,
849 baseclass
, subclass
, infclass
);
852 if (is_duplicate(busnr
, dev
, func
))
854 printf("\tduplicate!\n");
855 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
862 pcidev
[devind
].pd_baseclass
= baseclass
;
863 pcidev
[devind
].pd_subclass
= subclass
;
864 pcidev
[devind
].pd_infclass
= infclass
;
865 pcidev
[devind
].pd_vid
= vid
;
866 pcidev
[devind
].pd_did
= did
;
867 pcidev
[devind
].pd_inuse
= 0;
868 pcidev
[devind
].pd_bar_nr
= 0;
870 switch(headt
& PHT_MASK
)
873 record_bars_normal(devind
);
876 record_bars_bridge(devind
);
879 record_bars_cardbus(devind
);
882 printf("\t%d.%d.%d: unknown header type %d\n",
888 print_capabilities(devind
);
890 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
892 if (t3
== PCI_T3_VGA
|| t3
== PCI_T3_VGA_OLD
)
896 if (nr_pcidev
>= NR_PCIDEV
)
897 panic("too many PCI devices: %d", nr_pcidev
);
900 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
906 /*===========================================================================*
908 *===========================================================================*/
909 PRIVATE
int is_duplicate(busnr
, dev
, func
)
916 for (i
= 0; i
<nr_pcidev
; i
++)
918 if (pcidev
[i
].pd_busnr
== busnr
&&
919 pcidev
[i
].pd_dev
== dev
&&
920 pcidev
[i
].pd_func
== func
)
928 /*===========================================================================*
930 *===========================================================================*/
931 PRIVATE
void record_irq(devind
)
934 int ilr
, ipr
, busnr
, busind
, cb_devind
;
936 ilr
= pci_attr_r8_u(devind
, PCI_ILR
);
937 ipr
= pci_attr_r8_u(devind
, PCI_IPR
);
941 if (ipr
&& first
&& debug
)
944 printf("PCI: strange, BIOS assigned IRQ0\n");
946 ilr
= PCI_ILR_UNKNOWN
;
948 pcidev
[devind
].pd_ilr
= ilr
;
949 if (ilr
== PCI_ILR_UNKNOWN
&& !ipr
)
952 else if (ilr
!= PCI_ILR_UNKNOWN
&& ipr
)
955 printf("\tIRQ %d for INT%c\n", ilr
, 'A' + ipr
-1);
957 else if (ilr
!= PCI_ILR_UNKNOWN
)
960 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
961 ilr
, pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
962 pcidev
[devind
].pd_func
);
966 /* Check for cardbus devices */
967 busnr
= pcidev
[devind
].pd_busnr
;
968 busind
= get_busind(busnr
);
969 if (pcibus
[busind
].pb_type
== PBT_CARDBUS
)
971 cb_devind
= pcibus
[busind
].pb_devind
;
972 ilr
= pcidev
[cb_devind
].pd_ilr
;
973 if (ilr
!= PCI_ILR_UNKNOWN
)
978 "assigning IRQ %d to Cardbus device\n",
981 pci_attr_w8(devind
, PCI_ILR
, ilr
);
982 pcidev
[devind
].pd_ilr
= ilr
;
988 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
989 pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
990 pcidev
[devind
].pd_func
, 'A' + ipr
-1);
995 /*===========================================================================*
996 * record_bars_normal *
997 *===========================================================================*/
998 PRIVATE
void record_bars_normal(devind
)
1001 int i
, j
, clear_01
, clear_23
, pb_nr
;
1003 /* The BAR area of normal devices is six DWORDs in size. */
1004 record_bars(devind
, PCI_BAR_6
);
1006 /* Special case code for IDE controllers in compatibility mode */
1007 if (pcidev
[devind
].pd_baseclass
== PCI_BCR_MASS_STORAGE
&&
1008 pcidev
[devind
].pd_subclass
== PCI_MS_IDE
)
1013 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_PRI_NATIVE
))
1018 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1022 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_SEC_NATIVE
))
1027 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
1033 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
1035 pb_nr
= pcidev
[devind
].pd_bar
[i
].pb_nr
;
1036 if ((pb_nr
== 0 || pb_nr
== 1) && clear_01
)
1038 if (debug
) printf("skipping bar %d\n", pb_nr
);
1039 continue; /* Skip */
1041 if ((pb_nr
== 2 || pb_nr
== 3) && clear_23
)
1043 if (debug
) printf("skipping bar %d\n", pb_nr
);
1044 continue; /* Skip */
1049 continue; /* No need to copy */
1051 pcidev
[devind
].pd_bar
[j
]=
1052 pcidev
[devind
].pd_bar
[i
];
1055 pcidev
[devind
].pd_bar_nr
= j
;
1059 /*===========================================================================*
1060 * record_bars_bridge *
1061 *===========================================================================*/
1062 PRIVATE
void record_bars_bridge(devind
)
1065 u32_t base
, limit
, size
;
1067 /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
1068 * It may contain up to two 32-bit BARs, or one 64-bit BAR.
1070 record_bars(devind
, PCI_BAR_2
);
1072 base
= ((pci_attr_r8_u(devind
, PPB_IOBASE
) & PPB_IOB_MASK
) << 8) |
1073 (pci_attr_r16(devind
, PPB_IOBASEU16
) << 16);
1075 ((pci_attr_r8_u(devind
, PPB_IOLIMIT
) & PPB_IOL_MASK
) << 8) |
1076 ((~PPB_IOL_MASK
& 0xff) << 8) |
1077 (pci_attr_r16(devind
, PPB_IOLIMITU16
) << 16);
1078 size
= limit
-base
+ 1;
1081 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1085 base
= ((pci_attr_r16(devind
, PPB_MEMBASE
) & PPB_MEMB_MASK
) << 16);
1087 ((pci_attr_r16(devind
, PPB_MEMLIMIT
) & PPB_MEML_MASK
) << 16) |
1088 ((~PPB_MEML_MASK
& 0xffff) << 16);
1089 size
= limit
-base
+ 1;
1092 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1096 /* Ignore the upper 32 bits */
1097 base
= ((pci_attr_r16(devind
, PPB_PFMEMBASE
) & PPB_PFMEMB_MASK
) << 16);
1099 ((pci_attr_r16(devind
, PPB_PFMEMLIMIT
) &
1100 PPB_PFMEML_MASK
) << 16) |
1101 ((~PPB_PFMEML_MASK
& 0xffff) << 16);
1102 size
= limit
-base
+ 1;
1106 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1111 /*===========================================================================*
1112 * record_bars_cardbus *
1113 *===========================================================================*/
1114 PRIVATE
void record_bars_cardbus(devind
)
1117 u32_t base
, limit
, size
;
1119 /* The generic BAR area of CardBus devices is one DWORD in size. */
1120 record_bars(devind
, PCI_BAR
);
1122 base
= pci_attr_r32_u(devind
, CBB_MEMBASE_0
);
1123 limit
= pci_attr_r32_u(devind
, CBB_MEMLIMIT_0
) |
1124 (~CBB_MEML_MASK
& 0xffffffff);
1125 size
= limit
-base
+ 1;
1128 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1132 base
= pci_attr_r32_u(devind
, CBB_MEMBASE_1
);
1133 limit
= pci_attr_r32_u(devind
, CBB_MEMLIMIT_1
) |
1134 (~CBB_MEML_MASK
& 0xffffffff);
1135 size
= limit
-base
+ 1;
1138 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1142 base
= pci_attr_r32_u(devind
, CBB_IOBASE_0
);
1143 limit
= pci_attr_r32_u(devind
, CBB_IOLIMIT_0
) |
1144 (~CBB_IOL_MASK
& 0xffffffff);
1145 size
= limit
-base
+ 1;
1148 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1152 base
= pci_attr_r32_u(devind
, CBB_IOBASE_1
);
1153 limit
= pci_attr_r32_u(devind
, CBB_IOLIMIT_1
) |
1154 (~CBB_IOL_MASK
& 0xffffffff);
1155 size
= limit
-base
+ 1;
1158 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1163 /*===========================================================================*
1165 *===========================================================================*/
1166 PRIVATE
void record_bars(devind
, last_reg
)
1170 for (i
= 0, reg
= PCI_BAR
; reg
<= last_reg
; i
+= width
, reg
+= 4 * width
)
1172 width
= record_bar(devind
, i
, reg
== last_reg
);
1176 /*===========================================================================*
1178 *===========================================================================*/
1179 PRIVATE
int record_bar(devind
, bar_nr
, last
)
1184 int reg
, prefetch
, type
, dev_bar_nr
, width
;
1188 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
1191 reg
= PCI_BAR
+4*bar_nr
;
1193 bar
= pci_attr_r32_u(devind
, reg
);
1194 if (bar
& PCI_BAR_IO
)
1196 /* Disable I/O access before probing for BAR's size */
1197 cmd
= pci_attr_r16(devind
, PCI_CR
);
1198 pci_attr_w16(devind
, PCI_CR
, cmd
& ~PCI_CR_IO_EN
);
1200 /* Probe BAR's size */
1201 pci_attr_w32(devind
, reg
, 0xffffffff);
1202 bar2
= pci_attr_r32_u(devind
, reg
);
1204 /* Restore original state */
1205 pci_attr_w32(devind
, reg
, bar
);
1206 pci_attr_w16(devind
, PCI_CR
, cmd
);
1208 bar
&= ~(u32_t
)3; /* Clear non-address bits */
1210 bar2
= (~bar2
& 0xffff)+1;
1213 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1217 dev_bar_nr
= pcidev
[devind
].pd_bar_nr
++;
1218 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
= PBF_IO
;
1219 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_base
= bar
;
1220 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_size
= bar2
;
1221 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_nr
= bar_nr
;
1224 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1230 type
= (bar
& PCI_BAR_TYPE
);
1234 case PCI_TYPE_32_1M
:
1238 /* A 64-bit BAR takes up two consecutive DWORDs. */
1241 printf("PCI: device %d.%d.%d BAR %d extends"
1242 " beyond designated area\n",
1243 pcidev
[devind
].pd_busnr
,
1244 pcidev
[devind
].pd_dev
,
1245 pcidev
[devind
].pd_func
, bar_nr
);
1251 bar2
= pci_attr_r32_u(devind
, reg
+4);
1253 /* If the upper 32 bits of the BAR are not zero, the
1254 * memory is inaccessible to us; ignore the BAR.
1260 printf("\tbar_%d: (64-bit BAR with"
1261 " high bits set)\n", bar_nr
);
1270 /* Ignore the BAR. */
1273 printf("\tbar_%d: (unknown type %x)\n",
1280 /* Disable mem access before probing for BAR's size */
1281 cmd
= pci_attr_r16(devind
, PCI_CR
);
1282 pci_attr_w16(devind
, PCI_CR
, cmd
& ~PCI_CR_MEM_EN
);
1284 /* Probe BAR's size */
1285 pci_attr_w32(devind
, reg
, 0xffffffff);
1286 bar2
= pci_attr_r32_u(devind
, reg
);
1288 /* Restore original values */
1289 pci_attr_w32(devind
, reg
, bar
);
1290 pci_attr_w16(devind
, PCI_CR
, cmd
);
1293 return width
; /* Reg. is not implemented */
1295 prefetch
= !!(bar
& PCI_BAR_PREFETCH
);
1296 bar
&= ~(u32_t
)0xf; /* Clear non-address bits */
1297 bar2
&= ~(u32_t
)0xf;
1301 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n",
1303 prefetch
? " prefetchable" : "",
1304 type
== PCI_TYPE_64
? ", 64-bit" : "");
1307 dev_bar_nr
= pcidev
[devind
].pd_bar_nr
++;
1308 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
= 0;
1309 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_base
= bar
;
1310 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_size
= bar2
;
1311 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_nr
= bar_nr
;
1314 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1322 /*===========================================================================*
1323 * complete_bridges *
1324 *===========================================================================*/
1325 PRIVATE
void complete_bridges()
1327 int i
, freebus
, devind
, prim_busnr
;
1329 for (i
= 0; i
<nr_pcibus
; i
++)
1331 if (!pcibus
[i
].pb_needinit
)
1333 printf("should allocate bus number for bus %d\n", i
);
1334 freebus
= get_freebus();
1335 printf("got bus number %d\n", freebus
);
1337 devind
= pcibus
[i
].pb_devind
;
1339 prim_busnr
= pcidev
[devind
].pd_busnr
;
1340 if (prim_busnr
!= 0)
1343 "complete_bridge: updating subordinate bus number not implemented\n");
1346 pcibus
[i
].pb_needinit
= 0;
1347 pcibus
[i
].pb_busnr
= freebus
;
1349 printf("devind = %d\n", devind
);
1350 printf("prim_busnr= %d\n", prim_busnr
);
1352 pci_attr_w8(devind
, PPB_PRIMBN
, prim_busnr
);
1353 pci_attr_w8(devind
, PPB_SECBN
, freebus
);
1354 pci_attr_w8(devind
, PPB_SUBORDBN
, freebus
);
1356 printf("CR = 0x%x\n", pci_attr_r16(devind
, PCI_CR
));
1357 printf("SECBLT = 0x%x\n", pci_attr_r8_u(devind
, PPB_SECBLT
));
1358 printf("BRIDGECTRL = 0x%x\n",
1359 pci_attr_r16(devind
, PPB_BRIDGECTRL
));
1363 /*===========================================================================*
1365 *===========================================================================*/
1366 PRIVATE
void complete_bars(void)
1368 int i
, j
, r
, bar_nr
, reg
;
1369 u32_t memgap_low
, memgap_high
, iogap_low
, iogap_high
, io_high
,
1370 base
, size
, v32
, diff1
, diff2
;
1374 r
= env_get_param("memory", memstr
, sizeof(memstr
));
1376 panic("env_get_param failed: %d", r
);
1378 /* Set memgap_low to just above physical memory */
1383 base
= strtoul(cp
, &next
, 16);
1384 if (!(*next
) || next
== cp
|| *next
!= ':')
1385 goto bad_mem_string
;
1387 size
= strtoul(cp
, &next
, 16);
1388 if (next
== cp
|| (*next
!= ',' && *next
!= '\0'))
1390 goto bad_mem_string
;
1391 if (base
+size
> memgap_low
)
1392 memgap_low
= base
+size
;
1400 memgap_high
= 0xfe000000; /* Leave space for the CPU (APIC) */
1404 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1405 memgap_low
, memgap_high
);
1408 /* Find the lowest memory base */
1409 for (i
= 0; i
<nr_pcidev
; i
++)
1411 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1413 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
)
1415 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1417 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1418 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1420 if (base
>= memgap_high
)
1421 continue; /* Not in the gap */
1422 if (base
+size
<= memgap_low
)
1423 continue; /* Not in the gap */
1425 /* Reduce the gap by the smallest amount */
1426 diff1
= base
+size
-memgap_low
;
1427 diff2
= memgap_high
-base
;
1430 memgap_low
= base
+size
;
1438 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1439 memgap_low
, memgap_high
);
1442 /* Should check main memory size */
1443 if (memgap_high
< memgap_low
)
1445 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1446 memgap_low
, memgap_high
);
1450 iogap_high
= 0x10000;
1453 /* Find the free I/O space */
1454 for (i
= 0; i
<nr_pcidev
; i
++)
1456 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1458 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
))
1460 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1462 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1463 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1464 if (base
>= iogap_high
)
1466 if (base
+size
<= iogap_low
)
1472 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
1473 i
, pcidev
[i
].pd_vid
, pcidev
[i
].pd_did
,
1477 if (base
+size
-iogap_low
< iogap_high
-base
)
1478 iogap_low
= base
+size
;
1484 if (iogap_high
< iogap_low
)
1488 printf("iogap_high too low, should panic\n");
1491 panic("iogap_high too low: %d", iogap_high
);
1494 printf("I/O range = [0x%x..0x%x>\n", iogap_low
, iogap_high
);
1496 for (i
= 0; i
<nr_pcidev
; i
++)
1498 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1500 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
)
1502 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1504 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1505 if (size
< I386_PAGE_SIZE
)
1506 size
= I386_PAGE_SIZE
;
1507 base
= memgap_high
-size
;
1508 base
&= ~(u32_t
)(size
-1);
1509 if (base
< memgap_low
)
1510 panic("memory base too low: %d", base
);
1512 bar_nr
= pcidev
[i
].pd_bar
[j
].pb_nr
;
1513 reg
= PCI_BAR
+ 4*bar_nr
;
1514 v32
= pci_attr_r32_u(i
, reg
);
1515 pci_attr_w32(i
, reg
, v32
| base
);
1519 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1520 base
, size
, pcidev
[i
].pd_busnr
,
1521 pcidev
[i
].pd_dev
, pcidev
[i
].pd_func
,
1524 pcidev
[i
].pd_bar
[j
].pb_base
= base
;
1525 pcidev
[i
].pd_bar
[j
].pb_flags
&= ~PBF_INCOMPLETE
;
1528 io_high
= iogap_high
;
1529 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1531 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
))
1533 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1535 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1536 base
= iogap_high
-size
;
1537 base
&= ~(u32_t
)(size
-1);
1539 /* Assume that ISA compatibility is required. Only
1540 * use the lowest 256 bytes out of every 1024 bytes.
1544 if (base
< iogap_low
)
1545 panic("I/O base too low: %d", base
);
1548 bar_nr
= pcidev
[i
].pd_bar
[j
].pb_nr
;
1549 reg
= PCI_BAR
+ 4*bar_nr
;
1550 v32
= pci_attr_r32_u(i
, reg
);
1551 pci_attr_w32(i
, reg
, v32
| base
);
1555 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1556 base
, size
, pcidev
[i
].pd_busnr
,
1557 pcidev
[i
].pd_dev
, pcidev
[i
].pd_func
,
1560 pcidev
[i
].pd_bar
[j
].pb_base
= base
;
1561 pcidev
[i
].pd_bar
[j
].pb_flags
&= ~PBF_INCOMPLETE
;
1564 if (iogap_high
!= io_high
)
1566 update_bridge4dev_io(i
, iogap_high
,
1567 io_high
-iogap_high
);
1571 for (i
= 0; i
<nr_pcidev
; i
++)
1573 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1575 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1577 printf("should allocate resources for device %d\n", i
);
1583 printf("PCI: bad memory environment string '%s'\n", memstr
);
1587 /*===========================================================================*
1588 * update_bridge4dev_io *
1589 *===========================================================================*/
1590 PRIVATE
void update_bridge4dev_io(devind
, io_base
, io_size
)
1595 int busnr
, busind
, type
, br_devind
;
1598 busnr
= pcidev
[devind
].pd_busnr
;
1599 busind
= get_busind(busnr
);
1600 type
= pcibus
[busind
].pb_type
;
1601 if (type
== PBT_INTEL_HOST
)
1602 return; /* Nothing to do for host controller */
1603 if (type
== PBT_PCIBRIDGE
)
1606 "update_bridge4dev_io: not implemented for PCI bridges\n");
1609 if (type
!= PBT_CARDBUS
)
1610 panic("update_bridge4dev_io: strange bus type: %d", type
);
1614 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1617 br_devind
= pcibus
[busind
].pb_devind
;
1618 pci_attr_w32(br_devind
, CBB_IOLIMIT_0
, io_base
+io_size
-1);
1619 pci_attr_w32(br_devind
, CBB_IOBASE_0
, io_base
);
1621 /* Enable I/O access. Enable busmaster access as well. */
1622 v16
= pci_attr_r16(devind
, PCI_CR
);
1623 pci_attr_w16(devind
, PCI_CR
, v16
| PCI_CR_IO_EN
| PCI_CR_MAST_EN
);
1626 /*===========================================================================*
1628 *===========================================================================*/
1629 PRIVATE
int get_freebus()
1634 for (i
= 0; i
<nr_pcibus
; i
++)
1636 if (pcibus
[i
].pb_needinit
)
1638 if (pcibus
[i
].pb_type
== PBT_INTEL_HOST
)
1640 if (pcibus
[i
].pb_busnr
<= freebus
)
1641 freebus
= pcibus
[i
].pb_busnr
+1;
1642 printf("get_freebus: should check suboridinate bus number\n");
1647 /*===========================================================================*
1649 *===========================================================================*/
1650 PRIVATE
int do_isabridge(busind
)
1653 int i
, j
, r
, type
, busnr
, unknown_bridge
, bridge_dev
;
1661 vid
= did
= 0; /* lint */
1662 busnr
= pcibus
[busind
].pb_busnr
;
1663 for (i
= 0; i
< nr_pcidev
; i
++)
1665 if (pcidev
[i
].pd_busnr
!= busnr
)
1667 t3
= ((pcidev
[i
].pd_baseclass
<< 16) |
1668 (pcidev
[i
].pd_subclass
<< 8) | pcidev
[i
].pd_infclass
);
1669 if (t3
== PCI_T3_ISA
)
1671 /* ISA bridge. Report if no supported bridge is
1677 vid
= pcidev
[i
].pd_vid
;
1678 did
= pcidev
[i
].pd_did
;
1679 for (j
= 0; pci_isabridge
[j
].vid
!= 0; j
++)
1681 if (pci_isabridge
[j
].vid
!= vid
)
1683 if (pci_isabridge
[j
].did
!= did
)
1685 if (pci_isabridge
[j
].checkclass
&&
1686 unknown_bridge
!= i
)
1688 /* This part of multifunction device is
1695 if (pci_isabridge
[j
].vid
)
1702 if (bridge_dev
!= -1)
1704 dstr
= pci_dev_name(vid
, did
);
1706 dstr
= "unknown device";
1709 printf("found ISA bridge (%04X/%04X) %s\n",
1712 pcibus
[busind
].pb_isabridge_dev
= bridge_dev
;
1713 type
= pci_isabridge
[j
].type
;
1714 pcibus
[busind
].pb_isabridge_type
= type
;
1718 r
= do_piix(bridge_dev
);
1721 r
= do_via_isabr(bridge_dev
);
1724 r
= do_amd_isabr(bridge_dev
);
1727 r
= do_sis_isabr(bridge_dev
);
1730 panic("unknown ISA bridge type: %d", type
);
1735 if (unknown_bridge
== -1)
1739 printf("(warning) no ISA bridge found on bus %d\n",
1747 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
1748 pcidev
[unknown_bridge
].pd_vid
,
1749 pcidev
[unknown_bridge
].pd_did
, busind
);
1754 /*===========================================================================*
1756 *===========================================================================*/
1757 PRIVATE
void do_pcibridge(busind
)
1760 int i
, devind
, busnr
;
1763 u8_t sbusn
, baseclass
, subclass
, infclass
, headt
;
1766 vid
= did
= 0; /* lint */
1767 busnr
= pcibus
[busind
].pb_busnr
;
1768 for (devind
= 0; devind
< nr_pcidev
; devind
++)
1771 printf("do_pcibridge: trying %u.%u.%u\n",
1772 pcidev
[devind
].pd_busind
, pcidev
[devind
].pd_dev
,
1773 pcidev
[devind
].pd_func
);
1776 if (pcidev
[devind
].pd_busnr
!= busnr
)
1779 printf("wrong bus\n");
1784 vid
= pcidev
[devind
].pd_vid
;
1785 did
= pcidev
[devind
].pd_did
;
1786 for (i
= 0; pci_pcibridge
[i
].vid
!= 0; i
++)
1788 if (pci_pcibridge
[i
].vid
!= vid
)
1790 if (pci_pcibridge
[i
].did
!= did
)
1794 type
= pci_pcibridge
[i
].type
;
1795 if (pci_pcibridge
[i
].vid
== 0)
1797 headt
= pci_attr_r8_u(devind
, PCI_HEADT
);
1799 if ((headt
& PHT_MASK
) == PHT_BRIDGE
)
1801 else if ((headt
& PHT_MASK
) == PHT_CARDBUS
)
1806 printf("not a bridge\n");
1808 continue; /* Not a bridge */
1811 baseclass
= pci_attr_r8_u(devind
, PCI_BCR
);
1812 subclass
= pci_attr_r8_u(devind
, PCI_SCR
);
1813 infclass
= pci_attr_r8_u(devind
, PCI_PIFR
);
1814 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
1815 if (type
== PCI_PPB_STD
&&
1816 t3
!= PCI_T3_PCI2PCI
&&
1817 t3
!= PCI_T3_PCI2PCI_SUBTR
)
1820 "Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
1821 baseclass
, subclass
, infclass
,
1825 if (type
== PCI_PPB_CB
&&
1826 t3
!= PCI_T3_CARDBUS
)
1829 "Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
1830 baseclass
, subclass
, infclass
,
1838 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
1839 pcidev
[devind
].pd_busnr
,
1840 pcidev
[devind
].pd_dev
,
1841 pcidev
[devind
].pd_func
, vid
, did
);
1844 /* Assume that the BIOS initialized the secondary bus
1847 sbusn
= pci_attr_r8_u(devind
, PPB_SECBN
);
1849 if (nr_pcibus
>= NR_PCIBUS
)
1850 panic("too many PCI busses: %d", nr_pcibus
);
1853 pcibus
[ind
].pb_type
= PBT_PCIBRIDGE
;
1854 pcibus
[ind
].pb_needinit
= 1;
1855 pcibus
[ind
].pb_isabridge_dev
= -1;
1856 pcibus
[ind
].pb_isabridge_type
= 0;
1857 pcibus
[ind
].pb_devind
= devind
;
1858 pcibus
[ind
].pb_busnr
= sbusn
;
1859 pcibus
[ind
].pb_rreg8
= pcibus
[busind
].pb_rreg8
;
1860 pcibus
[ind
].pb_rreg16
= pcibus
[busind
].pb_rreg16
;
1861 pcibus
[ind
].pb_rreg32
= pcibus
[busind
].pb_rreg32
;
1862 pcibus
[ind
].pb_wreg8
= pcibus
[busind
].pb_wreg8
;
1863 pcibus
[ind
].pb_wreg16
= pcibus
[busind
].pb_wreg16
;
1864 pcibus
[ind
].pb_wreg32
= pcibus
[busind
].pb_wreg32
;
1868 pcibus
[ind
].pb_rsts
= pcibr_std_rsts
;
1869 pcibus
[ind
].pb_wsts
= pcibr_std_wsts
;
1872 pcibus
[ind
].pb_type
= PBT_CARDBUS
;
1873 pcibus
[ind
].pb_rsts
= pcibr_cb_rsts
;
1874 pcibus
[ind
].pb_wsts
= pcibr_cb_wsts
;
1877 pcibus
[ind
].pb_rsts
= pcibr_via_rsts
;
1878 pcibus
[ind
].pb_wsts
= pcibr_via_wsts
;
1881 panic("unknown PCI-PCI bridge type: %d", type
);
1886 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1887 ind
, sbusn
, pci_attr_r8_u(devind
, PPB_SUBORDBN
));
1891 printf("Secondary bus number not initialized\n");
1894 pcibus
[ind
].pb_needinit
= 0;
1898 /* Look for PCI bridges */
1903 /*===========================================================================*
1905 *===========================================================================*/
1906 PRIVATE
int get_busind(busnr
)
1911 for (i
= 0; i
<nr_pcibus
; i
++)
1913 if (pcibus
[i
].pb_busnr
== busnr
)
1916 panic("get_busind: can't find bus: %d", busnr
);
1919 /*===========================================================================*
1921 *===========================================================================*/
1922 PRIVATE
int do_piix(int devind
)
1924 int i
, s
, irqrc
, irq
;
1925 u32_t elcr1
, elcr2
, elcr
;
1928 printf("in piix\n");
1931 if (OK
!= (s
=sys_inb(PIIX_ELCR1
, &elcr1
)))
1932 printf("Warning, sys_inb failed: %d\n", s
);
1933 if (OK
!= (s
=sys_inb(PIIX_ELCR2
, &elcr2
)))
1934 printf("Warning, sys_inb failed: %d\n", s
);
1936 elcr1
= inb(PIIX_ELCR1
);
1937 elcr2
= inb(PIIX_ELCR2
);
1939 elcr
= elcr1
| (elcr2
<< 8);
1940 for (i
= 0; i
<4; i
++)
1942 irqrc
= pci_attr_r8_u(devind
, PIIX_PIRQRCA
+i
);
1943 if (irqrc
& PIIX_IRQ_DI
)
1946 printf("INT%c: disabled\n", 'A'+i
);
1950 irq
= irqrc
& PIIX_IRQ_MASK
;
1952 printf("INT%c: %d\n", 'A'+i
, irq
);
1953 if (!(elcr
& (1 << irq
)))
1958 "(warning) IRQ %d is not level triggered\n",
1968 /*===========================================================================*
1970 *===========================================================================*/
1971 PRIVATE
int do_amd_isabr(int devind
)
1973 int i
, busnr
, dev
, func
, xdevind
, irq
, edge
;
1977 /* Find required function */
1978 func
= AMD_ISABR_FUNC
;
1979 busnr
= pcidev
[devind
].pd_busnr
;
1980 dev
= pcidev
[devind
].pd_dev
;
1982 /* Fake a device with the required function */
1983 if (nr_pcidev
>= NR_PCIDEV
)
1984 panic("too many PCI devices: %d", nr_pcidev
);
1986 pcidev
[xdevind
].pd_busnr
= busnr
;
1987 pcidev
[xdevind
].pd_dev
= dev
;
1988 pcidev
[xdevind
].pd_func
= func
;
1989 pcidev
[xdevind
].pd_inuse
= 1;
1992 levmask
= pci_attr_r8_u(xdevind
, AMD_ISABR_PCIIRQ_LEV
);
1993 pciirq
= pci_attr_r16(xdevind
, AMD_ISABR_PCIIRQ_ROUTE
);
1994 for (i
= 0; i
<4; i
++)
1996 edge
= (levmask
>> i
) & 1;
1997 irq
= (pciirq
>> (4*i
)) & 0xf;
2001 printf("INT%c: disabled\n", 'A'+i
);
2006 printf("INT%c: %d\n", 'A'+i
, irq
);
2010 "(warning) IRQ %d is not level triggered\n",
2020 /*===========================================================================*
2022 *===========================================================================*/
2023 PRIVATE
int do_sis_isabr(int devind
)
2028 for (i
= 0; i
<4; i
++)
2030 irq
= pci_attr_r8_u(devind
, SIS_ISABR_IRQ_A
+i
);
2031 if (irq
& SIS_IRQ_DISABLED
)
2034 printf("INT%c: disabled\n", 'A'+i
);
2038 irq
&= SIS_IRQ_MASK
;
2040 printf("INT%c: %d\n", 'A'+i
, irq
);
2047 /*===========================================================================*
2049 *===========================================================================*/
2050 PRIVATE
int do_via_isabr(int devind
)
2055 levmask
= pci_attr_r8_u(devind
, VIA_ISABR_EL
);
2058 for (i
= 0; i
<4; i
++)
2063 edge
= (levmask
& VIA_ISABR_EL_INTA
);
2064 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R2
) >> 4;
2067 edge
= (levmask
& VIA_ISABR_EL_INTB
);
2068 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R2
);
2071 edge
= (levmask
& VIA_ISABR_EL_INTC
);
2072 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R3
) >> 4;
2075 edge
= (levmask
& VIA_ISABR_EL_INTD
);
2076 irq
= pci_attr_r8_u(devind
, VIA_ISABR_IRQ_R1
) >> 4;
2085 printf("INT%c: disabled\n", 'A'+i
);
2090 printf("INT%c: %d\n", 'A'+i
, irq
);
2094 "(warning) IRQ %d is not level triggered\n",
2105 /*===========================================================================*
2107 *===========================================================================*/
2108 PRIVATE
void report_vga(devind
)
2111 /* Report the amount of video memory. This is needed by the X11R6
2112 * postinstall script to chmem the X server. Hopefully this can be
2113 * removed when we get virtual memory.
2115 size_t amount
, size
;
2119 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
2121 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
)
2123 size
= pcidev
[devind
].pd_bar
[i
].pb_size
;
2130 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
2131 pcidev
[devind
].pd_busnr
,
2132 pcidev
[devind
].pd_dev
,
2133 pcidev
[devind
].pd_func
,
2140 /*===========================================================================*
2142 *===========================================================================*/
2143 PRIVATE
char *pci_vid_name(vid
)
2148 for (i
= 0; pci_vendor_table
[i
].name
; i
++)
2150 if (pci_vendor_table
[i
].vid
== vid
)
2151 return pci_vendor_table
[i
].name
;
2156 /*===========================================================================*
2157 * pci_baseclass_name *
2158 *===========================================================================*/
2159 PRIVATE
char *pci_baseclass_name(baseclass
)
2164 for (i
= 0; pci_baseclass_table
[i
].name
; i
++)
2166 if (pci_baseclass_table
[i
].baseclass
== baseclass
)
2167 return pci_baseclass_table
[i
].name
;
2172 /*===========================================================================*
2173 * pci_subclass_name *
2174 *===========================================================================*/
2175 PRIVATE
char *pci_subclass_name(baseclass
, subclass
, infclass
)
2182 for (i
= 0; pci_subclass_table
[i
].name
; i
++)
2184 if (pci_subclass_table
[i
].baseclass
!= baseclass
)
2186 if (pci_subclass_table
[i
].subclass
!= subclass
)
2188 if (pci_subclass_table
[i
].infclass
!= infclass
&&
2189 pci_subclass_table
[i
].infclass
!= (u16_t
)-1)
2193 return pci_subclass_table
[i
].name
;
2198 /*===========================================================================*
2200 *===========================================================================*/
2201 PRIVATE
void ntostr(n
, str
, end
)
2218 tmpstr
[i
]= '0' + (n
%10);
2237 /*===========================================================================*
2239 *===========================================================================*/
2240 PRIVATE u16_t
pci_attr_rsts(devind
)
2245 busnr
= pcidev
[devind
].pd_busnr
;
2246 busind
= get_busind(busnr
);
2247 return pcibus
[busind
].pb_rsts(busind
);
2251 /*===========================================================================*
2253 *===========================================================================*/
2254 PRIVATE u16_t
pcibr_std_rsts(busind
)
2259 devind
= pcibus
[busind
].pb_devind
;
2260 return pci_attr_r16(devind
, PPB_SSTS
);
2263 /*===========================================================================*
2265 *===========================================================================*/
2266 PRIVATE
void pcibr_std_wsts(busind
, value
)
2271 devind
= pcibus
[busind
].pb_devind
;
2274 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2275 busind
, value
, devind
);
2277 pci_attr_w16(devind
, PPB_SSTS
, value
);
2280 /*===========================================================================*
2282 *===========================================================================*/
2283 PRIVATE u16_t
pcibr_cb_rsts(busind
)
2287 devind
= pcibus
[busind
].pb_devind
;
2289 return pci_attr_r16(devind
, CBB_SSTS
);
2292 /*===========================================================================*
2294 *===========================================================================*/
2295 PRIVATE
void pcibr_cb_wsts(busind
, value
)
2300 devind
= pcibus
[busind
].pb_devind
;
2303 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2304 busind
, value
, devind
);
2306 pci_attr_w16(devind
, CBB_SSTS
, value
);
2309 /*===========================================================================*
2311 *===========================================================================*/
2312 PRIVATE u16_t
pcibr_via_rsts(busind
)
2316 devind
= pcibus
[busind
].pb_devind
;
2321 /*===========================================================================*
2323 *===========================================================================*/
2324 PRIVATE
void pcibr_via_wsts(busind
, value
)
2329 devind
= pcibus
[busind
].pb_devind
;
2332 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2333 busind
, value
, devind
);
2337 /*===========================================================================*
2339 *===========================================================================*/
2340 PRIVATE
void pci_attr_wsts(int devind
, u16_t value
)
2344 busnr
= pcidev
[devind
].pd_busnr
;
2345 busind
= get_busind(busnr
);
2346 pcibus
[busind
].pb_wsts(busind
, value
);
2350 /*===========================================================================*
2352 *===========================================================================*/
2353 PRIVATE u8_t
pcii_rreg8(busind
, devind
, port
)
2361 v
= PCII_RREG8_(pcibus
[busind
].pb_busnr
,
2362 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2365 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2366 printf("PCI: warning, sys_outl failed: %d\n", s
);
2368 outl(PCII_CONFADD
, PCII_UNSEL
);
2371 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2372 busind
, devind
, port
,
2373 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2374 pcidev
[devind
].pd_func
, v
);
2379 /*===========================================================================*
2381 *===========================================================================*/
2382 PRIVATE u16_t
pcii_rreg16(busind
, devind
, port
)
2390 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
,
2391 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2394 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2395 printf("PCI: warning, sys_outl failed: %d\n");
2397 outl(PCII_CONFADD
, PCII_UNSEL
);
2400 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2401 busind
, devind
, port
,
2402 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2403 pcidev
[devind
].pd_func
, v
);
2408 /*===========================================================================*
2410 *===========================================================================*/
2411 PRIVATE u32_t
pcii_rreg32(busind
, devind
, port
)
2419 v
= PCII_RREG32_(pcibus
[busind
].pb_busnr
,
2420 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2423 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2424 printf("PCI: warning, sys_outl failed: %d\n", s
);
2426 outl(PCII_CONFADD
, PCII_UNSEL
);
2429 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2430 busind
, devind
, port
,
2431 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2432 pcidev
[devind
].pd_func
, v
);
2437 /*===========================================================================*
2439 *===========================================================================*/
2440 PRIVATE
void pcii_wreg8(busind
, devind
, port
, value
)
2448 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2449 busind
, devind
, port
, value
,
2450 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2451 pcidev
[devind
].pd_func
);
2453 PCII_WREG8_(pcibus
[busind
].pb_busnr
,
2454 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2457 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2458 printf("PCI: warning, sys_outl failed: %d\n", s
);
2460 outl(PCII_CONFADD
, PCII_UNSEL
);
2464 /*===========================================================================*
2466 *===========================================================================*/
2467 PRIVATE
void pcii_wreg16(busind
, devind
, port
, value
)
2475 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2476 busind
, devind
, port
, value
,
2477 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2478 pcidev
[devind
].pd_func
);
2480 PCII_WREG16_(pcibus
[busind
].pb_busnr
,
2481 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2484 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2485 printf("PCI: warning, sys_outl failed: %d\n", s
);
2487 outl(PCII_CONFADD
, PCII_UNSEL
);
2491 /*===========================================================================*
2493 *===========================================================================*/
2494 PRIVATE
void pcii_wreg32(busind
, devind
, port
, value
)
2502 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2503 busind
, devind
, port
, value
,
2504 pcibus
[busind
].pb_busnr
, pcidev
[devind
].pd_dev
,
2505 pcidev
[devind
].pd_func
);
2507 PCII_WREG32_(pcibus
[busind
].pb_busnr
,
2508 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2511 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2512 printf("PCI: warning, sys_outl failed: %d\n");
2514 outl(PCII_CONFADD
, PCII_UNSEL
);
2518 /*===========================================================================*
2520 *===========================================================================*/
2521 PRIVATE u16_t
pcii_rsts(busind
)
2527 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
, 0, 0, PCI_SR
);
2529 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2530 printf("PCI: warning, sys_outl failed: %d\n", s
);
2532 outl(PCII_CONFADD
, PCII_UNSEL
);
2537 /*===========================================================================*
2539 *===========================================================================*/
2540 PRIVATE
void pcii_wsts(busind
, value
)
2545 PCII_WREG16_(pcibus
[busind
].pb_busnr
, 0, 0, PCI_SR
, value
);
2547 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2548 printf("PCI: warning, sys_outl failed: %d\n", s
);
2550 outl(PCII_CONFADD
, PCII_UNSEL
);
2555 /*===========================================================================*
2556 * print_capabilities *
2557 *===========================================================================*/
2558 PRIVATE
void print_capabilities(devind
)
2561 u8_t status
, capptr
, type
, next
, subtype
;
2564 /* Check capabilities bit in the device status register */
2565 status
= pci_attr_r16(devind
, PCI_SR
);
2566 if (!(status
& PSR_CAPPTR
))
2569 capptr
= (pci_attr_r8_u(devind
, PCI_CAPPTR
) & PCI_CP_MASK
);
2572 type
= pci_attr_r8_u(devind
, capptr
+CAP_TYPE
);
2573 next
= (pci_attr_r8_u(devind
, capptr
+CAP_NEXT
) & PCI_CP_MASK
);
2576 case 1: str
= "PCI Power Management"; break;
2577 case 2: str
= "AGP"; break;
2578 case 3: str
= "Vital Product Data"; break;
2579 case 4: str
= "Slot Identification"; break;
2580 case 5: str
= "Message Signaled Interrupts"; break;
2581 case 6: str
= "CompactPCI Hot Swap"; break;
2582 case 8: str
= "AMD HyperTransport"; break;
2583 case 0xf: str
= "Secure Device"; break;
2584 default: str
= "(unknown type)"; break;
2587 printf(" @0x%x (0x%08x): capability type 0x%x: %s",
2588 capptr
, pci_attr_r32_u(devind
, capptr
), type
, str
);
2590 print_hyper_cap(devind
, capptr
);
2591 else if (type
== 0x0f)
2593 subtype
= (pci_attr_r8_u(devind
, capptr
+2) & 0x07);
2596 case 0: str
= "Device Exclusion Vector"; break;
2597 case 3: str
= "IOMMU"; break;
2598 default: str
= "(unknown type)"; break;
2600 printf(", sub type 0%o: %s", subtype
, str
);
2608 /*===========================================================================*
2610 *===========================================================================*/
2611 PRIVATE
int visible(aclp
, devind
)
2612 struct rs_pci
*aclp
;
2619 return TRUE
; /* Should be changed when ACLs become
2622 /* Check whether the caller is allowed to get this device. */
2623 for (i
= 0; i
<aclp
->rsp_nr_device
; i
++)
2625 if (aclp
->rsp_device
[i
].vid
== pcidev
[devind
].pd_vid
&&
2626 aclp
->rsp_device
[i
].did
== pcidev
[devind
].pd_did
)
2631 if (!aclp
->rsp_nr_class
)
2634 class_id
= (pcidev
[devind
].pd_baseclass
<< 16) |
2635 (pcidev
[devind
].pd_subclass
<< 8) |
2636 pcidev
[devind
].pd_infclass
;
2637 for (i
= 0; i
<aclp
->rsp_nr_class
; i
++)
2639 if (aclp
->rsp_class
[i
].class ==
2640 (class_id
& aclp
->rsp_class
[i
].mask
))
2649 /*===========================================================================*
2651 *===========================================================================*/
2652 PRIVATE
void print_hyper_cap(devind
, capptr
)
2661 v
= pci_attr_r32_u(devind
, capptr
);
2662 printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr
);
2663 cmd
= (v
>> 16) & 0xffff;
2667 printf(" WarmReset");
2672 printf(" DblEnded");
2675 printf(" DevNum %d", (v
& 0x7C0000) >> 18);
2678 type0
= (cmd
& 0xE000) >> 13;
2679 type1
= (cmd
& 0xF800) >> 11;
2680 if (type0
== 0 || type0
== 1)
2682 printf("Capability Type: %s\n",
2683 type0
== 0 ? "Slave or Primary Interface" :
2684 "Host or Secondary Interface");
2689 printf(" Capability Type 0x%x", type1
);
2693 printf(" undecoded 0x%x\n", cmd
);
2696 printf("print_hyper_cap: off 4 (ctl): 0x%x\n",
2697 pci_attr_r32_u(devind
, capptr
+4));
2698 printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n",
2699 pci_attr_r32_u(devind
, capptr
+8));
2700 printf("print_hyper_cap: off 12 (cap): 0x%x\n",
2701 pci_attr_r32_u(devind
, capptr
+12));
2702 printf("print_hyper_cap: off 16 (buf count): 0x%x\n",
2703 pci_attr_r32_u(devind
, capptr
+16));
2704 v
= pci_attr_r32_u(devind
, capptr
+20);
2705 printf("print_hyper_cap: @0x%x, off 20 (bus nr): ",
2707 printf("prim %d", v
& 0xff);
2708 printf(", sec %d", (v
>> 8) & 0xff);
2709 printf(", sub %d", (v
>> 16) & 0xff);
2711 printf(", reserved %d", (v
>> 24) & 0xff);
2713 printf("print_hyper_cap: off 24 (type): 0x%x\n",
2714 pci_attr_r32_u(devind
, capptr
+24));
2719 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $