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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [m68knommu/] [platform/] [5307/] [bios32.c] - Blame information for rev 1781

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

Line No. Rev Author Line
1 199 simons
/*****************************************************************************/
2
 
3
/*
4
 *      bios32.c -- PCI access code for embedded CO-MEM Lite PCI controller.
5
 *
6
 *      (C) Copyright 1999-2000, Greg Ungerer (gerg@moreton.com.au).
7
 */
8
 
9
/*****************************************************************************/
10
 
11
#include <linux/config.h>
12
#include <linux/kernel.h>
13
#include <linux/types.h>
14
#include <linux/tasks.h>
15
#include <linux/bios32.h>
16
#include <linux/pci.h>
17
#include <linux/ptrace.h>
18
#include <linux/interrupt.h>
19
#include <linux/sched.h>
20
#include <asm/coldfire.h>
21
#include <asm/mcfsim.h>
22
#include <asm/elia.h>
23
#include <asm/irq.h>
24
#include <asm/anchor.h>
25
 
26
/*****************************************************************************/
27
#ifdef CONFIG_PCI
28
/*****************************************************************************/
29
 
30
/*
31
 *      PCI markers for bus present and active slots.
32
 */
33
int             pci_bus_is_present = 0;
34
unsigned long   pci_slotmask = 0;
35
 
36
/*
37
 *      Resource tracking. The CO-MEM part creates a virtual address
38
 *      space that all the PCI devices live in - it is not in any way
39
 *      directly mapped into the ColdFire address space. So we can
40
 *      really assign any resources we like to devices, as long as
41
 *      they do not clash with other PCI devices.
42
 */
43
unsigned int    pci_iobase = 0x100;             /* Arbitary start address */
44
unsigned int    pci_membase = 0x00010000;       /* Arbitary start address */
45
 
46
#define PCI_MINIO       0x100                   /* 256 byte minimum I/O */
47
#define PCI_MINMEM      0x00010000              /* 64k minimum chunk */
48
 
49
/*****************************************************************************/
50
 
51
void            pci_interrupt(int irq, void *id, struct pt_regs *fp);
52
extern int      mcf_autovector(int irq);
53
 
54
/*****************************************************************************/
55
 
56
void pci_resetbus(void)
57
{
58
        int     i;
59
 
60
#if 1
61
        printk("pci_resetbus()\n");
62
#endif
63
 
64
        *((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADDR)) |= eLIA_PCIRESET;
65
        for (i = 0; (i < 1000); i++) {
66
                *((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) =
67
                        (ppdata | eLIA_PCIRESET);
68
        }
69
 
70
 
71
        *((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = ppdata;
72
}
73
 
74
/*****************************************************************************/
75
 
76
int pcibios_assignres(int slot)
77
{
78
        volatile unsigned long  *rp;
79
        volatile unsigned char  *ip;
80
        unsigned int            idsel, addr, val, align, i;
81
        int                     bar;
82
 
83
#if 0
84
        printk("pcibios_assignres(slot=%x)\n", slot);
85
#endif
86
 
87
        rp = (volatile unsigned long *) COMEM_BASE;
88
        idsel = COMEM_DA_ADDR(0x1 << (slot + 16));
89
 
90
        /* Try to assign resource to each BAR */
91
        for (bar = 0; (bar < 6); bar++) {
92
                addr = COMEM_PCIBUS + PCI_BASE_ADDRESS_0 + (bar * 4);
93
                rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
94
                rp[LREG(addr)] = 0xffffffff;
95
 
96
                rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
97
                val = rp[LREG(addr)];
98
#if 1
99
printk("--------------------------------------------------------------\n");
100
printk("%s(%d): BAR[%d] initial read=%08x\n", __FILE__, __LINE__, bar, val);
101
#endif
102
                if (val == 0)
103
                        continue;
104
 
105
#if 1
106
printk("%s(%d): BAR[%d] after all 1 write=%08x\n", __FILE__, __LINE__, bar, val);
107
#endif
108
 
109
                /* Determine space required by BAR */
110
                /* FIXME: this should go backwords from 0x80000000... */
111
                for (i = 0; (i < 32); i++) {
112
                        if ((0x1 << i) & (val & 0xfffffffc))
113
                                break;
114
                }
115
 
116
#if 1
117
printk("%s(%d): BAR[%d] size=%08x(%d)\n", __FILE__, __LINE__, bar, (0x1 << i), i);
118
#endif
119
                i = 0x1 << i;
120
 
121
                /* Assign a resource */
122
                if (val & PCI_BASE_ADDRESS_SPACE_IO) {
123
#if 1
124
printk("%s(%d): BAR[%d] IO assignment size=%08x iobase=%08x\n", __FILE__, __LINE__, bar, i, pci_iobase);
125
#endif
126
                        if (i < PCI_MINIO) {
127
                                i = PCI_MINIO;
128
#if 1
129
printk("%s(%d): BAR[%d] adjusted minimum size=%08x\n", __FILE__, __LINE__, bar, i);
130
#endif
131
                        }
132
                        if (i > 0xffff) {
133
                                /* Invalid size?? */
134
                                val = 0 | PCI_BASE_ADDRESS_SPACE_IO;
135
#if 1
136
printk("%s(%d): BAR[%d] too big for IO??\n", __FILE__, __LINE__, bar);
137
#endif
138
                        } else {
139
                                /* Check for un-alignment */
140
                                if ((align = pci_iobase % i))
141
                                        pci_iobase += (i - align);
142
                                val = pci_iobase | PCI_BASE_ADDRESS_SPACE_IO;
143
                                pci_iobase += i;
144
#if 1
145
printk("%s(%d): BAR[%d]=%08x alignment=%08x iobase=%08x\n", __FILE__, __LINE__, bar, val, i, pci_iobase);
146
#endif
147
                        }
148
                } else {
149
 
150
#if 1
151
printk("%s(%d): BAR[%d] MEM assignment size=%08x membase=%08x\n", __FILE__, __LINE__, bar, i, pci_membase);
152
#endif
153
                        if (i < PCI_MINMEM) {
154
                                i = PCI_MINMEM;
155
#if 1
156
printk("%s(%d): BAR[%d] adjusted minimum size=%08x\n", __FILE__, __LINE__, bar, i);
157
#endif
158
                        }
159
                        /* Check for un-alignment */
160
                        if ((align = pci_membase % i))
161
                                pci_membase += (i - align);
162
                        val = pci_membase | PCI_BASE_ADDRESS_SPACE_MEMORY;
163
                        pci_membase += i;
164
#if 1
165
printk("%s(%d): BAR[%d]=%08x alignment=%08x membase=%08x\n", __FILE__, __LINE__, bar, val, i, pci_membase);
166
#endif
167
                }
168
 
169
                /* Write resource back into BAR register */
170
                rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
171
                rp[LREG(addr)] = val;
172
        }
173
 
174
 
175
        /* Assign IRQ if one is wanted... */
176
        ip = (volatile unsigned char *) (COMEM_BASE + COMEM_PCIBUS);
177
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
178
 
179
#if 0
180
        addr = (PCI_INTERRUPT_PIN & 0xfc) + (~PCI_INTERRUPT_PIN & 0x03);
181
        val = ip[addr];
182
        addr = (PCI_INTERRUPT_LINE & 0xfc) + (~PCI_INTERRUPT_LINE & 0x03);
183
        i = ip[addr];
184
printk("%s(%d): BEFORE interrupt[%x] line=%d pin=%d\n", __FILE__, __LINE__, (int) &ip[addr], i, val);
185
#endif
186
        addr = (PCI_INTERRUPT_PIN & 0xfc) + (~PCI_INTERRUPT_PIN & 0x03);
187
        if (ip[addr]) {
188
#if 0
189
printk("%s(%d): setting interrupt line...\n", __FILE__, __LINE__);
190
#endif
191
                rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
192
                addr = (PCI_INTERRUPT_LINE & 0xfc) + (~PCI_INTERRUPT_LINE & 0x03);
193
                ip[addr] = 25;
194
        }
195
#if 0
196
rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
197
addr = (PCI_INTERRUPT_LINE & 0xfc) + (~PCI_INTERRUPT_LINE & 0x03);
198
val = ip[addr];
199
addr = (PCI_INTERRUPT_PIN & 0xfc) + (~PCI_INTERRUPT_PIN & 0x03);
200
i = ip[addr];
201
printk("%s(%d): AFTER interrupt[%x] line=%d pin=%d\n", __FILE__, __LINE__, (int) &ip[PCI_INTERRUPT_LINE], val, i);
202
#endif
203
 
204
        return(0);
205
}
206
 
207
/*****************************************************************************/
208
 
209
int pcibios_enable(int slot)
210
{
211
        volatile unsigned long  *rp;
212
        unsigned int            idsel, addr;
213
 
214
#if 0
215
        printk("pcibios_enbale(slot=%x)\n", slot);
216
#endif
217
 
218
        rp = (volatile unsigned long *) COMEM_BASE;
219
        idsel = COMEM_DA_ADDR(0x1 << (slot + 16));
220
 
221
        /* Enable I/O and memory accesses to this device */
222
        addr = COMEM_PCIBUS + PCI_COMMAND;
223
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
224
        rp[LREG(addr)] = (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
225
 
226
#if 0
227
rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
228
printk("%s(%d): command[%x]=%x\n", __FILE__, __LINE__, (int) &rp[LREG(addr)], (int) rp[LREG(addr)]);
229
#endif
230
 
231
        return(0);
232
}
233
 
234
/*****************************************************************************/
235
 
236
unsigned long pcibios_init(unsigned long mem_start, unsigned long mem_end)
237
{
238
        volatile unsigned long  *rp;
239
        unsigned long           sel, id;
240
        int                     slot;
241
 
242
#if 0
243
        printk("pcibios_init()\n");
244
#endif
245
 
246
        pci_resetbus();
247
 
248
        /*
249
         *      Do some sort of basic check to see if the CO-MEM part
250
         *      is present...
251
         */
252
        rp = (volatile unsigned long *) COMEM_BASE;
253
        if ((rp[LREG(COMEM_LBUSCFG)] & 0xffff) != 0x0b50) {
254
                printk("PCI: no PCI bus present\n");
255
                return(mem_start);
256
        }
257
 
258
        pci_bus_is_present = 1;
259
 
260
        /*
261
         *      Do a quick scan of the PCI bus and see what is here.
262
         */
263
        for (slot = COMEM_MINDEV; (slot <= COMEM_MAXDEV); slot++) {
264
                sel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << (slot + 16));
265
                rp[LREG(COMEM_DAHBASE)] = sel;
266
                rp[LREG(COMEM_PCIBUS)] = 0; /* Clear bus */
267
                id = rp[LREG(COMEM_PCIBUS)];
268
                if ((id != 0) && ((id & 0xffff0000) != (sel & 0xffff0000))) {
269
                        printk("PCI: slot=%d id=%08x\n", slot, (int) id);
270
                        pci_slotmask |= 0x1 << slot;
271
                        pcibios_assignres(slot);
272
                        pcibios_enable(slot);
273
                }
274
        }
275
 
276
        /* Get PCI irq for local vectoring */
277
        if (request_irq(COMEM_IRQ, pci_interrupt, 0, "PCI bridge", NULL)) {
278
                printk("PCI: failed to acquire interrupt %d\n", COMEM_IRQ);
279
        } else {
280
#if 1
281
                printk("%s(%d): setting auto-vector...\n", __FILE__, __LINE__);
282
#endif
283
                mcf_autovector(COMEM_IRQ);
284
        }
285
 
286
#if 0
287
{
288
        int i;
289
        for (i = 0; (i < 0x100); i++) {
290
                if ((i % 0x10) == 0)
291
                        printk("\n%08x: ", i);
292
                printk("%02x ", pci_inb(i + 0x200));
293
        }
294
        printk("\n");
295
}
296
#endif
297
        return(mem_start);
298
}
299
 
300
/*****************************************************************************/
301
 
302
unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
303
{
304
        return(mem_start);
305
}
306
 
307
/*****************************************************************************/
308
 
309
int pcibios_present(void)
310
{
311
        return(pci_bus_is_present);
312
}
313
 
314
/*****************************************************************************/
315
 
316
int pcibios_read_config_dword(unsigned char bus, unsigned char dev,
317
        unsigned char offset, unsigned int *val)
318
{
319
        volatile unsigned long  *rp;
320
        unsigned long           idsel, fnsel;
321
 
322
#if 0
323
        printk("pcibios_read_config_dword(bus=%x,dev=%x,offset=%x,val=%x)\n",
324
                 bus, dev, offset, val);
325
#endif
326
 
327
        if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
328
                *val = 0xffffffff;
329
                return(PCIBIOS_SUCCESSFUL);
330
        }
331
 
332
        rp = (volatile unsigned long *) COMEM_BASE;
333
        idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
334
        fnsel = (dev & 0x7) << 8;
335
 
336
        rp[LREG(COMEM_DAHBASE)] = idsel;
337
        *val = rp[LREG(COMEM_PCIBUS + (offset & 0xfc) + fnsel)];
338
 
339
#if 1
340
        /* If we get back what we wrote, then nothing there */
341
        /* This is pretty dodgy, but, hey, what else do we do?? */
342
        if (!offset && (*val == ((idsel & 0xfffff000) | (offset & 0x00000fff))))
343
                *val = 0xffffffff;
344
#endif
345
 
346
        return(PCIBIOS_SUCCESSFUL);
347
}
348
 
349
/*****************************************************************************/
350
 
351
int pcibios_read_config_word(unsigned char bus, unsigned char dev,
352
        unsigned char offset, unsigned short *val)
353
{
354
        volatile unsigned long  *rp;
355
        volatile unsigned short *bp;
356
        unsigned long           idsel, fnsel;
357
        unsigned char           swapoffset;
358
 
359
#if 0
360
        printk("pcibios_read_config_word(bus=%x,dev=%x,offset=%x)\n",
361
                bus, dev, offset);
362
#endif
363
 
364
        if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
365
                *val = 0xffff;
366
                return(PCIBIOS_SUCCESSFUL);
367
        }
368
 
369
        rp = (volatile unsigned long *) COMEM_BASE;
370
        bp = (volatile unsigned short *) COMEM_BASE;
371
        idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
372
        fnsel = (dev & 0x7) << 8;
373
        swapoffset = (offset & 0xfc) + (~offset & 0x02);
374
 
375
        rp[LREG(COMEM_DAHBASE)] = idsel;
376
        *val = bp[WREG(COMEM_PCIBUS + swapoffset + fnsel)];
377
 
378
        return(PCIBIOS_SUCCESSFUL);
379
}
380
 
381
/*****************************************************************************/
382
 
383
int pcibios_read_config_byte(unsigned char bus, unsigned char dev,
384
        unsigned char offset, unsigned char *val)
385
{
386
        volatile unsigned long  *rp;
387
        volatile unsigned char  *bp;
388
        unsigned long           idsel, fnsel;
389
        unsigned char           swapoffset;
390
 
391
#if 0
392
        printk("pcibios_read_config_byte(bus=%x,dev=%x,offset=%x)\n",
393
                bus, dev, offset);
394
#endif
395
 
396
        if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
397
                *val = 0xff;
398
                return(PCIBIOS_SUCCESSFUL);
399
        }
400
 
401
        rp = (volatile unsigned long *) COMEM_BASE;
402
        bp = (volatile unsigned char *) COMEM_BASE;
403
        idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
404
        fnsel = (dev & 0x7) << 8;
405
        swapoffset = (offset & 0xfc) + (~offset & 0x03);
406
 
407
        rp[LREG(COMEM_DAHBASE)] = idsel;
408
        *val = bp[(COMEM_PCIBUS + swapoffset + fnsel)];
409
 
410
        return(PCIBIOS_SUCCESSFUL);
411
}
412
 
413
/*****************************************************************************/
414
 
415
int pcibios_write_config_dword(unsigned char bus, unsigned char dev,
416
        unsigned char offset, unsigned int val)
417
{
418
        volatile unsigned long  *rp;
419
        unsigned long           idsel, fnsel;
420
 
421
#if 0
422
        printk("pcibios_write_config_dword(bus=%x,dev=%x,offset=%x,val=%x)\n",
423
                 bus, dev, offset, val);
424
#endif
425
 
426
        if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
427
                return(PCIBIOS_SUCCESSFUL);
428
 
429
        rp = (volatile unsigned long *) COMEM_BASE;
430
        idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
431
        fnsel = (dev & 0x7) << 8;
432
 
433
        rp[LREG(COMEM_DAHBASE)] = idsel;
434
        rp[LREG(COMEM_PCIBUS + (offset & 0xfc) + fnsel)] = val;
435
        return(PCIBIOS_SUCCESSFUL);
436
}
437
 
438
/*****************************************************************************/
439
 
440
int pcibios_write_config_word(unsigned char bus, unsigned char dev,
441
        unsigned char offset, unsigned short val)
442
{
443
 
444
        volatile unsigned long  *rp;
445
        volatile unsigned short *bp;
446
        unsigned long           idsel, fnsel;
447
        unsigned char           swapoffset;
448
 
449
#if 0
450
        printk("pcibios_write_config_word(bus=%x,dev=%x,offset=%x,val=%x)\n",
451
                 bus, dev, offset, val);
452
#endif
453
 
454
        if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
455
                return(PCIBIOS_SUCCESSFUL);
456
 
457
        rp = (volatile unsigned long *) COMEM_BASE;
458
        bp = (volatile unsigned short *) COMEM_BASE;
459
        idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
460
        fnsel = (dev & 0x7) << 8;
461
        swapoffset = (offset & 0xfc) + (~offset & 0x02);
462
 
463
        rp[LREG(COMEM_DAHBASE)] = idsel;
464
        bp[WREG(COMEM_PCIBUS + swapoffset + fnsel)] = val;
465
        return(PCIBIOS_SUCCESSFUL);
466
}
467
 
468
/*****************************************************************************/
469
 
470
int pcibios_write_config_byte(unsigned char bus, unsigned char dev,
471
        unsigned char offset, unsigned char val)
472
{
473
        volatile unsigned long  *rp;
474
        volatile unsigned char  *bp;
475
        unsigned long           idsel, fnsel;
476
        unsigned char           swapoffset;
477
 
478
#if 0
479
        printk("pcibios_write_config_byte(bus=%x,dev=%x,offset=%x,val=%x)\n",
480
                 bus, dev, offset, val);
481
#endif
482
 
483
        if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
484
                return(PCIBIOS_SUCCESSFUL);
485
 
486
        rp = (volatile unsigned long *) COMEM_BASE;
487
        bp = (volatile unsigned char *) COMEM_BASE;
488
        idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
489
        fnsel = (dev & 0x7) << 8;
490
        swapoffset = (offset & 0xfc) + (~offset & 0x03);
491
 
492
        rp[LREG(COMEM_DAHBASE)] = idsel;
493
        bp[(COMEM_PCIBUS + swapoffset + fnsel)] = val;
494
        return(PCIBIOS_SUCCESSFUL);
495
}
496
 
497
/*****************************************************************************/
498
 
499
int pcibios_find_device(unsigned short vendor, unsigned short devid,
500
        unsigned short index, unsigned char *bus, unsigned char *dev)
501
{
502
        unsigned int    vendev, val;
503
        unsigned char   devnr;
504
 
505
#if 1
506
        printk("pcibios_find_device(vendor=%04x,devid=%04x,index=%d)\n",
507
                vendor, devid, index);
508
#endif
509
 
510
        if (vendor == 0xffff)
511
                return(PCIBIOS_BAD_VENDOR_ID);
512
 
513
        vendev = (devid << 16) | vendor;
514
        for (devnr = 0; (devnr < 32); devnr++) {
515
                pcibios_read_config_dword(0, devnr, PCI_VENDOR_ID, &val);
516
                if (vendev == val) {
517
                        if (index-- == 0) {
518
                                *bus = 0;
519
                                *dev = devnr;
520
                                return(PCIBIOS_SUCCESSFUL);
521
                        }
522
                }
523
        }
524
 
525
        return(PCIBIOS_DEVICE_NOT_FOUND);
526
}
527
 
528
/*****************************************************************************/
529
 
530
int pcibios_find_class(unsigned int class, unsigned short index,
531
        unsigned char *bus, unsigned char *dev)
532
{
533
        unsigned int    val;
534
        unsigned char   devnr;
535
 
536
#if 0
537
        printk("pcibios_find_class(class=%04x,index=%d)\n", class, index);
538
#endif
539
 
540
        for (devnr = 0; (devnr < 32); devnr++) {
541
                pcibios_read_config_dword(0, devnr, PCI_CLASS_REVISION, &val);
542
                if ((val >> 8) == class) {
543
                        if (index-- == 0) {
544
                                *bus = 0;
545
                                *dev = devnr;
546
                                return(PCIBIOS_SUCCESSFUL);
547
                        }
548
                }
549
        }
550
 
551
        return(PCIBIOS_DEVICE_NOT_FOUND);
552
}
553
 
554
/*****************************************************************************/
555
 
556
/*
557
 *      Local routines to interrcept the standard I/O and vector handling
558
 *      code. Don't include this 'till now - initialization code above needs
559
 *      access to the real code too.
560
 */
561
#include <asm/mcfpci.h>
562
 
563
/*****************************************************************************/
564
 
565
void pci_outb(unsigned char val, unsigned int addr)
566
{
567
        volatile unsigned long  *rp;
568
        volatile unsigned char  *bp;
569
 
570
#if 1
571
        printk("pci_outb(val=%02x,addr=%x)\n", val, addr);
572
#endif
573
 
574
        rp = (volatile unsigned long *) COMEM_BASE;
575
        bp = (volatile unsigned char *) COMEM_BASE;
576
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
577
        addr = (addr & ~0x3) + (~addr & 0x03);
578
        bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
579
}
580
 
581
/*****************************************************************************/
582
 
583
void pci_outw(unsigned short val, unsigned int addr)
584
{
585
        volatile unsigned long  *rp;
586
        volatile unsigned short *sp;
587
 
588
#if 1
589
        printk("pci_outw(val=%04x,addr=%x)\n", val, addr);
590
#endif
591
 
592
        rp = (volatile unsigned long *) COMEM_BASE;
593
        sp = (volatile unsigned short *) COMEM_BASE;
594
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
595
        addr = (addr & ~0x3) + (~addr & 0x02);
596
        sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
597
}
598
 
599
/*****************************************************************************/
600
 
601
void pci_outl(unsigned int val, unsigned int addr)
602
{
603
        volatile unsigned long  *rp;
604
        volatile unsigned int   *lp;
605
 
606
#if 1
607
        printk("pci_outl(val=%08x,addr=%x)\n", val, addr);
608
#endif
609
 
610
        rp = (volatile unsigned long *) COMEM_BASE;
611
        lp = (volatile unsigned int *) COMEM_BASE;
612
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
613
        lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
614
}
615
 
616
/*****************************************************************************/
617
 
618
unsigned char pci_inb(unsigned int addr)
619
{
620
        volatile unsigned long  *rp;
621
        volatile unsigned char  *bp;
622
        unsigned char           val;
623
 
624
#if 1
625
        printk("pci_inb(addr=%x)\n", addr);
626
#endif
627
 
628
        rp = (volatile unsigned long *) COMEM_BASE;
629
        bp = (volatile unsigned char *) COMEM_BASE;
630
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(addr);
631
        addr = (addr & ~0x3) + (~addr & 0x03);
632
        val = bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
633
#if 0
634
printk("%s(%d): (BASE=%08x)(addr=%x,OFFSET=%x) %08x=%02x\n",
635
        __FILE__, __LINE__, rp[LREG(COMEM_DAHBASE)],
636
        addr, COMEM_DA_OFFSET(addr),
637
        (int) &bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))], val);
638
#endif
639
#if 1
640
        printk("pci_inb(addr=%x)=%02x\n", addr, val);
641
#endif
642
        return(val);
643
}
644
 
645
/*****************************************************************************/
646
 
647
unsigned short pci_inw(unsigned int addr)
648
{
649
        volatile unsigned long  *rp;
650
        volatile unsigned short *sp;
651
        unsigned short          val;
652
 
653
#if 0
654
        printk("pci_inw(addr=%x)\n", addr);
655
#endif
656
 
657
        rp = (volatile unsigned long *) COMEM_BASE;
658
        sp = (volatile unsigned short *) COMEM_BASE;
659
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(addr);
660
        addr = (addr & ~0x3) + (~addr & 0x02);
661
        val = sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
662
#if 1
663
        printk("pci_inw(addr=%x)=%04x\n", addr, val);
664
#endif
665
        return(val);
666
}
667
 
668
/*****************************************************************************/
669
 
670
unsigned int pci_inl(unsigned int addr)
671
{
672
        volatile unsigned long  *rp;
673
        volatile unsigned int   *lp;
674
        unsigned int            val;
675
 
676
#if 0
677
        printk("pci_inl(addr=%x)\n", addr);
678
#endif
679
 
680
        rp = (volatile unsigned long *) COMEM_BASE;
681
        lp = (volatile unsigned int *) COMEM_BASE;
682
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(addr);
683
        val = lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
684
#if 1
685
        printk("pci_inl(addr=%x)=%08x\n", addr, val);
686
#endif
687
        return(val);
688
}
689
 
690
/*****************************************************************************/
691
 
692
void pci_outsb(void *addr, void *buf, int len)
693
{
694
        volatile unsigned long  *rp;
695
        volatile unsigned char  *bp;
696
        unsigned char           *dp = (unsigned char *) buf;
697
        unsigned int            a = (unsigned int) addr;
698
 
699
#if 1
700
        printk("pci_outsb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
701
#endif
702
 
703
        rp = (volatile unsigned long *) COMEM_BASE;
704
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
705
 
706
        a = (a & ~0x3) + (~a & 0x03);
707
        bp = (volatile unsigned char *)
708
                (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
709
 
710
        while (len--)
711
                *bp = *dp++;
712
}
713
 
714
/*****************************************************************************/
715
 
716
void pci_outsw(void *addr, void *buf, int len)
717
{
718
        volatile unsigned long  *rp;
719
        volatile unsigned short *wp;
720
        unsigned short          *dp = (unsigned short *) buf;
721
        unsigned int            a = (unsigned int) addr;
722
 
723
#if 1
724
        printk("pci_outsw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
725
#endif
726
 
727
        rp = (volatile unsigned long *) COMEM_BASE;
728
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
729
 
730
        a = (a & ~0x3) + (~a & 0x2);
731
        wp = (volatile unsigned short *)
732
                (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
733
 
734
        while (len--)
735
                *wp = *dp++;
736
}
737
 
738
/*****************************************************************************/
739
 
740
void pci_outsl(void *addr, void *buf, int len)
741
{
742
        volatile unsigned long  *rp;
743
        volatile unsigned long  *lp;
744
        unsigned long           *dp = (unsigned long *) buf;
745
        unsigned int            a = (unsigned int) addr;
746
 
747
#if 1
748
        printk("pci_outsl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
749
#endif
750
 
751
        rp = (volatile unsigned long *) COMEM_BASE;
752
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
753
 
754
        lp = (volatile unsigned long *)
755
                (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
756
 
757
        while (len--)
758
                *lp = *dp++;
759
}
760
 
761
/*****************************************************************************/
762
 
763
void pci_insb(void *addr, void *buf, int len)
764
{
765
        volatile unsigned long  *rp;
766
        volatile unsigned char  *bp;
767
        unsigned char           *dp = (unsigned char *) buf;
768
        unsigned int            a = (unsigned int) addr;
769
 
770
#if 1
771
        printk("pci_insb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
772
#endif
773
 
774
        rp = (volatile unsigned long *) COMEM_BASE;
775
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
776
 
777
        a = (a & ~0x3) + (~a & 0x03);
778
        bp = (volatile unsigned char *)
779
                (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
780
 
781
        while (len--)
782
                *dp++ = *bp;
783
}
784
 
785
/*****************************************************************************/
786
 
787
void pci_insw(void *addr, void *buf, int len)
788
{
789
        volatile unsigned long  *rp;
790
        volatile unsigned short *wp;
791
        unsigned short          *dp = (unsigned short *) buf;
792
        unsigned int            a = (unsigned int) addr;
793
 
794
#if 1
795
        printk("pci_insw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
796
#endif
797
 
798
        rp = (volatile unsigned long *) COMEM_BASE;
799
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
800
 
801
        a = (a & ~0x3) + (~a & 0x2);
802
        wp = (volatile unsigned short *)
803
                (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
804
 
805
        while (len--)
806
                *dp++ = *wp;
807
}
808
 
809
/*****************************************************************************/
810
 
811
void pci_insl(void *addr, void *buf, int len)
812
{
813
        volatile unsigned long  *rp;
814
        volatile unsigned long  *lp;
815
        unsigned long           *dp = (unsigned long *) buf;
816
        unsigned int            a = (unsigned int) addr;
817
 
818
#if 1
819
        printk("pci_insl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
820
#endif
821
 
822
        rp = (volatile unsigned long *) COMEM_BASE;
823
        rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
824
 
825
        lp = (volatile unsigned long *)
826
                (COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
827
 
828
        while (len--)
829
                *dp++ = *lp;
830
}
831
 
832
/*****************************************************************************/
833
 
834
typedef struct pci_localirqlist {
835
        void            (*handler)(int, void *, struct pt_regs *);
836
        const char      *device;
837
        void            *dev_id;
838
};
839
 
840
struct pci_localirqlist pci_irqlist[COMEM_MAXPCI];
841
 
842
/*****************************************************************************/
843
 
844
int pci_request_irq(unsigned int irq,
845
        void (*handler)(int, void *, struct pt_regs *),
846
        unsigned long flags, const char *device, void *dev_id)
847
{
848
        int     i;
849
 
850
#if 1
851
        printk("pci_request_irq(irq=%d,handler=%x,flags=%x,device=%s,"
852
                "dev_id=%x)\n", irq, (int) handler, (int) flags, device,
853
                (int) dev_id);
854
#endif
855
 
856
        /* Check if this interrupt handler is already lodged */
857
        for (i = 0; (i < COMEM_MAXPCI); i++) {
858
                if (pci_irqlist[i].handler == handler)
859
                        return(0);
860
        }
861
 
862
        /* Find a free spot to put this handler */
863
        for (i = 0; (i < COMEM_MAXPCI); i++) {
864
                if (pci_irqlist[i].handler == 0) {
865
                        pci_irqlist[i].handler = handler;
866
                        pci_irqlist[i].device = device;
867
                        pci_irqlist[i].dev_id = dev_id;
868
                        return(0);
869
                }
870
        }
871
 
872
        /* Couldn't fit?? */
873
        return(1);
874
}
875
 
876
/*****************************************************************************/
877
 
878
void pci_free_irq(unsigned int irq, void *dev_id)
879
{
880
#if 1
881
        printk("pci_free_irq(irq=%d,dev_id=%x)\n", irq, (int) dev_id);
882
#endif
883
 
884
        /* FIXME: need to free up irq... how to id it?? */
885
}
886
 
887
/*****************************************************************************/
888
 
889
void pci_interrupt(int irq, void *id, struct pt_regs *fp)
890
{
891
        int     i;
892
 
893
#if 1
894
        printk("pci_interrupt(irq=%d,id=%x,fp=%x)\n", irq, (int) id, (int) fp);
895
#endif
896
 
897
        for (i = 0; (i < COMEM_MAXPCI); i++) {
898
                if (pci_irqlist[i].handler) {
899
#if 1
900
                        printk("%s(%d): calling handler=%x\n",
901
                                __FILE__, __LINE__,
902
                                (int) pci_irqlist[i].handler);
903
#endif
904
                        (*pci_irqlist[i].handler)(irq, id, fp);
905
                }
906
        }
907
}
908
 
909
/*****************************************************************************/
910
#endif  /* CONFIG_PCI */

powered by: WebSVN 2.1.0

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