add/re-enable at_wini debug output
[minix3.git] / drivers / pci / pci.c
blob1e70d89c515dec4dac98df826a98920d48ae6190
1 #define USER_SPACE 1
2 /*
3 pci.c
5 Configure devices on the PCI bus
7 Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
8 */
10 #include "../drivers.h"
11 #define NDEBUG /* disable assertions */
12 #include <assert.h>
13 #include <ibm/pci.h>
14 #include <sys/vm.h>
15 #include <minix/com.h>
16 #include <minix/rs.h>
17 #include <minix/syslib.h>
19 #include "pci.h"
20 #include "pci_amd.h"
21 #include "pci_intel.h"
22 #include "pci_sis.h"
23 #include "pci_via.h"
24 #if __minix_vmd
25 #include "config.h"
26 #endif
28 #if !__minix_vmd
29 #define irq_mode_pci(irq) ((void)0)
30 #endif
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <minix/sysutil.h>
37 #define NR_PCIBUS 10
38 #define NR_PCIDEV 40
40 #define PBT_INTEL_HOST 1
41 #define PBT_PCIBRIDGE 2
42 #define PBT_CARDBUS 3
44 #define BAM_NR 6 /* Number of base-address registers */
46 int debug= 0;
48 PRIVATE struct pcibus
50 int pb_type;
51 int pb_needinit;
52 int pb_isabridge_dev;
53 int pb_isabridge_type;
55 int pb_devind;
56 int pb_busnr;
57 u8_t (*pb_rreg8)(int busind, int devind, int port);
58 u16_t (*pb_rreg16)(int busind, int devind, int port);
59 u32_t (*pb_rreg32)(int busind, int devind, int port);
60 void (*pb_wreg8)(int busind, int devind, int port, U8_t value);
61 void (*pb_wreg16)(int busind, int devind, int port, U16_t value);
62 void (*pb_wreg32)(int busind, int devind, int port, u32_t value);
63 u16_t (*pb_rsts)(int busind);
64 void (*pb_wsts)(int busind, U16_t value);
65 } pcibus[NR_PCIBUS];
66 PRIVATE int nr_pcibus= 0;
68 PRIVATE struct pcidev
70 u8_t pd_busnr;
71 u8_t pd_dev;
72 u8_t pd_func;
73 u8_t pd_baseclass;
74 u8_t pd_subclass;
75 u8_t pd_infclass;
76 u16_t pd_vid;
77 u16_t pd_did;
78 u8_t pd_ilr;
79 u8_t pd_inuse;
81 struct bar
83 int pb_flags;
84 int pb_nr;
85 u32_t pb_base;
86 u32_t pb_size;
87 } pd_bar[BAM_NR];
88 int pd_bar_nr;
90 char pd_name[M3_STRING];
91 } pcidev[NR_PCIDEV];
93 /* pb_flags */
94 #define PBF_IO 1 /* I/O else memory */
95 #define PBF_INCOMPLETE 2 /* not allocated */
97 PRIVATE int nr_pcidev= 0;
99 /* Work around the limitations of the PCI emulation in QEMU 0.7.1 */
100 PRIVATE int qemu_pci= 0;
102 FORWARD _PROTOTYPE( void pci_intel_init, (void) );
103 FORWARD _PROTOTYPE( void probe_bus, (int busind) );
104 FORWARD _PROTOTYPE( int is_duplicate, (U8_t busnr, U8_t dev, U8_t func) );
105 FORWARD _PROTOTYPE( void record_irq, (int devind) );
106 FORWARD _PROTOTYPE( void record_bars, (int devind) );
107 FORWARD _PROTOTYPE( void record_bars_bridge, (int devind) );
108 FORWARD _PROTOTYPE( void record_bars_cardbus, (int devind) );
109 FORWARD _PROTOTYPE( void record_bar, (int devind, int bar_nr) );
110 FORWARD _PROTOTYPE( void complete_bridges, (void) );
111 FORWARD _PROTOTYPE( void complete_bars, (void) );
112 FORWARD _PROTOTYPE( void update_bridge4dev_io, (int devind,
113 u32_t io_base, u32_t io_size) );
114 FORWARD _PROTOTYPE( int get_freebus, (void) );
115 FORWARD _PROTOTYPE( int do_isabridge, (int busind) );
116 FORWARD _PROTOTYPE( void do_pcibridge, (int busind) );
117 FORWARD _PROTOTYPE( int get_busind, (int busnr) );
118 FORWARD _PROTOTYPE( int do_piix, (int devind) );
119 FORWARD _PROTOTYPE( int do_amd_isabr, (int devind) );
120 FORWARD _PROTOTYPE( int do_sis_isabr, (int devind) );
121 FORWARD _PROTOTYPE( int do_via_isabr, (int devind) );
122 FORWARD _PROTOTYPE( void report_vga, (int devind) );
123 FORWARD _PROTOTYPE( char *pci_vid_name, (U16_t vid) );
124 FORWARD _PROTOTYPE( char *pci_baseclass_name, (U8_t baseclass) );
125 FORWARD _PROTOTYPE( char *pci_subclass_name, (U8_t baseclass,
126 U8_t subclass, U8_t infclass) );
127 FORWARD _PROTOTYPE( void ntostr, (unsigned n, char **str, char *end) );
128 FORWARD _PROTOTYPE( u16_t pci_attr_rsts, (int devind) );
129 FORWARD _PROTOTYPE( void pci_attr_wsts, (int devind, U16_t value) );
130 FORWARD _PROTOTYPE( u16_t pcibr_std_rsts, (int busind) );
131 FORWARD _PROTOTYPE( void pcibr_std_wsts, (int busind, U16_t value) );
132 FORWARD _PROTOTYPE( u16_t pcibr_cb_rsts, (int busind) );
133 FORWARD _PROTOTYPE( void pcibr_cb_wsts, (int busind, U16_t value) );
134 FORWARD _PROTOTYPE( u16_t pcibr_via_rsts, (int busind) );
135 FORWARD _PROTOTYPE( void pcibr_via_wsts, (int busind, U16_t value) );
136 FORWARD _PROTOTYPE( u8_t pcii_rreg8, (int busind, int devind, int port) );
137 FORWARD _PROTOTYPE( u16_t pcii_rreg16, (int busind, int devind,
138 int port) );
139 FORWARD _PROTOTYPE( u32_t pcii_rreg32, (int busind, int devind,
140 int port) );
141 FORWARD _PROTOTYPE( void pcii_wreg8, (int busind, int devind, int port,
142 U8_t value) );
143 FORWARD _PROTOTYPE( void pcii_wreg16, (int busind, int devind, int port,
144 U16_t value) );
145 FORWARD _PROTOTYPE( void pcii_wreg32, (int busind, int devind, int port,
146 u32_t value) );
147 FORWARD _PROTOTYPE( u16_t pcii_rsts, (int busind) );
148 FORWARD _PROTOTYPE( void pcii_wsts, (int busind, U16_t value) );
149 FORWARD _PROTOTYPE( void print_capabilities, (int devind) );
150 FORWARD _PROTOTYPE( int visible, (struct rs_pci *aclp, int devind) );
152 /*===========================================================================*
153 * helper functions for I/O *
154 *===========================================================================*/
155 PUBLIC unsigned pci_inb(U16_t port) {
156 u32_t value;
157 int s;
158 if ((s=sys_inb(port, &value)) !=OK)
159 printf("PCI: warning, sys_inb failed: %d\n", s);
160 return value;
162 PUBLIC unsigned pci_inw(U16_t port) {
163 u32_t value;
164 int s;
165 if ((s=sys_inw(port, &value)) !=OK)
166 printf("PCI: warning, sys_inw failed: %d\n", s);
167 return value;
169 PUBLIC unsigned pci_inl(U16_t port) {
170 U32_t value;
171 int s;
172 if ((s=sys_inl(port, &value)) !=OK)
173 printf("PCI: warning, sys_inl failed: %d\n", s);
174 return value;
176 PUBLIC void pci_outb(U16_t port, U8_t value) {
177 int s;
178 if ((s=sys_outb(port, value)) !=OK)
179 printf("PCI: warning, sys_outb failed: %d\n", s);
181 PUBLIC void pci_outw(U16_t port, U16_t value) {
182 int s;
183 if ((s=sys_outw(port, value)) !=OK)
184 printf("PCI: warning, sys_outw failed: %d\n", s);
186 PUBLIC void pci_outl(U16_t port, U32_t value) {
187 int s;
188 if ((s=sys_outl(port, value)) !=OK)
189 printf("PCI: warning, sys_outl failed: %d\n", s);
192 /*===========================================================================*
193 * pci_init *
194 *===========================================================================*/
195 PUBLIC void pci_init()
197 static int first_time= 1;
199 long v;
201 if (!first_time)
202 return;
204 v= 0;
205 env_parse("qemu_pci", "d", 0, &v, 0, 1);
206 qemu_pci= v;
208 v= 0;
209 env_parse("pci_debug", "d", 0, &v, 0, 1);
210 debug= v;
212 /* We don't expect to interrupted */
213 assert(first_time == 1);
214 first_time= -1;
216 /* Only Intel (compatible) PCI controllers are supported at the
217 * moment.
219 pci_intel_init();
221 first_time= 0;
224 /*===========================================================================*
225 * pci_find_dev *
226 *===========================================================================*/
227 PUBLIC int pci_find_dev(bus, dev, func, devindp)
228 u8_t bus;
229 u8_t dev;
230 u8_t func;
231 int *devindp;
233 int devind;
235 for (devind= 0; devind < nr_pcidev; devind++)
237 if (pcidev[devind].pd_busnr == bus &&
238 pcidev[devind].pd_dev == dev &&
239 pcidev[devind].pd_func == func)
241 break;
244 if (devind >= nr_pcidev)
245 return 0;
246 #if 0
247 if (pcidev[devind].pd_inuse)
248 return 0;
249 #endif
250 *devindp= devind;
251 return 1;
254 /*===========================================================================*
255 * pci_first_dev_a *
256 *===========================================================================*/
257 PUBLIC int pci_first_dev_a(aclp, devindp, vidp, didp)
258 struct rs_pci *aclp;
259 int *devindp;
260 u16_t *vidp;
261 u16_t *didp;
263 int i, devind;
265 for (devind= 0; devind < nr_pcidev; devind++)
267 #if 0
268 if (pcidev[devind].pd_inuse)
269 continue;
270 #endif
271 if (!visible(aclp, devind))
272 continue;
273 break;
275 if (devind >= nr_pcidev)
276 return 0;
277 *devindp= devind;
278 *vidp= pcidev[devind].pd_vid;
279 *didp= pcidev[devind].pd_did;
280 return 1;
283 /*===========================================================================*
284 * pci_next_dev *
285 *===========================================================================*/
286 PUBLIC int pci_next_dev_a(aclp, devindp, vidp, didp)
287 struct rs_pci *aclp;
288 int *devindp;
289 u16_t *vidp;
290 u16_t *didp;
292 int devind;
294 for (devind= *devindp+1; devind < nr_pcidev; devind++)
296 #if 0
297 if (pcidev[devind].pd_inuse)
298 continue;
299 #endif
300 if (!visible(aclp, devind))
301 continue;
302 break;
304 if (devind >= nr_pcidev)
305 return 0;
306 *devindp= devind;
307 *vidp= pcidev[devind].pd_vid;
308 *didp= pcidev[devind].pd_did;
309 return 1;
312 /*===========================================================================*
313 * pci_reserve3 *
314 *===========================================================================*/
315 PUBLIC int pci_reserve3(devind, proc, name)
316 int devind;
317 int proc;
318 char *name;
320 int i, r;
321 u8_t ilr;
322 struct io_range ior;
323 struct mem_range mr;
325 assert(devind <= nr_pcidev);
326 if(pcidev[devind].pd_inuse)
327 return EBUSY;
328 pcidev[devind].pd_inuse= 1;
329 strcpy(pcidev[devind].pd_name, name);
331 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
333 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
335 printf("pci_reserve3: BAR %d is incomplete\n", i);
336 continue;
338 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
340 ior.ior_base= pcidev[devind].pd_bar[i].pb_base;
341 ior.ior_limit= ior.ior_base +
342 pcidev[devind].pd_bar[i].pb_size-1;
344 if(debug) {
345 printf(
346 "pci_reserve3: for proc %d, adding I/O range [0x%x..0x%x]\n",
347 proc, ior.ior_base, ior.ior_limit);
349 r= sys_privctl(proc, SYS_PRIV_ADD_IO, 0, &ior);
350 if (r != OK)
352 printf("sys_privctl failed for proc %d: %d\n",
353 proc, r);
356 else
358 mr.mr_base= pcidev[devind].pd_bar[i].pb_base;
359 mr.mr_limit= mr.mr_base +
360 pcidev[devind].pd_bar[i].pb_size-1;
362 if(debug) {
363 printf(
364 "pci_reserve3: for proc %d, should add memory range [0x%x..0x%x]\n",
365 proc, mr.mr_base, mr.mr_limit);
367 r= sys_privctl(proc, SYS_PRIV_ADD_MEM, 0, &mr);
368 if (r != OK)
370 printf("sys_privctl failed for proc %d: %d\n",
371 proc, r);
375 ilr= pcidev[devind].pd_ilr;
376 if (ilr != PCI_ILR_UNKNOWN)
378 if(debug) printf("pci_reserve3: adding IRQ %d\n", ilr);
379 r= sys_privctl(proc, SYS_PRIV_ADD_IRQ, ilr, NULL);
380 if (r != OK)
382 printf("sys_privctl failed for proc %d: %d\n",
383 proc, r);
387 return OK;
390 #if 0
391 /*===========================================================================*
392 * pci_release *
393 *===========================================================================*/
394 PUBLIC void pci_release(name)
395 char *name;
397 int i;
399 for (i= 0; i<nr_pcidev; i++)
401 if (!pcidev[i].pd_inuse)
402 continue;
403 if (strcmp(pcidev[i].pd_name, name) != 0)
404 continue;
405 pcidev[i].pd_inuse= 0;
408 #endif
410 /*===========================================================================*
411 * pci_ids *
412 *===========================================================================*/
413 PUBLIC void pci_ids(devind, vidp, didp)
414 int devind;
415 u16_t *vidp;
416 u16_t *didp;
418 assert(devind <= nr_pcidev);
419 *vidp= pcidev[devind].pd_vid;
420 *didp= pcidev[devind].pd_did;
423 /*===========================================================================*
424 * pci_rescan_bus *
425 *===========================================================================*/
426 PUBLIC void pci_rescan_bus(busnr)
427 u8_t busnr;
429 int busind;
431 busind= get_busind(busnr);
432 probe_bus(busind);
434 /* Allocate bus numbers for uninitialized bridges */
435 complete_bridges();
437 /* Allocate I/O and memory resources for uninitialized devices */
438 complete_bars();
441 /*===========================================================================*
442 * pci_slot_name *
443 *===========================================================================*/
444 PUBLIC char *pci_slot_name(devind)
445 int devind;
447 static char label[]= "ddd.ddd.ddd";
448 char *end;
449 char *p;
451 p= label;
452 end= label+sizeof(label);
454 ntostr(pcidev[devind].pd_busnr, &p, end);
455 *p++= '.';
457 ntostr(pcidev[devind].pd_dev, &p, end);
458 *p++= '.';
460 ntostr(pcidev[devind].pd_func, &p, end);
462 return label;
465 /*===========================================================================*
466 * pci_dev_name *
467 *===========================================================================*/
468 PUBLIC char *pci_dev_name(vid, did)
469 u16_t vid;
470 u16_t did;
472 int i;
474 for (i= 0; pci_device_table[i].name; i++)
476 if (pci_device_table[i].vid == vid &&
477 pci_device_table[i].did == did)
479 return pci_device_table[i].name;
482 return NULL;
485 /*===========================================================================*
486 * pci_attr_r8 *
487 *===========================================================================*/
488 PUBLIC u8_t pci_attr_r8(devind, port)
489 int devind;
490 int port;
492 int busnr, busind;
494 busnr= pcidev[devind].pd_busnr;
495 busind= get_busind(busnr);
496 return pcibus[busind].pb_rreg8(busind, devind, port);
499 /*===========================================================================*
500 * pci_attr_r16 *
501 *===========================================================================*/
502 PUBLIC u16_t pci_attr_r16(devind, port)
503 int devind;
504 int port;
506 int busnr, busind;
508 busnr= pcidev[devind].pd_busnr;
509 busind= get_busind(busnr);
510 return pcibus[busind].pb_rreg16(busind, devind, port);
513 /*===========================================================================*
514 * pci_attr_r32 *
515 *===========================================================================*/
516 PUBLIC u32_t pci_attr_r32(devind, port)
517 int devind;
518 int port;
520 int busnr, busind;
522 busnr= pcidev[devind].pd_busnr;
523 busind= get_busind(busnr);
524 return pcibus[busind].pb_rreg32(busind, devind, port);
527 /*===========================================================================*
528 * pci_attr_w8 *
529 *===========================================================================*/
530 PUBLIC void pci_attr_w8(devind, port, value)
531 int devind;
532 int port;
533 u16_t value;
535 int busnr, busind;
537 busnr= pcidev[devind].pd_busnr;
538 busind= get_busind(busnr);
539 pcibus[busind].pb_wreg8(busind, devind, port, value);
542 /*===========================================================================*
543 * pci_attr_w16 *
544 *===========================================================================*/
545 PUBLIC void pci_attr_w16(devind, port, value)
546 int devind;
547 int port;
548 u16_t value;
550 int busnr, busind;
552 busnr= pcidev[devind].pd_busnr;
553 busind= get_busind(busnr);
554 pcibus[busind].pb_wreg16(busind, devind, port, value);
557 /*===========================================================================*
558 * pci_attr_w32 *
559 *===========================================================================*/
560 PUBLIC void pci_attr_w32(devind, port, value)
561 int devind;
562 int port;
563 u32_t value;
565 int busnr, busind;
567 busnr= pcidev[devind].pd_busnr;
568 busind= get_busind(busnr);
569 pcibus[busind].pb_wreg32(busind, devind, port, value);
572 /*===========================================================================*
573 * pci_intel_init *
574 *===========================================================================*/
575 PRIVATE void pci_intel_init()
577 /* Try to detect a know PCI controller. Read the Vendor ID and
578 * the Device ID for function 0 of device 0.
579 * Two times the value 0xffff suggests a system without a (compatible)
580 * PCI controller.
582 u32_t bus, dev, func;
583 u16_t vid, did;
584 int s, i, r, busind, busnr;
585 char *dstr;
587 bus= 0;
588 dev= 0;
589 func= 0;
591 vid= PCII_RREG16_(bus, dev, func, PCI_VID);
592 did= PCII_RREG16_(bus, dev, func, PCI_DID);
593 #if USER_SPACE
594 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
595 printf("PCI: warning, sys_outl failed: %d\n", s);
596 #else
597 outl(PCII_CONFADD, PCII_UNSEL);
598 #endif
600 if (vid == 0xffff && did == 0xffff)
601 return; /* Nothing here */
603 #if 0
604 for (i= 0; pci_intel_ctrl[i].vid; i++)
606 if (pci_intel_ctrl[i].vid == vid &&
607 pci_intel_ctrl[i].did == did)
609 break;
613 if (!pci_intel_ctrl[i].vid)
615 printf("pci_intel_init (warning): unknown PCI-controller:\n"
616 "\tvendor %04X (%s), device %04X\n",
617 vid, pci_vid_name(vid), did);
619 #endif
621 if (nr_pcibus >= NR_PCIBUS)
622 panic("PCI","too many PCI busses", nr_pcibus);
623 busind= nr_pcibus;
624 nr_pcibus++;
625 pcibus[busind].pb_type= PBT_INTEL_HOST;
626 pcibus[busind].pb_needinit= 0;
627 pcibus[busind].pb_isabridge_dev= -1;
628 pcibus[busind].pb_isabridge_type= 0;
629 pcibus[busind].pb_devind= -1;
630 pcibus[busind].pb_busnr= 0;
631 pcibus[busind].pb_rreg8= pcii_rreg8;
632 pcibus[busind].pb_rreg16= pcii_rreg16;
633 pcibus[busind].pb_rreg32= pcii_rreg32;
634 pcibus[busind].pb_wreg8= pcii_wreg8;
635 pcibus[busind].pb_wreg16= pcii_wreg16;
636 pcibus[busind].pb_wreg32= pcii_wreg32;
637 pcibus[busind].pb_rsts= pcii_rsts;
638 pcibus[busind].pb_wsts= pcii_wsts;
640 dstr= pci_dev_name(vid, did);
641 if (!dstr)
642 dstr= "unknown device";
643 if (debug)
645 printf("pci_intel_init: %s (%04X/%04X)\n",
646 dstr, vid, did);
649 probe_bus(busind);
651 r= do_isabridge(busind);
652 if (r != OK)
654 busnr= pcibus[busind].pb_busnr;
656 /* Disable all devices for this bus */
657 for (i= 0; i<nr_pcidev; i++)
659 if (pcidev[i].pd_busnr != busnr)
660 continue;
661 pcidev[i].pd_inuse= 1;
663 return;
666 /* Look for PCI bridges */
667 do_pcibridge(busind);
669 /* Allocate bus numbers for uninitialized bridges */
670 complete_bridges();
672 /* Allocate I/O and memory resources for uninitialized devices */
673 complete_bars();
676 /*===========================================================================*
677 * probe_bus *
678 *===========================================================================*/
679 PRIVATE void probe_bus(busind)
680 int busind;
682 u32_t dev, func, t3;
683 u16_t vid, did, sts;
684 u8_t headt;
685 u8_t baseclass, subclass, infclass;
686 int devind, busnr;
687 char *s, *dstr;
689 #if DEBUG
690 printf("probe_bus(%d)\n", busind);
691 #endif
692 if (nr_pcidev >= NR_PCIDEV)
693 panic("PCI","too many PCI devices", nr_pcidev);
694 devind= nr_pcidev;
696 busnr= pcibus[busind].pb_busnr;
697 for (dev= 0; dev<32; dev++)
700 for (func= 0; func < 8; func++)
702 pcidev[devind].pd_busnr= busnr;
703 pcidev[devind].pd_dev= dev;
704 pcidev[devind].pd_func= func;
706 pci_attr_wsts(devind,
707 PSR_SSE|PSR_RMAS|PSR_RTAS);
708 vid= pci_attr_r16(devind, PCI_VID);
709 did= pci_attr_r16(devind, PCI_DID);
710 headt= pci_attr_r8(devind, PCI_HEADT);
711 sts= pci_attr_rsts(devind);
713 #if 0
714 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
715 vid, did, headt, sts);
716 #endif
718 if (vid == NO_VID)
720 if (func == 0)
721 break; /* Nothing here */
723 /* Scan all functions of a multifunction
724 * device.
726 continue;
729 if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
731 if (qemu_pci)
733 printf(
734 "PCI: ignoring bad value 0x%x in sts for QEMU\n",
735 sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
737 else
739 if (func == 0)
740 break; /* Nothing here */
742 /* Scan all functions of a
743 * multifunction device.
745 continue;
749 dstr= pci_dev_name(vid, did);
750 if (debug)
752 if (dstr)
754 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
755 busind, (unsigned long)dev,
756 (unsigned long)func, dstr,
757 vid, did);
759 else
761 printf(
762 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
763 busind, (unsigned long)dev,
764 (unsigned long)func, vid,
765 pci_vid_name(vid), did);
767 printf("Device index: %d\n", devind);
768 printf("Subsystem: Vid 0x%x, did 0x%x\n",
769 pci_attr_r16(devind, PCI_SUBVID),
770 pci_attr_r16(devind, PCI_SUBDID));
773 baseclass= pci_attr_r8(devind, PCI_BCR);
774 subclass= pci_attr_r8(devind, PCI_SCR);
775 infclass= pci_attr_r8(devind, PCI_PIFR);
776 s= pci_subclass_name(baseclass, subclass, infclass);
777 if (!s)
778 s= pci_baseclass_name(baseclass);
780 if (!s)
781 s= "(unknown class)";
783 if (debug)
785 printf("\tclass %s (%X/%X/%X)\n", s,
786 baseclass, subclass, infclass);
789 if (is_duplicate(busnr, dev, func))
791 printf("\tduplicate!\n");
792 if (func == 0 && !(headt & PHT_MULTIFUNC))
793 break;
794 continue;
797 devind= nr_pcidev;
798 nr_pcidev++;
799 pcidev[devind].pd_baseclass= baseclass;
800 pcidev[devind].pd_subclass= subclass;
801 pcidev[devind].pd_infclass= infclass;
802 pcidev[devind].pd_vid= vid;
803 pcidev[devind].pd_did= did;
804 pcidev[devind].pd_inuse= 0;
805 pcidev[devind].pd_bar_nr= 0;
806 record_irq(devind);
807 switch(headt & PHT_MASK)
809 case PHT_NORMAL:
810 record_bars(devind);
811 break;
812 case PHT_BRIDGE:
813 record_bars_bridge(devind);
814 break;
815 case PHT_CARDBUS:
816 record_bars_cardbus(devind);
817 break;
818 default:
819 printf("\t%d.%d.%d: unknown header type %d\n",
820 busind, dev, func,
821 headt & PHT_MASK);
822 break;
824 if (debug)
825 print_capabilities(devind);
827 t3= ((baseclass << 16) | (subclass << 8) | infclass);
828 if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
829 report_vga(devind);
831 if (nr_pcidev >= NR_PCIDEV)
832 panic("PCI","too many PCI devices", nr_pcidev);
833 devind= nr_pcidev;
835 if (func == 0 && !(headt & PHT_MULTIFUNC))
836 break;
841 /*===========================================================================*
842 * is_duplicate *
843 *===========================================================================*/
844 PRIVATE int is_duplicate(busnr, dev, func)
845 u8_t busnr;
846 u8_t dev;
847 u8_t func;
849 int i;
851 for (i= 0; i<nr_pcidev; i++)
853 if (pcidev[i].pd_busnr == busnr &&
854 pcidev[i].pd_dev == dev &&
855 pcidev[i].pd_func == func)
857 return 1;
860 return 0;
863 /*===========================================================================*
864 * record_irq *
865 *===========================================================================*/
866 PRIVATE void record_irq(devind)
867 int devind;
869 int ilr, ipr, busnr, busind, cb_devind;
871 ilr= pci_attr_r8(devind, PCI_ILR);
872 ipr= pci_attr_r8(devind, PCI_IPR);
873 if (ilr == 0)
875 static int first= 1;
876 if (ipr && first && debug)
878 first= 0;
879 printf("PCI: strange, BIOS assigned IRQ0\n");
881 ilr= PCI_ILR_UNKNOWN;
883 pcidev[devind].pd_ilr= ilr;
884 if (ilr == PCI_ILR_UNKNOWN && !ipr)
887 else if (ilr != PCI_ILR_UNKNOWN && ipr)
889 if (debug)
890 printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
892 else if (ilr != PCI_ILR_UNKNOWN)
894 printf(
895 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
896 ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
897 pcidev[devind].pd_func);
899 else
901 /* Check for cardbus devices */
902 busnr= pcidev[devind].pd_busnr;
903 busind= get_busind(busnr);
904 if (pcibus[busind].pb_type == PBT_CARDBUS)
906 cb_devind= pcibus[busind].pb_devind;
907 ilr= pcidev[cb_devind].pd_ilr;
908 if (ilr != PCI_ILR_UNKNOWN)
910 if (debug)
912 printf(
913 "assigning IRQ %d to Cardbus device\n",
914 ilr);
916 pci_attr_w8(devind, PCI_ILR, ilr);
917 pcidev[devind].pd_ilr= ilr;
918 return;
921 if(debug) {
922 printf(
923 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
924 pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
925 pcidev[devind].pd_func, 'A' + ipr-1);
930 /*===========================================================================*
931 * record_bars *
932 *===========================================================================*/
933 PRIVATE void record_bars(devind)
934 int devind;
936 int i, j, reg, prefetch, type, clear_01, clear_23, pb_nr;
937 u32_t bar, bar2;
939 for (i= 0, reg= PCI_BAR; reg <= PCI_BAR_6; i++, reg += 4)
941 record_bar(devind, i);
944 /* Special case code for IDE controllers in compatibility mode */
945 if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
946 pcidev[devind].pd_subclass == PCI_MS_IDE)
948 /* IDE device */
949 clear_01= 0;
950 clear_23= 0;
951 if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
953 if (debug)
955 printf(
956 "primary channel is not in native mode, clearing BARs 0 and 1\n");
958 clear_01= 1;
960 if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
962 if (debug)
964 printf(
965 "secondary channel is not in native mode, clearing BARs 2 and 3\n");
967 clear_23= 1;
970 j= 0;
971 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
973 pb_nr= pcidev[devind].pd_bar[i].pb_nr;
974 if ((pb_nr == 0 || pb_nr == 1) && clear_01)
976 if (debug) printf("skipping bar %d\n", pb_nr);
977 continue; /* Skip */
979 if ((pb_nr == 2 || pb_nr == 3) && clear_23)
981 if (debug) printf("skipping bar %d\n", pb_nr);
982 continue; /* Skip */
984 if (i == j)
986 j++;
987 continue; /* No need to copy */
989 pcidev[devind].pd_bar[j]=
990 pcidev[devind].pd_bar[i];
991 j++;
993 pcidev[devind].pd_bar_nr= j;
997 /*===========================================================================*
998 * record_bars_bridge *
999 *===========================================================================*/
1000 PRIVATE void record_bars_bridge(devind)
1001 int devind;
1003 u32_t base, limit, size;
1005 record_bar(devind, 0);
1006 record_bar(devind, 1);
1008 base= ((pci_attr_r8(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
1009 (pci_attr_r16(devind, PPB_IOBASEU16) << 16);
1010 limit= 0xff |
1011 ((pci_attr_r8(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
1012 ((~PPB_IOL_MASK & 0xff) << 8) |
1013 (pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
1014 size= limit-base + 1;
1015 if (debug)
1017 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
1018 base, limit, size);
1021 base= ((pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
1022 limit= 0xffff |
1023 ((pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
1024 ((~PPB_MEML_MASK & 0xffff) << 16);
1025 size= limit-base + 1;
1026 if (debug)
1028 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1029 base, limit, size);
1032 /* Ignore the upper 32 bits */
1033 base= ((pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
1034 limit= 0xffff |
1035 ((pci_attr_r16(devind, PPB_PFMEMLIMIT) &
1036 PPB_PFMEML_MASK) << 16) |
1037 ((~PPB_PFMEML_MASK & 0xffff) << 16);
1038 size= limit-base + 1;
1039 if (debug)
1041 printf(
1042 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1043 base, limit, size);
1047 /*===========================================================================*
1048 * record_bars_cardbus *
1049 *===========================================================================*/
1050 PRIVATE void record_bars_cardbus(devind)
1051 int devind;
1053 u32_t base, limit, size;
1055 record_bar(devind, 0);
1057 base= pci_attr_r32(devind, CBB_MEMBASE_0);
1058 limit= pci_attr_r32(devind, CBB_MEMLIMIT_0) |
1059 (~CBB_MEML_MASK & 0xffffffff);
1060 size= limit-base + 1;
1061 if (debug)
1063 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1064 base, limit, size);
1067 base= pci_attr_r32(devind, CBB_MEMBASE_1);
1068 limit= pci_attr_r32(devind, CBB_MEMLIMIT_1) |
1069 (~CBB_MEML_MASK & 0xffffffff);
1070 size= limit-base + 1;
1071 if (debug)
1073 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1074 base, limit, size);
1077 base= pci_attr_r32(devind, CBB_IOBASE_0);
1078 limit= pci_attr_r32(devind, CBB_IOLIMIT_0) |
1079 (~CBB_IOL_MASK & 0xffffffff);
1080 size= limit-base + 1;
1081 if (debug)
1083 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1084 base, limit, size);
1087 base= pci_attr_r32(devind, CBB_IOBASE_1);
1088 limit= pci_attr_r32(devind, CBB_IOLIMIT_1) |
1089 (~CBB_IOL_MASK & 0xffffffff);
1090 size= limit-base + 1;
1091 if (debug)
1093 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1094 base, limit, size);
1098 /*===========================================================================*
1099 * record_bar *
1100 *===========================================================================*/
1101 PRIVATE void record_bar(devind, bar_nr)
1102 int devind;
1103 int bar_nr;
1105 int reg, prefetch, type, dev_bar_nr;
1106 u32_t bar, bar2;
1108 reg= PCI_BAR+4*bar_nr;
1110 bar= pci_attr_r32(devind, reg);
1111 if (bar & PCI_BAR_IO)
1113 /* Size register */
1114 pci_attr_w32(devind, reg, 0xffffffff);
1115 bar2= pci_attr_r32(devind, reg);
1116 pci_attr_w32(devind, reg, bar);
1118 bar &= ~(u32_t)3; /* Clear non-address bits */
1119 bar2 &= ~(u32_t)3;
1120 bar2= (~bar2 & 0xffff)+1;
1121 if (debug)
1123 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1124 bar_nr, bar2, bar);
1127 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1128 assert(dev_bar_nr < BAR_NR);
1129 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO;
1130 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1131 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1132 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1133 if (bar == 0)
1135 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1136 PBF_INCOMPLETE;
1139 else
1141 /* Size register */
1142 pci_attr_w32(devind, reg, 0xffffffff);
1143 bar2= pci_attr_r32(devind, reg);
1144 pci_attr_w32(devind, reg, bar);
1146 if (bar2 == 0)
1147 return; /* Reg. is not implemented */
1149 prefetch= !!(bar & PCI_BAR_PREFETCH);
1150 type= (bar & PCI_BAR_TYPE);
1151 bar &= ~(u32_t)0xf; /* Clear non-address bits */
1152 bar2 &= ~(u32_t)0xf;
1153 bar2= (~bar2)+1;
1154 if (debug)
1156 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory\n",
1157 bar_nr, bar2, bar,
1158 prefetch ? " prefetchable" : "");
1159 if (type != 0)
1160 printf("type = 0x%x\n", type);
1163 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1164 assert(dev_bar_nr < BAR_NR);
1165 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0;
1166 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1167 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1168 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1169 if (bar == 0)
1171 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1172 PBF_INCOMPLETE;
1177 /*===========================================================================*
1178 * complete_bridges *
1179 *===========================================================================*/
1180 PRIVATE void complete_bridges()
1182 int i, freebus, devind, prim_busnr;
1184 for (i= 0; i<nr_pcibus; i++)
1186 if (!pcibus[i].pb_needinit)
1187 continue;
1188 printf("should allocate bus number for bus %d\n", i);
1189 freebus= get_freebus();
1190 printf("got bus number %d\n", freebus);
1192 devind= pcibus[i].pb_devind;
1194 prim_busnr= pcidev[devind].pd_busnr;
1195 if (prim_busnr != 0)
1197 printf(
1198 "complete_bridge: updating subordinate bus number not implemented\n");
1201 pcibus[i].pb_needinit= 0;
1202 pcibus[i].pb_busnr= freebus;
1204 printf("devind = %d\n", devind);
1205 printf("prim_busnr= %d\n", prim_busnr);
1207 pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
1208 pci_attr_w8(devind, PPB_SECBN, freebus);
1209 pci_attr_w8(devind, PPB_SUBORDBN, freebus);
1211 printf("CR = 0x%x\n", pci_attr_r16(devind, PCI_CR));
1212 printf("SECBLT = 0x%x\n", pci_attr_r8(devind, PPB_SECBLT));
1213 printf("BRIDGECTRL = 0x%x\n",
1214 pci_attr_r16(devind, PPB_BRIDGECTRL));
1218 /*===========================================================================*
1219 * complete_bars *
1220 *===========================================================================*/
1221 PRIVATE void complete_bars()
1223 int i, j, r, bar_nr, reg;
1224 u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
1225 base, size, v32, diff1, diff2;
1226 char *cp, *next;
1227 char memstr[256];
1229 r= env_get_param("memory", memstr, sizeof(memstr));
1230 if (r != OK)
1231 panic("pci", "env_get_param failed", r);
1233 /* Set memgap_low to just above physical memory */
1234 memgap_low= 0;
1235 cp= memstr;
1236 while (*cp != '\0')
1238 base= strtoul(cp, &next, 16);
1239 if (next == cp || *next != ':')
1241 printf("PCI: bad memory environment string '%s'\n",
1242 memstr);
1243 panic(NULL, NULL, NO_NUM);
1245 cp= next+1;
1246 size= strtoul(cp, &next, 16);
1247 if (next == cp || (*next != ',' && *next != '\0'))
1249 printf("PCI: bad memory environment string '%s'\n",
1250 memstr);
1251 panic(NULL, NULL, NO_NUM);
1253 cp= next+1;
1255 if (base+size > memgap_low)
1256 memgap_low= base+size;
1259 memgap_high= 0xfe000000; /* Leave space for the CPU (APIC) */
1261 if (debug)
1263 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1264 memgap_low, memgap_high);
1267 /* Find the lowest memory base */
1268 for (i= 0; i<nr_pcidev; i++)
1270 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1272 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1273 continue;
1274 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1275 continue;
1276 base= pcidev[i].pd_bar[j].pb_base;
1277 size= pcidev[i].pd_bar[j].pb_size;
1279 if (base >= memgap_high)
1280 continue; /* Not in the gap */
1281 if (base+size <= memgap_low)
1282 continue; /* Not in the gap */
1284 /* Reduce the gap by the smallest amount */
1285 diff1= base+size-memgap_low;
1286 diff2= memgap_high-base;
1288 if (diff1 < diff2)
1289 memgap_low= base+size;
1290 else
1291 memgap_high= base;
1295 if (debug)
1297 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1298 memgap_low, memgap_high);
1301 /* Should check main memory size */
1302 if (memgap_high < memgap_low)
1304 printf("PCI: bad memory gap: [0x%x .. 0x%x>\n",
1305 memgap_low, memgap_high);
1306 panic(NULL, NULL, NO_NUM);
1309 iogap_high= 0x10000;
1310 iogap_low= 0x400;
1312 /* Find the free I/O space */
1313 for (i= 0; i<nr_pcidev; i++)
1315 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1317 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1318 continue;
1319 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1320 continue;
1321 base= pcidev[i].pd_bar[j].pb_base;
1322 size= pcidev[i].pd_bar[j].pb_size;
1323 if (base >= iogap_high)
1324 continue;
1325 if (base+size <= iogap_low)
1326 continue;
1327 #if 0
1328 if (debug)
1330 printf(
1331 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
1332 i, pcidev[i].pd_vid, pcidev[i].pd_did,
1333 j, base, size);
1335 #endif
1336 if (base+size-iogap_low < iogap_high-base)
1337 iogap_low= base+size;
1338 else
1339 iogap_high= base;
1343 if (iogap_high < iogap_low)
1345 if (debug)
1347 printf("iogap_high too low, should panic\n");
1349 else
1350 panic("pci", "iogap_high too low", iogap_high);
1352 if (debug)
1353 printf("I/O range = [0x%x..0x%x>\n", iogap_low, iogap_high);
1355 for (i= 0; i<nr_pcidev; i++)
1357 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1359 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1360 continue;
1361 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1362 continue;
1363 size= pcidev[i].pd_bar[j].pb_size;
1364 if (size < PAGE_SIZE)
1365 size= PAGE_SIZE;
1366 base= memgap_high-size;
1367 base &= ~(u32_t)(size-1);
1368 if (base < memgap_low)
1369 panic("pci", "memory base too low", base);
1370 memgap_high= base;
1371 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1372 reg= PCI_BAR + 4*bar_nr;
1373 v32= pci_attr_r32(i, reg);
1374 pci_attr_w32(i, reg, v32 | base);
1375 if (debug)
1377 printf(
1378 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1379 base, size, pcidev[i].pd_busnr,
1380 pcidev[i].pd_dev, pcidev[i].pd_func,
1381 bar_nr);
1383 pcidev[i].pd_bar[j].pb_base= base;
1384 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1387 io_high= iogap_high;
1388 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1390 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1391 continue;
1392 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1393 continue;
1394 size= pcidev[i].pd_bar[j].pb_size;
1395 base= iogap_high-size;
1396 base &= ~(u32_t)(size-1);
1398 /* Assume that ISA compatibility is required. Only
1399 * use the lowest 256 bytes out of every 1024 bytes.
1401 base &= 0xfcff;
1403 if (base < iogap_low)
1404 panic("pci", "I/O base too low", base);
1406 iogap_high= base;
1407 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1408 reg= PCI_BAR + 4*bar_nr;
1409 v32= pci_attr_r32(i, reg);
1410 pci_attr_w32(i, reg, v32 | base);
1411 if (debug)
1413 printf(
1414 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1415 base, size, pcidev[i].pd_busnr,
1416 pcidev[i].pd_dev, pcidev[i].pd_func,
1417 bar_nr);
1419 pcidev[i].pd_bar[j].pb_base= base;
1420 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1423 if (iogap_high != io_high)
1425 update_bridge4dev_io(i, iogap_high,
1426 io_high-iogap_high);
1430 for (i= 0; i<nr_pcidev; i++)
1432 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1434 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1435 continue;
1436 printf("should allocate resources for device %d\n", i);
1441 /*===========================================================================*
1442 * update_bridge4dev_io *
1443 *===========================================================================*/
1444 PRIVATE void update_bridge4dev_io(devind, io_base, io_size)
1445 int devind;
1446 u32_t io_base;
1447 u32_t io_size;
1449 int busnr, busind, type, br_devind;
1450 u16_t v16;
1452 busnr= pcidev[devind].pd_busnr;
1453 busind= get_busind(busnr);
1454 type= pcibus[busind].pb_type;
1455 if (type == PBT_INTEL_HOST)
1456 return; /* Nothing to do for host controller */
1457 if (type == PBT_PCIBRIDGE)
1459 printf(
1460 "update_bridge4dev_io: not implemented for PCI bridges\n");
1461 return;
1463 if (type != PBT_CARDBUS)
1464 panic("pci", "update_bridge4dev_io: strange bus type", type);
1466 if (debug)
1468 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1469 io_size, io_base);
1471 br_devind= pcibus[busind].pb_devind;
1472 pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
1473 pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
1475 /* Enable I/O access. Enable busmaster access as well. */
1476 v16= pci_attr_r16(devind, PCI_CR);
1477 pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
1480 /*===========================================================================*
1481 * get_freebus *
1482 *===========================================================================*/
1483 PRIVATE int get_freebus()
1485 int i, freebus;
1487 freebus= 1;
1488 for (i= 0; i<nr_pcibus; i++)
1490 if (pcibus[i].pb_needinit)
1491 continue;
1492 if (pcibus[i].pb_type == PBT_INTEL_HOST)
1493 continue;
1494 if (pcibus[i].pb_busnr <= freebus)
1495 freebus= pcibus[i].pb_busnr+1;
1496 printf("get_freebus: should check suboridinate bus number\n");
1498 return freebus;
1501 /*===========================================================================*
1502 * do_isabridge *
1503 *===========================================================================*/
1504 PRIVATE int do_isabridge(busind)
1505 int busind;
1507 int i, j, r, type, busnr, unknown_bridge, bridge_dev;
1508 u16_t vid, did;
1509 u32_t t3;
1510 char *dstr;
1512 unknown_bridge= -1;
1513 bridge_dev= -1;
1514 j= 0; /* lint */
1515 vid= did= 0; /* lint */
1516 busnr= pcibus[busind].pb_busnr;
1517 for (i= 0; i< nr_pcidev; i++)
1519 if (pcidev[i].pd_busnr != busnr)
1520 continue;
1521 t3= ((pcidev[i].pd_baseclass << 16) |
1522 (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
1523 if (t3 == PCI_T3_ISA)
1525 /* ISA bridge. Report if no supported bridge is
1526 * found.
1528 unknown_bridge= i;
1531 vid= pcidev[i].pd_vid;
1532 did= pcidev[i].pd_did;
1533 for (j= 0; pci_isabridge[j].vid != 0; j++)
1535 if (pci_isabridge[j].vid != vid)
1536 continue;
1537 if (pci_isabridge[j].did != did)
1538 continue;
1539 if (pci_isabridge[j].checkclass &&
1540 unknown_bridge != i)
1542 /* This part of multifunction device is
1543 * not the bridge.
1545 continue;
1547 break;
1549 if (pci_isabridge[j].vid)
1551 bridge_dev= i;
1552 break;
1556 if (bridge_dev != -1)
1558 dstr= pci_dev_name(vid, did);
1559 if (!dstr)
1560 dstr= "unknown device";
1561 if (debug)
1563 printf("found ISA bridge (%04X/%04X) %s\n",
1564 vid, did, dstr);
1566 pcibus[busind].pb_isabridge_dev= bridge_dev;
1567 type= pci_isabridge[j].type;
1568 pcibus[busind].pb_isabridge_type= type;
1569 switch(type)
1571 case PCI_IB_PIIX:
1572 r= do_piix(bridge_dev);
1573 break;
1574 case PCI_IB_VIA:
1575 r= do_via_isabr(bridge_dev);
1576 break;
1577 case PCI_IB_AMD:
1578 r= do_amd_isabr(bridge_dev);
1579 break;
1580 case PCI_IB_SIS:
1581 r= do_sis_isabr(bridge_dev);
1582 break;
1583 default:
1584 panic("PCI","unknown ISA bridge type", type);
1586 return r;
1589 if (unknown_bridge == -1)
1591 if (debug)
1593 printf("(warning) no ISA bridge found on bus %d\n",
1594 busind);
1596 return 0;
1598 if (debug)
1600 printf(
1601 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
1602 pcidev[unknown_bridge].pd_vid,
1603 pcidev[unknown_bridge].pd_did, busind);
1605 return 0;
1608 /*===========================================================================*
1609 * do_pcibridge *
1610 *===========================================================================*/
1611 PRIVATE void do_pcibridge(busind)
1612 int busind;
1614 int i, devind, busnr;
1615 int ind, type;
1616 u16_t vid, did;
1617 u8_t sbusn, baseclass, subclass, infclass, headt;
1618 u32_t t3;
1620 vid= did= 0; /* lint */
1621 busnr= pcibus[busind].pb_busnr;
1622 for (devind= 0; devind< nr_pcidev; devind++)
1624 #if 0
1625 printf("do_pcibridge: trying %u.%u.%u\n",
1626 pcidev[devind].pd_busind, pcidev[devind].pd_dev,
1627 pcidev[devind].pd_func);
1628 #endif
1630 if (pcidev[devind].pd_busnr != busnr)
1632 #if 0
1633 printf("wrong bus\n");
1634 #endif
1635 continue;
1638 vid= pcidev[devind].pd_vid;
1639 did= pcidev[devind].pd_did;
1640 for (i= 0; pci_pcibridge[i].vid != 0; i++)
1642 if (pci_pcibridge[i].vid != vid)
1643 continue;
1644 if (pci_pcibridge[i].did != did)
1645 continue;
1646 break;
1648 type= pci_pcibridge[i].type;
1649 if (pci_pcibridge[i].vid == 0)
1651 headt= pci_attr_r8(devind, PCI_HEADT);
1652 type= 0;
1653 if ((headt & PHT_MASK) == PHT_BRIDGE)
1654 type= PCI_PPB_STD;
1655 else if ((headt & PHT_MASK) == PHT_CARDBUS)
1656 type= PCI_PPB_CB;
1657 else
1659 #if 0
1660 printf("not a bridge\n");
1661 #endif
1662 continue; /* Not a bridge */
1665 baseclass= pci_attr_r8(devind, PCI_BCR);
1666 subclass= pci_attr_r8(devind, PCI_SCR);
1667 infclass= pci_attr_r8(devind, PCI_PIFR);
1668 t3= ((baseclass << 16) | (subclass << 8) | infclass);
1669 if (type == PCI_PPB_STD &&
1670 t3 != PCI_T3_PCI2PCI &&
1671 t3 != PCI_T3_PCI2PCI_SUBTR)
1673 printf(
1674 "Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
1675 baseclass, subclass, infclass,
1676 vid, did);
1677 continue;
1679 if (type == PCI_PPB_CB &&
1680 t3 != PCI_T3_CARDBUS)
1682 printf(
1683 "Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
1684 baseclass, subclass, infclass,
1685 vid, did);
1686 continue;
1690 if (debug)
1692 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
1693 pcidev[devind].pd_busnr,
1694 pcidev[devind].pd_dev,
1695 pcidev[devind].pd_func, vid, did);
1698 /* Assume that the BIOS initialized the secondary bus
1699 * number.
1701 sbusn= pci_attr_r8(devind, PPB_SECBN);
1702 #if DEBUG
1703 printf("sbusn = %d\n", sbusn);
1704 printf("subordn = %d\n", pci_attr_r8(devind, PPB_SUBORDBN));
1705 #endif
1707 if (nr_pcibus >= NR_PCIBUS)
1708 panic("PCI","too many PCI busses", nr_pcibus);
1709 ind= nr_pcibus;
1710 nr_pcibus++;
1711 pcibus[ind].pb_type= PBT_PCIBRIDGE;
1712 pcibus[ind].pb_needinit= 1;
1713 pcibus[ind].pb_isabridge_dev= -1;
1714 pcibus[ind].pb_isabridge_type= 0;
1715 pcibus[ind].pb_devind= devind;
1716 pcibus[ind].pb_busnr= sbusn;
1717 pcibus[ind].pb_rreg8= pcibus[busind].pb_rreg8;
1718 pcibus[ind].pb_rreg16= pcibus[busind].pb_rreg16;
1719 pcibus[ind].pb_rreg32= pcibus[busind].pb_rreg32;
1720 pcibus[ind].pb_wreg8= pcibus[busind].pb_wreg8;
1721 pcibus[ind].pb_wreg16= pcibus[busind].pb_wreg16;
1722 pcibus[ind].pb_wreg32= pcibus[busind].pb_wreg32;
1723 switch(type)
1725 case PCI_PPB_STD:
1726 pcibus[ind].pb_rsts= pcibr_std_rsts;
1727 pcibus[ind].pb_wsts= pcibr_std_wsts;
1728 break;
1729 case PCI_PPB_CB:
1730 pcibus[ind].pb_type= PBT_CARDBUS;
1731 pcibus[ind].pb_rsts= pcibr_cb_rsts;
1732 pcibus[ind].pb_wsts= pcibr_cb_wsts;
1733 break;
1734 case PCI_AGPB_VIA:
1735 pcibus[ind].pb_rsts= pcibr_via_rsts;
1736 pcibus[ind].pb_wsts= pcibr_via_wsts;
1737 break;
1738 default:
1739 panic("PCI","unknown PCI-PCI bridge type", type);
1741 if (sbusn == 0)
1743 printf("Secondary bus number not initialized\n");
1744 continue;
1746 pcibus[ind].pb_needinit= 0;
1748 probe_bus(ind);
1750 /* Look for PCI bridges */
1751 do_pcibridge(ind);
1755 /*===========================================================================*
1756 * get_busind *
1757 *===========================================================================*/
1758 PRIVATE int get_busind(busnr)
1759 int busnr;
1761 int i;
1763 for (i= 0; i<nr_pcibus; i++)
1765 if (pcibus[i].pb_busnr == busnr)
1766 return i;
1768 panic("pci", "get_busind: can't find bus", busnr);
1771 /*===========================================================================*
1772 * do_piix *
1773 *===========================================================================*/
1774 PRIVATE int do_piix(devind)
1775 int devind;
1777 int i, s, dev, func, irqrc, irq;
1778 u32_t elcr1, elcr2, elcr;
1780 #if DEBUG
1781 printf("in piix\n");
1782 #endif
1783 dev= pcidev[devind].pd_dev;
1784 func= pcidev[devind].pd_func;
1785 #if USER_SPACE
1786 if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
1787 printf("Warning, sys_inb failed: %d\n", s);
1788 if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
1789 printf("Warning, sys_inb failed: %d\n", s);
1790 #else
1791 elcr1= inb(PIIX_ELCR1);
1792 elcr2= inb(PIIX_ELCR2);
1793 #endif
1794 elcr= elcr1 | (elcr2 << 8);
1795 for (i= 0; i<4; i++)
1797 irqrc= pci_attr_r8(devind, PIIX_PIRQRCA+i);
1798 if (irqrc & PIIX_IRQ_DI)
1800 if (debug)
1801 printf("INT%c: disabled\n", 'A'+i);
1803 else
1805 irq= irqrc & PIIX_IRQ_MASK;
1806 if (debug)
1807 printf("INT%c: %d\n", 'A'+i, irq);
1808 if (!(elcr & (1 << irq)))
1810 if (debug)
1812 printf(
1813 "(warning) IRQ %d is not level triggered\n",
1814 irq);
1817 irq_mode_pci(irq);
1820 return 0;
1823 /*===========================================================================*
1824 * do_amd_isabr *
1825 *===========================================================================*/
1826 PRIVATE int do_amd_isabr(devind)
1827 int devind;
1829 int i, busnr, dev, func, xdevind, irq, edge;
1830 u8_t levmask;
1831 u16_t pciirq;
1833 /* Find required function */
1834 func= AMD_ISABR_FUNC;
1835 busnr= pcidev[devind].pd_busnr;
1836 dev= pcidev[devind].pd_dev;
1838 /* Fake a device with the required function */
1839 if (nr_pcidev >= NR_PCIDEV)
1840 panic("PCI","too many PCI devices", nr_pcidev);
1841 xdevind= nr_pcidev;
1842 pcidev[xdevind].pd_busnr= busnr;
1843 pcidev[xdevind].pd_dev= dev;
1844 pcidev[xdevind].pd_func= func;
1845 pcidev[xdevind].pd_inuse= 1;
1846 nr_pcidev++;
1848 levmask= pci_attr_r8(xdevind, AMD_ISABR_PCIIRQ_LEV);
1849 pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
1850 for (i= 0; i<4; i++)
1852 edge= (levmask >> i) & 1;
1853 irq= (pciirq >> (4*i)) & 0xf;
1854 if (!irq)
1856 if (debug)
1857 printf("INT%c: disabled\n", 'A'+i);
1859 else
1861 if (debug)
1862 printf("INT%c: %d\n", 'A'+i, irq);
1863 if (edge && debug)
1865 printf(
1866 "(warning) IRQ %d is not level triggered\n",
1867 irq);
1869 irq_mode_pci(irq);
1872 nr_pcidev--;
1873 return 0;
1876 /*===========================================================================*
1877 * do_sis_isabr *
1878 *===========================================================================*/
1879 PRIVATE int do_sis_isabr(devind)
1880 int devind;
1882 int i, dev, func, irq;
1884 dev= pcidev[devind].pd_dev;
1885 func= pcidev[devind].pd_func;
1886 irq= 0; /* lint */
1887 for (i= 0; i<4; i++)
1889 irq= pci_attr_r8(devind, SIS_ISABR_IRQ_A+i);
1890 if (irq & SIS_IRQ_DISABLED)
1892 if (debug)
1893 printf("INT%c: disabled\n", 'A'+i);
1895 else
1897 irq &= SIS_IRQ_MASK;
1898 if (debug)
1899 printf("INT%c: %d\n", 'A'+i, irq);
1900 irq_mode_pci(irq);
1903 return 0;
1906 /*===========================================================================*
1907 * do_via_isabr *
1908 *===========================================================================*/
1909 PRIVATE int do_via_isabr(devind)
1910 int devind;
1912 int i, dev, func, irq, edge;
1913 u8_t levmask;
1915 dev= pcidev[devind].pd_dev;
1916 func= pcidev[devind].pd_func;
1917 levmask= pci_attr_r8(devind, VIA_ISABR_EL);
1918 irq= 0; /* lint */
1919 edge= 0; /* lint */
1920 for (i= 0; i<4; i++)
1922 switch(i)
1924 case 0:
1925 edge= (levmask & VIA_ISABR_EL_INTA);
1926 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R2) >> 4;
1927 break;
1928 case 1:
1929 edge= (levmask & VIA_ISABR_EL_INTB);
1930 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R2);
1931 break;
1932 case 2:
1933 edge= (levmask & VIA_ISABR_EL_INTC);
1934 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R3) >> 4;
1935 break;
1936 case 3:
1937 edge= (levmask & VIA_ISABR_EL_INTD);
1938 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R1) >> 4;
1939 break;
1940 default:
1941 assert(0);
1943 irq &= 0xf;
1944 if (!irq)
1946 if (debug)
1947 printf("INT%c: disabled\n", 'A'+i);
1949 else
1951 if (debug)
1952 printf("INT%c: %d\n", 'A'+i, irq);
1953 if (edge && debug)
1955 printf(
1956 "(warning) IRQ %d is not level triggered\n",
1957 irq);
1959 irq_mode_pci(irq);
1962 return 0;
1966 /*===========================================================================*
1967 * report_vga *
1968 *===========================================================================*/
1969 PRIVATE void report_vga(devind)
1970 int devind;
1972 /* Report the amount of video memory. This is needed by the X11R6
1973 * postinstall script to chmem the X server. Hopefully this can be
1974 * removed when we get virtual memory.
1976 size_t amount, size;
1977 int i;
1979 amount= 0;
1980 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
1982 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
1983 continue;
1984 size= pcidev[devind].pd_bar[i].pb_size;
1985 if (size < amount)
1986 continue;
1987 amount= size;
1989 if (size != 0)
1991 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
1992 pcidev[devind].pd_busnr,
1993 pcidev[devind].pd_dev,
1994 pcidev[devind].pd_func,
1995 amount);
2000 /*===========================================================================*
2001 * pci_vid_name *
2002 *===========================================================================*/
2003 PRIVATE char *pci_vid_name(vid)
2004 u16_t vid;
2006 int i;
2008 for (i= 0; pci_vendor_table[i].name; i++)
2010 if (pci_vendor_table[i].vid == vid)
2011 return pci_vendor_table[i].name;
2013 return "unknown";
2016 /*===========================================================================*
2017 * pci_baseclass_name *
2018 *===========================================================================*/
2019 PRIVATE char *pci_baseclass_name(baseclass)
2020 u8_t baseclass;
2022 int i;
2024 for (i= 0; pci_baseclass_table[i].name; i++)
2026 if (pci_baseclass_table[i].baseclass == baseclass)
2027 return pci_baseclass_table[i].name;
2029 return NULL;
2032 /*===========================================================================*
2033 * pci_subclass_name *
2034 *===========================================================================*/
2035 PRIVATE char *pci_subclass_name(baseclass, subclass, infclass)
2036 u8_t baseclass;
2037 u8_t subclass;
2038 u8_t infclass;
2040 int i;
2042 for (i= 0; pci_subclass_table[i].name; i++)
2044 if (pci_subclass_table[i].baseclass != baseclass)
2045 continue;
2046 if (pci_subclass_table[i].subclass != subclass)
2047 continue;
2048 if (pci_subclass_table[i].infclass != infclass &&
2049 pci_subclass_table[i].infclass != (u16_t)-1)
2051 continue;
2053 return pci_subclass_table[i].name;
2055 return NULL;
2058 /*===========================================================================*
2059 * ntostr *
2060 *===========================================================================*/
2061 PRIVATE void ntostr(n, str, end)
2062 unsigned n;
2063 char **str;
2064 char *end;
2066 char tmpstr[20];
2067 int i;
2069 if (n == 0)
2071 tmpstr[0]= '0';
2072 i= 1;
2074 else
2076 for (i= 0; n; i++)
2078 tmpstr[i]= '0' + (n%10);
2079 n /= 10;
2082 for (; i>0; i--)
2084 if (*str == end)
2086 break;
2088 **str= tmpstr[i-1];
2089 (*str)++;
2091 if (*str == end)
2092 end[-1]= '\0';
2093 else
2094 **str= '\0';
2097 /*===========================================================================*
2098 * pci_attr_rsts *
2099 *===========================================================================*/
2100 PRIVATE u16_t pci_attr_rsts(devind)
2101 int devind;
2103 int busnr, busind;
2105 busnr= pcidev[devind].pd_busnr;
2106 busind= get_busind(busnr);
2107 return pcibus[busind].pb_rsts(busind);
2111 /*===========================================================================*
2112 * pcibr_std_rsts *
2113 *===========================================================================*/
2114 PRIVATE u16_t pcibr_std_rsts(busind)
2115 int busind;
2117 int devind;
2119 devind= pcibus[busind].pb_devind;
2120 return pci_attr_r16(devind, PPB_SSTS);
2123 /*===========================================================================*
2124 * pcibr_std_wsts *
2125 *===========================================================================*/
2126 PRIVATE void pcibr_std_wsts(busind, value)
2127 int busind;
2128 u16_t value;
2130 int devind;
2131 devind= pcibus[busind].pb_devind;
2133 #if 0
2134 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2135 busind, value, devind);
2136 #endif
2137 pci_attr_w16(devind, PPB_SSTS, value);
2140 /*===========================================================================*
2141 * pcibr_cb_rsts *
2142 *===========================================================================*/
2143 PRIVATE u16_t pcibr_cb_rsts(busind)
2144 int busind;
2146 int devind;
2147 devind= pcibus[busind].pb_devind;
2149 return pci_attr_r16(devind, CBB_SSTS);
2152 /*===========================================================================*
2153 * pcibr_cb_wsts *
2154 *===========================================================================*/
2155 PRIVATE void pcibr_cb_wsts(busind, value)
2156 int busind;
2157 u16_t value;
2159 int devind;
2160 devind= pcibus[busind].pb_devind;
2162 #if 0
2163 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2164 busind, value, devind);
2165 #endif
2166 pci_attr_w16(devind, CBB_SSTS, value);
2169 /*===========================================================================*
2170 * pcibr_via_rsts *
2171 *===========================================================================*/
2172 PRIVATE u16_t pcibr_via_rsts(busind)
2173 int busind;
2175 int devind;
2176 devind= pcibus[busind].pb_devind;
2178 return 0;
2181 /*===========================================================================*
2182 * pcibr_via_wsts *
2183 *===========================================================================*/
2184 PRIVATE void pcibr_via_wsts(busind, value)
2185 int busind;
2186 u16_t value;
2188 int devind;
2189 devind= pcibus[busind].pb_devind;
2191 #if 0
2192 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2193 busind, value, devind);
2194 #endif
2197 /*===========================================================================*
2198 * pci_attr_wsts *
2199 *===========================================================================*/
2200 PRIVATE void pci_attr_wsts(devind, value)
2201 int devind;
2202 u16_t value;
2204 int busnr, busind;
2206 busnr= pcidev[devind].pd_busnr;
2207 busind= get_busind(busnr);
2208 pcibus[busind].pb_wsts(busind, value);
2212 /*===========================================================================*
2213 * pcii_rreg8 *
2214 *===========================================================================*/
2215 PRIVATE u8_t pcii_rreg8(busind, devind, port)
2216 int busind;
2217 int devind;
2218 int port;
2220 u8_t v;
2221 int s;
2223 v= PCII_RREG8_(pcibus[busind].pb_busnr,
2224 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2225 port);
2226 #if USER_SPACE
2227 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2228 printf("PCI: warning, sys_outl failed: %d\n", s);
2229 #else
2230 outl(PCII_CONFADD, PCII_UNSEL);
2231 #endif
2232 #if 0
2233 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2234 busind, devind, port,
2235 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2236 pcidev[devind].pd_func, v);
2237 #endif
2238 return v;
2241 /*===========================================================================*
2242 * pcii_rreg16 *
2243 *===========================================================================*/
2244 PRIVATE u16_t pcii_rreg16(busind, devind, port)
2245 int busind;
2246 int devind;
2247 int port;
2249 u16_t v;
2250 int s;
2252 v= PCII_RREG16_(pcibus[busind].pb_busnr,
2253 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2254 port);
2255 #if USER_SPACE
2256 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2257 printf("PCI: warning, sys_outl failed: %d\n");
2258 #else
2259 outl(PCII_CONFADD, PCII_UNSEL);
2260 #endif
2261 #if 0
2262 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2263 busind, devind, port,
2264 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2265 pcidev[devind].pd_func, v);
2266 #endif
2267 return v;
2270 /*===========================================================================*
2271 * pcii_rreg32 *
2272 *===========================================================================*/
2273 PRIVATE u32_t pcii_rreg32(busind, devind, port)
2274 int busind;
2275 int devind;
2276 int port;
2278 u32_t v;
2279 int s;
2281 v= PCII_RREG32_(pcibus[busind].pb_busnr,
2282 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2283 port);
2284 #if USER_SPACE
2285 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2286 printf("PCI: warning, sys_outl failed: %d\n", s);
2287 #else
2288 outl(PCII_CONFADD, PCII_UNSEL);
2289 #endif
2290 #if 0
2291 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2292 busind, devind, port,
2293 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2294 pcidev[devind].pd_func, v);
2295 #endif
2296 return v;
2299 /*===========================================================================*
2300 * pcii_wreg8 *
2301 *===========================================================================*/
2302 PRIVATE void pcii_wreg8(busind, devind, port, value)
2303 int busind;
2304 int devind;
2305 int port;
2306 u8_t value;
2308 int s;
2309 #if 0
2310 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2311 busind, devind, port, value,
2312 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2313 pcidev[devind].pd_func);
2314 #endif
2315 PCII_WREG8_(pcibus[busind].pb_busnr,
2316 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2317 port, value);
2318 #if USER_SPACE
2319 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2320 printf("PCI: warning, sys_outl failed: %d\n", s);
2321 #else
2322 outl(PCII_CONFADD, PCII_UNSEL);
2323 #endif
2326 /*===========================================================================*
2327 * pcii_wreg16 *
2328 *===========================================================================*/
2329 PRIVATE void pcii_wreg16(busind, devind, port, value)
2330 int busind;
2331 int devind;
2332 int port;
2333 u16_t value;
2335 int s;
2336 #if 0
2337 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2338 busind, devind, port, value,
2339 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2340 pcidev[devind].pd_func);
2341 #endif
2342 PCII_WREG16_(pcibus[busind].pb_busnr,
2343 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2344 port, value);
2345 #if USER_SPACE
2346 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2347 printf("PCI: warning, sys_outl failed: %d\n", s);
2348 #else
2349 outl(PCII_CONFADD, PCII_UNSEL);
2350 #endif
2353 /*===========================================================================*
2354 * pcii_wreg32 *
2355 *===========================================================================*/
2356 PRIVATE void pcii_wreg32(busind, devind, port, value)
2357 int busind;
2358 int devind;
2359 int port;
2360 u32_t value;
2362 int s;
2363 #if 0
2364 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2365 busind, devind, port, value,
2366 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2367 pcidev[devind].pd_func);
2368 #endif
2369 PCII_WREG32_(pcibus[busind].pb_busnr,
2370 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2371 port, value);
2372 #if USER_SPACE
2373 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2374 printf("PCI: warning, sys_outl failed: %d\n");
2375 #else
2376 outl(PCII_CONFADD, PCII_UNSEL);
2377 #endif
2380 /*===========================================================================*
2381 * pcii_rsts *
2382 *===========================================================================*/
2383 PRIVATE u16_t pcii_rsts(busind)
2384 int busind;
2386 u16_t v;
2387 int s;
2389 v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
2390 #if USER_SPACE
2391 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2392 printf("PCI: warning, sys_outl failed: %d\n", s);
2393 #else
2394 outl(PCII_CONFADD, PCII_UNSEL);
2395 #endif
2396 return v;
2399 /*===========================================================================*
2400 * pcii_wsts *
2401 *===========================================================================*/
2402 PRIVATE void pcii_wsts(busind, value)
2403 int busind;
2404 u16_t value;
2406 int s;
2407 PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
2408 #if USER_SPACE
2409 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2410 printf("PCI: warning, sys_outl failed: %d\n", s);
2411 #else
2412 outl(PCII_CONFADD, PCII_UNSEL);
2413 #endif
2417 /*===========================================================================*
2418 * print_capabilities *
2419 *===========================================================================*/
2420 PRIVATE void print_capabilities(devind)
2421 int devind;
2423 u8_t status, capptr, type, next;
2424 char *str;
2426 /* Check capabilities bit in the device status register */
2427 status= pci_attr_r16(devind, PCI_SR);
2428 if (!(status & PSR_CAPPTR))
2429 return;
2431 capptr= (pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK);
2432 while (capptr != 0)
2434 type = pci_attr_r8(devind, capptr+CAP_TYPE);
2435 next= (pci_attr_r8(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
2436 switch(type)
2438 case 1: str= "PCI Power Management"; break;
2439 case 2: str= "AGP"; break;
2440 case 3: str= "Vital Product Data"; break;
2441 case 4: str= "Slot Identification"; break;
2442 case 5: str= "Message Signaled Interrupts"; break;
2443 case 6: str= "CompactPCI Hot Swap"; break;
2444 case 8: str= "AMD HyperTransport"; break;
2445 case 0xf: str= "AMD I/O MMU"; break;
2446 defuault: str= "(unknown type)"; break;
2449 printf(" @0x%x: capability type 0x%x: %s\n",
2450 capptr, type, str);
2451 capptr= next;
2456 /*===========================================================================*
2457 * visible *
2458 *===========================================================================*/
2459 PRIVATE int visible(aclp, devind)
2460 struct rs_pci *aclp;
2461 int devind;
2463 int i;
2464 u32_t class_id;
2466 if (!aclp)
2467 return TRUE; /* Should be changed when ACLs become
2468 * mandatory.
2470 /* Check whether the caller is allowed to get this device. */
2471 for (i= 0; i<aclp->rsp_nr_device; i++)
2473 if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
2474 aclp->rsp_device[i].did == pcidev[devind].pd_did)
2476 return TRUE;
2479 if (!aclp->rsp_nr_class)
2480 return FALSE;
2482 class_id= (pcidev[devind].pd_baseclass << 16) |
2483 (pcidev[devind].pd_subclass << 8) |
2484 pcidev[devind].pd_infclass;
2485 for (i= 0; i<aclp->rsp_nr_class; i++)
2487 if (aclp->rsp_class[i].class ==
2488 (class_id & aclp->rsp_class[i].mask))
2490 return TRUE;
2494 return FALSE;
2498 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $