also update spec file ...
[linux-flexiantxendom0-3.2.10.git] / arch / mips64 / kernel / traps.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle
7  * Copyright (C) 1995, 1996 Paul M. Antoine
8  * Copyright (C) 1998 Ulf Carlsson
9  * Copyright (C) 1999 Silicon Graphics, Inc.
10  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
11  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
12  * Copyright (C) 2002, 2003  Maciej W. Rozycki
13  */
14 #include <linux/config.h>
15 #include <linux/init.h>
16 #include <linux/mm.h>
17 #include <linux/module.h>
18 #include <linux/sched.h>
19 #include <linux/smp.h>
20 #include <linux/smp_lock.h>
21 #include <linux/spinlock.h>
22 #include <linux/kallsyms.h>
23
24 #include <asm/bootinfo.h>
25 #include <asm/branch.h>
26 #include <asm/cpu.h>
27 #include <asm/fpu.h>
28 #include <asm/module.h>
29 #include <asm/pgtable.h>
30 #include <asm/ptrace.h>
31 #include <asm/sections.h>
32 #include <asm/system.h>
33 #include <asm/tlbdebug.h>
34 #include <asm/traps.h>
35 #include <asm/uaccess.h>
36 #include <asm/mmu_context.h>
37 #include <asm/watch.h>
38 #include <asm/types.h>
39
40 extern asmlinkage void __xtlb_mod(void);
41 extern asmlinkage void __xtlb_tlbl(void);
42 extern asmlinkage void __xtlb_tlbs(void);
43 extern asmlinkage void handle_adel(void);
44 extern asmlinkage void handle_ades(void);
45 extern asmlinkage void handle_ibe(void);
46 extern asmlinkage void handle_dbe(void);
47 extern asmlinkage void handle_sys(void);
48 extern asmlinkage void handle_bp(void);
49 extern asmlinkage void handle_ri(void);
50 extern asmlinkage void handle_cpu(void);
51 extern asmlinkage void handle_ov(void);
52 extern asmlinkage void handle_tr(void);
53 extern asmlinkage void handle_fpe(void);
54 extern asmlinkage void handle_mdmx(void);
55 extern asmlinkage void handle_watch(void);
56 extern asmlinkage void handle_mcheck(void);
57 extern asmlinkage void handle_reserved(void);
58
59 extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
60         struct mips_fpu_soft_struct *ctx);
61
62 void (*board_be_init)(void);
63 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
64
65 /*
66  * These constant is for searching for possible module text segments.
67  * MODULE_RANGE is a guess of how much space is likely to be vmalloced.
68  */
69 #define MODULE_RANGE (8*1024*1024)
70
71 /*
72  * This routine abuses get_user()/put_user() to reference pointers
73  * with at least a bit of error checking ...
74  */
75 void show_stack(struct task_struct *task, unsigned long *sp)
76 {
77         const int field = 2 * sizeof(unsigned long);
78         long stackdata;
79         int i;
80
81         sp = sp ? sp : (unsigned long *) &sp;
82
83         printk("Stack: ");
84         i = 1;
85         while ((unsigned long) sp & (PAGE_SIZE - 1)) {
86                 if (i && ((i % (64 / sizeof(unsigned long))) == 0))
87                         printk("\n       ");
88                 if (i > 40) {
89                         printk(" ...");
90                         break;
91                 }
92
93                 if (__get_user(stackdata, sp++)) {
94                         printk(" (Bad stack address)");
95                         break;
96                 }
97
98                 printk(" %0*lx", field, stackdata);
99                 i++;
100         }
101         printk("\n");
102 }
103
104 void show_trace(struct task_struct *task, unsigned long *stack)
105 {
106         const int field = 2 * sizeof(unsigned long);
107         unsigned long addr;
108
109         if (!stack)
110                 stack = (unsigned long*)&stack;
111
112         printk("Call Trace:");
113 #ifdef CONFIG_KALLSYMS
114         printk("\n");
115 #endif
116         while (((long) stack & (THREAD_SIZE-1)) != 0) {
117                 addr = *stack++;
118                 if (kernel_text_address(addr)) {
119                         printk(" [<%0*lx>] ", field, addr);
120                         print_symbol("%s\n", addr);
121                 }
122         }
123         printk("\n");
124 }
125
126 void show_trace_task(struct task_struct *tsk)
127 {
128         show_trace(tsk, (long *)tsk->thread.reg29);
129 }
130
131 /*
132  * The architecture-independent dump_stack generator
133  */
134 void dump_stack(void)
135 {
136         unsigned long stack;
137
138         show_trace(current, &stack);
139 }
140
141 void show_code(unsigned int *pc)
142 {
143         long i;
144
145         printk("\nCode:");
146
147         for(i = -3 ; i < 6 ; i++) {
148                 unsigned int insn;
149                 if (__get_user(insn, pc + i)) {
150                         printk(" (Bad address in epc)\n");
151                         break;
152                 }
153                 printk("%c%08x%c", (i?' ':'<'), insn, (i?' ':'>'));
154         }
155 }
156
157 void show_regs(struct pt_regs *regs)
158 {
159         const int field = 2 * sizeof(unsigned long);
160         int i;
161
162         printk("Cpu %d\n", smp_processor_id());
163
164         /*
165          * Saved main processor registers
166          */
167         for (i = 0; i < 32; i++) {
168                 if ((i % 4) == 0)
169                         printk("$%2d :", i);
170                 if (i == 0)
171                         printk(" %0*lx", field, 0UL);
172                 else if (i == 26 || i == 27)
173                         printk(" %*s", field, "");
174                 else
175                         printk(" %0*lx", field, regs->regs[i]);
176
177                 i++;
178                 if ((i % 4) == 0)
179                         printk("\n");
180         }
181
182         printk("Hi      : %0*lx\n", field, regs->hi);
183         printk("Lo      : %0*lx\n", field, regs->lo);
184
185         /*
186          * Saved cp0 registers
187          */
188         printk("epc   : %0*lx    %s\n", field, regs->cp0_epc, print_tainted());
189         printk("Status: %0*lx\n", field, regs->cp0_status);
190         printk("Cause : %0*lx\n", field, regs->cp0_cause);
191
192         if (regs->cp0_status & ST0_KX)
193                 printk("KX ");
194         if (regs->cp0_status & ST0_SX)
195                 printk("SX ");
196         if (regs->cp0_status & ST0_UX)
197                 printk("UX ");
198         switch (regs->cp0_status & ST0_KSU) {
199         case KSU_USER:
200                 printk("USER ");
201                 break;
202         case KSU_SUPERVISOR:
203                 printk("SUPERVISOR ");
204                 break;
205         case KSU_KERNEL:
206                 printk("KERNEL ");
207                 break;
208         default:
209                 printk("BAD_MODE ");
210                 break;
211         }
212         if (regs->cp0_status & ST0_ERL)
213                 printk("ERL ");
214         if (regs->cp0_status & ST0_EXL)
215                 printk("EXL ");
216         if (regs->cp0_status & ST0_IE)
217                 printk("IE ");
218 }
219
220 void show_registers(struct pt_regs *regs)
221 {
222         const int field = 2 * sizeof(unsigned long);
223
224         show_regs(regs);
225         printk("Process %s (pid: %d, stackpage=%0*lx)\n",
226                 current->comm, current->pid, field, (unsigned long) current);
227         show_stack(current, (long *) regs->regs[29]);
228         show_trace(current, (long *) regs->regs[29]);
229         show_code((unsigned int *) regs->cp0_epc);
230         printk("\n");
231 }
232
233 static spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
234
235 void __die(const char * str, struct pt_regs * regs, const char * file,
236            const char * func, unsigned long line)
237 {
238         static int die_counter;
239
240         console_verbose();
241         spin_lock_irq(&die_lock);
242         printk("%s", str);
243         if (file && func)
244                 printk(" in %s:%s, line %ld", file, func, line);
245         printk("[#%d]:\n", ++die_counter);
246         show_registers(regs);
247         spin_unlock_irq(&die_lock);
248         do_exit(SIGSEGV);
249 }
250
251 void __die_if_kernel(const char * str, struct pt_regs * regs,
252                      const char * file, const char * func, unsigned long line)
253 {
254         if (!user_mode(regs))
255                 __die(str, regs, file, func, line);
256 }
257
258 extern const struct exception_table_entry __start___dbe_table[];
259 extern const struct exception_table_entry __stop___dbe_table[];
260
261 void __declare_dbe_table(void)
262 {
263         __asm__ __volatile__(
264         ".section\t__dbe_table,\"a\"\n\t"
265         ".previous"
266         );
267 }
268
269 asmlinkage void do_be(struct pt_regs *regs)
270 {
271         const int field = 2 * sizeof(unsigned long);
272         const struct exception_table_entry *fixup = NULL;
273         int data = regs->cp0_cause & 4;
274         int action = MIPS_BE_FATAL;
275
276         /* XXX For now.  Fixme, this searches the wrong table ...  */
277         if (data && !user_mode(regs))
278                 fixup = search_exception_tables(regs->cp0_epc);
279
280         if (fixup)
281                 action = MIPS_BE_FIXUP;
282
283         if (board_be_handler)
284                 action = board_be_handler(regs, fixup != 0);
285
286         switch (action) {
287         case MIPS_BE_DISCARD:
288                 return;
289         case MIPS_BE_FIXUP:
290                 if (fixup) {
291                         regs->cp0_epc = fixup->nextinsn;
292                         return;
293                 }
294                 break;
295         default:
296                 break;
297         }
298
299         /*
300          * Assume it would be too dangerous to continue ...
301          */
302         printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
303                data ? "Data" : "Instruction",
304                field, regs->cp0_epc, field, regs->regs[31]);
305         die_if_kernel("Oops", regs);
306         force_sig(SIGBUS, current);
307 }
308
309 static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
310 {
311         unsigned int *epc;
312
313         epc = (unsigned int *) regs->cp0_epc +
314               ((regs->cp0_cause & CAUSEF_BD) != 0);
315         if (!get_user(*opcode, epc))
316                 return 0;
317
318         force_sig(SIGSEGV, current);
319         return 1;
320 }
321
322 /*
323  * ll/sc emulation
324  */
325
326 #define OPCODE 0xfc000000
327 #define BASE   0x03e00000
328 #define RT     0x001f0000
329 #define OFFSET 0x0000ffff
330 #define LL     0xc0000000
331 #define SC     0xe0000000
332
333 /*
334  * The ll_bit is cleared by r*_switch.S
335  */
336
337 unsigned long ll_bit;
338
339 static struct task_struct *ll_task = NULL;
340
341 static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
342 {
343         unsigned long value, *vaddr;
344         long offset;
345         int signal = 0;
346
347         /*
348          * analyse the ll instruction that just caused a ri exception
349          * and put the referenced address to addr.
350          */
351
352         /* sign extend offset */
353         offset = opcode & OFFSET;
354         offset <<= 16;
355         offset >>= 16;
356
357         vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
358
359         if ((unsigned long)vaddr & 3) {
360                 signal = SIGBUS;
361                 goto sig;
362         }
363         if (get_user(value, vaddr)) {
364                 signal = SIGSEGV;
365                 goto sig;
366         }
367
368         if (ll_task == NULL || ll_task == current) {
369                 ll_bit = 1;
370         } else {
371                 ll_bit = 0;
372         }
373         ll_task = current;
374
375         regs->regs[(opcode & RT) >> 16] = value;
376
377         compute_return_epc(regs);
378         return;
379
380 sig:
381         force_sig(signal, current);
382 }
383
384 static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
385 {
386         unsigned long *vaddr, reg;
387         long offset;
388         int signal = 0;
389
390         /*
391          * analyse the sc instruction that just caused a ri exception
392          * and put the referenced address to addr.
393          */
394
395         /* sign extend offset */
396         offset = opcode & OFFSET;
397         offset <<= 16;
398         offset >>= 16;
399
400         vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset);
401         reg = (opcode & RT) >> 16;
402
403         if ((unsigned long)vaddr & 3) {
404                 signal = SIGBUS;
405                 goto sig;
406         }
407         if (ll_bit == 0 || ll_task != current) {
408                 regs->regs[reg] = 0;
409                 compute_return_epc(regs);
410                 return;
411         }
412
413         if (put_user(regs->regs[reg], vaddr)) {
414                 signal = SIGSEGV;
415                 goto sig;
416         }
417
418         regs->regs[reg] = 1;
419
420         compute_return_epc(regs);
421         return;
422
423 sig:
424         force_sig(signal, current);
425 }
426
427 /*
428  * ll uses the opcode of lwc0 and sc uses the opcode of swc0.  That is both
429  * opcodes are supposed to result in coprocessor unusable exceptions if
430  * executed on ll/sc-less processors.  That's the theory.  In practice a
431  * few processors such as NEC's VR4100 throw reserved instruction exceptions
432  * instead, so we're doing the emulation thing in both exception handlers.
433  */
434 static inline int simulate_llsc(struct pt_regs *regs)
435 {
436         unsigned int opcode;
437
438         if (unlikely(get_insn_opcode(regs, &opcode)))
439                 return -EFAULT;
440
441         if ((opcode & OPCODE) == LL) {
442                 simulate_ll(regs, opcode);
443                 return 0;
444         }
445         if ((opcode & OPCODE) == SC) {
446                 simulate_sc(regs, opcode);
447                 return 0;
448         }
449
450         return -EFAULT;                 /* Strange things going on ... */
451 }
452
453 asmlinkage void do_ov(struct pt_regs *regs)
454 {
455         siginfo_t info;
456
457         info.si_code = FPE_INTOVF;
458         info.si_signo = SIGFPE;
459         info.si_errno = 0;
460         info.si_addr = (void *)regs->cp0_epc;
461         force_sig_info(SIGFPE, &info, current);
462 }
463
464 /*
465  * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
466  */
467 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
468 {
469         if (fcr31 & FPU_CSR_UNI_X) {
470                 int sig;
471
472                 /*
473                  * Unimplemented operation exception.  If we've got the full
474                  * software emulator on-board, let's use it...
475                  *
476                  * Force FPU to dump state into task/thread context.  We're
477                  * moving a lot of data here for what is probably a single
478                  * instruction, but the alternative is to pre-decode the FP
479                  * register operands before invoking the emulator, which seems
480                  * a bit extreme for what should be an infrequent event.
481                  */
482                 save_fp(current);
483
484                 /* Run the emulator */
485                 sig = fpu_emulator_cop1Handler (0, regs,
486                         &current->thread.fpu.soft);
487
488                 /*
489                  * We can't allow the emulated instruction to leave any of
490                  * the cause bit set in $fcr31.
491                  */
492                 current->thread.fpu.soft.sr &= ~FPU_CSR_ALL_X;
493
494                 /* Restore the hardware register state */
495                 restore_fp(current);
496
497                 /* If something went wrong, signal */
498                 if (sig)
499                         force_sig(sig, current);
500
501                 return;
502         }
503
504         force_sig(SIGFPE, current);
505 }
506
507 asmlinkage void do_bp(struct pt_regs *regs)
508 {
509         unsigned int opcode, bcode;
510         siginfo_t info;
511
512         die_if_kernel("Break instruction in kernel code", regs);
513
514         if (get_insn_opcode(regs, &opcode))
515                 return;
516
517         /*
518          * There is the ancient bug in the MIPS assemblers that the break
519          * code starts left to bit 16 instead to bit 6 in the opcode.
520          * Gas is bug-compatible ...
521          */
522         bcode = ((opcode >> 16) & ((1 << 20) - 1));
523
524         /*
525          * (A short test says that IRIX 5.3 sends SIGTRAP for all break
526          * insns, even for break codes that indicate arithmetic failures.
527          * Weird ...)
528          * But should we continue the brokenness???  --macro
529          */
530         switch (bcode) {
531         case 6:
532         case 7:
533                 if (bcode == 7)
534                         info.si_code = FPE_INTDIV;
535                 else
536                         info.si_code = FPE_INTOVF;
537                 info.si_signo = SIGFPE;
538                 info.si_errno = 0;
539                 info.si_addr = (void *)regs->cp0_epc;
540                 force_sig_info(SIGFPE, &info, current);
541                 break;
542         default:
543                 force_sig(SIGTRAP, current);
544         }
545 }
546
547 asmlinkage void do_tr(struct pt_regs *regs)
548 {
549         unsigned int opcode, tcode = 0;
550         siginfo_t info;
551
552         die_if_kernel("Trap instruction in kernel code", regs);
553
554         if (get_insn_opcode(regs, &opcode))
555                 return;
556
557         /* Immediate versions don't provide a code.  */
558         if (!(opcode & OPCODE))
559                 tcode = ((opcode >> 6) & ((1 << 20) - 1));
560
561         /*
562          * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
563          * insns, even for trap codes that indicate arithmetic failures.
564          * Weird ...)
565          * But should we continue the brokenness???  --macro
566          */
567         switch (tcode) {
568         case 6:
569         case 7:
570                 if (tcode == 7)
571                         info.si_code = FPE_INTDIV;
572                 else
573                         info.si_code = FPE_INTOVF;
574                 info.si_signo = SIGFPE;
575                 info.si_errno = 0;
576                 info.si_addr = (void *)regs->cp0_epc;
577                 force_sig_info(SIGFPE, &info, current);
578                 break;
579         default:
580                 force_sig(SIGTRAP, current);
581         }
582 }
583
584 asmlinkage void do_ri(struct pt_regs *regs)
585 {
586         die_if_kernel("Reserved instruction in kernel code", regs);
587
588         if (!cpu_has_llsc)
589                 if (!simulate_llsc(regs))
590                         return;
591
592         force_sig(SIGILL, current);
593 }
594
595 asmlinkage void do_cpu(struct pt_regs *regs)
596 {
597         unsigned int cpid;
598
599         die_if_kernel("do_cpu invoked from kernel context!", regs);
600
601         cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
602
603         switch (cpid) {
604         case 0:
605                 if (cpu_has_llsc)
606                         break;
607
608                 if (!simulate_llsc(regs))
609                         return;
610                 break;
611
612         case 1:
613                 own_fpu();
614                 if (current->used_math) {       /* Using the FPU again.  */
615                         restore_fp(current);
616                 } else {                        /* First time FPU user.  */
617                         init_fpu();
618                         current->used_math = 1;
619                 }
620
621                 if (!cpu_has_fpu) {
622                         int sig = fpu_emulator_cop1Handler(0, regs,
623                                                 &current->thread.fpu.soft);
624                         if (sig)
625                                 force_sig(sig, current);
626                 }
627
628                 return;
629
630         case 2:
631         case 3:
632                 break;
633         }
634
635         force_sig(SIGILL, current);
636 }
637
638 asmlinkage void do_mdmx(struct pt_regs *regs)
639 {
640         force_sig(SIGILL, current);
641 }
642
643 asmlinkage void do_watch(struct pt_regs *regs)
644 {
645         /*
646          * We use the watch exception where available to detect stack
647          * overflows.
648          */
649         dump_tlb_all();
650         show_regs(regs);
651         panic("Caught WATCH exception - probably caused by stack overflow.");
652 }
653
654 asmlinkage void do_mcheck(struct pt_regs *regs)
655 {
656         show_regs(regs);
657         dump_tlb_all();
658         /*
659          * Some chips may have other causes of machine check (e.g. SB1
660          * graduation timer)
661          */
662         panic("Caught Machine Check exception - %scaused by multiple "
663               "matching entries in the TLB.",
664               (regs->cp0_status & ST0_TS) ? "" : "not ");
665 }
666
667 asmlinkage void do_reserved(struct pt_regs *regs)
668 {
669         /*
670          * Game over - no way to handle this if it ever occurs.  Most probably
671          * caused by a new unknown cpu type or after another deadly
672          * hard/software error.
673          */
674         show_regs(regs);
675         panic("Caught reserved exception %ld - should not happen.",
676               (regs->cp0_cause & 0x7f) >> 2);
677 }
678
679 /*
680  * Some MIPS CPUs can enable/disable for cache parity detection, but do
681  * it different ways.
682  */
683 static inline void parity_protection_init(void)
684 {
685         switch (current_cpu_data.cputype) {
686         case CPU_5KC:
687                 /* Set the PE bit (bit 31) in the c0_ecc register. */
688                 printk(KERN_INFO "Enable the cache parity protection for "
689                        "MIPS 5KC CPUs.\n");
690                 write_c0_ecc(read_c0_ecc() | 0x80000000);
691                 break;
692         default:
693                 break;
694         }
695 }
696
697 asmlinkage void cache_parity_error(void)
698 {
699         const int field = 2 * sizeof(unsigned long);
700         unsigned int reg_val;
701
702         /* For the moment, report the problem and hang. */
703         printk("Cache error exception:\n");
704         printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
705         reg_val = read_c0_cacheerr();
706         printk("c0_cacheerr == %08x\n", reg_val);
707
708         printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
709                reg_val & (1<<30) ? "secondary" : "primary",
710                reg_val & (1<<31) ? "data" : "insn");
711         printk("Error bits: %s%s%s%s%s%s%s\n",
712                reg_val & (1<<29) ? "ED " : "",
713                reg_val & (1<<28) ? "ET " : "",
714                reg_val & (1<<26) ? "EE " : "",
715                reg_val & (1<<25) ? "EB " : "",
716                reg_val & (1<<24) ? "EI " : "",
717                reg_val & (1<<23) ? "E1 " : "",
718                reg_val & (1<<22) ? "E0 " : "");
719         printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
720
721 #if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64)
722         if (reg_val & (1<<22))
723                 printk("DErrAddr0: 0x%08x\n", read_c0_derraddr0());
724
725         if (reg_val & (1<<23))
726                 printk("DErrAddr1: 0x%08x\n", read_c0_derraddr1());
727 #endif
728
729         panic("Can't handle the cache error!");
730 }
731
732 /*
733  * SDBBP EJTAG debug exception handler.
734  * We skip the instruction and return to the next instruction.
735  */
736 void ejtag_exception_handler(struct pt_regs *regs)
737 {
738         const int field = 2 * sizeof(unsigned long);
739         unsigned long depc, old_epc;
740         unsigned int debug;
741
742         printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
743         depc = read_c0_depc();
744         debug = read_c0_debug();
745         printk("c0_depc = %0*lx, DEBUG = %08x\n", field, depc, debug);
746         if (debug & 0x80000000) {
747                 /*
748                  * In branch delay slot.
749                  * We cheat a little bit here and use EPC to calculate the
750                  * debug return address (DEPC). EPC is restored after the
751                  * calculation.
752                  */
753                 old_epc = regs->cp0_epc;
754                 regs->cp0_epc = depc;
755                 __compute_return_epc(regs);
756                 depc = regs->cp0_epc;
757                 regs->cp0_epc = old_epc;
758         } else
759                 depc += 4;
760         write_c0_depc(depc);
761
762 #if 0
763         printk("\n\n----- Enable EJTAG single stepping ----\n\n");
764         write_c0_debug(debug | 0x100);
765 #endif
766 }
767
768 /*
769  * NMI exception handler.
770  */
771 void nmi_exception_handler(struct pt_regs *regs)
772 {
773         printk("NMI taken!!!!\n");
774         die("NMI", regs);
775         while(1) ;
776 }
777
778 unsigned long exception_handlers[32];
779
780 /*
781  * As a side effect of the way this is implemented we're limited
782  * to interrupt handlers in the address range from
783  * KSEG0 <= x < KSEG0 + 256mb on the Nevada.  Oh well ...
784  */
785 void *set_except_vector(int n, void *addr)
786 {
787         unsigned long handler = (unsigned long) addr;
788         unsigned long old_handler = exception_handlers[n];
789
790         exception_handlers[n] = handler;
791         if (n == 0 && cpu_has_divec) {
792                 *(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
793                                                  (0x03ffffff & (handler >> 2));
794                 flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
795         }
796         return (void *)old_handler;
797 }
798
799 asmlinkage int (*save_fp_context)(struct sigcontext *sc);
800 asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
801
802 extern asmlinkage int _save_fp_context(struct sigcontext *sc);
803 extern asmlinkage int _restore_fp_context(struct sigcontext *sc);
804
805 extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc);
806 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc);
807
808 void __init per_cpu_trap_init(void)
809 {
810         unsigned int cpu = smp_processor_id();
811
812         /* Some firmware leaves the BEV flag set, clear it.  */
813         clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV);
814         set_c0_status(ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX);
815
816         /*
817          * Some MIPS CPUs have a dedicated interrupt vector which reduces the
818          * interrupt processing overhead.  Use it where available.
819          */
820         if (cpu_has_divec)
821                 set_c0_cause(CAUSEF_IV);
822
823         cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
824         write_c0_context(((long)(&pgd_current[cpu])) << 23);
825         write_c0_wired(0);
826 }
827
828 void __init trap_init(void)
829 {
830         extern char except_vec0_generic;
831         extern char except_vec3_generic, except_vec3_r4000;
832         extern char except_vec_ejtag_debug;
833         extern char except_vec4;
834         unsigned long i;
835
836         per_cpu_trap_init();
837
838         /* Copy the generic exception handlers to their final destination. */
839         memcpy((void *) KSEG0         , &except_vec0_generic, 0x80);
840         memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
841
842         /*
843          * Setup default vectors
844          */
845         for (i = 0; i <= 31; i++)
846                 set_except_vector(i, handle_reserved);
847
848         /*
849          * Copy the EJTAG debug exception vector handler code to it's final
850          * destination.
851          */
852         if (cpu_has_ejtag)
853                 memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
854
855         /*
856          * Only some CPUs have the watch exceptions or a dedicated
857          * interrupt vector.
858          */
859         if (cpu_has_watch)
860                 set_except_vector(23, handle_watch);
861
862         /*
863          * Some MIPS CPUs have a dedicated interrupt vector which reduces the
864          * interrupt processing overhead.  Use it where available.
865          */
866         if (cpu_has_divec)
867                 memcpy((void *)(KSEG0 + 0x200), &except_vec4, 0x8);
868
869         /*
870          * Some CPUs can enable/disable for cache parity detection, but does
871          * it different ways.
872          */
873         parity_protection_init();
874
875         /*
876          * The Data Bus Errors / Instruction Bus Errors are signaled
877          * by external hardware.  Therefore these two exceptions
878          * may have board specific handlers.
879          */
880         if (board_be_init)
881                 board_be_init();
882
883         set_except_vector(1, __xtlb_mod);
884         set_except_vector(2, __xtlb_tlbl);
885         set_except_vector(3, __xtlb_tlbs);
886         set_except_vector(4, handle_adel);
887         set_except_vector(5, handle_ades);
888
889         set_except_vector(6, handle_ibe);
890         set_except_vector(7, handle_dbe);
891
892         set_except_vector(8, handle_sys);
893         set_except_vector(9, handle_bp);
894         set_except_vector(10, handle_ri);
895         set_except_vector(11, handle_cpu);
896         set_except_vector(12, handle_ov);
897         set_except_vector(13, handle_tr);
898         set_except_vector(22, handle_mdmx);
899
900         if (cpu_has_fpu && !cpu_has_nofpuex)
901                 set_except_vector(15, handle_fpe);
902
903         if (cpu_has_mcheck)
904                 set_except_vector(24, handle_mcheck);
905
906         if (cpu_has_vce)
907                 memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x100);
908         else if (cpu_has_4kex)
909                 memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
910         else
911                 memcpy((void *)(KSEG0 + 0x080), &except_vec3_generic, 0x80);
912
913         if (current_cpu_data.cputype == CPU_R6000 ||
914             current_cpu_data.cputype == CPU_R6000A) {
915                 /*
916                  * The R6000 is the only R-series CPU that features a machine
917                  * check exception (similar to the R4000 cache error) and
918                  * unaligned ldc1/sdc1 exception.  The handlers have not been
919                  * written yet.  Well, anyway there is no R6000 machine on the
920                  * current list of targets for Linux/MIPS.
921                  * (Duh, crap, there is someone with a tripple R6k machine)
922                  */
923                 //set_except_vector(14, handle_mc);
924                 //set_except_vector(15, handle_ndc);
925         }
926
927         if (cpu_has_fpu) {
928                 save_fp_context = _save_fp_context;
929                 restore_fp_context = _restore_fp_context;
930         } else {
931                 save_fp_context = fpu_emulator_save_context;
932                 restore_fp_context = fpu_emulator_restore_context;
933         }
934
935         flush_icache_range(KSEG0, KSEG0 + 0x400);
936
937         if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
938                 set_c0_status(ST0_XX);
939
940         atomic_inc(&init_mm.mm_count);  /* XXX UP?  */
941         current->active_mm = &init_mm;
942 }