5 Configure devices on the PCI bus
7 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
10 #include "../drivers.h"
11 #define NDEBUG /* disable assertions */
15 #include <minix/com.h>
17 #include <minix/syslib.h>
21 #include "pci_intel.h"
29 #define irq_mode_pci(irq) ((void)0)
35 #include <minix/sysutil.h>
40 #define PBT_INTEL_HOST 1
41 #define PBT_PCIBRIDGE 2
44 #define BAM_NR 6 /* Number of base-address registers */
53 int pb_isabridge_type
;
57 u8_t (*pb_rreg8
)(int busind
, int devind
, int port
);
58 u16_t (*pb_rreg16
)(int busind
, int devind
, int port
);
59 u32_t (*pb_rreg32
)(int busind
, int devind
, int port
);
60 void (*pb_wreg8
)(int busind
, int devind
, int port
, U8_t value
);
61 void (*pb_wreg16
)(int busind
, int devind
, int port
, U16_t value
);
62 void (*pb_wreg32
)(int busind
, int devind
, int port
, u32_t value
);
63 u16_t (*pb_rsts
)(int busind
);
64 void (*pb_wsts
)(int busind
, U16_t value
);
66 PRIVATE
int nr_pcibus
= 0;
90 char pd_name
[M3_STRING
];
94 #define PBF_IO 1 /* I/O else memory */
95 #define PBF_INCOMPLETE 2 /* not allocated */
97 PRIVATE
int nr_pcidev
= 0;
99 /* Work around the limitations of the PCI emulation in QEMU 0.7.1 */
100 PRIVATE
int qemu_pci
= 0;
102 FORWARD
_PROTOTYPE( void pci_intel_init
, (void) );
103 FORWARD
_PROTOTYPE( void probe_bus
, (int busind
) );
104 FORWARD
_PROTOTYPE( int is_duplicate
, (U8_t busnr
, U8_t dev
, U8_t func
) );
105 FORWARD
_PROTOTYPE( void record_irq
, (int devind
) );
106 FORWARD
_PROTOTYPE( void record_bars
, (int devind
) );
107 FORWARD
_PROTOTYPE( void record_bars_bridge
, (int devind
) );
108 FORWARD
_PROTOTYPE( void record_bars_cardbus
, (int devind
) );
109 FORWARD
_PROTOTYPE( void record_bar
, (int devind
, int bar_nr
) );
110 FORWARD
_PROTOTYPE( void complete_bridges
, (void) );
111 FORWARD
_PROTOTYPE( void complete_bars
, (void) );
112 FORWARD
_PROTOTYPE( void update_bridge4dev_io
, (int devind
,
113 u32_t io_base
, u32_t io_size
) );
114 FORWARD
_PROTOTYPE( int get_freebus
, (void) );
115 FORWARD
_PROTOTYPE( int do_isabridge
, (int busind
) );
116 FORWARD
_PROTOTYPE( void do_pcibridge
, (int busind
) );
117 FORWARD
_PROTOTYPE( int get_busind
, (int busnr
) );
118 FORWARD
_PROTOTYPE( int do_piix
, (int devind
) );
119 FORWARD
_PROTOTYPE( int do_amd_isabr
, (int devind
) );
120 FORWARD
_PROTOTYPE( int do_sis_isabr
, (int devind
) );
121 FORWARD
_PROTOTYPE( int do_via_isabr
, (int devind
) );
122 FORWARD
_PROTOTYPE( void report_vga
, (int devind
) );
123 FORWARD
_PROTOTYPE( char *pci_vid_name
, (U16_t vid
) );
124 FORWARD
_PROTOTYPE( char *pci_baseclass_name
, (U8_t baseclass
) );
125 FORWARD
_PROTOTYPE( char *pci_subclass_name
, (U8_t baseclass
,
126 U8_t subclass
, U8_t infclass
) );
127 FORWARD
_PROTOTYPE( void ntostr
, (unsigned n
, char **str
, char *end
) );
128 FORWARD
_PROTOTYPE( u16_t pci_attr_rsts
, (int devind
) );
129 FORWARD
_PROTOTYPE( void pci_attr_wsts
, (int devind
, U16_t value
) );
130 FORWARD
_PROTOTYPE( u16_t pcibr_std_rsts
, (int busind
) );
131 FORWARD
_PROTOTYPE( void pcibr_std_wsts
, (int busind
, U16_t value
) );
132 FORWARD
_PROTOTYPE( u16_t pcibr_cb_rsts
, (int busind
) );
133 FORWARD
_PROTOTYPE( void pcibr_cb_wsts
, (int busind
, U16_t value
) );
134 FORWARD
_PROTOTYPE( u16_t pcibr_via_rsts
, (int busind
) );
135 FORWARD
_PROTOTYPE( void pcibr_via_wsts
, (int busind
, U16_t value
) );
136 FORWARD
_PROTOTYPE( u8_t pcii_rreg8
, (int busind
, int devind
, int port
) );
137 FORWARD
_PROTOTYPE( u16_t pcii_rreg16
, (int busind
, int devind
,
139 FORWARD
_PROTOTYPE( u32_t pcii_rreg32
, (int busind
, int devind
,
141 FORWARD
_PROTOTYPE( void pcii_wreg8
, (int busind
, int devind
, int port
,
143 FORWARD
_PROTOTYPE( void pcii_wreg16
, (int busind
, int devind
, int port
,
145 FORWARD
_PROTOTYPE( void pcii_wreg32
, (int busind
, int devind
, int port
,
147 FORWARD
_PROTOTYPE( u16_t pcii_rsts
, (int busind
) );
148 FORWARD
_PROTOTYPE( void pcii_wsts
, (int busind
, U16_t value
) );
149 FORWARD
_PROTOTYPE( void print_capabilities
, (int devind
) );
150 FORWARD
_PROTOTYPE( int visible
, (struct rs_pci
*aclp
, int devind
) );
152 /*===========================================================================*
153 * helper functions for I/O *
154 *===========================================================================*/
155 PUBLIC
unsigned pci_inb(U16_t port
) {
158 if ((s
=sys_inb(port
, &value
)) !=OK
)
159 printf("PCI: warning, sys_inb failed: %d\n", s
);
162 PUBLIC
unsigned pci_inw(U16_t port
) {
165 if ((s
=sys_inw(port
, &value
)) !=OK
)
166 printf("PCI: warning, sys_inw failed: %d\n", s
);
169 PUBLIC
unsigned pci_inl(U16_t port
) {
172 if ((s
=sys_inl(port
, &value
)) !=OK
)
173 printf("PCI: warning, sys_inl failed: %d\n", s
);
176 PUBLIC
void pci_outb(U16_t port
, U8_t value
) {
178 if ((s
=sys_outb(port
, value
)) !=OK
)
179 printf("PCI: warning, sys_outb failed: %d\n", s
);
181 PUBLIC
void pci_outw(U16_t port
, U16_t value
) {
183 if ((s
=sys_outw(port
, value
)) !=OK
)
184 printf("PCI: warning, sys_outw failed: %d\n", s
);
186 PUBLIC
void pci_outl(U16_t port
, U32_t value
) {
188 if ((s
=sys_outl(port
, value
)) !=OK
)
189 printf("PCI: warning, sys_outl failed: %d\n", s
);
192 /*===========================================================================*
194 *===========================================================================*/
195 PUBLIC
void pci_init()
197 static int first_time
= 1;
205 env_parse("qemu_pci", "d", 0, &v
, 0, 1);
209 env_parse("pci_debug", "d", 0, &v
, 0, 1);
212 /* We don't expect to interrupted */
213 assert(first_time
== 1);
216 /* Only Intel (compatible) PCI controllers are supported at the
224 /*===========================================================================*
226 *===========================================================================*/
227 PUBLIC
int pci_find_dev(bus
, dev
, func
, devindp
)
235 for (devind
= 0; devind
< nr_pcidev
; devind
++)
237 if (pcidev
[devind
].pd_busnr
== bus
&&
238 pcidev
[devind
].pd_dev
== dev
&&
239 pcidev
[devind
].pd_func
== func
)
244 if (devind
>= nr_pcidev
)
247 if (pcidev
[devind
].pd_inuse
)
254 /*===========================================================================*
256 *===========================================================================*/
257 PUBLIC
int pci_first_dev_a(aclp
, devindp
, vidp
, didp
)
265 for (devind
= 0; devind
< nr_pcidev
; devind
++)
268 if (pcidev
[devind
].pd_inuse
)
271 if (!visible(aclp
, devind
))
275 if (devind
>= nr_pcidev
)
278 *vidp
= pcidev
[devind
].pd_vid
;
279 *didp
= pcidev
[devind
].pd_did
;
283 /*===========================================================================*
285 *===========================================================================*/
286 PUBLIC
int pci_next_dev_a(aclp
, devindp
, vidp
, didp
)
294 for (devind
= *devindp
+1; devind
< nr_pcidev
; devind
++)
297 if (pcidev
[devind
].pd_inuse
)
300 if (!visible(aclp
, devind
))
304 if (devind
>= nr_pcidev
)
307 *vidp
= pcidev
[devind
].pd_vid
;
308 *didp
= pcidev
[devind
].pd_did
;
312 /*===========================================================================*
314 *===========================================================================*/
315 PUBLIC
int pci_reserve3(devind
, proc
, name
)
325 assert(devind
<= nr_pcidev
);
326 if(pcidev
[devind
].pd_inuse
)
328 pcidev
[devind
].pd_inuse
= 1;
329 strcpy(pcidev
[devind
].pd_name
, name
);
331 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
333 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_INCOMPLETE
)
335 printf("pci_reserve3: BAR %d is incomplete\n", i
);
338 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
)
340 ior
.ior_base
= pcidev
[devind
].pd_bar
[i
].pb_base
;
341 ior
.ior_limit
= ior
.ior_base
+
342 pcidev
[devind
].pd_bar
[i
].pb_size
-1;
346 "pci_reserve3: for proc %d, adding I/O range [0x%x..0x%x]\n",
347 proc
, ior
.ior_base
, ior
.ior_limit
);
349 r
= sys_privctl(proc
, SYS_PRIV_ADD_IO
, 0, &ior
);
352 printf("sys_privctl failed for proc %d: %d\n",
358 mr
.mr_base
= pcidev
[devind
].pd_bar
[i
].pb_base
;
359 mr
.mr_limit
= mr
.mr_base
+
360 pcidev
[devind
].pd_bar
[i
].pb_size
-1;
364 "pci_reserve3: for proc %d, should add memory range [0x%x..0x%x]\n",
365 proc
, mr
.mr_base
, mr
.mr_limit
);
367 r
= sys_privctl(proc
, SYS_PRIV_ADD_MEM
, 0, &mr
);
370 printf("sys_privctl failed for proc %d: %d\n",
375 ilr
= pcidev
[devind
].pd_ilr
;
376 if (ilr
!= PCI_ILR_UNKNOWN
)
378 if(debug
) printf("pci_reserve3: adding IRQ %d\n", ilr
);
379 r
= sys_privctl(proc
, SYS_PRIV_ADD_IRQ
, ilr
, NULL
);
382 printf("sys_privctl failed for proc %d: %d\n",
391 /*===========================================================================*
393 *===========================================================================*/
394 PUBLIC
void pci_release(name
)
399 for (i
= 0; i
<nr_pcidev
; i
++)
401 if (!pcidev
[i
].pd_inuse
)
403 if (strcmp(pcidev
[i
].pd_name
, name
) != 0)
405 pcidev
[i
].pd_inuse
= 0;
410 /*===========================================================================*
412 *===========================================================================*/
413 PUBLIC
void pci_ids(devind
, vidp
, didp
)
418 assert(devind
<= nr_pcidev
);
419 *vidp
= pcidev
[devind
].pd_vid
;
420 *didp
= pcidev
[devind
].pd_did
;
423 /*===========================================================================*
425 *===========================================================================*/
426 PUBLIC
void pci_rescan_bus(busnr
)
431 busind
= get_busind(busnr
);
434 /* Allocate bus numbers for uninitialized bridges */
437 /* Allocate I/O and memory resources for uninitialized devices */
441 /*===========================================================================*
443 *===========================================================================*/
444 PUBLIC
char *pci_slot_name(devind
)
447 static char label
[]= "ddd.ddd.ddd";
452 end
= label
+sizeof(label
);
454 ntostr(pcidev
[devind
].pd_busnr
, &p
, end
);
457 ntostr(pcidev
[devind
].pd_dev
, &p
, end
);
460 ntostr(pcidev
[devind
].pd_func
, &p
, end
);
465 /*===========================================================================*
467 *===========================================================================*/
468 PUBLIC
char *pci_dev_name(vid
, did
)
474 for (i
= 0; pci_device_table
[i
].name
; i
++)
476 if (pci_device_table
[i
].vid
== vid
&&
477 pci_device_table
[i
].did
== did
)
479 return pci_device_table
[i
].name
;
485 /*===========================================================================*
487 *===========================================================================*/
488 PUBLIC u8_t
pci_attr_r8(devind
, port
)
494 busnr
= pcidev
[devind
].pd_busnr
;
495 busind
= get_busind(busnr
);
496 return pcibus
[busind
].pb_rreg8(busind
, devind
, port
);
499 /*===========================================================================*
501 *===========================================================================*/
502 PUBLIC u16_t
pci_attr_r16(devind
, port
)
508 busnr
= pcidev
[devind
].pd_busnr
;
509 busind
= get_busind(busnr
);
510 return pcibus
[busind
].pb_rreg16(busind
, devind
, port
);
513 /*===========================================================================*
515 *===========================================================================*/
516 PUBLIC u32_t
pci_attr_r32(devind
, port
)
522 busnr
= pcidev
[devind
].pd_busnr
;
523 busind
= get_busind(busnr
);
524 return pcibus
[busind
].pb_rreg32(busind
, devind
, port
);
527 /*===========================================================================*
529 *===========================================================================*/
530 PUBLIC
void pci_attr_w8(devind
, port
, value
)
537 busnr
= pcidev
[devind
].pd_busnr
;
538 busind
= get_busind(busnr
);
539 pcibus
[busind
].pb_wreg8(busind
, devind
, port
, value
);
542 /*===========================================================================*
544 *===========================================================================*/
545 PUBLIC
void pci_attr_w16(devind
, port
, value
)
552 busnr
= pcidev
[devind
].pd_busnr
;
553 busind
= get_busind(busnr
);
554 pcibus
[busind
].pb_wreg16(busind
, devind
, port
, value
);
557 /*===========================================================================*
559 *===========================================================================*/
560 PUBLIC
void pci_attr_w32(devind
, port
, value
)
567 busnr
= pcidev
[devind
].pd_busnr
;
568 busind
= get_busind(busnr
);
569 pcibus
[busind
].pb_wreg32(busind
, devind
, port
, value
);
572 /*===========================================================================*
574 *===========================================================================*/
575 PRIVATE
void pci_intel_init()
577 /* Try to detect a know PCI controller. Read the Vendor ID and
578 * the Device ID for function 0 of device 0.
579 * Two times the value 0xffff suggests a system without a (compatible)
582 u32_t bus
, dev
, func
;
584 int s
, i
, r
, busind
, busnr
;
591 vid
= PCII_RREG16_(bus
, dev
, func
, PCI_VID
);
592 did
= PCII_RREG16_(bus
, dev
, func
, PCI_DID
);
594 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
595 printf("PCI: warning, sys_outl failed: %d\n", s
);
597 outl(PCII_CONFADD
, PCII_UNSEL
);
600 if (vid
== 0xffff && did
== 0xffff)
601 return; /* Nothing here */
604 for (i
= 0; pci_intel_ctrl
[i
].vid
; i
++)
606 if (pci_intel_ctrl
[i
].vid
== vid
&&
607 pci_intel_ctrl
[i
].did
== did
)
613 if (!pci_intel_ctrl
[i
].vid
)
615 printf("pci_intel_init (warning): unknown PCI-controller:\n"
616 "\tvendor %04X (%s), device %04X\n",
617 vid
, pci_vid_name(vid
), did
);
621 if (nr_pcibus
>= NR_PCIBUS
)
622 panic("PCI","too many PCI busses", nr_pcibus
);
625 pcibus
[busind
].pb_type
= PBT_INTEL_HOST
;
626 pcibus
[busind
].pb_needinit
= 0;
627 pcibus
[busind
].pb_isabridge_dev
= -1;
628 pcibus
[busind
].pb_isabridge_type
= 0;
629 pcibus
[busind
].pb_devind
= -1;
630 pcibus
[busind
].pb_busnr
= 0;
631 pcibus
[busind
].pb_rreg8
= pcii_rreg8
;
632 pcibus
[busind
].pb_rreg16
= pcii_rreg16
;
633 pcibus
[busind
].pb_rreg32
= pcii_rreg32
;
634 pcibus
[busind
].pb_wreg8
= pcii_wreg8
;
635 pcibus
[busind
].pb_wreg16
= pcii_wreg16
;
636 pcibus
[busind
].pb_wreg32
= pcii_wreg32
;
637 pcibus
[busind
].pb_rsts
= pcii_rsts
;
638 pcibus
[busind
].pb_wsts
= pcii_wsts
;
640 dstr
= pci_dev_name(vid
, did
);
642 dstr
= "unknown device";
645 printf("pci_intel_init: %s (%04X/%04X)\n",
651 r
= do_isabridge(busind
);
654 busnr
= pcibus
[busind
].pb_busnr
;
656 /* Disable all devices for this bus */
657 for (i
= 0; i
<nr_pcidev
; i
++)
659 if (pcidev
[i
].pd_busnr
!= busnr
)
661 pcidev
[i
].pd_inuse
= 1;
666 /* Look for PCI bridges */
667 do_pcibridge(busind
);
669 /* Allocate bus numbers for uninitialized bridges */
672 /* Allocate I/O and memory resources for uninitialized devices */
676 /*===========================================================================*
678 *===========================================================================*/
679 PRIVATE
void probe_bus(busind
)
685 u8_t baseclass
, subclass
, infclass
;
690 printf("probe_bus(%d)\n", busind
);
692 if (nr_pcidev
>= NR_PCIDEV
)
693 panic("PCI","too many PCI devices", nr_pcidev
);
696 busnr
= pcibus
[busind
].pb_busnr
;
697 for (dev
= 0; dev
<32; dev
++)
700 for (func
= 0; func
< 8; func
++)
702 pcidev
[devind
].pd_busnr
= busnr
;
703 pcidev
[devind
].pd_dev
= dev
;
704 pcidev
[devind
].pd_func
= func
;
706 pci_attr_wsts(devind
,
707 PSR_SSE
|PSR_RMAS
|PSR_RTAS
);
708 vid
= pci_attr_r16(devind
, PCI_VID
);
709 did
= pci_attr_r16(devind
, PCI_DID
);
710 headt
= pci_attr_r8(devind
, PCI_HEADT
);
711 sts
= pci_attr_rsts(devind
);
714 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
715 vid
, did
, headt
, sts
);
721 break; /* Nothing here */
723 /* Scan all functions of a multifunction
729 if (sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
))
734 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
735 sts
& (PSR_SSE
|PSR_RMAS
|PSR_RTAS
));
740 break; /* Nothing here */
742 /* Scan all functions of a
743 * multifunction device.
749 dstr
= pci_dev_name(vid
, did
);
754 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
755 busind
, (unsigned long)dev
,
756 (unsigned long)func
, dstr
,
762 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
763 busind
, (unsigned long)dev
,
764 (unsigned long)func
, vid
,
765 pci_vid_name(vid
), did
);
767 printf("Device index: %d\n", devind
);
768 printf("Subsystem: Vid 0x%x, did 0x%x\n",
769 pci_attr_r16(devind
, PCI_SUBVID
),
770 pci_attr_r16(devind
, PCI_SUBDID
));
773 baseclass
= pci_attr_r8(devind
, PCI_BCR
);
774 subclass
= pci_attr_r8(devind
, PCI_SCR
);
775 infclass
= pci_attr_r8(devind
, PCI_PIFR
);
776 s
= pci_subclass_name(baseclass
, subclass
, infclass
);
778 s
= pci_baseclass_name(baseclass
);
781 s
= "(unknown class)";
785 printf("\tclass %s (%X/%X/%X)\n", s
,
786 baseclass
, subclass
, infclass
);
789 if (is_duplicate(busnr
, dev
, func
))
791 printf("\tduplicate!\n");
792 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
799 pcidev
[devind
].pd_baseclass
= baseclass
;
800 pcidev
[devind
].pd_subclass
= subclass
;
801 pcidev
[devind
].pd_infclass
= infclass
;
802 pcidev
[devind
].pd_vid
= vid
;
803 pcidev
[devind
].pd_did
= did
;
804 pcidev
[devind
].pd_inuse
= 0;
805 pcidev
[devind
].pd_bar_nr
= 0;
807 switch(headt
& PHT_MASK
)
813 record_bars_bridge(devind
);
816 record_bars_cardbus(devind
);
819 printf("\t%d.%d.%d: unknown header type %d\n",
825 print_capabilities(devind
);
827 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
828 if (t3
== PCI_T3_VGA
|| t3
== PCI_T3_VGA_OLD
)
831 if (nr_pcidev
>= NR_PCIDEV
)
832 panic("PCI","too many PCI devices", nr_pcidev
);
835 if (func
== 0 && !(headt
& PHT_MULTIFUNC
))
841 /*===========================================================================*
843 *===========================================================================*/
844 PRIVATE
int is_duplicate(busnr
, dev
, func
)
851 for (i
= 0; i
<nr_pcidev
; i
++)
853 if (pcidev
[i
].pd_busnr
== busnr
&&
854 pcidev
[i
].pd_dev
== dev
&&
855 pcidev
[i
].pd_func
== func
)
863 /*===========================================================================*
865 *===========================================================================*/
866 PRIVATE
void record_irq(devind
)
869 int ilr
, ipr
, busnr
, busind
, cb_devind
;
871 ilr
= pci_attr_r8(devind
, PCI_ILR
);
872 ipr
= pci_attr_r8(devind
, PCI_IPR
);
876 if (ipr
&& first
&& debug
)
879 printf("PCI: strange, BIOS assigned IRQ0\n");
881 ilr
= PCI_ILR_UNKNOWN
;
883 pcidev
[devind
].pd_ilr
= ilr
;
884 if (ilr
== PCI_ILR_UNKNOWN
&& !ipr
)
887 else if (ilr
!= PCI_ILR_UNKNOWN
&& ipr
)
890 printf("\tIRQ %d for INT%c\n", ilr
, 'A' + ipr
-1);
892 else if (ilr
!= PCI_ILR_UNKNOWN
)
895 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
896 ilr
, pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
897 pcidev
[devind
].pd_func
);
901 /* Check for cardbus devices */
902 busnr
= pcidev
[devind
].pd_busnr
;
903 busind
= get_busind(busnr
);
904 if (pcibus
[busind
].pb_type
== PBT_CARDBUS
)
906 cb_devind
= pcibus
[busind
].pb_devind
;
907 ilr
= pcidev
[cb_devind
].pd_ilr
;
908 if (ilr
!= PCI_ILR_UNKNOWN
)
913 "assigning IRQ %d to Cardbus device\n",
916 pci_attr_w8(devind
, PCI_ILR
, ilr
);
917 pcidev
[devind
].pd_ilr
= ilr
;
923 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
924 pcidev
[devind
].pd_busnr
, pcidev
[devind
].pd_dev
,
925 pcidev
[devind
].pd_func
, 'A' + ipr
-1);
930 /*===========================================================================*
932 *===========================================================================*/
933 PRIVATE
void record_bars(devind
)
936 int i
, j
, reg
, prefetch
, type
, clear_01
, clear_23
, pb_nr
;
939 for (i
= 0, reg
= PCI_BAR
; reg
<= PCI_BAR_6
; i
++, reg
+= 4)
941 record_bar(devind
, i
);
944 /* Special case code for IDE controllers in compatibility mode */
945 if (pcidev
[devind
].pd_baseclass
== PCI_BCR_MASS_STORAGE
&&
946 pcidev
[devind
].pd_subclass
== PCI_MS_IDE
)
951 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_PRI_NATIVE
))
956 "primary channel is not in native mode, clearing BARs 0 and 1\n");
960 if (!(pcidev
[devind
].pd_infclass
& PCI_IDE_SEC_NATIVE
))
965 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
971 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
973 pb_nr
= pcidev
[devind
].pd_bar
[i
].pb_nr
;
974 if ((pb_nr
== 0 || pb_nr
== 1) && clear_01
)
976 if (debug
) printf("skipping bar %d\n", pb_nr
);
979 if ((pb_nr
== 2 || pb_nr
== 3) && clear_23
)
981 if (debug
) printf("skipping bar %d\n", pb_nr
);
987 continue; /* No need to copy */
989 pcidev
[devind
].pd_bar
[j
]=
990 pcidev
[devind
].pd_bar
[i
];
993 pcidev
[devind
].pd_bar_nr
= j
;
997 /*===========================================================================*
998 * record_bars_bridge *
999 *===========================================================================*/
1000 PRIVATE
void record_bars_bridge(devind
)
1003 u32_t base
, limit
, size
;
1005 record_bar(devind
, 0);
1006 record_bar(devind
, 1);
1008 base
= ((pci_attr_r8(devind
, PPB_IOBASE
) & PPB_IOB_MASK
) << 8) |
1009 (pci_attr_r16(devind
, PPB_IOBASEU16
) << 16);
1011 ((pci_attr_r8(devind
, PPB_IOLIMIT
) & PPB_IOL_MASK
) << 8) |
1012 ((~PPB_IOL_MASK
& 0xff) << 8) |
1013 (pci_attr_r16(devind
, PPB_IOLIMITU16
) << 16);
1014 size
= limit
-base
+ 1;
1017 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1021 base
= ((pci_attr_r16(devind
, PPB_MEMBASE
) & PPB_MEMB_MASK
) << 16);
1023 ((pci_attr_r16(devind
, PPB_MEMLIMIT
) & PPB_MEML_MASK
) << 16) |
1024 ((~PPB_MEML_MASK
& 0xffff) << 16);
1025 size
= limit
-base
+ 1;
1028 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1032 /* Ignore the upper 32 bits */
1033 base
= ((pci_attr_r16(devind
, PPB_PFMEMBASE
) & PPB_PFMEMB_MASK
) << 16);
1035 ((pci_attr_r16(devind
, PPB_PFMEMLIMIT
) &
1036 PPB_PFMEML_MASK
) << 16) |
1037 ((~PPB_PFMEML_MASK
& 0xffff) << 16);
1038 size
= limit
-base
+ 1;
1042 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1047 /*===========================================================================*
1048 * record_bars_cardbus *
1049 *===========================================================================*/
1050 PRIVATE
void record_bars_cardbus(devind
)
1053 u32_t base
, limit
, size
;
1055 record_bar(devind
, 0);
1057 base
= pci_attr_r32(devind
, CBB_MEMBASE_0
);
1058 limit
= pci_attr_r32(devind
, CBB_MEMLIMIT_0
) |
1059 (~CBB_MEML_MASK
& 0xffffffff);
1060 size
= limit
-base
+ 1;
1063 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1067 base
= pci_attr_r32(devind
, CBB_MEMBASE_1
);
1068 limit
= pci_attr_r32(devind
, CBB_MEMLIMIT_1
) |
1069 (~CBB_MEML_MASK
& 0xffffffff);
1070 size
= limit
-base
+ 1;
1073 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1077 base
= pci_attr_r32(devind
, CBB_IOBASE_0
);
1078 limit
= pci_attr_r32(devind
, CBB_IOLIMIT_0
) |
1079 (~CBB_IOL_MASK
& 0xffffffff);
1080 size
= limit
-base
+ 1;
1083 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1087 base
= pci_attr_r32(devind
, CBB_IOBASE_1
);
1088 limit
= pci_attr_r32(devind
, CBB_IOLIMIT_1
) |
1089 (~CBB_IOL_MASK
& 0xffffffff);
1090 size
= limit
-base
+ 1;
1093 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1098 /*===========================================================================*
1100 *===========================================================================*/
1101 PRIVATE
void record_bar(devind
, bar_nr
)
1105 int reg
, prefetch
, type
, dev_bar_nr
;
1108 reg
= PCI_BAR
+4*bar_nr
;
1110 bar
= pci_attr_r32(devind
, reg
);
1111 if (bar
& PCI_BAR_IO
)
1114 pci_attr_w32(devind
, reg
, 0xffffffff);
1115 bar2
= pci_attr_r32(devind
, reg
);
1116 pci_attr_w32(devind
, reg
, bar
);
1118 bar
&= ~(u32_t
)3; /* Clear non-address bits */
1120 bar2
= (~bar2
& 0xffff)+1;
1123 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1127 dev_bar_nr
= pcidev
[devind
].pd_bar_nr
++;
1128 assert(dev_bar_nr
< BAR_NR
);
1129 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
= PBF_IO
;
1130 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_base
= bar
;
1131 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_size
= bar2
;
1132 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_nr
= bar_nr
;
1135 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1142 pci_attr_w32(devind
, reg
, 0xffffffff);
1143 bar2
= pci_attr_r32(devind
, reg
);
1144 pci_attr_w32(devind
, reg
, bar
);
1147 return; /* Reg. is not implemented */
1149 prefetch
= !!(bar
& PCI_BAR_PREFETCH
);
1150 type
= (bar
& PCI_BAR_TYPE
);
1151 bar
&= ~(u32_t
)0xf; /* Clear non-address bits */
1152 bar2
&= ~(u32_t
)0xf;
1156 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory\n",
1158 prefetch
? " prefetchable" : "");
1160 printf("type = 0x%x\n", type
);
1163 dev_bar_nr
= pcidev
[devind
].pd_bar_nr
++;
1164 assert(dev_bar_nr
< BAR_NR
);
1165 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
= 0;
1166 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_base
= bar
;
1167 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_size
= bar2
;
1168 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_nr
= bar_nr
;
1171 pcidev
[devind
].pd_bar
[dev_bar_nr
].pb_flags
|=
1177 /*===========================================================================*
1178 * complete_bridges *
1179 *===========================================================================*/
1180 PRIVATE
void complete_bridges()
1182 int i
, freebus
, devind
, prim_busnr
;
1184 for (i
= 0; i
<nr_pcibus
; i
++)
1186 if (!pcibus
[i
].pb_needinit
)
1188 printf("should allocate bus number for bus %d\n", i
);
1189 freebus
= get_freebus();
1190 printf("got bus number %d\n", freebus
);
1192 devind
= pcibus
[i
].pb_devind
;
1194 prim_busnr
= pcidev
[devind
].pd_busnr
;
1195 if (prim_busnr
!= 0)
1198 "complete_bridge: updating subordinate bus number not implemented\n");
1201 pcibus
[i
].pb_needinit
= 0;
1202 pcibus
[i
].pb_busnr
= freebus
;
1204 printf("devind = %d\n", devind
);
1205 printf("prim_busnr= %d\n", prim_busnr
);
1207 pci_attr_w8(devind
, PPB_PRIMBN
, prim_busnr
);
1208 pci_attr_w8(devind
, PPB_SECBN
, freebus
);
1209 pci_attr_w8(devind
, PPB_SUBORDBN
, freebus
);
1211 printf("CR = 0x%x\n", pci_attr_r16(devind
, PCI_CR
));
1212 printf("SECBLT = 0x%x\n", pci_attr_r8(devind
, PPB_SECBLT
));
1213 printf("BRIDGECTRL = 0x%x\n",
1214 pci_attr_r16(devind
, PPB_BRIDGECTRL
));
1218 /*===========================================================================*
1220 *===========================================================================*/
1221 PRIVATE
void complete_bars()
1223 int i
, j
, r
, bar_nr
, reg
;
1224 u32_t memgap_low
, memgap_high
, iogap_low
, iogap_high
, io_high
,
1225 base
, size
, v32
, diff1
, diff2
;
1229 r
= env_get_param("memory", memstr
, sizeof(memstr
));
1231 panic("pci", "env_get_param failed", r
);
1233 /* Set memgap_low to just above physical memory */
1238 base
= strtoul(cp
, &next
, 16);
1239 if (next
== cp
|| *next
!= ':')
1241 printf("PCI: bad memory environment string '%s'\n",
1243 panic(NULL
, NULL
, NO_NUM
);
1246 size
= strtoul(cp
, &next
, 16);
1247 if (next
== cp
|| (*next
!= ',' && *next
!= '\0'))
1249 printf("PCI: bad memory environment string '%s'\n",
1251 panic(NULL
, NULL
, NO_NUM
);
1255 if (base
+size
> memgap_low
)
1256 memgap_low
= base
+size
;
1259 memgap_high
= 0xfe000000; /* Leave space for the CPU (APIC) */
1263 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1264 memgap_low
, memgap_high
);
1267 /* Find the lowest memory base */
1268 for (i
= 0; i
<nr_pcidev
; i
++)
1270 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1272 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
)
1274 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1276 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1277 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1279 if (base
>= memgap_high
)
1280 continue; /* Not in the gap */
1281 if (base
+size
<= memgap_low
)
1282 continue; /* Not in the gap */
1284 /* Reduce the gap by the smallest amount */
1285 diff1
= base
+size
-memgap_low
;
1286 diff2
= memgap_high
-base
;
1289 memgap_low
= base
+size
;
1297 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1298 memgap_low
, memgap_high
);
1301 /* Should check main memory size */
1302 if (memgap_high
< memgap_low
)
1304 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1305 memgap_low
, memgap_high
);
1306 panic(NULL
, NULL
, NO_NUM
);
1309 iogap_high
= 0x10000;
1312 /* Find the free I/O space */
1313 for (i
= 0; i
<nr_pcidev
; i
++)
1315 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1317 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
))
1319 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
)
1321 base
= pcidev
[i
].pd_bar
[j
].pb_base
;
1322 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1323 if (base
>= iogap_high
)
1325 if (base
+size
<= iogap_low
)
1331 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
1332 i
, pcidev
[i
].pd_vid
, pcidev
[i
].pd_did
,
1336 if (base
+size
-iogap_low
< iogap_high
-base
)
1337 iogap_low
= base
+size
;
1343 if (iogap_high
< iogap_low
)
1347 printf("iogap_high too low, should panic\n");
1350 panic("pci", "iogap_high too low", iogap_high
);
1353 printf("I/O range = [0x%x..0x%x>\n", iogap_low
, iogap_high
);
1355 for (i
= 0; i
<nr_pcidev
; i
++)
1357 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1359 if (pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
)
1361 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1363 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1364 if (size
< PAGE_SIZE
)
1366 base
= memgap_high
-size
;
1367 base
&= ~(u32_t
)(size
-1);
1368 if (base
< memgap_low
)
1369 panic("pci", "memory base too low", base
);
1371 bar_nr
= pcidev
[i
].pd_bar
[j
].pb_nr
;
1372 reg
= PCI_BAR
+ 4*bar_nr
;
1373 v32
= pci_attr_r32(i
, reg
);
1374 pci_attr_w32(i
, reg
, v32
| base
);
1378 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1379 base
, size
, pcidev
[i
].pd_busnr
,
1380 pcidev
[i
].pd_dev
, pcidev
[i
].pd_func
,
1383 pcidev
[i
].pd_bar
[j
].pb_base
= base
;
1384 pcidev
[i
].pd_bar
[j
].pb_flags
&= ~PBF_INCOMPLETE
;
1387 io_high
= iogap_high
;
1388 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1390 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_IO
))
1392 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1394 size
= pcidev
[i
].pd_bar
[j
].pb_size
;
1395 base
= iogap_high
-size
;
1396 base
&= ~(u32_t
)(size
-1);
1398 /* Assume that ISA compatibility is required. Only
1399 * use the lowest 256 bytes out of every 1024 bytes.
1403 if (base
< iogap_low
)
1404 panic("pci", "I/O base too low", base
);
1407 bar_nr
= pcidev
[i
].pd_bar
[j
].pb_nr
;
1408 reg
= PCI_BAR
+ 4*bar_nr
;
1409 v32
= pci_attr_r32(i
, reg
);
1410 pci_attr_w32(i
, reg
, v32
| base
);
1414 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1415 base
, size
, pcidev
[i
].pd_busnr
,
1416 pcidev
[i
].pd_dev
, pcidev
[i
].pd_func
,
1419 pcidev
[i
].pd_bar
[j
].pb_base
= base
;
1420 pcidev
[i
].pd_bar
[j
].pb_flags
&= ~PBF_INCOMPLETE
;
1423 if (iogap_high
!= io_high
)
1425 update_bridge4dev_io(i
, iogap_high
,
1426 io_high
-iogap_high
);
1430 for (i
= 0; i
<nr_pcidev
; i
++)
1432 for (j
= 0; j
<pcidev
[i
].pd_bar_nr
; j
++)
1434 if (!(pcidev
[i
].pd_bar
[j
].pb_flags
& PBF_INCOMPLETE
))
1436 printf("should allocate resources for device %d\n", i
);
1441 /*===========================================================================*
1442 * update_bridge4dev_io *
1443 *===========================================================================*/
1444 PRIVATE
void update_bridge4dev_io(devind
, io_base
, io_size
)
1449 int busnr
, busind
, type
, br_devind
;
1452 busnr
= pcidev
[devind
].pd_busnr
;
1453 busind
= get_busind(busnr
);
1454 type
= pcibus
[busind
].pb_type
;
1455 if (type
== PBT_INTEL_HOST
)
1456 return; /* Nothing to do for host controller */
1457 if (type
== PBT_PCIBRIDGE
)
1460 "update_bridge4dev_io: not implemented for PCI bridges\n");
1463 if (type
!= PBT_CARDBUS
)
1464 panic("pci", "update_bridge4dev_io: strange bus type", type
);
1468 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1471 br_devind
= pcibus
[busind
].pb_devind
;
1472 pci_attr_w32(br_devind
, CBB_IOLIMIT_0
, io_base
+io_size
-1);
1473 pci_attr_w32(br_devind
, CBB_IOBASE_0
, io_base
);
1475 /* Enable I/O access. Enable busmaster access as well. */
1476 v16
= pci_attr_r16(devind
, PCI_CR
);
1477 pci_attr_w16(devind
, PCI_CR
, v16
| PCI_CR_IO_EN
| PCI_CR_MAST_EN
);
1480 /*===========================================================================*
1482 *===========================================================================*/
1483 PRIVATE
int get_freebus()
1488 for (i
= 0; i
<nr_pcibus
; i
++)
1490 if (pcibus
[i
].pb_needinit
)
1492 if (pcibus
[i
].pb_type
== PBT_INTEL_HOST
)
1494 if (pcibus
[i
].pb_busnr
<= freebus
)
1495 freebus
= pcibus
[i
].pb_busnr
+1;
1496 printf("get_freebus: should check suboridinate bus number\n");
1501 /*===========================================================================*
1503 *===========================================================================*/
1504 PRIVATE
int do_isabridge(busind
)
1507 int i
, j
, r
, type
, busnr
, unknown_bridge
, bridge_dev
;
1515 vid
= did
= 0; /* lint */
1516 busnr
= pcibus
[busind
].pb_busnr
;
1517 for (i
= 0; i
< nr_pcidev
; i
++)
1519 if (pcidev
[i
].pd_busnr
!= busnr
)
1521 t3
= ((pcidev
[i
].pd_baseclass
<< 16) |
1522 (pcidev
[i
].pd_subclass
<< 8) | pcidev
[i
].pd_infclass
);
1523 if (t3
== PCI_T3_ISA
)
1525 /* ISA bridge. Report if no supported bridge is
1531 vid
= pcidev
[i
].pd_vid
;
1532 did
= pcidev
[i
].pd_did
;
1533 for (j
= 0; pci_isabridge
[j
].vid
!= 0; j
++)
1535 if (pci_isabridge
[j
].vid
!= vid
)
1537 if (pci_isabridge
[j
].did
!= did
)
1539 if (pci_isabridge
[j
].checkclass
&&
1540 unknown_bridge
!= i
)
1542 /* This part of multifunction device is
1549 if (pci_isabridge
[j
].vid
)
1556 if (bridge_dev
!= -1)
1558 dstr
= pci_dev_name(vid
, did
);
1560 dstr
= "unknown device";
1563 printf("found ISA bridge (%04X/%04X) %s\n",
1566 pcibus
[busind
].pb_isabridge_dev
= bridge_dev
;
1567 type
= pci_isabridge
[j
].type
;
1568 pcibus
[busind
].pb_isabridge_type
= type
;
1572 r
= do_piix(bridge_dev
);
1575 r
= do_via_isabr(bridge_dev
);
1578 r
= do_amd_isabr(bridge_dev
);
1581 r
= do_sis_isabr(bridge_dev
);
1584 panic("PCI","unknown ISA bridge type", type
);
1589 if (unknown_bridge
== -1)
1593 printf("(warning) no ISA bridge found on bus %d\n",
1601 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
1602 pcidev
[unknown_bridge
].pd_vid
,
1603 pcidev
[unknown_bridge
].pd_did
, busind
);
1608 /*===========================================================================*
1610 *===========================================================================*/
1611 PRIVATE
void do_pcibridge(busind
)
1614 int i
, devind
, busnr
;
1617 u8_t sbusn
, baseclass
, subclass
, infclass
, headt
;
1620 vid
= did
= 0; /* lint */
1621 busnr
= pcibus
[busind
].pb_busnr
;
1622 for (devind
= 0; devind
< nr_pcidev
; devind
++)
1625 printf("do_pcibridge: trying %u.%u.%u\n",
1626 pcidev
[devind
].pd_busind
, pcidev
[devind
].pd_dev
,
1627 pcidev
[devind
].pd_func
);
1630 if (pcidev
[devind
].pd_busnr
!= busnr
)
1633 printf("wrong bus\n");
1638 vid
= pcidev
[devind
].pd_vid
;
1639 did
= pcidev
[devind
].pd_did
;
1640 for (i
= 0; pci_pcibridge
[i
].vid
!= 0; i
++)
1642 if (pci_pcibridge
[i
].vid
!= vid
)
1644 if (pci_pcibridge
[i
].did
!= did
)
1648 type
= pci_pcibridge
[i
].type
;
1649 if (pci_pcibridge
[i
].vid
== 0)
1651 headt
= pci_attr_r8(devind
, PCI_HEADT
);
1653 if ((headt
& PHT_MASK
) == PHT_BRIDGE
)
1655 else if ((headt
& PHT_MASK
) == PHT_CARDBUS
)
1660 printf("not a bridge\n");
1662 continue; /* Not a bridge */
1665 baseclass
= pci_attr_r8(devind
, PCI_BCR
);
1666 subclass
= pci_attr_r8(devind
, PCI_SCR
);
1667 infclass
= pci_attr_r8(devind
, PCI_PIFR
);
1668 t3
= ((baseclass
<< 16) | (subclass
<< 8) | infclass
);
1669 if (type
== PCI_PPB_STD
&&
1670 t3
!= PCI_T3_PCI2PCI
&&
1671 t3
!= PCI_T3_PCI2PCI_SUBTR
)
1674 "Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
1675 baseclass
, subclass
, infclass
,
1679 if (type
== PCI_PPB_CB
&&
1680 t3
!= PCI_T3_CARDBUS
)
1683 "Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
1684 baseclass
, subclass
, infclass
,
1692 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
1693 pcidev
[devind
].pd_busnr
,
1694 pcidev
[devind
].pd_dev
,
1695 pcidev
[devind
].pd_func
, vid
, did
);
1698 /* Assume that the BIOS initialized the secondary bus
1701 sbusn
= pci_attr_r8(devind
, PPB_SECBN
);
1703 printf("sbusn = %d\n", sbusn
);
1704 printf("subordn = %d\n", pci_attr_r8(devind
, PPB_SUBORDBN
));
1707 if (nr_pcibus
>= NR_PCIBUS
)
1708 panic("PCI","too many PCI busses", nr_pcibus
);
1711 pcibus
[ind
].pb_type
= PBT_PCIBRIDGE
;
1712 pcibus
[ind
].pb_needinit
= 1;
1713 pcibus
[ind
].pb_isabridge_dev
= -1;
1714 pcibus
[ind
].pb_isabridge_type
= 0;
1715 pcibus
[ind
].pb_devind
= devind
;
1716 pcibus
[ind
].pb_busnr
= sbusn
;
1717 pcibus
[ind
].pb_rreg8
= pcibus
[busind
].pb_rreg8
;
1718 pcibus
[ind
].pb_rreg16
= pcibus
[busind
].pb_rreg16
;
1719 pcibus
[ind
].pb_rreg32
= pcibus
[busind
].pb_rreg32
;
1720 pcibus
[ind
].pb_wreg8
= pcibus
[busind
].pb_wreg8
;
1721 pcibus
[ind
].pb_wreg16
= pcibus
[busind
].pb_wreg16
;
1722 pcibus
[ind
].pb_wreg32
= pcibus
[busind
].pb_wreg32
;
1726 pcibus
[ind
].pb_rsts
= pcibr_std_rsts
;
1727 pcibus
[ind
].pb_wsts
= pcibr_std_wsts
;
1730 pcibus
[ind
].pb_type
= PBT_CARDBUS
;
1731 pcibus
[ind
].pb_rsts
= pcibr_cb_rsts
;
1732 pcibus
[ind
].pb_wsts
= pcibr_cb_wsts
;
1735 pcibus
[ind
].pb_rsts
= pcibr_via_rsts
;
1736 pcibus
[ind
].pb_wsts
= pcibr_via_wsts
;
1739 panic("PCI","unknown PCI-PCI bridge type", type
);
1743 printf("Secondary bus number not initialized\n");
1746 pcibus
[ind
].pb_needinit
= 0;
1750 /* Look for PCI bridges */
1755 /*===========================================================================*
1757 *===========================================================================*/
1758 PRIVATE
int get_busind(busnr
)
1763 for (i
= 0; i
<nr_pcibus
; i
++)
1765 if (pcibus
[i
].pb_busnr
== busnr
)
1768 panic("pci", "get_busind: can't find bus", busnr
);
1771 /*===========================================================================*
1773 *===========================================================================*/
1774 PRIVATE
int do_piix(devind
)
1777 int i
, s
, dev
, func
, irqrc
, irq
;
1778 u32_t elcr1
, elcr2
, elcr
;
1781 printf("in piix\n");
1783 dev
= pcidev
[devind
].pd_dev
;
1784 func
= pcidev
[devind
].pd_func
;
1786 if (OK
!= (s
=sys_inb(PIIX_ELCR1
, &elcr1
)))
1787 printf("Warning, sys_inb failed: %d\n", s
);
1788 if (OK
!= (s
=sys_inb(PIIX_ELCR2
, &elcr2
)))
1789 printf("Warning, sys_inb failed: %d\n", s
);
1791 elcr1
= inb(PIIX_ELCR1
);
1792 elcr2
= inb(PIIX_ELCR2
);
1794 elcr
= elcr1
| (elcr2
<< 8);
1795 for (i
= 0; i
<4; i
++)
1797 irqrc
= pci_attr_r8(devind
, PIIX_PIRQRCA
+i
);
1798 if (irqrc
& PIIX_IRQ_DI
)
1801 printf("INT%c: disabled\n", 'A'+i
);
1805 irq
= irqrc
& PIIX_IRQ_MASK
;
1807 printf("INT%c: %d\n", 'A'+i
, irq
);
1808 if (!(elcr
& (1 << irq
)))
1813 "(warning) IRQ %d is not level triggered\n",
1823 /*===========================================================================*
1825 *===========================================================================*/
1826 PRIVATE
int do_amd_isabr(devind
)
1829 int i
, busnr
, dev
, func
, xdevind
, irq
, edge
;
1833 /* Find required function */
1834 func
= AMD_ISABR_FUNC
;
1835 busnr
= pcidev
[devind
].pd_busnr
;
1836 dev
= pcidev
[devind
].pd_dev
;
1838 /* Fake a device with the required function */
1839 if (nr_pcidev
>= NR_PCIDEV
)
1840 panic("PCI","too many PCI devices", nr_pcidev
);
1842 pcidev
[xdevind
].pd_busnr
= busnr
;
1843 pcidev
[xdevind
].pd_dev
= dev
;
1844 pcidev
[xdevind
].pd_func
= func
;
1845 pcidev
[xdevind
].pd_inuse
= 1;
1848 levmask
= pci_attr_r8(xdevind
, AMD_ISABR_PCIIRQ_LEV
);
1849 pciirq
= pci_attr_r16(xdevind
, AMD_ISABR_PCIIRQ_ROUTE
);
1850 for (i
= 0; i
<4; i
++)
1852 edge
= (levmask
>> i
) & 1;
1853 irq
= (pciirq
>> (4*i
)) & 0xf;
1857 printf("INT%c: disabled\n", 'A'+i
);
1862 printf("INT%c: %d\n", 'A'+i
, irq
);
1866 "(warning) IRQ %d is not level triggered\n",
1876 /*===========================================================================*
1878 *===========================================================================*/
1879 PRIVATE
int do_sis_isabr(devind
)
1882 int i
, dev
, func
, irq
;
1884 dev
= pcidev
[devind
].pd_dev
;
1885 func
= pcidev
[devind
].pd_func
;
1887 for (i
= 0; i
<4; i
++)
1889 irq
= pci_attr_r8(devind
, SIS_ISABR_IRQ_A
+i
);
1890 if (irq
& SIS_IRQ_DISABLED
)
1893 printf("INT%c: disabled\n", 'A'+i
);
1897 irq
&= SIS_IRQ_MASK
;
1899 printf("INT%c: %d\n", 'A'+i
, irq
);
1906 /*===========================================================================*
1908 *===========================================================================*/
1909 PRIVATE
int do_via_isabr(devind
)
1912 int i
, dev
, func
, irq
, edge
;
1915 dev
= pcidev
[devind
].pd_dev
;
1916 func
= pcidev
[devind
].pd_func
;
1917 levmask
= pci_attr_r8(devind
, VIA_ISABR_EL
);
1920 for (i
= 0; i
<4; i
++)
1925 edge
= (levmask
& VIA_ISABR_EL_INTA
);
1926 irq
= pci_attr_r8(devind
, VIA_ISABR_IRQ_R2
) >> 4;
1929 edge
= (levmask
& VIA_ISABR_EL_INTB
);
1930 irq
= pci_attr_r8(devind
, VIA_ISABR_IRQ_R2
);
1933 edge
= (levmask
& VIA_ISABR_EL_INTC
);
1934 irq
= pci_attr_r8(devind
, VIA_ISABR_IRQ_R3
) >> 4;
1937 edge
= (levmask
& VIA_ISABR_EL_INTD
);
1938 irq
= pci_attr_r8(devind
, VIA_ISABR_IRQ_R1
) >> 4;
1947 printf("INT%c: disabled\n", 'A'+i
);
1952 printf("INT%c: %d\n", 'A'+i
, irq
);
1956 "(warning) IRQ %d is not level triggered\n",
1966 /*===========================================================================*
1968 *===========================================================================*/
1969 PRIVATE
void report_vga(devind
)
1972 /* Report the amount of video memory. This is needed by the X11R6
1973 * postinstall script to chmem the X server. Hopefully this can be
1974 * removed when we get virtual memory.
1976 size_t amount
, size
;
1980 for (i
= 0; i
<pcidev
[devind
].pd_bar_nr
; i
++)
1982 if (pcidev
[devind
].pd_bar
[i
].pb_flags
& PBF_IO
)
1984 size
= pcidev
[devind
].pd_bar
[i
].pb_size
;
1991 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
1992 pcidev
[devind
].pd_busnr
,
1993 pcidev
[devind
].pd_dev
,
1994 pcidev
[devind
].pd_func
,
2000 /*===========================================================================*
2002 *===========================================================================*/
2003 PRIVATE
char *pci_vid_name(vid
)
2008 for (i
= 0; pci_vendor_table
[i
].name
; i
++)
2010 if (pci_vendor_table
[i
].vid
== vid
)
2011 return pci_vendor_table
[i
].name
;
2016 /*===========================================================================*
2017 * pci_baseclass_name *
2018 *===========================================================================*/
2019 PRIVATE
char *pci_baseclass_name(baseclass
)
2024 for (i
= 0; pci_baseclass_table
[i
].name
; i
++)
2026 if (pci_baseclass_table
[i
].baseclass
== baseclass
)
2027 return pci_baseclass_table
[i
].name
;
2032 /*===========================================================================*
2033 * pci_subclass_name *
2034 *===========================================================================*/
2035 PRIVATE
char *pci_subclass_name(baseclass
, subclass
, infclass
)
2042 for (i
= 0; pci_subclass_table
[i
].name
; i
++)
2044 if (pci_subclass_table
[i
].baseclass
!= baseclass
)
2046 if (pci_subclass_table
[i
].subclass
!= subclass
)
2048 if (pci_subclass_table
[i
].infclass
!= infclass
&&
2049 pci_subclass_table
[i
].infclass
!= (u16_t
)-1)
2053 return pci_subclass_table
[i
].name
;
2058 /*===========================================================================*
2060 *===========================================================================*/
2061 PRIVATE
void ntostr(n
, str
, end
)
2078 tmpstr
[i
]= '0' + (n
%10);
2097 /*===========================================================================*
2099 *===========================================================================*/
2100 PRIVATE u16_t
pci_attr_rsts(devind
)
2105 busnr
= pcidev
[devind
].pd_busnr
;
2106 busind
= get_busind(busnr
);
2107 return pcibus
[busind
].pb_rsts(busind
);
2111 /*===========================================================================*
2113 *===========================================================================*/
2114 PRIVATE u16_t
pcibr_std_rsts(busind
)
2119 devind
= pcibus
[busind
].pb_devind
;
2120 return pci_attr_r16(devind
, PPB_SSTS
);
2123 /*===========================================================================*
2125 *===========================================================================*/
2126 PRIVATE
void pcibr_std_wsts(busind
, value
)
2131 devind
= pcibus
[busind
].pb_devind
;
2134 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2135 busind
, value
, devind
);
2137 pci_attr_w16(devind
, PPB_SSTS
, value
);
2140 /*===========================================================================*
2142 *===========================================================================*/
2143 PRIVATE u16_t
pcibr_cb_rsts(busind
)
2147 devind
= pcibus
[busind
].pb_devind
;
2149 return pci_attr_r16(devind
, CBB_SSTS
);
2152 /*===========================================================================*
2154 *===========================================================================*/
2155 PRIVATE
void pcibr_cb_wsts(busind
, value
)
2160 devind
= pcibus
[busind
].pb_devind
;
2163 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2164 busind
, value
, devind
);
2166 pci_attr_w16(devind
, CBB_SSTS
, value
);
2169 /*===========================================================================*
2171 *===========================================================================*/
2172 PRIVATE u16_t
pcibr_via_rsts(busind
)
2176 devind
= pcibus
[busind
].pb_devind
;
2181 /*===========================================================================*
2183 *===========================================================================*/
2184 PRIVATE
void pcibr_via_wsts(busind
, value
)
2189 devind
= pcibus
[busind
].pb_devind
;
2192 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2193 busind
, value
, devind
);
2197 /*===========================================================================*
2199 *===========================================================================*/
2200 PRIVATE
void pci_attr_wsts(devind
, value
)
2206 busnr
= pcidev
[devind
].pd_busnr
;
2207 busind
= get_busind(busnr
);
2208 pcibus
[busind
].pb_wsts(busind
, value
);
2212 /*===========================================================================*
2214 *===========================================================================*/
2215 PRIVATE u8_t
pcii_rreg8(busind
, devind
, port
)
2223 v
= PCII_RREG8_(pcibus
[busind
].pb_busnr
,
2224 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2227 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2228 printf("PCI: warning, sys_outl failed: %d\n", s
);
2230 outl(PCII_CONFADD
, PCII_UNSEL
);
2233 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2234 busind
, devind
, port
,
2235 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2236 pcidev
[devind
].pd_func
, v
);
2241 /*===========================================================================*
2243 *===========================================================================*/
2244 PRIVATE u16_t
pcii_rreg16(busind
, devind
, port
)
2252 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
,
2253 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2256 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2257 printf("PCI: warning, sys_outl failed: %d\n");
2259 outl(PCII_CONFADD
, PCII_UNSEL
);
2262 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2263 busind
, devind
, port
,
2264 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2265 pcidev
[devind
].pd_func
, v
);
2270 /*===========================================================================*
2272 *===========================================================================*/
2273 PRIVATE u32_t
pcii_rreg32(busind
, devind
, port
)
2281 v
= PCII_RREG32_(pcibus
[busind
].pb_busnr
,
2282 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2285 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2286 printf("PCI: warning, sys_outl failed: %d\n", s
);
2288 outl(PCII_CONFADD
, PCII_UNSEL
);
2291 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2292 busind
, devind
, port
,
2293 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2294 pcidev
[devind
].pd_func
, v
);
2299 /*===========================================================================*
2301 *===========================================================================*/
2302 PRIVATE
void pcii_wreg8(busind
, devind
, port
, value
)
2310 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2311 busind
, devind
, port
, value
,
2312 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2313 pcidev
[devind
].pd_func
);
2315 PCII_WREG8_(pcibus
[busind
].pb_busnr
,
2316 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2319 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2320 printf("PCI: warning, sys_outl failed: %d\n", s
);
2322 outl(PCII_CONFADD
, PCII_UNSEL
);
2326 /*===========================================================================*
2328 *===========================================================================*/
2329 PRIVATE
void pcii_wreg16(busind
, devind
, port
, value
)
2337 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2338 busind
, devind
, port
, value
,
2339 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2340 pcidev
[devind
].pd_func
);
2342 PCII_WREG16_(pcibus
[busind
].pb_busnr
,
2343 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2346 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2347 printf("PCI: warning, sys_outl failed: %d\n", s
);
2349 outl(PCII_CONFADD
, PCII_UNSEL
);
2353 /*===========================================================================*
2355 *===========================================================================*/
2356 PRIVATE
void pcii_wreg32(busind
, devind
, port
, value
)
2364 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2365 busind
, devind
, port
, value
,
2366 pcibus
[busind
].pb_bus
, pcidev
[devind
].pd_dev
,
2367 pcidev
[devind
].pd_func
);
2369 PCII_WREG32_(pcibus
[busind
].pb_busnr
,
2370 pcidev
[devind
].pd_dev
, pcidev
[devind
].pd_func
,
2373 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2374 printf("PCI: warning, sys_outl failed: %d\n");
2376 outl(PCII_CONFADD
, PCII_UNSEL
);
2380 /*===========================================================================*
2382 *===========================================================================*/
2383 PRIVATE u16_t
pcii_rsts(busind
)
2389 v
= PCII_RREG16_(pcibus
[busind
].pb_busnr
, 0, 0, PCI_SR
);
2391 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2392 printf("PCI: warning, sys_outl failed: %d\n", s
);
2394 outl(PCII_CONFADD
, PCII_UNSEL
);
2399 /*===========================================================================*
2401 *===========================================================================*/
2402 PRIVATE
void pcii_wsts(busind
, value
)
2407 PCII_WREG16_(pcibus
[busind
].pb_busnr
, 0, 0, PCI_SR
, value
);
2409 if (OK
!= (s
=sys_outl(PCII_CONFADD
, PCII_UNSEL
)))
2410 printf("PCI: warning, sys_outl failed: %d\n", s
);
2412 outl(PCII_CONFADD
, PCII_UNSEL
);
2417 /*===========================================================================*
2418 * print_capabilities *
2419 *===========================================================================*/
2420 PRIVATE
void print_capabilities(devind
)
2423 u8_t status
, capptr
, type
, next
;
2426 /* Check capabilities bit in the device status register */
2427 status
= pci_attr_r16(devind
, PCI_SR
);
2428 if (!(status
& PSR_CAPPTR
))
2431 capptr
= (pci_attr_r8(devind
, PCI_CAPPTR
) & PCI_CP_MASK
);
2434 type
= pci_attr_r8(devind
, capptr
+CAP_TYPE
);
2435 next
= (pci_attr_r8(devind
, capptr
+CAP_NEXT
) & PCI_CP_MASK
);
2438 case 1: str
= "PCI Power Management"; break;
2439 case 2: str
= "AGP"; break;
2440 case 3: str
= "Vital Product Data"; break;
2441 case 4: str
= "Slot Identification"; break;
2442 case 5: str
= "Message Signaled Interrupts"; break;
2443 case 6: str
= "CompactPCI Hot Swap"; break;
2444 case 8: str
= "AMD HyperTransport"; break;
2445 case 0xf: str
= "AMD I/O MMU"; break;
2446 defuault
: str
= "(unknown type)"; break;
2449 printf(" @0x%x: capability type 0x%x: %s\n",
2456 /*===========================================================================*
2458 *===========================================================================*/
2459 PRIVATE
int visible(aclp
, devind
)
2460 struct rs_pci
*aclp
;
2467 return TRUE
; /* Should be changed when ACLs become
2470 /* Check whether the caller is allowed to get this device. */
2471 for (i
= 0; i
<aclp
->rsp_nr_device
; i
++)
2473 if (aclp
->rsp_device
[i
].vid
== pcidev
[devind
].pd_vid
&&
2474 aclp
->rsp_device
[i
].did
== pcidev
[devind
].pd_did
)
2479 if (!aclp
->rsp_nr_class
)
2482 class_id
= (pcidev
[devind
].pd_baseclass
<< 16) |
2483 (pcidev
[devind
].pd_subclass
<< 8) |
2484 pcidev
[devind
].pd_infclass
;
2485 for (i
= 0; i
<aclp
->rsp_nr_class
; i
++)
2487 if (aclp
->rsp_class
[i
].class ==
2488 (class_id
& aclp
->rsp_class
[i
].mask
))
2498 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $