mkfs, mkproto: minor improvements
[minix.git] / drivers / pci / pci.c
blob41699318833957c8de5fe65c81288d15a8afe561
1 /*
2 pci.c
4 Configure devices on the PCI bus
6 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
7 */
9 #include <assert.h>
10 #include <machine/pci.h>
11 #include <machine/vm.h>
12 #include <minix/com.h>
13 #include <minix/ds.h>
14 #include <minix/syslib.h>
15 #include <minix/param.h>
17 #include "pci.h"
18 #include <machine/pci_amd.h>
19 #include <machine/pci_intel.h>
20 #include <machine/pci_sis.h>
21 #include <machine/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 <minix/sysutil.h>
33 #include <minix/acpi.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 static 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 static int nr_pcibus= 0;
63 static 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 static int nr_pcidev= 0;
96 static void pci_intel_init(void);
97 static void probe_bus(int busind);
98 static int is_duplicate(u8_t busnr, u8_t dev, u8_t func);
99 static void record_irq(int devind);
100 static void record_bars_normal(int devind);
101 static void record_bars_bridge(int devind);
102 static void record_bars_cardbus(int devind);
103 static void record_bars(int devind, int last_reg);
104 static int record_bar(int devind, int bar_nr, int last);
105 static void complete_bridges(void);
106 static void complete_bars(void);
107 static void update_bridge4dev_io(int devind, u32_t io_base, u32_t
108 io_size);
109 static int get_freebus(void);
110 static int do_isabridge(int busind);
111 static void do_pcibridge(int busind);
112 static int get_busind(int busnr);
113 static int do_piix(int devind);
114 static int do_amd_isabr(int devind);
115 static int do_sis_isabr(int devind);
116 static int do_via_isabr(int devind);
117 #if 0
118 static void report_vga(int devind);
119 #endif
120 static char *pci_vid_name(u16_t vid);
121 static char *pci_baseclass_name(u8_t baseclass);
122 static char *pci_subclass_name(u8_t baseclass, u8_t subclass, u8_t
123 infclass);
124 static void ntostr(unsigned n, char **str, const char *end);
126 static u8_t pci_attr_r8_u(int devind, int port);
127 static u32_t pci_attr_r32_u(int devind, int port);
129 static u16_t pci_attr_rsts(int devind);
130 static void pci_attr_wsts(int devind, u16_t value);
131 static u16_t pcibr_std_rsts(int busind);
132 static void pcibr_std_wsts(int busind, u16_t value);
133 static u16_t pcibr_cb_rsts(int busind);
134 static void pcibr_cb_wsts(int busind, u16_t value);
135 static u16_t pcibr_via_rsts(int busind);
136 static void pcibr_via_wsts(int busind, u16_t value);
137 static u8_t pcii_rreg8(int busind, int devind, int port);
138 static u16_t pcii_rreg16(int busind, int devind, int port);
139 static u32_t pcii_rreg32(int busind, int devind, int port);
140 static void pcii_wreg8(int busind, int devind, int port, u8_t value);
141 static void pcii_wreg16(int busind, int devind, int port, u16_t value);
142 static void pcii_wreg32(int busind, int devind, int port, u32_t value);
143 static u16_t pcii_rsts(int busind);
144 static void pcii_wsts(int busind, u16_t value);
145 static void print_capabilities(int devind);
146 static int visible(struct rs_pci *aclp, int devind);
147 static void print_hyper_cap(int devind, u8_t capptr);
149 static struct machine machine;
150 static endpoint_t acpi_ep;
152 /*===========================================================================*
153 * sef_cb_init_fresh *
154 *===========================================================================*/
155 int sef_cb_init_fresh(int type, sef_init_info_t *info)
157 /* Initialize the pci driver. */
158 long v;
159 int i, r;
160 struct rprocpub rprocpub[NR_BOOT_PROCS];
162 v= 0;
163 env_parse("pci_debug", "d", 0, &v, 0, 1);
164 debug= v;
166 if (sys_getmachine(&machine)) {
167 printf("PCI: no machine\n");
168 return ENODEV;
170 if (machine.apic_enabled &&
171 ds_retrieve_label_endpt("acpi", &acpi_ep) != OK) {
172 panic("PCI: Cannot use APIC mode without ACPI!\n");
175 /* Only Intel (compatible) PCI controllers are supported at the
176 * moment.
178 pci_intel_init();
180 /* Map all the services in the boot image. */
181 if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
182 (vir_bytes) rprocpub, sizeof(rprocpub))) != OK) {
183 panic("sys_safecopyfrom failed: %d", r);
185 for(i=0;i < NR_BOOT_PROCS;i++) {
186 if(rprocpub[i].in_use) {
187 if((r = map_service(&rprocpub[i])) != OK) {
188 panic("unable to map service: %d", r);
193 return(OK);
196 /*===========================================================================*
197 * map_service *
198 *===========================================================================*/
199 int map_service(rpub)
200 struct rprocpub *rpub;
202 /* Map a new service by registering a new acl entry if required. */
203 int i;
205 /* Stop right now if no pci device or class is found. */
206 if(rpub->pci_acl.rsp_nr_device == 0
207 && rpub->pci_acl.rsp_nr_class == 0) {
208 return(OK);
211 /* Find a free acl slot. */
212 for (i= 0; i<NR_DRIVERS; i++)
214 if (!pci_acl[i].inuse)
215 break;
217 if (i >= NR_DRIVERS)
219 printf("PCI: map_service: table is full\n");
220 return ENOMEM;
223 /* Initialize acl slot. */
224 pci_acl[i].inuse = 1;
225 pci_acl[i].acl = rpub->pci_acl;
227 return(OK);
230 /*===========================================================================*
231 * helper functions for I/O *
232 *===========================================================================*/
233 unsigned pci_inb(u16_t port) {
234 u32_t value;
235 int s;
236 if ((s=sys_inb(port, &value)) !=OK)
237 printf("PCI: warning, sys_inb failed: %d\n", s);
238 return value;
240 unsigned pci_inw(u16_t port) {
241 u32_t value;
242 int s;
243 if ((s=sys_inw(port, &value)) !=OK)
244 printf("PCI: warning, sys_inw failed: %d\n", s);
245 return value;
247 unsigned pci_inl(u16_t port) {
248 u32_t value;
249 int s;
250 if ((s=sys_inl(port, &value)) !=OK)
251 printf("PCI: warning, sys_inl failed: %d\n", s);
252 return value;
254 void pci_outb(u16_t port, u8_t value) {
255 int s;
256 if ((s=sys_outb(port, value)) !=OK)
257 printf("PCI: warning, sys_outb failed: %d\n", s);
259 void pci_outw(u16_t port, u16_t value) {
260 int s;
261 if ((s=sys_outw(port, value)) !=OK)
262 printf("PCI: warning, sys_outw failed: %d\n", s);
264 void pci_outl(u16_t port, u32_t value) {
265 int s;
266 if ((s=sys_outl(port, value)) !=OK)
267 printf("PCI: warning, sys_outl failed: %d\n", s);
270 /*===========================================================================*
271 * pci_find_dev *
272 *===========================================================================*/
273 int pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp)
275 int devind;
277 for (devind= 0; devind < nr_pcidev; devind++)
279 if (pcidev[devind].pd_busnr == bus &&
280 pcidev[devind].pd_dev == dev &&
281 pcidev[devind].pd_func == func)
283 break;
286 if (devind >= nr_pcidev)
287 return 0;
288 #if 0
289 if (pcidev[devind].pd_inuse)
290 return 0;
291 #endif
292 *devindp= devind;
293 return 1;
296 /*===========================================================================*
297 * pci_first_dev_a *
298 *===========================================================================*/
299 int pci_first_dev_a(
300 struct rs_pci *aclp,
301 int *devindp,
302 u16_t *vidp,
303 u16_t *didp
306 int devind;
308 for (devind= 0; devind < nr_pcidev; devind++)
310 #if 0
311 if (pcidev[devind].pd_inuse)
312 continue;
313 #endif
314 if (!visible(aclp, devind))
315 continue;
316 break;
318 if (devind >= nr_pcidev)
319 return 0;
320 *devindp= devind;
321 *vidp= pcidev[devind].pd_vid;
322 *didp= pcidev[devind].pd_did;
323 return 1;
326 /*===========================================================================*
327 * pci_next_dev *
328 *===========================================================================*/
329 int pci_next_dev_a(
330 struct rs_pci *aclp,
331 int *devindp,
332 u16_t *vidp,
333 u16_t *didp
336 int devind;
338 for (devind= *devindp+1; devind < nr_pcidev; devind++)
340 #if 0
341 if (pcidev[devind].pd_inuse)
342 continue;
343 #endif
344 if (!visible(aclp, devind))
345 continue;
346 break;
348 if (devind >= nr_pcidev)
349 return 0;
350 *devindp= devind;
351 *vidp= pcidev[devind].pd_vid;
352 *didp= pcidev[devind].pd_did;
353 return 1;
356 /*===========================================================================*
357 * pci_reserve_a *
358 *===========================================================================*/
359 int pci_reserve_a(devind, proc, aclp)
360 int devind;
361 endpoint_t proc;
362 struct rs_pci *aclp;
364 int i, r;
365 int ilr;
366 struct io_range ior;
367 struct minix_mem_range mr;
369 if (devind < 0 || devind >= nr_pcidev)
371 printf("pci_reserve_a: bad devind: %d\n", devind);
372 return EINVAL;
374 if (!visible(aclp, devind))
376 printf("pci_reserve_a: %u is not allowed to reserve %d\n",
377 proc, devind);
378 return EPERM;
381 if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
382 return EBUSY;
383 pcidev[devind].pd_inuse= 1;
384 pcidev[devind].pd_proc= proc;
386 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
388 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
390 printf("pci_reserve_a: BAR %d is incomplete\n", i);
391 continue;
393 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
395 ior.ior_base= pcidev[devind].pd_bar[i].pb_base;
396 ior.ior_limit= ior.ior_base +
397 pcidev[devind].pd_bar[i].pb_size-1;
399 if(debug) {
400 printf(
401 "pci_reserve_a: for proc %d, adding I/O range [0x%x..0x%x]\n",
402 proc, ior.ior_base, ior.ior_limit);
404 r= sys_privctl(proc, SYS_PRIV_ADD_IO, &ior);
405 if (r != OK)
407 printf("sys_privctl failed for proc %d: %d\n",
408 proc, r);
411 else
413 mr.mr_base= pcidev[devind].pd_bar[i].pb_base;
414 mr.mr_limit= mr.mr_base +
415 pcidev[devind].pd_bar[i].pb_size-1;
417 r= sys_privctl(proc, SYS_PRIV_ADD_MEM, &mr);
418 if (r != OK)
420 printf("sys_privctl failed for proc %d: %d\n",
421 proc, r);
425 ilr= pcidev[devind].pd_ilr;
426 if (ilr != PCI_ILR_UNKNOWN)
428 if(debug) printf("pci_reserve_a: adding IRQ %d\n", ilr);
429 r= sys_privctl(proc, SYS_PRIV_ADD_IRQ, &ilr);
430 if (r != OK)
432 printf("sys_privctl failed for proc %d: %d\n",
433 proc, r);
437 return OK;
440 /*===========================================================================*
441 * pci_release *
442 *===========================================================================*/
443 void pci_release(proc)
444 endpoint_t proc;
446 int i;
448 for (i= 0; i<nr_pcidev; i++)
450 if (!pcidev[i].pd_inuse)
451 continue;
452 if (pcidev[i].pd_proc != proc)
453 continue;
454 pcidev[i].pd_inuse= 0;
458 /*===========================================================================*
459 * pci_ids_s *
460 *===========================================================================*/
461 int pci_ids_s(int devind, u16_t *vidp, u16_t *didp)
463 if (devind < 0 || devind >= nr_pcidev)
464 return EINVAL;
466 *vidp= pcidev[devind].pd_vid;
467 *didp= pcidev[devind].pd_did;
468 return OK;
471 /*===========================================================================*
472 * pci_rescan_bus *
473 *===========================================================================*/
474 void pci_rescan_bus(u8_t busnr)
476 int busind;
478 busind= get_busind(busnr);
479 probe_bus(busind);
481 /* Allocate bus numbers for uninitialized bridges */
482 complete_bridges();
484 /* Allocate I/O and memory resources for uninitialized devices */
485 complete_bars();
488 /*===========================================================================*
489 * pci_slot_name_s *
490 *===========================================================================*/
491 int pci_slot_name_s(devind, cpp)
492 int devind;
493 char **cpp;
495 static char label[]= "ddd.ddd.ddd";
496 char *end;
497 char *p;
499 if (devind < 0 || devind >= nr_pcidev)
500 return EINVAL;
502 p= label;
503 end= label+sizeof(label);
505 ntostr(pcidev[devind].pd_busnr, &p, end);
506 *p++= '.';
508 ntostr(pcidev[devind].pd_dev, &p, end);
509 *p++= '.';
511 ntostr(pcidev[devind].pd_func, &p, end);
513 *cpp= label;
514 return OK;
517 /*===========================================================================*
518 * pci_dev_name *
519 *===========================================================================*/
520 char *pci_dev_name(u16_t vid, u16_t did)
522 int i;
524 for (i= 0; pci_device_table[i].name; i++)
526 if (pci_device_table[i].vid == vid &&
527 pci_device_table[i].did == did)
529 return pci_device_table[i].name;
532 return NULL;
535 /*===========================================================================*
536 * pci_get_bar_s *
537 *===========================================================================*/
538 int pci_get_bar_s(int devind, int port, u32_t *base, u32_t *size,
539 int *ioflag)
541 int i, reg;
543 if (devind < 0 || devind >= nr_pcidev)
544 return EINVAL;
546 for (i= 0; i < pcidev[devind].pd_bar_nr; i++)
548 reg= PCI_BAR+4*pcidev[devind].pd_bar[i].pb_nr;
550 if (reg == port)
552 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
553 return EINVAL;
555 *base= pcidev[devind].pd_bar[i].pb_base;
556 *size= pcidev[devind].pd_bar[i].pb_size;
557 *ioflag=
558 !!(pcidev[devind].pd_bar[i].pb_flags & PBF_IO);
559 return OK;
562 return EINVAL;
565 /*===========================================================================*
566 * pci_attr_r8_s *
567 *===========================================================================*/
568 int pci_attr_r8_s(int devind, int port, u8_t *vp)
570 if (devind < 0 || devind >= nr_pcidev)
571 return EINVAL;
572 if (port < 0 || port > 255)
573 return EINVAL;
575 *vp= pci_attr_r8_u(devind, port);
576 return OK;
579 /*===========================================================================*
580 * pci_attr_r8_u *
581 *===========================================================================*/
582 static u8_t pci_attr_r8_u(devind, port)
583 int devind;
584 int port;
586 int busnr, busind;
588 busnr= pcidev[devind].pd_busnr;
589 busind= get_busind(busnr);
590 return pcibus[busind].pb_rreg8(busind, devind, port);
593 /*===========================================================================*
594 * pci_attr_r16 *
595 *===========================================================================*/
596 u16_t pci_attr_r16(devind, port)
597 int devind;
598 int port;
600 int busnr, busind;
602 busnr= pcidev[devind].pd_busnr;
603 busind= get_busind(busnr);
604 return pcibus[busind].pb_rreg16(busind, devind, port);
607 /*===========================================================================*
608 * pci_attr_r32_s *
609 *===========================================================================*/
610 int pci_attr_r32_s(int devind, int port, u32_t *vp)
612 if (devind < 0 || devind >= nr_pcidev)
613 return EINVAL;
614 if (port < 0 || port > 256-4)
615 return EINVAL;
617 *vp= pci_attr_r32_u(devind, port);
618 return OK;
621 /*===========================================================================*
622 * pci_attr_r32_u *
623 *===========================================================================*/
624 static u32_t pci_attr_r32_u(devind, port)
625 int devind;
626 int port;
628 int busnr, busind;
630 busnr= pcidev[devind].pd_busnr;
631 busind= get_busind(busnr);
632 return pcibus[busind].pb_rreg32(busind, devind, port);
635 /*===========================================================================*
636 * pci_attr_w8 *
637 *===========================================================================*/
638 void pci_attr_w8(int devind, int port, u8_t value)
640 int busnr, busind;
642 busnr= pcidev[devind].pd_busnr;
643 busind= get_busind(busnr);
644 pcibus[busind].pb_wreg8(busind, devind, port, value);
647 /*===========================================================================*
648 * pci_attr_w16 *
649 *===========================================================================*/
650 void pci_attr_w16(int devind, int port, u16_t value)
652 int busnr, busind;
654 busnr= pcidev[devind].pd_busnr;
655 busind= get_busind(busnr);
656 pcibus[busind].pb_wreg16(busind, devind, port, value);
659 /*===========================================================================*
660 * pci_attr_w32 *
661 *===========================================================================*/
662 void pci_attr_w32(int devind, int port, u32_t value)
664 int busnr, busind;
666 busnr= pcidev[devind].pd_busnr;
667 busind= get_busind(busnr);
668 pcibus[busind].pb_wreg32(busind, devind, port, value);
671 /*===========================================================================*
672 * pci_intel_init *
673 *===========================================================================*/
674 static void pci_intel_init()
676 /* Try to detect a know PCI controller. Read the Vendor ID and
677 * the Device ID for function 0 of device 0.
678 * Two times the value 0xffff suggests a system without a (compatible)
679 * PCI controller.
681 u32_t bus, dev, func;
682 u16_t vid, did;
683 int s, i, r, busind, busnr;
684 char *dstr;
686 bus= 0;
687 dev= 0;
688 func= 0;
690 vid= PCII_RREG16_(bus, dev, func, PCI_VID);
691 did= PCII_RREG16_(bus, dev, func, PCI_DID);
692 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
693 printf("PCI: warning, sys_outl failed: %d\n", s);
695 #if 0
696 if (vid == 0xffff && did == 0xffff)
697 return; /* Nothing here */
699 for (i= 0; pci_intel_ctrl[i].vid; i++)
701 if (pci_intel_ctrl[i].vid == vid &&
702 pci_intel_ctrl[i].did == did)
704 break;
708 if (!pci_intel_ctrl[i].vid)
710 printf("pci_intel_init (warning): unknown PCI-controller:\n"
711 "\tvendor %04X (%s), device %04X\n",
712 vid, pci_vid_name(vid), did);
714 #endif
716 if (nr_pcibus >= NR_PCIBUS)
717 panic("too many PCI busses: %d", nr_pcibus);
718 busind= nr_pcibus;
719 nr_pcibus++;
720 pcibus[busind].pb_type= PBT_INTEL_HOST;
721 pcibus[busind].pb_needinit= 0;
722 pcibus[busind].pb_isabridge_dev= -1;
723 pcibus[busind].pb_isabridge_type= 0;
724 pcibus[busind].pb_devind= -1;
725 pcibus[busind].pb_busnr= 0;
726 pcibus[busind].pb_rreg8= pcii_rreg8;
727 pcibus[busind].pb_rreg16= pcii_rreg16;
728 pcibus[busind].pb_rreg32= pcii_rreg32;
729 pcibus[busind].pb_wreg8= pcii_wreg8;
730 pcibus[busind].pb_wreg16= pcii_wreg16;
731 pcibus[busind].pb_wreg32= pcii_wreg32;
732 pcibus[busind].pb_rsts= pcii_rsts;
733 pcibus[busind].pb_wsts= pcii_wsts;
735 dstr= pci_dev_name(vid, did);
736 if (!dstr)
737 dstr= "unknown device";
738 if (debug)
740 printf("pci_intel_init: %s (%04X/%04X)\n",
741 dstr, vid, did);
744 probe_bus(busind);
746 r= do_isabridge(busind);
747 if (r != OK)
749 busnr= pcibus[busind].pb_busnr;
751 /* Disable all devices for this bus */
752 for (i= 0; i<nr_pcidev; i++)
754 if (pcidev[i].pd_busnr != busnr)
755 continue;
756 pcidev[i].pd_inuse= 1;
758 return;
761 /* Look for PCI bridges */
762 do_pcibridge(busind);
764 /* Allocate bus numbers for uninitialized bridges */
765 complete_bridges();
767 /* Allocate I/O and memory resources for uninitialized devices */
768 complete_bars();
771 /*===========================================================================*
772 * probe_bus *
773 *===========================================================================*/
774 static void probe_bus(int busind)
776 u32_t dev, func, t3;
777 u16_t vid, did, sts;
778 u8_t headt;
779 u8_t baseclass, subclass, infclass;
780 int devind, busnr;
781 char *s, *dstr;
783 if (debug)
784 printf("probe_bus(%d)\n", busind);
785 if (nr_pcidev >= NR_PCIDEV)
786 panic("too many PCI devices: %d", nr_pcidev);
787 devind= nr_pcidev;
789 busnr= pcibus[busind].pb_busnr;
790 for (dev= 0; dev<32; dev++)
793 for (func= 0; func < 8; func++)
795 pcidev[devind].pd_busnr= busnr;
796 pcidev[devind].pd_dev= dev;
797 pcidev[devind].pd_func= func;
799 pci_attr_wsts(devind,
800 PSR_SSE|PSR_RMAS|PSR_RTAS);
801 vid= pci_attr_r16(devind, PCI_VID);
802 did= pci_attr_r16(devind, PCI_DID);
803 headt= pci_attr_r8_u(devind, PCI_HEADT);
804 sts= pci_attr_rsts(devind);
806 #if 0
807 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
808 vid, did, headt, sts);
809 #endif
811 if (vid == NO_VID && did == NO_VID)
813 if (func == 0)
814 break; /* Nothing here */
816 /* Scan all functions of a multifunction
817 * device.
819 continue;
822 if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
824 static int warned = 0;
826 if(!warned) {
827 printf(
828 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
829 sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
830 warned = 1;
834 dstr= pci_dev_name(vid, did);
835 if (debug)
837 if (dstr)
839 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
840 busnr, (unsigned long)dev,
841 (unsigned long)func, dstr,
842 vid, did);
844 else
846 printf(
847 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
848 busnr, (unsigned long)dev,
849 (unsigned long)func, vid,
850 pci_vid_name(vid), did);
852 printf("Device index: %d\n", devind);
853 printf("Subsystem: Vid 0x%x, did 0x%x\n",
854 pci_attr_r16(devind, PCI_SUBVID),
855 pci_attr_r16(devind, PCI_SUBDID));
858 baseclass= pci_attr_r8_u(devind, PCI_BCR);
859 subclass= pci_attr_r8_u(devind, PCI_SCR);
860 infclass= pci_attr_r8_u(devind, PCI_PIFR);
861 s= pci_subclass_name(baseclass, subclass, infclass);
862 if (!s)
863 s= pci_baseclass_name(baseclass);
865 if (!s)
866 s= "(unknown class)";
868 if (debug)
870 printf("\tclass %s (%X/%X/%X)\n", s,
871 baseclass, subclass, infclass);
874 if (is_duplicate(busnr, dev, func))
876 printf("\tduplicate!\n");
877 if (func == 0 && !(headt & PHT_MULTIFUNC))
878 break;
879 continue;
882 devind= nr_pcidev;
883 nr_pcidev++;
884 pcidev[devind].pd_baseclass= baseclass;
885 pcidev[devind].pd_subclass= subclass;
886 pcidev[devind].pd_infclass= infclass;
887 pcidev[devind].pd_vid= vid;
888 pcidev[devind].pd_did= did;
889 pcidev[devind].pd_inuse= 0;
890 pcidev[devind].pd_bar_nr= 0;
891 record_irq(devind);
892 switch(headt & PHT_MASK)
894 case PHT_NORMAL:
895 record_bars_normal(devind);
896 break;
897 case PHT_BRIDGE:
898 record_bars_bridge(devind);
899 break;
900 case PHT_CARDBUS:
901 record_bars_cardbus(devind);
902 break;
903 default:
904 printf("\t%d.%d.%d: unknown header type %d\n",
905 busind, dev, func,
906 headt & PHT_MASK);
907 break;
909 if (debug)
910 print_capabilities(devind);
912 t3= ((baseclass << 16) | (subclass << 8) | infclass);
913 #if 0
914 if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
915 report_vga(devind);
916 #endif
918 if (nr_pcidev >= NR_PCIDEV)
919 panic("too many PCI devices: %d", nr_pcidev);
920 devind= nr_pcidev;
922 if (func == 0 && !(headt & PHT_MULTIFUNC))
923 break;
928 /*===========================================================================*
929 * is_duplicate *
930 *===========================================================================*/
931 static int is_duplicate(u8_t busnr, u8_t dev, u8_t func)
933 int i;
935 for (i= 0; i<nr_pcidev; i++)
937 if (pcidev[i].pd_busnr == busnr &&
938 pcidev[i].pd_dev == dev &&
939 pcidev[i].pd_func == func)
941 return 1;
944 return 0;
947 static int acpi_get_irq(unsigned bus, unsigned dev, unsigned pin)
949 int err;
950 message m;
952 ((struct acpi_get_irq_req *)&m)->hdr.request = ACPI_REQ_GET_IRQ;
953 ((struct acpi_get_irq_req *)&m)->bus = bus;
954 ((struct acpi_get_irq_req *)&m)->dev = dev;
955 ((struct acpi_get_irq_req *)&m)->pin = pin;
957 if ((err = sendrec(acpi_ep, &m)) != OK)
958 panic("PCI: error %d while receiveing from ACPI\n", err);
960 return ((struct acpi_get_irq_resp *)&m)->irq;
963 static int derive_irq(struct pcidev * dev, int pin)
965 struct pcidev * parent_bridge;
966 int slot;
968 parent_bridge = &pcidev[pcibus[get_busind(dev->pd_busnr)].pb_devind];
971 * We don't support PCI-Express, no ARI, decode the slot of the device
972 * and mangle the pin as the device is behind a bridge
974 slot = ((dev->pd_func) >> 3) & 0x1f;
976 return acpi_get_irq(parent_bridge->pd_busnr,
977 parent_bridge->pd_dev, (pin + slot) % 4);
980 /*===========================================================================*
981 * record_irq *
982 *===========================================================================*/
983 static void record_irq(devind)
984 int devind;
986 int ilr, ipr, busnr, busind, cb_devind;
988 ilr= pci_attr_r8_u(devind, PCI_ILR);
989 ipr= pci_attr_r8_u(devind, PCI_IPR);
991 if (ipr && machine.apic_enabled) {
992 int irq;
994 irq = acpi_get_irq(pcidev[devind].pd_busnr,
995 pcidev[devind].pd_dev, ipr - 1);
997 if (irq < 0)
998 irq = derive_irq(&pcidev[devind], ipr - 1);
1000 if (irq >= 0) {
1001 ilr = irq;
1002 pci_attr_w8(devind, PCI_ILR, ilr);
1003 if (debug)
1004 printf("PCI: ACPI IRQ %d for "
1005 "device %d.%d.%d INT%c\n",
1006 irq,
1007 pcidev[devind].pd_busnr,
1008 pcidev[devind].pd_dev,
1009 pcidev[devind].pd_func,
1010 'A' + ipr-1);
1012 else if (debug) {
1013 printf("PCI: no ACPI IRQ routing for "
1014 "device %d.%d.%d INT%c\n",
1015 pcidev[devind].pd_busnr,
1016 pcidev[devind].pd_dev,
1017 pcidev[devind].pd_func,
1018 'A' + ipr-1);
1022 if (ilr == 0)
1024 static int first= 1;
1025 if (ipr && first && debug)
1027 first= 0;
1028 printf("PCI: strange, BIOS assigned IRQ0\n");
1030 ilr= PCI_ILR_UNKNOWN;
1032 pcidev[devind].pd_ilr= ilr;
1033 if (ilr == PCI_ILR_UNKNOWN && !ipr)
1036 else if (ilr != PCI_ILR_UNKNOWN && ipr)
1038 if (debug)
1039 printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
1041 else if (ilr != PCI_ILR_UNKNOWN)
1043 printf(
1044 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
1045 ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
1046 pcidev[devind].pd_func);
1048 else
1050 /* Check for cardbus devices */
1051 busnr= pcidev[devind].pd_busnr;
1052 busind= get_busind(busnr);
1053 if (pcibus[busind].pb_type == PBT_CARDBUS)
1055 cb_devind= pcibus[busind].pb_devind;
1056 ilr= pcidev[cb_devind].pd_ilr;
1057 if (ilr != PCI_ILR_UNKNOWN)
1059 if (debug)
1061 printf(
1062 "assigning IRQ %d to Cardbus device\n",
1063 ilr);
1065 pci_attr_w8(devind, PCI_ILR, ilr);
1066 pcidev[devind].pd_ilr= ilr;
1067 return;
1070 if(debug) {
1071 printf(
1072 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
1073 pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
1074 pcidev[devind].pd_func, 'A' + ipr-1);
1079 /*===========================================================================*
1080 * record_bars_normal *
1081 *===========================================================================*/
1082 static void record_bars_normal(devind)
1083 int devind;
1085 int i, j, clear_01, clear_23, pb_nr;
1087 /* The BAR area of normal devices is six DWORDs in size. */
1088 record_bars(devind, PCI_BAR_6);
1090 /* Special case code for IDE controllers in compatibility mode */
1091 if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
1092 pcidev[devind].pd_subclass == PCI_MS_IDE)
1094 /* IDE device */
1095 clear_01= 0;
1096 clear_23= 0;
1097 if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
1099 if (debug)
1101 printf(
1102 "primary channel is not in native mode, clearing BARs 0 and 1\n");
1104 clear_01= 1;
1106 if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
1108 if (debug)
1110 printf(
1111 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
1113 clear_23= 1;
1116 j= 0;
1117 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
1119 pb_nr= pcidev[devind].pd_bar[i].pb_nr;
1120 if ((pb_nr == 0 || pb_nr == 1) && clear_01)
1122 if (debug) printf("skipping bar %d\n", pb_nr);
1123 continue; /* Skip */
1125 if ((pb_nr == 2 || pb_nr == 3) && clear_23)
1127 if (debug) printf("skipping bar %d\n", pb_nr);
1128 continue; /* Skip */
1130 if (i == j)
1132 j++;
1133 continue; /* No need to copy */
1135 pcidev[devind].pd_bar[j]=
1136 pcidev[devind].pd_bar[i];
1137 j++;
1139 pcidev[devind].pd_bar_nr= j;
1143 /*===========================================================================*
1144 * record_bars_bridge *
1145 *===========================================================================*/
1146 static void record_bars_bridge(devind)
1147 int devind;
1149 u32_t base, limit, size;
1151 /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
1152 * It may contain up to two 32-bit BARs, or one 64-bit BAR.
1154 record_bars(devind, PCI_BAR_2);
1156 base= ((pci_attr_r8_u(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
1157 (pci_attr_r16(devind, PPB_IOBASEU16) << 16);
1158 limit= 0xff |
1159 ((pci_attr_r8_u(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
1160 ((~PPB_IOL_MASK & 0xff) << 8) |
1161 (pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
1162 size= limit-base + 1;
1163 if (debug)
1165 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1166 base, limit, size);
1169 base= ((pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
1170 limit= 0xffff |
1171 ((pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
1172 ((~PPB_MEML_MASK & 0xffff) << 16);
1173 size= limit-base + 1;
1174 if (debug)
1176 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1177 base, limit, size);
1180 /* Ignore the upper 32 bits */
1181 base= ((pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
1182 limit= 0xffff |
1183 ((pci_attr_r16(devind, PPB_PFMEMLIMIT) &
1184 PPB_PFMEML_MASK) << 16) |
1185 ((~PPB_PFMEML_MASK & 0xffff) << 16);
1186 size= limit-base + 1;
1187 if (debug)
1189 printf(
1190 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1191 base, limit, size);
1195 /*===========================================================================*
1196 * record_bars_cardbus *
1197 *===========================================================================*/
1198 static void record_bars_cardbus(devind)
1199 int devind;
1201 u32_t base, limit, size;
1203 /* The generic BAR area of CardBus devices is one DWORD in size. */
1204 record_bars(devind, PCI_BAR);
1206 base= pci_attr_r32_u(devind, CBB_MEMBASE_0);
1207 limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_0) |
1208 (~CBB_MEML_MASK & 0xffffffff);
1209 size= limit-base + 1;
1210 if (debug)
1212 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1213 base, limit, size);
1216 base= pci_attr_r32_u(devind, CBB_MEMBASE_1);
1217 limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_1) |
1218 (~CBB_MEML_MASK & 0xffffffff);
1219 size= limit-base + 1;
1220 if (debug)
1222 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1223 base, limit, size);
1226 base= pci_attr_r32_u(devind, CBB_IOBASE_0);
1227 limit= pci_attr_r32_u(devind, CBB_IOLIMIT_0) |
1228 (~CBB_IOL_MASK & 0xffffffff);
1229 size= limit-base + 1;
1230 if (debug)
1232 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1233 base, limit, size);
1236 base= pci_attr_r32_u(devind, CBB_IOBASE_1);
1237 limit= pci_attr_r32_u(devind, CBB_IOLIMIT_1) |
1238 (~CBB_IOL_MASK & 0xffffffff);
1239 size= limit-base + 1;
1240 if (debug)
1242 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1243 base, limit, size);
1247 /*===========================================================================*
1248 * record_bars *
1249 *===========================================================================*/
1250 static void record_bars(int devind, int last_reg)
1252 int i, reg, width;
1254 for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width)
1256 width = record_bar(devind, i, reg == last_reg);
1260 /*===========================================================================*
1261 * record_bar *
1262 *===========================================================================*/
1263 static int record_bar(devind, bar_nr, last)
1264 int devind;
1265 int bar_nr;
1266 int last;
1268 int reg, prefetch, type, dev_bar_nr, width;
1269 u32_t bar, bar2;
1270 u16_t cmd;
1272 /* Start by assuming that this is a 32-bit bar, taking up one DWORD. */
1273 width = 1;
1275 reg= PCI_BAR+4*bar_nr;
1277 bar= pci_attr_r32_u(devind, reg);
1278 if (bar & PCI_BAR_IO)
1280 /* Disable I/O 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_IO_EN);
1284 /* Probe BAR's size */
1285 pci_attr_w32(devind, reg, 0xffffffff);
1286 bar2= pci_attr_r32_u(devind, reg);
1288 /* Restore original state */
1289 pci_attr_w32(devind, reg, bar);
1290 pci_attr_w16(devind, PCI_CR, cmd);
1292 bar &= PCI_BAR_IO_MASK; /* Clear non-address bits */
1293 bar2 &= PCI_BAR_IO_MASK;
1294 bar2= (~bar2 & 0xffff)+1;
1295 if (debug)
1297 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1298 bar_nr, bar2, bar);
1301 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1302 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO;
1303 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1304 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1305 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1306 if (bar == 0)
1308 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1309 PBF_INCOMPLETE;
1312 else
1314 type= (bar & PCI_BAR_TYPE);
1316 switch(type) {
1317 case PCI_TYPE_32:
1318 case PCI_TYPE_32_1M:
1319 break;
1321 case PCI_TYPE_64:
1322 /* A 64-bit BAR takes up two consecutive DWORDs. */
1323 if (last)
1325 printf("PCI: device %d.%d.%d BAR %d extends"
1326 " beyond designated area\n",
1327 pcidev[devind].pd_busnr,
1328 pcidev[devind].pd_dev,
1329 pcidev[devind].pd_func, bar_nr);
1331 return width;
1333 width++;
1335 bar2= pci_attr_r32_u(devind, reg+4);
1337 /* If the upper 32 bits of the BAR are not zero, the
1338 * memory is inaccessible to us; ignore the BAR.
1340 if (bar2 != 0)
1342 if (debug)
1344 printf("\tbar_%d: (64-bit BAR with"
1345 " high bits set)\n", bar_nr);
1348 return width;
1351 break;
1353 default:
1354 /* Ignore the BAR. */
1355 if (debug)
1357 printf("\tbar_%d: (unknown type %x)\n",
1358 bar_nr, type);
1361 return width;
1364 /* Disable mem access before probing for BAR's size */
1365 cmd = pci_attr_r16(devind, PCI_CR);
1366 pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_MEM_EN);
1368 /* Probe BAR's size */
1369 pci_attr_w32(devind, reg, 0xffffffff);
1370 bar2= pci_attr_r32_u(devind, reg);
1372 /* Restore original values */
1373 pci_attr_w32(devind, reg, bar);
1374 pci_attr_w16(devind, PCI_CR, cmd);
1376 if (bar2 == 0)
1377 return width; /* Reg. is not implemented */
1379 prefetch= !!(bar & PCI_BAR_PREFETCH);
1380 bar &= PCI_BAR_MEM_MASK; /* Clear non-address bits */
1381 bar2 &= PCI_BAR_MEM_MASK;
1382 bar2= (~bar2)+1;
1383 if (debug)
1385 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory%s\n",
1386 bar_nr, bar2, bar,
1387 prefetch ? " prefetchable" : "",
1388 type == PCI_TYPE_64 ? ", 64-bit" : "");
1391 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1392 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0;
1393 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1394 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1395 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1396 if (bar == 0)
1398 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1399 PBF_INCOMPLETE;
1403 return width;
1406 /*===========================================================================*
1407 * complete_bridges *
1408 *===========================================================================*/
1409 static void complete_bridges()
1411 int i, freebus, devind, prim_busnr;
1413 for (i= 0; i<nr_pcibus; i++)
1415 if (!pcibus[i].pb_needinit)
1416 continue;
1417 printf("should allocate bus number for bus %d\n", i);
1418 freebus= get_freebus();
1419 printf("got bus number %d\n", freebus);
1421 devind= pcibus[i].pb_devind;
1423 prim_busnr= pcidev[devind].pd_busnr;
1424 if (prim_busnr != 0)
1426 printf(
1427 "complete_bridge: updating subordinate bus number not implemented\n");
1430 pcibus[i].pb_needinit= 0;
1431 pcibus[i].pb_busnr= freebus;
1433 printf("devind = %d\n", devind);
1434 printf("prim_busnr= %d\n", prim_busnr);
1436 pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
1437 pci_attr_w8(devind, PPB_SECBN, freebus);
1438 pci_attr_w8(devind, PPB_SUBORDBN, freebus);
1440 printf("CR = 0x%x\n", pci_attr_r16(devind, PCI_CR));
1441 printf("SECBLT = 0x%x\n", pci_attr_r8_u(devind, PPB_SECBLT));
1442 printf("BRIDGECTRL = 0x%x\n",
1443 pci_attr_r16(devind, PPB_BRIDGECTRL));
1447 /*===========================================================================*
1448 * complete_bars *
1449 *===========================================================================*/
1450 static void complete_bars(void)
1452 int i, j, bar_nr, reg;
1453 u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
1454 base, size, v32, diff1, diff2;
1455 kinfo_t kinfo;
1457 if(OK != sys_getkinfo(&kinfo))
1458 panic("can't get kinfo");
1460 /* Set memgap_low to just above physical memory */
1461 memgap_low= kinfo.mem_high_phys;
1462 memgap_high= 0xfe000000; /* Leave space for the CPU (APIC) */
1464 if (debug)
1466 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1467 memgap_low, memgap_high);
1470 /* Find the lowest memory base */
1471 for (i= 0; i<nr_pcidev; i++)
1473 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1475 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1476 continue;
1477 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1478 continue;
1479 base= pcidev[i].pd_bar[j].pb_base;
1480 size= pcidev[i].pd_bar[j].pb_size;
1482 if (base >= memgap_high)
1483 continue; /* Not in the gap */
1484 if (base+size <= memgap_low)
1485 continue; /* Not in the gap */
1487 /* Reduce the gap by the smallest amount */
1488 diff1= base+size-memgap_low;
1489 diff2= memgap_high-base;
1491 if (diff1 < diff2)
1492 memgap_low= base+size;
1493 else
1494 memgap_high= base;
1498 if (debug)
1500 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1501 memgap_low, memgap_high);
1504 /* Should check main memory size */
1505 if (memgap_high < memgap_low)
1507 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1508 memgap_low, memgap_high);
1509 panic(NULL);
1512 iogap_high= 0x10000;
1513 iogap_low= 0x400;
1515 /* Find the free I/O space */
1516 for (i= 0; i<nr_pcidev; i++)
1518 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1520 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1521 continue;
1522 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1523 continue;
1524 base= pcidev[i].pd_bar[j].pb_base;
1525 size= pcidev[i].pd_bar[j].pb_size;
1526 if (base >= iogap_high)
1527 continue;
1528 if (base+size <= iogap_low)
1529 continue;
1530 #if 0
1531 if (debug)
1533 printf(
1534 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
1535 i, pcidev[i].pd_vid, pcidev[i].pd_did,
1536 j, base, size);
1538 #endif
1539 if (base+size-iogap_low < iogap_high-base)
1540 iogap_low= base+size;
1541 else
1542 iogap_high= base;
1546 if (iogap_high < iogap_low)
1548 if (debug)
1550 printf("iogap_high too low, should panic\n");
1552 else
1553 panic("iogap_high too low: %d", iogap_high);
1555 if (debug)
1556 printf("I/O range = [0x%x..0x%x>\n", iogap_low, iogap_high);
1558 for (i= 0; i<nr_pcidev; i++)
1560 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1562 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1563 continue;
1564 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1565 continue;
1566 size= pcidev[i].pd_bar[j].pb_size;
1567 if (size < I386_PAGE_SIZE)
1568 size= I386_PAGE_SIZE;
1569 base= memgap_high-size;
1570 base &= ~(u32_t)(size-1);
1571 if (base < memgap_low)
1572 panic("memory base too low: %d", base);
1573 memgap_high= base;
1574 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1575 reg= PCI_BAR + 4*bar_nr;
1576 v32= pci_attr_r32_u(i, reg);
1577 pci_attr_w32(i, reg, v32 | base);
1578 if (debug)
1580 printf(
1581 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1582 base, size, pcidev[i].pd_busnr,
1583 pcidev[i].pd_dev, pcidev[i].pd_func,
1584 bar_nr);
1586 pcidev[i].pd_bar[j].pb_base= base;
1587 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1590 io_high= iogap_high;
1591 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1593 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1594 continue;
1595 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1596 continue;
1597 size= pcidev[i].pd_bar[j].pb_size;
1598 base= iogap_high-size;
1599 base &= ~(u32_t)(size-1);
1601 /* Assume that ISA compatibility is required. Only
1602 * use the lowest 256 bytes out of every 1024 bytes.
1604 base &= 0xfcff;
1606 if (base < iogap_low)
1607 panic("I/O base too low: %d", base);
1609 iogap_high= base;
1610 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1611 reg= PCI_BAR + 4*bar_nr;
1612 v32= pci_attr_r32_u(i, reg);
1613 pci_attr_w32(i, reg, v32 | base);
1614 if (debug)
1616 printf(
1617 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1618 base, size, pcidev[i].pd_busnr,
1619 pcidev[i].pd_dev, pcidev[i].pd_func,
1620 bar_nr);
1622 pcidev[i].pd_bar[j].pb_base= base;
1623 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1626 if (iogap_high != io_high)
1628 update_bridge4dev_io(i, iogap_high,
1629 io_high-iogap_high);
1633 for (i= 0; i<nr_pcidev; i++)
1635 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1637 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1638 continue;
1639 printf("should allocate resources for device %d\n", i);
1642 return;
1645 /*===========================================================================*
1646 * update_bridge4dev_io *
1647 *===========================================================================*/
1648 static void update_bridge4dev_io(
1649 int devind,
1650 u32_t io_base,
1651 u32_t io_size
1654 int busnr, busind, type, br_devind;
1655 u16_t v16;
1657 busnr= pcidev[devind].pd_busnr;
1658 busind= get_busind(busnr);
1659 type= pcibus[busind].pb_type;
1660 if (type == PBT_INTEL_HOST)
1661 return; /* Nothing to do for host controller */
1662 if (type == PBT_PCIBRIDGE)
1664 printf(
1665 "update_bridge4dev_io: not implemented for PCI bridges\n");
1666 return;
1668 if (type != PBT_CARDBUS)
1669 panic("update_bridge4dev_io: strange bus type: %d", type);
1671 if (debug)
1673 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1674 io_size, io_base);
1676 br_devind= pcibus[busind].pb_devind;
1677 pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
1678 pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
1680 /* Enable I/O access. Enable busmaster access as well. */
1681 v16= pci_attr_r16(devind, PCI_CR);
1682 pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
1685 /*===========================================================================*
1686 * get_freebus *
1687 *===========================================================================*/
1688 static int get_freebus()
1690 int i, freebus;
1692 freebus= 1;
1693 for (i= 0; i<nr_pcibus; i++)
1695 if (pcibus[i].pb_needinit)
1696 continue;
1697 if (pcibus[i].pb_type == PBT_INTEL_HOST)
1698 continue;
1699 if (pcibus[i].pb_busnr <= freebus)
1700 freebus= pcibus[i].pb_busnr+1;
1701 printf("get_freebus: should check suboridinate bus number\n");
1703 return freebus;
1706 /*===========================================================================*
1707 * do_isabridge *
1708 *===========================================================================*/
1709 static int do_isabridge(busind)
1710 int busind;
1712 int i, j, r, type, busnr, unknown_bridge, bridge_dev;
1713 u16_t vid, did;
1714 u32_t t3;
1715 char *dstr;
1717 unknown_bridge= -1;
1718 bridge_dev= -1;
1719 j= 0; /* lint */
1720 vid= did= 0; /* lint */
1721 busnr= pcibus[busind].pb_busnr;
1722 for (i= 0; i< nr_pcidev; i++)
1724 if (pcidev[i].pd_busnr != busnr)
1725 continue;
1726 t3= ((pcidev[i].pd_baseclass << 16) |
1727 (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
1728 if (t3 == PCI_T3_ISA)
1730 /* ISA bridge. Report if no supported bridge is
1731 * found.
1733 unknown_bridge= i;
1736 vid= pcidev[i].pd_vid;
1737 did= pcidev[i].pd_did;
1738 for (j= 0; pci_isabridge[j].vid != 0; j++)
1740 if (pci_isabridge[j].vid != vid)
1741 continue;
1742 if (pci_isabridge[j].did != did)
1743 continue;
1744 if (pci_isabridge[j].checkclass &&
1745 unknown_bridge != i)
1747 /* This part of multifunction device is
1748 * not the bridge.
1750 continue;
1752 break;
1754 if (pci_isabridge[j].vid)
1756 bridge_dev= i;
1757 break;
1761 if (bridge_dev != -1)
1763 dstr= pci_dev_name(vid, did);
1764 if (!dstr)
1765 dstr= "unknown device";
1766 if (debug)
1768 printf("found ISA bridge (%04X/%04X) %s\n",
1769 vid, did, dstr);
1771 pcibus[busind].pb_isabridge_dev= bridge_dev;
1772 type= pci_isabridge[j].type;
1773 pcibus[busind].pb_isabridge_type= type;
1774 switch(type)
1776 case PCI_IB_PIIX:
1777 r= do_piix(bridge_dev);
1778 break;
1779 case PCI_IB_VIA:
1780 r= do_via_isabr(bridge_dev);
1781 break;
1782 case PCI_IB_AMD:
1783 r= do_amd_isabr(bridge_dev);
1784 break;
1785 case PCI_IB_SIS:
1786 r= do_sis_isabr(bridge_dev);
1787 break;
1788 default:
1789 panic("unknown ISA bridge type: %d", type);
1791 return r;
1794 if (unknown_bridge == -1)
1796 if (debug)
1798 printf("(warning) no ISA bridge found on bus %d\n",
1799 busind);
1801 return 0;
1803 if (debug)
1805 printf(
1806 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
1807 pcidev[unknown_bridge].pd_vid,
1808 pcidev[unknown_bridge].pd_did, busind);
1810 return 0;
1814 * tells acpi which two busses are connected by this bridge. The primary bus
1815 * (pbnr) must be already known to acpi and it must map dev as the connection to
1816 * the secondary (sbnr) bus
1818 static void acpi_map_bridge(unsigned pbnr, unsigned dev, unsigned sbnr)
1820 int err;
1821 message m;
1823 ((struct acpi_map_bridge_req *)&m)->hdr.request = ACPI_REQ_MAP_BRIDGE;
1824 ((struct acpi_map_bridge_req *)&m)->primary_bus = pbnr;
1825 ((struct acpi_map_bridge_req *)&m)->secondary_bus = sbnr;
1826 ((struct acpi_map_bridge_req *)&m)->device = dev;
1828 if ((err = sendrec(acpi_ep, &m)) != OK)
1829 panic("PCI: error %d while receiveing from ACPI\n", err);
1831 if (((struct acpi_map_bridge_resp *)&m)->err != OK)
1832 printf("PCI: acpi failed to map pci (%d) to pci (%d) bridge\n",
1833 pbnr, sbnr);
1836 /*===========================================================================*
1837 * do_pcibridge *
1838 *===========================================================================*/
1839 static void do_pcibridge(busind)
1840 int busind;
1842 int i, devind, busnr;
1843 int ind, type;
1844 u16_t vid, did;
1845 u8_t sbusn, baseclass, subclass, infclass, headt;
1846 u32_t t3;
1848 vid= did= 0; /* lint */
1849 busnr= pcibus[busind].pb_busnr;
1850 for (devind= 0; devind< nr_pcidev; devind++)
1852 #if 0
1853 printf("do_pcibridge: trying %u.%u.%u\n",
1854 pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
1855 pcidev[devind].pd_func);
1856 #endif
1858 if (pcidev[devind].pd_busnr != busnr)
1860 #if 0
1861 printf("wrong bus\n");
1862 #endif
1863 continue;
1866 vid= pcidev[devind].pd_vid;
1867 did= pcidev[devind].pd_did;
1868 for (i= 0; pci_pcibridge[i].vid != 0; i++)
1870 if (pci_pcibridge[i].vid != vid)
1871 continue;
1872 if (pci_pcibridge[i].did != did)
1873 continue;
1874 break;
1876 type= pci_pcibridge[i].type;
1877 if (pci_pcibridge[i].vid == 0)
1879 headt= pci_attr_r8_u(devind, PCI_HEADT);
1880 type= 0;
1881 if ((headt & PHT_MASK) == PHT_BRIDGE)
1882 type= PCI_PPB_STD;
1883 else if ((headt & PHT_MASK) == PHT_CARDBUS)
1884 type= PCI_PPB_CB;
1885 else
1887 #if 0
1888 printf("not a bridge\n");
1889 #endif
1890 continue; /* Not a bridge */
1893 baseclass= pci_attr_r8_u(devind, PCI_BCR);
1894 subclass= pci_attr_r8_u(devind, PCI_SCR);
1895 infclass= pci_attr_r8_u(devind, PCI_PIFR);
1896 t3= ((baseclass << 16) | (subclass << 8) | infclass);
1897 if (type == PCI_PPB_STD &&
1898 t3 != PCI_T3_PCI2PCI &&
1899 t3 != PCI_T3_PCI2PCI_SUBTR)
1901 printf(
1902 "Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
1903 baseclass, subclass, infclass,
1904 vid, did);
1905 continue;
1907 if (type == PCI_PPB_CB &&
1908 t3 != PCI_T3_CARDBUS)
1910 printf(
1911 "Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
1912 baseclass, subclass, infclass,
1913 vid, did);
1914 continue;
1918 if (debug)
1920 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
1921 pcidev[devind].pd_busnr,
1922 pcidev[devind].pd_dev,
1923 pcidev[devind].pd_func, vid, did);
1926 /* Assume that the BIOS initialized the secondary bus
1927 * number.
1929 sbusn= pci_attr_r8_u(devind, PPB_SECBN);
1931 if (nr_pcibus >= NR_PCIBUS)
1932 panic("too many PCI busses: %d", nr_pcibus);
1933 ind= nr_pcibus;
1934 nr_pcibus++;
1935 pcibus[ind].pb_type= PBT_PCIBRIDGE;
1936 pcibus[ind].pb_needinit= 1;
1937 pcibus[ind].pb_isabridge_dev= -1;
1938 pcibus[ind].pb_isabridge_type= 0;
1939 pcibus[ind].pb_devind= devind;
1940 pcibus[ind].pb_busnr= sbusn;
1941 pcibus[ind].pb_rreg8= pcibus[busind].pb_rreg8;
1942 pcibus[ind].pb_rreg16= pcibus[busind].pb_rreg16;
1943 pcibus[ind].pb_rreg32= pcibus[busind].pb_rreg32;
1944 pcibus[ind].pb_wreg8= pcibus[busind].pb_wreg8;
1945 pcibus[ind].pb_wreg16= pcibus[busind].pb_wreg16;
1946 pcibus[ind].pb_wreg32= pcibus[busind].pb_wreg32;
1947 switch(type)
1949 case PCI_PPB_STD:
1950 pcibus[ind].pb_rsts= pcibr_std_rsts;
1951 pcibus[ind].pb_wsts= pcibr_std_wsts;
1952 break;
1953 case PCI_PPB_CB:
1954 pcibus[ind].pb_type= PBT_CARDBUS;
1955 pcibus[ind].pb_rsts= pcibr_cb_rsts;
1956 pcibus[ind].pb_wsts= pcibr_cb_wsts;
1957 break;
1958 case PCI_AGPB_VIA:
1959 pcibus[ind].pb_rsts= pcibr_via_rsts;
1960 pcibus[ind].pb_wsts= pcibr_via_wsts;
1961 break;
1962 default:
1963 panic("unknown PCI-PCI bridge type: %d", type);
1966 if (machine.apic_enabled)
1967 acpi_map_bridge(pcidev[devind].pd_busnr,
1968 pcidev[devind].pd_dev, sbusn);
1970 if (debug)
1972 printf(
1973 "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
1974 ind, sbusn, pci_attr_r8_u(devind, PPB_SUBORDBN));
1976 if (sbusn == 0)
1978 printf("Secondary bus number not initialized\n");
1979 continue;
1981 pcibus[ind].pb_needinit= 0;
1983 probe_bus(ind);
1985 /* Look for PCI bridges */
1986 do_pcibridge(ind);
1990 /*===========================================================================*
1991 * get_busind *
1992 *===========================================================================*/
1993 static int get_busind(busnr)
1994 int busnr;
1996 int i;
1998 for (i= 0; i<nr_pcibus; i++)
2000 if (pcibus[i].pb_busnr == busnr)
2001 return i;
2003 panic("get_busind: can't find bus: %d", busnr);
2006 /*===========================================================================*
2007 * do_piix *
2008 *===========================================================================*/
2009 static int do_piix(int devind)
2011 int i, s, irqrc, irq;
2012 u32_t elcr1, elcr2, elcr;
2014 #if DEBUG
2015 printf("in piix\n");
2016 #endif
2017 if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
2018 printf("Warning, sys_inb failed: %d\n", s);
2019 if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
2020 printf("Warning, sys_inb failed: %d\n", s);
2021 elcr= elcr1 | (elcr2 << 8);
2022 for (i= 0; i<4; i++)
2024 irqrc= pci_attr_r8_u(devind, PIIX_PIRQRCA+i);
2025 if (irqrc & PIIX_IRQ_DI)
2027 if (debug)
2028 printf("INT%c: disabled\n", 'A'+i);
2030 else
2032 irq= irqrc & PIIX_IRQ_MASK;
2033 if (debug)
2034 printf("INT%c: %d\n", 'A'+i, irq);
2035 if (!(elcr & (1 << irq)))
2037 if (debug)
2039 printf(
2040 "(warning) IRQ %d is not level triggered\n",
2041 irq);
2044 irq_mode_pci(irq);
2047 return 0;
2050 /*===========================================================================*
2051 * do_amd_isabr *
2052 *===========================================================================*/
2053 static int do_amd_isabr(int devind)
2055 int i, busnr, dev, func, xdevind, irq, edge;
2056 u8_t levmask;
2057 u16_t pciirq;
2059 /* Find required function */
2060 func= AMD_ISABR_FUNC;
2061 busnr= pcidev[devind].pd_busnr;
2062 dev= pcidev[devind].pd_dev;
2064 /* Fake a device with the required function */
2065 if (nr_pcidev >= NR_PCIDEV)
2066 panic("too many PCI devices: %d", nr_pcidev);
2067 xdevind= nr_pcidev;
2068 pcidev[xdevind].pd_busnr= busnr;
2069 pcidev[xdevind].pd_dev= dev;
2070 pcidev[xdevind].pd_func= func;
2071 pcidev[xdevind].pd_inuse= 1;
2072 nr_pcidev++;
2074 levmask= pci_attr_r8_u(xdevind, AMD_ISABR_PCIIRQ_LEV);
2075 pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
2076 for (i= 0; i<4; i++)
2078 edge= (levmask >> i) & 1;
2079 irq= (pciirq >> (4*i)) & 0xf;
2080 if (!irq)
2082 if (debug)
2083 printf("INT%c: disabled\n", 'A'+i);
2085 else
2087 if (debug)
2088 printf("INT%c: %d\n", 'A'+i, irq);
2089 if (edge && debug)
2091 printf(
2092 "(warning) IRQ %d is not level triggered\n",
2093 irq);
2095 irq_mode_pci(irq);
2098 nr_pcidev--;
2099 return 0;
2102 /*===========================================================================*
2103 * do_sis_isabr *
2104 *===========================================================================*/
2105 static int do_sis_isabr(int devind)
2107 int i, irq;
2109 irq= 0; /* lint */
2110 for (i= 0; i<4; i++)
2112 irq= pci_attr_r8_u(devind, SIS_ISABR_IRQ_A+i);
2113 if (irq & SIS_IRQ_DISABLED)
2115 if (debug)
2116 printf("INT%c: disabled\n", 'A'+i);
2118 else
2120 irq &= SIS_IRQ_MASK;
2121 if (debug)
2122 printf("INT%c: %d\n", 'A'+i, irq);
2123 irq_mode_pci(irq);
2126 return 0;
2129 /*===========================================================================*
2130 * do_via_isabr *
2131 *===========================================================================*/
2132 static int do_via_isabr(int devind)
2134 int i, irq, edge;
2135 u8_t levmask;
2137 levmask= pci_attr_r8_u(devind, VIA_ISABR_EL);
2138 irq= 0; /* lint */
2139 edge= 0; /* lint */
2140 for (i= 0; i<4; i++)
2142 switch(i)
2144 case 0:
2145 edge= (levmask & VIA_ISABR_EL_INTA);
2146 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2) >> 4;
2147 break;
2148 case 1:
2149 edge= (levmask & VIA_ISABR_EL_INTB);
2150 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2);
2151 break;
2152 case 2:
2153 edge= (levmask & VIA_ISABR_EL_INTC);
2154 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R3) >> 4;
2155 break;
2156 case 3:
2157 edge= (levmask & VIA_ISABR_EL_INTD);
2158 irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R1) >> 4;
2159 break;
2160 default:
2161 assert(0);
2163 irq &= 0xf;
2164 if (!irq)
2166 if (debug)
2167 printf("INT%c: disabled\n", 'A'+i);
2169 else
2171 if (debug)
2172 printf("INT%c: %d\n", 'A'+i, irq);
2173 if (edge && debug)
2175 printf(
2176 "(warning) IRQ %d is not level triggered\n",
2177 irq);
2179 irq_mode_pci(irq);
2182 return 0;
2186 #if 0
2187 /*===========================================================================*
2188 * report_vga *
2189 *===========================================================================*/
2190 static void report_vga(devind)
2191 int devind;
2193 /* Report the amount of video memory. This is needed by the X11R6
2194 * postinstall script to chmem the X server. Hopefully this can be
2195 * removed when we get virtual memory.
2197 size_t amount, size;
2198 int i;
2200 amount= 0;
2201 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
2203 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
2204 continue;
2205 size= pcidev[devind].pd_bar[i].pb_size;
2206 if (size < amount)
2207 continue;
2208 amount= size;
2210 if (size != 0)
2212 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
2213 pcidev[devind].pd_busnr,
2214 pcidev[devind].pd_dev,
2215 pcidev[devind].pd_func,
2216 amount);
2219 #endif
2222 /*===========================================================================*
2223 * pci_vid_name *
2224 *===========================================================================*/
2225 static char *pci_vid_name(u16_t vid)
2227 int i;
2229 for (i= 0; pci_vendor_table[i].name; i++)
2231 if (pci_vendor_table[i].vid == vid)
2232 return pci_vendor_table[i].name;
2234 return "unknown";
2237 /*===========================================================================*
2238 * pci_baseclass_name *
2239 *===========================================================================*/
2240 static char *pci_baseclass_name(u8_t baseclass)
2242 int i;
2244 for (i= 0; pci_baseclass_table[i].name; i++)
2246 if (pci_baseclass_table[i].baseclass == baseclass)
2247 return pci_baseclass_table[i].name;
2249 return NULL;
2252 /*===========================================================================*
2253 * pci_subclass_name *
2254 *===========================================================================*/
2255 static char *pci_subclass_name(u8_t baseclass, u8_t subclass, u8_t infclass)
2257 int i;
2259 for (i= 0; pci_subclass_table[i].name; i++)
2261 if (pci_subclass_table[i].baseclass != baseclass)
2262 continue;
2263 if (pci_subclass_table[i].subclass != subclass)
2264 continue;
2265 if (pci_subclass_table[i].infclass != infclass &&
2266 pci_subclass_table[i].infclass != (u16_t)-1)
2268 continue;
2270 return pci_subclass_table[i].name;
2272 return NULL;
2275 /*===========================================================================*
2276 * ntostr *
2277 *===========================================================================*/
2278 static void ntostr(n, str, end)
2279 unsigned n;
2280 char **str;
2281 const char *end;
2283 char tmpstr[20];
2284 int i;
2286 if (n == 0)
2288 tmpstr[0]= '0';
2289 i= 1;
2291 else
2293 for (i= 0; n; i++)
2295 tmpstr[i]= '0' + (n%10);
2296 n /= 10;
2299 for (; i>0; i--)
2301 if (*str == end)
2303 break;
2305 **str= tmpstr[i-1];
2306 (*str)++;
2308 if (*str == end)
2309 (*str)[-1]= '\0';
2310 else
2311 **str= '\0';
2314 /*===========================================================================*
2315 * pci_attr_rsts *
2316 *===========================================================================*/
2317 static u16_t pci_attr_rsts(devind)
2318 int devind;
2320 int busnr, busind;
2322 busnr= pcidev[devind].pd_busnr;
2323 busind= get_busind(busnr);
2324 return pcibus[busind].pb_rsts(busind);
2328 /*===========================================================================*
2329 * pcibr_std_rsts *
2330 *===========================================================================*/
2331 static u16_t pcibr_std_rsts(busind)
2332 int busind;
2334 int devind;
2336 devind= pcibus[busind].pb_devind;
2337 return pci_attr_r16(devind, PPB_SSTS);
2340 /*===========================================================================*
2341 * pcibr_std_wsts *
2342 *===========================================================================*/
2343 static void pcibr_std_wsts(int busind, u16_t value)
2345 int devind;
2346 devind= pcibus[busind].pb_devind;
2348 #if 0
2349 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2350 busind, value, devind);
2351 #endif
2352 pci_attr_w16(devind, PPB_SSTS, value);
2355 /*===========================================================================*
2356 * pcibr_cb_rsts *
2357 *===========================================================================*/
2358 static u16_t pcibr_cb_rsts(busind)
2359 int busind;
2361 int devind;
2362 devind= pcibus[busind].pb_devind;
2364 return pci_attr_r16(devind, CBB_SSTS);
2367 /*===========================================================================*
2368 * pcibr_cb_wsts *
2369 *===========================================================================*/
2370 static void pcibr_cb_wsts(int busind, u16_t value)
2372 int devind;
2373 devind= pcibus[busind].pb_devind;
2375 #if 0
2376 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2377 busind, value, devind);
2378 #endif
2379 pci_attr_w16(devind, CBB_SSTS, value);
2382 /*===========================================================================*
2383 * pcibr_via_rsts *
2384 *===========================================================================*/
2385 static u16_t pcibr_via_rsts(int busind)
2387 return 0;
2390 /*===========================================================================*
2391 * pcibr_via_wsts *
2392 *===========================================================================*/
2393 static void pcibr_via_wsts(int busind, u16_t value)
2395 int devind;
2396 devind= pcibus[busind].pb_devind;
2398 #if 0
2399 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2400 busind, value, devind);
2401 #endif
2404 /*===========================================================================*
2405 * pci_attr_wsts *
2406 *===========================================================================*/
2407 static void pci_attr_wsts(int devind, u16_t value)
2409 int busnr, busind;
2411 busnr= pcidev[devind].pd_busnr;
2412 busind= get_busind(busnr);
2413 pcibus[busind].pb_wsts(busind, value);
2417 /*===========================================================================*
2418 * pcii_rreg8 *
2419 *===========================================================================*/
2420 static u8_t pcii_rreg8(busind, devind, port)
2421 int busind;
2422 int devind;
2423 int port;
2425 u8_t v;
2426 int s;
2428 v= PCII_RREG8_(pcibus[busind].pb_busnr,
2429 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2430 port);
2431 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2432 printf("PCI: warning, sys_outl failed: %d\n", s);
2433 #if 0
2434 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2435 busind, devind, port,
2436 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2437 pcidev[devind].pd_func, v);
2438 #endif
2439 return v;
2442 /*===========================================================================*
2443 * pcii_rreg16 *
2444 *===========================================================================*/
2445 static u16_t pcii_rreg16(int busind, int devind, int port)
2447 u16_t v;
2448 int s;
2450 v= PCII_RREG16_(pcibus[busind].pb_busnr,
2451 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2452 port);
2453 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2454 printf("PCI: warning, sys_outl failed: %d\n", s);
2455 #if 0
2456 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2457 busind, devind, port,
2458 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2459 pcidev[devind].pd_func, v);
2460 #endif
2461 return v;
2464 /*===========================================================================*
2465 * pcii_rreg32 *
2466 *===========================================================================*/
2467 static u32_t pcii_rreg32(int busind, int devind, int port)
2469 u32_t v;
2470 int s;
2472 v= PCII_RREG32_(pcibus[busind].pb_busnr,
2473 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2474 port);
2475 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2476 printf("PCI: warning, sys_outl failed: %d\n", s);
2477 #if 0
2478 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2479 busind, devind, port,
2480 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2481 pcidev[devind].pd_func, v);
2482 #endif
2483 return v;
2486 /*===========================================================================*
2487 * pcii_wreg8 *
2488 *===========================================================================*/
2489 static void pcii_wreg8(
2490 int busind,
2491 int devind,
2492 int port,
2493 u8_t value
2496 int s;
2497 #if 0
2498 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2499 busind, devind, port, value,
2500 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2501 pcidev[devind].pd_func);
2502 #endif
2503 PCII_WREG8_(pcibus[busind].pb_busnr,
2504 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2505 port, value);
2506 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2507 printf("PCI: warning, sys_outl failed: %d\n", s);
2510 /*===========================================================================*
2511 * pcii_wreg16 *
2512 *===========================================================================*/
2513 static void pcii_wreg16(
2514 int busind,
2515 int devind,
2516 int port,
2517 u16_t value
2520 int s;
2521 #if 0
2522 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2523 busind, devind, port, value,
2524 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2525 pcidev[devind].pd_func);
2526 #endif
2527 PCII_WREG16_(pcibus[busind].pb_busnr,
2528 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2529 port, value);
2530 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2531 printf("PCI: warning, sys_outl failed: %d\n", s);
2534 /*===========================================================================*
2535 * pcii_wreg32 *
2536 *===========================================================================*/
2537 static void pcii_wreg32(
2538 int busind,
2539 int devind,
2540 int port,
2541 u32_t value
2544 int s;
2545 #if 0
2546 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2547 busind, devind, port, value,
2548 pcibus[busind].pb_busnr, pcidev[devind].pd_dev,
2549 pcidev[devind].pd_func);
2550 #endif
2551 PCII_WREG32_(pcibus[busind].pb_busnr,
2552 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2553 port, value);
2554 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2555 printf("PCI: warning, sys_outl failed: %d\n",s);
2558 /*===========================================================================*
2559 * pcii_rsts *
2560 *===========================================================================*/
2561 static u16_t pcii_rsts(int busind)
2563 u16_t v;
2564 int s;
2566 v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
2567 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2568 printf("PCI: warning, sys_outl failed: %d\n", s);
2569 return v;
2572 /*===========================================================================*
2573 * pcii_wsts *
2574 *===========================================================================*/
2575 static void pcii_wsts(int busind, u16_t value)
2577 int s;
2578 PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
2579 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2580 printf("PCI: warning, sys_outl failed: %d\n", s);
2584 /*===========================================================================*
2585 * print_capabilities *
2586 *===========================================================================*/
2587 static void print_capabilities(int devind)
2589 u8_t status, capptr, type, next, subtype;
2590 char *str;
2592 /* Check capabilities bit in the device status register */
2593 status= pci_attr_r16(devind, PCI_SR);
2594 if (!(status & PSR_CAPPTR))
2595 return;
2597 capptr= (pci_attr_r8_u(devind, PCI_CAPPTR) & PCI_CP_MASK);
2598 while (capptr != 0)
2600 type = pci_attr_r8_u(devind, capptr+CAP_TYPE);
2601 next= (pci_attr_r8_u(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
2602 switch(type)
2604 case 1: str= "PCI Power Management"; break;
2605 case 2: str= "AGP"; break;
2606 case 3: str= "Vital Product Data"; break;
2607 case 4: str= "Slot Identification"; break;
2608 case 5: str= "Message Signaled Interrupts"; break;
2609 case 6: str= "CompactPCI Hot Swap"; break;
2610 case 8: str= "AMD HyperTransport"; break;
2611 case 0xf: str= "Secure Device"; break;
2612 default: str= "(unknown type)"; break;
2615 printf(" @0x%x (0x%08x): capability type 0x%x: %s",
2616 capptr, pci_attr_r32_u(devind, capptr), type, str);
2617 if (type == 0x08)
2618 print_hyper_cap(devind, capptr);
2619 else if (type == 0x0f)
2621 subtype= (pci_attr_r8_u(devind, capptr+2) & 0x07);
2622 switch(subtype)
2624 case 0: str= "Device Exclusion Vector"; break;
2625 case 3: str= "IOMMU"; break;
2626 default: str= "(unknown type)"; break;
2628 printf(", sub type 0%o: %s", subtype, str);
2630 printf("\n");
2631 capptr= next;
2636 /*===========================================================================*
2637 * visible *
2638 *===========================================================================*/
2639 static int visible(aclp, devind)
2640 struct rs_pci *aclp;
2641 int devind;
2643 int i;
2644 u32_t class_id;
2646 if (!aclp)
2647 return TRUE; /* Should be changed when ACLs become
2648 * mandatory. Do note that procfs relies
2649 * on being able to see all devices.
2651 /* Check whether the caller is allowed to get this device. */
2652 for (i= 0; i<aclp->rsp_nr_device; i++)
2654 if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
2655 aclp->rsp_device[i].did == pcidev[devind].pd_did)
2657 return TRUE;
2660 if (!aclp->rsp_nr_class)
2661 return FALSE;
2663 class_id= (pcidev[devind].pd_baseclass << 16) |
2664 (pcidev[devind].pd_subclass << 8) |
2665 pcidev[devind].pd_infclass;
2666 for (i= 0; i<aclp->rsp_nr_class; i++)
2668 if (aclp->rsp_class[i].pciclass ==
2669 (class_id & aclp->rsp_class[i].mask))
2671 return TRUE;
2675 return FALSE;
2678 /*===========================================================================*
2679 * print_hyper_cap *
2680 *===========================================================================*/
2681 static void print_hyper_cap(int devind, u8_t capptr)
2683 u32_t v;
2684 u16_t cmd;
2685 int type0, type1;
2687 printf("\n");
2688 v= pci_attr_r32_u(devind, capptr);
2689 printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr);
2690 cmd= (v >> 16) & 0xffff;
2691 #if 0
2692 if (v & 0x10000)
2694 printf(" WarmReset");
2695 v &= ~0x10000;
2697 if (v & 0x20000)
2699 printf(" DblEnded");
2700 v &= ~0x20000;
2702 printf(" DevNum %d", (v & 0x7C0000) >> 18);
2703 v &= ~0x7C0000;
2704 #endif
2705 type0= (cmd & 0xE000) >> 13;
2706 type1= (cmd & 0xF800) >> 11;
2707 if (type0 == 0 || type0 == 1)
2709 printf("Capability Type: %s\n",
2710 type0 == 0 ? "Slave or Primary Interface" :
2711 "Host or Secondary Interface");
2712 cmd &= ~0xE000;
2714 else
2716 printf(" Capability Type 0x%x", type1);
2717 cmd &= ~0xF800;
2719 if (cmd)
2720 printf(" undecoded 0x%x\n", cmd);
2722 #if 0
2723 printf("print_hyper_cap: off 4 (ctl): 0x%x\n",
2724 pci_attr_r32_u(devind, capptr+4));
2725 printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n",
2726 pci_attr_r32_u(devind, capptr+8));
2727 printf("print_hyper_cap: off 12 (cap): 0x%x\n",
2728 pci_attr_r32_u(devind, capptr+12));
2729 printf("print_hyper_cap: off 16 (buf count): 0x%x\n",
2730 pci_attr_r32_u(devind, capptr+16));
2731 v= pci_attr_r32_u(devind, capptr+20);
2732 printf("print_hyper_cap: @0x%x, off 20 (bus nr): ",
2733 capptr+20);
2734 printf("prim %d", v & 0xff);
2735 printf(", sec %d", (v >> 8) & 0xff);
2736 printf(", sub %d", (v >> 16) & 0xff);
2737 if (v >> 24)
2738 printf(", reserved %d", (v >> 24) & 0xff);
2739 printf("\n");
2740 printf("print_hyper_cap: off 24 (type): 0x%x\n",
2741 pci_attr_r32_u(devind, capptr+24));
2742 #endif
2746 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $