OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [ppc/] [kernel/] [pci.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1624 jcastillo
/*
2
 * PCI support
3
 * -- rough emulation of "PCI BIOS" functions
4
 *
5
 * Note: these are very motherboard specific!  Some way needs to
6
 * be worked out to handle the differences.
7
 */
8
 
9
#include <linux/types.h>
10
#include <linux/bios32.h>
11
#include <linux/pci.h>
12
 
13
/*
14
 * PCI interrupt configuration.  This is motherboard specific.
15
 */
16
 
17
 
18
/* Which PCI interrupt line does a given device [slot] use? */
19
/* Note: This really should be two dimensional based in slot/pin used */
20
unsigned char *Motherboard_map;
21
 
22
/* How is the 82378 PIRQ mapping setup? */
23
unsigned char *Motherboard_routes;
24
 
25
/* Tables for known hardware */
26
 
27
/* Motorola PowerStack */
28
static char Blackhawk_pci_IRQ_map[16] =
29
  {
30
        0,       /* Slot 0  - unused */
31
        0,       /* Slot 1  - unused */
32
        0,       /* Slot 2  - unused */
33
        0,       /* Slot 3  - unused */
34
        0,       /* Slot 4  - unused */
35
        0,       /* Slot 5  - unused */
36
        0,       /* Slot 6  - unused */
37
        0,       /* Slot 7  - unused */
38
        0,       /* Slot 8  - unused */
39
        0,       /* Slot 9  - unused */
40
        0,       /* Slot 10 - unused */
41
        0,       /* Slot 11 - unused */
42
        3,      /* Slot 12 - SCSI */
43
        0,       /* Slot 13 - unused */
44
        1,      /* Slot 14 - Ethernet */
45
        0,       /* Slot 15 - unused */
46
  };
47
 
48
static char Blackhawk_pci_IRQ_routes[] =
49
   {
50
        0,       /* Line 0 - Unused */
51
        9,      /* Line 1 */
52
        11,     /* Line 2 */
53
        14,     /* Line 3 */
54
        15      /* Line 4 */
55
   };
56
 
57
/* Motorola MVME16xx */
58
static char Genesis_pci_IRQ_map[16] =
59
  {
60
        0,       /* Slot 0  - unused */
61
        0,       /* Slot 1  - unused */
62
        0,       /* Slot 2  - unused */
63
        0,       /* Slot 3  - unused */
64
        0,       /* Slot 4  - unused */
65
        0,       /* Slot 5  - unused */
66
        0,       /* Slot 6  - unused */
67
        0,       /* Slot 7  - unused */
68
        0,       /* Slot 8  - unused */
69
        0,       /* Slot 9  - unused */
70
        0,       /* Slot 10 - unused */
71
        0,       /* Slot 11 - unused */
72
        3,      /* Slot 12 - SCSI */
73
        0,       /* Slot 13 - unused */
74
        1,      /* Slot 14 - Ethernet */
75
        0,       /* Slot 15 - unused */
76
  };
77
 
78
static char Genesis_pci_IRQ_routes[] =
79
   {
80
        0,       /* Line 0 - Unused */
81
        10,     /* Line 1 */
82
        11,     /* Line 2 */
83
        14,     /* Line 3 */
84
        15      /* Line 4 */
85
   };
86
 
87
/* Motorola Series-E */
88
static char Comet_pci_IRQ_map[16] =
89
  {
90
        0,       /* Slot 0  - unused */
91
        0,       /* Slot 1  - unused */
92
        0,       /* Slot 2  - unused */
93
        0,       /* Slot 3  - unused */
94
        0,       /* Slot 4  - unused */
95
        0,       /* Slot 5  - unused */
96
        0,       /* Slot 6  - unused */
97
        0,       /* Slot 7  - unused */
98
        0,       /* Slot 8  - unused */
99
        0,       /* Slot 9  - unused */
100
        0,       /* Slot 10 - unused */
101
        0,       /* Slot 11 - unused */
102
        3,      /* Slot 12 - SCSI */
103
        0,       /* Slot 13 - unused */
104
        1,      /* Slot 14 - Ethernet */
105
        0,       /* Slot 15 - unused */
106
  };
107
 
108
static char Comet_pci_IRQ_routes[] =
109
   {
110
        0,       /* Line 0 - Unused */
111
        10,     /* Line 1 */
112
        11,     /* Line 2 */
113
        14,     /* Line 3 */
114
        15      /* Line 4 */
115
   };
116
 
117
/* BeBox */
118
static char BeBox_pci_IRQ_map[16] =
119
  {
120
        0,       /* Slot 0  - unused */
121
        0,       /* Slot 1  - unused */
122
        0,       /* Slot 2  - unused */
123
        0,       /* Slot 3  - unused */
124
        0,       /* Slot 4  - unused */
125
        0,       /* Slot 5  - unused */
126
        0,       /* Slot 6  - unused */
127
        0,       /* Slot 7  - unused */
128
        0,       /* Slot 8  - unused */
129
        0,       /* Slot 9  - unused */
130
        0,       /* Slot 10 - unused */
131
        0,       /* Slot 11 - unused */
132
        16,     /* Slot 12 - SCSI */
133
        0,       /* Slot 13 - unused */
134
        0,       /* Slot 14 - unused */
135
        0,       /* Slot 15 - unused */
136
  };
137
 
138
static char BeBox_pci_IRQ_routes[] =
139
   {
140
        0,       /* Line 0 - Unused */
141
        9,      /* Line 1 */
142
        11,     /* Line 2 */
143
        14,     /* Line 3 */
144
        15      /* Line 4 */
145
   };
146
 
147
/* #define PCI_DEBUG */
148
 
149
#ifdef PCI_STATS
150
int PCI_conversions[2];
151
#endif
152
 
153
unsigned long pcibios_init(unsigned long mem_start,
154
                           unsigned long mem_end)
155
{
156
        return mem_start;
157
}
158
 
159
unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
160
{
161
  return mem_start;
162
}
163
 
164
 
165
unsigned long
166
_LE_to_BE_long(unsigned long val)
167
{
168
        unsigned char *p = (unsigned char *)&val;
169
#ifdef PCI_STATS
170
        PCI_conversions[0]++;
171
#endif  
172
        return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0));
173
}
174
 
175
unsigned short
176
_LE_to_BE_short(unsigned long val)
177
{
178
        unsigned char *p = (unsigned char *)&val;
179
#ifdef PCI_STATS
180
        PCI_conversions[1]++;
181
#endif  
182
        return ((p[3] << 8) | (p[2] << 0));
183
}
184
 
185
int
186
pcibios_present (void)
187
{
188
#ifdef PCI_DEBUG        
189
        printk("PCI [BIOS] present?\n");
190
#endif  
191
        return (1);
192
}
193
 
194
int
195
pcibios_read_config_dword (unsigned char bus,
196
    unsigned char dev, unsigned char offset, unsigned int *val)
197
{
198
        unsigned long _val;
199
        unsigned long *ptr;
200
        dev >>= 3;
201
#ifdef PCI_DEBUG        
202
        printk("PCI Read config dword[%d.%d.%x] = ", bus, dev, offset);
203
#endif  
204
        if ((bus != 0) || (dev < 11) || (dev > 16))
205
        {
206
                *val = 0xFFFFFFFF;
207
                return PCIBIOS_DEVICE_NOT_FOUND;
208
        } else
209
        {
210
                ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
211
#ifdef PCI_DEBUG        
212
                printk("[%x] ", ptr);
213
#endif          
214
                _val = _LE_to_BE_long(*ptr);
215
        }
216
#ifdef PCI_DEBUG        
217
        printk("%x\n", _val);
218
#endif  
219
        *val = _val;
220
        return PCIBIOS_SUCCESSFUL;
221
}
222
 
223
int
224
pcibios_read_config_word (unsigned char bus,
225
    unsigned char dev, unsigned char offset, unsigned short *val)
226
{
227
        unsigned short _val;
228
        unsigned short *ptr;
229
        dev >>= 3;
230
#ifdef PCI_DEBUG        
231
        printk("PCI Read config word[%d.%d.%x] = ", bus, dev, offset);
232
#endif  
233
        if ((bus != 0) || (dev < 11) || (dev > 16))
234
        {
235
                *val = 0xFFFFFFFF;
236
                return PCIBIOS_DEVICE_NOT_FOUND;
237
        } else
238
        {
239
                ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
240
#ifdef PCI_DEBUG        
241
                printk("[%x] ", ptr);
242
#endif          
243
                _val = _LE_to_BE_short(*ptr);
244
        }
245
#ifdef PCI_DEBUG        
246
        printk("%x\n", _val);
247
#endif          
248
        *val = _val;
249
        return PCIBIOS_SUCCESSFUL;
250
}
251
 
252
int
253
pcibios_read_config_byte (unsigned char bus,
254
    unsigned char dev, unsigned char offset, unsigned char *val)
255
{
256
        unsigned char _val;
257
        volatile unsigned char *ptr;
258
        dev >>= 3;
259
        /* Note: the configuration registers don't always have this right! */
260
        if (offset == PCI_INTERRUPT_LINE)
261
        {
262
                if (Motherboard_map[dev] <= 4)
263
                {
264
                        *val = Motherboard_routes[Motherboard_map[dev]];
265
                } else
266
                { /* Pseudo interrupts [for BeBox] */
267
                        *val = Motherboard_map[dev];
268
                }
269
#ifdef PCI_DEBUG        
270
                printk("PCI Read Interrupt Line[%d.%d] = %d\n", bus, dev, *val);
271
#endif          
272
                return PCIBIOS_SUCCESSFUL;
273
        }
274
#ifdef PCI_DEBUG        
275
        printk("PCI Read config byte[%d.%d.%x] = ", bus, dev, offset);
276
#endif          
277
        if ((bus != 0) || (dev < 11) || (dev > 16))
278
        {
279
                *val = 0xFFFFFFFF;
280
                return PCIBIOS_DEVICE_NOT_FOUND;
281
        } else
282
        {
283
                ptr = (unsigned char *)(0x80800000 | (1<<dev) | offset ^ 1);
284
#ifdef PCI_DEBUG        
285
                printk("[%x] ", ptr);
286
#endif          
287
                _val = *ptr;
288
        }
289
#ifdef PCI_DEBUG        
290
        printk("%x\n", _val);
291
#endif
292
        *val = _val;
293
        return PCIBIOS_SUCCESSFUL;
294
}
295
 
296
int
297
pcibios_write_config_dword (unsigned char bus,
298
    unsigned char dev, unsigned char offset, unsigned int val)
299
{
300
        unsigned long _val;
301
        unsigned long *ptr;
302
        dev >>= 3;
303
        _val = _LE_to_BE_long(val);
304
#ifdef PCI_DEBUG        
305
        printk("PCI Write config dword[%d.%d.%x] = %x\n", bus, dev, offset, _val);
306
#endif          
307
        if ((bus != 0) || (dev < 11) || (dev > 16))
308
        {
309
                return PCIBIOS_DEVICE_NOT_FOUND;
310
        } else
311
        {
312
                ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
313
                *ptr = _val;
314
        }
315
        return PCIBIOS_SUCCESSFUL;
316
}
317
 
318
int
319
pcibios_write_config_word (unsigned char bus,
320
    unsigned char dev, unsigned char offset, unsigned short val)
321
{
322
        unsigned short _val;
323
        unsigned short *ptr;
324
        dev >>= 3;
325
        _val = _LE_to_BE_short(val);
326
#ifdef PCI_DEBUG        
327
        printk("PCI Write config word[%d.%d.%x] = %x\n", bus, dev, offset, _val);
328
#endif          
329
        if ((bus != 0) || (dev < 11) || (dev > 16))
330
        {
331
                return PCIBIOS_DEVICE_NOT_FOUND;
332
        } else
333
        {
334
                ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
335
                *ptr = _val;
336
        }
337
        return PCIBIOS_SUCCESSFUL;
338
}
339
 
340
int
341
pcibios_write_config_byte (unsigned char bus,
342
    unsigned char dev, unsigned char offset, unsigned char val)
343
{
344
        unsigned char _val;
345
        unsigned char *ptr;
346
        dev >>= 3;
347
        _val = val;
348
#ifdef PCI_DEBUG        
349
        printk("PCI Write config byte[%d.%d.%x] = %x\n", bus, dev, offset, _val);
350
#endif          
351
        if ((bus != 0) || (dev < 11) || (dev > 16))
352
        {
353
                return PCIBIOS_DEVICE_NOT_FOUND;
354
        } else
355
        {
356
                ptr = (unsigned char *)(0x80800000 | (1<<dev) | offset ^ 1);
357
                *ptr = _val;
358
        }
359
        return PCIBIOS_SUCCESSFUL;
360
}
361
 
362
int
363
pcibios_find_device (unsigned short vendor, unsigned short device_id,
364
                     unsigned short index, unsigned char *bus,
365
                     unsigned char *dev)
366
{
367
        unsigned long w, desired = (device_id << 16) | vendor;
368
        int devnr;
369
 
370
        if (vendor == 0xffff) {
371
                return PCIBIOS_BAD_VENDOR_ID;
372
        }
373
 
374
        for (devnr = 11;  devnr < 16;  devnr++)
375
        {
376
                pcibios_read_config_dword(0, devnr<<3, PCI_VENDOR_ID, &w);
377
                if (w == desired) {
378
                        if (index == 0) {
379
                                *bus = 0;
380
                                *dev = devnr<<3;
381
                                return PCIBIOS_SUCCESSFUL;
382
                        }
383
                        --index;
384
                }
385
        }
386
        return PCIBIOS_DEVICE_NOT_FOUND;
387
}
388
 
389
int
390
pcibios_find_class (unsigned int class_code, unsigned short index,
391
    unsigned char *bus, unsigned char *dev)
392
{
393
        int dev_nr, class, indx;
394
        indx = 0;
395
#ifdef PCI_DEBUG        
396
        printk("pcibios_find_class - class: %x, index: %x", class_code, index);
397
#endif  
398
        for (dev_nr = 11;  dev_nr < 16;  dev_nr++)
399
        {
400
                pcibios_read_config_dword(0, dev_nr<<3, PCI_CLASS_REVISION, &class);
401
                if ((class>>8) == class_code)
402
                {
403
                        if (index == indx)
404
                        {
405
                                *bus = 0;
406
                                *dev = dev_nr<<3;
407
#ifdef PCI_DEBUG
408
        printk(" - device: %x\n", dev_nr);
409
#endif  
410
                                return (0);
411
                        }
412
                        indx++;
413
                }
414
        }
415
#ifdef PCI_DEBUG
416
        printk(" - not found\n");
417
#endif  
418
        return PCIBIOS_DEVICE_NOT_FOUND;
419
}
420
 
421
const char *pcibios_strerror(int error)
422
{
423
        static char buf[32];
424
        switch (error)
425
        {       case PCIBIOS_SUCCESSFUL:
426
                        return ("PCI BIOS: no error");
427
                case PCIBIOS_FUNC_NOT_SUPPORTED:
428
                        return ("PCI BIOS: function not supported");
429
                case PCIBIOS_BAD_VENDOR_ID:
430
                        return ("PCI BIOS: bad vendor ID");
431
                case PCIBIOS_DEVICE_NOT_FOUND:
432
                        return ("PCI BIOS: device not found");
433
                case PCIBIOS_BAD_REGISTER_NUMBER:
434
                        return ("PCI BIOS: bad register number");
435
                case PCIBIOS_SET_FAILED:
436
                        return ("PCI BIOS: set failed");
437
                case PCIBIOS_BUFFER_TOO_SMALL:
438
                        return ("PCI BIOS: buffer too small");
439
                default:
440
                        sprintf(buf, "PCI BIOS: invalid error #%d", error);
441
                        return(buf);
442
        }
443
}
444
 
445
/*
446
 * Note: This routine has to access the PCI configuration space
447
 * for the PCI bridge chip (Intel 82378).
448
 */
449
 
450
void route_PCI_interrupts(void)
451
{
452
        unsigned char *ibc_pirq = (unsigned char *)0x80800860;
453
        unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
454
        extern unsigned long isBeBox[];
455
        int i;
456
        /* Decide which motherboard this is & how the PCI interrupts are routed */
457
        if (isBeBox[0])
458
        {
459
                Motherboard_map = BeBox_pci_IRQ_map;
460
                Motherboard_routes = BeBox_pci_IRQ_routes;
461
        } else
462
        { /* Motorola hardware */
463
                switch (inb(0x800) & 0xF0)
464
                {
465
                        case 0x10: /* MVME16xx */
466
                                Motherboard_map = Genesis_pci_IRQ_map;
467
                                Motherboard_routes = Genesis_pci_IRQ_routes;
468
                                break;
469
                        case 0x20: /* Series E */
470
                                Motherboard_map = Comet_pci_IRQ_map;
471
                                Motherboard_routes = Comet_pci_IRQ_routes;
472
                                break;
473
                        case 0x40: /* PowerStack */
474
                        default: /* Can't hurt, can it? */
475
                                Motherboard_map = Blackhawk_pci_IRQ_map;
476
                                Motherboard_routes = Blackhawk_pci_IRQ_routes;
477
                                break;
478
                }
479
        }
480
        /* Set up mapping from slots */
481
        for (i = 1;  i <= 4;  i++)
482
        {
483
                ibc_pirq[i-1] = Motherboard_routes[i];
484
        }
485
        /* Enable PCI interrupts */
486
        *ibc_pcicon |= 0x20;
487
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.