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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [alpha/] [kernel/] [core_tsunami.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      linux/arch/alpha/kernel/core_tsunami.c
3
 *
4
 * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
5
 *
6
 * Code common to all TSUNAMI core logic chips.
7
 */
8
 
9
#include <linux/kernel.h>
10
#include <linux/types.h>
11
#include <linux/pci.h>
12
#include <linux/sched.h>
13
#include <linux/init.h>
14
 
15
#include <asm/ptrace.h>
16
#include <asm/system.h>
17
#include <asm/smp.h>
18
 
19
#define __EXTERN_INLINE inline
20
#include <asm/io.h>
21
#include <asm/core_tsunami.h>
22
#undef __EXTERN_INLINE
23
 
24
#include <linux/bootmem.h>
25
 
26
#include "proto.h"
27
#include "pci_impl.h"
28
 
29
 
30
static struct
31
{
32
        unsigned long wsba[4];
33
        unsigned long wsm[4];
34
        unsigned long tba[4];
35
} saved_pchip[2];
36
 
37
/*
38
 * NOTE: Herein lie back-to-back mb instructions.  They are magic.
39
 * One plausible explanation is that the I/O controller does not properly
40
 * handle the system transaction.  Another involves timing.  Ho hum.
41
 */
42
 
43
/*
44
 * BIOS32-style PCI interface:
45
 */
46
 
47
#define DEBUG_MCHECK 0          /* 0 = minimal, 1 = debug, 2 = debug+dump.  */
48
#define DEBUG_CONFIG 0
49
 
50
#if DEBUG_CONFIG
51
# define DBG_CFG(args)  printk args
52
#else
53
# define DBG_CFG(args)
54
#endif
55
 
56
 
57
/*
58
 * Given a bus, device, and function number, compute resulting
59
 * configuration space address
60
 * accordingly.  It is therefore not safe to have concurrent
61
 * invocations to configuration space access routines, but there
62
 * really shouldn't be any need for this.
63
 *
64
 * Note that all config space accesses use Type 1 address format.
65
 *
66
 * Note also that type 1 is determined by non-zero bus number.
67
 *
68
 * Type 1:
69
 *
70
 *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
71
 *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
72
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73
 * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
74
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75
 *
76
 *      31:24   reserved
77
 *      23:16   bus number (8 bits = 128 possible buses)
78
 *      15:11   Device number (5 bits)
79
 *      10:8    function number
80
 *       7:2    register number
81
 *
82
 * Notes:
83
 *      The function number selects which function of a multi-function device
84
 *      (e.g., SCSI and Ethernet).
85
 *
86
 *      The register selects a DWORD (32 bit) register offset.  Hence it
87
 *      doesn't get shifted by 2 bits as we want to "drop" the bottom two
88
 *      bits.
89
 */
90
 
91
static int
92
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
93
             unsigned char *type1)
94
{
95
        struct pci_controller *hose = dev->sysdata;
96
        unsigned long addr;
97
        u8 bus = dev->bus->number;
98
        u8 device_fn = dev->devfn;
99
 
100
        DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
101
                 "pci_addr=0x%p, type1=0x%p)\n",
102
                 bus, device_fn, where, pci_addr, type1));
103
 
104
        if (hose->first_busno == dev->bus->number)
105
                bus = 0;
106
        *type1 = (bus != 0);
107
 
108
        addr = (bus << 16) | (device_fn << 8) | where;
109
        addr |= hose->config_space_base;
110
 
111
        *pci_addr = addr;
112
        DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
113
        return 0;
114
}
115
 
116
static int
117
tsunami_read_config_byte(struct pci_dev *dev, int where, u8 *value)
118
{
119
        unsigned long addr;
120
        unsigned char type1;
121
 
122
        if (mk_conf_addr(dev, where, &addr, &type1))
123
                return PCIBIOS_DEVICE_NOT_FOUND;
124
 
125
        *value = __kernel_ldbu(*(vucp)addr);
126
        return PCIBIOS_SUCCESSFUL;
127
}
128
 
129
static int
130
tsunami_read_config_word(struct pci_dev *dev, int where, u16 *value)
131
{
132
        unsigned long addr;
133
        unsigned char type1;
134
 
135
        if (mk_conf_addr(dev, where, &addr, &type1))
136
                return PCIBIOS_DEVICE_NOT_FOUND;
137
 
138
        *value = __kernel_ldwu(*(vusp)addr);
139
        return PCIBIOS_SUCCESSFUL;
140
}
141
 
142
static int
143
tsunami_read_config_dword(struct pci_dev *dev, int where, u32 *value)
144
{
145
        unsigned long addr;
146
        unsigned char type1;
147
 
148
        if (mk_conf_addr(dev, where, &addr, &type1))
149
                return PCIBIOS_DEVICE_NOT_FOUND;
150
 
151
        *value = *(vuip)addr;
152
        return PCIBIOS_SUCCESSFUL;
153
}
154
 
155
static int
156
tsunami_write_config_byte(struct pci_dev *dev, int where, u8 value)
157
{
158
        unsigned long addr;
159
        unsigned char type1;
160
 
161
        if (mk_conf_addr(dev, where, &addr, &type1))
162
                return PCIBIOS_DEVICE_NOT_FOUND;
163
 
164
        __kernel_stb(value, *(vucp)addr);
165
        mb();
166
        __kernel_ldbu(*(vucp)addr);
167
        return PCIBIOS_SUCCESSFUL;
168
}
169
 
170
static int
171
tsunami_write_config_word(struct pci_dev *dev, int where, u16 value)
172
{
173
        unsigned long addr;
174
        unsigned char type1;
175
 
176
        if (mk_conf_addr(dev, where, &addr, &type1))
177
                return PCIBIOS_DEVICE_NOT_FOUND;
178
 
179
        __kernel_stw(value, *(vusp)addr);
180
        mb();
181
        __kernel_ldwu(*(vusp)addr);
182
        return PCIBIOS_SUCCESSFUL;
183
}
184
 
185
static int
186
tsunami_write_config_dword(struct pci_dev *dev, int where, u32 value)
187
{
188
        unsigned long addr;
189
        unsigned char type1;
190
 
191
        if (mk_conf_addr(dev, where, &addr, &type1))
192
                return PCIBIOS_DEVICE_NOT_FOUND;
193
 
194
        *(vuip)addr = value;
195
        mb();
196
        *(vuip)addr;
197
        return PCIBIOS_SUCCESSFUL;
198
}
199
 
200
struct pci_ops tsunami_pci_ops =
201
{
202
        read_byte:      tsunami_read_config_byte,
203
        read_word:      tsunami_read_config_word,
204
        read_dword:     tsunami_read_config_dword,
205
        write_byte:     tsunami_write_config_byte,
206
        write_word:     tsunami_write_config_word,
207
        write_dword:    tsunami_write_config_dword
208
};
209
 
210
void
211
tsunami_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
212
{
213
        tsunami_pchip *pchip = hose->index ? TSUNAMI_pchip1 : TSUNAMI_pchip0;
214
        volatile unsigned long *csr;
215
        unsigned long value;
216
 
217
        /* We can invalidate up to 8 tlb entries in a go.  The flush
218
           matches against <31:16> in the pci address.  */
219
        csr = &pchip->tlbia.csr;
220
        if (((start ^ end) & 0xffff0000) == 0)
221
                csr = &pchip->tlbiv.csr;
222
 
223
        /* For TBIA, it doesn't matter what value we write.  For TBI,
224
           it's the shifted tag bits.  */
225
        value = (start & 0xffff0000) >> 12;
226
 
227
        *csr = value;
228
        mb();
229
        *csr;
230
}
231
 
232
#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
233
static long __init
234
tsunami_probe_read(volatile unsigned long *vaddr)
235
{
236
        long dont_care, probe_result;
237
        int cpu = smp_processor_id();
238
        int s = swpipl(IPL_MCHECK - 1);
239
 
240
        mcheck_taken(cpu) = 0;
241
        mcheck_expected(cpu) = 1;
242
        mb();
243
        dont_care = *vaddr;
244
        draina();
245
        mcheck_expected(cpu) = 0;
246
        probe_result = !mcheck_taken(cpu);
247
        mcheck_taken(cpu) = 0;
248
        setipl(s);
249
 
250
        printk("dont_care == 0x%lx\n", dont_care);
251
 
252
        return probe_result;
253
}
254
 
255
static long __init
256
tsunami_probe_write(volatile unsigned long *vaddr)
257
{
258
        long true_contents, probe_result = 1;
259
 
260
        TSUNAMI_cchip->misc.csr |= (1L << 28); /* clear NXM... */
261
        true_contents = *vaddr;
262
        *vaddr = 0;
263
        draina();
264
        if (TSUNAMI_cchip->misc.csr & (1L << 28)) {
265
                int source = (TSUNAMI_cchip->misc.csr >> 29) & 7;
266
                TSUNAMI_cchip->misc.csr |= (1L << 28); /* ...and unlock NXS. */
267
                probe_result = 0;
268
                printk("tsunami_probe_write: unit %d at 0x%016lx\n", source,
269
                       (unsigned long)vaddr);
270
        }
271
        if (probe_result)
272
                *vaddr = true_contents;
273
        return probe_result;
274
}
275
#else
276
#define tsunami_probe_read(ADDR) 1
277
#endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */
278
 
279
#define FN __FUNCTION__
280
 
281
static void __init
282
tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
283
{
284
        struct pci_controller *hose;
285
 
286
        if (tsunami_probe_read(&pchip->pctl.csr) == 0)
287
                return;
288
 
289
        hose = alloc_pci_controller();
290
        if (index == 0)
291
                pci_isa_hose = hose;
292
        hose->io_space = alloc_resource();
293
        hose->mem_space = alloc_resource();
294
 
295
        /* This is for userland consumption.  For some reason, the 40-bit
296
           PIO bias that we use in the kernel through KSEG didn't work for
297
           the page table based user mappings.  So make sure we get the
298
           43-bit PIO bias.  */
299
        hose->sparse_mem_base = 0;
300
        hose->sparse_io_base = 0;
301
        hose->dense_mem_base
302
          = (TSUNAMI_MEM(index) & 0xffffffffff) | 0x80000000000;
303
        hose->dense_io_base
304
          = (TSUNAMI_IO(index) & 0xffffffffff) | 0x80000000000;
305
 
306
        hose->config_space_base = TSUNAMI_CONF(index);
307
        hose->index = index;
308
 
309
        hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS;
310
        hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE - 1;
311
        hose->io_space->name = pci_io_names[index];
312
        hose->io_space->flags = IORESOURCE_IO;
313
 
314
        hose->mem_space->start = TSUNAMI_MEM(index) - TSUNAMI_MEM_BIAS;
315
        hose->mem_space->end = hose->mem_space->start + 0xffffffff;
316
        hose->mem_space->name = pci_mem_names[index];
317
        hose->mem_space->flags = IORESOURCE_MEM;
318
 
319
        if (request_resource(&ioport_resource, hose->io_space) < 0)
320
                printk(KERN_ERR "Failed to request IO on hose %d\n", index);
321
        if (request_resource(&iomem_resource, hose->mem_space) < 0)
322
                printk(KERN_ERR "Failed to request MEM on hose %d\n", index);
323
 
324
        /*
325
         * Save the existing PCI window translations.  SRM will
326
         * need them when we go to reboot.
327
         */
328
 
329
        saved_pchip[index].wsba[0] = pchip->wsba[0].csr;
330
        saved_pchip[index].wsm[0] = pchip->wsm[0].csr;
331
        saved_pchip[index].tba[0] = pchip->tba[0].csr;
332
 
333
        saved_pchip[index].wsba[1] = pchip->wsba[1].csr;
334
        saved_pchip[index].wsm[1] = pchip->wsm[1].csr;
335
        saved_pchip[index].tba[1] = pchip->tba[1].csr;
336
 
337
        saved_pchip[index].wsba[2] = pchip->wsba[2].csr;
338
        saved_pchip[index].wsm[2] = pchip->wsm[2].csr;
339
        saved_pchip[index].tba[2] = pchip->tba[2].csr;
340
 
341
        saved_pchip[index].wsba[3] = pchip->wsba[3].csr;
342
        saved_pchip[index].wsm[3] = pchip->wsm[3].csr;
343
        saved_pchip[index].tba[3] = pchip->tba[3].csr;
344
 
345
        /*
346
         * Set up the PCI to main memory translation windows.
347
         *
348
         * Note: Window 3 is scatter-gather only
349
         *
350
         * Window 0 is scatter-gather 8MB at 8MB (for isa)
351
         * Window 1 is scatter-gather (up to) 1GB at 1GB
352
         * Window 2 is direct access 2GB at 2GB
353
         *
354
         * NOTE: we need the align_entry settings for Acer devices on ES40,
355
         * specifically floppy and IDE when memory is larger than 2GB.
356
         */
357
        hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
358
        /* Initially set for 4 PTEs, but will be overridden to 64K for ISA. */
359
        hose->sg_isa->align_entry = 4;
360
 
361
        hose->sg_pci = iommu_arena_new(hose, 0x40000000,
362
                                       size_for_memory(0x40000000), 0);
363
        hose->sg_pci->align_entry = 4; /* Tsunami caches 4 PTEs at a time */
364
 
365
        __direct_map_base = 0x80000000;
366
        __direct_map_size = 0x80000000;
367
 
368
        pchip->wsba[0].csr = hose->sg_isa->dma_base | 3;
369
        pchip->wsm[0].csr  = (hose->sg_isa->size - 1) & 0xfff00000;
370
        pchip->tba[0].csr  = virt_to_phys(hose->sg_isa->ptes);
371
 
372
        pchip->wsba[1].csr = hose->sg_pci->dma_base | 3;
373
        pchip->wsm[1].csr  = (hose->sg_pci->size - 1) & 0xfff00000;
374
        pchip->tba[1].csr  = virt_to_phys(hose->sg_pci->ptes);
375
 
376
        pchip->wsba[2].csr = 0x80000000 | 1;
377
        pchip->wsm[2].csr  = (0x80000000 - 1) & 0xfff00000;
378
        pchip->tba[2].csr  = 0;
379
 
380
        pchip->wsba[3].csr = 0;
381
 
382
        /* Enable the Monster Window to make DAC pci64 possible. */
383
        pchip->pctl.csr |= pctl_m_mwin;
384
 
385
        tsunami_pci_tbi(hose, 0, -1);
386
}
387
 
388
void __init
389
tsunami_init_arch(void)
390
{
391
#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
392
        extern asmlinkage void entInt(void);
393
        unsigned long tmp;
394
 
395
        /* Ho hum.. init_arch is called before init_IRQ, but we need to be
396
           able to handle machine checks.  So install the handler now.  */
397
        wrent(entInt, 0);
398
 
399
        /* NXMs just don't matter to Tsunami--unless they make it
400
           choke completely. */
401
        tmp = (unsigned long)(TSUNAMI_cchip - 1);
402
        printk("%s: probing bogus address:  0x%016lx\n", FN, bogus_addr);
403
        printk("\tprobe %s\n",
404
               tsunami_probe_write((unsigned long *)bogus_addr)
405
               ? "succeeded" : "failed");
406
#endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */
407
 
408
#if 0
409
        printk("%s: CChip registers:\n", FN);
410
        printk("%s: CSR_CSC 0x%lx\n", FN, TSUNAMI_cchip->csc.csr);
411
        printk("%s: CSR_MTR 0x%lx\n", FN, TSUNAMI_cchip.mtr.csr);
412
        printk("%s: CSR_MISC 0x%lx\n", FN, TSUNAMI_cchip->misc.csr);
413
        printk("%s: CSR_DIM0 0x%lx\n", FN, TSUNAMI_cchip->dim0.csr);
414
        printk("%s: CSR_DIM1 0x%lx\n", FN, TSUNAMI_cchip->dim1.csr);
415
        printk("%s: CSR_DIR0 0x%lx\n", FN, TSUNAMI_cchip->dir0.csr);
416
        printk("%s: CSR_DIR1 0x%lx\n", FN, TSUNAMI_cchip->dir1.csr);
417
        printk("%s: CSR_DRIR 0x%lx\n", FN, TSUNAMI_cchip->drir.csr);
418
 
419
        printk("%s: DChip registers:\n");
420
        printk("%s: CSR_DSC 0x%lx\n", FN, TSUNAMI_dchip->dsc.csr);
421
        printk("%s: CSR_STR 0x%lx\n", FN, TSUNAMI_dchip->str.csr);
422
        printk("%s: CSR_DREV 0x%lx\n", FN, TSUNAMI_dchip->drev.csr);
423
#endif
424
        /* With multiple PCI busses, we play with I/O as physical addrs.  */
425
        ioport_resource.end = ~0UL;
426
        iomem_resource.end = ~0UL;
427
 
428
        /* Find how many hoses we have, and initialize them.  TSUNAMI
429
           and TYPHOON can have 2, but might only have 1 (DS10).  */
430
 
431
        tsunami_init_one_pchip(TSUNAMI_pchip0, 0);
432
        if (TSUNAMI_cchip->csc.csr & 1L<<14)
433
                tsunami_init_one_pchip(TSUNAMI_pchip1, 1);
434
}
435
 
436
static void
437
tsunami_kill_one_pchip(tsunami_pchip *pchip, int index)
438
{
439
        pchip->wsba[0].csr = saved_pchip[index].wsba[0];
440
        pchip->wsm[0].csr = saved_pchip[index].wsm[0];
441
        pchip->tba[0].csr = saved_pchip[index].tba[0];
442
 
443
        pchip->wsba[1].csr = saved_pchip[index].wsba[1];
444
        pchip->wsm[1].csr = saved_pchip[index].wsm[1];
445
        pchip->tba[1].csr = saved_pchip[index].tba[1];
446
 
447
        pchip->wsba[2].csr = saved_pchip[index].wsba[2];
448
        pchip->wsm[2].csr = saved_pchip[index].wsm[2];
449
        pchip->tba[2].csr = saved_pchip[index].tba[2];
450
 
451
        pchip->wsba[3].csr = saved_pchip[index].wsba[3];
452
        pchip->wsm[3].csr = saved_pchip[index].wsm[3];
453
        pchip->tba[3].csr = saved_pchip[index].tba[3];
454
}
455
 
456
void
457
tsunami_kill_arch(int mode)
458
{
459
        tsunami_kill_one_pchip(TSUNAMI_pchip0, 0);
460
        if (TSUNAMI_cchip->csc.csr & 1L<<14)
461
                tsunami_kill_one_pchip(TSUNAMI_pchip1, 1);
462
}
463
 
464
static inline void
465
tsunami_pci_clr_err_1(tsunami_pchip *pchip)
466
{
467
        pchip->perror.csr;
468
        pchip->perror.csr = 0x040;
469
        mb();
470
        pchip->perror.csr;
471
}
472
 
473
static inline void
474
tsunami_pci_clr_err(void)
475
{
476
        tsunami_pci_clr_err_1(TSUNAMI_pchip0);
477
 
478
        /* TSUNAMI and TYPHOON can have 2, but might only have 1 (DS10) */
479
        if (TSUNAMI_cchip->csc.csr & 1L<<14)
480
                tsunami_pci_clr_err_1(TSUNAMI_pchip1);
481
}
482
 
483
void
484
tsunami_machine_check(unsigned long vector, unsigned long la_ptr,
485
                      struct pt_regs * regs)
486
{
487
        /* Clear error before any reporting.  */
488
        mb();
489
        mb();  /* magic */
490
        draina();
491
        tsunami_pci_clr_err();
492
        wrmces(0x7);
493
        mb();
494
 
495
        process_mcheck_info(vector, la_ptr, regs, "TSUNAMI",
496
                            mcheck_expected(smp_processor_id()));
497
}

powered by: WebSVN 2.1.0

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