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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: traps.c,v 1.1.1.1 2004-04-15 01:34:36 phoenix Exp $
2
 * arch/sparc64/kernel/traps.c
3
 *
4
 * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
5
 * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com)
6
 */
7
 
8
/*
9
 * I like traps on v9, :))))
10
 */
11
 
12
#include <linux/config.h>
13
#include <linux/sched.h>  /* for jiffies */
14
#include <linux/kernel.h>
15
#include <linux/signal.h>
16
#include <linux/smp.h>
17
#include <linux/smp_lock.h>
18
#include <linux/mm.h>
19
 
20
#include <asm/delay.h>
21
#include <asm/system.h>
22
#include <asm/ptrace.h>
23
#include <asm/oplib.h>
24
#include <asm/page.h>
25
#include <asm/pgtable.h>
26
#include <asm/unistd.h>
27
#include <asm/uaccess.h>
28
#include <asm/fpumacro.h>
29
#include <asm/lsu.h>
30
#include <asm/dcu.h>
31
#include <asm/estate.h>
32
#include <asm/chafsr.h>
33
#include <asm/psrcompat.h>
34
#include <asm/processor.h>
35
#ifdef CONFIG_KMOD
36
#include <linux/kmod.h>
37
#endif
38
 
39
/* When an irrecoverable trap occurs at tl > 0, the trap entry
40
 * code logs the trap state registers at every level in the trap
41
 * stack.  It is found at (pt_regs + sizeof(pt_regs)) and the layout
42
 * is as follows:
43
 */
44
struct tl1_traplog {
45
        struct {
46
                unsigned long tstate;
47
                unsigned long tpc;
48
                unsigned long tnpc;
49
                unsigned long tt;
50
        } trapstack[4];
51
        unsigned long tl;
52
};
53
 
54
static void dump_tl1_traplog(struct tl1_traplog *p)
55
{
56
        int i;
57
 
58
        printk("TRAPLOG: Error at trap level 0x%lx, dumping track stack.\n",
59
               p->tl);
60
        for (i = 0; i < 4; i++) {
61
                printk(KERN_CRIT
62
                       "TRAPLOG: Trap level %d TSTATE[%016lx] TPC[%016lx] "
63
                       "TNPC[%016lx] TT[%lx]\n",
64
                       i + 1,
65
                       p->trapstack[i].tstate, p->trapstack[i].tpc,
66
                       p->trapstack[i].tnpc, p->trapstack[i].tt);
67
        }
68
}
69
 
70
void bad_trap (struct pt_regs *regs, long lvl)
71
{
72
        char buffer[32];
73
        siginfo_t info;
74
 
75
        if (lvl < 0x100) {
76
                sprintf(buffer, "Bad hw trap %lx at tl0\n", lvl);
77
                die_if_kernel(buffer, regs);
78
        }
79
 
80
        lvl -= 0x100;
81
        if (regs->tstate & TSTATE_PRIV) {
82
                sprintf(buffer, "Kernel bad sw trap %lx", lvl);
83
                die_if_kernel (buffer, regs);
84
        }
85
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
86
                regs->tpc &= 0xffffffff;
87
                regs->tnpc &= 0xffffffff;
88
        }
89
        info.si_signo = SIGILL;
90
        info.si_errno = 0;
91
        info.si_code = ILL_ILLTRP;
92
        info.si_addr = (void *)regs->tpc;
93
        info.si_trapno = lvl;
94
        force_sig_info(SIGILL, &info, current);
95
}
96
 
97
void bad_trap_tl1 (struct pt_regs *regs, long lvl)
98
{
99
        char buffer[32];
100
 
101
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
102
 
103
        sprintf (buffer, "Bad trap %lx at tl>0", lvl);
104
        die_if_kernel (buffer, regs);
105
}
106
 
107
#ifdef CONFIG_DEBUG_BUGVERBOSE
108
void do_BUG(const char *file, int line)
109
{
110
        bust_spinlocks(1);
111
        printk("kernel BUG at %s:%d!\n", file, line);
112
}
113
#endif
114
 
115
void instruction_access_exception(struct pt_regs *regs,
116
                                  unsigned long sfsr, unsigned long sfar)
117
{
118
        siginfo_t info;
119
 
120
        if (regs->tstate & TSTATE_PRIV) {
121
                printk("instruction_access_exception: SFSR[%016lx] SFAR[%016lx], going.\n",
122
                       sfsr, sfar);
123
                die_if_kernel("Iax", regs);
124
        }
125
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
126
                regs->tpc &= 0xffffffff;
127
                regs->tnpc &= 0xffffffff;
128
        }
129
        info.si_signo = SIGSEGV;
130
        info.si_errno = 0;
131
        info.si_code = SEGV_MAPERR;
132
        info.si_addr = (void *)regs->tpc;
133
        info.si_trapno = 0;
134
        force_sig_info(SIGSEGV, &info, current);
135
}
136
 
137
void instruction_access_exception_tl1(struct pt_regs *regs,
138
                                      unsigned long sfsr, unsigned long sfar)
139
{
140
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
141
        instruction_access_exception(regs, sfsr, sfar);
142
}
143
 
144
void data_access_exception (struct pt_regs *regs,
145
                            unsigned long sfsr, unsigned long sfar)
146
{
147
        siginfo_t info;
148
 
149
        if (regs->tstate & TSTATE_PRIV) {
150
                /* Test if this comes from uaccess places. */
151
                unsigned long fixup, g2;
152
 
153
                g2 = regs->u_regs[UREG_G2];
154
                if ((fixup = search_exception_table (regs->tpc, &g2))) {
155
                        /* Ouch, somebody is trying ugly VM hole tricks on us... */
156
#ifdef DEBUG_EXCEPTIONS
157
                        printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc);
158
                        printk("EX_TABLE: insn<%016lx> fixup<%016lx> "
159
                               "g2<%016lx>\n", regs->tpc, fixup, g2);
160
#endif
161
                        regs->tpc = fixup;
162
                        regs->tnpc = regs->tpc + 4;
163
                        regs->u_regs[UREG_G2] = g2;
164
                        return;
165
                }
166
                /* Shit... */
167
                printk("data_access_exception: SFSR[%016lx] SFAR[%016lx], going.\n",
168
                       sfsr, sfar);
169
                die_if_kernel("Dax", regs);
170
        }
171
 
172
        info.si_signo = SIGSEGV;
173
        info.si_errno = 0;
174
        info.si_code = SEGV_MAPERR;
175
        info.si_addr = (void *)sfar;
176
        info.si_trapno = 0;
177
        force_sig_info(SIGSEGV, &info, current);
178
}
179
 
180
#ifdef CONFIG_PCI
181
/* This is really pathetic... */
182
extern volatile int pci_poke_in_progress;
183
extern volatile int pci_poke_cpu;
184
extern volatile int pci_poke_faulted;
185
#endif
186
 
187
/* When access exceptions happen, we must do this. */
188
static void spitfire_clean_and_reenable_l1_caches(void)
189
{
190
        unsigned long va;
191
 
192
        if (tlb_type != spitfire)
193
                BUG();
194
 
195
        /* Clean 'em. */
196
        for (va =  0; va < (PAGE_SIZE << 1); va += 32) {
197
                spitfire_put_icache_tag(va, 0x0);
198
                spitfire_put_dcache_tag(va, 0x0);
199
        }
200
 
201
        /* Re-enable in LSU. */
202
        __asm__ __volatile__("flush %%g6\n\t"
203
                             "membar #Sync\n\t"
204
                             "stxa %0, [%%g0] %1\n\t"
205
                             "membar #Sync"
206
                             : /* no outputs */
207
                             : "r" (LSU_CONTROL_IC | LSU_CONTROL_DC |
208
                                    LSU_CONTROL_IM | LSU_CONTROL_DM),
209
                             "i" (ASI_LSU_CONTROL)
210
                             : "memory");
211
}
212
 
213
void do_iae(struct pt_regs *regs)
214
{
215
        siginfo_t info;
216
 
217
        spitfire_clean_and_reenable_l1_caches();
218
 
219
        info.si_signo = SIGBUS;
220
        info.si_errno = 0;
221
        info.si_code = BUS_OBJERR;
222
        info.si_addr = (void *)0;
223
        info.si_trapno = 0;
224
        force_sig_info(SIGBUS, &info, current);
225
}
226
 
227
void do_dae(struct pt_regs *regs)
228
{
229
#ifdef CONFIG_PCI
230
        if (pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) {
231
                spitfire_clean_and_reenable_l1_caches();
232
 
233
                pci_poke_faulted = 1;
234
 
235
                /* Why the fuck did they have to change this? */
236
                if (tlb_type == cheetah || tlb_type == cheetah_plus)
237
                        regs->tpc += 4;
238
 
239
                regs->tnpc = regs->tpc + 4;
240
                return;
241
        }
242
#endif
243
        do_iae(regs);
244
}
245
 
246
static char ecc_syndrome_table[] = {
247
        0x4c, 0x40, 0x41, 0x48, 0x42, 0x48, 0x48, 0x49,
248
        0x43, 0x48, 0x48, 0x49, 0x48, 0x49, 0x49, 0x4a,
249
        0x44, 0x48, 0x48, 0x20, 0x48, 0x39, 0x4b, 0x48,
250
        0x48, 0x25, 0x31, 0x48, 0x28, 0x48, 0x48, 0x2c,
251
        0x45, 0x48, 0x48, 0x21, 0x48, 0x3d, 0x04, 0x48,
252
        0x48, 0x4b, 0x35, 0x48, 0x2d, 0x48, 0x48, 0x29,
253
        0x48, 0x00, 0x01, 0x48, 0x0a, 0x48, 0x48, 0x4b,
254
        0x0f, 0x48, 0x48, 0x4b, 0x48, 0x49, 0x49, 0x48,
255
        0x46, 0x48, 0x48, 0x2a, 0x48, 0x3b, 0x27, 0x48,
256
        0x48, 0x4b, 0x33, 0x48, 0x22, 0x48, 0x48, 0x2e,
257
        0x48, 0x19, 0x1d, 0x48, 0x1b, 0x4a, 0x48, 0x4b,
258
        0x1f, 0x48, 0x4a, 0x4b, 0x48, 0x4b, 0x4b, 0x48,
259
        0x48, 0x4b, 0x24, 0x48, 0x07, 0x48, 0x48, 0x36,
260
        0x4b, 0x48, 0x48, 0x3e, 0x48, 0x30, 0x38, 0x48,
261
        0x49, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x16, 0x48,
262
        0x48, 0x12, 0x4b, 0x48, 0x49, 0x48, 0x48, 0x4b,
263
        0x47, 0x48, 0x48, 0x2f, 0x48, 0x3f, 0x4b, 0x48,
264
        0x48, 0x06, 0x37, 0x48, 0x23, 0x48, 0x48, 0x2b,
265
        0x48, 0x05, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x32,
266
        0x26, 0x48, 0x48, 0x3a, 0x48, 0x34, 0x3c, 0x48,
267
        0x48, 0x11, 0x15, 0x48, 0x13, 0x4a, 0x48, 0x4b,
268
        0x17, 0x48, 0x4a, 0x4b, 0x48, 0x4b, 0x4b, 0x48,
269
        0x49, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x1e, 0x48,
270
        0x48, 0x1a, 0x4b, 0x48, 0x49, 0x48, 0x48, 0x4b,
271
        0x48, 0x08, 0x0d, 0x48, 0x02, 0x48, 0x48, 0x49,
272
        0x03, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x4b, 0x48,
273
        0x49, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x10, 0x48,
274
        0x48, 0x14, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x4b,
275
        0x49, 0x48, 0x48, 0x49, 0x48, 0x4b, 0x18, 0x48,
276
        0x48, 0x1c, 0x4b, 0x48, 0x4b, 0x48, 0x48, 0x4b,
277
        0x4a, 0x0c, 0x09, 0x48, 0x0e, 0x48, 0x48, 0x4b,
278
        0x0b, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x4b, 0x4a
279
};
280
 
281
/* cee_trap in entry.S encodes AFSR/UDBH/UDBL error status
282
 * in the following format.  The AFAR is left as is, with
283
 * reserved bits cleared, and is a raw 40-bit physical
284
 * address.
285
 */
286
#define CE_STATUS_UDBH_UE               (1UL << (43 + 9))
287
#define CE_STATUS_UDBH_CE               (1UL << (43 + 8))
288
#define CE_STATUS_UDBH_ESYNDR           (0xffUL << 43)
289
#define CE_STATUS_UDBH_SHIFT            43
290
#define CE_STATUS_UDBL_UE               (1UL << (33 + 9))
291
#define CE_STATUS_UDBL_CE               (1UL << (33 + 8))
292
#define CE_STATUS_UDBL_ESYNDR           (0xffUL << 33)
293
#define CE_STATUS_UDBL_SHIFT            33
294
#define CE_STATUS_AFSR_MASK             (0x1ffffffffUL)
295
#define CE_STATUS_AFSR_ME               (1UL << 32)
296
#define CE_STATUS_AFSR_PRIV             (1UL << 31)
297
#define CE_STATUS_AFSR_ISAP             (1UL << 30)
298
#define CE_STATUS_AFSR_ETP              (1UL << 29)
299
#define CE_STATUS_AFSR_IVUE             (1UL << 28)
300
#define CE_STATUS_AFSR_TO               (1UL << 27)
301
#define CE_STATUS_AFSR_BERR             (1UL << 26)
302
#define CE_STATUS_AFSR_LDP              (1UL << 25)
303
#define CE_STATUS_AFSR_CP               (1UL << 24)
304
#define CE_STATUS_AFSR_WP               (1UL << 23)
305
#define CE_STATUS_AFSR_EDP              (1UL << 22)
306
#define CE_STATUS_AFSR_UE               (1UL << 21)
307
#define CE_STATUS_AFSR_CE               (1UL << 20)
308
#define CE_STATUS_AFSR_ETS              (0xfUL << 16)
309
#define CE_STATUS_AFSR_ETS_SHIFT        16
310
#define CE_STATUS_AFSR_PSYND            (0xffffUL << 0)
311
#define CE_STATUS_AFSR_PSYND_SHIFT      0
312
 
313
/* Layout of Ecache TAG Parity Syndrome of AFSR */
314
#define AFSR_ETSYNDROME_7_0             0x1UL /* E$-tag bus bits  <7:0> */
315
#define AFSR_ETSYNDROME_15_8            0x2UL /* E$-tag bus bits <15:8> */
316
#define AFSR_ETSYNDROME_21_16           0x4UL /* E$-tag bus bits <21:16> */
317
#define AFSR_ETSYNDROME_24_22           0x8UL /* E$-tag bus bits <24:22> */
318
 
319
static char *syndrome_unknown = "<Unknown>";
320
 
321
asmlinkage void cee_log(unsigned long ce_status,
322
                        unsigned long afar,
323
                        struct pt_regs *regs)
324
{
325
        char memmod_str[64];
326
        char *p;
327
        unsigned short scode, udb_reg;
328
 
329
        printk(KERN_WARNING "CPU[%d]: Correctable ECC Error "
330
               "AFSR[%lx] AFAR[%016lx] UDBL[%lx] UDBH[%lx]\n",
331
               smp_processor_id(),
332
               (ce_status & CE_STATUS_AFSR_MASK),
333
               afar,
334
               ((ce_status >> CE_STATUS_UDBL_SHIFT) & 0x3ffUL),
335
               ((ce_status >> CE_STATUS_UDBH_SHIFT) & 0x3ffUL));
336
 
337
        udb_reg = ((ce_status >> CE_STATUS_UDBL_SHIFT) & 0x3ffUL);
338
        if (udb_reg & (1 << 8)) {
339
                scode = ecc_syndrome_table[udb_reg & 0xff];
340
                if (prom_getunumber(scode, afar,
341
                                    memmod_str, sizeof(memmod_str)) == -1)
342
                        p = syndrome_unknown;
343
                else
344
                        p = memmod_str;
345
                printk(KERN_WARNING "CPU[%d]: UDBL Syndrome[%x] "
346
                       "Memory Module \"%s\"\n",
347
                       smp_processor_id(), scode, p);
348
        }
349
 
350
        udb_reg = ((ce_status >> CE_STATUS_UDBH_SHIFT) & 0x3ffUL);
351
        if (udb_reg & (1 << 8)) {
352
                scode = ecc_syndrome_table[udb_reg & 0xff];
353
                if (prom_getunumber(scode, afar,
354
                                    memmod_str, sizeof(memmod_str)) == -1)
355
                        p = syndrome_unknown;
356
                else
357
                        p = memmod_str;
358
                printk(KERN_WARNING "CPU[%d]: UDBH Syndrome[%x] "
359
                       "Memory Module \"%s\"\n",
360
                       smp_processor_id(), scode, p);
361
        }
362
}
363
 
364
/* Cheetah error trap handling. */
365
static unsigned long ecache_flush_physbase;
366
static unsigned long ecache_flush_linesize;
367
static unsigned long ecache_flush_size;
368
 
369
/* WARNING: The error trap handlers in assembly know the precise
370
 *          layout of the following structure.
371
 *
372
 * C-level handlers below use this information to log the error
373
 * and then determine how to recover (if possible).
374
 */
375
struct cheetah_err_info {
376
/*0x00*/u64 afsr;
377
/*0x08*/u64 afar;
378
 
379
        /* D-cache state */
380
/*0x10*/u64 dcache_data[4];     /* The actual data      */
381
/*0x30*/u64 dcache_index;       /* D-cache index        */
382
/*0x38*/u64 dcache_tag;         /* D-cache tag/valid    */
383
/*0x40*/u64 dcache_utag;        /* D-cache microtag     */
384
/*0x48*/u64 dcache_stag;        /* D-cache snooptag     */
385
 
386
        /* I-cache state */
387
/*0x50*/u64 icache_data[8];     /* The actual insns + predecode */
388
/*0x90*/u64 icache_index;       /* I-cache index        */
389
/*0x98*/u64 icache_tag;         /* I-cache phys tag     */
390
/*0xa0*/u64 icache_utag;        /* I-cache microtag     */
391
/*0xa8*/u64 icache_stag;        /* I-cache snooptag     */
392
/*0xb0*/u64 icache_upper;       /* I-cache upper-tag    */
393
/*0xb8*/u64 icache_lower;       /* I-cache lower-tag    */
394
 
395
        /* E-cache state */
396
/*0xc0*/u64 ecache_data[4];     /* 32 bytes from staging registers */
397
/*0xe0*/u64 ecache_index;       /* E-cache index        */
398
/*0xe8*/u64 ecache_tag;         /* E-cache tag/state    */
399
 
400
/*0xf0*/u64 __pad[32 - 30];
401
};
402
#define CHAFSR_INVALID          ((u64)-1L)
403
 
404
/* This table is ordered in priority of errors and matches the
405
 * AFAR overwrite policy as well.
406
 */
407
 
408
struct afsr_error_table {
409
        unsigned long mask;
410
        const char *name;
411
};
412
 
413
static const char CHAFSR_PERR_msg[] =
414
        "System interface protocol error";
415
static const char CHAFSR_IERR_msg[] =
416
        "Internal processor error";
417
static const char CHAFSR_ISAP_msg[] =
418
        "System request parity error on incoming addresss";
419
static const char CHAFSR_UCU_msg[] =
420
        "Uncorrectable E-cache ECC error for ifetch/data";
421
static const char CHAFSR_UCC_msg[] =
422
        "SW Correctable E-cache ECC error for ifetch/data";
423
static const char CHAFSR_UE_msg[] =
424
        "Uncorrectable system bus data ECC error for read";
425
static const char CHAFSR_EDU_msg[] =
426
        "Uncorrectable E-cache ECC error for stmerge/blkld";
427
static const char CHAFSR_EMU_msg[] =
428
        "Uncorrectable system bus MTAG error";
429
static const char CHAFSR_WDU_msg[] =
430
        "Uncorrectable E-cache ECC error for writeback";
431
static const char CHAFSR_CPU_msg[] =
432
        "Uncorrectable ECC error for copyout";
433
static const char CHAFSR_CE_msg[] =
434
        "HW corrected system bus data ECC error for read";
435
static const char CHAFSR_EDC_msg[] =
436
        "HW corrected E-cache ECC error for stmerge/blkld";
437
static const char CHAFSR_EMC_msg[] =
438
        "HW corrected system bus MTAG ECC error";
439
static const char CHAFSR_WDC_msg[] =
440
        "HW corrected E-cache ECC error for writeback";
441
static const char CHAFSR_CPC_msg[] =
442
        "HW corrected ECC error for copyout";
443
static const char CHAFSR_TO_msg[] =
444
        "Unmapped error from system bus";
445
static const char CHAFSR_BERR_msg[] =
446
        "Bus error response from system bus";
447
static const char CHAFSR_IVC_msg[] =
448
        "HW corrected system bus data ECC error for ivec read";
449
static const char CHAFSR_IVU_msg[] =
450
        "Uncorrectable system bus data ECC error for ivec read";
451
static struct afsr_error_table __cheetah_error_table[] = {
452
        {       CHAFSR_PERR,    CHAFSR_PERR_msg         },
453
        {       CHAFSR_IERR,    CHAFSR_IERR_msg         },
454
        {       CHAFSR_ISAP,    CHAFSR_ISAP_msg         },
455
        {       CHAFSR_UCU,     CHAFSR_UCU_msg          },
456
        {       CHAFSR_UCC,     CHAFSR_UCC_msg          },
457
        {       CHAFSR_UE,      CHAFSR_UE_msg           },
458
        {       CHAFSR_EDU,     CHAFSR_EDU_msg          },
459
        {       CHAFSR_EMU,     CHAFSR_EMU_msg          },
460
        {       CHAFSR_WDU,     CHAFSR_WDU_msg          },
461
        {       CHAFSR_CPU,     CHAFSR_CPU_msg          },
462
        {       CHAFSR_CE,      CHAFSR_CE_msg           },
463
        {       CHAFSR_EDC,     CHAFSR_EDC_msg          },
464
        {       CHAFSR_EMC,     CHAFSR_EMC_msg          },
465
        {       CHAFSR_WDC,     CHAFSR_WDC_msg          },
466
        {       CHAFSR_CPC,     CHAFSR_CPC_msg          },
467
        {       CHAFSR_TO,      CHAFSR_TO_msg           },
468
        {       CHAFSR_BERR,    CHAFSR_BERR_msg         },
469
        /* These two do not update the AFAR. */
470
        {       CHAFSR_IVC,     CHAFSR_IVC_msg          },
471
        {       CHAFSR_IVU,     CHAFSR_IVU_msg          },
472
        {       0,               NULL                    },
473
};
474
static const char CHPAFSR_DTO_msg[] =
475
        "System bus unmapped error for prefetch/storequeue-read";
476
static const char CHPAFSR_DBERR_msg[] =
477
        "System bus error for prefetch/storequeue-read";
478
static const char CHPAFSR_THCE_msg[] =
479
        "Hardware corrected E-cache Tag ECC error";
480
static const char CHPAFSR_TSCE_msg[] =
481
        "SW handled correctable E-cache Tag ECC error";
482
static const char CHPAFSR_TUE_msg[] =
483
        "Uncorrectable E-cache Tag ECC error";
484
static const char CHPAFSR_DUE_msg[] =
485
        "System bus uncorrectable data ECC error due to prefetch/store-fill";
486
static struct afsr_error_table __cheetah_plus_error_table[] = {
487
        {       CHAFSR_PERR,    CHAFSR_PERR_msg         },
488
        {       CHAFSR_IERR,    CHAFSR_IERR_msg         },
489
        {       CHAFSR_ISAP,    CHAFSR_ISAP_msg         },
490
        {       CHAFSR_UCU,     CHAFSR_UCU_msg          },
491
        {       CHAFSR_UCC,     CHAFSR_UCC_msg          },
492
        {       CHAFSR_UE,      CHAFSR_UE_msg           },
493
        {       CHAFSR_EDU,     CHAFSR_EDU_msg          },
494
        {       CHAFSR_EMU,     CHAFSR_EMU_msg          },
495
        {       CHAFSR_WDU,     CHAFSR_WDU_msg          },
496
        {       CHAFSR_CPU,     CHAFSR_CPU_msg          },
497
        {       CHAFSR_CE,      CHAFSR_CE_msg           },
498
        {       CHAFSR_EDC,     CHAFSR_EDC_msg          },
499
        {       CHAFSR_EMC,     CHAFSR_EMC_msg          },
500
        {       CHAFSR_WDC,     CHAFSR_WDC_msg          },
501
        {       CHAFSR_CPC,     CHAFSR_CPC_msg          },
502
        {       CHAFSR_TO,      CHAFSR_TO_msg           },
503
        {       CHAFSR_BERR,    CHAFSR_BERR_msg         },
504
        {       CHPAFSR_DTO,    CHPAFSR_DTO_msg         },
505
        {       CHPAFSR_DBERR,  CHPAFSR_DBERR_msg       },
506
        {       CHPAFSR_THCE,   CHPAFSR_THCE_msg        },
507
        {       CHPAFSR_TSCE,   CHPAFSR_TSCE_msg        },
508
        {       CHPAFSR_TUE,    CHPAFSR_TUE_msg         },
509
        {       CHPAFSR_DUE,    CHPAFSR_DUE_msg         },
510
        /* These two do not update the AFAR. */
511
        {       CHAFSR_IVC,     CHAFSR_IVC_msg          },
512
        {       CHAFSR_IVU,     CHAFSR_IVU_msg          },
513
        {       0,               NULL                    },
514
};
515
static const char JPAFSR_JETO_msg[] =
516
        "System interface protocol error, hw timeout caused";
517
static const char JPAFSR_SCE_msg[] =
518
        "Parity error on system snoop results";
519
static const char JPAFSR_JEIC_msg[] =
520
        "System interface protocol error, illegal command detected";
521
static const char JPAFSR_JEIT_msg[] =
522
        "System interface protocol error, illegal ADTYPE detected";
523
static const char JPAFSR_OM_msg[] =
524
        "Out of range memory error has occurred";
525
static const char JPAFSR_ETP_msg[] =
526
        "Parity error on L2 cache tag SRAM";
527
static const char JPAFSR_UMS_msg[] =
528
        "Error due to unsupported store";
529
static const char JPAFSR_RUE_msg[] =
530
        "Uncorrectable ECC error from remote cache/memory";
531
static const char JPAFSR_RCE_msg[] =
532
        "Correctable ECC error from remote cache/memory";
533
static const char JPAFSR_BP_msg[] =
534
        "JBUS parity error on returned read data";
535
static const char JPAFSR_WBP_msg[] =
536
        "JBUS parity error on data for writeback or block store";
537
static const char JPAFSR_FRC_msg[] =
538
        "Foreign read to DRAM incurring correctable ECC error";
539
static const char JPAFSR_FRU_msg[] =
540
        "Foreign read to DRAM incurring uncorrectable ECC error";
541
static struct afsr_error_table __jalapeno_error_table[] = {
542
        {       JPAFSR_JETO,    JPAFSR_JETO_msg         },
543
        {       JPAFSR_SCE,     JPAFSR_SCE_msg          },
544
        {       JPAFSR_JEIC,    JPAFSR_JEIC_msg         },
545
        {       JPAFSR_JEIT,    JPAFSR_JEIT_msg         },
546
        {       CHAFSR_PERR,    CHAFSR_PERR_msg         },
547
        {       CHAFSR_IERR,    CHAFSR_IERR_msg         },
548
        {       CHAFSR_ISAP,    CHAFSR_ISAP_msg         },
549
        {       CHAFSR_UCU,     CHAFSR_UCU_msg          },
550
        {       CHAFSR_UCC,     CHAFSR_UCC_msg          },
551
        {       CHAFSR_UE,      CHAFSR_UE_msg           },
552
        {       CHAFSR_EDU,     CHAFSR_EDU_msg          },
553
        {       JPAFSR_OM,      JPAFSR_OM_msg           },
554
        {       CHAFSR_WDU,     CHAFSR_WDU_msg          },
555
        {       CHAFSR_CPU,     CHAFSR_CPU_msg          },
556
        {       CHAFSR_CE,      CHAFSR_CE_msg           },
557
        {       CHAFSR_EDC,     CHAFSR_EDC_msg          },
558
        {       JPAFSR_ETP,     JPAFSR_ETP_msg          },
559
        {       CHAFSR_WDC,     CHAFSR_WDC_msg          },
560
        {       CHAFSR_CPC,     CHAFSR_CPC_msg          },
561
        {       CHAFSR_TO,      CHAFSR_TO_msg           },
562
        {       CHAFSR_BERR,    CHAFSR_BERR_msg         },
563
        {       JPAFSR_UMS,     JPAFSR_UMS_msg          },
564
        {       JPAFSR_RUE,     JPAFSR_RUE_msg          },
565
        {       JPAFSR_RCE,     JPAFSR_RCE_msg          },
566
        {       JPAFSR_BP,      JPAFSR_BP_msg           },
567
        {       JPAFSR_WBP,     JPAFSR_WBP_msg          },
568
        {       JPAFSR_FRC,     JPAFSR_FRC_msg          },
569
        {       JPAFSR_FRU,     JPAFSR_FRU_msg          },
570
        /* These two do not update the AFAR. */
571
        {       CHAFSR_IVU,     CHAFSR_IVU_msg          },
572
        {       0,               NULL                    },
573
};
574
static struct afsr_error_table *cheetah_error_table;
575
static unsigned long cheetah_afsr_errors;
576
 
577
/* This is allocated at boot time based upon the largest hardware
578
 * cpu ID in the system.  We allocate two entries per cpu, one for
579
 * TL==0 logging and one for TL >= 1 logging.
580
 */
581
struct cheetah_err_info *cheetah_error_log;
582
 
583
static __inline__ struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr)
584
{
585
        struct cheetah_err_info *p;
586
        int cpu = smp_processor_id();
587
 
588
        if (!cheetah_error_log)
589
                return NULL;
590
 
591
        p = cheetah_error_log + (cpu * 2);
592
        if ((afsr & CHAFSR_TL1) != 0UL)
593
                p++;
594
 
595
        return p;
596
}
597
 
598
extern unsigned int tl0_icpe[], tl1_icpe[];
599
extern unsigned int tl0_dcpe[], tl1_dcpe[];
600
extern unsigned int tl0_fecc[], tl1_fecc[];
601
extern unsigned int tl0_cee[], tl1_cee[];
602
extern unsigned int tl0_iae[], tl1_iae[];
603
extern unsigned int tl0_dae[], tl1_dae[];
604
extern unsigned int cheetah_plus_icpe_trap_vector[], cheetah_plus_icpe_trap_vector_tl1[];
605
extern unsigned int cheetah_plus_dcpe_trap_vector[], cheetah_plus_dcpe_trap_vector_tl1[];
606
extern unsigned int cheetah_fecc_trap_vector[], cheetah_fecc_trap_vector_tl1[];
607
extern unsigned int cheetah_cee_trap_vector[], cheetah_cee_trap_vector_tl1[];
608
extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector_tl1[];
609
 
610
void cheetah_ecache_flush_init(void)
611
{
612
        unsigned long largest_size, smallest_linesize, order, ver;
613
        char type[16];
614
        int node, highest_cpu, i;
615
 
616
        /* Scan all cpu device tree nodes, note two values:
617
         * 1) largest E-cache size
618
         * 2) smallest E-cache line size
619
         */
620
        largest_size = 0UL;
621
        smallest_linesize = ~0UL;
622
        node = prom_getchild(prom_root_node);
623
        while ((node = prom_getsibling(node)) != 0) {
624
                prom_getstring(node, "device_type", type, sizeof(type));
625
                if (!strcmp(type, "cpu")) {
626
                        unsigned long val;
627
 
628
                        val = prom_getintdefault(node, "ecache-size",
629
                                                 (2 * 1024 * 1024));
630
                        if (val > largest_size)
631
                                largest_size = val;
632
                        val = prom_getintdefault(node, "ecache-line-size", 64);
633
                        if (val < smallest_linesize)
634
                                smallest_linesize = val;
635
                }
636
        }
637
        if (largest_size == 0UL || smallest_linesize == ~0UL) {
638
                prom_printf("cheetah_ecache_flush_init: Cannot probe cpu E-cache "
639
                            "parameters.\n");
640
                prom_halt();
641
        }
642
 
643
        ecache_flush_size = (2 * largest_size);
644
        ecache_flush_linesize = smallest_linesize;
645
 
646
        /* Discover a physically contiguous chunk of physical
647
         * memory in 'sp_banks' of size ecache_flush_size calculated
648
         * above.  Store the physical base of this area at
649
         * ecache_flush_physbase.
650
         */
651
        for (node = 0; ; node++) {
652
                if (sp_banks[node].num_bytes == 0)
653
                        break;
654
                if (sp_banks[node].num_bytes >= ecache_flush_size) {
655
                        ecache_flush_physbase = sp_banks[node].base_addr;
656
                        break;
657
                }
658
        }
659
 
660
        /* Note: Zero would be a valid value of ecache_flush_physbase so
661
         * don't use that as the success test. :-)
662
         */
663
        if (sp_banks[node].num_bytes == 0) {
664
                prom_printf("cheetah_ecache_flush_init: Cannot find %d byte "
665
                            "contiguous physical memory.\n", ecache_flush_size);
666
                prom_halt();
667
        }
668
 
669
        /* Now allocate error trap reporting scoreboard. */
670
        highest_cpu = 0;
671
#ifdef CONFIG_SMP
672
        for (i = 0; i < NR_CPUS; i++) {
673
                if ((1UL << i) & cpu_present_map)
674
                        highest_cpu = i;
675
        }
676
#endif
677
        highest_cpu++;
678
        node = highest_cpu * (2 * sizeof(struct cheetah_err_info));
679
        for (order = 0; order < MAX_ORDER; order++) {
680
                if ((PAGE_SIZE << order) >= node)
681
                        break;
682
        }
683
        cheetah_error_log = (struct cheetah_err_info *)
684
                __get_free_pages(GFP_KERNEL, order);
685
        if (!cheetah_error_log) {
686
                prom_printf("cheetah_ecache_flush_init: Failed to allocate "
687
                            "error logging scoreboard (%d bytes).\n", node);
688
                prom_halt();
689
        }
690
        memset(cheetah_error_log, 0, PAGE_SIZE << order);
691
 
692
        /* Mark all AFSRs as invalid so that the trap handler will
693
         * log new new information there.
694
         */
695
        for (i = 0; i < 2 * highest_cpu; i++)
696
                cheetah_error_log[i].afsr = CHAFSR_INVALID;
697
 
698
        __asm__ ("rdpr %%ver, %0" : "=r" (ver));
699
        if ((ver >> 32) == 0x003e0016) {
700
                cheetah_error_table = &__jalapeno_error_table[0];
701
                cheetah_afsr_errors = JPAFSR_ERRORS;
702
        } else if ((ver >> 32) == 0x003e0015) {
703
                cheetah_error_table = &__cheetah_plus_error_table[0];
704
                cheetah_afsr_errors = CHPAFSR_ERRORS;
705
        } else {
706
                cheetah_error_table = &__cheetah_error_table[0];
707
                cheetah_afsr_errors = CHAFSR_ERRORS;
708
        }
709
 
710
        /* Now patch trap tables. */
711
        memcpy(tl0_fecc, cheetah_fecc_trap_vector, (8 * 4));
712
        memcpy(tl1_fecc, cheetah_fecc_trap_vector_tl1, (8 * 4));
713
        memcpy(tl0_cee, cheetah_cee_trap_vector, (8 * 4));
714
        memcpy(tl1_cee, cheetah_cee_trap_vector_tl1, (8 * 4));
715
        memcpy(tl0_iae, cheetah_deferred_trap_vector, (8 * 4));
716
        memcpy(tl1_iae, cheetah_deferred_trap_vector_tl1, (8 * 4));
717
        memcpy(tl0_dae, cheetah_deferred_trap_vector, (8 * 4));
718
        memcpy(tl1_dae, cheetah_deferred_trap_vector_tl1, (8 * 4));
719
        if (tlb_type == cheetah_plus) {
720
                memcpy(tl0_dcpe, cheetah_plus_dcpe_trap_vector, (8 * 4));
721
                memcpy(tl1_dcpe, cheetah_plus_dcpe_trap_vector_tl1, (8 * 4));
722
                memcpy(tl0_icpe, cheetah_plus_icpe_trap_vector, (8 * 4));
723
                memcpy(tl1_icpe, cheetah_plus_icpe_trap_vector_tl1, (8 * 4));
724
        }
725
        flushi(PAGE_OFFSET);
726
}
727
 
728
static void cheetah_flush_ecache(void)
729
{
730
        unsigned long flush_base = ecache_flush_physbase;
731
        unsigned long flush_linesize = ecache_flush_linesize;
732
        unsigned long flush_size = ecache_flush_size;
733
 
734
        __asm__ __volatile__("1: subcc  %0, %4, %0\n\t"
735
                             "   bne,pt %%xcc, 1b\n\t"
736
                             "    ldxa  [%2 + %0] %3, %%g0\n\t"
737
                             : "=&r" (flush_size)
738
                             : "0" (flush_size), "r" (flush_base),
739
                               "i" (ASI_PHYS_USE_EC), "r" (flush_linesize));
740
}
741
 
742
static void cheetah_flush_ecache_line(unsigned long physaddr)
743
{
744
        unsigned long alias;
745
 
746
        physaddr &= ~(8UL - 1UL);
747
        physaddr = (ecache_flush_physbase +
748
                    (physaddr & ((ecache_flush_size>>1UL) - 1UL)));
749
        alias = physaddr + (ecache_flush_size >> 1UL);
750
        __asm__ __volatile__("ldxa [%0] %2, %%g0\n\t"
751
                             "ldxa [%1] %2, %%g0\n\t"
752
                             "membar #Sync"
753
                             : /* no outputs */
754
                             : "r" (physaddr), "r" (alias),
755
                               "i" (ASI_PHYS_USE_EC));
756
}
757
 
758
/* Unfortunately, the diagnostic access to the I-cache tags we need to
759
 * use to clear the thing interferes with I-cache coherency transactions.
760
 *
761
 * So we must only flush the I-cache when it is disabled.
762
 */
763
static void __cheetah_flush_icache(void)
764
{
765
        unsigned long i;
766
 
767
        /* Clear the valid bits in all the tags. */
768
        for (i = 0; i < (1 << 15); i += (1 << 5)) {
769
                __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
770
                                     "membar #Sync"
771
                                     : /* no outputs */
772
                                     : "r" (i | (2 << 3)), "i" (ASI_IC_TAG));
773
        }
774
}
775
 
776
static void cheetah_flush_icache(void)
777
{
778
        unsigned long dcu_save;
779
 
780
        /* Save current DCU, disable I-cache. */
781
        __asm__ __volatile__("ldxa [%%g0] %1, %0\n\t"
782
                             "or %0, %2, %%g1\n\t"
783
                             "stxa %%g1, [%%g0] %1\n\t"
784
                             "membar #Sync"
785
                             : "=r" (dcu_save)
786
                             : "i" (ASI_DCU_CONTROL_REG), "i" (DCU_IC)
787
                             : "g1");
788
 
789
        __cheetah_flush_icache();
790
 
791
        /* Restore DCU register */
792
        __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
793
                             "membar #Sync"
794
                             : /* no outputs */
795
                             : "r" (dcu_save), "i" (ASI_DCU_CONTROL_REG));
796
}
797
 
798
static void cheetah_flush_dcache(void)
799
{
800
        unsigned long i;
801
 
802
        for (i = 0; i < (1 << 16); i += (1 << 5)) {
803
                __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
804
                                     "membar #Sync"
805
                                     : /* no outputs */
806
                                     : "r" (i), "i" (ASI_DCACHE_TAG));
807
        }
808
}
809
 
810
/* In order to make the even parity correct we must do two things.
811
 * First, we clear DC_data_parity and set DC_utag to an appropriate value.
812
 * Next, we clear out all 32-bytes of data for that line.  Data of
813
 * all-zero + tag parity value of zero == correct parity.
814
 */
815
static void cheetah_plus_zap_dcache_parity(void)
816
{
817
        unsigned long i;
818
 
819
        for (i = 0; i < (1 << 16); i += (1 << 5)) {
820
                unsigned long tag = (i >> 14);
821
                unsigned long j;
822
 
823
                __asm__ __volatile__("membar    #Sync\n\t"
824
                                     "stxa      %0, [%1] %2\n\t"
825
                                     "membar    #Sync"
826
                                     : /* no outputs */
827
                                     : "r" (tag), "r" (i),
828
                                       "i" (ASI_DCACHE_UTAG));
829
                for (j = i; j < i + (1 << 5); j += (1 << 3))
830
                        __asm__ __volatile__("membar    #Sync\n\t"
831
                                             "stxa      %%g0, [%0] %1\n\t"
832
                                             "membar    #Sync"
833
                                             : /* no outputs */
834
                                             : "r" (j), "i" (ASI_DCACHE_DATA));
835
        }
836
}
837
 
838
/* Conversion tables used to frob Cheetah AFSR syndrome values into
839
 * something palatable to the memory controller driver get_unumber
840
 * routine.
841
 */
842
#define MT0     137
843
#define MT1     138
844
#define MT2     139
845
#define NONE    254
846
#define MTC0    140
847
#define MTC1    141
848
#define MTC2    142
849
#define MTC3    143
850
#define C0      128
851
#define C1      129
852
#define C2      130
853
#define C3      131
854
#define C4      132
855
#define C5      133
856
#define C6      134
857
#define C7      135
858
#define C8      136
859
#define M2      144
860
#define M3      145
861
#define M4      146
862
#define M       147
863
static unsigned char cheetah_ecc_syntab[] = {
864
/*00*/NONE, C0, C1, M2, C2, M2, M3, 47, C3, M2, M2, 53, M2, 41, 29, M,
865
/*01*/C4, M, M, 50, M2, 38, 25, M2, M2, 33, 24, M2, 11, M, M2, 16,
866
/*02*/C5, M, M, 46, M2, 37, 19, M2, M, 31, 32, M, 7, M2, M2, 10,
867
/*03*/M2, 40, 13, M2, 59, M, M2, 66, M, M2, M2, 0, M2, 67, 71, M,
868
/*04*/C6, M, M, 43, M, 36, 18, M, M2, 49, 15, M, 63, M2, M2, 6,
869
/*05*/M2, 44, 28, M2, M, M2, M2, 52, 68, M2, M2, 62, M2, M3, M3, M4,
870
/*06*/M2, 26, 106, M2, 64, M, M2, 2, 120, M, M2, M3, M, M3, M3, M4,
871
/*07*/116, M2, M2, M3, M2, M3, M, M4, M2, 58, 54, M2, M, M4, M4, M3,
872
/*08*/C7, M2, M, 42, M, 35, 17, M2, M, 45, 14, M2, 21, M2, M2, 5,
873
/*09*/M, 27, M, M, 99, M, M, 3, 114, M2, M2, 20, M2, M3, M3, M,
874
/*0a*/M2, 23, 113, M2, 112, M2, M, 51, 95, M, M2, M3, M2, M3, M3, M2,
875
/*0b*/103, M, M2, M3, M2, M3, M3, M4, M2, 48, M, M, 73, M2, M, M3,
876
/*0c*/M2, 22, 110, M2, 109, M2, M, 9, 108, M2, M, M3, M2, M3, M3, M,
877
/*0d*/102, M2, M, M, M2, M3, M3, M, M2, M3, M3, M2, M, M4, M, M3,
878
/*0e*/98, M, M2, M3, M2, M, M3, M4, M2, M3, M3, M4, M3, M, M, M,
879
/*0f*/M2, M3, M3, M, M3, M, M, M, 56, M4, M, M3, M4, M, M, M,
880
/*10*/C8, M, M2, 39, M, 34, 105, M2, M, 30, 104, M, 101, M, M, 4,
881
/*11*/M, M, 100, M, 83, M, M2, 12, 87, M, M, 57, M2, M, M3, M,
882
/*12*/M2, 97, 82, M2, 78, M2, M2, 1, 96, M, M, M, M, M, M3, M2,
883
/*13*/94, M, M2, M3, M2, M, M3, M, M2, M, 79, M, 69, M, M4, M,
884
/*14*/M2, 93, 92, M, 91, M, M2, 8, 90, M2, M2, M, M, M, M, M4,
885
/*15*/89, M, M, M3, M2, M3, M3, M, M, M, M3, M2, M3, M2, M, M3,
886
/*16*/86, M, M2, M3, M2, M, M3, M, M2, M, M3, M, M3, M, M, M3,
887
/*17*/M, M, M3, M2, M3, M2, M4, M, 60, M, M2, M3, M4, M, M, M2,
888
/*18*/M2, 88, 85, M2, 84, M, M2, 55, 81, M2, M2, M3, M2, M3, M3, M4,
889
/*19*/77, M, M, M, M2, M3, M, M, M2, M3, M3, M4, M3, M2, M, M,
890
/*1a*/74, M, M2, M3, M, M, M3, M, M, M, M3, M, M3, M, M4, M3,
891
/*1b*/M2, 70, 107, M4, 65, M2, M2, M, 127, M, M, M, M2, M3, M3, M,
892
/*1c*/80, M2, M2, 72, M, 119, 118, M, M2, 126, 76, M, 125, M, M4, M3,
893
/*1d*/M2, 115, 124, M, 75, M, M, M3, 61, M, M4, M, M4, M, M, M,
894
/*1e*/M, 123, 122, M4, 121, M4, M, M3, 117, M2, M2, M3, M4, M3, M, M,
895
/*1f*/111, M, M, M, M4, M3, M3, M, M, M, M3, M, M3, M2, M, M
896
};
897
static unsigned char cheetah_mtag_syntab[] = {
898
       NONE, MTC0,
899
       MTC1, NONE,
900
       MTC2, NONE,
901
       NONE, MT0,
902
       MTC3, NONE,
903
       NONE, MT1,
904
       NONE, MT2,
905
       NONE, NONE
906
};
907
 
908
/* Return the highest priority error conditon mentioned. */
909
static __inline__ unsigned long cheetah_get_hipri(unsigned long afsr)
910
{
911
        unsigned long tmp = 0;
912
        int i;
913
 
914
        for (i = 0; cheetah_error_table[i].mask; i++) {
915
                if ((tmp = (afsr & cheetah_error_table[i].mask)) != 0UL)
916
                        return tmp;
917
        }
918
        return tmp;
919
}
920
 
921
static const char *cheetah_get_string(unsigned long bit)
922
{
923
        int i;
924
 
925
        for (i = 0; cheetah_error_table[i].mask; i++) {
926
                if ((bit & cheetah_error_table[i].mask) != 0UL)
927
                        return cheetah_error_table[i].name;
928
        }
929
        return "???";
930
}
931
 
932
extern int chmc_getunumber(int, unsigned long, char *, int);
933
 
934
static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *info,
935
                               unsigned long afsr, unsigned long afar, int recoverable)
936
{
937
        unsigned long hipri;
938
        char unum[256];
939
 
940
        printk("%s" "ERROR(%d): Cheetah error trap taken afsr[%016lx] afar[%016lx] TL1(%d)\n",
941
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
942
               afsr, afar,
943
               (afsr & CHAFSR_TL1) ? 1 : 0);
944
        printk("%s" "ERROR(%d): TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n",
945
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
946
               regs->tpc, regs->tnpc, regs->tstate);
947
        printk("%s" "ERROR(%d): M_SYND(%lx),  E_SYND(%lx)%s%s\n",
948
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
949
               (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT,
950
               (afsr & CHAFSR_E_SYNDROME) >> CHAFSR_E_SYNDROME_SHIFT,
951
               (afsr & CHAFSR_ME) ? ", Multiple Errors" : "",
952
               (afsr & CHAFSR_PRIV) ? ", Privileged" : "");
953
        hipri = cheetah_get_hipri(afsr);
954
        printk("%s" "ERROR(%d): Highest priority error (%016lx) \"%s\"\n",
955
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
956
               hipri, cheetah_get_string(hipri));
957
 
958
        /* Try to get unumber if relevant. */
959
#define ESYND_ERRORS    (CHAFSR_IVC | CHAFSR_IVU | \
960
                         CHAFSR_CPC | CHAFSR_CPU | \
961
                         CHAFSR_UE  | CHAFSR_CE  | \
962
                         CHAFSR_EDC | CHAFSR_EDU  | \
963
                         CHAFSR_UCC | CHAFSR_UCU  | \
964
                         CHAFSR_WDU | CHAFSR_WDC)
965
#define MSYND_ERRORS    (CHAFSR_EMC | CHAFSR_EMU)
966
        if (afsr & ESYND_ERRORS) {
967
                int syndrome;
968
                int ret;
969
 
970
                syndrome = (afsr & CHAFSR_E_SYNDROME) >> CHAFSR_E_SYNDROME_SHIFT;
971
                syndrome = cheetah_ecc_syntab[syndrome];
972
                ret = chmc_getunumber(syndrome, afar, unum, sizeof(unum));
973
                if (ret != -1)
974
                        printk("%s" "ERROR(%d): AFAR E-syndrome [%s]\n",
975
                               (recoverable ? KERN_WARNING : KERN_CRIT),
976
                               smp_processor_id(), unum);
977
        } else if (afsr & MSYND_ERRORS) {
978
                int syndrome;
979
                int ret;
980
 
981
                syndrome = (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT;
982
                syndrome = cheetah_mtag_syntab[syndrome];
983
                ret = chmc_getunumber(syndrome, afar, unum, sizeof(unum));
984
                if (ret != -1)
985
                        printk("%s" "ERROR(%d): AFAR M-syndrome [%s]\n",
986
                               (recoverable ? KERN_WARNING : KERN_CRIT),
987
                               smp_processor_id(), unum);
988
        }
989
 
990
        /* Now dump the cache snapshots. */
991
        printk("%s" "ERROR(%d): D-cache idx[%x] tag[%016lx] utag[%016lx] stag[%016lx]\n",
992
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
993
               (int) info->dcache_index,
994
               info->dcache_tag,
995
               info->dcache_utag,
996
               info->dcache_stag);
997
        printk("%s" "ERROR(%d): D-cache data0[%016lx] data1[%016lx] data2[%016lx] data3[%016lx]\n",
998
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
999
               info->dcache_data[0],
1000
               info->dcache_data[1],
1001
               info->dcache_data[2],
1002
               info->dcache_data[3]);
1003
        printk("%s" "ERROR(%d): I-cache idx[%x] tag[%016lx] utag[%016lx] stag[%016lx] "
1004
               "u[%016lx] l[%016lx]\n",
1005
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1006
               (int) info->icache_index,
1007
               info->icache_tag,
1008
               info->icache_utag,
1009
               info->icache_stag,
1010
               info->icache_upper,
1011
               info->icache_lower);
1012
        printk("%s" "ERROR(%d): I-cache INSN0[%016lx] INSN1[%016lx] INSN2[%016lx] INSN3[%016lx]\n",
1013
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1014
               info->icache_data[0],
1015
               info->icache_data[1],
1016
               info->icache_data[2],
1017
               info->icache_data[3]);
1018
        printk("%s" "ERROR(%d): I-cache INSN4[%016lx] INSN5[%016lx] INSN6[%016lx] INSN7[%016lx]\n",
1019
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1020
               info->icache_data[4],
1021
               info->icache_data[5],
1022
               info->icache_data[6],
1023
               info->icache_data[7]);
1024
        printk("%s" "ERROR(%d): E-cache idx[%x] tag[%016lx]\n",
1025
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1026
               (int) info->ecache_index, info->ecache_tag);
1027
        printk("%s" "ERROR(%d): E-cache data0[%016lx] data1[%016lx] data2[%016lx] data3[%016lx]\n",
1028
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1029
               info->ecache_data[0],
1030
               info->ecache_data[1],
1031
               info->ecache_data[2],
1032
               info->ecache_data[3]);
1033
 
1034
        afsr = (afsr & ~hipri) & cheetah_afsr_errors;
1035
        while (afsr != 0UL) {
1036
                unsigned long bit = cheetah_get_hipri(afsr);
1037
 
1038
                printk("%s" "ERROR: Multiple-error (%016lx) \"%s\"\n",
1039
                       (recoverable ? KERN_WARNING : KERN_CRIT),
1040
                       bit, cheetah_get_string(bit));
1041
 
1042
                afsr &= ~bit;
1043
        }
1044
 
1045
        if (!recoverable)
1046
                printk(KERN_CRIT "ERROR: This condition is not recoverable.\n");
1047
}
1048
 
1049
static int cheetah_recheck_errors(struct cheetah_err_info *logp)
1050
{
1051
        unsigned long afsr, afar;
1052
        int ret = 0;
1053
 
1054
        __asm__ __volatile__("ldxa [%%g0] %1, %0\n\t"
1055
                             : "=r" (afsr)
1056
                             : "i" (ASI_AFSR));
1057
        if ((afsr & cheetah_afsr_errors) != 0) {
1058
                if (logp != NULL) {
1059
                        __asm__ __volatile__("ldxa [%%g0] %1, %0\n\t"
1060
                                             : "=r" (afar)
1061
                                             : "i" (ASI_AFAR));
1062
                        logp->afsr = afsr;
1063
                        logp->afar = afar;
1064
                }
1065
                ret = 1;
1066
        }
1067
        __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
1068
                             "membar #Sync\n\t"
1069
                             : : "r" (afsr), "i" (ASI_AFSR));
1070
 
1071
        return ret;
1072
}
1073
 
1074
void cheetah_fecc_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar)
1075
{
1076
        struct cheetah_err_info local_snapshot, *p;
1077
        int recoverable;
1078
 
1079
        /* Flush E-cache */
1080
        cheetah_flush_ecache();
1081
 
1082
        p = cheetah_get_error_log(afsr);
1083
        if (!p) {
1084
                prom_printf("ERROR: Early Fast-ECC error afsr[%016lx] afar[%016lx]\n",
1085
                            afsr, afar);
1086
                prom_printf("ERROR: CPU(%d) TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n",
1087
                            smp_processor_id(), regs->tpc, regs->tnpc, regs->tstate);
1088
                prom_halt();
1089
        }
1090
 
1091
        /* Grab snapshot of logged error. */
1092
        memcpy(&local_snapshot, p, sizeof(local_snapshot));
1093
 
1094
        /* If the current trap snapshot does not match what the
1095
         * trap handler passed along into our args, big trouble.
1096
         * In such a case, mark the local copy as invalid.
1097
         *
1098
         * Else, it matches and we mark the afsr in the non-local
1099
         * copy as invalid so we may log new error traps there.
1100
         */
1101
        if (p->afsr != afsr || p->afar != afar)
1102
                local_snapshot.afsr = CHAFSR_INVALID;
1103
        else
1104
                p->afsr = CHAFSR_INVALID;
1105
 
1106
        cheetah_flush_icache();
1107
        cheetah_flush_dcache();
1108
 
1109
        /* Re-enable I-cache/D-cache */
1110
        __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1111
                             "or %%g1, %1, %%g1\n\t"
1112
                             "stxa %%g1, [%%g0] %0\n\t"
1113
                             "membar #Sync"
1114
                             : /* no outputs */
1115
                             : "i" (ASI_DCU_CONTROL_REG),
1116
                               "i" (DCU_DC | DCU_IC)
1117
                             : "g1");
1118
 
1119
        /* Re-enable error reporting */
1120
        __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1121
                             "or %%g1, %1, %%g1\n\t"
1122
                             "stxa %%g1, [%%g0] %0\n\t"
1123
                             "membar #Sync"
1124
                             : /* no outputs */
1125
                             : "i" (ASI_ESTATE_ERROR_EN),
1126
                               "i" (ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN)
1127
                             : "g1");
1128
 
1129
        /* Decide if we can continue after handling this trap and
1130
         * logging the error.
1131
         */
1132
        recoverable = 1;
1133
        if (afsr & (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP))
1134
                recoverable = 0;
1135
 
1136
        /* Re-check AFSR/AFAR.  What we are looking for here is whether a new
1137
         * error was logged while we had error reporting traps disabled.
1138
         */
1139
        if (cheetah_recheck_errors(&local_snapshot)) {
1140
                unsigned long new_afsr = local_snapshot.afsr;
1141
 
1142
                /* If we got a new asynchronous error, die... */
1143
                if (new_afsr & (CHAFSR_EMU | CHAFSR_EDU |
1144
                                CHAFSR_WDU | CHAFSR_CPU |
1145
                                CHAFSR_IVU | CHAFSR_UE |
1146
                                CHAFSR_BERR | CHAFSR_TO))
1147
                        recoverable = 0;
1148
        }
1149
 
1150
        /* Log errors. */
1151
        cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
1152
 
1153
        if (!recoverable)
1154
                panic("Irrecoverable Fast-ECC error trap.\n");
1155
 
1156
        /* Flush E-cache to kick the error trap handlers out. */
1157
        cheetah_flush_ecache();
1158
}
1159
 
1160
/* Try to fix a correctable error by pushing the line out from
1161
 * the E-cache.  Recheck error reporting registers to see if the
1162
 * problem is intermittent.
1163
 */
1164
static int cheetah_fix_ce(unsigned long physaddr)
1165
{
1166
        unsigned long orig_estate;
1167
        unsigned long alias1, alias2;
1168
        int ret;
1169
 
1170
        /* Make sure correctable error traps are disabled. */
1171
        __asm__ __volatile__("ldxa      [%%g0] %2, %0\n\t"
1172
                             "andn      %0, %1, %%g1\n\t"
1173
                             "stxa      %%g1, [%%g0] %2\n\t"
1174
                             "membar    #Sync"
1175
                             : "=&r" (orig_estate)
1176
                             : "i" (ESTATE_ERROR_CEEN),
1177
                               "i" (ASI_ESTATE_ERROR_EN)
1178
                             : "g1");
1179
 
1180
        /* We calculate alias addresses that will force the
1181
         * cache line in question out of the E-cache.  Then
1182
         * we bring it back in with an atomic instruction so
1183
         * that we get it in some modified/exclusive state,
1184
         * then we displace it again to try and get proper ECC
1185
         * pushed back into the system.
1186
         */
1187
        physaddr &= ~(8UL - 1UL);
1188
        alias1 = (ecache_flush_physbase +
1189
                  (physaddr & ((ecache_flush_size >> 1) - 1)));
1190
        alias2 = alias1 + (ecache_flush_size >> 1);
1191
        __asm__ __volatile__("ldxa      [%0] %3, %%g0\n\t"
1192
                             "ldxa      [%1] %3, %%g0\n\t"
1193
                             "casxa     [%2] %3, %%g0, %%g0\n\t"
1194
                             "membar    #StoreLoad | #StoreStore\n\t"
1195
                             "ldxa      [%0] %3, %%g0\n\t"
1196
                             "ldxa      [%1] %3, %%g0\n\t"
1197
                             "membar    #Sync"
1198
                             : /* no outputs */
1199
                             : "r" (alias1), "r" (alias2),
1200
                               "r" (physaddr), "i" (ASI_PHYS_USE_EC));
1201
 
1202
        /* Did that trigger another error? */
1203
        if (cheetah_recheck_errors(NULL)) {
1204
                /* Try one more time. */
1205
                __asm__ __volatile__("ldxa [%0] %1, %%g0\n\t"
1206
                                     "membar #Sync"
1207
                                     : : "r" (physaddr), "i" (ASI_PHYS_USE_EC));
1208
                if (cheetah_recheck_errors(NULL))
1209
                        ret = 2;
1210
                else
1211
                        ret = 1;
1212
        } else {
1213
                /* No new error, intermittent problem. */
1214
                ret = 0;
1215
        }
1216
 
1217
        /* Restore error enables. */
1218
        __asm__ __volatile__("stxa      %0, [%%g0] %1\n\t"
1219
                             "membar    #Sync"
1220
                             : : "r" (orig_estate), "i" (ASI_ESTATE_ERROR_EN));
1221
 
1222
        return ret;
1223
}
1224
 
1225
/* Return non-zero if PADDR is a valid physical memory address. */
1226
static int cheetah_check_main_memory(unsigned long paddr)
1227
{
1228
        int i;
1229
 
1230
        for (i = 0; ; i++) {
1231
                if (sp_banks[i].num_bytes == 0)
1232
                        break;
1233
                if (paddr >= sp_banks[i].base_addr &&
1234
                    paddr < (sp_banks[i].base_addr + sp_banks[i].num_bytes))
1235
                        return 1;
1236
        }
1237
        return 0;
1238
}
1239
 
1240
void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar)
1241
{
1242
        struct cheetah_err_info local_snapshot, *p;
1243
        int recoverable, is_memory;
1244
 
1245
        p = cheetah_get_error_log(afsr);
1246
        if (!p) {
1247
                prom_printf("ERROR: Early CEE error afsr[%016lx] afar[%016lx]\n",
1248
                            afsr, afar);
1249
                prom_printf("ERROR: CPU(%d) TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n",
1250
                            smp_processor_id(), regs->tpc, regs->tnpc, regs->tstate);
1251
                prom_halt();
1252
        }
1253
 
1254
        /* Grab snapshot of logged error. */
1255
        memcpy(&local_snapshot, p, sizeof(local_snapshot));
1256
 
1257
        /* If the current trap snapshot does not match what the
1258
         * trap handler passed along into our args, big trouble.
1259
         * In such a case, mark the local copy as invalid.
1260
         *
1261
         * Else, it matches and we mark the afsr in the non-local
1262
         * copy as invalid so we may log new error traps there.
1263
         */
1264
        if (p->afsr != afsr || p->afar != afar)
1265
                local_snapshot.afsr = CHAFSR_INVALID;
1266
        else
1267
                p->afsr = CHAFSR_INVALID;
1268
 
1269
        is_memory = cheetah_check_main_memory(afar);
1270
 
1271
        if (is_memory && (afsr & CHAFSR_CE) != 0UL) {
1272
                /* XXX Might want to log the results of this operation
1273
                 * XXX somewhere... -DaveM
1274
                 */
1275
                cheetah_fix_ce(afar);
1276
        }
1277
 
1278
        {
1279
                int flush_all, flush_line;
1280
 
1281
                flush_all = flush_line = 0;
1282
                if ((afsr & CHAFSR_EDC) != 0UL) {
1283
                        if ((afsr & cheetah_afsr_errors) == CHAFSR_EDC)
1284
                                flush_line = 1;
1285
                        else
1286
                                flush_all = 1;
1287
                } else if ((afsr & CHAFSR_CPC) != 0UL) {
1288
                        if ((afsr & cheetah_afsr_errors) == CHAFSR_CPC)
1289
                                flush_line = 1;
1290
                        else
1291
                                flush_all = 1;
1292
                }
1293
 
1294
                /* Trap handler only disabled I-cache, flush it. */
1295
                cheetah_flush_icache();
1296
 
1297
                /* Re-enable I-cache */
1298
                __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1299
                                     "or %%g1, %1, %%g1\n\t"
1300
                                     "stxa %%g1, [%%g0] %0\n\t"
1301
                                     "membar #Sync"
1302
                                     : /* no outputs */
1303
                                     : "i" (ASI_DCU_CONTROL_REG),
1304
                                     "i" (DCU_IC)
1305
                                     : "g1");
1306
 
1307
                if (flush_all)
1308
                        cheetah_flush_ecache();
1309
                else if (flush_line)
1310
                        cheetah_flush_ecache_line(afar);
1311
        }
1312
 
1313
        /* Re-enable error reporting */
1314
        __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1315
                             "or %%g1, %1, %%g1\n\t"
1316
                             "stxa %%g1, [%%g0] %0\n\t"
1317
                             "membar #Sync"
1318
                             : /* no outputs */
1319
                             : "i" (ASI_ESTATE_ERROR_EN),
1320
                               "i" (ESTATE_ERROR_CEEN)
1321
                             : "g1");
1322
 
1323
        /* Decide if we can continue after handling this trap and
1324
         * logging the error.
1325
         */
1326
        recoverable = 1;
1327
        if (afsr & (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP))
1328
                recoverable = 0;
1329
 
1330
        /* Re-check AFSR/AFAR */
1331
        (void) cheetah_recheck_errors(&local_snapshot);
1332
 
1333
        /* Log errors. */
1334
        cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
1335
 
1336
        if (!recoverable)
1337
                panic("Irrecoverable Correctable-ECC error trap.\n");
1338
}
1339
 
1340
void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar)
1341
{
1342
        struct cheetah_err_info local_snapshot, *p;
1343
        int recoverable, is_memory;
1344
 
1345
#ifdef CONFIG_PCI
1346
        /* Check for the special PCI poke sequence. */
1347
        if (pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) {
1348
                cheetah_flush_icache();
1349
                cheetah_flush_dcache();
1350
 
1351
                /* Re-enable I-cache/D-cache */
1352
                __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1353
                                     "or %%g1, %1, %%g1\n\t"
1354
                                     "stxa %%g1, [%%g0] %0\n\t"
1355
                                     "membar #Sync"
1356
                                     : /* no outputs */
1357
                                     : "i" (ASI_DCU_CONTROL_REG),
1358
                                       "i" (DCU_DC | DCU_IC)
1359
                                     : "g1");
1360
 
1361
                /* Re-enable error reporting */
1362
                __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1363
                                     "or %%g1, %1, %%g1\n\t"
1364
                                     "stxa %%g1, [%%g0] %0\n\t"
1365
                                     "membar #Sync"
1366
                                     : /* no outputs */
1367
                                     : "i" (ASI_ESTATE_ERROR_EN),
1368
                                       "i" (ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN)
1369
                                     : "g1");
1370
 
1371
                (void) cheetah_recheck_errors(NULL);
1372
 
1373
                pci_poke_faulted = 1;
1374
                regs->tpc += 4;
1375
                regs->tnpc = regs->tpc + 4;
1376
                return;
1377
        }
1378
#endif
1379
 
1380
        p = cheetah_get_error_log(afsr);
1381
        if (!p) {
1382
                prom_printf("ERROR: Early deferred error afsr[%016lx] afar[%016lx]\n",
1383
                            afsr, afar);
1384
                prom_printf("ERROR: CPU(%d) TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n",
1385
                            smp_processor_id(), regs->tpc, regs->tnpc, regs->tstate);
1386
                prom_halt();
1387
        }
1388
 
1389
        /* Grab snapshot of logged error. */
1390
        memcpy(&local_snapshot, p, sizeof(local_snapshot));
1391
 
1392
        /* If the current trap snapshot does not match what the
1393
         * trap handler passed along into our args, big trouble.
1394
         * In such a case, mark the local copy as invalid.
1395
         *
1396
         * Else, it matches and we mark the afsr in the non-local
1397
         * copy as invalid so we may log new error traps there.
1398
         */
1399
        if (p->afsr != afsr || p->afar != afar)
1400
                local_snapshot.afsr = CHAFSR_INVALID;
1401
        else
1402
                p->afsr = CHAFSR_INVALID;
1403
 
1404
        is_memory = cheetah_check_main_memory(afar);
1405
 
1406
        {
1407
                int flush_all, flush_line;
1408
 
1409
                flush_all = flush_line = 0;
1410
                if ((afsr & CHAFSR_EDU) != 0UL) {
1411
                        if ((afsr & cheetah_afsr_errors) == CHAFSR_EDU)
1412
                                flush_line = 1;
1413
                        else
1414
                                flush_all = 1;
1415
                } else if ((afsr & CHAFSR_BERR) != 0UL) {
1416
                        if ((afsr & cheetah_afsr_errors) == CHAFSR_BERR)
1417
                                flush_line = 1;
1418
                        else
1419
                                flush_all = 1;
1420
                }
1421
 
1422
                cheetah_flush_icache();
1423
                cheetah_flush_dcache();
1424
 
1425
                /* Re-enable I/D caches */
1426
                __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1427
                                     "or %%g1, %1, %%g1\n\t"
1428
                                     "stxa %%g1, [%%g0] %0\n\t"
1429
                                     "membar #Sync"
1430
                                     : /* no outputs */
1431
                                     : "i" (ASI_DCU_CONTROL_REG),
1432
                                     "i" (DCU_IC | DCU_DC)
1433
                                     : "g1");
1434
 
1435
                if (flush_all)
1436
                        cheetah_flush_ecache();
1437
                else if (flush_line)
1438
                        cheetah_flush_ecache_line(afar);
1439
        }
1440
 
1441
        /* Re-enable error reporting */
1442
        __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1443
                             "or %%g1, %1, %%g1\n\t"
1444
                             "stxa %%g1, [%%g0] %0\n\t"
1445
                             "membar #Sync"
1446
                             : /* no outputs */
1447
                             : "i" (ASI_ESTATE_ERROR_EN),
1448
                             "i" (ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN)
1449
                             : "g1");
1450
 
1451
        /* Decide if we can continue after handling this trap and
1452
         * logging the error.
1453
         */
1454
        recoverable = 1;
1455
        if (afsr & (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP))
1456
                recoverable = 0;
1457
 
1458
        /* Re-check AFSR/AFAR.  What we are looking for here is whether a new
1459
         * error was logged while we had error reporting traps disabled.
1460
         */
1461
        if (cheetah_recheck_errors(&local_snapshot)) {
1462
                unsigned long new_afsr = local_snapshot.afsr;
1463
 
1464
                /* If we got a new asynchronous error, die... */
1465
                if (new_afsr & (CHAFSR_EMU | CHAFSR_EDU |
1466
                                CHAFSR_WDU | CHAFSR_CPU |
1467
                                CHAFSR_IVU | CHAFSR_UE |
1468
                                CHAFSR_BERR | CHAFSR_TO))
1469
                        recoverable = 0;
1470
        }
1471
 
1472
        /* Log errors. */
1473
        cheetah_log_errors(regs, &local_snapshot, afsr, afar, recoverable);
1474
 
1475
        /* "Recoverable" here means we try to yank the page from ever
1476
         * being newly used again.  This depends upon a few things:
1477
         * 1) Must be main memory, and AFAR must be valid.
1478
         * 2) If we trapped from use, OK.
1479
         * 3) Else, if we trapped from kernel we must find exception
1480
         *    table entry (ie. we have to have been accessing user
1481
         *    space).
1482
         *
1483
         * If AFAR is not in main memory, or we trapped from kernel
1484
         * and cannot find an exception table entry, it is unacceptable
1485
         * to try and continue.
1486
         */
1487
        if (recoverable && is_memory) {
1488
                if ((regs->tstate & TSTATE_PRIV) == 0UL) {
1489
                        /* OK, usermode access. */
1490
                        recoverable = 1;
1491
                } else {
1492
                        unsigned long g2 = regs->u_regs[UREG_G2];
1493
                        unsigned long fixup = search_exception_table(regs->tpc, &g2);
1494
 
1495
                        if (fixup != 0UL) {
1496
                                /* OK, kernel access to userspace. */
1497
                                recoverable = 1;
1498
 
1499
                        } else {
1500
                                /* BAD, privileged state is corrupted. */
1501
                                recoverable = 0;
1502
                        }
1503
 
1504
                        if (recoverable) {
1505
                                struct page *page = virt_to_page(__va(afar));
1506
 
1507
                                if (VALID_PAGE(page))
1508
                                        get_page(page);
1509
                                else
1510
                                        recoverable = 0;
1511
 
1512
                                /* Only perform fixup if we still have a
1513
                                 * recoverable condition.
1514
                                 */
1515
                                if (fixup != 0UL && recoverable) {
1516
                                        regs->tpc = fixup;
1517
                                        regs->tnpc = regs->tpc + 4;
1518
                                        regs->u_regs[UREG_G2] = g2;
1519
                                }
1520
                        }
1521
                }
1522
        } else {
1523
                recoverable = 0;
1524
        }
1525
 
1526
        if (!recoverable)
1527
                panic("Irrecoverable deferred error trap.\n");
1528
}
1529
 
1530
/* Handle a D/I cache parity error trap.  TYPE is encoded as:
1531
 *
1532
 * Bit0:        0=dcache,1=icache
1533
 * Bit1:        0=recoverable,1=unrecoverable
1534
 *
1535
 * The hardware has disabled both the I-cache and D-cache in
1536
 * the %dcr register.
1537
 */
1538
void cheetah_plus_parity_error(int type, struct pt_regs *regs)
1539
{
1540
        if (type & 0x1)
1541
                __cheetah_flush_icache();
1542
        else
1543
                cheetah_plus_zap_dcache_parity();
1544
        cheetah_flush_dcache();
1545
 
1546
        /* Re-enable I-cache/D-cache */
1547
        __asm__ __volatile__("ldxa [%%g0] %0, %%g1\n\t"
1548
                             "or %%g1, %1, %%g1\n\t"
1549
                             "stxa %%g1, [%%g0] %0\n\t"
1550
                             "membar #Sync"
1551
                             : /* no outputs */
1552
                             : "i" (ASI_DCU_CONTROL_REG),
1553
                               "i" (DCU_DC | DCU_IC)
1554
                             : "g1");
1555
 
1556
        if (type & 0x2) {
1557
                printk(KERN_EMERG "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n",
1558
                       smp_processor_id(),
1559
                       (type & 0x1) ? 'I' : 'D',
1560
                       regs->tpc);
1561
                panic("Irrecoverable Cheetah+ parity error.");
1562
        }
1563
 
1564
        printk(KERN_WARNING "CPU[%d]: Cheetah+ %c-cache parity error at TPC[%016lx]\n",
1565
               smp_processor_id(),
1566
               (type & 0x1) ? 'I' : 'D',
1567
               regs->tpc);
1568
}
1569
 
1570
void do_fpe_common(struct pt_regs *regs)
1571
{
1572
        if(regs->tstate & TSTATE_PRIV) {
1573
                regs->tpc = regs->tnpc;
1574
                regs->tnpc += 4;
1575
        } else {
1576
                unsigned long fsr = current->thread.xfsr[0];
1577
                siginfo_t info;
1578
 
1579
                if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1580
                        regs->tpc &= 0xffffffff;
1581
                        regs->tnpc &= 0xffffffff;
1582
                }
1583
                info.si_signo = SIGFPE;
1584
                info.si_errno = 0;
1585
                info.si_addr = (void *)regs->tpc;
1586
                info.si_trapno = 0;
1587
                info.si_code = __SI_FAULT;
1588
                if ((fsr & 0x1c000) == (1 << 14)) {
1589
                        if (fsr & 0x10)
1590
                                info.si_code = FPE_FLTINV;
1591
                        else if (fsr & 0x08)
1592
                                info.si_code = FPE_FLTOVF;
1593
                        else if (fsr & 0x04)
1594
                                info.si_code = FPE_FLTUND;
1595
                        else if (fsr & 0x02)
1596
                                info.si_code = FPE_FLTDIV;
1597
                        else if (fsr & 0x01)
1598
                                info.si_code = FPE_FLTRES;
1599
                }
1600
                force_sig_info(SIGFPE, &info, current);
1601
        }
1602
}
1603
 
1604
void do_fpieee(struct pt_regs *regs)
1605
{
1606
        do_fpe_common(regs);
1607
}
1608
 
1609
extern int do_mathemu(struct pt_regs *, struct fpustate *);
1610
 
1611
void do_fpother(struct pt_regs *regs)
1612
{
1613
        struct fpustate *f = FPUSTATE;
1614
        int ret = 0;
1615
 
1616
        switch ((current->thread.xfsr[0] & 0x1c000)) {
1617
        case (2 << 14): /* unfinished_FPop */
1618
        case (3 << 14): /* unimplemented_FPop */
1619
                ret = do_mathemu(regs, f);
1620
                break;
1621
        }
1622
        if (ret)
1623
                return;
1624
        do_fpe_common(regs);
1625
}
1626
 
1627
void do_tof(struct pt_regs *regs)
1628
{
1629
        siginfo_t info;
1630
 
1631
        if(regs->tstate & TSTATE_PRIV)
1632
                die_if_kernel("Penguin overflow trap from kernel mode", regs);
1633
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1634
                regs->tpc &= 0xffffffff;
1635
                regs->tnpc &= 0xffffffff;
1636
        }
1637
        info.si_signo = SIGEMT;
1638
        info.si_errno = 0;
1639
        info.si_code = EMT_TAGOVF;
1640
        info.si_addr = (void *)regs->tpc;
1641
        info.si_trapno = 0;
1642
        force_sig_info(SIGEMT, &info, current);
1643
}
1644
 
1645
void do_div0(struct pt_regs *regs)
1646
{
1647
        siginfo_t info;
1648
 
1649
        if (regs->tstate & TSTATE_PRIV)
1650
                die_if_kernel("TL0: Kernel divide by zero.", regs);
1651
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1652
                regs->tpc &= 0xffffffff;
1653
                regs->tnpc &= 0xffffffff;
1654
        }
1655
        info.si_signo = SIGFPE;
1656
        info.si_errno = 0;
1657
        info.si_code = FPE_INTDIV;
1658
        info.si_addr = (void *)regs->tpc;
1659
        info.si_trapno = 0;
1660
        force_sig_info(SIGFPE, &info, current);
1661
}
1662
 
1663
void instruction_dump (unsigned int *pc)
1664
{
1665
        int i;
1666
 
1667
        if((((unsigned long) pc) & 3))
1668
                return;
1669
 
1670
        printk("Instruction DUMP:");
1671
        for(i = -3; i < 6; i++)
1672
                printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>');
1673
        printk("\n");
1674
}
1675
 
1676
void user_instruction_dump (unsigned int *pc)
1677
{
1678
        int i;
1679
        unsigned int buf[9];
1680
 
1681
        if((((unsigned long) pc) & 3))
1682
                return;
1683
 
1684
        if(copy_from_user(buf, pc - 3, sizeof(buf)))
1685
                return;
1686
 
1687
        printk("Instruction DUMP:");
1688
        for(i = 0; i < 9; i++)
1689
                printk("%c%08x%c",i==3?' ':'<',buf[i],i==3?' ':'>');
1690
        printk("\n");
1691
}
1692
 
1693
void show_trace_raw(struct task_struct *tsk, unsigned long ksp)
1694
{
1695
        unsigned long pc, fp;
1696
        unsigned long task_base = (unsigned long)tsk;
1697
        struct reg_window *rw;
1698
        int count = 0;
1699
 
1700
        if (tsk == current)
1701
                flushw_all();
1702
 
1703
        fp = ksp + STACK_BIAS;
1704
        do {
1705
                /* Bogus frame pointer? */
1706
                if (fp < (task_base + sizeof(struct task_struct)) ||
1707
                    fp >= (task_base + THREAD_SIZE))
1708
                        break;
1709
                rw = (struct reg_window *)fp;
1710
                pc = rw->ins[7];
1711
                printk("[%016lx] ", pc);
1712
                fp = rw->ins[6] + STACK_BIAS;
1713
        } while (++count < 16);
1714
        printk("\n");
1715
}
1716
 
1717
void show_trace_task(struct task_struct *tsk)
1718
{
1719
        if (tsk)
1720
                show_trace_raw(tsk, tsk->thread.ksp);
1721
}
1722
 
1723
void dump_stack(void)
1724
{
1725
        unsigned long ksp;
1726
 
1727
        __asm__ __volatile__("mov       %%fp, %0"
1728
                             : "=r" (ksp));
1729
        show_trace_raw(current, ksp);
1730
}
1731
 
1732
void die_if_kernel(char *str, struct pt_regs *regs)
1733
{
1734
        extern void __show_regs(struct pt_regs * regs);
1735
        extern void smp_report_regs(void);
1736
        int count = 0;
1737
        struct reg_window *lastrw;
1738
 
1739
        /* Amuse the user. */
1740
        printk(
1741
"              \\|/ ____ \\|/\n"
1742
"              \"@'/ .. \\`@\"\n"
1743
"              /_| \\__/ |_\\\n"
1744
"                 \\__U_/\n");
1745
 
1746
        printk("%s(%d): %s\n", current->comm, current->pid, str);
1747
        __asm__ __volatile__("flushw");
1748
        __show_regs(regs);
1749
        if(regs->tstate & TSTATE_PRIV) {
1750
                struct reg_window *rw = (struct reg_window *)
1751
                        (regs->u_regs[UREG_FP] + STACK_BIAS);
1752
 
1753
                /* Stop the back trace when we hit userland or we
1754
                 * find some badly aligned kernel stack.
1755
                 */
1756
                lastrw = (struct reg_window *)current;
1757
                while(rw                                        &&
1758
                      count++ < 30                              &&
1759
                      rw >= lastrw                              &&
1760
                      (char *) rw < ((char *) current)
1761
                        + sizeof (union task_union)             &&
1762
                      !(((unsigned long) rw) & 0x7)) {
1763
                        printk("Caller[%016lx]\n", rw->ins[7]);
1764
                        lastrw = rw;
1765
                        rw = (struct reg_window *)
1766
                                (rw->ins[6] + STACK_BIAS);
1767
                }
1768
                instruction_dump ((unsigned int *) regs->tpc);
1769
        } else {
1770
                if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1771
                        regs->tpc &= 0xffffffff;
1772
                        regs->tnpc &= 0xffffffff;
1773
                }
1774
                user_instruction_dump ((unsigned int *) regs->tpc);
1775
        }
1776
#ifdef CONFIG_SMP
1777
        smp_report_regs();
1778
#endif
1779
 
1780
        if(regs->tstate & TSTATE_PRIV)
1781
                do_exit(SIGKILL);
1782
        do_exit(SIGSEGV);
1783
}
1784
 
1785
extern int handle_popc(u32 insn, struct pt_regs *regs);
1786
extern int handle_ldf_stq(u32 insn, struct pt_regs *regs);
1787
 
1788
void do_illegal_instruction(struct pt_regs *regs)
1789
{
1790
        unsigned long pc = regs->tpc;
1791
        unsigned long tstate = regs->tstate;
1792
        u32 insn;
1793
        siginfo_t info;
1794
 
1795
        if(tstate & TSTATE_PRIV)
1796
                die_if_kernel("Kernel illegal instruction", regs);
1797
        if(current->thread.flags & SPARC_FLAG_32BIT)
1798
                pc = (u32)pc;
1799
        if (get_user(insn, (u32 *)pc) != -EFAULT) {
1800
                if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ {
1801
                        if (handle_popc(insn, regs))
1802
                                return;
1803
                } else if ((insn & 0xc1580000) == 0xc1100000) /* LDQ/STQ */ {
1804
                        if (handle_ldf_stq(insn, regs))
1805
                                return;
1806
                }
1807
        }
1808
        info.si_signo = SIGILL;
1809
        info.si_errno = 0;
1810
        info.si_code = ILL_ILLOPC;
1811
        info.si_addr = (void *)pc;
1812
        info.si_trapno = 0;
1813
        force_sig_info(SIGILL, &info, current);
1814
}
1815
 
1816
void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr)
1817
{
1818
        siginfo_t info;
1819
 
1820
        if(regs->tstate & TSTATE_PRIV) {
1821
                extern void kernel_unaligned_trap(struct pt_regs *regs,
1822
                                                  unsigned int insn,
1823
                                                  unsigned long sfar, unsigned long sfsr);
1824
 
1825
                return kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc), sfar, sfsr);
1826
        }
1827
        info.si_signo = SIGBUS;
1828
        info.si_errno = 0;
1829
        info.si_code = BUS_ADRALN;
1830
        info.si_addr = (void *)sfar;
1831
        info.si_trapno = 0;
1832
        force_sig_info(SIGBUS, &info, current);
1833
}
1834
 
1835
void do_privop(struct pt_regs *regs)
1836
{
1837
        siginfo_t info;
1838
 
1839
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1840
                regs->tpc &= 0xffffffff;
1841
                regs->tnpc &= 0xffffffff;
1842
        }
1843
        info.si_signo = SIGILL;
1844
        info.si_errno = 0;
1845
        info.si_code = ILL_PRVOPC;
1846
        info.si_addr = (void *)regs->tpc;
1847
        info.si_trapno = 0;
1848
        force_sig_info(SIGILL, &info, current);
1849
}
1850
 
1851
void do_privact(struct pt_regs *regs)
1852
{
1853
        do_privop(regs);
1854
}
1855
 
1856
/* Trap level 1 stuff or other traps we should never see... */
1857
void do_cee(struct pt_regs *regs)
1858
{
1859
        die_if_kernel("TL0: Cache Error Exception", regs);
1860
}
1861
 
1862
void do_cee_tl1(struct pt_regs *regs)
1863
{
1864
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1865
        die_if_kernel("TL1: Cache Error Exception", regs);
1866
}
1867
 
1868
void do_dae_tl1(struct pt_regs *regs)
1869
{
1870
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1871
        die_if_kernel("TL1: Data Access Exception", regs);
1872
}
1873
 
1874
void do_iae_tl1(struct pt_regs *regs)
1875
{
1876
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1877
        die_if_kernel("TL1: Instruction Access Exception", regs);
1878
}
1879
 
1880
void do_div0_tl1(struct pt_regs *regs)
1881
{
1882
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1883
        die_if_kernel("TL1: DIV0 Exception", regs);
1884
}
1885
 
1886
void do_fpdis_tl1(struct pt_regs *regs)
1887
{
1888
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1889
        die_if_kernel("TL1: FPU Disabled", regs);
1890
}
1891
 
1892
void do_fpieee_tl1(struct pt_regs *regs)
1893
{
1894
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1895
        die_if_kernel("TL1: FPU IEEE Exception", regs);
1896
}
1897
 
1898
void do_fpother_tl1(struct pt_regs *regs)
1899
{
1900
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1901
        die_if_kernel("TL1: FPU Other Exception", regs);
1902
}
1903
 
1904
void do_ill_tl1(struct pt_regs *regs)
1905
{
1906
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1907
        die_if_kernel("TL1: Illegal Instruction Exception", regs);
1908
}
1909
 
1910
void do_irq_tl1(struct pt_regs *regs)
1911
{
1912
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1913
        die_if_kernel("TL1: IRQ Exception", regs);
1914
}
1915
 
1916
void do_lddfmna_tl1(struct pt_regs *regs)
1917
{
1918
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1919
        die_if_kernel("TL1: LDDF Exception", regs);
1920
}
1921
 
1922
void do_stdfmna_tl1(struct pt_regs *regs)
1923
{
1924
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1925
        die_if_kernel("TL1: STDF Exception", regs);
1926
}
1927
 
1928
void do_paw(struct pt_regs *regs)
1929
{
1930
        die_if_kernel("TL0: Phys Watchpoint Exception", regs);
1931
}
1932
 
1933
void do_paw_tl1(struct pt_regs *regs)
1934
{
1935
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1936
        die_if_kernel("TL1: Phys Watchpoint Exception", regs);
1937
}
1938
 
1939
void do_vaw(struct pt_regs *regs)
1940
{
1941
        die_if_kernel("TL0: Virt Watchpoint Exception", regs);
1942
}
1943
 
1944
void do_vaw_tl1(struct pt_regs *regs)
1945
{
1946
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1947
        die_if_kernel("TL1: Virt Watchpoint Exception", regs);
1948
}
1949
 
1950
void do_tof_tl1(struct pt_regs *regs)
1951
{
1952
        dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
1953
        die_if_kernel("TL1: Tag Overflow Exception", regs);
1954
}
1955
 
1956
void do_getpsr(struct pt_regs *regs)
1957
{
1958
        regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate);
1959
        regs->tpc   = regs->tnpc;
1960
        regs->tnpc += 4;
1961
        if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
1962
                regs->tpc &= 0xffffffff;
1963
                regs->tnpc &= 0xffffffff;
1964
        }
1965
}
1966
 
1967
void trap_init(void)
1968
{
1969
        /* Attach to the address space of init_task. */
1970
        atomic_inc(&init_mm.mm_count);
1971
        current->active_mm = &init_mm;
1972
 
1973
        /* NOTE: Other cpus have this done as they are started
1974
         *       up on SMP.
1975
         */
1976
}

powered by: WebSVN 2.1.0

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