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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [alpha/] [kernel/] [cia.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * Code common to all CIA chips.
3
 *
4
 * Written by David A Rusling (david.rusling@reo.mts.dec.com).
5
 * December 1995.
6
 *
7
 */
8
#include <linux/kernel.h>
9
#include <linux/config.h>
10
#include <linux/types.h>
11
#include <linux/bios32.h>
12
#include <linux/pci.h>
13
#include <linux/sched.h>
14
 
15
#include <asm/system.h>
16
#include <asm/io.h>
17
#include <asm/hwrpb.h>
18
#include <asm/ptrace.h>
19
#include <asm/mmu_context.h>
20
 
21
extern struct hwrpb_struct *hwrpb;
22
extern asmlinkage void wrmces(unsigned long mces);
23
 
24
/*
25
 * Machine check reasons.  Defined according to PALcode sources
26
 * (osf.h and platform.h).
27
 */
28
#define MCHK_K_TPERR            0x0080
29
#define MCHK_K_TCPERR           0x0082
30
#define MCHK_K_HERR             0x0084
31
#define MCHK_K_ECC_C            0x0086
32
#define MCHK_K_ECC_NC           0x0088
33
#define MCHK_K_OS_BUGCHECK      0x008A
34
#define MCHK_K_PAL_BUGCHECK     0x0090
35
 
36
/*
37
 * BIOS32-style PCI interface:
38
 */
39
 
40
#ifdef CONFIG_ALPHA_CIA
41
 
42
/* #define DEBUG_MCHECK */
43
/* #define DEBUG_CONFIG */
44
/* #define DEBUG_DUMP_REGS */
45
 
46
#ifdef DEBUG_MCHECK
47
# define DBGM(args)     printk args
48
#else
49
# define DBGM(args)
50
#endif
51
#ifdef DEBUG_CONFIG
52
# define DBGC(args)     printk args
53
#else
54
# define DBGC(args)
55
#endif
56
 
57
#define vuip    volatile unsigned int  *
58
 
59
static volatile unsigned int CIA_mcheck_expected = 0;
60
static volatile unsigned int CIA_mcheck_taken = 0;
61
static unsigned int CIA_jd;
62
 
63
#ifdef CONFIG_ALPHA_SRM_SETUP
64
unsigned int CIA_DMA_WIN_BASE = CIA_DMA_WIN_BASE_DEFAULT;
65
unsigned int CIA_DMA_WIN_SIZE = CIA_DMA_WIN_SIZE_DEFAULT;
66
unsigned long cia_sm_base_r1, cia_sm_base_r2, cia_sm_base_r3;
67
#endif /* SRM_SETUP */
68
 
69
/*
70
 * Given a bus, device, and function number, compute resulting
71
 * configuration space address and setup the CIA_HAXR2 register
72
 * accordingly.  It is therefore not safe to have concurrent
73
 * invocations to configuration space access routines, but there
74
 * really shouldn't be any need for this.
75
 *
76
 * Type 0:
77
 *
78
 *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
79
 *  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
80
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81
 * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
82
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83
 *
84
 *      31:11   Device select bit.
85
 *      10:8    Function number
86
 *       7:2    Register number
87
 *
88
 * Type 1:
89
 *
90
 *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
91
 *  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
92
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
93
 * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
94
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95
 *
96
 *      31:24   reserved
97
 *      23:16   bus number (8 bits = 128 possible buses)
98
 *      15:11   Device number (5 bits)
99
 *      10:8    function number
100
 *       7:2    register number
101
 *
102
 * Notes:
103
 *      The function number selects which function of a multi-function device
104
 *      (e.g., scsi and ethernet).
105
 *
106
 *      The register selects a DWORD (32 bit) register offset.  Hence it
107
 *      doesn't get shifted by 2 bits as we want to "drop" the bottom two
108
 *      bits.
109
 */
110
static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
111
                        unsigned char where, unsigned long *pci_addr,
112
                        unsigned char *type1)
113
{
114
        unsigned long addr;
115
 
116
        DBGC(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p, type1=0x%p)\n",
117
             bus, device_fn, where, pci_addr, type1));
118
 
119
        if (bus == 0) {
120
                int device = device_fn >> 3;
121
 
122
                /* type 0 configuration cycle: */
123
 
124
                if (device > 20) {
125
                        DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n",
126
                             device));
127
                        return -1;
128
                }
129
 
130
                *type1 = 0;
131
                addr = (device_fn << 8) | (where);
132
        } else {
133
                /* type 1 configuration cycle: */
134
                *type1 = 1;
135
                addr = (bus << 16) | (device_fn << 8) | (where);
136
        }
137
        *pci_addr = addr;
138
        DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
139
        return 0;
140
}
141
 
142
 
143
static unsigned int conf_read(unsigned long addr, unsigned char type1)
144
{
145
        unsigned long flags;
146
        unsigned int stat0, value;
147
        unsigned int cia_cfg = 0; /* to keep gcc quiet */
148
 
149
        value = 0xffffffffU;
150
        mb();
151
 
152
        save_flags(flags);      /* avoid getting hit by machine check */
153
        cli();
154
 
155
        DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
156
 
157
        /* reset status register to avoid losing errors: */
158
        stat0 = *((vuip)CIA_IOC_CIA_ERR);
159
        *((vuip)CIA_IOC_CIA_ERR) = stat0;
160
        mb();
161
        DBGC(("conf_read: CIA ERR was 0x%x\n", stat0));
162
        /* if Type1 access, must set CIA CFG */
163
        if (type1) {
164
                cia_cfg = *((vuip)CIA_IOC_CFG);
165
                *((vuip)CIA_IOC_CFG) = cia_cfg | 1;
166
                mb();
167
                DBGC(("conf_read: TYPE1 access\n"));
168
        }
169
 
170
        mb();
171
        draina();
172
        CIA_mcheck_expected = 1;
173
        CIA_mcheck_taken = 0;
174
        mb();
175
        /* access configuration space: */
176
        value = *((vuip)addr);
177
        mb();
178
        mb();
179
        if (CIA_mcheck_taken) {
180
                CIA_mcheck_taken = 0;
181
                value = 0xffffffffU;
182
                mb();
183
        }
184
        CIA_mcheck_expected = 0;
185
        mb();
186
 
187
        /* if Type1 access, must reset IOC CFG so normal IO space ops work */
188
        if (type1) {
189
                *((vuip)CIA_IOC_CFG) = cia_cfg & ~1;
190
                mb();
191
        }
192
 
193
        DBGC(("conf_read(): finished\n"));
194
 
195
        restore_flags(flags);
196
        return value;
197
}
198
 
199
 
200
static void conf_write(unsigned long addr, unsigned int value, unsigned char type1)
201
{
202
        unsigned long flags;
203
        unsigned int stat0;
204
        unsigned int cia_cfg = 0; /* to keep gcc quiet */
205
 
206
        save_flags(flags);      /* avoid getting hit by machine check */
207
        cli();
208
 
209
        /* reset status register to avoid losing errors: */
210
        stat0 = *((vuip)CIA_IOC_CIA_ERR);
211
        *((vuip)CIA_IOC_CIA_ERR) = stat0;
212
        mb();
213
        DBGC(("conf_write: CIA ERR was 0x%x\n", stat0));
214
        /* if Type1 access, must set CIA CFG */
215
        if (type1) {
216
                cia_cfg = *((vuip)CIA_IOC_CFG);
217
                *((vuip)CIA_IOC_CFG) = cia_cfg | 1;
218
                mb();
219
                DBGC(("conf_write: TYPE1 access\n"));
220
        }
221
 
222
        draina();
223
        CIA_mcheck_expected = 1;
224
        mb();
225
        /* access configuration space: */
226
        *((vuip)addr) = value;
227
        mb();
228
        mb();
229
 
230
        CIA_mcheck_expected = 0;
231
                mb();
232
 
233
        /* if Type1 access, must reset IOC CFG so normal IO space ops work */
234
        if (type1) {
235
                *((vuip)CIA_IOC_CFG) = cia_cfg & ~1;
236
                mb();
237
        }
238
 
239
        DBGC(("conf_write(): finished\n"));
240
        restore_flags(flags);
241
}
242
 
243
 
244
int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
245
                              unsigned char where, unsigned char *value)
246
{
247
        unsigned long addr = CIA_CONF;
248
        unsigned long pci_addr;
249
        unsigned char type1;
250
 
251
        *value = 0xff;
252
 
253
        if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
254
                return PCIBIOS_SUCCESSFUL;
255
        }
256
 
257
        addr |= (pci_addr << 5) + 0x00;
258
 
259
        *value = conf_read(addr, type1) >> ((where & 3) * 8);
260
 
261
        return PCIBIOS_SUCCESSFUL;
262
}
263
 
264
 
265
int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
266
                              unsigned char where, unsigned short *value)
267
{
268
        unsigned long addr = CIA_CONF;
269
        unsigned long pci_addr;
270
        unsigned char type1;
271
 
272
        *value = 0xffff;
273
 
274
        if (where & 0x1) {
275
                return PCIBIOS_BAD_REGISTER_NUMBER;
276
        }
277
 
278
        if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
279
                return PCIBIOS_SUCCESSFUL;
280
        }
281
 
282
        addr |= (pci_addr << 5) + 0x08;
283
 
284
        *value = conf_read(addr, type1) >> ((where & 3) * 8);
285
        return PCIBIOS_SUCCESSFUL;
286
}
287
 
288
 
289
int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
290
                               unsigned char where, unsigned int *value)
291
{
292
        unsigned long addr = CIA_CONF;
293
        unsigned long pci_addr;
294
        unsigned char type1;
295
 
296
        *value = 0xffffffff;
297
        if (where & 0x3) {
298
                return PCIBIOS_BAD_REGISTER_NUMBER;
299
        }
300
 
301
        if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
302
                return PCIBIOS_SUCCESSFUL;
303
        }
304
        addr |= (pci_addr << 5) + 0x18;
305
        *value = conf_read(addr, type1);
306
        return PCIBIOS_SUCCESSFUL;
307
}
308
 
309
 
310
int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
311
                               unsigned char where, unsigned char value)
312
{
313
        unsigned long addr = CIA_CONF;
314
        unsigned long pci_addr;
315
        unsigned char type1;
316
 
317
        if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
318
                return PCIBIOS_SUCCESSFUL;
319
        }
320
        addr |= (pci_addr << 5) + 0x00;
321
        conf_write(addr, value << ((where & 3) * 8), type1);
322
        return PCIBIOS_SUCCESSFUL;
323
}
324
 
325
 
326
int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
327
                               unsigned char where, unsigned short value)
328
{
329
        unsigned long addr = CIA_CONF;
330
        unsigned long pci_addr;
331
        unsigned char type1;
332
 
333
        if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
334
                return PCIBIOS_SUCCESSFUL;
335
        }
336
        addr |= (pci_addr << 5) + 0x08;
337
        conf_write(addr, value << ((where & 3) * 8), type1);
338
        return PCIBIOS_SUCCESSFUL;
339
}
340
 
341
 
342
int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
343
                                unsigned char where, unsigned int value)
344
{
345
        unsigned long addr = CIA_CONF;
346
        unsigned long pci_addr;
347
        unsigned char type1;
348
 
349
        if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
350
                return PCIBIOS_SUCCESSFUL;
351
        }
352
        addr |= (pci_addr << 5) + 0x18;
353
        conf_write(addr, value << ((where & 3) * 8), type1);
354
        return PCIBIOS_SUCCESSFUL;
355
}
356
 
357
 
358
unsigned long cia_init(unsigned long mem_start, unsigned long mem_end)
359
{
360
        unsigned int cia_tmp;
361
 
362
#ifdef DEBUG_DUMP_REGS
363
        {
364
          unsigned int temp;
365
#if 1
366
          temp = *((vuip)CIA_IOC_CIA_REV); mb();
367
          printk("CIA_init: CIA_REV was 0x%x\n", temp);
368
          temp = *((vuip)CIA_IOC_PCI_LAT); mb();
369
          printk("CIA_init: CIA_PCI_LAT was 0x%x\n", temp);
370
          temp = *((vuip)CIA_IOC_CIA_CTRL); mb();
371
          printk("CIA_init: CIA_CTRL was 0x%x\n", temp);
372
          temp = *((vuip)0xfffffc8740000140UL); mb();
373
          printk("CIA_init: CIA_CTRL1 was 0x%x\n", temp);
374
          temp = *((vuip)CIA_IOC_HAE_MEM); mb();
375
          printk("CIA_init: CIA_HAE_MEM was 0x%x\n", temp);
376
          temp = *((vuip)CIA_IOC_HAE_IO); mb();
377
          printk("CIA_init: CIA_HAE_IO was 0x%x\n", temp);
378
          temp = *((vuip)CIA_IOC_CFG); mb();
379
          printk("CIA_init: CIA_CFG was 0x%x\n", temp);
380
          temp = *((vuip)CIA_IOC_CACK_EN); mb();
381
          printk("CIA_init: CIA_CACK_EN was 0x%x\n", temp);
382
          temp = *((vuip)CIA_IOC_CFG); mb();
383
          printk("CIA_init: CIA_CFG was 0x%x\n", temp);
384
          temp = *((vuip)CIA_IOC_CIA_DIAG); mb();
385
          printk("CIA_init: CIA_DIAG was 0x%x\n", temp);
386
          temp = *((vuip)CIA_IOC_DIAG_CHECK); mb();
387
          printk("CIA_init: CIA_DIAG_CHECK was 0x%x\n", temp);
388
          temp = *((vuip)CIA_IOC_PERF_MONITOR); mb();
389
          printk("CIA_init: CIA_PERF_MONITOR was 0x%x\n", temp);
390
          temp = *((vuip)CIA_IOC_PERF_CONTROL); mb();
391
          printk("CIA_init: CIA_PERF_CONTROL was 0x%x\n", temp);
392
          temp = *((vuip)CIA_IOC_CIA_ERR); mb();
393
          printk("CIA_init: CIA_ERR was 0x%x\n", temp);
394
          temp = *((vuip)CIA_IOC_CIA_STAT); mb();
395
          printk("CIA_init: CIA_STAT was 0x%x\n", temp);
396
          temp = *((vuip)CIA_IOC_MCR); mb();
397
          printk("CIA_init: CIA_MCR was 0x%x\n", temp);
398
          temp = *((vuip)CIA_IOC_ERR_MASK); mb();
399
          printk("CIA_init: CIA_ERR_MASK was 0x%x\n", temp);
400
#endif
401
          temp = *((vuip)CIA_IOC_PCI_W0_BASE); mb();
402
          printk("CIA_init: W0_BASE was 0x%x\n", temp);
403
          temp = *((vuip)CIA_IOC_PCI_W1_BASE); mb();
404
          printk("CIA_init: W1_BASE was 0x%x\n", temp);
405
          temp = *((vuip)CIA_IOC_PCI_W2_BASE); mb();
406
          printk("CIA_init: W2_BASE was 0x%x\n", temp);
407
          temp = *((vuip)CIA_IOC_PCI_W3_BASE); mb();
408
          printk("CIA_init: W3_BASE was 0x%x\n", temp);
409
        }
410
#endif /* DEBUG_DUMP_REGS */
411
 
412
        /*
413
         * Set up error reporting.
414
         */
415
        cia_tmp = *(vuip)CIA_IOC_CIA_ERR;
416
        cia_tmp |= 0x180 ;   /* master, target abort */
417
        *(vuip)CIA_IOC_CIA_ERR = cia_tmp ;
418
        mb() ;
419
 
420
        cia_tmp = *(vuip)CIA_IOC_CIA_CTRL;
421
        cia_tmp |= 0x400;   /* turn on FILL_ERR to get mchecks */
422
        *(vuip)CIA_IOC_CIA_CTRL = cia_tmp ;
423
        mb() ;
424
 
425
#ifdef CONFIG_ALPHA_SRM_SETUP
426
        /* check window 0 for enabled and mapped to 0 */
427
        if (((*(vuip)CIA_IOC_PCI_W0_BASE & 3) == 1) &&
428
            (*(vuip)CIA_IOC_PCI_T0_BASE == 0))
429
        {
430
          CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W0_BASE & 0xfff00000U;
431
          CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W0_MASK & 0xfff00000U;
432
          CIA_DMA_WIN_SIZE += 0x00100000U;
433
#if 1
434
          printk("cia_init: using Window 0 settings\n");
435
          printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
436
                 *(vuip)CIA_IOC_PCI_W0_BASE,
437
                 *(vuip)CIA_IOC_PCI_W0_MASK,
438
                 *(vuip)CIA_IOC_PCI_T0_BASE);
439
#endif
440
        }
441
        else  /* check window 1 for enabled and mapped to 0 */
442
        if (((*(vuip)CIA_IOC_PCI_W1_BASE & 3) == 1) &&
443
            (*(vuip)CIA_IOC_PCI_T1_BASE == 0))
444
        {
445
          CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W1_BASE & 0xfff00000U;
446
          CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W1_MASK & 0xfff00000U;
447
          CIA_DMA_WIN_SIZE += 0x00100000U;
448
#if 1
449
          printk("cia_init: using Window 1 settings\n");
450
          printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
451
                 *(vuip)CIA_IOC_PCI_W1_BASE,
452
                 *(vuip)CIA_IOC_PCI_W1_MASK,
453
                 *(vuip)CIA_IOC_PCI_T1_BASE);
454
#endif
455
        }
456
        else  /* check window 2 for enabled and mapped to 0 */
457
        if (((*(vuip)CIA_IOC_PCI_W2_BASE & 3) == 1) &&
458
            (*(vuip)CIA_IOC_PCI_T2_BASE == 0))
459
        {
460
          CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W2_BASE & 0xfff00000U;
461
          CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W2_MASK & 0xfff00000U;
462
          CIA_DMA_WIN_SIZE += 0x00100000U;
463
#if 1
464
          printk("cia_init: using Window 2 settings\n");
465
          printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
466
                 *(vuip)CIA_IOC_PCI_W2_BASE,
467
                 *(vuip)CIA_IOC_PCI_W2_MASK,
468
                 *(vuip)CIA_IOC_PCI_T2_BASE);
469
#endif
470
        }
471
        else  /* check window 3 for enabled and mapped to 0 */
472
        if (((*(vuip)CIA_IOC_PCI_W3_BASE & 3) == 1) &&
473
            (*(vuip)CIA_IOC_PCI_T3_BASE == 0))
474
        {
475
          CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W3_BASE & 0xfff00000U;
476
          CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W3_MASK & 0xfff00000U;
477
          CIA_DMA_WIN_SIZE += 0x00100000U;
478
#if 1
479
          printk("cia_init: using Window 3 settings\n");
480
          printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
481
                 *(vuip)CIA_IOC_PCI_W3_BASE,
482
                 *(vuip)CIA_IOC_PCI_W3_MASK,
483
                 *(vuip)CIA_IOC_PCI_T3_BASE);
484
#endif
485
        }
486
        else  /* we must use our defaults which were pre-initialized... */
487
#endif /* SRM_SETUP */
488
        {
489
        /*
490
         * Set up the PCI->physical memory translation windows.
491
         * For now, windows 1,2 and 3 are disabled.  In the future, we may
492
         * want to use them to do scatter/gather DMA.  Window 0
493
         * goes at 1 GB and is 1 GB large.
494
         */
495
 
496
        *(vuip)CIA_IOC_PCI_W0_BASE = 1U | (CIA_DMA_WIN_BASE & 0xfff00000U);
497
        *(vuip)CIA_IOC_PCI_W0_MASK = (CIA_DMA_WIN_SIZE - 1) & 0xfff00000U;
498
        *(vuip)CIA_IOC_PCI_T0_BASE = 0;
499
 
500
        *(vuip)CIA_IOC_PCI_W1_BASE = 0x0 ;
501
        *(vuip)CIA_IOC_PCI_W2_BASE = 0x0 ;
502
        *(vuip)CIA_IOC_PCI_W3_BASE = 0x0 ;
503
        }
504
 
505
        /*
506
         * check ASN in HWRPB for validity, report if bad
507
         */
508
        if (hwrpb->max_asn != MAX_ASN) {
509
                printk("CIA_init: max ASN from HWRPB is bad (0x%lx)\n",
510
                        hwrpb->max_asn);
511
                hwrpb->max_asn = MAX_ASN;
512
        }
513
 
514
        /*
515
         *  Next, clear the CIA_CFG register, which gets used
516
         *  for PCI Config Space accesses. That is the way
517
         *  we want to use it, and we do not want to depend on
518
         *  what ARC or SRM might have left behind...
519
         */
520
        {
521
          unsigned int cia_cfg = *((vuip)CIA_IOC_CFG); mb();
522
          if (cia_cfg) {
523
              printk("CIA_init: CFG was 0x%x\n", cia_cfg);
524
              *((vuip)CIA_IOC_CFG) = 0; mb();
525
          }
526
        }
527
 
528
        {
529
          unsigned int cia_hae_mem = *((vuip)CIA_IOC_HAE_MEM);
530
          unsigned int cia_hae_io = *((vuip)CIA_IOC_HAE_IO);
531
#if 0
532
          printk("CIA_init: HAE_MEM was 0x%x\n", cia_hae_mem);
533
          printk("CIA_init: HAE_IO was 0x%x\n", cia_hae_io);
534
#endif
535
#ifdef CONFIG_ALPHA_SRM_SETUP
536
          /*
537
            sigh... For the SRM setup, unless we know apriori what the HAE
538
            contents will be, we need to setup the arbitrary region bases
539
            so we can test against the range of addresses and tailor the
540
            region chosen for the SPARSE memory access.
541
 
542
            see include/asm-alpha/cia.h for the SPARSE mem read/write
543
          */
544
          cia_sm_base_r1 = (cia_hae_mem      ) & 0xe0000000UL; /* region 1 */
545
          cia_sm_base_r2 = (cia_hae_mem << 16) & 0xf8000000UL; /* region 2 */
546
          cia_sm_base_r3 = (cia_hae_mem << 24) & 0xfc000000UL; /* region 3 */
547
#else /* SRM_SETUP */
548
          *((vuip)CIA_IOC_HAE_MEM) = 0; mb();
549
          cia_hae_mem = *((vuip)CIA_IOC_HAE_MEM);
550
          *((vuip)CIA_IOC_HAE_IO) = 0; mb();
551
          cia_hae_io = *((vuip)CIA_IOC_HAE_IO);
552
#endif /* SRM_SETUP */
553
        }
554
 
555
        return mem_start;
556
}
557
 
558
int cia_pci_clr_err(void)
559
{
560
        CIA_jd = *((vuip)CIA_IOC_CIA_ERR);
561
        DBGM(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd));
562
        *((vuip)CIA_IOC_CIA_ERR) = 0x0180;
563
        mb();
564
        return 0;
565
}
566
 
567
void cia_machine_check(unsigned long vector, unsigned long la_ptr,
568
                         struct pt_regs * regs)
569
{
570
        struct el_common *mchk_header;
571
        struct el_procdata *mchk_procdata;
572
        struct el_CIA_sysdata_mcheck *mchk_sysdata;
573
        unsigned long * ptr;
574
        const char * reason;
575
        char buf[128];
576
        long i;
577
 
578
        mchk_header = (struct el_common *)la_ptr;
579
        mchk_procdata =
580
                (struct el_procdata *)(la_ptr + mchk_header->proc_offset);
581
        mchk_sysdata =
582
          (struct el_CIA_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset);
583
 
584
        DBGM(("cia_machine_check: vector=0x%lx la_ptr=0x%lx\n", vector, la_ptr));
585
        DBGM(("                     pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
586
             regs->pc, mchk_header->size, mchk_header->proc_offset, mchk_header->sys_offset));
587
        DBGM(("cia_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
588
             CIA_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear));
589
#ifdef DEBUG_MCHECK
590
        {
591
            unsigned long *ptr;
592
            int i;
593
 
594
            ptr = (unsigned long *)la_ptr;
595
            for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
596
                        printk(" +%lx %lx %lx\n", i*sizeof(long),
597
                               ptr[i], ptr[i+1]);
598
            }
599
        }
600
#endif /* DEBUG_MCHECK */
601
        /*
602
         * Check if machine check is due to a badaddr() and if so,
603
         * ignore the machine check.
604
         */
605
        mb();
606
        mb();
607
        if (CIA_mcheck_expected) {
608
                DBGM(("CIA machine check expected\n"));
609
                CIA_mcheck_expected = 0;
610
                CIA_mcheck_taken = 1;
611
                mb();
612
                mb();
613
                draina();
614
                cia_pci_clr_err();
615
                wrmces(0x7);
616
                mb();
617
                return;
618
        }
619
 
620
        switch ((unsigned int) mchk_header->code) {
621
              case MCHK_K_TPERR:        reason = "tag parity error"; break;
622
              case MCHK_K_TCPERR:       reason = "tag control parity error"; break;
623
              case MCHK_K_HERR:         reason = "generic hard error"; break;
624
              case MCHK_K_ECC_C:        reason = "correctable ECC error"; break;
625
              case MCHK_K_ECC_NC:       reason = "uncorrectable ECC error"; break;
626
              case MCHK_K_OS_BUGCHECK:  reason = "OS-specific PAL bugcheck"; break;
627
              case MCHK_K_PAL_BUGCHECK: reason = "callsys in kernel mode"; break;
628
              case 0x96: reason = "i-cache read retryable error"; break;
629
              case 0x98: reason = "processor detected hard error"; break;
630
 
631
                /* system specific (these are for Alcor, at least): */
632
              case 0x203: reason = "system detected uncorrectable ECC error"; break;
633
              case 0x205: reason = "parity error detected by CIA"; break;
634
              case 0x207: reason = "non-existent memory error"; break;
635
              case 0x209: reason = "PCI SERR detected"; break;
636
              case 0x20b: reason = "PCI data parity error detected"; break;
637
              case 0x20d: reason = "PCI address parity error detected"; break;
638
              case 0x20f: reason = "PCI master abort error"; break;
639
              case 0x211: reason = "PCI target abort error"; break;
640
              case 0x213: reason = "scatter/gather PTE invalid error"; break;
641
              case 0x215: reason = "flash ROM write error"; break;
642
              case 0x217: reason = "IOA timeout detected"; break;
643
              case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
644
              case 0x21b: reason = "EISA fail-safe timer timeout"; break;
645
              case 0x21d: reason = "EISA bus time-out"; break;
646
              case 0x21f: reason = "EISA software generated NMI"; break;
647
              case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
648
              default:
649
                sprintf(buf, "reason for machine-check unknown (0x%x)",
650
                        (unsigned int) mchk_header->code);
651
                reason = buf;
652
                break;
653
        }
654
        wrmces(rdmces());       /* reset machine check pending flag */
655
        mb();
656
 
657
        printk(KERN_CRIT "  CIA machine check: %s%s\n",
658
               reason, mchk_header->retry ? " (retryable)" : "");
659
        printk(KERN_CRIT "   vector=0x%lx la_ptr=0x%lx pc=0x%lx\n",
660
               vector, la_ptr, regs->pc);
661
 
662
        /* dump the logout area to give all info: */
663
 
664
        ptr = (unsigned long *)la_ptr;
665
        for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
666
            printk(KERN_CRIT " +%8lx %016lx %016lx\n",
667
                   i*sizeof(long), ptr[i], ptr[i+1]);
668
        }
669
}
670
 
671
#endif /* CONFIG_ALPHA_CIA */

powered by: WebSVN 2.1.0

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