dec21140A ethernet driver for virtualpc, contributed by nicolas tittley.
[minix.git] / drivers / pci / pci.c
blob72393c568ec3e77623a1c2ad47709e9794ff87d8
1 #define USER_SPACE 1
2 /*
3 pci.c
5 Configure devices on the PCI bus
7 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
8 */
10 #include "../drivers.h"
11 #include <assert.h>
12 #include <ibm/pci.h>
13 #include <sys/vm_i386.h>
14 #include <minix/com.h>
15 #include <minix/syslib.h>
17 #include "pci.h"
18 #include "pci_amd.h"
19 #include "pci_intel.h"
20 #include "pci_sis.h"
21 #include "pci_via.h"
22 #if __minix_vmd
23 #include "config.h"
24 #endif
26 #if !__minix_vmd
27 #define irq_mode_pci(irq) ((void)0)
28 #endif
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <minix/sysutil.h>
35 #define PBT_INTEL_HOST 1
36 #define PBT_PCIBRIDGE 2
37 #define PBT_CARDBUS 3
39 #define BAM_NR 6 /* Number of base-address registers */
41 int debug= 0;
43 PRIVATE struct pcibus
45 int pb_type;
46 int pb_needinit;
47 int pb_isabridge_dev;
48 int pb_isabridge_type;
50 int pb_devind;
51 int pb_busnr;
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);
60 } pcibus[NR_PCIBUS];
61 PRIVATE int nr_pcibus= 0;
63 PRIVATE struct pcidev
65 u8_t pd_busnr;
66 u8_t pd_dev;
67 u8_t pd_func;
68 u8_t pd_baseclass;
69 u8_t pd_subclass;
70 u8_t pd_infclass;
71 u16_t pd_vid;
72 u16_t pd_did;
73 u8_t pd_ilr;
75 u8_t pd_inuse;
76 endpoint_t pd_proc;
78 struct bar
80 int pb_flags;
81 int pb_nr;
82 u32_t pb_base;
83 u32_t pb_size;
84 } pd_bar[BAM_NR];
85 int pd_bar_nr;
86 } pcidev[NR_PCIDEV];
88 EXTERN struct pci_acl pci_acl[NR_DRIVERS];
90 /* pb_flags */
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) );
117 #if 0
118 FORWARD _PROTOTYPE( void report_vga, (int devind) );
119 #endif
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,
139 int port) );
140 FORWARD _PROTOTYPE( u32_t pcii_rreg32, (int busind, int devind,
141 int port) );
142 FORWARD _PROTOTYPE( void pcii_wreg8, (int busind, int devind, int port,
143 U8_t value) );
144 FORWARD _PROTOTYPE( void pcii_wreg16, (int busind, int devind, int port,
145 U16_t value) );
146 FORWARD _PROTOTYPE( void pcii_wreg32, (int busind, int devind, int port,
147 u32_t value) );
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. */
160 long v;
161 int i, r;
162 struct rprocpub rprocpub[NR_BOOT_PROCS];
164 v= 0;
165 env_parse("pci_debug", "d", 0, &v, 0, 1);
166 debug= v;
168 /* Only Intel (compatible) PCI controllers are supported at the
169 * moment.
171 pci_intel_init();
173 /* Map all the services in the boot image. */
174 if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
175 (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) {
176 panic("pci", "sys_safecopyfrom failed", r);
178 for(i=0;i < NR_BOOT_PROCS;i++) {
179 if(rprocpub[i].in_use) {
180 if((r = map_service(&rprocpub[i])) != OK) {
181 panic("pci", "unable to map service", r);
186 return(OK);
189 /*===========================================================================*
190 * map_service *
191 *===========================================================================*/
192 PUBLIC int map_service(rpub)
193 struct rprocpub *rpub;
195 /* Map a new service by registering a new acl entry if required. */
196 int i;
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) {
201 return(OK);
204 /* Find a free acl slot. */
205 for (i= 0; i<NR_DRIVERS; i++)
207 if (!pci_acl[i].inuse)
208 break;
210 if (i >= NR_DRIVERS)
212 printf("PCI: map_service: table is full\n");
213 return ENOMEM;
216 /* Initialize acl slot. */
217 pci_acl[i].inuse = 1;
218 pci_acl[i].acl = rpub->pci_acl;
220 return(OK);
223 /*===========================================================================*
224 * helper functions for I/O *
225 *===========================================================================*/
226 PUBLIC unsigned pci_inb(U16_t port) {
227 u32_t value;
228 int s;
229 if ((s=sys_inb(port, &value)) !=OK)
230 printf("PCI: warning, sys_inb failed: %d\n", s);
231 return value;
233 PUBLIC unsigned pci_inw(U16_t port) {
234 u32_t value;
235 int s;
236 if ((s=sys_inw(port, &value)) !=OK)
237 printf("PCI: warning, sys_inw failed: %d\n", s);
238 return value;
240 PUBLIC unsigned pci_inl(U16_t port) {
241 U32_t value;
242 int s;
243 if ((s=sys_inl(port, &value)) !=OK)
244 printf("PCI: warning, sys_inl failed: %d\n", s);
245 return value;
247 PUBLIC void pci_outb(U16_t port, U8_t value) {
248 int s;
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) {
253 int s;
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) {
258 int s;
259 if ((s=sys_outl(port, value)) !=OK)
260 printf("PCI: warning, sys_outl failed: %d\n", s);
263 /*===========================================================================*
264 * pci_find_dev *
265 *===========================================================================*/
266 PUBLIC int pci_find_dev(bus, dev, func, devindp)
267 u8_t bus;
268 u8_t dev;
269 u8_t func;
270 int *devindp;
272 int devind;
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)
280 break;
283 if (devind >= nr_pcidev)
284 return 0;
285 #if 0
286 if (pcidev[devind].pd_inuse)
287 return 0;
288 #endif
289 *devindp= devind;
290 return 1;
293 /*===========================================================================*
294 * pci_first_dev_a *
295 *===========================================================================*/
296 PUBLIC int pci_first_dev_a(aclp, devindp, vidp, didp)
297 struct rs_pci *aclp;
298 int *devindp;
299 u16_t *vidp;
300 u16_t *didp;
302 int i, devind;
304 for (devind= 0; devind < nr_pcidev; devind++)
306 #if 0
307 if (pcidev[devind].pd_inuse)
308 continue;
309 #endif
310 if (!visible(aclp, devind))
311 continue;
312 break;
314 if (devind >= nr_pcidev)
315 return 0;
316 *devindp= devind;
317 *vidp= pcidev[devind].pd_vid;
318 *didp= pcidev[devind].pd_did;
319 return 1;
322 /*===========================================================================*
323 * pci_next_dev *
324 *===========================================================================*/
325 PUBLIC int pci_next_dev_a(aclp, devindp, vidp, didp)
326 struct rs_pci *aclp;
327 int *devindp;
328 u16_t *vidp;
329 u16_t *didp;
331 int devind;
333 for (devind= *devindp+1; devind < nr_pcidev; devind++)
335 #if 0
336 if (pcidev[devind].pd_inuse)
337 continue;
338 #endif
339 if (!visible(aclp, devind))
340 continue;
341 break;
343 if (devind >= nr_pcidev)
344 return 0;
345 *devindp= devind;
346 *vidp= pcidev[devind].pd_vid;
347 *didp= pcidev[devind].pd_did;
348 return 1;
351 /*===========================================================================*
352 * pci_reserve2 *
353 *===========================================================================*/
354 PUBLIC int pci_reserve2(devind, proc)
355 int devind;
356 endpoint_t proc;
358 int i, r;
359 int ilr;
360 struct io_range ior;
361 struct mem_range mr;
363 if (devind < 0 || devind >= nr_pcidev)
365 printf("pci:pci_reserve2: bad devind: %d\n", devind);
366 return EINVAL;
368 if(pcidev[devind].pd_inuse)
369 return EBUSY;
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);
378 continue;
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;
386 if(debug) {
387 printf(
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);
392 if (r != OK)
394 printf("sys_privctl failed for proc %d: %d\n",
395 proc, r);
398 else
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);
405 if (r != OK)
407 printf("sys_privctl failed for proc %d: %d\n",
408 proc, r);
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);
417 if (r != OK)
419 printf("sys_privctl failed for proc %d: %d\n",
420 proc, r);
424 return OK;
427 /*===========================================================================*
428 * pci_release *
429 *===========================================================================*/
430 PUBLIC void pci_release(proc)
431 endpoint_t proc;
433 int i;
435 for (i= 0; i<nr_pcidev; i++)
437 if (!pcidev[i].pd_inuse)
438 continue;
439 if (pcidev[i].pd_proc != proc)
440 continue;
441 pcidev[i].pd_inuse= 0;
445 /*===========================================================================*
446 * pci_ids_s *
447 *===========================================================================*/
448 PUBLIC int pci_ids_s(devind, vidp, didp)
449 int devind;
450 u16_t *vidp;
451 u16_t *didp;
453 if (devind < 0 || devind >= nr_pcidev)
454 return EINVAL;
456 *vidp= pcidev[devind].pd_vid;
457 *didp= pcidev[devind].pd_did;
458 return OK;
461 /*===========================================================================*
462 * pci_rescan_bus *
463 *===========================================================================*/
464 PUBLIC void pci_rescan_bus(busnr)
465 u8_t busnr;
467 int busind;
469 busind= get_busind(busnr);
470 probe_bus(busind);
472 /* Allocate bus numbers for uninitialized bridges */
473 complete_bridges();
475 /* Allocate I/O and memory resources for uninitialized devices */
476 complete_bars();
479 /*===========================================================================*
480 * pci_slot_name_s *
481 *===========================================================================*/
482 PUBLIC int pci_slot_name_s(devind, cpp)
483 int devind;
484 char **cpp;
486 static char label[]= "ddd.ddd.ddd";
487 char *end;
488 char *p;
490 if (devind < 0 || devind >= nr_pcidev)
491 return EINVAL;
493 p= label;
494 end= label+sizeof(label);
496 ntostr(pcidev[devind].pd_busnr, &p, end);
497 *p++= '.';
499 ntostr(pcidev[devind].pd_dev, &p, end);
500 *p++= '.';
502 ntostr(pcidev[devind].pd_func, &p, end);
504 *cpp= label;
505 return OK;
508 /*===========================================================================*
509 * pci_dev_name *
510 *===========================================================================*/
511 PUBLIC char *pci_dev_name(vid, did)
512 u16_t vid;
513 u16_t did;
515 int i;
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;
525 return NULL;
528 /*===========================================================================*
529 * pci_attr_r8_s *
530 *===========================================================================*/
531 PUBLIC int pci_attr_r8_s(devind, port, vp)
532 int devind;
533 int port;
534 u8_t *vp;
536 if (devind < 0 || devind >= nr_pcidev)
537 return EINVAL;
538 if (port < 0 || port > 255)
539 return EINVAL;
541 *vp= pci_attr_r8_u(devind, port);
542 return OK;
545 /*===========================================================================*
546 * pci_attr_r8_u *
547 *===========================================================================*/
548 PRIVATE u8_t pci_attr_r8_u(devind, port)
549 int devind;
550 int port;
552 int busnr, busind;
554 busnr= pcidev[devind].pd_busnr;
555 busind= get_busind(busnr);
556 return pcibus[busind].pb_rreg8(busind, devind, port);
559 /*===========================================================================*
560 * pci_attr_r16 *
561 *===========================================================================*/
562 PUBLIC u16_t pci_attr_r16(devind, port)
563 int devind;
564 int port;
566 int busnr, busind;
568 busnr= pcidev[devind].pd_busnr;
569 busind= get_busind(busnr);
570 return pcibus[busind].pb_rreg16(busind, devind, port);
573 /*===========================================================================*
574 * pci_attr_r32_s *
575 *===========================================================================*/
576 PUBLIC int pci_attr_r32_s(devind, port, vp)
577 int devind;
578 int port;
579 u32_t *vp;
581 if (devind < 0 || devind >= nr_pcidev)
582 return EINVAL;
583 if (port < 0 || port > 256-4)
584 return EINVAL;
586 *vp= pci_attr_r32_u(devind, port);
587 return OK;
590 /*===========================================================================*
591 * pci_attr_r32_u *
592 *===========================================================================*/
593 PRIVATE u32_t pci_attr_r32_u(devind, port)
594 int devind;
595 int port;
597 int busnr, busind;
599 busnr= pcidev[devind].pd_busnr;
600 busind= get_busind(busnr);
601 return pcibus[busind].pb_rreg32(busind, devind, port);
604 /*===========================================================================*
605 * pci_attr_w8 *
606 *===========================================================================*/
607 PUBLIC void pci_attr_w8(devind, port, value)
608 int devind;
609 int port;
610 u16_t value;
612 int busnr, busind;
614 busnr= pcidev[devind].pd_busnr;
615 busind= get_busind(busnr);
616 pcibus[busind].pb_wreg8(busind, devind, port, value);
619 /*===========================================================================*
620 * pci_attr_w16 *
621 *===========================================================================*/
622 PUBLIC void pci_attr_w16(devind, port, value)
623 int devind;
624 int port;
625 u16_t value;
627 int busnr, busind;
629 busnr= pcidev[devind].pd_busnr;
630 busind= get_busind(busnr);
631 pcibus[busind].pb_wreg16(busind, devind, port, value);
634 /*===========================================================================*
635 * pci_attr_w32 *
636 *===========================================================================*/
637 PUBLIC void pci_attr_w32(devind, port, value)
638 int devind;
639 int port;
640 u32_t value;
642 int busnr, busind;
644 busnr= pcidev[devind].pd_busnr;
645 busind= get_busind(busnr);
646 pcibus[busind].pb_wreg32(busind, devind, port, value);
649 /*===========================================================================*
650 * pci_intel_init *
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)
657 * PCI controller.
659 u32_t bus, dev, func;
660 u16_t vid, did;
661 int s, i, r, busind, busnr;
662 char *dstr;
664 bus= 0;
665 dev= 0;
666 func= 0;
668 vid= PCII_RREG16_(bus, dev, func, PCI_VID);
669 did= PCII_RREG16_(bus, dev, func, PCI_DID);
670 #if USER_SPACE
671 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
672 printf("PCI: warning, sys_outl failed: %d\n", s);
673 #else
674 outl(PCII_CONFADD, PCII_UNSEL);
675 #endif
677 if (vid == 0xffff && did == 0xffff)
678 return; /* Nothing here */
680 #if 0
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)
686 break;
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);
696 #endif
698 if (nr_pcibus >= NR_PCIBUS)
699 panic("PCI","too many PCI busses", nr_pcibus);
700 busind= nr_pcibus;
701 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);
718 if (!dstr)
719 dstr= "unknown device";
720 if (debug)
722 printf("pci_intel_init: %s (%04X/%04X)\n",
723 dstr, vid, did);
726 probe_bus(busind);
728 r= do_isabridge(busind);
729 if (r != OK)
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)
737 continue;
738 pcidev[i].pd_inuse= 1;
740 return;
743 /* Look for PCI bridges */
744 do_pcibridge(busind);
746 /* Allocate bus numbers for uninitialized bridges */
747 complete_bridges();
749 /* Allocate I/O and memory resources for uninitialized devices */
750 complete_bars();
753 /*===========================================================================*
754 * probe_bus *
755 *===========================================================================*/
756 PRIVATE void probe_bus(busind)
757 int busind;
759 u32_t dev, func, t3;
760 u16_t vid, did, sts;
761 u8_t headt;
762 u8_t baseclass, subclass, infclass;
763 int devind, busnr;
764 char *s, *dstr;
766 #if DEBUG
767 printf("probe_bus(%d)\n", busind);
768 #endif
769 if (nr_pcidev >= NR_PCIDEV)
770 panic("PCI","too many PCI devices", nr_pcidev);
771 devind= nr_pcidev;
773 busnr= pcibus[busind].pb_busnr;
774 for (dev= 0; dev<32; dev++)
777 for (func= 0; func < 8; func++)
779 pcidev[devind].pd_busnr= busnr;
780 pcidev[devind].pd_dev= dev;
781 pcidev[devind].pd_func= func;
783 pci_attr_wsts(devind,
784 PSR_SSE|PSR_RMAS|PSR_RTAS);
785 vid= pci_attr_r16(devind, PCI_VID);
786 did= pci_attr_r16(devind, PCI_DID);
787 headt= pci_attr_r8_u(devind, PCI_HEADT);
788 sts= pci_attr_rsts(devind);
790 #if 0
791 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
792 vid, did, headt, sts);
793 #endif
795 if (vid == NO_VID && did == NO_VID)
797 if (func == 0)
798 break; /* Nothing here */
800 /* Scan all functions of a multifunction
801 * device.
803 continue;
806 if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
808 printf(
809 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
810 sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
813 dstr= pci_dev_name(vid, did);
814 if (debug)
816 if (dstr)
818 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
819 busind, (unsigned long)dev,
820 (unsigned long)func, dstr,
821 vid, did);
823 else
825 printf(
826 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
827 busind, (unsigned long)dev,
828 (unsigned long)func, vid,
829 pci_vid_name(vid), did);
831 printf("Device index: %d\n", devind);
832 printf("Subsystem: Vid 0x%x, did 0x%x\n",
833 pci_attr_r16(devind, PCI_SUBVID),
834 pci_attr_r16(devind, PCI_SUBDID));
837 baseclass= pci_attr_r8_u(devind, PCI_BCR);
838 subclass= pci_attr_r8_u(devind, PCI_SCR);
839 infclass= pci_attr_r8_u(devind, PCI_PIFR);
840 s= pci_subclass_name(baseclass, subclass, infclass);
841 if (!s)
842 s= pci_baseclass_name(baseclass);
844 if (!s)
845 s= "(unknown class)";
847 if (debug)
849 printf("\tclass %s (%X/%X/%X)\n", s,
850 baseclass, subclass, infclass);
853 if (is_duplicate(busnr, dev, func))
855 printf("\tduplicate!\n");
856 if (func == 0 && !(headt & PHT_MULTIFUNC))
857 break;
858 continue;
861 devind= nr_pcidev;
862 nr_pcidev++;
863 pcidev[devind].pd_baseclass= baseclass;
864 pcidev[devind].pd_subclass= subclass;
865 pcidev[devind].pd_infclass= infclass;
866 pcidev[devind].pd_vid= vid;
867 pcidev[devind].pd_did= did;
868 pcidev[devind].pd_inuse= 0;
869 pcidev[devind].pd_bar_nr= 0;
870 record_irq(devind);
871 switch(headt & PHT_MASK)
873 case PHT_NORMAL:
874 record_bars_normal(devind);
875 break;
876 case PHT_BRIDGE:
877 record_bars_bridge(devind);
878 break;
879 case PHT_CARDBUS:
880 record_bars_cardbus(devind);
881 break;
882 default:
883 printf("\t%d.%d.%d: unknown header type %d\n",
884 busind, dev, func,
885 headt & PHT_MASK);
886 break;
888 if (debug)
889 print_capabilities(devind);
891 t3= ((baseclass << 16) | (subclass << 8) | infclass);
892 #if 0
893 if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
894 report_vga(devind);
895 #endif
897 if (nr_pcidev >= NR_PCIDEV)
898 panic("PCI","too many PCI devices", nr_pcidev);
899 devind= nr_pcidev;
901 if (func == 0 && !(headt & PHT_MULTIFUNC))
902 break;
907 /*===========================================================================*
908 * is_duplicate *
909 *===========================================================================*/
910 PRIVATE int is_duplicate(busnr, dev, func)
911 u8_t busnr;
912 u8_t dev;
913 u8_t func;
915 int i;
917 for (i= 0; i<nr_pcidev; i++)
919 if (pcidev[i].pd_busnr == busnr &&
920 pcidev[i].pd_dev == dev &&
921 pcidev[i].pd_func == func)
923 return 1;
926 return 0;
929 /*===========================================================================*
930 * record_irq *
931 *===========================================================================*/
932 PRIVATE void record_irq(devind)
933 int devind;
935 int ilr, ipr, busnr, busind, cb_devind;
937 ilr= pci_attr_r8_u(devind, PCI_ILR);
938 ipr= pci_attr_r8_u(devind, PCI_IPR);
939 if (ilr == 0)
941 static int first= 1;
942 if (ipr && first && debug)
944 first= 0;
945 printf("PCI: strange, BIOS assigned IRQ0\n");
947 ilr= PCI_ILR_UNKNOWN;
949 pcidev[devind].pd_ilr= ilr;
950 if (ilr == PCI_ILR_UNKNOWN && !ipr)
953 else if (ilr != PCI_ILR_UNKNOWN && ipr)
955 if (debug)
956 printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
958 else if (ilr != PCI_ILR_UNKNOWN)
960 printf(
961 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
962 ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
963 pcidev[devind].pd_func);
965 else
967 /* Check for cardbus devices */
968 busnr= pcidev[devind].pd_busnr;
969 busind= get_busind(busnr);
970 if (pcibus[busind].pb_type == PBT_CARDBUS)
972 cb_devind= pcibus[busind].pb_devind;
973 ilr= pcidev[cb_devind].pd_ilr;
974 if (ilr != PCI_ILR_UNKNOWN)
976 if (debug)
978 printf(
979 "assigning IRQ %d to Cardbus device\n",
980 ilr);
982 pci_attr_w8(devind, PCI_ILR, ilr);
983 pcidev[devind].pd_ilr= ilr;
984 return;
987 if(debug) {
988 printf(
989 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
990 pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
991 pcidev[devind].pd_func, 'A' + ipr-1);
996 /*===========================================================================*
997 * record_bars_normal *
998 *===========================================================================*/
999 PRIVATE void record_bars_normal(devind)
1000 int devind;
1002 int i, j, clear_01, clear_23, pb_nr;
1004 /* The BAR area of normal devices is six DWORDs in size. */
1005 record_bars(devind, PCI_BAR_6);
1007 /* Special case code for IDE controllers in compatibility mode */
1008 if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
1009 pcidev[devind].pd_subclass == PCI_MS_IDE)
1011 /* IDE device */
1012 clear_01= 0;
1013 clear_23= 0;
1014 if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
1016 if (debug)
1018 printf(
1019 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1021 clear_01= 1;
1023 if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
1025 if (debug)
1027 printf(
1028 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
1030 clear_23= 1;
1033 j= 0;
1034 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
1036 pb_nr= pcidev[devind].pd_bar[i].pb_nr;
1037 if ((pb_nr == 0 || pb_nr == 1) && clear_01)
1039 if (debug) printf("skipping bar %d\n", pb_nr);
1040 continue; /* Skip */
1042 if ((pb_nr == 2 || pb_nr == 3) && clear_23)
1044 if (debug) printf("skipping bar %d\n", pb_nr);
1045 continue; /* Skip */
1047 if (i == j)
1049 j++;
1050 continue; /* No need to copy */
1052 pcidev[devind].pd_bar[j]=
1053 pcidev[devind].pd_bar[i];
1054 j++;
1056 pcidev[devind].pd_bar_nr= j;
1060 /*===========================================================================*
1061 * record_bars_bridge *
1062 *===========================================================================*/
1063 PRIVATE void record_bars_bridge(devind)
1064 int devind;
1066 u32_t base, limit, size;
1068 /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
1069 * It may contain up to two 32-bit BARs, or one 64-bit BAR.
1071 record_bars(devind, PCI_BAR_2);
1073 base= ((pci_attr_r8_u(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
1074 (pci_attr_r16(devind, PPB_IOBASEU16) << 16);
1075 limit= 0xff |
1076 ((pci_attr_r8_u(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
1077 ((~PPB_IOL_MASK & 0xff) << 8) |
1078 (pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
1079 size= limit-base + 1;
1080 if (debug)
1082 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1083 base, limit, size);
1086 base= ((pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
1087 limit= 0xffff |
1088 ((pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
1089 ((~PPB_MEML_MASK & 0xffff) << 16);
1090 size= limit-base + 1;
1091 if (debug)
1093 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1094 base, limit, size);
1097 /* Ignore the upper 32 bits */
1098 base= ((pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
1099 limit= 0xffff |
1100 ((pci_attr_r16(devind, PPB_PFMEMLIMIT) &
1101 PPB_PFMEML_MASK) << 16) |
1102 ((~PPB_PFMEML_MASK & 0xffff) << 16);
1103 size= limit-base + 1;
1104 if (debug)
1106 printf(
1107 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1108 base, limit, size);
1112 /*===========================================================================*
1113 * record_bars_cardbus *
1114 *===========================================================================*/
1115 PRIVATE void record_bars_cardbus(devind)
1116 int devind;
1118 u32_t base, limit, size;
1120 /* The generic BAR area of CardBus devices is one DWORD in size. */
1121 record_bars(devind, PCI_BAR);
1123 base= pci_attr_r32_u(devind, CBB_MEMBASE_0);
1124 limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_0) |
1125 (~CBB_MEML_MASK & 0xffffffff);
1126 size= limit-base + 1;
1127 if (debug)
1129 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1130 base, limit, size);
1133 base= pci_attr_r32_u(devind, CBB_MEMBASE_1);
1134 limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_1) |
1135 (~CBB_MEML_MASK & 0xffffffff);
1136 size= limit-base + 1;
1137 if (debug)
1139 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1140 base, limit, size);
1143 base= pci_attr_r32_u(devind, CBB_IOBASE_0);
1144 limit= pci_attr_r32_u(devind, CBB_IOLIMIT_0) |
1145 (~CBB_IOL_MASK & 0xffffffff);
1146 size= limit-base + 1;
1147 if (debug)
1149 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1150 base, limit, size);
1153 base= pci_attr_r32_u(devind, CBB_IOBASE_1);
1154 limit= pci_attr_r32_u(devind, CBB_IOLIMIT_1) |
1155 (~CBB_IOL_MASK & 0xffffffff);
1156 size= limit-base + 1;
1157 if (debug)
1159 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1160 base, limit, size);
1164 /*===========================================================================*
1165 * record_bars *
1166 *===========================================================================*/
1167 PRIVATE void record_bars(devind, last_reg)
1169 int i, reg, width;
1171 for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width)
1173 width = record_bar(devind, i, reg == last_reg);
1177 /*===========================================================================*
1178 * record_bar *
1179 *===========================================================================*/
1180 PRIVATE int record_bar(devind, bar_nr, last)
1181 int devind;
1182 int bar_nr;
1183 int last;
1185 int reg, prefetch, type, dev_bar_nr, width;
1186 u32_t bar, bar2;
1187 u16_t cmd;
1189 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
1190 width = 1;
1192 reg= PCI_BAR+4*bar_nr;
1194 bar= pci_attr_r32_u(devind, reg);
1195 if (bar & PCI_BAR_IO)
1197 /* Disable I/O access before probing for BAR's size */
1198 cmd = pci_attr_r16(devind, PCI_CR);
1199 pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_IO_EN);
1201 /* Probe BAR's size */
1202 pci_attr_w32(devind, reg, 0xffffffff);
1203 bar2= pci_attr_r32_u(devind, reg);
1205 /* Restore original state */
1206 pci_attr_w32(devind, reg, bar);
1207 pci_attr_w16(devind, PCI_CR, cmd);
1209 bar &= ~(u32_t)3; /* Clear non-address bits */
1210 bar2 &= ~(u32_t)3;
1211 bar2= (~bar2 & 0xffff)+1;
1212 if (debug)
1214 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1215 bar_nr, bar2, bar);
1218 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1219 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO;
1220 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1221 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1222 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1223 if (bar == 0)
1225 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1226 PBF_INCOMPLETE;
1229 else
1231 type= (bar & PCI_BAR_TYPE);
1233 switch(type) {
1234 case PCI_TYPE_32:
1235 case PCI_TYPE_32_1M:
1236 break;
1238 case PCI_TYPE_64:
1239 /* A 64-bit BAR takes up two consecutive DWORDs. */
1240 if (last)
1242 printf("PCI: device %d.%d.%d BAR %d extends"
1243 " beyond designated area\n",
1244 pcidev[devind].pd_busnr,
1245 pcidev[devind].pd_dev,
1246 pcidev[devind].pd_func, bar_nr);
1248 return width;
1250 width++;
1252 bar2= pci_attr_r32_u(devind, reg+4);
1254 /* If the upper 32 bits of the BAR are not zero, the
1255 * memory is inaccessible to us; ignore the BAR.
1257 if (bar2 != 0)
1259 if (debug)
1261 printf("\tbar_%d: (64-bit BAR with"
1262 " high bits set)\n", bar_nr);
1265 return width;
1268 break;
1270 default:
1271 /* Ignore the BAR. */
1272 if (debug)
1274 printf("\tbar_%d: (unknown type %x)\n",
1275 bar_nr, type);
1278 return width;
1281 /* Disable mem access before probing for BAR's size */
1282 cmd = pci_attr_r16(devind, PCI_CR);
1283 pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_MEM_EN);
1285 /* Probe BAR's size */
1286 pci_attr_w32(devind, reg, 0xffffffff);
1287 bar2= pci_attr_r32_u(devind, reg);
1289 /* Restore original values */
1290 pci_attr_w32(devind, reg, bar);
1291 pci_attr_w16(devind, PCI_CR, cmd);
1293 if (bar2 == 0)
1294 return width; /* Reg. is not implemented */
1296 prefetch= !!(bar & PCI_BAR_PREFETCH);
1297 bar &= ~(u32_t)0xf; /* Clear non-address bits */
1298 bar2 &= ~(u32_t)0xf;
1299 bar2= (~bar2)+1;
1300 if (debug)
1302 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n",
1303 bar_nr, bar2, bar,
1304 prefetch ? " prefetchable" : "",
1305 type == PCI_TYPE_64 ? ", 64-bit" : "");
1308 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1309 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0;
1310 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1311 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1312 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1313 if (bar == 0)
1315 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1316 PBF_INCOMPLETE;
1320 return width;
1323 /*===========================================================================*
1324 * complete_bridges *
1325 *===========================================================================*/
1326 PRIVATE void complete_bridges()
1328 int i, freebus, devind, prim_busnr;
1330 for (i= 0; i<nr_pcibus; i++)
1332 if (!pcibus[i].pb_needinit)
1333 continue;
1334 printf("should allocate bus number for bus %d\n", i);
1335 freebus= get_freebus();
1336 printf("got bus number %d\n", freebus);
1338 devind= pcibus[i].pb_devind;
1340 prim_busnr= pcidev[devind].pd_busnr;
1341 if (prim_busnr != 0)
1343 printf(
1344 "complete_bridge: updating subordinate bus number not implemented\n");
1347 pcibus[i].pb_needinit= 0;
1348 pcibus[i].pb_busnr= freebus;
1350 printf("devind = %d\n", devind);
1351 printf("prim_busnr= %d\n", prim_busnr);
1353 pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
1354 pci_attr_w8(devind, PPB_SECBN, freebus);
1355 pci_attr_w8(devind, PPB_SUBORDBN, freebus);
1357 printf("CR = 0x%x\n", pci_attr_r16(devind, PCI_CR));
1358 printf("SECBLT = 0x%x\n", pci_attr_r8_u(devind, PPB_SECBLT));
1359 printf("BRIDGECTRL = 0x%x\n",
1360 pci_attr_r16(devind, PPB_BRIDGECTRL));
1364 /*===========================================================================*
1365 * complete_bars *
1366 *===========================================================================*/
1367 PRIVATE void complete_bars(void)
1369 int i, j, r, bar_nr, reg;
1370 u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
1371 base, size, v32, diff1, diff2;
1372 char *cp, *next;
1373 char memstr[256];
1375 r= env_get_param("memory", memstr, sizeof(memstr));
1376 if (r != OK)
1377 panic("pci", "env_get_param failed", r);
1379 /* Set memgap_low to just above physical memory */
1380 memgap_low= 0;
1381 cp= memstr;
1382 while (*cp != '\0')
1384 base= strtoul(cp, &next, 16);
1385 if (!(*next) || next == cp || *next != ':')
1386 goto bad_mem_string;
1387 cp= next+1;
1388 size= strtoul(cp, &next, 16);
1389 if (next == cp || (*next != ',' && *next != '\0'))
1390 if (!*next)
1391 goto bad_mem_string;
1392 if (base+size > memgap_low)
1393 memgap_low= base+size;
1395 if (*next)
1396 cp= next+1;
1397 else
1398 break;
1401 memgap_high= 0xfe000000; /* Leave space for the CPU (APIC) */
1403 if (debug)
1405 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1406 memgap_low, memgap_high);
1409 /* Find the lowest memory base */
1410 for (i= 0; i<nr_pcidev; i++)
1412 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1414 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1415 continue;
1416 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1417 continue;
1418 base= pcidev[i].pd_bar[j].pb_base;
1419 size= pcidev[i].pd_bar[j].pb_size;
1421 if (base >= memgap_high)
1422 continue; /* Not in the gap */
1423 if (base+size <= memgap_low)
1424 continue; /* Not in the gap */
1426 /* Reduce the gap by the smallest amount */
1427 diff1= base+size-memgap_low;
1428 diff2= memgap_high-base;
1430 if (diff1 < diff2)
1431 memgap_low= base+size;
1432 else
1433 memgap_high= base;
1437 if (debug)
1439 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1440 memgap_low, memgap_high);
1443 /* Should check main memory size */
1444 if (memgap_high < memgap_low)
1446 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1447 memgap_low, memgap_high);
1448 panic(NULL, NULL, NO_NUM);
1451 iogap_high= 0x10000;
1452 iogap_low= 0x400;
1454 /* Find the free I/O space */
1455 for (i= 0; i<nr_pcidev; i++)
1457 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1459 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1460 continue;
1461 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1462 continue;
1463 base= pcidev[i].pd_bar[j].pb_base;
1464 size= pcidev[i].pd_bar[j].pb_size;
1465 if (base >= iogap_high)
1466 continue;
1467 if (base+size <= iogap_low)
1468 continue;
1469 #if 0
1470 if (debug)
1472 printf(
1473 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
1474 i, pcidev[i].pd_vid, pcidev[i].pd_did,
1475 j, base, size);
1477 #endif
1478 if (base+size-iogap_low < iogap_high-base)
1479 iogap_low= base+size;
1480 else
1481 iogap_high= base;
1485 if (iogap_high < iogap_low)
1487 if (debug)
1489 printf("iogap_high too low, should panic\n");
1491 else
1492 panic("pci", "iogap_high too low", iogap_high);
1494 if (debug)
1495 printf("I/O range = [0x%x..0x%x>\n", iogap_low, iogap_high);
1497 for (i= 0; i<nr_pcidev; i++)
1499 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1501 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1502 continue;
1503 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1504 continue;
1505 size= pcidev[i].pd_bar[j].pb_size;
1506 if (size < I386_PAGE_SIZE)
1507 size= I386_PAGE_SIZE;
1508 base= memgap_high-size;
1509 base &= ~(u32_t)(size-1);
1510 if (base < memgap_low)
1511 panic("pci", "memory base too low", base);
1512 memgap_high= base;
1513 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1514 reg= PCI_BAR + 4*bar_nr;
1515 v32= pci_attr_r32_u(i, reg);
1516 pci_attr_w32(i, reg, v32 | base);
1517 if (debug)
1519 printf(
1520 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1521 base, size, pcidev[i].pd_busnr,
1522 pcidev[i].pd_dev, pcidev[i].pd_func,
1523 bar_nr);
1525 pcidev[i].pd_bar[j].pb_base= base;
1526 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1529 io_high= iogap_high;
1530 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1532 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1533 continue;
1534 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1535 continue;
1536 size= pcidev[i].pd_bar[j].pb_size;
1537 base= iogap_high-size;
1538 base &= ~(u32_t)(size-1);
1540 /* Assume that ISA compatibility is required. Only
1541 * use the lowest 256 bytes out of every 1024 bytes.
1543 base &= 0xfcff;
1545 if (base < iogap_low)
1546 panic("pci", "I/O base too low", base);
1548 iogap_high= base;
1549 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1550 reg= PCI_BAR + 4*bar_nr;
1551 v32= pci_attr_r32_u(i, reg);
1552 pci_attr_w32(i, reg, v32 | base);
1553 if (debug)
1555 printf(
1556 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1557 base, size, pcidev[i].pd_busnr,
1558 pcidev[i].pd_dev, pcidev[i].pd_func,
1559 bar_nr);
1561 pcidev[i].pd_bar[j].pb_base= base;
1562 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1565 if (iogap_high != io_high)
1567 update_bridge4dev_io(i, iogap_high,
1568 io_high-iogap_high);
1572 for (i= 0; i<nr_pcidev; i++)
1574 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1576 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1577 continue;
1578 printf("should allocate resources for device %d\n", i);
1581 return;
1583 bad_mem_string:
1584 printf("PCI: bad memory environment string '%s'\n", memstr);
1585 panic(NULL, NULL, NO_NUM);
1588 /*===========================================================================*
1589 * update_bridge4dev_io *
1590 *===========================================================================*/
1591 PRIVATE void update_bridge4dev_io(devind, io_base, io_size)
1592 int devind;
1593 u32_t io_base;
1594 u32_t io_size;
1596 int busnr, busind, type, br_devind;
1597 u16_t v16;
1599 busnr= pcidev[devind].pd_busnr;
1600 busind= get_busind(busnr);
1601 type= pcibus[busind].pb_type;
1602 if (type == PBT_INTEL_HOST)
1603 return; /* Nothing to do for host controller */
1604 if (type == PBT_PCIBRIDGE)
1606 printf(
1607 "update_bridge4dev_io: not implemented for PCI bridges\n");
1608 return;
1610 if (type != PBT_CARDBUS)
1611 panic("pci", "update_bridge4dev_io: strange bus type", type);
1613 if (debug)
1615 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1616 io_size, io_base);
1618 br_devind= pcibus[busind].pb_devind;
1619 pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
1620 pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
1622 /* Enable I/O access. Enable busmaster access as well. */
1623 v16= pci_attr_r16(devind, PCI_CR);
1624 pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
1627 /*===========================================================================*
1628 * get_freebus *
1629 *===========================================================================*/
1630 PRIVATE int get_freebus()
1632 int i, freebus;
1634 freebus= 1;
1635 for (i= 0; i<nr_pcibus; i++)
1637 if (pcibus[i].pb_needinit)
1638 continue;
1639 if (pcibus[i].pb_type == PBT_INTEL_HOST)
1640 continue;
1641 if (pcibus[i].pb_busnr <= freebus)
1642 freebus= pcibus[i].pb_busnr+1;
1643 printf("get_freebus: should check suboridinate bus number\n");
1645 return freebus;
1648 /*===========================================================================*
1649 * do_isabridge *
1650 *===========================================================================*/
1651 PRIVATE int do_isabridge(busind)
1652 int busind;
1654 int i, j, r, type, busnr, unknown_bridge, bridge_dev;
1655 u16_t vid, did;
1656 u32_t t3;
1657 char *dstr;
1659 unknown_bridge= -1;
1660 bridge_dev= -1;
1661 j= 0; /* lint */
1662 vid= did= 0; /* lint */
1663 busnr= pcibus[busind].pb_busnr;
1664 for (i= 0; i< nr_pcidev; i++)
1666 if (pcidev[i].pd_busnr != busnr)
1667 continue;
1668 t3= ((pcidev[i].pd_baseclass << 16) |
1669 (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
1670 if (t3 == PCI_T3_ISA)
1672 /* ISA bridge. Report if no supported bridge is
1673 * found.
1675 unknown_bridge= i;
1678 vid= pcidev[i].pd_vid;
1679 did= pcidev[i].pd_did;
1680 for (j= 0; pci_isabridge[j].vid != 0; j++)
1682 if (pci_isabridge[j].vid != vid)
1683 continue;
1684 if (pci_isabridge[j].did != did)
1685 continue;
1686 if (pci_isabridge[j].checkclass &&
1687 unknown_bridge != i)
1689 /* This part of multifunction device is
1690 * not the bridge.
1692 continue;
1694 break;
1696 if (pci_isabridge[j].vid)
1698 bridge_dev= i;
1699 break;
1703 if (bridge_dev != -1)
1705 dstr= pci_dev_name(vid, did);
1706 if (!dstr)
1707 dstr= "unknown device";
1708 if (debug)
1710 printf("found ISA bridge (%04X/%04X) %s\n",
1711 vid, did, dstr);
1713 pcibus[busind].pb_isabridge_dev= bridge_dev;
1714 type= pci_isabridge[j].type;
1715 pcibus[busind].pb_isabridge_type= type;
1716 switch(type)
1718 case PCI_IB_PIIX:
1719 r= do_piix(bridge_dev);
1720 break;
1721 case PCI_IB_VIA:
1722 r= do_via_isabr(bridge_dev);
1723 break;
1724 case PCI_IB_AMD:
1725 r= do_amd_isabr(bridge_dev);
1726 break;
1727 case PCI_IB_SIS:
1728 r= do_sis_isabr(bridge_dev);
1729 break;
1730 default:
1731 panic("PCI","unknown ISA bridge type", type);
1733 return r;
1736 if (unknown_bridge == -1)
1738 if (debug)
1740 printf("(warning) no ISA bridge found on bus %d\n",
1741 busind);
1743 return 0;
1745 if (debug)
1747 printf(
1748 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
1749 pcidev[unknown_bridge].pd_vid,
1750 pcidev[unknown_bridge].pd_did, busind);
1752 return 0;
1755 /*===========================================================================*
1756 * do_pcibridge *
1757 *===========================================================================*/
1758 PRIVATE void do_pcibridge(busind)
1759 int busind;
1761 int i, devind, busnr;
1762 int ind, type;
1763 u16_t vid, did;
1764 u8_t sbusn, baseclass, subclass, infclass, headt;
1765 u32_t t3;
1767 vid= did= 0; /* lint */
1768 busnr= pcibus[busind].pb_busnr;
1769 for (devind= 0; devind< nr_pcidev; devind++)
1771 #if 0
1772 printf("do_pcibridge: trying %u.%u.%u\n",
1773 pcidev[devind].pd_busind, pcidev[devind].pd_dev,
1774 pcidev[devind].pd_func);
1775 #endif
1777 if (pcidev[devind].pd_busnr != busnr)
1779 #if 0
1780 printf("wrong bus\n");
1781 #endif
1782 continue;
1785 vid= pcidev[devind].pd_vid;
1786 did= pcidev[devind].pd_did;
1787 for (i= 0; pci_pcibridge[i].vid != 0; i++)
1789 if (pci_pcibridge[i].vid != vid)
1790 continue;
1791 if (pci_pcibridge[i].did != did)
1792 continue;
1793 break;
1795 type= pci_pcibridge[i].type;
1796 if (pci_pcibridge[i].vid == 0)
1798 headt= pci_attr_r8_u(devind, PCI_HEADT);
1799 type= 0;
1800 if ((headt & PHT_MASK) == PHT_BRIDGE)
1801 type= PCI_PPB_STD;
1802 else if ((headt & PHT_MASK) == PHT_CARDBUS)
1803 type= PCI_PPB_CB;
1804 else
1806 #if 0
1807 printf("not a bridge\n");
1808 #endif
1809 continue; /* Not a bridge */
1812 baseclass= pci_attr_r8_u(devind, PCI_BCR);
1813 subclass= pci_attr_r8_u(devind, PCI_SCR);
1814 infclass= pci_attr_r8_u(devind, PCI_PIFR);
1815 t3= ((baseclass << 16) | (subclass << 8) | infclass);
1816 if (type == PCI_PPB_STD &&
1817 t3 != PCI_T3_PCI2PCI &&
1818 t3 != PCI_T3_PCI2PCI_SUBTR)
1820 printf(
1821 "Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
1822 baseclass, subclass, infclass,
1823 vid, did);
1824 continue;
1826 if (type == PCI_PPB_CB &&
1827 t3 != PCI_T3_CARDBUS)
1829 printf(
1830 "Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
1831 baseclass, subclass, infclass,
1832 vid, did);
1833 continue;
1837 if (debug)
1839 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
1840 pcidev[devind].pd_busnr,
1841 pcidev[devind].pd_dev,
1842 pcidev[devind].pd_func, vid, did);
1845 /* Assume that the BIOS initialized the secondary bus
1846 * number.
1848 sbusn= pci_attr_r8_u(devind, PPB_SECBN);
1850 if (nr_pcibus >= NR_PCIBUS)
1851 panic("PCI","too many PCI busses", nr_pcibus);
1852 ind= nr_pcibus;
1853 nr_pcibus++;
1854 pcibus[ind].pb_type= PBT_PCIBRIDGE;
1855 pcibus[ind].pb_needinit= 1;
1856 pcibus[ind].pb_isabridge_dev= -1;
1857 pcibus[ind].pb_isabridge_type= 0;
1858 pcibus[ind].pb_devind= devind;
1859 pcibus[ind].pb_busnr= sbusn;
1860 pcibus[ind].pb_rreg8= pcibus[busind].pb_rreg8;
1861 pcibus[ind].pb_rreg16= pcibus[busind].pb_rreg16;
1862 pcibus[ind].pb_rreg32= pcibus[busind].pb_rreg32;
1863 pcibus[ind].pb_wreg8= pcibus[busind].pb_wreg8;
1864 pcibus[ind].pb_wreg16= pcibus[busind].pb_wreg16;
1865 pcibus[ind].pb_wreg32= pcibus[busind].pb_wreg32;
1866 switch(type)
1868 case PCI_PPB_STD:
1869 pcibus[ind].pb_rsts= pcibr_std_rsts;
1870 pcibus[ind].pb_wsts= pcibr_std_wsts;
1871 break;
1872 case PCI_PPB_CB:
1873 pcibus[ind].pb_type= PBT_CARDBUS;
1874 pcibus[ind].pb_rsts= pcibr_cb_rsts;
1875 pcibus[ind].pb_wsts= pcibr_cb_wsts;
1876 break;
1877 case PCI_AGPB_VIA:
1878 pcibus[ind].pb_rsts= pcibr_via_rsts;
1879 pcibus[ind].pb_wsts= pcibr_via_wsts;
1880 break;
1881 default:
1882 panic("PCI","unknown PCI-PCI bridge type", type);
1884 if (debug)
1886 printf(
1887 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1888 ind, sbusn, pci_attr_r8_u(devind, PPB_SUBORDBN));
1890 if (sbusn == 0)
1892 printf("Secondary bus number not initialized\n");
1893 continue;
1895 pcibus[ind].pb_needinit= 0;
1897 probe_bus(ind);
1899 /* Look for PCI bridges */
1900 do_pcibridge(ind);
1904 /*===========================================================================*
1905 * get_busind *
1906 *===========================================================================*/
1907 PRIVATE int get_busind(busnr)
1908 int busnr;
1910 int i;
1912 for (i= 0; i<nr_pcibus; i++)
1914 if (pcibus[i].pb_busnr == busnr)
1915 return i;
1917 panic("pci", "get_busind: can't find bus", busnr);
1920 /*===========================================================================*
1921 * do_piix *
1922 *===========================================================================*/
1923 PRIVATE int do_piix(devind)
1924 int devind;
1926 int i, s, dev, func, irqrc, irq;
1927 u32_t elcr1, elcr2, elcr;
1929 #if DEBUG
1930 printf("in piix\n");
1931 #endif
1932 dev= pcidev[devind].pd_dev;
1933 func= pcidev[devind].pd_func;
1934 #if USER_SPACE
1935 if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
1936 printf("Warning, sys_inb failed: %d\n", s);
1937 if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
1938 printf("Warning, sys_inb failed: %d\n", s);
1939 #else
1940 elcr1= inb(PIIX_ELCR1);
1941 elcr2= inb(PIIX_ELCR2);
1942 #endif
1943 elcr= elcr1 | (elcr2 << 8);
1944 for (i= 0; i<4; i++)
1946 irqrc= pci_attr_r8_u(devind, PIIX_PIRQRCA+i);
1947 if (irqrc & PIIX_IRQ_DI)
1949 if (debug)
1950 printf("INT%c: disabled\n", 'A'+i);
1952 else
1954 irq= irqrc & PIIX_IRQ_MASK;
1955 if (debug)
1956 printf("INT%c: %d\n", 'A'+i, irq);
1957 if (!(elcr & (1 << irq)))
1959 if (debug)
1961 printf(
1962 "(warning) IRQ %d is not level triggered\n",
1963 irq);
1966 irq_mode_pci(irq);
1969 return 0;
1972 /*===========================================================================*
1973 * do_amd_isabr *
1974 *===========================================================================*/
1975 PRIVATE int do_amd_isabr(devind)
1976 int devind;
1978 int i, busnr, dev, func, xdevind, irq, edge;
1979 u8_t levmask;
1980 u16_t pciirq;
1982 /* Find required function */
1983 func= AMD_ISABR_FUNC;
1984 busnr= pcidev[devind].pd_busnr;
1985 dev= pcidev[devind].pd_dev;
1987 /* Fake a device with the required function */
1988 if (nr_pcidev >= NR_PCIDEV)
1989 panic("PCI","too many PCI devices", nr_pcidev);
1990 xdevind= nr_pcidev;
1991 pcidev[xdevind].pd_busnr= busnr;
1992 pcidev[xdevind].pd_dev= dev;
1993 pcidev[xdevind].pd_func= func;
1994 pcidev[xdevind].pd_inuse= 1;
1995 nr_pcidev++;
1997 levmask= pci_attr_r8_u(xdevind, AMD_ISABR_PCIIRQ_LEV);
1998 pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
1999 for (i= 0; i<4; i++)
2001 edge= (levmask >> i) & 1;
2002 irq= (pciirq >> (4*i)) & 0xf;
2003 if (!irq)
2005 if (debug)
2006 printf("INT%c: disabled\n", 'A'+i);
2008 else
2010 if (debug)
2011 printf("INT%c: %d\n", 'A'+i, irq);
2012 if (edge && debug)
2014 printf(
2015 "(warning) IRQ %d is not level triggered\n",
2016 irq);
2018 irq_mode_pci(irq);
2021 nr_pcidev--;
2022 return 0;
2025 /*===========================================================================*
2026 * do_sis_isabr *
2027 *===========================================================================*/
2028 PRIVATE int do_sis_isabr(devind)
2029 int devind;
2031 int i, dev, func, irq;
2033 dev= pcidev[devind].pd_dev;
2034 func= pcidev[devind].pd_func;
2035 irq= 0; /* lint */
2036 for (i= 0; i<4; i++)
2038 irq= pci_attr_r8_u(devind, SIS_ISABR_IRQ_A+i);
2039 if (irq & SIS_IRQ_DISABLED)
2041 if (debug)
2042 printf("INT%c: disabled\n", 'A'+i);
2044 else
2046 irq &= SIS_IRQ_MASK;
2047 if (debug)
2048 printf("INT%c: %d\n", 'A'+i, irq);
2049 irq_mode_pci(irq);
2052 return 0;
2055 /*===========================================================================*
2056 * do_via_isabr *
2057 *===========================================================================*/
2058 PRIVATE int do_via_isabr(devind)
2059 int devind;
2061 int i, dev, func, irq, edge;
2062 u8_t levmask;
2064 dev= pcidev[devind].pd_dev;
2065 func= pcidev[devind].pd_func;
2066 levmask= pci_attr_r8_u(devind, VIA_ISABR_EL);
2067 irq= 0; /* lint */
2068 edge= 0; /* lint */
2069 for (i= 0; i<4; i++)
2071 switch(i)
2073 case 0:
2074 edge= (levmask & VIA_ISABR_EL_INTA);
2075 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2) >> 4;
2076 break;
2077 case 1:
2078 edge= (levmask & VIA_ISABR_EL_INTB);
2079 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2);
2080 break;
2081 case 2:
2082 edge= (levmask & VIA_ISABR_EL_INTC);
2083 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R3) >> 4;
2084 break;
2085 case 3:
2086 edge= (levmask & VIA_ISABR_EL_INTD);
2087 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R1) >> 4;
2088 break;
2089 default:
2090 assert(0);
2092 irq &= 0xf;
2093 if (!irq)
2095 if (debug)
2096 printf("INT%c: disabled\n", 'A'+i);
2098 else
2100 if (debug)
2101 printf("INT%c: %d\n", 'A'+i, irq);
2102 if (edge && debug)
2104 printf(
2105 "(warning) IRQ %d is not level triggered\n",
2106 irq);
2108 irq_mode_pci(irq);
2111 return 0;
2115 #if 0
2116 /*===========================================================================*
2117 * report_vga *
2118 *===========================================================================*/
2119 PRIVATE void report_vga(devind)
2120 int devind;
2122 /* Report the amount of video memory. This is needed by the X11R6
2123 * postinstall script to chmem the X server. Hopefully this can be
2124 * removed when we get virtual memory.
2126 size_t amount, size;
2127 int i;
2129 amount= 0;
2130 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
2132 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
2133 continue;
2134 size= pcidev[devind].pd_bar[i].pb_size;
2135 if (size < amount)
2136 continue;
2137 amount= size;
2139 if (size != 0)
2141 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
2142 pcidev[devind].pd_busnr,
2143 pcidev[devind].pd_dev,
2144 pcidev[devind].pd_func,
2145 amount);
2148 #endif
2151 /*===========================================================================*
2152 * pci_vid_name *
2153 *===========================================================================*/
2154 PRIVATE char *pci_vid_name(vid)
2155 u16_t vid;
2157 int i;
2159 for (i= 0; pci_vendor_table[i].name; i++)
2161 if (pci_vendor_table[i].vid == vid)
2162 return pci_vendor_table[i].name;
2164 return "unknown";
2167 /*===========================================================================*
2168 * pci_baseclass_name *
2169 *===========================================================================*/
2170 PRIVATE char *pci_baseclass_name(baseclass)
2171 u8_t baseclass;
2173 int i;
2175 for (i= 0; pci_baseclass_table[i].name; i++)
2177 if (pci_baseclass_table[i].baseclass == baseclass)
2178 return pci_baseclass_table[i].name;
2180 return NULL;
2183 /*===========================================================================*
2184 * pci_subclass_name *
2185 *===========================================================================*/
2186 PRIVATE char *pci_subclass_name(baseclass, subclass, infclass)
2187 u8_t baseclass;
2188 u8_t subclass;
2189 u8_t infclass;
2191 int i;
2193 for (i= 0; pci_subclass_table[i].name; i++)
2195 if (pci_subclass_table[i].baseclass != baseclass)
2196 continue;
2197 if (pci_subclass_table[i].subclass != subclass)
2198 continue;
2199 if (pci_subclass_table[i].infclass != infclass &&
2200 pci_subclass_table[i].infclass != (u16_t)-1)
2202 continue;
2204 return pci_subclass_table[i].name;
2206 return NULL;
2209 /*===========================================================================*
2210 * ntostr *
2211 *===========================================================================*/
2212 PRIVATE void ntostr(n, str, end)
2213 unsigned n;
2214 char **str;
2215 char *end;
2217 char tmpstr[20];
2218 int i;
2220 if (n == 0)
2222 tmpstr[0]= '0';
2223 i= 1;
2225 else
2227 for (i= 0; n; i++)
2229 tmpstr[i]= '0' + (n%10);
2230 n /= 10;
2233 for (; i>0; i--)
2235 if (*str == end)
2237 break;
2239 **str= tmpstr[i-1];
2240 (*str)++;
2242 if (*str == end)
2243 end[-1]= '\0';
2244 else
2245 **str= '\0';
2248 /*===========================================================================*
2249 * pci_attr_rsts *
2250 *===========================================================================*/
2251 PRIVATE u16_t pci_attr_rsts(devind)
2252 int devind;
2254 int busnr, busind;
2256 busnr= pcidev[devind].pd_busnr;
2257 busind= get_busind(busnr);
2258 return pcibus[busind].pb_rsts(busind);
2262 /*===========================================================================*
2263 * pcibr_std_rsts *
2264 *===========================================================================*/
2265 PRIVATE u16_t pcibr_std_rsts(busind)
2266 int busind;
2268 int devind;
2270 devind= pcibus[busind].pb_devind;
2271 return pci_attr_r16(devind, PPB_SSTS);
2274 /*===========================================================================*
2275 * pcibr_std_wsts *
2276 *===========================================================================*/
2277 PRIVATE void pcibr_std_wsts(busind, value)
2278 int busind;
2279 u16_t value;
2281 int devind;
2282 devind= pcibus[busind].pb_devind;
2284 #if 0
2285 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2286 busind, value, devind);
2287 #endif
2288 pci_attr_w16(devind, PPB_SSTS, value);
2291 /*===========================================================================*
2292 * pcibr_cb_rsts *
2293 *===========================================================================*/
2294 PRIVATE u16_t pcibr_cb_rsts(busind)
2295 int busind;
2297 int devind;
2298 devind= pcibus[busind].pb_devind;
2300 return pci_attr_r16(devind, CBB_SSTS);
2303 /*===========================================================================*
2304 * pcibr_cb_wsts *
2305 *===========================================================================*/
2306 PRIVATE void pcibr_cb_wsts(busind, value)
2307 int busind;
2308 u16_t value;
2310 int devind;
2311 devind= pcibus[busind].pb_devind;
2313 #if 0
2314 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2315 busind, value, devind);
2316 #endif
2317 pci_attr_w16(devind, CBB_SSTS, value);
2320 /*===========================================================================*
2321 * pcibr_via_rsts *
2322 *===========================================================================*/
2323 PRIVATE u16_t pcibr_via_rsts(busind)
2324 int busind;
2326 int devind;
2327 devind= pcibus[busind].pb_devind;
2329 return 0;
2332 /*===========================================================================*
2333 * pcibr_via_wsts *
2334 *===========================================================================*/
2335 PRIVATE void pcibr_via_wsts(busind, value)
2336 int busind;
2337 u16_t value;
2339 int devind;
2340 devind= pcibus[busind].pb_devind;
2342 #if 0
2343 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2344 busind, value, devind);
2345 #endif
2348 /*===========================================================================*
2349 * pci_attr_wsts *
2350 *===========================================================================*/
2351 PRIVATE void pci_attr_wsts(devind, value)
2352 int devind;
2353 u16_t value;
2355 int busnr, busind;
2357 busnr= pcidev[devind].pd_busnr;
2358 busind= get_busind(busnr);
2359 pcibus[busind].pb_wsts(busind, value);
2363 /*===========================================================================*
2364 * pcii_rreg8 *
2365 *===========================================================================*/
2366 PRIVATE u8_t pcii_rreg8(busind, devind, port)
2367 int busind;
2368 int devind;
2369 int port;
2371 u8_t v;
2372 int s;
2374 v= PCII_RREG8_(pcibus[busind].pb_busnr,
2375 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2376 port);
2377 #if USER_SPACE
2378 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2379 printf("PCI: warning, sys_outl failed: %d\n", s);
2380 #else
2381 outl(PCII_CONFADD, PCII_UNSEL);
2382 #endif
2383 #if 0
2384 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2385 busind, devind, port,
2386 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2387 pcidev[devind].pd_func, v);
2388 #endif
2389 return v;
2392 /*===========================================================================*
2393 * pcii_rreg16 *
2394 *===========================================================================*/
2395 PRIVATE u16_t pcii_rreg16(busind, devind, port)
2396 int busind;
2397 int devind;
2398 int port;
2400 u16_t v;
2401 int s;
2403 v= PCII_RREG16_(pcibus[busind].pb_busnr,
2404 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2405 port);
2406 #if USER_SPACE
2407 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2408 printf("PCI: warning, sys_outl failed: %d\n");
2409 #else
2410 outl(PCII_CONFADD, PCII_UNSEL);
2411 #endif
2412 #if 0
2413 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2414 busind, devind, port,
2415 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2416 pcidev[devind].pd_func, v);
2417 #endif
2418 return v;
2421 /*===========================================================================*
2422 * pcii_rreg32 *
2423 *===========================================================================*/
2424 PRIVATE u32_t pcii_rreg32(busind, devind, port)
2425 int busind;
2426 int devind;
2427 int port;
2429 u32_t v;
2430 int s;
2432 v= PCII_RREG32_(pcibus[busind].pb_busnr,
2433 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2434 port);
2435 #if USER_SPACE
2436 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2437 printf("PCI: warning, sys_outl failed: %d\n", s);
2438 #else
2439 outl(PCII_CONFADD, PCII_UNSEL);
2440 #endif
2441 #if 0
2442 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2443 busind, devind, port,
2444 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2445 pcidev[devind].pd_func, v);
2446 #endif
2447 return v;
2450 /*===========================================================================*
2451 * pcii_wreg8 *
2452 *===========================================================================*/
2453 PRIVATE void pcii_wreg8(busind, devind, port, value)
2454 int busind;
2455 int devind;
2456 int port;
2457 u8_t value;
2459 int s;
2460 #if 0
2461 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2462 busind, devind, port, value,
2463 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2464 pcidev[devind].pd_func);
2465 #endif
2466 PCII_WREG8_(pcibus[busind].pb_busnr,
2467 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2468 port, value);
2469 #if USER_SPACE
2470 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2471 printf("PCI: warning, sys_outl failed: %d\n", s);
2472 #else
2473 outl(PCII_CONFADD, PCII_UNSEL);
2474 #endif
2477 /*===========================================================================*
2478 * pcii_wreg16 *
2479 *===========================================================================*/
2480 PRIVATE void pcii_wreg16(busind, devind, port, value)
2481 int busind;
2482 int devind;
2483 int port;
2484 u16_t value;
2486 int s;
2487 #if 0
2488 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2489 busind, devind, port, value,
2490 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2491 pcidev[devind].pd_func);
2492 #endif
2493 PCII_WREG16_(pcibus[busind].pb_busnr,
2494 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2495 port, value);
2496 #if USER_SPACE
2497 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2498 printf("PCI: warning, sys_outl failed: %d\n", s);
2499 #else
2500 outl(PCII_CONFADD, PCII_UNSEL);
2501 #endif
2504 /*===========================================================================*
2505 * pcii_wreg32 *
2506 *===========================================================================*/
2507 PRIVATE void pcii_wreg32(busind, devind, port, value)
2508 int busind;
2509 int devind;
2510 int port;
2511 u32_t value;
2513 int s;
2514 #if 0
2515 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2516 busind, devind, port, value,
2517 pcibus[busind].pb_busnr, pcidev[devind].pd_dev,
2518 pcidev[devind].pd_func);
2519 #endif
2520 PCII_WREG32_(pcibus[busind].pb_busnr,
2521 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2522 port, value);
2523 #if USER_SPACE
2524 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2525 printf("PCI: warning, sys_outl failed: %d\n");
2526 #else
2527 outl(PCII_CONFADD, PCII_UNSEL);
2528 #endif
2531 /*===========================================================================*
2532 * pcii_rsts *
2533 *===========================================================================*/
2534 PRIVATE u16_t pcii_rsts(busind)
2535 int busind;
2537 u16_t v;
2538 int s;
2540 v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
2541 #if USER_SPACE
2542 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2543 printf("PCI: warning, sys_outl failed: %d\n", s);
2544 #else
2545 outl(PCII_CONFADD, PCII_UNSEL);
2546 #endif
2547 return v;
2550 /*===========================================================================*
2551 * pcii_wsts *
2552 *===========================================================================*/
2553 PRIVATE void pcii_wsts(busind, value)
2554 int busind;
2555 u16_t value;
2557 int s;
2558 PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
2559 #if USER_SPACE
2560 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2561 printf("PCI: warning, sys_outl failed: %d\n", s);
2562 #else
2563 outl(PCII_CONFADD, PCII_UNSEL);
2564 #endif
2568 /*===========================================================================*
2569 * print_capabilities *
2570 *===========================================================================*/
2571 PRIVATE void print_capabilities(devind)
2572 int devind;
2574 u8_t status, capptr, type, next, subtype;
2575 char *str;
2577 /* Check capabilities bit in the device status register */
2578 status= pci_attr_r16(devind, PCI_SR);
2579 if (!(status & PSR_CAPPTR))
2580 return;
2582 capptr= (pci_attr_r8_u(devind, PCI_CAPPTR) & PCI_CP_MASK);
2583 while (capptr != 0)
2585 type = pci_attr_r8_u(devind, capptr+CAP_TYPE);
2586 next= (pci_attr_r8_u(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
2587 switch(type)
2589 case 1: str= "PCI Power Management"; break;
2590 case 2: str= "AGP"; break;
2591 case 3: str= "Vital Product Data"; break;
2592 case 4: str= "Slot Identification"; break;
2593 case 5: str= "Message Signaled Interrupts"; break;
2594 case 6: str= "CompactPCI Hot Swap"; break;
2595 case 8: str= "AMD HyperTransport"; break;
2596 case 0xf: str= "Secure Device"; break;
2597 default: str= "(unknown type)"; break;
2600 printf(" @0x%x (0x%08x): capability type 0x%x: %s",
2601 capptr, pci_attr_r32_u(devind, capptr), type, str);
2602 if (type == 0x08)
2603 print_hyper_cap(devind, capptr);
2604 else if (type == 0x0f)
2606 subtype= (pci_attr_r8_u(devind, capptr+2) & 0x07);
2607 switch(subtype)
2609 case 0: str= "Device Exclusion Vector"; break;
2610 case 3: str= "IOMMU"; break;
2611 default: str= "(unknown type)"; break;
2613 printf(", sub type 0%o: %s", subtype, str);
2615 printf("\n");
2616 capptr= next;
2621 /*===========================================================================*
2622 * visible *
2623 *===========================================================================*/
2624 PRIVATE int visible(aclp, devind)
2625 struct rs_pci *aclp;
2626 int devind;
2628 int i;
2629 u32_t class_id;
2631 if (!aclp)
2632 return TRUE; /* Should be changed when ACLs become
2633 * mandatory.
2635 /* Check whether the caller is allowed to get this device. */
2636 for (i= 0; i<aclp->rsp_nr_device; i++)
2638 if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
2639 aclp->rsp_device[i].did == pcidev[devind].pd_did)
2641 return TRUE;
2644 if (!aclp->rsp_nr_class)
2645 return FALSE;
2647 class_id= (pcidev[devind].pd_baseclass << 16) |
2648 (pcidev[devind].pd_subclass << 8) |
2649 pcidev[devind].pd_infclass;
2650 for (i= 0; i<aclp->rsp_nr_class; i++)
2652 if (aclp->rsp_class[i].class ==
2653 (class_id & aclp->rsp_class[i].mask))
2655 return TRUE;
2659 return FALSE;
2662 /*===========================================================================*
2663 * print_hyper_cap *
2664 *===========================================================================*/
2665 PRIVATE void print_hyper_cap(devind, capptr)
2666 int devind;
2667 u8_t capptr;
2669 u32_t v;
2670 u16_t cmd;
2671 int type0, type1;
2673 printf("\n");
2674 v= pci_attr_r32_u(devind, capptr);
2675 printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr);
2676 cmd= (v >> 16) & 0xffff;
2677 #if 0
2678 if (v & 0x10000)
2680 printf(" WarmReset");
2681 v &= ~0x10000;
2683 if (v & 0x20000)
2685 printf(" DblEnded");
2686 v &= ~0x20000;
2688 printf(" DevNum %d", (v & 0x7C0000) >> 18);
2689 v &= ~0x7C0000;
2690 #endif
2691 type0= (cmd & 0xE000) >> 13;
2692 type1= (cmd & 0xF800) >> 11;
2693 if (type0 == 0 || type0 == 1)
2695 printf("Capability Type: %s\n",
2696 type0 == 0 ? "Slave or Primary Interface" :
2697 "Host or Secondary Interface");
2698 cmd &= ~0xE000;
2700 else
2702 printf(" Capability Type 0x%x", type1);
2703 cmd &= ~0xF800;
2705 if (cmd)
2706 printf(" undecoded 0x%x\n", cmd);
2708 #if 0
2709 printf("print_hyper_cap: off 4 (ctl): 0x%x\n",
2710 pci_attr_r32_u(devind, capptr+4));
2711 printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n",
2712 pci_attr_r32_u(devind, capptr+8));
2713 printf("print_hyper_cap: off 12 (cap): 0x%x\n",
2714 pci_attr_r32_u(devind, capptr+12));
2715 printf("print_hyper_cap: off 16 (buf count): 0x%x\n",
2716 pci_attr_r32_u(devind, capptr+16));
2717 v= pci_attr_r32_u(devind, capptr+20);
2718 printf("print_hyper_cap: @0x%x, off 20 (bus nr): ",
2719 capptr+20);
2720 printf("prim %d", v & 0xff);
2721 printf(", sec %d", (v >> 8) & 0xff);
2722 printf(", sub %d", (v >> 16) & 0xff);
2723 if (v >> 24)
2724 printf(", reserved %d", (v >> 24) & 0xff);
2725 printf("\n");
2726 printf("print_hyper_cap: off 24 (type): 0x%x\n",
2727 pci_attr_r32_u(devind, capptr+24));
2728 #endif
2732 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $