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