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

Subversion Repositories or1k

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

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

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

powered by: WebSVN 2.1.0

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