1 | #define USER_SPACE 1
|
---|
2 | /*
|
---|
3 | pci.c
|
---|
4 |
|
---|
5 | Configure devices on the PCI bus
|
---|
6 |
|
---|
7 | Created: 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 <minix/com.h>
|
---|
14 | #include <minix/syslib.h>
|
---|
15 |
|
---|
16 | #include "pci.h"
|
---|
17 | #include "pci_amd.h"
|
---|
18 | #include "pci_intel.h"
|
---|
19 | #include "pci_sis.h"
|
---|
20 | #include "pci_via.h"
|
---|
21 | #if __minix_vmd
|
---|
22 | #include "config.h"
|
---|
23 | #endif
|
---|
24 |
|
---|
25 | #if !__minix_vmd
|
---|
26 | #define irq_mode_pci(irq) ((void)0)
|
---|
27 | #endif
|
---|
28 |
|
---|
29 | #include <stdlib.h>
|
---|
30 | #include <stdio.h>
|
---|
31 | #include <string.h>
|
---|
32 | #include <minix/sysutil.h>
|
---|
33 |
|
---|
34 | #define NR_PCIBUS 4
|
---|
35 | #define NR_PCIDEV 40
|
---|
36 |
|
---|
37 | #define PBT_INTEL 1
|
---|
38 | #define PBT_PCIBRIDGE 2
|
---|
39 |
|
---|
40 | PRIVATE int debug= 0;
|
---|
41 |
|
---|
42 | PRIVATE struct pcibus
|
---|
43 | {
|
---|
44 | int pb_type;
|
---|
45 | int pb_isabridge_dev;
|
---|
46 | int pb_isabridge_type;
|
---|
47 |
|
---|
48 | int pb_devind;
|
---|
49 | int pb_bus;
|
---|
50 | u8_t (*pb_rreg8)(int busind, int devind, int port);
|
---|
51 | u16_t (*pb_rreg16)(int busind, int devind, int port);
|
---|
52 | u32_t (*pb_rreg32)(int busind, int devind, int port);
|
---|
53 | void (*pb_wreg16)(int busind, int devind, int port, U16_t value);
|
---|
54 | void (*pb_wreg32)(int busind, int devind, int port, u32_t value);
|
---|
55 | u16_t (*pb_rsts)(int busind);
|
---|
56 | void (*pb_wsts)(int busind, U16_t value);
|
---|
57 | } pcibus[NR_PCIBUS];
|
---|
58 | PRIVATE int nr_pcibus= 0;
|
---|
59 |
|
---|
60 | PRIVATE struct pcidev
|
---|
61 | {
|
---|
62 | u8_t pd_busind;
|
---|
63 | u8_t pd_dev;
|
---|
64 | u8_t pd_func;
|
---|
65 | u8_t pd_baseclass;
|
---|
66 | u8_t pd_subclass;
|
---|
67 | u8_t pd_infclass;
|
---|
68 | u16_t pd_vid;
|
---|
69 | u16_t pd_did;
|
---|
70 | u8_t pd_inuse;
|
---|
71 | } pcidev[NR_PCIDEV];
|
---|
72 | PRIVATE int nr_pcidev= 0;
|
---|
73 |
|
---|
74 | /* Work around the limitation of the PCI emulation in QEMU 0.7.1 */
|
---|
75 | PRIVATE int qemu_pci= 0;
|
---|
76 |
|
---|
77 | FORWARD _PROTOTYPE( void pci_intel_init, (void) );
|
---|
78 | FORWARD _PROTOTYPE( void probe_bus, (int busind) );
|
---|
79 | FORWARD _PROTOTYPE( int do_isabridge, (int busind) );
|
---|
80 | FORWARD _PROTOTYPE( void do_pcibridge, (int busind) );
|
---|
81 | FORWARD _PROTOTYPE( int do_piix, (int devind) );
|
---|
82 | FORWARD _PROTOTYPE( int do_amd_isabr, (int devind) );
|
---|
83 | FORWARD _PROTOTYPE( int do_sis_isabr, (int devind) );
|
---|
84 | FORWARD _PROTOTYPE( int do_via_isabr, (int devind) );
|
---|
85 | FORWARD _PROTOTYPE( char *pci_vid_name, (U16_t vid) );
|
---|
86 | FORWARD _PROTOTYPE( char *pci_baseclass_name, (U8_t baseclass) );
|
---|
87 | FORWARD _PROTOTYPE( char *pci_subclass_name, (U8_t baseclass,
|
---|
88 | U8_t subclass, U8_t infclass) );
|
---|
89 | FORWARD _PROTOTYPE( void ntostr, (unsigned n, char **str, char *end) );
|
---|
90 | FORWARD _PROTOTYPE( u16_t pci_attr_rsts, (int devind) );
|
---|
91 | FORWARD _PROTOTYPE( void pci_attr_wsts, (int devind, U16_t value) );
|
---|
92 | FORWARD _PROTOTYPE( u16_t pcibr_intel_rsts, (int busind) );
|
---|
93 | FORWARD _PROTOTYPE( void pcibr_intel_wsts, (int busind, U16_t value) );
|
---|
94 | FORWARD _PROTOTYPE( u16_t pcibr_via_rsts, (int busind) );
|
---|
95 | FORWARD _PROTOTYPE( void pcibr_via_wsts, (int busind, U16_t value) );
|
---|
96 | FORWARD _PROTOTYPE( u8_t pcii_rreg8, (int busind, int devind, int port) );
|
---|
97 | FORWARD _PROTOTYPE( u16_t pcii_rreg16, (int busind, int devind,
|
---|
98 | int port) );
|
---|
99 | FORWARD _PROTOTYPE( u32_t pcii_rreg32, (int busind, int devind,
|
---|
100 | int port) );
|
---|
101 | FORWARD _PROTOTYPE( void pcii_wreg16, (int busind, int devind, int port,
|
---|
102 | U16_t value) );
|
---|
103 | FORWARD _PROTOTYPE( void pcii_wreg32, (int busind, int devind, int port,
|
---|
104 | u32_t value) );
|
---|
105 | FORWARD _PROTOTYPE( u16_t pcii_rsts, (int busind) );
|
---|
106 | FORWARD _PROTOTYPE( void pcii_wsts, (int busind, U16_t value) );
|
---|
107 |
|
---|
108 | /*===========================================================================*
|
---|
109 | * helper functions for I/O *
|
---|
110 | *===========================================================================*/
|
---|
111 | PUBLIC unsigned pci_inb(U16_t port) {
|
---|
112 | U8_t value;
|
---|
113 | int s;
|
---|
114 | if ((s=sys_inb(port, &value)) !=OK)
|
---|
115 | printf("PCI: warning, sys_inb failed: %d\n", s);
|
---|
116 | return value;
|
---|
117 | }
|
---|
118 | PUBLIC unsigned pci_inw(U16_t port) {
|
---|
119 | U16_t value;
|
---|
120 | int s;
|
---|
121 | if ((s=sys_inw(port, &value)) !=OK)
|
---|
122 | printf("PCI: warning, sys_inw failed: %d\n", s);
|
---|
123 | return value;
|
---|
124 | }
|
---|
125 | PUBLIC unsigned pci_inl(U16_t port) {
|
---|
126 | U32_t value;
|
---|
127 | int s;
|
---|
128 | if ((s=sys_inl(port, &value)) !=OK)
|
---|
129 | printf("PCI: warning, sys_inl failed: %d\n", s);
|
---|
130 | return value;
|
---|
131 | }
|
---|
132 | PUBLIC void pci_outb(U16_t port, U8_t value) {
|
---|
133 | int s;
|
---|
134 | if ((s=sys_outb(port, value)) !=OK)
|
---|
135 | printf("PCI: warning, sys_outb failed: %d\n", s);
|
---|
136 | }
|
---|
137 | PUBLIC void pci_outw(U16_t port, U16_t value) {
|
---|
138 | int s;
|
---|
139 | if ((s=sys_outw(port, value)) !=OK)
|
---|
140 | printf("PCI: warning, sys_outw failed: %d\n", s);
|
---|
141 | }
|
---|
142 | PUBLIC void pci_outl(U16_t port, U32_t value) {
|
---|
143 | int s;
|
---|
144 | if ((s=sys_outl(port, value)) !=OK)
|
---|
145 | printf("PCI: warning, sys_outl failed: %d\n", s);
|
---|
146 | }
|
---|
147 |
|
---|
148 | /*===========================================================================*
|
---|
149 | * pci_init *
|
---|
150 | *===========================================================================*/
|
---|
151 | PUBLIC void pci_init()
|
---|
152 | {
|
---|
153 | static int first_time= 1;
|
---|
154 |
|
---|
155 | long v;
|
---|
156 |
|
---|
157 | if (!first_time)
|
---|
158 | return;
|
---|
159 |
|
---|
160 | v= 0;
|
---|
161 | env_parse("qemu_pci", "d", 0, &v, 0, 1);
|
---|
162 | qemu_pci= v;
|
---|
163 |
|
---|
164 | v= 0;
|
---|
165 | env_parse("pci_debug", "d", 0, &v, 0, 1);
|
---|
166 | debug= v;
|
---|
167 |
|
---|
168 | /* We don't expect to interrupted */
|
---|
169 | assert(first_time == 1);
|
---|
170 | first_time= -1;
|
---|
171 |
|
---|
172 | /* Only Intel (compatible) PCI controllers are supported at the
|
---|
173 | * moment.
|
---|
174 | */
|
---|
175 | pci_intel_init();
|
---|
176 |
|
---|
177 | first_time= 0;
|
---|
178 | }
|
---|
179 |
|
---|
180 | /*===========================================================================*
|
---|
181 | * pci_find_dev *
|
---|
182 | *===========================================================================*/
|
---|
183 | PUBLIC int pci_find_dev(bus, dev, func, devindp)
|
---|
184 | u8_t bus;
|
---|
185 | u8_t dev;
|
---|
186 | u8_t func;
|
---|
187 | int *devindp;
|
---|
188 | {
|
---|
189 | int devind;
|
---|
190 |
|
---|
191 | for (devind= 0; devind < nr_pcidev; devind++)
|
---|
192 | {
|
---|
193 | if (pcidev[devind].pd_busind == bus &&
|
---|
194 | pcidev[devind].pd_dev == dev &&
|
---|
195 | pcidev[devind].pd_func == func)
|
---|
196 | {
|
---|
197 | break;
|
---|
198 | }
|
---|
199 | }
|
---|
200 | if (devind >= nr_pcidev)
|
---|
201 | return 0;
|
---|
202 | if (pcidev[devind].pd_inuse)
|
---|
203 | return 0;
|
---|
204 | *devindp= devind;
|
---|
205 | return 1;
|
---|
206 | }
|
---|
207 |
|
---|
208 | /*===========================================================================*
|
---|
209 | * pci_first_dev *
|
---|
210 | *===========================================================================*/
|
---|
211 | PUBLIC int pci_first_dev(devindp, vidp, didp)
|
---|
212 | int *devindp;
|
---|
213 | u16_t *vidp;
|
---|
214 | u16_t *didp;
|
---|
215 | {
|
---|
216 | int devind;
|
---|
217 |
|
---|
218 | for (devind= 0; devind < nr_pcidev; devind++)
|
---|
219 | {
|
---|
220 | if (!pcidev[devind].pd_inuse)
|
---|
221 | break;
|
---|
222 | }
|
---|
223 | if (devind >= nr_pcidev)
|
---|
224 | return 0;
|
---|
225 | *devindp= devind;
|
---|
226 | *vidp= pcidev[devind].pd_vid;
|
---|
227 | *didp= pcidev[devind].pd_did;
|
---|
228 | return 1;
|
---|
229 | }
|
---|
230 |
|
---|
231 | /*===========================================================================*
|
---|
232 | * pci_next_dev *
|
---|
233 | *===========================================================================*/
|
---|
234 | PUBLIC int pci_next_dev(devindp, vidp, didp)
|
---|
235 | int *devindp;
|
---|
236 | u16_t *vidp;
|
---|
237 | u16_t *didp;
|
---|
238 | {
|
---|
239 | int devind;
|
---|
240 |
|
---|
241 | for (devind= *devindp+1; devind < nr_pcidev; devind++)
|
---|
242 | {
|
---|
243 | if (!pcidev[devind].pd_inuse)
|
---|
244 | break;
|
---|
245 | }
|
---|
246 | if (devind >= nr_pcidev)
|
---|
247 | return 0;
|
---|
248 | *devindp= devind;
|
---|
249 | *vidp= pcidev[devind].pd_vid;
|
---|
250 | *didp= pcidev[devind].pd_did;
|
---|
251 | return 1;
|
---|
252 | }
|
---|
253 |
|
---|
254 | /*===========================================================================*
|
---|
255 | * pci_reserve *
|
---|
256 | *===========================================================================*/
|
---|
257 | PUBLIC void pci_reserve(devind)
|
---|
258 | int devind;
|
---|
259 | {
|
---|
260 | assert(devind <= nr_pcidev);
|
---|
261 | assert(!pcidev[devind].pd_inuse);
|
---|
262 | pcidev[devind].pd_inuse= 1;
|
---|
263 | }
|
---|
264 |
|
---|
265 | /*===========================================================================*
|
---|
266 | * pci_ids *
|
---|
267 | *===========================================================================*/
|
---|
268 | PUBLIC void pci_ids(devind, vidp, didp)
|
---|
269 | int devind;
|
---|
270 | u16_t *vidp;
|
---|
271 | u16_t *didp;
|
---|
272 | {
|
---|
273 | assert(devind <= nr_pcidev);
|
---|
274 | *vidp= pcidev[devind].pd_vid;
|
---|
275 | *didp= pcidev[devind].pd_did;
|
---|
276 | }
|
---|
277 |
|
---|
278 | /*===========================================================================*
|
---|
279 | * pci_slot_name *
|
---|
280 | *===========================================================================*/
|
---|
281 | PUBLIC char *pci_slot_name(devind)
|
---|
282 | int devind;
|
---|
283 | {
|
---|
284 | static char label[]= "ddd.ddd.ddd";
|
---|
285 | char *end;
|
---|
286 | char *p;
|
---|
287 |
|
---|
288 | p= label;
|
---|
289 | end= label+sizeof(label);
|
---|
290 |
|
---|
291 | ntostr(pcidev[devind].pd_busind, &p, end);
|
---|
292 | *p++= '.';
|
---|
293 |
|
---|
294 | ntostr(pcidev[devind].pd_dev, &p, end);
|
---|
295 | *p++= '.';
|
---|
296 |
|
---|
297 | ntostr(pcidev[devind].pd_func, &p, end);
|
---|
298 |
|
---|
299 | return label;
|
---|
300 | }
|
---|
301 |
|
---|
302 | /*===========================================================================*
|
---|
303 | * pci_dev_name *
|
---|
304 | *===========================================================================*/
|
---|
305 | PUBLIC char *pci_dev_name(vid, did)
|
---|
306 | u16_t vid;
|
---|
307 | u16_t did;
|
---|
308 | {
|
---|
309 | int i;
|
---|
310 |
|
---|
311 | for (i= 0; pci_device_table[i].name; i++)
|
---|
312 | {
|
---|
313 | if (pci_device_table[i].vid == vid &&
|
---|
314 | pci_device_table[i].did == did)
|
---|
315 | {
|
---|
316 | return pci_device_table[i].name;
|
---|
317 | }
|
---|
318 | }
|
---|
319 | return NULL;
|
---|
320 | }
|
---|
321 |
|
---|
322 | /*===========================================================================*
|
---|
323 | * pci_attr_r8 *
|
---|
324 | *===========================================================================*/
|
---|
325 | PUBLIC u8_t pci_attr_r8(devind, port)
|
---|
326 | int devind;
|
---|
327 | int port;
|
---|
328 | {
|
---|
329 | int busind;
|
---|
330 |
|
---|
331 | busind= pcidev[devind].pd_busind;
|
---|
332 | return pcibus[busind].pb_rreg8(busind, devind, port);
|
---|
333 | }
|
---|
334 |
|
---|
335 | /*===========================================================================*
|
---|
336 | * pci_attr_r16 *
|
---|
337 | *===========================================================================*/
|
---|
338 | PUBLIC u16_t pci_attr_r16(devind, port)
|
---|
339 | int devind;
|
---|
340 | int port;
|
---|
341 | {
|
---|
342 | int busind;
|
---|
343 |
|
---|
344 | busind= pcidev[devind].pd_busind;
|
---|
345 | return pcibus[busind].pb_rreg16(busind, devind, port);
|
---|
346 | }
|
---|
347 |
|
---|
348 | /*===========================================================================*
|
---|
349 | * pci_attr_r32 *
|
---|
350 | *===========================================================================*/
|
---|
351 | PUBLIC u32_t pci_attr_r32(devind, port)
|
---|
352 | int devind;
|
---|
353 | int port;
|
---|
354 | {
|
---|
355 | int busind;
|
---|
356 |
|
---|
357 | busind= pcidev[devind].pd_busind;
|
---|
358 | return pcibus[busind].pb_rreg32(busind, devind, port);
|
---|
359 | }
|
---|
360 |
|
---|
361 | /*===========================================================================*
|
---|
362 | * pci_attr_w16 *
|
---|
363 | *===========================================================================*/
|
---|
364 | PUBLIC void pci_attr_w16(devind, port, value)
|
---|
365 | int devind;
|
---|
366 | int port;
|
---|
367 | u16_t value;
|
---|
368 | {
|
---|
369 | int busind;
|
---|
370 |
|
---|
371 | busind= pcidev[devind].pd_busind;
|
---|
372 | pcibus[busind].pb_wreg16(busind, devind, port, value);
|
---|
373 | }
|
---|
374 |
|
---|
375 | /*===========================================================================*
|
---|
376 | * pci_attr_w32 *
|
---|
377 | *===========================================================================*/
|
---|
378 | PUBLIC void pci_attr_w32(devind, port, value)
|
---|
379 | int devind;
|
---|
380 | int port;
|
---|
381 | u32_t value;
|
---|
382 | {
|
---|
383 | int busind;
|
---|
384 |
|
---|
385 | busind= pcidev[devind].pd_busind;
|
---|
386 | pcibus[busind].pb_wreg32(busind, devind, port, value);
|
---|
387 | }
|
---|
388 |
|
---|
389 | /*===========================================================================*
|
---|
390 | * pci_intel_init *
|
---|
391 | *===========================================================================*/
|
---|
392 | PRIVATE void pci_intel_init()
|
---|
393 | {
|
---|
394 | /* Try to detect a know PCI controller. Read the Vendor ID and
|
---|
395 | * the Device ID for function 0 of device 0.
|
---|
396 | * Two times the value 0xffff suggests a system without a (compatible)
|
---|
397 | * PCI controller. Only controllers with values listed in the table
|
---|
398 | * pci_intel_ctrl are actually used.
|
---|
399 | */
|
---|
400 | u32_t bus, dev, func;
|
---|
401 | u16_t vid, did;
|
---|
402 | int s, i, r, busind;
|
---|
403 | char *dstr;
|
---|
404 |
|
---|
405 | bus= 0;
|
---|
406 | dev= 0;
|
---|
407 | func= 0;
|
---|
408 |
|
---|
409 | vid= PCII_RREG16_(bus, dev, func, PCI_VID);
|
---|
410 | did= PCII_RREG16_(bus, dev, func, PCI_DID);
|
---|
411 | #if USER_SPACE
|
---|
412 | if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
|
---|
413 | printf("PCI: warning, sys_outl failed: %d\n", s);
|
---|
414 | #else
|
---|
415 | outl(PCII_CONFADD, PCII_UNSEL);
|
---|
416 | #endif
|
---|
417 |
|
---|
418 | if (vid == 0xffff && did == 0xffff)
|
---|
419 | return; /* Nothing here */
|
---|
420 |
|
---|
421 | for (i= 0; pci_intel_ctrl[i].vid; i++)
|
---|
422 | {
|
---|
423 | if (pci_intel_ctrl[i].vid == vid &&
|
---|
424 | pci_intel_ctrl[i].did == did)
|
---|
425 | {
|
---|
426 | break;
|
---|
427 | }
|
---|
428 | }
|
---|
429 |
|
---|
430 | if (!pci_intel_ctrl[i].vid)
|
---|
431 | {
|
---|
432 | printf("pci_intel_init (warning): unknown PCI-controller:\n"
|
---|
433 | "\tvendor %04X (%s), device %04X\n",
|
---|
434 | vid, pci_vid_name(vid), did);
|
---|
435 | }
|
---|
436 |
|
---|
437 | if (nr_pcibus >= NR_PCIBUS)
|
---|
438 | panic("PCI","too many PCI busses", nr_pcibus);
|
---|
439 | busind= nr_pcibus;
|
---|
440 | nr_pcibus++;
|
---|
441 | pcibus[busind].pb_type= PBT_INTEL;
|
---|
442 | pcibus[busind].pb_isabridge_dev= -1;
|
---|
443 | pcibus[busind].pb_isabridge_type= 0;
|
---|
444 | pcibus[busind].pb_devind= -1;
|
---|
445 | pcibus[busind].pb_bus= 0;
|
---|
446 | pcibus[busind].pb_rreg8= pcii_rreg8;
|
---|
447 | pcibus[busind].pb_rreg16= pcii_rreg16;
|
---|
448 | pcibus[busind].pb_rreg32= pcii_rreg32;
|
---|
449 | pcibus[busind].pb_wreg16= pcii_wreg16;
|
---|
450 | pcibus[busind].pb_wreg32= pcii_wreg32;
|
---|
451 | pcibus[busind].pb_rsts= pcii_rsts;
|
---|
452 | pcibus[busind].pb_wsts= pcii_wsts;
|
---|
453 |
|
---|
454 | dstr= pci_dev_name(vid, did);
|
---|
455 | if (!dstr)
|
---|
456 | dstr= "unknown device";
|
---|
457 | if (debug)
|
---|
458 | {
|
---|
459 | printf("pci_intel_init: %s (%04X/%04X)\n",
|
---|
460 | dstr, vid, did);
|
---|
461 | }
|
---|
462 |
|
---|
463 | probe_bus(busind);
|
---|
464 |
|
---|
465 | r= do_isabridge(busind);
|
---|
466 | if (r != OK)
|
---|
467 | {
|
---|
468 | /* Disable all devices for this bus */
|
---|
469 | for (i= 0; i<nr_pcidev; i++)
|
---|
470 | {
|
---|
471 | if (pcidev[i].pd_busind != busind)
|
---|
472 | continue;
|
---|
473 | pcidev[i].pd_inuse= 1;
|
---|
474 | }
|
---|
475 | return;
|
---|
476 | }
|
---|
477 |
|
---|
478 | /* Look for PCI bridges (for AGP) */
|
---|
479 | do_pcibridge(busind);
|
---|
480 | }
|
---|
481 |
|
---|
482 | /*===========================================================================*
|
---|
483 | * probe_bus *
|
---|
484 | *===========================================================================*/
|
---|
485 | PRIVATE void probe_bus(busind)
|
---|
486 | int busind;
|
---|
487 | {
|
---|
488 | u32_t dev, func;
|
---|
489 | u16_t vid, did, sts;
|
---|
490 | u8_t headt;
|
---|
491 | u8_t baseclass, subclass, infclass;
|
---|
492 | int devind;
|
---|
493 | char *s, *dstr;
|
---|
494 |
|
---|
495 | #if DEBUG
|
---|
496 | printf("probe_bus(%d)\n", busind);
|
---|
497 | #endif
|
---|
498 | if (nr_pcidev >= NR_PCIDEV)
|
---|
499 | panic("PCI","too many PCI devices", nr_pcidev);
|
---|
500 | devind= nr_pcidev;
|
---|
501 |
|
---|
502 | for (dev= 0; dev<32; dev++)
|
---|
503 | {
|
---|
504 |
|
---|
505 | for (func= 0; func < 8; func++)
|
---|
506 | {
|
---|
507 | pcidev[devind].pd_busind= busind;
|
---|
508 | pcidev[devind].pd_dev= dev;
|
---|
509 | pcidev[devind].pd_func= func;
|
---|
510 |
|
---|
511 | pci_attr_wsts(devind,
|
---|
512 | PSR_SSE|PSR_RMAS|PSR_RTAS);
|
---|
513 | vid= pci_attr_r16(devind, PCI_VID);
|
---|
514 | did= pci_attr_r16(devind, PCI_DID);
|
---|
515 | headt= pci_attr_r8(devind, PCI_HEADT);
|
---|
516 | sts= pci_attr_rsts(devind);
|
---|
517 |
|
---|
518 | if (vid == NO_VID)
|
---|
519 | break; /* Nothing here */
|
---|
520 |
|
---|
521 | if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
|
---|
522 | {
|
---|
523 | if (qemu_pci)
|
---|
524 | {
|
---|
525 | printf(
|
---|
526 | "pci: ignoring bad value 0x%x in sts for QEMU\n",
|
---|
527 | sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
|
---|
528 | }
|
---|
529 | else
|
---|
530 | break;
|
---|
531 | }
|
---|
532 |
|
---|
533 | dstr= pci_dev_name(vid, did);
|
---|
534 | if (debug)
|
---|
535 | {
|
---|
536 | if (dstr)
|
---|
537 | {
|
---|
538 | printf("%d.%lu.%lu: %s (%04X/%04X)\n",
|
---|
539 | busind, (unsigned long)dev,
|
---|
540 | (unsigned long)func, dstr,
|
---|
541 | vid, did);
|
---|
542 | }
|
---|
543 | else
|
---|
544 | {
|
---|
545 | printf(
|
---|
546 | "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
|
---|
547 | busind, (unsigned long)dev,
|
---|
548 | (unsigned long)func, vid,
|
---|
549 | pci_vid_name(vid), did);
|
---|
550 | }
|
---|
551 | }
|
---|
552 |
|
---|
553 | baseclass= pci_attr_r8(devind, PCI_BCR);
|
---|
554 | subclass= pci_attr_r8(devind, PCI_SCR);
|
---|
555 | infclass= pci_attr_r8(devind, PCI_PIFR);
|
---|
556 | s= pci_subclass_name(baseclass, subclass, infclass);
|
---|
557 | if (!s)
|
---|
558 | s= pci_baseclass_name(baseclass);
|
---|
559 | {
|
---|
560 | if (!s)
|
---|
561 | s= "(unknown class)";
|
---|
562 | }
|
---|
563 | if (debug)
|
---|
564 | {
|
---|
565 | printf("\tclass %s (%X/%X/%X)\n", s,
|
---|
566 | baseclass, subclass, infclass);
|
---|
567 | }
|
---|
568 |
|
---|
569 | devind= nr_pcidev;
|
---|
570 | nr_pcidev++;
|
---|
571 | pcidev[devind].pd_baseclass= baseclass;
|
---|
572 | pcidev[devind].pd_subclass= subclass;
|
---|
573 | pcidev[devind].pd_infclass= infclass;
|
---|
574 | pcidev[devind].pd_vid= vid;
|
---|
575 | pcidev[devind].pd_did= did;
|
---|
576 | pcidev[devind].pd_inuse= 0;
|
---|
577 |
|
---|
578 | if (nr_pcidev >= NR_PCIDEV)
|
---|
579 | panic("PCI","too many PCI devices", nr_pcidev);
|
---|
580 | devind= nr_pcidev;
|
---|
581 |
|
---|
582 | if (func == 0 && !(headt & PHT_MULTIFUNC))
|
---|
583 | break;
|
---|
584 | }
|
---|
585 | }
|
---|
586 | }
|
---|
587 |
|
---|
588 | /*===========================================================================*
|
---|
589 | * do_isabridge *
|
---|
590 | *===========================================================================*/
|
---|
591 | PRIVATE int do_isabridge(busind)
|
---|
592 | int busind;
|
---|
593 | {
|
---|
594 | int unknown_bridge= -1;
|
---|
595 | int bridge_dev= -1;
|
---|
596 | int i, j, r, type;
|
---|
597 | u16_t vid, did;
|
---|
598 | char *dstr;
|
---|
599 |
|
---|
600 | j= 0; /* lint */
|
---|
601 | vid= did= 0; /* lint */
|
---|
602 | for (i= 0; i< nr_pcidev; i++)
|
---|
603 | {
|
---|
604 | if (pcidev[i].pd_busind != busind)
|
---|
605 | continue;
|
---|
606 | if (pcidev[i].pd_baseclass == 0x06 &&
|
---|
607 | pcidev[i].pd_subclass == 0x01 &&
|
---|
608 | pcidev[i].pd_infclass == 0x00)
|
---|
609 | {
|
---|
610 | /* ISA bridge. Report if no supported bridge is
|
---|
611 | * found.
|
---|
612 | */
|
---|
613 | unknown_bridge= i;
|
---|
614 | }
|
---|
615 |
|
---|
616 | vid= pcidev[i].pd_vid;
|
---|
617 | did= pcidev[i].pd_did;
|
---|
618 | for (j= 0; pci_isabridge[j].vid != 0; j++)
|
---|
619 | {
|
---|
620 | if (pci_isabridge[j].vid != vid)
|
---|
621 | continue;
|
---|
622 | if (pci_isabridge[j].did != did)
|
---|
623 | continue;
|
---|
624 | if (pci_isabridge[j].checkclass &&
|
---|
625 | unknown_bridge != i)
|
---|
626 | {
|
---|
627 | /* This part of multifunction device is
|
---|
628 | * not the bridge.
|
---|
629 | */
|
---|
630 | continue;
|
---|
631 | }
|
---|
632 | break;
|
---|
633 | }
|
---|
634 | if (pci_isabridge[j].vid)
|
---|
635 | {
|
---|
636 | bridge_dev= i;
|
---|
637 | break;
|
---|
638 | }
|
---|
639 | }
|
---|
640 |
|
---|
641 | if (bridge_dev != -1)
|
---|
642 | {
|
---|
643 | dstr= pci_dev_name(vid, did);
|
---|
644 | if (!dstr)
|
---|
645 | dstr= "unknown device";
|
---|
646 | if (debug)
|
---|
647 | {
|
---|
648 | printf("found ISA bridge (%04X/%04X) %s\n",
|
---|
649 | vid, did, dstr);
|
---|
650 | }
|
---|
651 | pcibus[busind].pb_isabridge_dev= bridge_dev;
|
---|
652 | type= pci_isabridge[j].type;
|
---|
653 | pcibus[busind].pb_isabridge_type= type;
|
---|
654 | switch(type)
|
---|
655 | {
|
---|
656 | case PCI_IB_PIIX:
|
---|
657 | r= do_piix(bridge_dev);
|
---|
658 | break;
|
---|
659 | case PCI_IB_VIA:
|
---|
660 | r= do_via_isabr(bridge_dev);
|
---|
661 | break;
|
---|
662 | case PCI_IB_AMD:
|
---|
663 | r= do_amd_isabr(bridge_dev);
|
---|
664 | break;
|
---|
665 | case PCI_IB_SIS:
|
---|
666 | r= do_sis_isabr(bridge_dev);
|
---|
667 | break;
|
---|
668 | default:
|
---|
669 | panic("PCI","unknown ISA bridge type", type);
|
---|
670 | }
|
---|
671 | return r;
|
---|
672 | }
|
---|
673 |
|
---|
674 | if (unknown_bridge == -1)
|
---|
675 | {
|
---|
676 | printf("(warning) no ISA bridge found on bus %d", busind);
|
---|
677 | return 0;
|
---|
678 | }
|
---|
679 | printf("(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
|
---|
680 | pcidev[unknown_bridge].pd_vid,
|
---|
681 | pcidev[unknown_bridge].pd_did,
|
---|
682 | busind);
|
---|
683 | return 0;
|
---|
684 | }
|
---|
685 |
|
---|
686 | /*===========================================================================*
|
---|
687 | * do_pcibridge *
|
---|
688 | *===========================================================================*/
|
---|
689 | PRIVATE void do_pcibridge(busind)
|
---|
690 | int busind;
|
---|
691 | {
|
---|
692 | int devind, i;
|
---|
693 | int ind, type;
|
---|
694 | u16_t vid, did;
|
---|
695 | u8_t sbusn, baseclass, subclass, infclass;
|
---|
696 | u32_t t3;
|
---|
697 |
|
---|
698 | vid= did= 0; /* lint */
|
---|
699 | for (devind= 0; devind< nr_pcidev; devind++)
|
---|
700 | {
|
---|
701 | if (pcidev[devind].pd_busind != busind)
|
---|
702 | continue;
|
---|
703 |
|
---|
704 | vid= pcidev[devind].pd_vid;
|
---|
705 | did= pcidev[devind].pd_did;
|
---|
706 | for (i= 0; pci_pcibridge[i].vid != 0; i++)
|
---|
707 | {
|
---|
708 | if (pci_pcibridge[i].vid != vid)
|
---|
709 | continue;
|
---|
710 | if (pci_pcibridge[i].did != did)
|
---|
711 | continue;
|
---|
712 | break;
|
---|
713 | }
|
---|
714 | if (pci_pcibridge[i].vid == 0)
|
---|
715 | {
|
---|
716 | if (debug)
|
---|
717 | {
|
---|
718 | /* Report unsupported bridges */
|
---|
719 | baseclass= pci_attr_r8(devind, PCI_BCR);
|
---|
720 | subclass= pci_attr_r8(devind, PCI_SCR);
|
---|
721 | infclass= pci_attr_r8(devind, PCI_PIFR);
|
---|
722 | t3= ((baseclass << 16) | (subclass << 8) |
|
---|
723 | infclass);
|
---|
724 | if (t3 != PCI_T3_PCI2PCI &&
|
---|
725 | t3 != PCI_T3_PCI2PCI_SUBTR)
|
---|
726 | {
|
---|
727 | /* No a PCI-to-PCI bridge */
|
---|
728 | continue;
|
---|
729 | }
|
---|
730 | printf(
|
---|
731 | "Ignoring unknown PCI-to-PCI bridge: %04X/%04X\n",
|
---|
732 | vid, did);
|
---|
733 | }
|
---|
734 | continue;
|
---|
735 | }
|
---|
736 | type= pci_pcibridge[i].type;
|
---|
737 |
|
---|
738 | if (debug)
|
---|
739 | printf("PCI-to-PCI bridge: %04X/%04X\n", vid, did);
|
---|
740 |
|
---|
741 | /* Assume that the BIOS initialized the secondary bus
|
---|
742 | * number.
|
---|
743 | */
|
---|
744 | sbusn= pci_attr_r8(devind, PPB_SBUSN);
|
---|
745 | #if DEBUG
|
---|
746 | printf("sbusn = %d\n", sbusn);
|
---|
747 | #endif
|
---|
748 |
|
---|
749 | if (nr_pcibus >= NR_PCIBUS)
|
---|
750 | panic("PCI","too many PCI busses", nr_pcibus);
|
---|
751 | ind= nr_pcibus;
|
---|
752 | nr_pcibus++;
|
---|
753 | pcibus[ind].pb_type= PBT_PCIBRIDGE;
|
---|
754 | pcibus[ind].pb_isabridge_dev= -1;
|
---|
755 | pcibus[ind].pb_isabridge_type= 0;
|
---|
756 | pcibus[ind].pb_devind= devind;
|
---|
757 | pcibus[ind].pb_bus= sbusn;
|
---|
758 | pcibus[ind].pb_rreg8= pcibus[busind].pb_rreg8;
|
---|
759 | pcibus[ind].pb_rreg16= pcibus[busind].pb_rreg16;
|
---|
760 | pcibus[ind].pb_rreg32= pcibus[busind].pb_rreg32;
|
---|
761 | pcibus[ind].pb_wreg16= pcibus[busind].pb_wreg16;
|
---|
762 | pcibus[ind].pb_wreg32= pcibus[busind].pb_wreg32;
|
---|
763 | switch(type)
|
---|
764 | {
|
---|
765 | case PCI_PCIB_INTEL:
|
---|
766 | case PCI_AGPB_INTEL:
|
---|
767 | pcibus[ind].pb_rsts= pcibr_intel_rsts;
|
---|
768 | pcibus[ind].pb_wsts= pcibr_intel_wsts;
|
---|
769 | break;
|
---|
770 | case PCI_AGPB_VIA:
|
---|
771 | pcibus[ind].pb_rsts= pcibr_via_rsts;
|
---|
772 | pcibus[ind].pb_wsts= pcibr_via_wsts;
|
---|
773 | break;
|
---|
774 | default:
|
---|
775 | panic("PCI","unknown PCI-PCI bridge type", type);
|
---|
776 | }
|
---|
777 |
|
---|
778 | probe_bus(ind);
|
---|
779 | }
|
---|
780 | }
|
---|
781 |
|
---|
782 | /*===========================================================================*
|
---|
783 | * do_piix *
|
---|
784 | *===========================================================================*/
|
---|
785 | PRIVATE int do_piix(devind)
|
---|
786 | int devind;
|
---|
787 | {
|
---|
788 | int i, s, dev, func, irqrc, irq;
|
---|
789 | u16_t elcr1, elcr2, elcr;
|
---|
790 |
|
---|
791 | #if DEBUG
|
---|
792 | printf("in piix\n");
|
---|
793 | #endif
|
---|
794 | dev= pcidev[devind].pd_dev;
|
---|
795 | func= pcidev[devind].pd_func;
|
---|
796 | #if USER_SPACE
|
---|
797 | if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
|
---|
798 | printf("Warning, sys_inb failed: %d\n", s);
|
---|
799 | if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
|
---|
800 | printf("Warning, sys_inb failed: %d\n", s);
|
---|
801 | #else
|
---|
802 | elcr1= inb(PIIX_ELCR1);
|
---|
803 | elcr2= inb(PIIX_ELCR2);
|
---|
804 | #endif
|
---|
805 | elcr= elcr1 | (elcr2 << 8);
|
---|
806 | for (i= 0; i<4; i++)
|
---|
807 | {
|
---|
808 | irqrc= pci_attr_r8(devind, PIIX_PIRQRCA+i);
|
---|
809 | if (irqrc & PIIX_IRQ_DI)
|
---|
810 | {
|
---|
811 | if (debug)
|
---|
812 | printf("INT%c: disabled\n", 'A'+i);
|
---|
813 | }
|
---|
814 | else
|
---|
815 | {
|
---|
816 | irq= irqrc & PIIX_IRQ_MASK;
|
---|
817 | if (debug)
|
---|
818 | printf("INT%c: %d\n", 'A'+i, irq);
|
---|
819 | if (!(elcr & (1 << irq)))
|
---|
820 | {
|
---|
821 | if (debug)
|
---|
822 | {
|
---|
823 | printf(
|
---|
824 | "(warning) IRQ %d is not level triggered\n",
|
---|
825 | irq);
|
---|
826 | }
|
---|
827 | }
|
---|
828 | irq_mode_pci(irq);
|
---|
829 | }
|
---|
830 | }
|
---|
831 | return 0;
|
---|
832 | }
|
---|
833 |
|
---|
834 | /*===========================================================================*
|
---|
835 | * do_amd_isabr *
|
---|
836 | *===========================================================================*/
|
---|
837 | PRIVATE int do_amd_isabr(devind)
|
---|
838 | int devind;
|
---|
839 | {
|
---|
840 | int i, bus, dev, func, xdevind, irq, edge;
|
---|
841 | u8_t levmask;
|
---|
842 | u16_t pciirq;
|
---|
843 |
|
---|
844 | /* Find required function */
|
---|
845 | func= AMD_ISABR_FUNC;
|
---|
846 | bus= pcidev[devind].pd_busind;
|
---|
847 | dev= pcidev[devind].pd_dev;
|
---|
848 |
|
---|
849 | /* Fake a device with the required function */
|
---|
850 | if (nr_pcidev >= NR_PCIDEV)
|
---|
851 | panic("PCI","too many PCI devices", nr_pcidev);
|
---|
852 | xdevind= nr_pcidev;
|
---|
853 | pcidev[xdevind].pd_busind= bus;
|
---|
854 | pcidev[xdevind].pd_dev= dev;
|
---|
855 | pcidev[xdevind].pd_func= func;
|
---|
856 | pcidev[xdevind].pd_inuse= 1;
|
---|
857 | nr_pcidev++;
|
---|
858 |
|
---|
859 | levmask= pci_attr_r8(xdevind, AMD_ISABR_PCIIRQ_LEV);
|
---|
860 | pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
|
---|
861 | for (i= 0; i<4; i++)
|
---|
862 | {
|
---|
863 | edge= (levmask >> i) & 1;
|
---|
864 | irq= (pciirq >> (4*i)) & 0xf;
|
---|
865 | if (!irq)
|
---|
866 | {
|
---|
867 | if (debug)
|
---|
868 | printf("INT%c: disabled\n", 'A'+i);
|
---|
869 | }
|
---|
870 | else
|
---|
871 | {
|
---|
872 | if (debug)
|
---|
873 | printf("INT%c: %d\n", 'A'+i, irq);
|
---|
874 | if (edge && debug)
|
---|
875 | {
|
---|
876 | printf(
|
---|
877 | "(warning) IRQ %d is not level triggered\n",
|
---|
878 | irq);
|
---|
879 | }
|
---|
880 | irq_mode_pci(irq);
|
---|
881 | }
|
---|
882 | }
|
---|
883 | nr_pcidev--;
|
---|
884 | return 0;
|
---|
885 | }
|
---|
886 |
|
---|
887 | /*===========================================================================*
|
---|
888 | * do_sis_isabr *
|
---|
889 | *===========================================================================*/
|
---|
890 | PRIVATE int do_sis_isabr(devind)
|
---|
891 | int devind;
|
---|
892 | {
|
---|
893 | int i, dev, func, irq;
|
---|
894 |
|
---|
895 | dev= pcidev[devind].pd_dev;
|
---|
896 | func= pcidev[devind].pd_func;
|
---|
897 | irq= 0; /* lint */
|
---|
898 | for (i= 0; i<4; i++)
|
---|
899 | {
|
---|
900 | irq= pci_attr_r8(devind, SIS_ISABR_IRQ_A+i);
|
---|
901 | if (irq & SIS_IRQ_DISABLED)
|
---|
902 | {
|
---|
903 | if (debug)
|
---|
904 | printf("INT%c: disabled\n", 'A'+i);
|
---|
905 | }
|
---|
906 | else
|
---|
907 | {
|
---|
908 | irq &= SIS_IRQ_MASK;
|
---|
909 | if (debug)
|
---|
910 | printf("INT%c: %d\n", 'A'+i, irq);
|
---|
911 | irq_mode_pci(irq);
|
---|
912 | }
|
---|
913 | }
|
---|
914 | return 0;
|
---|
915 | }
|
---|
916 |
|
---|
917 | /*===========================================================================*
|
---|
918 | * do_via_isabr *
|
---|
919 | *===========================================================================*/
|
---|
920 | PRIVATE int do_via_isabr(devind)
|
---|
921 | int devind;
|
---|
922 | {
|
---|
923 | int i, dev, func, irq, edge;
|
---|
924 | u8_t levmask;
|
---|
925 |
|
---|
926 | dev= pcidev[devind].pd_dev;
|
---|
927 | func= pcidev[devind].pd_func;
|
---|
928 | levmask= pci_attr_r8(devind, VIA_ISABR_EL);
|
---|
929 | irq= 0; /* lint */
|
---|
930 | edge= 0; /* lint */
|
---|
931 | for (i= 0; i<4; i++)
|
---|
932 | {
|
---|
933 | switch(i)
|
---|
934 | {
|
---|
935 | case 0:
|
---|
936 | edge= (levmask & VIA_ISABR_EL_INTA);
|
---|
937 | irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R2) >> 4;
|
---|
938 | break;
|
---|
939 | case 1:
|
---|
940 | edge= (levmask & VIA_ISABR_EL_INTB);
|
---|
941 | irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R2);
|
---|
942 | break;
|
---|
943 | case 2:
|
---|
944 | edge= (levmask & VIA_ISABR_EL_INTC);
|
---|
945 | irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R3) >> 4;
|
---|
946 | break;
|
---|
947 | case 3:
|
---|
948 | edge= (levmask & VIA_ISABR_EL_INTD);
|
---|
949 | irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R1) >> 4;
|
---|
950 | break;
|
---|
951 | default:
|
---|
952 | assert(0);
|
---|
953 | }
|
---|
954 | irq &= 0xf;
|
---|
955 | if (!irq)
|
---|
956 | {
|
---|
957 | if (debug)
|
---|
958 | printf("INT%c: disabled\n", 'A'+i);
|
---|
959 | }
|
---|
960 | else
|
---|
961 | {
|
---|
962 | if (debug)
|
---|
963 | printf("INT%c: %d\n", 'A'+i, irq);
|
---|
964 | if (edge && debug)
|
---|
965 | {
|
---|
966 | printf(
|
---|
967 | "(warning) IRQ %d is not level triggered\n",
|
---|
968 | irq);
|
---|
969 | }
|
---|
970 | irq_mode_pci(irq);
|
---|
971 | }
|
---|
972 | }
|
---|
973 | return 0;
|
---|
974 | }
|
---|
975 |
|
---|
976 | /*===========================================================================*
|
---|
977 | * pci_vid_name *
|
---|
978 | *===========================================================================*/
|
---|
979 | PRIVATE char *pci_vid_name(vid)
|
---|
980 | u16_t vid;
|
---|
981 | {
|
---|
982 | int i;
|
---|
983 |
|
---|
984 | for (i= 0; pci_vendor_table[i].name; i++)
|
---|
985 | {
|
---|
986 | if (pci_vendor_table[i].vid == vid)
|
---|
987 | return pci_vendor_table[i].name;
|
---|
988 | }
|
---|
989 | return "unknown";
|
---|
990 | }
|
---|
991 |
|
---|
992 | /*===========================================================================*
|
---|
993 | * pci_baseclass_name *
|
---|
994 | *===========================================================================*/
|
---|
995 | PRIVATE char *pci_baseclass_name(baseclass)
|
---|
996 | u8_t baseclass;
|
---|
997 | {
|
---|
998 | int i;
|
---|
999 |
|
---|
1000 | for (i= 0; pci_baseclass_table[i].name; i++)
|
---|
1001 | {
|
---|
1002 | if (pci_baseclass_table[i].baseclass == baseclass)
|
---|
1003 | return pci_baseclass_table[i].name;
|
---|
1004 | }
|
---|
1005 | return NULL;
|
---|
1006 | }
|
---|
1007 |
|
---|
1008 | /*===========================================================================*
|
---|
1009 | * pci_subclass_name *
|
---|
1010 | *===========================================================================*/
|
---|
1011 | PRIVATE char *pci_subclass_name(baseclass, subclass, infclass)
|
---|
1012 | u8_t baseclass;
|
---|
1013 | u8_t subclass;
|
---|
1014 | u8_t infclass;
|
---|
1015 | {
|
---|
1016 | int i;
|
---|
1017 |
|
---|
1018 | for (i= 0; pci_subclass_table[i].name; i++)
|
---|
1019 | {
|
---|
1020 | if (pci_subclass_table[i].baseclass != baseclass)
|
---|
1021 | continue;
|
---|
1022 | if (pci_subclass_table[i].subclass != subclass)
|
---|
1023 | continue;
|
---|
1024 | if (pci_subclass_table[i].infclass != infclass &&
|
---|
1025 | pci_subclass_table[i].infclass != (u16_t)-1)
|
---|
1026 | {
|
---|
1027 | continue;
|
---|
1028 | }
|
---|
1029 | return pci_subclass_table[i].name;
|
---|
1030 | }
|
---|
1031 | return NULL;
|
---|
1032 | }
|
---|
1033 |
|
---|
1034 | /*===========================================================================*
|
---|
1035 | * ntostr *
|
---|
1036 | *===========================================================================*/
|
---|
1037 | PRIVATE void ntostr(n, str, end)
|
---|
1038 | unsigned n;
|
---|
1039 | char **str;
|
---|
1040 | char *end;
|
---|
1041 | {
|
---|
1042 | char tmpstr[20];
|
---|
1043 | int i;
|
---|
1044 |
|
---|
1045 | if (n == 0)
|
---|
1046 | {
|
---|
1047 | tmpstr[0]= '0';
|
---|
1048 | i= 1;
|
---|
1049 | }
|
---|
1050 | else
|
---|
1051 | {
|
---|
1052 | for (i= 0; n; i++)
|
---|
1053 | {
|
---|
1054 | tmpstr[i]= '0' + (n%10);
|
---|
1055 | n /= 10;
|
---|
1056 | }
|
---|
1057 | }
|
---|
1058 | for (; i>0; i--)
|
---|
1059 | {
|
---|
1060 | if (*str == end)
|
---|
1061 | {
|
---|
1062 | break;
|
---|
1063 | }
|
---|
1064 | **str= tmpstr[i-1];
|
---|
1065 | (*str)++;
|
---|
1066 | }
|
---|
1067 | if (*str == end)
|
---|
1068 | end[-1]= '\0';
|
---|
1069 | else
|
---|
1070 | **str= '\0';
|
---|
1071 | }
|
---|
1072 |
|
---|
1073 | /*===========================================================================*
|
---|
1074 | * pci_attr_rsts *
|
---|
1075 | *===========================================================================*/
|
---|
1076 | PRIVATE u16_t pci_attr_rsts(devind)
|
---|
1077 | int devind;
|
---|
1078 | {
|
---|
1079 | int busind;
|
---|
1080 |
|
---|
1081 | busind= pcidev[devind].pd_busind;
|
---|
1082 | return pcibus[busind].pb_rsts(busind);
|
---|
1083 | }
|
---|
1084 |
|
---|
1085 |
|
---|
1086 | /*===========================================================================*
|
---|
1087 | * pcibr_intel_rsts *
|
---|
1088 | *===========================================================================*/
|
---|
1089 | PRIVATE u16_t pcibr_intel_rsts(busind)
|
---|
1090 | int busind;
|
---|
1091 | {
|
---|
1092 | int devind;
|
---|
1093 | devind= pcibus[busind].pb_devind;
|
---|
1094 |
|
---|
1095 | return pci_attr_r16(devind, PPB_SSTS);
|
---|
1096 | }
|
---|
1097 |
|
---|
1098 | /*===========================================================================*
|
---|
1099 | * pcibr_intel_wsts *
|
---|
1100 | *===========================================================================*/
|
---|
1101 | PRIVATE void pcibr_intel_wsts(busind, value)
|
---|
1102 | int busind;
|
---|
1103 | u16_t value;
|
---|
1104 | {
|
---|
1105 | int devind;
|
---|
1106 | devind= pcibus[busind].pb_devind;
|
---|
1107 |
|
---|
1108 | #if 0
|
---|
1109 | printf("pcibr_intel_wsts(%d, 0x%X), devind= %d\n",
|
---|
1110 | busind, value, devind);
|
---|
1111 | #endif
|
---|
1112 | pci_attr_w16(devind, PPB_SSTS, value);
|
---|
1113 | }
|
---|
1114 |
|
---|
1115 | /*===========================================================================*
|
---|
1116 | * pcibr_via_rsts *
|
---|
1117 | *===========================================================================*/
|
---|
1118 | PRIVATE u16_t pcibr_via_rsts(busind)
|
---|
1119 | int busind;
|
---|
1120 | {
|
---|
1121 | int devind;
|
---|
1122 | devind= pcibus[busind].pb_devind;
|
---|
1123 |
|
---|
1124 | return 0;
|
---|
1125 | }
|
---|
1126 |
|
---|
1127 | /*===========================================================================*
|
---|
1128 | * pcibr_via_wsts *
|
---|
1129 | *===========================================================================*/
|
---|
1130 | PRIVATE void pcibr_via_wsts(busind, value)
|
---|
1131 | int busind;
|
---|
1132 | u16_t value;
|
---|
1133 | {
|
---|
1134 | int devind;
|
---|
1135 | devind= pcibus[busind].pb_devind;
|
---|
1136 |
|
---|
1137 | #if 0
|
---|
1138 | printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
|
---|
1139 | busind, value, devind);
|
---|
1140 | #endif
|
---|
1141 | }
|
---|
1142 |
|
---|
1143 | /*===========================================================================*
|
---|
1144 | * pci_attr_wsts *
|
---|
1145 | *===========================================================================*/
|
---|
1146 | PRIVATE void pci_attr_wsts(devind, value)
|
---|
1147 | int devind;
|
---|
1148 | u16_t value;
|
---|
1149 | {
|
---|
1150 | int busind;
|
---|
1151 |
|
---|
1152 | busind= pcidev[devind].pd_busind;
|
---|
1153 | pcibus[busind].pb_wsts(busind, value);
|
---|
1154 | }
|
---|
1155 |
|
---|
1156 |
|
---|
1157 | /*===========================================================================*
|
---|
1158 | * pcii_rreg8 *
|
---|
1159 | *===========================================================================*/
|
---|
1160 | PRIVATE u8_t pcii_rreg8(busind, devind, port)
|
---|
1161 | int busind;
|
---|
1162 | int devind;
|
---|
1163 | int port;
|
---|
1164 | {
|
---|
1165 | u8_t v;
|
---|
1166 | int s;
|
---|
1167 |
|
---|
1168 | v= PCII_RREG8_(pcibus[busind].pb_bus,
|
---|
1169 | pcidev[devind].pd_dev, pcidev[devind].pd_func,
|
---|
1170 | port);
|
---|
1171 | #if USER_SPACE
|
---|
1172 | if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
|
---|
1173 | printf("PCI: warning, sys_outl failed: %d\n", s);
|
---|
1174 | #else
|
---|
1175 | outl(PCII_CONFADD, PCII_UNSEL);
|
---|
1176 | #endif
|
---|
1177 | #if 0
|
---|
1178 | printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
|
---|
1179 | busind, devind, port,
|
---|
1180 | pcibus[busind].pb_bus, pcidev[devind].pd_dev,
|
---|
1181 | pcidev[devind].pd_func, v);
|
---|
1182 | #endif
|
---|
1183 | return v;
|
---|
1184 | }
|
---|
1185 |
|
---|
1186 | /*===========================================================================*
|
---|
1187 | * pcii_rreg16 *
|
---|
1188 | *===========================================================================*/
|
---|
1189 | PRIVATE u16_t pcii_rreg16(busind, devind, port)
|
---|
1190 | int busind;
|
---|
1191 | int devind;
|
---|
1192 | int port;
|
---|
1193 | {
|
---|
1194 | u16_t v;
|
---|
1195 | int s;
|
---|
1196 |
|
---|
1197 | v= PCII_RREG16_(pcibus[busind].pb_bus,
|
---|
1198 | pcidev[devind].pd_dev, pcidev[devind].pd_func,
|
---|
1199 | port);
|
---|
1200 | #if USER_SPACE
|
---|
1201 | if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
|
---|
1202 | printf("PCI: warning, sys_outl failed: %d\n");
|
---|
1203 | #else
|
---|
1204 | outl(PCII_CONFADD, PCII_UNSEL);
|
---|
1205 | #endif
|
---|
1206 | #if 0
|
---|
1207 | printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
|
---|
1208 | busind, devind, port,
|
---|
1209 | pcibus[busind].pb_bus, pcidev[devind].pd_dev,
|
---|
1210 | pcidev[devind].pd_func, v);
|
---|
1211 | #endif
|
---|
1212 | return v;
|
---|
1213 | }
|
---|
1214 |
|
---|
1215 | /*===========================================================================*
|
---|
1216 | * pcii_rreg32 *
|
---|
1217 | *===========================================================================*/
|
---|
1218 | PRIVATE u32_t pcii_rreg32(busind, devind, port)
|
---|
1219 | int busind;
|
---|
1220 | int devind;
|
---|
1221 | int port;
|
---|
1222 | {
|
---|
1223 | u32_t v;
|
---|
1224 | int s;
|
---|
1225 |
|
---|
1226 | v= PCII_RREG32_(pcibus[busind].pb_bus,
|
---|
1227 | pcidev[devind].pd_dev, pcidev[devind].pd_func,
|
---|
1228 | port);
|
---|
1229 | #if USER_SPACE
|
---|
1230 | if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
|
---|
1231 | printf("PCI: warning, sys_outl failed: %d\n", s);
|
---|
1232 | #else
|
---|
1233 | outl(PCII_CONFADD, PCII_UNSEL);
|
---|
1234 | #endif
|
---|
1235 | #if 0
|
---|
1236 | printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
|
---|
1237 | busind, devind, port,
|
---|
1238 | pcibus[busind].pb_bus, pcidev[devind].pd_dev,
|
---|
1239 | pcidev[devind].pd_func, v);
|
---|
1240 | #endif
|
---|
1241 | return v;
|
---|
1242 | }
|
---|
1243 |
|
---|
1244 | /*===========================================================================*
|
---|
1245 | * pcii_wreg16 *
|
---|
1246 | *===========================================================================*/
|
---|
1247 | PRIVATE void pcii_wreg16(busind, devind, port, value)
|
---|
1248 | int busind;
|
---|
1249 | int devind;
|
---|
1250 | int port;
|
---|
1251 | u16_t value;
|
---|
1252 | {
|
---|
1253 | int s;
|
---|
1254 | #if 0
|
---|
1255 | printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
|
---|
1256 | busind, devind, port, value,
|
---|
1257 | pcibus[busind].pb_bus, pcidev[devind].pd_dev,
|
---|
1258 | pcidev[devind].pd_func);
|
---|
1259 | #endif
|
---|
1260 | PCII_WREG16_(pcibus[busind].pb_bus,
|
---|
1261 | pcidev[devind].pd_dev, pcidev[devind].pd_func,
|
---|
1262 | port, value);
|
---|
1263 | #if USER_SPACE
|
---|
1264 | if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
|
---|
1265 | printf("PCI: warning, sys_outl failed: %d\n", s);
|
---|
1266 | #else
|
---|
1267 | outl(PCII_CONFADD, PCII_UNSEL);
|
---|
1268 | #endif
|
---|
1269 | }
|
---|
1270 |
|
---|
1271 | /*===========================================================================*
|
---|
1272 | * pcii_wreg32 *
|
---|
1273 | *===========================================================================*/
|
---|
1274 | PRIVATE void pcii_wreg32(busind, devind, port, value)
|
---|
1275 | int busind;
|
---|
1276 | int devind;
|
---|
1277 | int port;
|
---|
1278 | u32_t value;
|
---|
1279 | {
|
---|
1280 | int s;
|
---|
1281 | #if 0
|
---|
1282 | printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
|
---|
1283 | busind, devind, port, value,
|
---|
1284 | pcibus[busind].pb_bus, pcidev[devind].pd_dev,
|
---|
1285 | pcidev[devind].pd_func);
|
---|
1286 | #endif
|
---|
1287 | PCII_WREG32_(pcibus[busind].pb_bus,
|
---|
1288 | pcidev[devind].pd_dev, pcidev[devind].pd_func,
|
---|
1289 | port, value);
|
---|
1290 | #if USER_SPACE
|
---|
1291 | if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
|
---|
1292 | printf("PCI: warning, sys_outl failed: %d\n");
|
---|
1293 | #else
|
---|
1294 | outl(PCII_CONFADD, PCII_UNSEL);
|
---|
1295 | #endif
|
---|
1296 | }
|
---|
1297 |
|
---|
1298 | /*===========================================================================*
|
---|
1299 | * pcii_rsts *
|
---|
1300 | *===========================================================================*/
|
---|
1301 | PRIVATE u16_t pcii_rsts(busind)
|
---|
1302 | int busind;
|
---|
1303 | {
|
---|
1304 | u16_t v;
|
---|
1305 | int s;
|
---|
1306 |
|
---|
1307 | v= PCII_RREG16_(pcibus[busind].pb_bus, 0, 0, PCI_PCISTS);
|
---|
1308 | #if USER_SPACE
|
---|
1309 | if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
|
---|
1310 | printf("PCI: warning, sys_outl failed: %d\n", s);
|
---|
1311 | #else
|
---|
1312 | outl(PCII_CONFADD, PCII_UNSEL);
|
---|
1313 | #endif
|
---|
1314 | return v;
|
---|
1315 | }
|
---|
1316 |
|
---|
1317 | /*===========================================================================*
|
---|
1318 | * pcii_wsts *
|
---|
1319 | *===========================================================================*/
|
---|
1320 | PRIVATE void pcii_wsts(busind, value)
|
---|
1321 | int busind;
|
---|
1322 | u16_t value;
|
---|
1323 | {
|
---|
1324 | int s;
|
---|
1325 | PCII_WREG16_(pcibus[busind].pb_bus, 0, 0, PCI_PCISTS, value);
|
---|
1326 | #if USER_SPACE
|
---|
1327 | if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
|
---|
1328 | printf("PCI: warning, sys_outl failed: %d\n", s);
|
---|
1329 | #else
|
---|
1330 | outl(PCII_CONFADD, PCII_UNSEL);
|
---|
1331 | #endif
|
---|
1332 | }
|
---|
1333 |
|
---|
1334 | /*
|
---|
1335 | * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $
|
---|
1336 | */
|
---|