panic() cleanup.
[minix.git] / drivers / pci / pci.c
blob38cb1489ea39bd962be0538c7f24262ec2ebc855
1 #define USER_SPACE 1
2 /*
3 pci.c
4 #define USER_SPACE 1
6 Configure devices on the PCI bus
8 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
9 */
11 #include "../drivers.h"
12 #include <assert.h>
13 #include <ibm/pci.h>
14 #include <sys/vm_i386.h>
15 #include <minix/com.h>
16 #include <minix/syslib.h>
18 #include "pci.h"
19 #include "pci_amd.h"
20 #include "pci_intel.h"
21 #include "pci_sis.h"
22 #include "pci_via.h"
23 #if __minix_vmd
24 #include "config.h"
25 #endif
27 #if !__minix_vmd
28 #define irq_mode_pci(irq) ((void)0)
29 #endif
31 #include <stdlib.h>
32 #include <stdio.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("sys_safecopyfrom failed: %d", r);
178 for(i=0;i < NR_BOOT_PROCS;i++) {
179 if(rprocpub[i].in_use) {
180 if((r = map_service(&rprocpub[i])) != OK) {
181 panic("unable to map service: %d", r);
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("too many PCI busses: %d", 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(int busind)
758 u32_t dev, func, t3;
759 u16_t vid, did, sts;
760 u8_t headt;
761 u8_t baseclass, subclass, infclass;
762 int devind, busnr;
763 char *s, *dstr;
765 #if DEBUG
766 printf("probe_bus(%d)\n", busind);
767 #endif
768 if (nr_pcidev >= NR_PCIDEV)
769 panic("too many PCI devices: %d", nr_pcidev);
770 devind= nr_pcidev;
772 busnr= pcibus[busind].pb_busnr;
773 for (dev= 0; dev<32; dev++)
776 for (func= 0; func < 8; func++)
778 pcidev[devind].pd_busnr= busnr;
779 pcidev[devind].pd_dev= dev;
780 pcidev[devind].pd_func= func;
782 pci_attr_wsts(devind,
783 PSR_SSE|PSR_RMAS|PSR_RTAS);
784 vid= pci_attr_r16(devind, PCI_VID);
785 did= pci_attr_r16(devind, PCI_DID);
786 headt= pci_attr_r8_u(devind, PCI_HEADT);
787 sts= pci_attr_rsts(devind);
789 #if 0
790 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
791 vid, did, headt, sts);
792 #endif
794 if (vid == NO_VID && did == NO_VID)
796 if (func == 0)
797 break; /* Nothing here */
799 /* Scan all functions of a multifunction
800 * device.
802 continue;
805 if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
807 printf(
808 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
809 sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
812 dstr= pci_dev_name(vid, did);
813 if (debug)
815 if (dstr)
817 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
818 busind, (unsigned long)dev,
819 (unsigned long)func, dstr,
820 vid, did);
822 else
824 printf(
825 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
826 busind, (unsigned long)dev,
827 (unsigned long)func, vid,
828 pci_vid_name(vid), did);
830 printf("Device index: %d\n", devind);
831 printf("Subsystem: Vid 0x%x, did 0x%x\n",
832 pci_attr_r16(devind, PCI_SUBVID),
833 pci_attr_r16(devind, PCI_SUBDID));
836 baseclass= pci_attr_r8_u(devind, PCI_BCR);
837 subclass= pci_attr_r8_u(devind, PCI_SCR);
838 infclass= pci_attr_r8_u(devind, PCI_PIFR);
839 s= pci_subclass_name(baseclass, subclass, infclass);
840 if (!s)
841 s= pci_baseclass_name(baseclass);
843 if (!s)
844 s= "(unknown class)";
846 if (debug)
848 printf("\tclass %s (%X/%X/%X)\n", s,
849 baseclass, subclass, infclass);
852 if (is_duplicate(busnr, dev, func))
854 printf("\tduplicate!\n");
855 if (func == 0 && !(headt & PHT_MULTIFUNC))
856 break;
857 continue;
860 devind= nr_pcidev;
861 nr_pcidev++;
862 pcidev[devind].pd_baseclass= baseclass;
863 pcidev[devind].pd_subclass= subclass;
864 pcidev[devind].pd_infclass= infclass;
865 pcidev[devind].pd_vid= vid;
866 pcidev[devind].pd_did= did;
867 pcidev[devind].pd_inuse= 0;
868 pcidev[devind].pd_bar_nr= 0;
869 record_irq(devind);
870 switch(headt & PHT_MASK)
872 case PHT_NORMAL:
873 record_bars_normal(devind);
874 break;
875 case PHT_BRIDGE:
876 record_bars_bridge(devind);
877 break;
878 case PHT_CARDBUS:
879 record_bars_cardbus(devind);
880 break;
881 default:
882 printf("\t%d.%d.%d: unknown header type %d\n",
883 busind, dev, func,
884 headt & PHT_MASK);
885 break;
887 if (debug)
888 print_capabilities(devind);
890 t3= ((baseclass << 16) | (subclass << 8) | infclass);
891 #if 0
892 if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
893 report_vga(devind);
894 #endif
896 if (nr_pcidev >= NR_PCIDEV)
897 panic("too many PCI devices: %d", nr_pcidev);
898 devind= nr_pcidev;
900 if (func == 0 && !(headt & PHT_MULTIFUNC))
901 break;
906 /*===========================================================================*
907 * is_duplicate *
908 *===========================================================================*/
909 PRIVATE int is_duplicate(busnr, dev, func)
910 u8_t busnr;
911 u8_t dev;
912 u8_t func;
914 int i;
916 for (i= 0; i<nr_pcidev; i++)
918 if (pcidev[i].pd_busnr == busnr &&
919 pcidev[i].pd_dev == dev &&
920 pcidev[i].pd_func == func)
922 return 1;
925 return 0;
928 /*===========================================================================*
929 * record_irq *
930 *===========================================================================*/
931 PRIVATE void record_irq(devind)
932 int devind;
934 int ilr, ipr, busnr, busind, cb_devind;
936 ilr= pci_attr_r8_u(devind, PCI_ILR);
937 ipr= pci_attr_r8_u(devind, PCI_IPR);
938 if (ilr == 0)
940 static int first= 1;
941 if (ipr && first && debug)
943 first= 0;
944 printf("PCI: strange, BIOS assigned IRQ0\n");
946 ilr= PCI_ILR_UNKNOWN;
948 pcidev[devind].pd_ilr= ilr;
949 if (ilr == PCI_ILR_UNKNOWN && !ipr)
952 else if (ilr != PCI_ILR_UNKNOWN && ipr)
954 if (debug)
955 printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
957 else if (ilr != PCI_ILR_UNKNOWN)
959 printf(
960 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
961 ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
962 pcidev[devind].pd_func);
964 else
966 /* Check for cardbus devices */
967 busnr= pcidev[devind].pd_busnr;
968 busind= get_busind(busnr);
969 if (pcibus[busind].pb_type == PBT_CARDBUS)
971 cb_devind= pcibus[busind].pb_devind;
972 ilr= pcidev[cb_devind].pd_ilr;
973 if (ilr != PCI_ILR_UNKNOWN)
975 if (debug)
977 printf(
978 "assigning IRQ %d to Cardbus device\n",
979 ilr);
981 pci_attr_w8(devind, PCI_ILR, ilr);
982 pcidev[devind].pd_ilr= ilr;
983 return;
986 if(debug) {
987 printf(
988 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
989 pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
990 pcidev[devind].pd_func, 'A' + ipr-1);
995 /*===========================================================================*
996 * record_bars_normal *
997 *===========================================================================*/
998 PRIVATE void record_bars_normal(devind)
999 int devind;
1001 int i, j, clear_01, clear_23, pb_nr;
1003 /* The BAR area of normal devices is six DWORDs in size. */
1004 record_bars(devind, PCI_BAR_6);
1006 /* Special case code for IDE controllers in compatibility mode */
1007 if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
1008 pcidev[devind].pd_subclass == PCI_MS_IDE)
1010 /* IDE device */
1011 clear_01= 0;
1012 clear_23= 0;
1013 if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
1015 if (debug)
1017 printf(
1018 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1020 clear_01= 1;
1022 if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
1024 if (debug)
1026 printf(
1027 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
1029 clear_23= 1;
1032 j= 0;
1033 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
1035 pb_nr= pcidev[devind].pd_bar[i].pb_nr;
1036 if ((pb_nr == 0 || pb_nr == 1) && clear_01)
1038 if (debug) printf("skipping bar %d\n", pb_nr);
1039 continue; /* Skip */
1041 if ((pb_nr == 2 || pb_nr == 3) && clear_23)
1043 if (debug) printf("skipping bar %d\n", pb_nr);
1044 continue; /* Skip */
1046 if (i == j)
1048 j++;
1049 continue; /* No need to copy */
1051 pcidev[devind].pd_bar[j]=
1052 pcidev[devind].pd_bar[i];
1053 j++;
1055 pcidev[devind].pd_bar_nr= j;
1059 /*===========================================================================*
1060 * record_bars_bridge *
1061 *===========================================================================*/
1062 PRIVATE void record_bars_bridge(devind)
1063 int devind;
1065 u32_t base, limit, size;
1067 /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
1068 * It may contain up to two 32-bit BARs, or one 64-bit BAR.
1070 record_bars(devind, PCI_BAR_2);
1072 base= ((pci_attr_r8_u(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
1073 (pci_attr_r16(devind, PPB_IOBASEU16) << 16);
1074 limit= 0xff |
1075 ((pci_attr_r8_u(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
1076 ((~PPB_IOL_MASK & 0xff) << 8) |
1077 (pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
1078 size= limit-base + 1;
1079 if (debug)
1081 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1082 base, limit, size);
1085 base= ((pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
1086 limit= 0xffff |
1087 ((pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
1088 ((~PPB_MEML_MASK & 0xffff) << 16);
1089 size= limit-base + 1;
1090 if (debug)
1092 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1093 base, limit, size);
1096 /* Ignore the upper 32 bits */
1097 base= ((pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
1098 limit= 0xffff |
1099 ((pci_attr_r16(devind, PPB_PFMEMLIMIT) &
1100 PPB_PFMEML_MASK) << 16) |
1101 ((~PPB_PFMEML_MASK & 0xffff) << 16);
1102 size= limit-base + 1;
1103 if (debug)
1105 printf(
1106 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1107 base, limit, size);
1111 /*===========================================================================*
1112 * record_bars_cardbus *
1113 *===========================================================================*/
1114 PRIVATE void record_bars_cardbus(devind)
1115 int devind;
1117 u32_t base, limit, size;
1119 /* The generic BAR area of CardBus devices is one DWORD in size. */
1120 record_bars(devind, PCI_BAR);
1122 base= pci_attr_r32_u(devind, CBB_MEMBASE_0);
1123 limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_0) |
1124 (~CBB_MEML_MASK & 0xffffffff);
1125 size= limit-base + 1;
1126 if (debug)
1128 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1129 base, limit, size);
1132 base= pci_attr_r32_u(devind, CBB_MEMBASE_1);
1133 limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_1) |
1134 (~CBB_MEML_MASK & 0xffffffff);
1135 size= limit-base + 1;
1136 if (debug)
1138 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1139 base, limit, size);
1142 base= pci_attr_r32_u(devind, CBB_IOBASE_0);
1143 limit= pci_attr_r32_u(devind, CBB_IOLIMIT_0) |
1144 (~CBB_IOL_MASK & 0xffffffff);
1145 size= limit-base + 1;
1146 if (debug)
1148 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1149 base, limit, size);
1152 base= pci_attr_r32_u(devind, CBB_IOBASE_1);
1153 limit= pci_attr_r32_u(devind, CBB_IOLIMIT_1) |
1154 (~CBB_IOL_MASK & 0xffffffff);
1155 size= limit-base + 1;
1156 if (debug)
1158 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1159 base, limit, size);
1163 /*===========================================================================*
1164 * record_bars *
1165 *===========================================================================*/
1166 PRIVATE void record_bars(devind, last_reg)
1168 int i, reg, width;
1170 for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width)
1172 width = record_bar(devind, i, reg == last_reg);
1176 /*===========================================================================*
1177 * record_bar *
1178 *===========================================================================*/
1179 PRIVATE int record_bar(devind, bar_nr, last)
1180 int devind;
1181 int bar_nr;
1182 int last;
1184 int reg, prefetch, type, dev_bar_nr, width;
1185 u32_t bar, bar2;
1186 u16_t cmd;
1188 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
1189 width = 1;
1191 reg= PCI_BAR+4*bar_nr;
1193 bar= pci_attr_r32_u(devind, reg);
1194 if (bar & PCI_BAR_IO)
1196 /* Disable I/O access before probing for BAR's size */
1197 cmd = pci_attr_r16(devind, PCI_CR);
1198 pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_IO_EN);
1200 /* Probe BAR's size */
1201 pci_attr_w32(devind, reg, 0xffffffff);
1202 bar2= pci_attr_r32_u(devind, reg);
1204 /* Restore original state */
1205 pci_attr_w32(devind, reg, bar);
1206 pci_attr_w16(devind, PCI_CR, cmd);
1208 bar &= ~(u32_t)3; /* Clear non-address bits */
1209 bar2 &= ~(u32_t)3;
1210 bar2= (~bar2 & 0xffff)+1;
1211 if (debug)
1213 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1214 bar_nr, bar2, bar);
1217 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1218 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO;
1219 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1220 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1221 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1222 if (bar == 0)
1224 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1225 PBF_INCOMPLETE;
1228 else
1230 type= (bar & PCI_BAR_TYPE);
1232 switch(type) {
1233 case PCI_TYPE_32:
1234 case PCI_TYPE_32_1M:
1235 break;
1237 case PCI_TYPE_64:
1238 /* A 64-bit BAR takes up two consecutive DWORDs. */
1239 if (last)
1241 printf("PCI: device %d.%d.%d BAR %d extends"
1242 " beyond designated area\n",
1243 pcidev[devind].pd_busnr,
1244 pcidev[devind].pd_dev,
1245 pcidev[devind].pd_func, bar_nr);
1247 return width;
1249 width++;
1251 bar2= pci_attr_r32_u(devind, reg+4);
1253 /* If the upper 32 bits of the BAR are not zero, the
1254 * memory is inaccessible to us; ignore the BAR.
1256 if (bar2 != 0)
1258 if (debug)
1260 printf("\tbar_%d: (64-bit BAR with"
1261 " high bits set)\n", bar_nr);
1264 return width;
1267 break;
1269 default:
1270 /* Ignore the BAR. */
1271 if (debug)
1273 printf("\tbar_%d: (unknown type %x)\n",
1274 bar_nr, type);
1277 return width;
1280 /* Disable mem access before probing for BAR's size */
1281 cmd = pci_attr_r16(devind, PCI_CR);
1282 pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_MEM_EN);
1284 /* Probe BAR's size */
1285 pci_attr_w32(devind, reg, 0xffffffff);
1286 bar2= pci_attr_r32_u(devind, reg);
1288 /* Restore original values */
1289 pci_attr_w32(devind, reg, bar);
1290 pci_attr_w16(devind, PCI_CR, cmd);
1292 if (bar2 == 0)
1293 return width; /* Reg. is not implemented */
1295 prefetch= !!(bar & PCI_BAR_PREFETCH);
1296 bar &= ~(u32_t)0xf; /* Clear non-address bits */
1297 bar2 &= ~(u32_t)0xf;
1298 bar2= (~bar2)+1;
1299 if (debug)
1301 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n",
1302 bar_nr, bar2, bar,
1303 prefetch ? " prefetchable" : "",
1304 type == PCI_TYPE_64 ? ", 64-bit" : "");
1307 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1308 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0;
1309 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1310 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1311 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1312 if (bar == 0)
1314 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1315 PBF_INCOMPLETE;
1319 return width;
1322 /*===========================================================================*
1323 * complete_bridges *
1324 *===========================================================================*/
1325 PRIVATE void complete_bridges()
1327 int i, freebus, devind, prim_busnr;
1329 for (i= 0; i<nr_pcibus; i++)
1331 if (!pcibus[i].pb_needinit)
1332 continue;
1333 printf("should allocate bus number for bus %d\n", i);
1334 freebus= get_freebus();
1335 printf("got bus number %d\n", freebus);
1337 devind= pcibus[i].pb_devind;
1339 prim_busnr= pcidev[devind].pd_busnr;
1340 if (prim_busnr != 0)
1342 printf(
1343 "complete_bridge: updating subordinate bus number not implemented\n");
1346 pcibus[i].pb_needinit= 0;
1347 pcibus[i].pb_busnr= freebus;
1349 printf("devind = %d\n", devind);
1350 printf("prim_busnr= %d\n", prim_busnr);
1352 pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
1353 pci_attr_w8(devind, PPB_SECBN, freebus);
1354 pci_attr_w8(devind, PPB_SUBORDBN, freebus);
1356 printf("CR = 0x%x\n", pci_attr_r16(devind, PCI_CR));
1357 printf("SECBLT = 0x%x\n", pci_attr_r8_u(devind, PPB_SECBLT));
1358 printf("BRIDGECTRL = 0x%x\n",
1359 pci_attr_r16(devind, PPB_BRIDGECTRL));
1363 /*===========================================================================*
1364 * complete_bars *
1365 *===========================================================================*/
1366 PRIVATE void complete_bars(void)
1368 int i, j, r, bar_nr, reg;
1369 u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
1370 base, size, v32, diff1, diff2;
1371 char *cp, *next;
1372 char memstr[256];
1374 r= env_get_param("memory", memstr, sizeof(memstr));
1375 if (r != OK)
1376 panic("env_get_param failed: %d", r);
1378 /* Set memgap_low to just above physical memory */
1379 memgap_low= 0;
1380 cp= memstr;
1381 while (*cp != '\0')
1383 base= strtoul(cp, &next, 16);
1384 if (!(*next) || next == cp || *next != ':')
1385 goto bad_mem_string;
1386 cp= next+1;
1387 size= strtoul(cp, &next, 16);
1388 if (next == cp || (*next != ',' && *next != '\0'))
1389 if (!*next)
1390 goto bad_mem_string;
1391 if (base+size > memgap_low)
1392 memgap_low= base+size;
1394 if (*next)
1395 cp= next+1;
1396 else
1397 break;
1400 memgap_high= 0xfe000000; /* Leave space for the CPU (APIC) */
1402 if (debug)
1404 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1405 memgap_low, memgap_high);
1408 /* Find the lowest memory base */
1409 for (i= 0; i<nr_pcidev; i++)
1411 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1413 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1414 continue;
1415 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1416 continue;
1417 base= pcidev[i].pd_bar[j].pb_base;
1418 size= pcidev[i].pd_bar[j].pb_size;
1420 if (base >= memgap_high)
1421 continue; /* Not in the gap */
1422 if (base+size <= memgap_low)
1423 continue; /* Not in the gap */
1425 /* Reduce the gap by the smallest amount */
1426 diff1= base+size-memgap_low;
1427 diff2= memgap_high-base;
1429 if (diff1 < diff2)
1430 memgap_low= base+size;
1431 else
1432 memgap_high= base;
1436 if (debug)
1438 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1439 memgap_low, memgap_high);
1442 /* Should check main memory size */
1443 if (memgap_high < memgap_low)
1445 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1446 memgap_low, memgap_high);
1447 panic(NULL);
1450 iogap_high= 0x10000;
1451 iogap_low= 0x400;
1453 /* Find the free I/O space */
1454 for (i= 0; i<nr_pcidev; i++)
1456 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1458 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1459 continue;
1460 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1461 continue;
1462 base= pcidev[i].pd_bar[j].pb_base;
1463 size= pcidev[i].pd_bar[j].pb_size;
1464 if (base >= iogap_high)
1465 continue;
1466 if (base+size <= iogap_low)
1467 continue;
1468 #if 0
1469 if (debug)
1471 printf(
1472 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
1473 i, pcidev[i].pd_vid, pcidev[i].pd_did,
1474 j, base, size);
1476 #endif
1477 if (base+size-iogap_low < iogap_high-base)
1478 iogap_low= base+size;
1479 else
1480 iogap_high= base;
1484 if (iogap_high < iogap_low)
1486 if (debug)
1488 printf("iogap_high too low, should panic\n");
1490 else
1491 panic("iogap_high too low: %d", iogap_high);
1493 if (debug)
1494 printf("I/O range = [0x%x..0x%x>\n", iogap_low, iogap_high);
1496 for (i= 0; i<nr_pcidev; i++)
1498 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1500 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1501 continue;
1502 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1503 continue;
1504 size= pcidev[i].pd_bar[j].pb_size;
1505 if (size < I386_PAGE_SIZE)
1506 size= I386_PAGE_SIZE;
1507 base= memgap_high-size;
1508 base &= ~(u32_t)(size-1);
1509 if (base < memgap_low)
1510 panic("memory base too low: %d", base);
1511 memgap_high= base;
1512 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1513 reg= PCI_BAR + 4*bar_nr;
1514 v32= pci_attr_r32_u(i, reg);
1515 pci_attr_w32(i, reg, v32 | base);
1516 if (debug)
1518 printf(
1519 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1520 base, size, pcidev[i].pd_busnr,
1521 pcidev[i].pd_dev, pcidev[i].pd_func,
1522 bar_nr);
1524 pcidev[i].pd_bar[j].pb_base= base;
1525 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1528 io_high= iogap_high;
1529 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1531 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1532 continue;
1533 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1534 continue;
1535 size= pcidev[i].pd_bar[j].pb_size;
1536 base= iogap_high-size;
1537 base &= ~(u32_t)(size-1);
1539 /* Assume that ISA compatibility is required. Only
1540 * use the lowest 256 bytes out of every 1024 bytes.
1542 base &= 0xfcff;
1544 if (base < iogap_low)
1545 panic("I/O base too low: %d", base);
1547 iogap_high= base;
1548 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1549 reg= PCI_BAR + 4*bar_nr;
1550 v32= pci_attr_r32_u(i, reg);
1551 pci_attr_w32(i, reg, v32 | base);
1552 if (debug)
1554 printf(
1555 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1556 base, size, pcidev[i].pd_busnr,
1557 pcidev[i].pd_dev, pcidev[i].pd_func,
1558 bar_nr);
1560 pcidev[i].pd_bar[j].pb_base= base;
1561 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1564 if (iogap_high != io_high)
1566 update_bridge4dev_io(i, iogap_high,
1567 io_high-iogap_high);
1571 for (i= 0; i<nr_pcidev; i++)
1573 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1575 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1576 continue;
1577 printf("should allocate resources for device %d\n", i);
1580 return;
1582 bad_mem_string:
1583 printf("PCI: bad memory environment string '%s'\n", memstr);
1584 panic(NULL);
1587 /*===========================================================================*
1588 * update_bridge4dev_io *
1589 *===========================================================================*/
1590 PRIVATE void update_bridge4dev_io(devind, io_base, io_size)
1591 int devind;
1592 u32_t io_base;
1593 u32_t io_size;
1595 int busnr, busind, type, br_devind;
1596 u16_t v16;
1598 busnr= pcidev[devind].pd_busnr;
1599 busind= get_busind(busnr);
1600 type= pcibus[busind].pb_type;
1601 if (type == PBT_INTEL_HOST)
1602 return; /* Nothing to do for host controller */
1603 if (type == PBT_PCIBRIDGE)
1605 printf(
1606 "update_bridge4dev_io: not implemented for PCI bridges\n");
1607 return;
1609 if (type != PBT_CARDBUS)
1610 panic("update_bridge4dev_io: strange bus type: %d", type);
1612 if (debug)
1614 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1615 io_size, io_base);
1617 br_devind= pcibus[busind].pb_devind;
1618 pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
1619 pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
1621 /* Enable I/O access. Enable busmaster access as well. */
1622 v16= pci_attr_r16(devind, PCI_CR);
1623 pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
1626 /*===========================================================================*
1627 * get_freebus *
1628 *===========================================================================*/
1629 PRIVATE int get_freebus()
1631 int i, freebus;
1633 freebus= 1;
1634 for (i= 0; i<nr_pcibus; i++)
1636 if (pcibus[i].pb_needinit)
1637 continue;
1638 if (pcibus[i].pb_type == PBT_INTEL_HOST)
1639 continue;
1640 if (pcibus[i].pb_busnr <= freebus)
1641 freebus= pcibus[i].pb_busnr+1;
1642 printf("get_freebus: should check suboridinate bus number\n");
1644 return freebus;
1647 /*===========================================================================*
1648 * do_isabridge *
1649 *===========================================================================*/
1650 PRIVATE int do_isabridge(busind)
1651 int busind;
1653 int i, j, r, type, busnr, unknown_bridge, bridge_dev;
1654 u16_t vid, did;
1655 u32_t t3;
1656 char *dstr;
1658 unknown_bridge= -1;
1659 bridge_dev= -1;
1660 j= 0; /* lint */
1661 vid= did= 0; /* lint */
1662 busnr= pcibus[busind].pb_busnr;
1663 for (i= 0; i< nr_pcidev; i++)
1665 if (pcidev[i].pd_busnr != busnr)
1666 continue;
1667 t3= ((pcidev[i].pd_baseclass << 16) |
1668 (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
1669 if (t3 == PCI_T3_ISA)
1671 /* ISA bridge. Report if no supported bridge is
1672 * found.
1674 unknown_bridge= i;
1677 vid= pcidev[i].pd_vid;
1678 did= pcidev[i].pd_did;
1679 for (j= 0; pci_isabridge[j].vid != 0; j++)
1681 if (pci_isabridge[j].vid != vid)
1682 continue;
1683 if (pci_isabridge[j].did != did)
1684 continue;
1685 if (pci_isabridge[j].checkclass &&
1686 unknown_bridge != i)
1688 /* This part of multifunction device is
1689 * not the bridge.
1691 continue;
1693 break;
1695 if (pci_isabridge[j].vid)
1697 bridge_dev= i;
1698 break;
1702 if (bridge_dev != -1)
1704 dstr= pci_dev_name(vid, did);
1705 if (!dstr)
1706 dstr= "unknown device";
1707 if (debug)
1709 printf("found ISA bridge (%04X/%04X) %s\n",
1710 vid, did, dstr);
1712 pcibus[busind].pb_isabridge_dev= bridge_dev;
1713 type= pci_isabridge[j].type;
1714 pcibus[busind].pb_isabridge_type= type;
1715 switch(type)
1717 case PCI_IB_PIIX:
1718 r= do_piix(bridge_dev);
1719 break;
1720 case PCI_IB_VIA:
1721 r= do_via_isabr(bridge_dev);
1722 break;
1723 case PCI_IB_AMD:
1724 r= do_amd_isabr(bridge_dev);
1725 break;
1726 case PCI_IB_SIS:
1727 r= do_sis_isabr(bridge_dev);
1728 break;
1729 default:
1730 panic("unknown ISA bridge type: %d", type);
1732 return r;
1735 if (unknown_bridge == -1)
1737 if (debug)
1739 printf("(warning) no ISA bridge found on bus %d\n",
1740 busind);
1742 return 0;
1744 if (debug)
1746 printf(
1747 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
1748 pcidev[unknown_bridge].pd_vid,
1749 pcidev[unknown_bridge].pd_did, busind);
1751 return 0;
1754 /*===========================================================================*
1755 * do_pcibridge *
1756 *===========================================================================*/
1757 PRIVATE void do_pcibridge(busind)
1758 int busind;
1760 int i, devind, busnr;
1761 int ind, type;
1762 u16_t vid, did;
1763 u8_t sbusn, baseclass, subclass, infclass, headt;
1764 u32_t t3;
1766 vid= did= 0; /* lint */
1767 busnr= pcibus[busind].pb_busnr;
1768 for (devind= 0; devind< nr_pcidev; devind++)
1770 #if 0
1771 printf("do_pcibridge: trying %u.%u.%u\n",
1772 pcidev[devind].pd_busind, pcidev[devind].pd_dev,
1773 pcidev[devind].pd_func);
1774 #endif
1776 if (pcidev[devind].pd_busnr != busnr)
1778 #if 0
1779 printf("wrong bus\n");
1780 #endif
1781 continue;
1784 vid= pcidev[devind].pd_vid;
1785 did= pcidev[devind].pd_did;
1786 for (i= 0; pci_pcibridge[i].vid != 0; i++)
1788 if (pci_pcibridge[i].vid != vid)
1789 continue;
1790 if (pci_pcibridge[i].did != did)
1791 continue;
1792 break;
1794 type= pci_pcibridge[i].type;
1795 if (pci_pcibridge[i].vid == 0)
1797 headt= pci_attr_r8_u(devind, PCI_HEADT);
1798 type= 0;
1799 if ((headt & PHT_MASK) == PHT_BRIDGE)
1800 type= PCI_PPB_STD;
1801 else if ((headt & PHT_MASK) == PHT_CARDBUS)
1802 type= PCI_PPB_CB;
1803 else
1805 #if 0
1806 printf("not a bridge\n");
1807 #endif
1808 continue; /* Not a bridge */
1811 baseclass= pci_attr_r8_u(devind, PCI_BCR);
1812 subclass= pci_attr_r8_u(devind, PCI_SCR);
1813 infclass= pci_attr_r8_u(devind, PCI_PIFR);
1814 t3= ((baseclass << 16) | (subclass << 8) | infclass);
1815 if (type == PCI_PPB_STD &&
1816 t3 != PCI_T3_PCI2PCI &&
1817 t3 != PCI_T3_PCI2PCI_SUBTR)
1819 printf(
1820 "Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
1821 baseclass, subclass, infclass,
1822 vid, did);
1823 continue;
1825 if (type == PCI_PPB_CB &&
1826 t3 != PCI_T3_CARDBUS)
1828 printf(
1829 "Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
1830 baseclass, subclass, infclass,
1831 vid, did);
1832 continue;
1836 if (debug)
1838 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
1839 pcidev[devind].pd_busnr,
1840 pcidev[devind].pd_dev,
1841 pcidev[devind].pd_func, vid, did);
1844 /* Assume that the BIOS initialized the secondary bus
1845 * number.
1847 sbusn= pci_attr_r8_u(devind, PPB_SECBN);
1849 if (nr_pcibus >= NR_PCIBUS)
1850 panic("too many PCI busses: %d", nr_pcibus);
1851 ind= nr_pcibus;
1852 nr_pcibus++;
1853 pcibus[ind].pb_type= PBT_PCIBRIDGE;
1854 pcibus[ind].pb_needinit= 1;
1855 pcibus[ind].pb_isabridge_dev= -1;
1856 pcibus[ind].pb_isabridge_type= 0;
1857 pcibus[ind].pb_devind= devind;
1858 pcibus[ind].pb_busnr= sbusn;
1859 pcibus[ind].pb_rreg8= pcibus[busind].pb_rreg8;
1860 pcibus[ind].pb_rreg16= pcibus[busind].pb_rreg16;
1861 pcibus[ind].pb_rreg32= pcibus[busind].pb_rreg32;
1862 pcibus[ind].pb_wreg8= pcibus[busind].pb_wreg8;
1863 pcibus[ind].pb_wreg16= pcibus[busind].pb_wreg16;
1864 pcibus[ind].pb_wreg32= pcibus[busind].pb_wreg32;
1865 switch(type)
1867 case PCI_PPB_STD:
1868 pcibus[ind].pb_rsts= pcibr_std_rsts;
1869 pcibus[ind].pb_wsts= pcibr_std_wsts;
1870 break;
1871 case PCI_PPB_CB:
1872 pcibus[ind].pb_type= PBT_CARDBUS;
1873 pcibus[ind].pb_rsts= pcibr_cb_rsts;
1874 pcibus[ind].pb_wsts= pcibr_cb_wsts;
1875 break;
1876 case PCI_AGPB_VIA:
1877 pcibus[ind].pb_rsts= pcibr_via_rsts;
1878 pcibus[ind].pb_wsts= pcibr_via_wsts;
1879 break;
1880 default:
1881 panic("unknown PCI-PCI bridge type: %d", type);
1883 if (debug)
1885 printf(
1886 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1887 ind, sbusn, pci_attr_r8_u(devind, PPB_SUBORDBN));
1889 if (sbusn == 0)
1891 printf("Secondary bus number not initialized\n");
1892 continue;
1894 pcibus[ind].pb_needinit= 0;
1896 probe_bus(ind);
1898 /* Look for PCI bridges */
1899 do_pcibridge(ind);
1903 /*===========================================================================*
1904 * get_busind *
1905 *===========================================================================*/
1906 PRIVATE int get_busind(busnr)
1907 int busnr;
1909 int i;
1911 for (i= 0; i<nr_pcibus; i++)
1913 if (pcibus[i].pb_busnr == busnr)
1914 return i;
1916 panic("get_busind: can't find bus: %d", busnr);
1919 /*===========================================================================*
1920 * do_piix *
1921 *===========================================================================*/
1922 PRIVATE int do_piix(int devind)
1924 int i, s, irqrc, irq;
1925 u32_t elcr1, elcr2, elcr;
1927 #if DEBUG
1928 printf("in piix\n");
1929 #endif
1930 #if USER_SPACE
1931 if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
1932 printf("Warning, sys_inb failed: %d\n", s);
1933 if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
1934 printf("Warning, sys_inb failed: %d\n", s);
1935 #else
1936 elcr1= inb(PIIX_ELCR1);
1937 elcr2= inb(PIIX_ELCR2);
1938 #endif
1939 elcr= elcr1 | (elcr2 << 8);
1940 for (i= 0; i<4; i++)
1942 irqrc= pci_attr_r8_u(devind, PIIX_PIRQRCA+i);
1943 if (irqrc & PIIX_IRQ_DI)
1945 if (debug)
1946 printf("INT%c: disabled\n", 'A'+i);
1948 else
1950 irq= irqrc & PIIX_IRQ_MASK;
1951 if (debug)
1952 printf("INT%c: %d\n", 'A'+i, irq);
1953 if (!(elcr & (1 << irq)))
1955 if (debug)
1957 printf(
1958 "(warning) IRQ %d is not level triggered\n",
1959 irq);
1962 irq_mode_pci(irq);
1965 return 0;
1968 /*===========================================================================*
1969 * do_amd_isabr *
1970 *===========================================================================*/
1971 PRIVATE int do_amd_isabr(int devind)
1973 int i, busnr, dev, func, xdevind, irq, edge;
1974 u8_t levmask;
1975 u16_t pciirq;
1977 /* Find required function */
1978 func= AMD_ISABR_FUNC;
1979 busnr= pcidev[devind].pd_busnr;
1980 dev= pcidev[devind].pd_dev;
1982 /* Fake a device with the required function */
1983 if (nr_pcidev >= NR_PCIDEV)
1984 panic("too many PCI devices: %d", nr_pcidev);
1985 xdevind= nr_pcidev;
1986 pcidev[xdevind].pd_busnr= busnr;
1987 pcidev[xdevind].pd_dev= dev;
1988 pcidev[xdevind].pd_func= func;
1989 pcidev[xdevind].pd_inuse= 1;
1990 nr_pcidev++;
1992 levmask= pci_attr_r8_u(xdevind, AMD_ISABR_PCIIRQ_LEV);
1993 pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
1994 for (i= 0; i<4; i++)
1996 edge= (levmask >> i) & 1;
1997 irq= (pciirq >> (4*i)) & 0xf;
1998 if (!irq)
2000 if (debug)
2001 printf("INT%c: disabled\n", 'A'+i);
2003 else
2005 if (debug)
2006 printf("INT%c: %d\n", 'A'+i, irq);
2007 if (edge && debug)
2009 printf(
2010 "(warning) IRQ %d is not level triggered\n",
2011 irq);
2013 irq_mode_pci(irq);
2016 nr_pcidev--;
2017 return 0;
2020 /*===========================================================================*
2021 * do_sis_isabr *
2022 *===========================================================================*/
2023 PRIVATE int do_sis_isabr(int devind)
2025 int i, irq;
2027 irq= 0; /* lint */
2028 for (i= 0; i<4; i++)
2030 irq= pci_attr_r8_u(devind, SIS_ISABR_IRQ_A+i);
2031 if (irq & SIS_IRQ_DISABLED)
2033 if (debug)
2034 printf("INT%c: disabled\n", 'A'+i);
2036 else
2038 irq &= SIS_IRQ_MASK;
2039 if (debug)
2040 printf("INT%c: %d\n", 'A'+i, irq);
2041 irq_mode_pci(irq);
2044 return 0;
2047 /*===========================================================================*
2048 * do_via_isabr *
2049 *===========================================================================*/
2050 PRIVATE int do_via_isabr(int devind)
2052 int i, irq, edge;
2053 u8_t levmask;
2055 levmask= pci_attr_r8_u(devind, VIA_ISABR_EL);
2056 irq= 0; /* lint */
2057 edge= 0; /* lint */
2058 for (i= 0; i<4; i++)
2060 switch(i)
2062 case 0:
2063 edge= (levmask & VIA_ISABR_EL_INTA);
2064 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2) >> 4;
2065 break;
2066 case 1:
2067 edge= (levmask & VIA_ISABR_EL_INTB);
2068 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2);
2069 break;
2070 case 2:
2071 edge= (levmask & VIA_ISABR_EL_INTC);
2072 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R3) >> 4;
2073 break;
2074 case 3:
2075 edge= (levmask & VIA_ISABR_EL_INTD);
2076 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R1) >> 4;
2077 break;
2078 default:
2079 assert(0);
2081 irq &= 0xf;
2082 if (!irq)
2084 if (debug)
2085 printf("INT%c: disabled\n", 'A'+i);
2087 else
2089 if (debug)
2090 printf("INT%c: %d\n", 'A'+i, irq);
2091 if (edge && debug)
2093 printf(
2094 "(warning) IRQ %d is not level triggered\n",
2095 irq);
2097 irq_mode_pci(irq);
2100 return 0;
2104 #if 0
2105 /*===========================================================================*
2106 * report_vga *
2107 *===========================================================================*/
2108 PRIVATE void report_vga(devind)
2109 int devind;
2111 /* Report the amount of video memory. This is needed by the X11R6
2112 * postinstall script to chmem the X server. Hopefully this can be
2113 * removed when we get virtual memory.
2115 size_t amount, size;
2116 int i;
2118 amount= 0;
2119 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
2121 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
2122 continue;
2123 size= pcidev[devind].pd_bar[i].pb_size;
2124 if (size < amount)
2125 continue;
2126 amount= size;
2128 if (size != 0)
2130 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
2131 pcidev[devind].pd_busnr,
2132 pcidev[devind].pd_dev,
2133 pcidev[devind].pd_func,
2134 amount);
2137 #endif
2140 /*===========================================================================*
2141 * pci_vid_name *
2142 *===========================================================================*/
2143 PRIVATE char *pci_vid_name(vid)
2144 u16_t vid;
2146 int i;
2148 for (i= 0; pci_vendor_table[i].name; i++)
2150 if (pci_vendor_table[i].vid == vid)
2151 return pci_vendor_table[i].name;
2153 return "unknown";
2156 /*===========================================================================*
2157 * pci_baseclass_name *
2158 *===========================================================================*/
2159 PRIVATE char *pci_baseclass_name(baseclass)
2160 u8_t baseclass;
2162 int i;
2164 for (i= 0; pci_baseclass_table[i].name; i++)
2166 if (pci_baseclass_table[i].baseclass == baseclass)
2167 return pci_baseclass_table[i].name;
2169 return NULL;
2172 /*===========================================================================*
2173 * pci_subclass_name *
2174 *===========================================================================*/
2175 PRIVATE char *pci_subclass_name(baseclass, subclass, infclass)
2176 u8_t baseclass;
2177 u8_t subclass;
2178 u8_t infclass;
2180 int i;
2182 for (i= 0; pci_subclass_table[i].name; i++)
2184 if (pci_subclass_table[i].baseclass != baseclass)
2185 continue;
2186 if (pci_subclass_table[i].subclass != subclass)
2187 continue;
2188 if (pci_subclass_table[i].infclass != infclass &&
2189 pci_subclass_table[i].infclass != (u16_t)-1)
2191 continue;
2193 return pci_subclass_table[i].name;
2195 return NULL;
2198 /*===========================================================================*
2199 * ntostr *
2200 *===========================================================================*/
2201 PRIVATE void ntostr(n, str, end)
2202 unsigned n;
2203 char **str;
2204 char *end;
2206 char tmpstr[20];
2207 int i;
2209 if (n == 0)
2211 tmpstr[0]= '0';
2212 i= 1;
2214 else
2216 for (i= 0; n; i++)
2218 tmpstr[i]= '0' + (n%10);
2219 n /= 10;
2222 for (; i>0; i--)
2224 if (*str == end)
2226 break;
2228 **str= tmpstr[i-1];
2229 (*str)++;
2231 if (*str == end)
2232 end[-1]= '\0';
2233 else
2234 **str= '\0';
2237 /*===========================================================================*
2238 * pci_attr_rsts *
2239 *===========================================================================*/
2240 PRIVATE u16_t pci_attr_rsts(devind)
2241 int devind;
2243 int busnr, busind;
2245 busnr= pcidev[devind].pd_busnr;
2246 busind= get_busind(busnr);
2247 return pcibus[busind].pb_rsts(busind);
2251 /*===========================================================================*
2252 * pcibr_std_rsts *
2253 *===========================================================================*/
2254 PRIVATE u16_t pcibr_std_rsts(busind)
2255 int busind;
2257 int devind;
2259 devind= pcibus[busind].pb_devind;
2260 return pci_attr_r16(devind, PPB_SSTS);
2263 /*===========================================================================*
2264 * pcibr_std_wsts *
2265 *===========================================================================*/
2266 PRIVATE void pcibr_std_wsts(busind, value)
2267 int busind;
2268 u16_t value;
2270 int devind;
2271 devind= pcibus[busind].pb_devind;
2273 #if 0
2274 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2275 busind, value, devind);
2276 #endif
2277 pci_attr_w16(devind, PPB_SSTS, value);
2280 /*===========================================================================*
2281 * pcibr_cb_rsts *
2282 *===========================================================================*/
2283 PRIVATE u16_t pcibr_cb_rsts(busind)
2284 int busind;
2286 int devind;
2287 devind= pcibus[busind].pb_devind;
2289 return pci_attr_r16(devind, CBB_SSTS);
2292 /*===========================================================================*
2293 * pcibr_cb_wsts *
2294 *===========================================================================*/
2295 PRIVATE void pcibr_cb_wsts(busind, value)
2296 int busind;
2297 u16_t value;
2299 int devind;
2300 devind= pcibus[busind].pb_devind;
2302 #if 0
2303 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2304 busind, value, devind);
2305 #endif
2306 pci_attr_w16(devind, CBB_SSTS, value);
2309 /*===========================================================================*
2310 * pcibr_via_rsts *
2311 *===========================================================================*/
2312 PRIVATE u16_t pcibr_via_rsts(busind)
2313 int busind;
2315 int devind;
2316 devind= pcibus[busind].pb_devind;
2318 return 0;
2321 /*===========================================================================*
2322 * pcibr_via_wsts *
2323 *===========================================================================*/
2324 PRIVATE void pcibr_via_wsts(busind, value)
2325 int busind;
2326 u16_t value;
2328 int devind;
2329 devind= pcibus[busind].pb_devind;
2331 #if 0
2332 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2333 busind, value, devind);
2334 #endif
2337 /*===========================================================================*
2338 * pci_attr_wsts *
2339 *===========================================================================*/
2340 PRIVATE void pci_attr_wsts(int devind, u16_t value)
2342 int busnr, busind;
2344 busnr= pcidev[devind].pd_busnr;
2345 busind= get_busind(busnr);
2346 pcibus[busind].pb_wsts(busind, value);
2350 /*===========================================================================*
2351 * pcii_rreg8 *
2352 *===========================================================================*/
2353 PRIVATE u8_t pcii_rreg8(busind, devind, port)
2354 int busind;
2355 int devind;
2356 int port;
2358 u8_t v;
2359 int s;
2361 v= PCII_RREG8_(pcibus[busind].pb_busnr,
2362 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2363 port);
2364 #if USER_SPACE
2365 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2366 printf("PCI: warning, sys_outl failed: %d\n", s);
2367 #else
2368 outl(PCII_CONFADD, PCII_UNSEL);
2369 #endif
2370 #if 0
2371 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2372 busind, devind, port,
2373 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2374 pcidev[devind].pd_func, v);
2375 #endif
2376 return v;
2379 /*===========================================================================*
2380 * pcii_rreg16 *
2381 *===========================================================================*/
2382 PRIVATE u16_t pcii_rreg16(busind, devind, port)
2383 int busind;
2384 int devind;
2385 int port;
2387 u16_t v;
2388 int s;
2390 v= PCII_RREG16_(pcibus[busind].pb_busnr,
2391 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2392 port);
2393 #if USER_SPACE
2394 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2395 printf("PCI: warning, sys_outl failed: %d\n");
2396 #else
2397 outl(PCII_CONFADD, PCII_UNSEL);
2398 #endif
2399 #if 0
2400 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2401 busind, devind, port,
2402 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2403 pcidev[devind].pd_func, v);
2404 #endif
2405 return v;
2408 /*===========================================================================*
2409 * pcii_rreg32 *
2410 *===========================================================================*/
2411 PRIVATE u32_t pcii_rreg32(busind, devind, port)
2412 int busind;
2413 int devind;
2414 int port;
2416 u32_t v;
2417 int s;
2419 v= PCII_RREG32_(pcibus[busind].pb_busnr,
2420 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2421 port);
2422 #if USER_SPACE
2423 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2424 printf("PCI: warning, sys_outl failed: %d\n", s);
2425 #else
2426 outl(PCII_CONFADD, PCII_UNSEL);
2427 #endif
2428 #if 0
2429 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2430 busind, devind, port,
2431 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2432 pcidev[devind].pd_func, v);
2433 #endif
2434 return v;
2437 /*===========================================================================*
2438 * pcii_wreg8 *
2439 *===========================================================================*/
2440 PRIVATE void pcii_wreg8(busind, devind, port, value)
2441 int busind;
2442 int devind;
2443 int port;
2444 u8_t value;
2446 int s;
2447 #if 0
2448 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2449 busind, devind, port, value,
2450 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2451 pcidev[devind].pd_func);
2452 #endif
2453 PCII_WREG8_(pcibus[busind].pb_busnr,
2454 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2455 port, value);
2456 #if USER_SPACE
2457 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2458 printf("PCI: warning, sys_outl failed: %d\n", s);
2459 #else
2460 outl(PCII_CONFADD, PCII_UNSEL);
2461 #endif
2464 /*===========================================================================*
2465 * pcii_wreg16 *
2466 *===========================================================================*/
2467 PRIVATE void pcii_wreg16(busind, devind, port, value)
2468 int busind;
2469 int devind;
2470 int port;
2471 u16_t value;
2473 int s;
2474 #if 0
2475 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2476 busind, devind, port, value,
2477 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2478 pcidev[devind].pd_func);
2479 #endif
2480 PCII_WREG16_(pcibus[busind].pb_busnr,
2481 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2482 port, value);
2483 #if USER_SPACE
2484 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2485 printf("PCI: warning, sys_outl failed: %d\n", s);
2486 #else
2487 outl(PCII_CONFADD, PCII_UNSEL);
2488 #endif
2491 /*===========================================================================*
2492 * pcii_wreg32 *
2493 *===========================================================================*/
2494 PRIVATE void pcii_wreg32(busind, devind, port, value)
2495 int busind;
2496 int devind;
2497 int port;
2498 u32_t value;
2500 int s;
2501 #if 0
2502 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2503 busind, devind, port, value,
2504 pcibus[busind].pb_busnr, pcidev[devind].pd_dev,
2505 pcidev[devind].pd_func);
2506 #endif
2507 PCII_WREG32_(pcibus[busind].pb_busnr,
2508 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2509 port, value);
2510 #if USER_SPACE
2511 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2512 printf("PCI: warning, sys_outl failed: %d\n");
2513 #else
2514 outl(PCII_CONFADD, PCII_UNSEL);
2515 #endif
2518 /*===========================================================================*
2519 * pcii_rsts *
2520 *===========================================================================*/
2521 PRIVATE u16_t pcii_rsts(busind)
2522 int busind;
2524 u16_t v;
2525 int s;
2527 v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
2528 #if USER_SPACE
2529 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2530 printf("PCI: warning, sys_outl failed: %d\n", s);
2531 #else
2532 outl(PCII_CONFADD, PCII_UNSEL);
2533 #endif
2534 return v;
2537 /*===========================================================================*
2538 * pcii_wsts *
2539 *===========================================================================*/
2540 PRIVATE void pcii_wsts(busind, value)
2541 int busind;
2542 u16_t value;
2544 int s;
2545 PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
2546 #if USER_SPACE
2547 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2548 printf("PCI: warning, sys_outl failed: %d\n", s);
2549 #else
2550 outl(PCII_CONFADD, PCII_UNSEL);
2551 #endif
2555 /*===========================================================================*
2556 * print_capabilities *
2557 *===========================================================================*/
2558 PRIVATE void print_capabilities(devind)
2559 int devind;
2561 u8_t status, capptr, type, next, subtype;
2562 char *str;
2564 /* Check capabilities bit in the device status register */
2565 status= pci_attr_r16(devind, PCI_SR);
2566 if (!(status & PSR_CAPPTR))
2567 return;
2569 capptr= (pci_attr_r8_u(devind, PCI_CAPPTR) & PCI_CP_MASK);
2570 while (capptr != 0)
2572 type = pci_attr_r8_u(devind, capptr+CAP_TYPE);
2573 next= (pci_attr_r8_u(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
2574 switch(type)
2576 case 1: str= "PCI Power Management"; break;
2577 case 2: str= "AGP"; break;
2578 case 3: str= "Vital Product Data"; break;
2579 case 4: str= "Slot Identification"; break;
2580 case 5: str= "Message Signaled Interrupts"; break;
2581 case 6: str= "CompactPCI Hot Swap"; break;
2582 case 8: str= "AMD HyperTransport"; break;
2583 case 0xf: str= "Secure Device"; break;
2584 default: str= "(unknown type)"; break;
2587 printf(" @0x%x (0x%08x): capability type 0x%x: %s",
2588 capptr, pci_attr_r32_u(devind, capptr), type, str);
2589 if (type == 0x08)
2590 print_hyper_cap(devind, capptr);
2591 else if (type == 0x0f)
2593 subtype= (pci_attr_r8_u(devind, capptr+2) & 0x07);
2594 switch(subtype)
2596 case 0: str= "Device Exclusion Vector"; break;
2597 case 3: str= "IOMMU"; break;
2598 default: str= "(unknown type)"; break;
2600 printf(", sub type 0%o: %s", subtype, str);
2602 printf("\n");
2603 capptr= next;
2608 /*===========================================================================*
2609 * visible *
2610 *===========================================================================*/
2611 PRIVATE int visible(aclp, devind)
2612 struct rs_pci *aclp;
2613 int devind;
2615 int i;
2616 u32_t class_id;
2618 if (!aclp)
2619 return TRUE; /* Should be changed when ACLs become
2620 * mandatory.
2622 /* Check whether the caller is allowed to get this device. */
2623 for (i= 0; i<aclp->rsp_nr_device; i++)
2625 if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
2626 aclp->rsp_device[i].did == pcidev[devind].pd_did)
2628 return TRUE;
2631 if (!aclp->rsp_nr_class)
2632 return FALSE;
2634 class_id= (pcidev[devind].pd_baseclass << 16) |
2635 (pcidev[devind].pd_subclass << 8) |
2636 pcidev[devind].pd_infclass;
2637 for (i= 0; i<aclp->rsp_nr_class; i++)
2639 if (aclp->rsp_class[i].class ==
2640 (class_id & aclp->rsp_class[i].mask))
2642 return TRUE;
2646 return FALSE;
2649 /*===========================================================================*
2650 * print_hyper_cap *
2651 *===========================================================================*/
2652 PRIVATE void print_hyper_cap(devind, capptr)
2653 int devind;
2654 u8_t capptr;
2656 u32_t v;
2657 u16_t cmd;
2658 int type0, type1;
2660 printf("\n");
2661 v= pci_attr_r32_u(devind, capptr);
2662 printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr);
2663 cmd= (v >> 16) & 0xffff;
2664 #if 0
2665 if (v & 0x10000)
2667 printf(" WarmReset");
2668 v &= ~0x10000;
2670 if (v & 0x20000)
2672 printf(" DblEnded");
2673 v &= ~0x20000;
2675 printf(" DevNum %d", (v & 0x7C0000) >> 18);
2676 v &= ~0x7C0000;
2677 #endif
2678 type0= (cmd & 0xE000) >> 13;
2679 type1= (cmd & 0xF800) >> 11;
2680 if (type0 == 0 || type0 == 1)
2682 printf("Capability Type: %s\n",
2683 type0 == 0 ? "Slave or Primary Interface" :
2684 "Host or Secondary Interface");
2685 cmd &= ~0xE000;
2687 else
2689 printf(" Capability Type 0x%x", type1);
2690 cmd &= ~0xF800;
2692 if (cmd)
2693 printf(" undecoded 0x%x\n", cmd);
2695 #if 0
2696 printf("print_hyper_cap: off 4 (ctl): 0x%x\n",
2697 pci_attr_r32_u(devind, capptr+4));
2698 printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n",
2699 pci_attr_r32_u(devind, capptr+8));
2700 printf("print_hyper_cap: off 12 (cap): 0x%x\n",
2701 pci_attr_r32_u(devind, capptr+12));
2702 printf("print_hyper_cap: off 16 (buf count): 0x%x\n",
2703 pci_attr_r32_u(devind, capptr+16));
2704 v= pci_attr_r32_u(devind, capptr+20);
2705 printf("print_hyper_cap: @0x%x, off 20 (bus nr): ",
2706 capptr+20);
2707 printf("prim %d", v & 0xff);
2708 printf(", sec %d", (v >> 8) & 0xff);
2709 printf(", sub %d", (v >> 16) & 0xff);
2710 if (v >> 24)
2711 printf(", reserved %d", (v >> 24) & 0xff);
2712 printf("\n");
2713 printf("print_hyper_cap: off 24 (type): 0x%x\n",
2714 pci_attr_r32_u(devind, capptr+24));
2715 #endif
2719 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $