source: trunk/minix/drivers/pci/pci.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 58.3 KB
RevLine 
[9]1#define USER_SPACE 1
2/*
3pci.c
4
5Configure devices on the PCI bus
6
7Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
8*/
9
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/syslib.h>
17
18#include "pci.h"
19#include "pci_amd.h"
20#include "pci_intel.h"
21#include "pci_sis.h"
22#include "pci_via.h"
23#if __minix_vmd
24#include "config.h"
25#endif
26
27#if !__minix_vmd
28#define irq_mode_pci(irq) ((void)0)
29#endif
30
31#include <stdlib.h>
32#include <stdio.h>
33#include <string.h>
34#include <minix/sysutil.h>
35
36#define NR_PCIBUS 10
37#define NR_PCIDEV 40
38
39#define PBT_INTEL_HOST 1
40#define PBT_PCIBRIDGE 2
41#define PBT_CARDBUS 3
42
43#define BAM_NR 6 /* Number of base-address registers */
44
45PRIVATE int debug= 0;
46
47PRIVATE struct pcibus
48{
49 int pb_type;
50 int pb_needinit;
51 int pb_isabridge_dev;
52 int pb_isabridge_type;
53
54 int pb_devind;
55 int pb_busnr;
56 u8_t (*pb_rreg8)(int busind, int devind, int port);
57 u16_t (*pb_rreg16)(int busind, int devind, int port);
58 u32_t (*pb_rreg32)(int busind, int devind, int port);
59 void (*pb_wreg8)(int busind, int devind, int port, U8_t value);
60 void (*pb_wreg16)(int busind, int devind, int port, U16_t value);
61 void (*pb_wreg32)(int busind, int devind, int port, u32_t value);
62 u16_t (*pb_rsts)(int busind);
63 void (*pb_wsts)(int busind, U16_t value);
64} pcibus[NR_PCIBUS];
65PRIVATE int nr_pcibus= 0;
66
67PRIVATE struct pcidev
68{
69 u8_t pd_busnr;
70 u8_t pd_dev;
71 u8_t pd_func;
72 u8_t pd_baseclass;
73 u8_t pd_subclass;
74 u8_t pd_infclass;
75 u16_t pd_vid;
76 u16_t pd_did;
77 u8_t pd_ilr;
78 u8_t pd_inuse;
79
80 struct bar
81 {
82 int pb_flags;
83 int pb_nr;
84 u32_t pb_base;
85 u32_t pb_size;
86 } pd_bar[BAM_NR];
87 int pd_bar_nr;
88
89 char pd_name[M3_STRING];
90} pcidev[NR_PCIDEV];
91
92/* pb_flags */
93#define PBF_IO 1 /* I/O else memory */
94#define PBF_INCOMPLETE 2 /* not allocated */
95
96PRIVATE int nr_pcidev= 0;
97
98/* Work around the limitations of the PCI emulation in QEMU 0.7.1 */
99PRIVATE int qemu_pci= 0;
100
101FORWARD _PROTOTYPE( void pci_intel_init, (void) );
102FORWARD _PROTOTYPE( void probe_bus, (int busind) );
103FORWARD _PROTOTYPE( int is_duplicate, (U8_t busnr, U8_t dev, U8_t func) );
104FORWARD _PROTOTYPE( void record_irq, (int devind) );
105FORWARD _PROTOTYPE( void record_bars, (int devind) );
106FORWARD _PROTOTYPE( void record_bars_bridge, (int devind) );
107FORWARD _PROTOTYPE( void record_bars_cardbus, (int devind) );
108FORWARD _PROTOTYPE( void record_bar, (int devind, int bar_nr) );
109FORWARD _PROTOTYPE( void complete_bridges, (void) );
110FORWARD _PROTOTYPE( void complete_bars, (void) );
111FORWARD _PROTOTYPE( void update_bridge4dev_io, (int devind,
112 u32_t io_base, u32_t io_size) );
113FORWARD _PROTOTYPE( int get_freebus, (void) );
114FORWARD _PROTOTYPE( int do_isabridge, (int busind) );
115FORWARD _PROTOTYPE( void do_pcibridge, (int busind) );
116FORWARD _PROTOTYPE( int get_busind, (int busnr) );
117FORWARD _PROTOTYPE( int do_piix, (int devind) );
118FORWARD _PROTOTYPE( int do_amd_isabr, (int devind) );
119FORWARD _PROTOTYPE( int do_sis_isabr, (int devind) );
120FORWARD _PROTOTYPE( int do_via_isabr, (int devind) );
121FORWARD _PROTOTYPE( void report_vga, (int devind) );
122FORWARD _PROTOTYPE( char *pci_vid_name, (U16_t vid) );
123FORWARD _PROTOTYPE( char *pci_baseclass_name, (U8_t baseclass) );
124FORWARD _PROTOTYPE( char *pci_subclass_name, (U8_t baseclass,
125 U8_t subclass, U8_t infclass) );
126FORWARD _PROTOTYPE( void ntostr, (unsigned n, char **str, char *end) );
127FORWARD _PROTOTYPE( u16_t pci_attr_rsts, (int devind) );
128FORWARD _PROTOTYPE( void pci_attr_wsts, (int devind, U16_t value) );
129FORWARD _PROTOTYPE( u16_t pcibr_std_rsts, (int busind) );
130FORWARD _PROTOTYPE( void pcibr_std_wsts, (int busind, U16_t value) );
131FORWARD _PROTOTYPE( u16_t pcibr_cb_rsts, (int busind) );
132FORWARD _PROTOTYPE( void pcibr_cb_wsts, (int busind, U16_t value) );
133FORWARD _PROTOTYPE( u16_t pcibr_via_rsts, (int busind) );
134FORWARD _PROTOTYPE( void pcibr_via_wsts, (int busind, U16_t value) );
135FORWARD _PROTOTYPE( u8_t pcii_rreg8, (int busind, int devind, int port) );
136FORWARD _PROTOTYPE( u16_t pcii_rreg16, (int busind, int devind,
137 int port) );
138FORWARD _PROTOTYPE( u32_t pcii_rreg32, (int busind, int devind,
139 int port) );
140FORWARD _PROTOTYPE( void pcii_wreg8, (int busind, int devind, int port,
141 U8_t value) );
142FORWARD _PROTOTYPE( void pcii_wreg16, (int busind, int devind, int port,
143 U16_t value) );
144FORWARD _PROTOTYPE( void pcii_wreg32, (int busind, int devind, int port,
145 u32_t value) );
146FORWARD _PROTOTYPE( u16_t pcii_rsts, (int busind) );
147FORWARD _PROTOTYPE( void pcii_wsts, (int busind, U16_t value) );
148FORWARD _PROTOTYPE( void print_capabilities, (int devind) );
149
150/*===========================================================================*
151 * helper functions for I/O *
152 *===========================================================================*/
153PUBLIC unsigned pci_inb(U16_t port) {
154 u32_t value;
155 int s;
156 if ((s=sys_inb(port, &value)) !=OK)
157 printf("PCI: warning, sys_inb failed: %d\n", s);
158 return value;
159}
160PUBLIC unsigned pci_inw(U16_t port) {
161 u32_t value;
162 int s;
163 if ((s=sys_inw(port, &value)) !=OK)
164 printf("PCI: warning, sys_inw failed: %d\n", s);
165 return value;
166}
167PUBLIC unsigned pci_inl(U16_t port) {
168 U32_t value;
169 int s;
170 if ((s=sys_inl(port, &value)) !=OK)
171 printf("PCI: warning, sys_inl failed: %d\n", s);
172 return value;
173}
174PUBLIC void pci_outb(U16_t port, U8_t value) {
175 int s;
176 if ((s=sys_outb(port, value)) !=OK)
177 printf("PCI: warning, sys_outb failed: %d\n", s);
178}
179PUBLIC void pci_outw(U16_t port, U16_t value) {
180 int s;
181 if ((s=sys_outw(port, value)) !=OK)
182 printf("PCI: warning, sys_outw failed: %d\n", s);
183}
184PUBLIC void pci_outl(U16_t port, U32_t value) {
185 int s;
186 if ((s=sys_outl(port, value)) !=OK)
187 printf("PCI: warning, sys_outl failed: %d\n", s);
188}
189
190/*===========================================================================*
191 * pci_init *
192 *===========================================================================*/
193PUBLIC void pci_init()
194{
195 static int first_time= 1;
196
197 long v;
198
199 if (!first_time)
200 return;
201
202 v= 0;
203 env_parse("qemu_pci", "d", 0, &v, 0, 1);
204 qemu_pci= v;
205
206 v= 0;
207 env_parse("pci_debug", "d", 0, &v, 0, 1);
208 debug= v;
209
210 /* We don't expect to interrupted */
211 assert(first_time == 1);
212 first_time= -1;
213
214 /* Only Intel (compatible) PCI controllers are supported at the
215 * moment.
216 */
217 pci_intel_init();
218
219 first_time= 0;
220}
221
222/*===========================================================================*
223 * pci_find_dev *
224 *===========================================================================*/
225PUBLIC int pci_find_dev(bus, dev, func, devindp)
226u8_t bus;
227u8_t dev;
228u8_t func;
229int *devindp;
230{
231 int devind;
232
233 for (devind= 0; devind < nr_pcidev; devind++)
234 {
235 if (pcidev[devind].pd_busnr == bus &&
236 pcidev[devind].pd_dev == dev &&
237 pcidev[devind].pd_func == func)
238 {
239 break;
240 }
241 }
242 if (devind >= nr_pcidev)
243 return 0;
244 if (pcidev[devind].pd_inuse)
245 return 0;
246 *devindp= devind;
247 return 1;
248}
249
250/*===========================================================================*
251 * pci_first_dev *
252 *===========================================================================*/
253PUBLIC int pci_first_dev(devindp, vidp, didp)
254int *devindp;
255u16_t *vidp;
256u16_t *didp;
257{
258 int devind;
259
260 for (devind= 0; devind < nr_pcidev; devind++)
261 {
262 if (!pcidev[devind].pd_inuse)
263 break;
264 }
265 if (devind >= nr_pcidev)
266 return 0;
267 *devindp= devind;
268 *vidp= pcidev[devind].pd_vid;
269 *didp= pcidev[devind].pd_did;
270 return 1;
271}
272
273/*===========================================================================*
274 * pci_next_dev *
275 *===========================================================================*/
276PUBLIC int pci_next_dev(devindp, vidp, didp)
277int *devindp;
278u16_t *vidp;
279u16_t *didp;
280{
281 int devind;
282
283 for (devind= *devindp+1; devind < nr_pcidev; devind++)
284 {
285 if (!pcidev[devind].pd_inuse)
286 break;
287 }
288 if (devind >= nr_pcidev)
289 return 0;
290 *devindp= devind;
291 *vidp= pcidev[devind].pd_vid;
292 *didp= pcidev[devind].pd_did;
293 return 1;
294}
295
296/*===========================================================================*
297 * pci_reserve3 *
298 *===========================================================================*/
299PUBLIC void pci_reserve3(devind, proc, name)
300int devind;
301int proc;
302char *name;
303{
304 int i, r;
305 u8_t ilr;
306 struct io_range ior;
307 struct mem_range mr;
308
309 assert(devind <= nr_pcidev);
310 assert(!pcidev[devind].pd_inuse);
311 pcidev[devind].pd_inuse= 1;
312 strcpy(pcidev[devind].pd_name, name);
313
314 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
315 {
316 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
317 {
318 printf("pci_reserve3: BAR %d is incomplete\n", i);
319 continue;
320 }
321 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
322 {
323 ior.ior_base= pcidev[devind].pd_bar[i].pb_base;
324 ior.ior_limit= ior.ior_base +
325 pcidev[devind].pd_bar[i].pb_size-1;
326
327 if(debug) {
328 printf(
329 "pci_reserve3: for proc %d, adding I/O range [0x%x..0x%x]\n",
330 proc, ior.ior_base, ior.ior_limit);
331 }
332 r= sys_privctl(proc, SYS_PRIV_ADD_IO, 0, &ior);
333 if (r != OK)
334 {
335 printf("sys_privctl failed for proc %d: %d\n",
336 proc, r);
337 }
338 }
339 else
340 {
341 mr.mr_base= pcidev[devind].pd_bar[i].pb_base;
342 mr.mr_limit= mr.mr_base +
343 pcidev[devind].pd_bar[i].pb_size-1;
344
345 if(debug) {
346 printf(
347 "pci_reserve3: for proc %d, should add memory range [0x%x..0x%x]\n",
348 proc, mr.mr_base, mr.mr_limit);
349 }
350 r= sys_privctl(proc, SYS_PRIV_ADD_MEM, 0, &mr);
351 if (r != OK)
352 {
353 printf("sys_privctl failed for proc %d: %d\n",
354 proc, r);
355 }
356 }
357 }
358 ilr= pcidev[devind].pd_ilr;
359 if (ilr != PCI_ILR_UNKNOWN)
360 {
361 if(debug) printf("pci_reserve3: adding IRQ %d\n", ilr);
362 r= sys_privctl(proc, SYS_PRIV_ADD_IRQ, ilr, NULL);
363 if (r != OK)
364 {
365 printf("sys_privctl failed for proc %d: %d\n",
366 proc, r);
367 }
368 }
369}
370
371/*===========================================================================*
372 * pci_release *
373 *===========================================================================*/
374PUBLIC void pci_release(name)
375char *name;
376{
377 int i;
378
379 for (i= 0; i<nr_pcidev; i++)
380 {
381 if (!pcidev[i].pd_inuse)
382 continue;
383 if (strcmp(pcidev[i].pd_name, name) != 0)
384 continue;
385 pcidev[i].pd_inuse= 0;
386 }
387}
388
389/*===========================================================================*
390 * pci_ids *
391 *===========================================================================*/
392PUBLIC void pci_ids(devind, vidp, didp)
393int devind;
394u16_t *vidp;
395u16_t *didp;
396{
397 assert(devind <= nr_pcidev);
398 *vidp= pcidev[devind].pd_vid;
399 *didp= pcidev[devind].pd_did;
400}
401
402/*===========================================================================*
403 * pci_rescan_bus *
404 *===========================================================================*/
405PUBLIC void pci_rescan_bus(busnr)
406u8_t busnr;
407{
408 int busind;
409
410 busind= get_busind(busnr);
411 probe_bus(busind);
412
413 /* Allocate bus numbers for uninitialized bridges */
414 complete_bridges();
415
416 /* Allocate I/O and memory resources for uninitialized devices */
417 complete_bars();
418}
419
420/*===========================================================================*
421 * pci_slot_name *
422 *===========================================================================*/
423PUBLIC char *pci_slot_name(devind)
424int devind;
425{
426 static char label[]= "ddd.ddd.ddd";
427 char *end;
428 char *p;
429
430 p= label;
431 end= label+sizeof(label);
432
433 ntostr(pcidev[devind].pd_busnr, &p, end);
434 *p++= '.';
435
436 ntostr(pcidev[devind].pd_dev, &p, end);
437 *p++= '.';
438
439 ntostr(pcidev[devind].pd_func, &p, end);
440
441 return label;
442}
443
444/*===========================================================================*
445 * pci_dev_name *
446 *===========================================================================*/
447PUBLIC char *pci_dev_name(vid, did)
448u16_t vid;
449u16_t did;
450{
451 int i;
452
453 for (i= 0; pci_device_table[i].name; i++)
454 {
455 if (pci_device_table[i].vid == vid &&
456 pci_device_table[i].did == did)
457 {
458 return pci_device_table[i].name;
459 }
460 }
461 return NULL;
462}
463
464/*===========================================================================*
465 * pci_attr_r8 *
466 *===========================================================================*/
467PUBLIC u8_t pci_attr_r8(devind, port)
468int devind;
469int port;
470{
471 int busnr, busind;
472
473 busnr= pcidev[devind].pd_busnr;
474 busind= get_busind(busnr);
475 return pcibus[busind].pb_rreg8(busind, devind, port);
476}
477
478/*===========================================================================*
479 * pci_attr_r16 *
480 *===========================================================================*/
481PUBLIC u16_t pci_attr_r16(devind, port)
482int devind;
483int port;
484{
485 int busnr, busind;
486
487 busnr= pcidev[devind].pd_busnr;
488 busind= get_busind(busnr);
489 return pcibus[busind].pb_rreg16(busind, devind, port);
490}
491
492/*===========================================================================*
493 * pci_attr_r32 *
494 *===========================================================================*/
495PUBLIC u32_t pci_attr_r32(devind, port)
496int devind;
497int port;
498{
499 int busnr, busind;
500
501 busnr= pcidev[devind].pd_busnr;
502 busind= get_busind(busnr);
503 return pcibus[busind].pb_rreg32(busind, devind, port);
504}
505
506/*===========================================================================*
507 * pci_attr_w8 *
508 *===========================================================================*/
509PUBLIC void pci_attr_w8(devind, port, value)
510int devind;
511int port;
512u16_t value;
513{
514 int busnr, busind;
515
516 busnr= pcidev[devind].pd_busnr;
517 busind= get_busind(busnr);
518 pcibus[busind].pb_wreg8(busind, devind, port, value);
519}
520
521/*===========================================================================*
522 * pci_attr_w16 *
523 *===========================================================================*/
524PUBLIC void pci_attr_w16(devind, port, value)
525int devind;
526int port;
527u16_t value;
528{
529 int busnr, busind;
530
531 busnr= pcidev[devind].pd_busnr;
532 busind= get_busind(busnr);
533 pcibus[busind].pb_wreg16(busind, devind, port, value);
534}
535
536/*===========================================================================*
537 * pci_attr_w32 *
538 *===========================================================================*/
539PUBLIC void pci_attr_w32(devind, port, value)
540int devind;
541int port;
542u32_t value;
543{
544 int busnr, busind;
545
546 busnr= pcidev[devind].pd_busnr;
547 busind= get_busind(busnr);
548 pcibus[busind].pb_wreg32(busind, devind, port, value);
549}
550
551/*===========================================================================*
552 * pci_intel_init *
553 *===========================================================================*/
554PRIVATE void pci_intel_init()
555{
556 /* Try to detect a know PCI controller. Read the Vendor ID and
557 * the Device ID for function 0 of device 0.
558 * Two times the value 0xffff suggests a system without a (compatible)
559 * PCI controller.
560 */
561 u32_t bus, dev, func;
562 u16_t vid, did;
563 int s, i, r, busind, busnr;
564 char *dstr;
565
566 bus= 0;
567 dev= 0;
568 func= 0;
569
570 vid= PCII_RREG16_(bus, dev, func, PCI_VID);
571 did= PCII_RREG16_(bus, dev, func, PCI_DID);
572#if USER_SPACE
573 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
574 printf("PCI: warning, sys_outl failed: %d\n", s);
575#else
576 outl(PCII_CONFADD, PCII_UNSEL);
577#endif
578
579 if (vid == 0xffff && did == 0xffff)
580 return; /* Nothing here */
581
582#if 0
583 for (i= 0; pci_intel_ctrl[i].vid; i++)
584 {
585 if (pci_intel_ctrl[i].vid == vid &&
586 pci_intel_ctrl[i].did == did)
587 {
588 break;
589 }
590 }
591
592 if (!pci_intel_ctrl[i].vid)
593 {
594 printf("pci_intel_init (warning): unknown PCI-controller:\n"
595 "\tvendor %04X (%s), device %04X\n",
596 vid, pci_vid_name(vid), did);
597 }
598#endif
599
600 if (nr_pcibus >= NR_PCIBUS)
601 panic("PCI","too many PCI busses", nr_pcibus);
602 busind= nr_pcibus;
603 nr_pcibus++;
604 pcibus[busind].pb_type= PBT_INTEL_HOST;
605 pcibus[busind].pb_needinit= 0;
606 pcibus[busind].pb_isabridge_dev= -1;
607 pcibus[busind].pb_isabridge_type= 0;
608 pcibus[busind].pb_devind= -1;
609 pcibus[busind].pb_busnr= 0;
610 pcibus[busind].pb_rreg8= pcii_rreg8;
611 pcibus[busind].pb_rreg16= pcii_rreg16;
612 pcibus[busind].pb_rreg32= pcii_rreg32;
613 pcibus[busind].pb_wreg8= pcii_wreg8;
614 pcibus[busind].pb_wreg16= pcii_wreg16;
615 pcibus[busind].pb_wreg32= pcii_wreg32;
616 pcibus[busind].pb_rsts= pcii_rsts;
617 pcibus[busind].pb_wsts= pcii_wsts;
618
619 dstr= pci_dev_name(vid, did);
620 if (!dstr)
621 dstr= "unknown device";
622 if (debug)
623 {
624 printf("pci_intel_init: %s (%04X/%04X)\n",
625 dstr, vid, did);
626 }
627
628 probe_bus(busind);
629
630 r= do_isabridge(busind);
631 if (r != OK)
632 {
633 busnr= pcibus[busind].pb_busnr;
634
635 /* Disable all devices for this bus */
636 for (i= 0; i<nr_pcidev; i++)
637 {
638 if (pcidev[i].pd_busnr != busnr)
639 continue;
640 pcidev[i].pd_inuse= 1;
641 }
642 return;
643 }
644
645 /* Look for PCI bridges */
646 do_pcibridge(busind);
647
648 /* Allocate bus numbers for uninitialized bridges */
649 complete_bridges();
650
651 /* Allocate I/O and memory resources for uninitialized devices */
652 complete_bars();
653}
654
655/*===========================================================================*
656 * probe_bus *
657 *===========================================================================*/
658PRIVATE void probe_bus(busind)
659int busind;
660{
661 u32_t dev, func, t3;
662 u16_t vid, did, sts;
663 u8_t headt;
664 u8_t baseclass, subclass, infclass;
665 int devind, busnr;
666 char *s, *dstr;
667
668#if DEBUG
669printf("probe_bus(%d)\n", busind);
670#endif
671 if (nr_pcidev >= NR_PCIDEV)
672 panic("PCI","too many PCI devices", nr_pcidev);
673 devind= nr_pcidev;
674
675 busnr= pcibus[busind].pb_busnr;
676 for (dev= 0; dev<32; dev++)
677 {
678
679 for (func= 0; func < 8; func++)
680 {
681 pcidev[devind].pd_busnr= busnr;
682 pcidev[devind].pd_dev= dev;
683 pcidev[devind].pd_func= func;
684
685 pci_attr_wsts(devind,
686 PSR_SSE|PSR_RMAS|PSR_RTAS);
687 vid= pci_attr_r16(devind, PCI_VID);
688 did= pci_attr_r16(devind, PCI_DID);
689 headt= pci_attr_r8(devind, PCI_HEADT);
690 sts= pci_attr_rsts(devind);
691
692#if 0
693 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
694 vid, did, headt, sts);
695#endif
696
697 if (vid == NO_VID)
698 {
699 if (func == 0)
700 break; /* Nothing here */
701
702 /* Scan all functions of a multifunction
703 * device.
704 */
705 continue;
706 }
707
708 if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
709 {
710 if (qemu_pci)
711 {
712 printf(
713 "pci: ignoring bad value 0x%x in sts for QEMU\n",
714 sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
715 }
716 else
717 {
718 if (func == 0)
719 break; /* Nothing here */
720
721 /* Scan all functions of a
722 * multifunction device.
723 */
724 continue;
725 }
726 }
727
728 dstr= pci_dev_name(vid, did);
729 if (debug)
730 {
731 if (dstr)
732 {
733 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
734 busind, (unsigned long)dev,
735 (unsigned long)func, dstr,
736 vid, did);
737 }
738 else
739 {
740 printf(
741 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
742 busind, (unsigned long)dev,
743 (unsigned long)func, vid,
744 pci_vid_name(vid), did);
745 }
746 printf("Device index: %d\n", devind);
747 printf("Subsystem: Vid 0x%x, did 0x%x\n",
748 pci_attr_r16(devind, PCI_SUBVID),
749 pci_attr_r16(devind, PCI_SUBDID));
750 }
751
752 baseclass= pci_attr_r8(devind, PCI_BCR);
753 subclass= pci_attr_r8(devind, PCI_SCR);
754 infclass= pci_attr_r8(devind, PCI_PIFR);
755 s= pci_subclass_name(baseclass, subclass, infclass);
756 if (!s)
757 s= pci_baseclass_name(baseclass);
758 {
759 if (!s)
760 s= "(unknown class)";
761 }
762 if (debug)
763 {
764 printf("\tclass %s (%X/%X/%X)\n", s,
765 baseclass, subclass, infclass);
766 }
767
768 if (is_duplicate(busnr, dev, func))
769 {
770 printf("\tduplicate!\n");
771 if (func == 0 && !(headt & PHT_MULTIFUNC))
772 break;
773 continue;
774 }
775
776 devind= nr_pcidev;
777 nr_pcidev++;
778 pcidev[devind].pd_baseclass= baseclass;
779 pcidev[devind].pd_subclass= subclass;
780 pcidev[devind].pd_infclass= infclass;
781 pcidev[devind].pd_vid= vid;
782 pcidev[devind].pd_did= did;
783 pcidev[devind].pd_inuse= 0;
784 pcidev[devind].pd_bar_nr= 0;
785 record_irq(devind);
786 switch(headt & PHT_MASK)
787 {
788 case PHT_NORMAL:
789 record_bars(devind);
790 break;
791 case PHT_BRIDGE:
792 record_bars_bridge(devind);
793 break;
794 case PHT_CARDBUS:
795 record_bars_cardbus(devind);
796 break;
797 default:
798 printf("\t%d.%d.%d: unknown header type %d\n",
799 busind, dev, func,
800 headt & PHT_MASK);
801 break;
802 }
803 if (debug)
804 print_capabilities(devind);
805
806 t3= ((baseclass << 16) | (subclass << 8) | infclass);
807 if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
808 report_vga(devind);
809
810 if (nr_pcidev >= NR_PCIDEV)
811 panic("PCI","too many PCI devices", nr_pcidev);
812 devind= nr_pcidev;
813
814 if (func == 0 && !(headt & PHT_MULTIFUNC))
815 break;
816 }
817 }
818}
819
820/*===========================================================================*
821 * is_duplicate *
822 *===========================================================================*/
823PRIVATE int is_duplicate(busnr, dev, func)
824u8_t busnr;
825u8_t dev;
826u8_t func;
827{
828 int i;
829
830 for (i= 0; i<nr_pcidev; i++)
831 {
832 if (pcidev[i].pd_busnr == busnr &&
833 pcidev[i].pd_dev == dev &&
834 pcidev[i].pd_func == func)
835 {
836 return 1;
837 }
838 }
839 return 0;
840}
841
842/*===========================================================================*
843 * record_irq *
844 *===========================================================================*/
845PRIVATE void record_irq(devind)
846int devind;
847{
848 int ilr, ipr, busnr, busind, cb_devind;
849
850 ilr= pci_attr_r8(devind, PCI_ILR);
851 ipr= pci_attr_r8(devind, PCI_IPR);
852 if (ilr == 0)
853 {
854 static int first= 1;
855 if (ipr && first && debug)
856 {
857 first= 0;
858 printf("PCI: strange, BIOS assigned IRQ0\n");
859 }
860 ilr= PCI_ILR_UNKNOWN;
861 }
862 pcidev[devind].pd_ilr= ilr;
863 if (ilr == PCI_ILR_UNKNOWN && !ipr)
864 {
865 }
866 else if (ilr != PCI_ILR_UNKNOWN && ipr)
867 {
868 if (debug)
869 printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
870 }
871 else if (ilr != PCI_ILR_UNKNOWN)
872 {
873 printf(
874 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
875 ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
876 pcidev[devind].pd_func);
877 }
878 else
879 {
880 /* Check for cardbus devices */
881 busnr= pcidev[devind].pd_busnr;
882 busind= get_busind(busnr);
883 if (pcibus[busind].pb_type == PBT_CARDBUS)
884 {
885 cb_devind= pcibus[busind].pb_devind;
886 ilr= pcidev[cb_devind].pd_ilr;
887 if (ilr != PCI_ILR_UNKNOWN)
888 {
889 if (debug)
890 {
891 printf(
892 "assigning IRQ %d to Cardbus device\n",
893 ilr);
894 }
895 pci_attr_w8(devind, PCI_ILR, ilr);
896 pcidev[devind].pd_ilr= ilr;
897 return;
898 }
899 }
900 if(debug) {
901 printf(
902 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
903 pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
904 pcidev[devind].pd_func, 'A' + ipr-1);
905 }
906 }
907}
908
909/*===========================================================================*
910 * record_bars *
911 *===========================================================================*/
912PRIVATE void record_bars(devind)
913int devind;
914{
915 int i, j, reg, prefetch, type, clear_01, clear_23, pb_nr;
916 u32_t bar, bar2;
917
918 for (i= 0, reg= PCI_BAR; reg <= PCI_BAR_6; i++, reg += 4)
919 {
920 record_bar(devind, i);
921 }
922
923 /* Special case code for IDE controllers in compatibility mode */
924 if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
925 pcidev[devind].pd_subclass == PCI_MS_IDE)
926 {
927 /* IDE device */
928 clear_01= 0;
929 clear_23= 0;
930 if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
931 {
932 if (debug)
933 {
934 printf(
935 "primary channel is not in native mode, clearing BARs 0 and 1\n");
936 }
937 clear_01= 1;
938 }
939 if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
940 {
941 if (debug)
942 {
943 printf(
944 "primary channel is not in native mode, clearing BARs 2 and 3\n");
945 }
946 clear_23= 1;
947 }
948
949 j= 0;
950 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
951 {
952 pb_nr= pcidev[devind].pd_bar[i].pb_nr;
953 if ((pb_nr == 0 || pb_nr == 1) && clear_01)
954 {
955 if (debug) printf("skipping bar %d\n", pb_nr);
956 continue; /* Skip */
957 }
958 if ((pb_nr == 2 || pb_nr == 3) && clear_23)
959 {
960 if (debug) printf("skipping bar %d\n", pb_nr);
961 continue; /* Skip */
962 }
963 if (i == j)
964 continue; /* No need to copy */
965 pcidev[devind].pd_bar[j]=
966 pcidev[devind].pd_bar[i];
967 j++;
968 }
969 pcidev[devind].pd_bar_nr= j;
970 }
971}
972
973/*===========================================================================*
974 * record_bars_bridge *
975 *===========================================================================*/
976PRIVATE void record_bars_bridge(devind)
977int devind;
978{
979 u32_t base, limit, size;
980
981 record_bar(devind, 0);
982 record_bar(devind, 1);
983
984 base= ((pci_attr_r8(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
985 (pci_attr_r16(devind, PPB_IOBASEU16) << 16);
986 limit= 0xff |
987 ((pci_attr_r8(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
988 ((~PPB_IOL_MASK & 0xff) << 8) |
989 (pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
990 size= limit-base + 1;
991 if (debug)
992 {
993 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
994 base, limit, size);
995 }
996
997 base= ((pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
998 limit= 0xffff |
999 ((pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
1000 ((~PPB_MEML_MASK & 0xffff) << 16);
1001 size= limit-base + 1;
1002 if (debug)
1003 {
1004 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
1005 base, limit, size);
1006 }
1007
1008 /* Ignore the upper 32 bits */
1009 base= ((pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
1010 limit= 0xffff |
1011 ((pci_attr_r16(devind, PPB_PFMEMLIMIT) &
1012 PPB_PFMEML_MASK) << 16) |
1013 ((~PPB_PFMEML_MASK & 0xffff) << 16);
1014 size= limit-base + 1;
1015 if (debug)
1016 {
1017 printf(
1018 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
1019 base, limit, size);
1020 }
1021}
1022
1023/*===========================================================================*
1024 * record_bars_cardbus *
1025 *===========================================================================*/
1026PRIVATE void record_bars_cardbus(devind)
1027int devind;
1028{
1029 u32_t base, limit, size;
1030
1031 record_bar(devind, 0);
1032
1033 base= pci_attr_r32(devind, CBB_MEMBASE_0);
1034 limit= pci_attr_r32(devind, CBB_MEMLIMIT_0) |
1035 (~CBB_MEML_MASK & 0xffffffff);
1036 size= limit-base + 1;
1037 if (debug)
1038 {
1039 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
1040 base, limit, size);
1041 }
1042
1043 base= pci_attr_r32(devind, CBB_MEMBASE_1);
1044 limit= pci_attr_r32(devind, CBB_MEMLIMIT_1) |
1045 (~CBB_MEML_MASK & 0xffffffff);
1046 size= limit-base + 1;
1047 if (debug)
1048 {
1049 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
1050 base, limit, size);
1051 }
1052
1053 base= pci_attr_r32(devind, CBB_IOBASE_0);
1054 limit= pci_attr_r32(devind, CBB_IOLIMIT_0) |
1055 (~CBB_IOL_MASK & 0xffffffff);
1056 size= limit-base + 1;
1057 if (debug)
1058 {
1059 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
1060 base, limit, size);
1061 }
1062
1063 base= pci_attr_r32(devind, CBB_IOBASE_1);
1064 limit= pci_attr_r32(devind, CBB_IOLIMIT_1) |
1065 (~CBB_IOL_MASK & 0xffffffff);
1066 size= limit-base + 1;
1067 if (debug)
1068 {
1069 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
1070 base, limit, size);
1071 }
1072}
1073
1074/*===========================================================================*
1075 * record_bar *
1076 *===========================================================================*/
1077PRIVATE void record_bar(devind, bar_nr)
1078int devind;
1079int bar_nr;
1080{
1081 int reg, prefetch, type, dev_bar_nr;
1082 u32_t bar, bar2;
1083
1084 reg= PCI_BAR+4*bar_nr;
1085
1086 bar= pci_attr_r32(devind, reg);
1087 if (bar & PCI_BAR_IO)
1088 {
1089 /* Size register */
1090 pci_attr_w32(devind, reg, 0xffffffff);
1091 bar2= pci_attr_r32(devind, reg);
1092 pci_attr_w32(devind, reg, bar);
1093
1094 bar &= ~(u32_t)3; /* Clear non-address bits */
1095 bar2 &= ~(u32_t)3;
1096 bar2= (~bar2 & 0xffff)+1;
1097 if (debug)
1098 {
1099 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
1100 bar_nr, bar2, bar);
1101 }
1102
1103 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1104 assert(dev_bar_nr < BAR_NR);
1105 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO;
1106 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1107 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1108 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1109 if (bar == 0)
1110 {
1111 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1112 PBF_INCOMPLETE;
1113 }
1114 }
1115 else
1116 {
1117 /* Size register */
1118 pci_attr_w32(devind, reg, 0xffffffff);
1119 bar2= pci_attr_r32(devind, reg);
1120 pci_attr_w32(devind, reg, bar);
1121
1122 if (bar2 == 0)
1123 return; /* Reg. is not implemented */
1124
1125 prefetch= !!(bar & PCI_BAR_PREFETCH);
1126 type= (bar & PCI_BAR_TYPE);
1127 bar &= ~(u32_t)0xf; /* Clear non-address bits */
1128 bar2 &= ~(u32_t)0xf;
1129 bar2= (~bar2)+1;
1130 if (debug)
1131 {
1132 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory\n",
1133 bar_nr, bar2, bar,
1134 prefetch ? " prefetchable" : "");
1135 if (type != 0)
1136 printf("type = 0x%x\n", type);
1137 }
1138
1139 dev_bar_nr= pcidev[devind].pd_bar_nr++;
1140 assert(dev_bar_nr < BAR_NR);
1141 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0;
1142 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
1143 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
1144 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
1145 if (bar == 0)
1146 {
1147 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
1148 PBF_INCOMPLETE;
1149 }
1150 }
1151}
1152
1153/*===========================================================================*
1154 * complete_bridges *
1155 *===========================================================================*/
1156PRIVATE void complete_bridges()
1157{
1158 int i, freebus, devind, prim_busnr;
1159
1160 for (i= 0; i<nr_pcibus; i++)
1161 {
1162 if (!pcibus[i].pb_needinit)
1163 continue;
1164 printf("should allocate bus number for bus %d\n", i);
1165 freebus= get_freebus();
1166 printf("got bus number %d\n", freebus);
1167
1168 devind= pcibus[i].pb_devind;
1169
1170 prim_busnr= pcidev[devind].pd_busnr;
1171 if (prim_busnr != 0)
1172 {
1173 printf(
1174 "complete_bridge: updating subordinate bus number not implemented\n");
1175 }
1176
1177 pcibus[i].pb_needinit= 0;
1178 pcibus[i].pb_busnr= freebus;
1179
1180 printf("devind = %d\n", devind);
1181 printf("prim_busnr= %d\n", prim_busnr);
1182
1183 pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
1184 pci_attr_w8(devind, PPB_SECBN, freebus);
1185 pci_attr_w8(devind, PPB_SUBORDBN, freebus);
1186
1187 printf("CR = 0x%x\n", pci_attr_r16(devind, PCI_CR));
1188 printf("SECBLT = 0x%x\n", pci_attr_r8(devind, PPB_SECBLT));
1189 printf("BRIDGECTRL = 0x%x\n",
1190 pci_attr_r16(devind, PPB_BRIDGECTRL));
1191 }
1192}
1193
1194/*===========================================================================*
1195 * complete_bars *
1196 *===========================================================================*/
1197PRIVATE void complete_bars()
1198{
1199 int i, j, r, bar_nr, reg;
1200 u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
1201 base, size, v32, diff1, diff2;
1202 char *cp, *next;
1203 char memstr[256];
1204
1205 r= env_get_param("memory", memstr, sizeof(memstr));
1206 if (r != OK)
1207 panic("pci", "env_get_param failed", r);
1208
1209 /* Set memgap_low to just above physical memory */
1210 memgap_low= 0;
1211 cp= memstr;
1212 while (*cp != '\0')
1213 {
1214 base= strtoul(cp, &next, 16);
1215 if (next == cp || *next != ':')
1216 {
1217 printf("pci: bad memory environment string '%s'\n",
1218 memstr);
1219 panic(NULL, NULL, NO_NUM);
1220 }
1221 cp= next+1;
1222 size= strtoul(cp, &next, 16);
1223 if (next == cp || (*next != ',' && *next != '\0'))
1224 {
1225 printf("pci: bad memory environment string '%s'\n",
1226 memstr);
1227 panic(NULL, NULL, NO_NUM);
1228 }
1229 cp= next+1;
1230
1231 if (base+size > memgap_low)
1232 memgap_low= base+size;
1233 }
1234
1235 memgap_high= 0xfe000000; /* Leave space for the CPU (APIC) */
1236
1237 if (debug)
1238 {
1239 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
1240 memgap_low, memgap_high);
1241 }
1242
1243 /* Find the lowest memory base */
1244 for (i= 0; i<nr_pcidev; i++)
1245 {
1246 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1247 {
1248 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1249 continue;
1250 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1251 continue;
1252 base= pcidev[i].pd_bar[j].pb_base;
1253 size= pcidev[i].pd_bar[j].pb_size;
1254
1255 if (base >= memgap_high)
1256 continue; /* Not in the gap */
1257 if (base+size <= memgap_low)
1258 continue; /* Not in the gap */
1259
1260 /* Reduce the gap by the smallest amount */
1261 diff1= base+size-memgap_low;
1262 diff2= memgap_high-base;
1263
1264 if (diff1 < diff2)
1265 memgap_low= base+size;
1266 else
1267 memgap_high= base;
1268 }
1269 }
1270
1271 if (debug)
1272 {
1273 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
1274 memgap_low, memgap_high);
1275 }
1276
1277 /* Should check main memory size */
1278 if (memgap_high < memgap_low)
1279 {
1280 printf("pci: bad memory gap: [0x%x .. 0x%x>\n",
1281 memgap_low, memgap_high);
1282 panic(NULL, NULL, NO_NUM);
1283 }
1284
1285 iogap_high= 0x10000;
1286 iogap_low= 0x400;
1287
1288 /* Find the free I/O space */
1289 for (i= 0; i<nr_pcidev; i++)
1290 {
1291 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1292 {
1293 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1294 continue;
1295 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
1296 continue;
1297 base= pcidev[i].pd_bar[j].pb_base;
1298 size= pcidev[i].pd_bar[j].pb_size;
1299 if (base >= iogap_high)
1300 continue;
1301 if (base+size <= iogap_low)
1302 continue;
1303#if 0
1304 if (debug)
1305 {
1306 printf(
1307 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
1308 i, pcidev[i].pd_vid, pcidev[i].pd_did,
1309 j, base, size);
1310 }
1311#endif
1312 if (base+size-iogap_low < iogap_high-base)
1313 iogap_low= base+size;
1314 else
1315 iogap_high= base;
1316 }
1317 }
1318
1319 if (iogap_high < iogap_low)
1320 {
1321 if (debug)
1322 {
1323 printf("iogap_high too low, should panic\n");
1324 }
1325 else
1326 panic("pci", "iogap_high too low", iogap_high);
1327 }
1328 if (debug)
1329 printf("I/O range = [0x%x..0x%x>\n", iogap_low, iogap_high);
1330
1331 for (i= 0; i<nr_pcidev; i++)
1332 {
1333 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1334 {
1335 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
1336 continue;
1337 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1338 continue;
1339 size= pcidev[i].pd_bar[j].pb_size;
1340 if (size < PAGE_SIZE)
1341 size= PAGE_SIZE;
1342 base= memgap_high-size;
1343 base &= ~(u32_t)(size-1);
1344 if (base < memgap_low)
1345 panic("pci", "memory base too low", base);
1346 memgap_high= base;
1347 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1348 reg= PCI_BAR + 4*bar_nr;
1349 v32= pci_attr_r32(i, reg);
1350 pci_attr_w32(i, reg, v32 | base);
1351 if (debug)
1352 {
1353 printf(
1354 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1355 base, size, pcidev[i].pd_busnr,
1356 pcidev[i].pd_dev, pcidev[i].pd_func,
1357 bar_nr);
1358 }
1359 pcidev[i].pd_bar[j].pb_base= base;
1360 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1361 }
1362
1363 io_high= iogap_high;
1364 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1365 {
1366 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
1367 continue;
1368 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1369 continue;
1370 size= pcidev[i].pd_bar[j].pb_size;
1371 base= iogap_high-size;
1372 base &= ~(u32_t)(size-1);
1373
1374 /* Assume that ISA compatibility is required. Only
1375 * use the lowest 256 bytes out of every 1024 bytes.
1376 */
1377 base &= 0xfcff;
1378
1379 if (base < iogap_low)
1380 panic("pci", "I/O base too low", base);
1381
1382 iogap_high= base;
1383 bar_nr= pcidev[i].pd_bar[j].pb_nr;
1384 reg= PCI_BAR + 4*bar_nr;
1385 v32= pci_attr_r32(i, reg);
1386 pci_attr_w32(i, reg, v32 | base);
1387 if (debug)
1388 {
1389 printf(
1390 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
1391 base, size, pcidev[i].pd_busnr,
1392 pcidev[i].pd_dev, pcidev[i].pd_func,
1393 bar_nr);
1394 }
1395 pcidev[i].pd_bar[j].pb_base= base;
1396 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
1397
1398 }
1399 if (iogap_high != io_high)
1400 {
1401 update_bridge4dev_io(i, iogap_high,
1402 io_high-iogap_high);
1403 }
1404 }
1405
1406 for (i= 0; i<nr_pcidev; i++)
1407 {
1408 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
1409 {
1410 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
1411 continue;
1412 printf("should allocate resources for device %d\n", i);
1413 }
1414 }
1415}
1416
1417/*===========================================================================*
1418 * update_bridge4dev_io *
1419 *===========================================================================*/
1420PRIVATE void update_bridge4dev_io(devind, io_base, io_size)
1421int devind;
1422u32_t io_base;
1423u32_t io_size;
1424{
1425 int busnr, busind, type, br_devind;
1426 u16_t v16;
1427
1428 busnr= pcidev[devind].pd_busnr;
1429 busind= get_busind(busnr);
1430 type= pcibus[busind].pb_type;
1431 if (type == PBT_INTEL_HOST)
1432 return; /* Nothing to do for host controller */
1433 if (type == PBT_PCIBRIDGE)
1434 {
1435 printf(
1436 "update_bridge4dev_io: not implemented for PCI bridges\n");
1437 return;
1438 }
1439 if (type != PBT_CARDBUS)
1440 panic("pci", "update_bridge4dev_io: strange bus type", type);
1441
1442 if (debug)
1443 {
1444 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
1445 io_size, io_base);
1446 }
1447 br_devind= pcibus[busind].pb_devind;
1448 pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
1449 pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
1450
1451 /* Enable I/O access. Enable busmaster access as well. */
1452 v16= pci_attr_r16(devind, PCI_CR);
1453 pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
1454}
1455
1456/*===========================================================================*
1457 * get_freebus *
1458 *===========================================================================*/
1459PRIVATE int get_freebus()
1460{
1461 int i, freebus;
1462
1463 freebus= 1;
1464 for (i= 0; i<nr_pcibus; i++)
1465 {
1466 if (pcibus[i].pb_needinit)
1467 continue;
1468 if (pcibus[i].pb_type == PBT_INTEL_HOST)
1469 continue;
1470 if (pcibus[i].pb_busnr <= freebus)
1471 freebus= pcibus[i].pb_busnr+1;
1472 printf("get_freebus: should check suboridinate bus number\n");
1473 }
1474 return freebus;
1475}
1476
1477/*===========================================================================*
1478 * do_isabridge *
1479 *===========================================================================*/
1480PRIVATE int do_isabridge(busind)
1481int busind;
1482{
1483 int i, j, r, type, busnr, unknown_bridge, bridge_dev;
1484 u16_t vid, did;
1485 u32_t t3;
1486 char *dstr;
1487
1488 unknown_bridge= -1;
1489 bridge_dev= -1;
1490 j= 0; /* lint */
1491 vid= did= 0; /* lint */
1492 busnr= pcibus[busind].pb_busnr;
1493 for (i= 0; i< nr_pcidev; i++)
1494 {
1495 if (pcidev[i].pd_busnr != busnr)
1496 continue;
1497 t3= ((pcidev[i].pd_baseclass << 16) |
1498 (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
1499 if (t3 == PCI_T3_ISA)
1500 {
1501 /* ISA bridge. Report if no supported bridge is
1502 * found.
1503 */
1504 unknown_bridge= i;
1505 }
1506
1507 vid= pcidev[i].pd_vid;
1508 did= pcidev[i].pd_did;
1509 for (j= 0; pci_isabridge[j].vid != 0; j++)
1510 {
1511 if (pci_isabridge[j].vid != vid)
1512 continue;
1513 if (pci_isabridge[j].did != did)
1514 continue;
1515 if (pci_isabridge[j].checkclass &&
1516 unknown_bridge != i)
1517 {
1518 /* This part of multifunction device is
1519 * not the bridge.
1520 */
1521 continue;
1522 }
1523 break;
1524 }
1525 if (pci_isabridge[j].vid)
1526 {
1527 bridge_dev= i;
1528 break;
1529 }
1530 }
1531
1532 if (bridge_dev != -1)
1533 {
1534 dstr= pci_dev_name(vid, did);
1535 if (!dstr)
1536 dstr= "unknown device";
1537 if (debug)
1538 {
1539 printf("found ISA bridge (%04X/%04X) %s\n",
1540 vid, did, dstr);
1541 }
1542 pcibus[busind].pb_isabridge_dev= bridge_dev;
1543 type= pci_isabridge[j].type;
1544 pcibus[busind].pb_isabridge_type= type;
1545 switch(type)
1546 {
1547 case PCI_IB_PIIX:
1548 r= do_piix(bridge_dev);
1549 break;
1550 case PCI_IB_VIA:
1551 r= do_via_isabr(bridge_dev);
1552 break;
1553 case PCI_IB_AMD:
1554 r= do_amd_isabr(bridge_dev);
1555 break;
1556 case PCI_IB_SIS:
1557 r= do_sis_isabr(bridge_dev);
1558 break;
1559 default:
1560 panic("PCI","unknown ISA bridge type", type);
1561 }
1562 return r;
1563 }
1564
1565 if (unknown_bridge == -1)
1566 {
1567 if (debug)
1568 {
1569 printf("(warning) no ISA bridge found on bus %d\n",
1570 busind);
1571 }
1572 return 0;
1573 }
1574 if (debug)
1575 {
1576 printf(
1577 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
1578 pcidev[unknown_bridge].pd_vid,
1579 pcidev[unknown_bridge].pd_did, busind);
1580 }
1581 return 0;
1582}
1583
1584/*===========================================================================*
1585 * do_pcibridge *
1586 *===========================================================================*/
1587PRIVATE void do_pcibridge(busind)
1588int busind;
1589{
1590 int i, devind, busnr;
1591 int ind, type;
1592 u16_t vid, did;
1593 u8_t sbusn, baseclass, subclass, infclass, headt;
1594 u32_t t3;
1595
1596 vid= did= 0; /* lint */
1597 busnr= pcibus[busind].pb_busnr;
1598 for (devind= 0; devind< nr_pcidev; devind++)
1599 {
1600#if 0
1601 printf("do_pcibridge: trying %u.%u.%u\n",
1602 pcidev[devind].pd_busind, pcidev[devind].pd_dev,
1603 pcidev[devind].pd_func);
1604#endif
1605
1606 if (pcidev[devind].pd_busnr != busnr)
1607 {
1608#if 0
1609 printf("wrong bus\n");
1610#endif
1611 continue;
1612 }
1613
1614 vid= pcidev[devind].pd_vid;
1615 did= pcidev[devind].pd_did;
1616 for (i= 0; pci_pcibridge[i].vid != 0; i++)
1617 {
1618 if (pci_pcibridge[i].vid != vid)
1619 continue;
1620 if (pci_pcibridge[i].did != did)
1621 continue;
1622 break;
1623 }
1624 type= pci_pcibridge[i].type;
1625 if (pci_pcibridge[i].vid == 0)
1626 {
1627 headt= pci_attr_r8(devind, PCI_HEADT);
1628 type= 0;
1629 if ((headt & PHT_MASK) == PHT_BRIDGE)
1630 type= PCI_PPB_STD;
1631 else if ((headt & PHT_MASK) == PHT_CARDBUS)
1632 type= PCI_PPB_CB;
1633 else
1634 {
1635#if 0
1636 printf("not a bridge\n");
1637#endif
1638 continue; /* Not a bridge */
1639 }
1640
1641 baseclass= pci_attr_r8(devind, PCI_BCR);
1642 subclass= pci_attr_r8(devind, PCI_SCR);
1643 infclass= pci_attr_r8(devind, PCI_PIFR);
1644 t3= ((baseclass << 16) | (subclass << 8) | infclass);
1645 if (type == PCI_PPB_STD &&
1646 t3 != PCI_T3_PCI2PCI &&
1647 t3 != PCI_T3_PCI2PCI_SUBTR)
1648 {
1649 printf(
1650"Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
1651 baseclass, subclass, infclass,
1652 vid, did);
1653 continue;
1654 }
1655 if (type == PCI_PPB_CB &&
1656 t3 != PCI_T3_CARDBUS)
1657 {
1658 printf(
1659"Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
1660 baseclass, subclass, infclass,
1661 vid, did);
1662 continue;
1663 }
1664 }
1665
1666 if (debug)
1667 {
1668 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
1669 pcidev[devind].pd_busnr,
1670 pcidev[devind].pd_dev,
1671 pcidev[devind].pd_func, vid, did);
1672 }
1673
1674 /* Assume that the BIOS initialized the secondary bus
1675 * number.
1676 */
1677 sbusn= pci_attr_r8(devind, PPB_SECBN);
1678#if DEBUG
1679 printf("sbusn = %d\n", sbusn);
1680 printf("subordn = %d\n", pci_attr_r8(devind, PPB_SUBORDBN));
1681#endif
1682
1683 if (nr_pcibus >= NR_PCIBUS)
1684 panic("PCI","too many PCI busses", nr_pcibus);
1685 ind= nr_pcibus;
1686 nr_pcibus++;
1687 pcibus[ind].pb_type= PBT_PCIBRIDGE;
1688 pcibus[ind].pb_needinit= 1;
1689 pcibus[ind].pb_isabridge_dev= -1;
1690 pcibus[ind].pb_isabridge_type= 0;
1691 pcibus[ind].pb_devind= devind;
1692 pcibus[ind].pb_busnr= sbusn;
1693 pcibus[ind].pb_rreg8= pcibus[busind].pb_rreg8;
1694 pcibus[ind].pb_rreg16= pcibus[busind].pb_rreg16;
1695 pcibus[ind].pb_rreg32= pcibus[busind].pb_rreg32;
1696 pcibus[ind].pb_wreg8= pcibus[busind].pb_wreg8;
1697 pcibus[ind].pb_wreg16= pcibus[busind].pb_wreg16;
1698 pcibus[ind].pb_wreg32= pcibus[busind].pb_wreg32;
1699 switch(type)
1700 {
1701 case PCI_PPB_STD:
1702 pcibus[ind].pb_rsts= pcibr_std_rsts;
1703 pcibus[ind].pb_wsts= pcibr_std_wsts;
1704 break;
1705 case PCI_PPB_CB:
1706 pcibus[ind].pb_type= PBT_CARDBUS;
1707 pcibus[ind].pb_rsts= pcibr_cb_rsts;
1708 pcibus[ind].pb_wsts= pcibr_cb_wsts;
1709 break;
1710 case PCI_AGPB_VIA:
1711 pcibus[ind].pb_rsts= pcibr_via_rsts;
1712 pcibus[ind].pb_wsts= pcibr_via_wsts;
1713 break;
1714 default:
1715 panic("PCI","unknown PCI-PCI bridge type", type);
1716 }
1717 if (sbusn == 0)
1718 {
1719 printf("Secondary bus number not initialized\n");
1720 continue;
1721 }
1722 pcibus[ind].pb_needinit= 0;
1723
1724 probe_bus(ind);
1725
1726 /* Look for PCI bridges */
1727 do_pcibridge(ind);
1728 }
1729}
1730
1731/*===========================================================================*
1732 * get_busind *
1733 *===========================================================================*/
1734PRIVATE int get_busind(busnr)
1735int busnr;
1736{
1737 int i;
1738
1739 for (i= 0; i<nr_pcibus; i++)
1740 {
1741 if (pcibus[i].pb_busnr == busnr)
1742 return i;
1743 }
1744 panic("pci", "get_busind: can't find bus", busnr);
1745}
1746
1747/*===========================================================================*
1748 * do_piix *
1749 *===========================================================================*/
1750PRIVATE int do_piix(devind)
1751int devind;
1752{
1753 int i, s, dev, func, irqrc, irq;
1754 u32_t elcr1, elcr2, elcr;
1755
1756#if DEBUG
1757 printf("in piix\n");
1758#endif
1759 dev= pcidev[devind].pd_dev;
1760 func= pcidev[devind].pd_func;
1761#if USER_SPACE
1762 if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
1763 printf("Warning, sys_inb failed: %d\n", s);
1764 if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
1765 printf("Warning, sys_inb failed: %d\n", s);
1766#else
1767 elcr1= inb(PIIX_ELCR1);
1768 elcr2= inb(PIIX_ELCR2);
1769#endif
1770 elcr= elcr1 | (elcr2 << 8);
1771 for (i= 0; i<4; i++)
1772 {
1773 irqrc= pci_attr_r8(devind, PIIX_PIRQRCA+i);
1774 if (irqrc & PIIX_IRQ_DI)
1775 {
1776 if (debug)
1777 printf("INT%c: disabled\n", 'A'+i);
1778 }
1779 else
1780 {
1781 irq= irqrc & PIIX_IRQ_MASK;
1782 if (debug)
1783 printf("INT%c: %d\n", 'A'+i, irq);
1784 if (!(elcr & (1 << irq)))
1785 {
1786 if (debug)
1787 {
1788 printf(
1789 "(warning) IRQ %d is not level triggered\n",
1790 irq);
1791 }
1792 }
1793 irq_mode_pci(irq);
1794 }
1795 }
1796 return 0;
1797}
1798
1799/*===========================================================================*
1800 * do_amd_isabr *
1801 *===========================================================================*/
1802PRIVATE int do_amd_isabr(devind)
1803int devind;
1804{
1805 int i, busnr, dev, func, xdevind, irq, edge;
1806 u8_t levmask;
1807 u16_t pciirq;
1808
1809 /* Find required function */
1810 func= AMD_ISABR_FUNC;
1811 busnr= pcidev[devind].pd_busnr;
1812 dev= pcidev[devind].pd_dev;
1813
1814 /* Fake a device with the required function */
1815 if (nr_pcidev >= NR_PCIDEV)
1816 panic("PCI","too many PCI devices", nr_pcidev);
1817 xdevind= nr_pcidev;
1818 pcidev[xdevind].pd_busnr= busnr;
1819 pcidev[xdevind].pd_dev= dev;
1820 pcidev[xdevind].pd_func= func;
1821 pcidev[xdevind].pd_inuse= 1;
1822 nr_pcidev++;
1823
1824 levmask= pci_attr_r8(xdevind, AMD_ISABR_PCIIRQ_LEV);
1825 pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
1826 for (i= 0; i<4; i++)
1827 {
1828 edge= (levmask >> i) & 1;
1829 irq= (pciirq >> (4*i)) & 0xf;
1830 if (!irq)
1831 {
1832 if (debug)
1833 printf("INT%c: disabled\n", 'A'+i);
1834 }
1835 else
1836 {
1837 if (debug)
1838 printf("INT%c: %d\n", 'A'+i, irq);
1839 if (edge && debug)
1840 {
1841 printf(
1842 "(warning) IRQ %d is not level triggered\n",
1843 irq);
1844 }
1845 irq_mode_pci(irq);
1846 }
1847 }
1848 nr_pcidev--;
1849 return 0;
1850}
1851
1852/*===========================================================================*
1853 * do_sis_isabr *
1854 *===========================================================================*/
1855PRIVATE int do_sis_isabr(devind)
1856int devind;
1857{
1858 int i, dev, func, irq;
1859
1860 dev= pcidev[devind].pd_dev;
1861 func= pcidev[devind].pd_func;
1862 irq= 0; /* lint */
1863 for (i= 0; i<4; i++)
1864 {
1865 irq= pci_attr_r8(devind, SIS_ISABR_IRQ_A+i);
1866 if (irq & SIS_IRQ_DISABLED)
1867 {
1868 if (debug)
1869 printf("INT%c: disabled\n", 'A'+i);
1870 }
1871 else
1872 {
1873 irq &= SIS_IRQ_MASK;
1874 if (debug)
1875 printf("INT%c: %d\n", 'A'+i, irq);
1876 irq_mode_pci(irq);
1877 }
1878 }
1879 return 0;
1880}
1881
1882/*===========================================================================*
1883 * do_via_isabr *
1884 *===========================================================================*/
1885PRIVATE int do_via_isabr(devind)
1886int devind;
1887{
1888 int i, dev, func, irq, edge;
1889 u8_t levmask;
1890
1891 dev= pcidev[devind].pd_dev;
1892 func= pcidev[devind].pd_func;
1893 levmask= pci_attr_r8(devind, VIA_ISABR_EL);
1894 irq= 0; /* lint */
1895 edge= 0; /* lint */
1896 for (i= 0; i<4; i++)
1897 {
1898 switch(i)
1899 {
1900 case 0:
1901 edge= (levmask & VIA_ISABR_EL_INTA);
1902 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R2) >> 4;
1903 break;
1904 case 1:
1905 edge= (levmask & VIA_ISABR_EL_INTB);
1906 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R2);
1907 break;
1908 case 2:
1909 edge= (levmask & VIA_ISABR_EL_INTC);
1910 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R3) >> 4;
1911 break;
1912 case 3:
1913 edge= (levmask & VIA_ISABR_EL_INTD);
1914 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R1) >> 4;
1915 break;
1916 default:
1917 assert(0);
1918 }
1919 irq &= 0xf;
1920 if (!irq)
1921 {
1922 if (debug)
1923 printf("INT%c: disabled\n", 'A'+i);
1924 }
1925 else
1926 {
1927 if (debug)
1928 printf("INT%c: %d\n", 'A'+i, irq);
1929 if (edge && debug)
1930 {
1931 printf(
1932 "(warning) IRQ %d is not level triggered\n",
1933 irq);
1934 }
1935 irq_mode_pci(irq);
1936 }
1937 }
1938 return 0;
1939}
1940
1941
1942/*===========================================================================*
1943 * report_vga *
1944 *===========================================================================*/
1945PRIVATE void report_vga(devind)
1946int devind;
1947{
1948 /* Report the amount of video memory. This is needed by the X11R6
1949 * postinstall script to chmem the X server. Hopefully this can be
1950 * removed when we get virtual memory.
1951 */
1952 size_t amount, size;
1953 int i;
1954
1955 amount= 0;
1956 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
1957 {
1958 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
1959 continue;
1960 size= pcidev[devind].pd_bar[i].pb_size;
1961 if (size < amount)
1962 continue;
1963 amount= size;
1964 }
1965 if (size != 0)
1966 {
1967 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
1968 pcidev[devind].pd_busnr,
1969 pcidev[devind].pd_dev,
1970 pcidev[devind].pd_func,
1971 amount);
1972 }
1973}
1974
1975
1976/*===========================================================================*
1977 * pci_vid_name *
1978 *===========================================================================*/
1979PRIVATE char *pci_vid_name(vid)
1980u16_t vid;
1981{
1982 int i;
1983
1984 for (i= 0; pci_vendor_table[i].name; i++)
1985 {
1986 if (pci_vendor_table[i].vid == vid)
1987 return pci_vendor_table[i].name;
1988 }
1989 return "unknown";
1990}
1991
1992/*===========================================================================*
1993 * pci_baseclass_name *
1994 *===========================================================================*/
1995PRIVATE char *pci_baseclass_name(baseclass)
1996u8_t baseclass;
1997{
1998 int i;
1999
2000 for (i= 0; pci_baseclass_table[i].name; i++)
2001 {
2002 if (pci_baseclass_table[i].baseclass == baseclass)
2003 return pci_baseclass_table[i].name;
2004 }
2005 return NULL;
2006}
2007
2008/*===========================================================================*
2009 * pci_subclass_name *
2010 *===========================================================================*/
2011PRIVATE char *pci_subclass_name(baseclass, subclass, infclass)
2012u8_t baseclass;
2013u8_t subclass;
2014u8_t infclass;
2015{
2016 int i;
2017
2018 for (i= 0; pci_subclass_table[i].name; i++)
2019 {
2020 if (pci_subclass_table[i].baseclass != baseclass)
2021 continue;
2022 if (pci_subclass_table[i].subclass != subclass)
2023 continue;
2024 if (pci_subclass_table[i].infclass != infclass &&
2025 pci_subclass_table[i].infclass != (u16_t)-1)
2026 {
2027 continue;
2028 }
2029 return pci_subclass_table[i].name;
2030 }
2031 return NULL;
2032}
2033
2034/*===========================================================================*
2035 * ntostr *
2036 *===========================================================================*/
2037PRIVATE void ntostr(n, str, end)
2038unsigned n;
2039char **str;
2040char *end;
2041{
2042 char tmpstr[20];
2043 int i;
2044
2045 if (n == 0)
2046 {
2047 tmpstr[0]= '0';
2048 i= 1;
2049 }
2050 else
2051 {
2052 for (i= 0; n; i++)
2053 {
2054 tmpstr[i]= '0' + (n%10);
2055 n /= 10;
2056 }
2057 }
2058 for (; i>0; i--)
2059 {
2060 if (*str == end)
2061 {
2062 break;
2063 }
2064 **str= tmpstr[i-1];
2065 (*str)++;
2066 }
2067 if (*str == end)
2068 end[-1]= '\0';
2069 else
2070 **str= '\0';
2071}
2072
2073/*===========================================================================*
2074 * pci_attr_rsts *
2075 *===========================================================================*/
2076PRIVATE u16_t pci_attr_rsts(devind)
2077int devind;
2078{
2079 int busnr, busind;
2080
2081 busnr= pcidev[devind].pd_busnr;
2082 busind= get_busind(busnr);
2083 return pcibus[busind].pb_rsts(busind);
2084}
2085
2086
2087/*===========================================================================*
2088 * pcibr_std_rsts *
2089 *===========================================================================*/
2090PRIVATE u16_t pcibr_std_rsts(busind)
2091int busind;
2092{
2093 int devind;
2094
2095 devind= pcibus[busind].pb_devind;
2096 return pci_attr_r16(devind, PPB_SSTS);
2097}
2098
2099/*===========================================================================*
2100 * pcibr_std_wsts *
2101 *===========================================================================*/
2102PRIVATE void pcibr_std_wsts(busind, value)
2103int busind;
2104u16_t value;
2105{
2106 int devind;
2107 devind= pcibus[busind].pb_devind;
2108
2109#if 0
2110 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
2111 busind, value, devind);
2112#endif
2113 pci_attr_w16(devind, PPB_SSTS, value);
2114}
2115
2116/*===========================================================================*
2117 * pcibr_cb_rsts *
2118 *===========================================================================*/
2119PRIVATE u16_t pcibr_cb_rsts(busind)
2120int busind;
2121{
2122 int devind;
2123 devind= pcibus[busind].pb_devind;
2124
2125 return pci_attr_r16(devind, CBB_SSTS);
2126}
2127
2128/*===========================================================================*
2129 * pcibr_cb_wsts *
2130 *===========================================================================*/
2131PRIVATE void pcibr_cb_wsts(busind, value)
2132int busind;
2133u16_t value;
2134{
2135 int devind;
2136 devind= pcibus[busind].pb_devind;
2137
2138#if 0
2139 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
2140 busind, value, devind);
2141#endif
2142 pci_attr_w16(devind, CBB_SSTS, value);
2143}
2144
2145/*===========================================================================*
2146 * pcibr_via_rsts *
2147 *===========================================================================*/
2148PRIVATE u16_t pcibr_via_rsts(busind)
2149int busind;
2150{
2151 int devind;
2152 devind= pcibus[busind].pb_devind;
2153
2154 return 0;
2155}
2156
2157/*===========================================================================*
2158 * pcibr_via_wsts *
2159 *===========================================================================*/
2160PRIVATE void pcibr_via_wsts(busind, value)
2161int busind;
2162u16_t value;
2163{
2164 int devind;
2165 devind= pcibus[busind].pb_devind;
2166
2167#if 0
2168 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
2169 busind, value, devind);
2170#endif
2171}
2172
2173/*===========================================================================*
2174 * pci_attr_wsts *
2175 *===========================================================================*/
2176PRIVATE void pci_attr_wsts(devind, value)
2177int devind;
2178u16_t value;
2179{
2180 int busnr, busind;
2181
2182 busnr= pcidev[devind].pd_busnr;
2183 busind= get_busind(busnr);
2184 pcibus[busind].pb_wsts(busind, value);
2185}
2186
2187
2188/*===========================================================================*
2189 * pcii_rreg8 *
2190 *===========================================================================*/
2191PRIVATE u8_t pcii_rreg8(busind, devind, port)
2192int busind;
2193int devind;
2194int port;
2195{
2196 u8_t v;
2197 int s;
2198
2199 v= PCII_RREG8_(pcibus[busind].pb_busnr,
2200 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2201 port);
2202#if USER_SPACE
2203 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2204 printf("PCI: warning, sys_outl failed: %d\n", s);
2205#else
2206 outl(PCII_CONFADD, PCII_UNSEL);
2207#endif
2208#if 0
2209 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2210 busind, devind, port,
2211 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2212 pcidev[devind].pd_func, v);
2213#endif
2214 return v;
2215}
2216
2217/*===========================================================================*
2218 * pcii_rreg16 *
2219 *===========================================================================*/
2220PRIVATE u16_t pcii_rreg16(busind, devind, port)
2221int busind;
2222int devind;
2223int port;
2224{
2225 u16_t v;
2226 int s;
2227
2228 v= PCII_RREG16_(pcibus[busind].pb_busnr,
2229 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2230 port);
2231#if USER_SPACE
2232 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2233 printf("PCI: warning, sys_outl failed: %d\n");
2234#else
2235 outl(PCII_CONFADD, PCII_UNSEL);
2236#endif
2237#if 0
2238 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2239 busind, devind, port,
2240 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2241 pcidev[devind].pd_func, v);
2242#endif
2243 return v;
2244}
2245
2246/*===========================================================================*
2247 * pcii_rreg32 *
2248 *===========================================================================*/
2249PRIVATE u32_t pcii_rreg32(busind, devind, port)
2250int busind;
2251int devind;
2252int port;
2253{
2254 u32_t v;
2255 int s;
2256
2257 v= PCII_RREG32_(pcibus[busind].pb_busnr,
2258 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2259 port);
2260#if USER_SPACE
2261 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2262 printf("PCI: warning, sys_outl failed: %d\n", s);
2263#else
2264 outl(PCII_CONFADD, PCII_UNSEL);
2265#endif
2266#if 0
2267 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
2268 busind, devind, port,
2269 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2270 pcidev[devind].pd_func, v);
2271#endif
2272 return v;
2273}
2274
2275/*===========================================================================*
2276 * pcii_wreg8 *
2277 *===========================================================================*/
2278PRIVATE void pcii_wreg8(busind, devind, port, value)
2279int busind;
2280int devind;
2281int port;
2282u8_t value;
2283{
2284 int s;
2285#if 0
2286 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2287 busind, devind, port, value,
2288 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2289 pcidev[devind].pd_func);
2290#endif
2291 PCII_WREG8_(pcibus[busind].pb_busnr,
2292 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2293 port, value);
2294#if USER_SPACE
2295 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2296 printf("PCI: warning, sys_outl failed: %d\n", s);
2297#else
2298 outl(PCII_CONFADD, PCII_UNSEL);
2299#endif
2300}
2301
2302/*===========================================================================*
2303 * pcii_wreg16 *
2304 *===========================================================================*/
2305PRIVATE void pcii_wreg16(busind, devind, port, value)
2306int busind;
2307int devind;
2308int port;
2309u16_t value;
2310{
2311 int s;
2312#if 0
2313 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2314 busind, devind, port, value,
2315 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2316 pcidev[devind].pd_func);
2317#endif
2318 PCII_WREG16_(pcibus[busind].pb_busnr,
2319 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2320 port, value);
2321#if USER_SPACE
2322 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2323 printf("PCI: warning, sys_outl failed: %d\n", s);
2324#else
2325 outl(PCII_CONFADD, PCII_UNSEL);
2326#endif
2327}
2328
2329/*===========================================================================*
2330 * pcii_wreg32 *
2331 *===========================================================================*/
2332PRIVATE void pcii_wreg32(busind, devind, port, value)
2333int busind;
2334int devind;
2335int port;
2336u32_t value;
2337{
2338 int s;
2339#if 0
2340 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
2341 busind, devind, port, value,
2342 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
2343 pcidev[devind].pd_func);
2344#endif
2345 PCII_WREG32_(pcibus[busind].pb_busnr,
2346 pcidev[devind].pd_dev, pcidev[devind].pd_func,
2347 port, value);
2348#if USER_SPACE
2349 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2350 printf("PCI: warning, sys_outl failed: %d\n");
2351#else
2352 outl(PCII_CONFADD, PCII_UNSEL);
2353#endif
2354}
2355
2356/*===========================================================================*
2357 * pcii_rsts *
2358 *===========================================================================*/
2359PRIVATE u16_t pcii_rsts(busind)
2360int busind;
2361{
2362 u16_t v;
2363 int s;
2364
2365 v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
2366#if USER_SPACE
2367 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2368 printf("PCI: warning, sys_outl failed: %d\n", s);
2369#else
2370 outl(PCII_CONFADD, PCII_UNSEL);
2371#endif
2372 return v;
2373}
2374
2375/*===========================================================================*
2376 * pcii_wsts *
2377 *===========================================================================*/
2378PRIVATE void pcii_wsts(busind, value)
2379int busind;
2380u16_t value;
2381{
2382 int s;
2383 PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
2384#if USER_SPACE
2385 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
2386 printf("PCI: warning, sys_outl failed: %d\n", s);
2387#else
2388 outl(PCII_CONFADD, PCII_UNSEL);
2389#endif
2390}
2391
2392
2393/*===========================================================================*
2394 * print_capabilities *
2395 *===========================================================================*/
2396PRIVATE void print_capabilities(devind)
2397int devind;
2398{
2399 u8_t status, capptr, type, next;
2400 char *str;
2401
2402 /* Check capabilities bit in the device status register */
2403 status= pci_attr_r16(devind, PCI_SR);
2404 if (!(status & PSR_CAPPTR))
2405 return;
2406
2407 capptr= (pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK);
2408 while (capptr != 0)
2409 {
2410 type = pci_attr_r8(devind, capptr+CAP_TYPE);
2411 next= (pci_attr_r8(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
2412 switch(type)
2413 {
2414 case 1: str= "PCI Power Management"; break;
2415 case 2: str= "AGP"; break;
2416 case 3: str= "Vital Product Data"; break;
2417 case 4: str= "Slot Identification"; break;
2418 case 5: str= "Message Signaled Interrupts"; break;
2419 case 6: str= "CompactPCI Hot Swap"; break;
2420 case 8: str= "AMD HyperTransport"; break;
2421 case 0xf: str= "AMD I/O MMU"; break;
2422 defuault: str= "(unknown type)"; break;
2423 }
2424
2425 printf(" @0x%x: capability type 0x%x: %s\n",
2426 capptr, type, str);
2427 capptr= next;
2428 }
2429}
2430
2431/*
2432 * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $
2433 */
Note: See TracBrowser for help on using the repository browser.