File: /usr/src/linux/arch/mips/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 * Modified for R3000 by Paul M. Antoine, 1995, 1996
8 * Complete output from die() by Ulf Carlsson, 1998
9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 *
11 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
12 * Copyright (C) 2000, 01 MIPS Technologies, Inc.
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
23 #include <asm/bootinfo.h>
24 #include <asm/branch.h>
25 #include <asm/cpu.h>
26 #include <asm/cachectl.h>
27 #include <asm/inst.h>
28 #include <asm/jazz.h>
29 #include <asm/module.h>
30 #include <asm/pgtable.h>
31 #include <asm/io.h>
32 #include <asm/siginfo.h>
33 #include <asm/watch.h>
34 #include <asm/system.h>
35 #include <asm/uaccess.h>
36 #include <asm/mmu_context.h>
37
38 /*
39 * Machine specific interrupt handlers
40 */
41 extern asmlinkage void acer_pica_61_handle_int(void);
42 extern asmlinkage void decstation_handle_int(void);
43 extern asmlinkage void deskstation_rpc44_handle_int(void);
44 extern asmlinkage void deskstation_tyne_handle_int(void);
45 extern asmlinkage void mips_magnum_4000_handle_int(void);
46
47 extern asmlinkage void handle_mod(void);
48 extern asmlinkage void handle_tlbl(void);
49 extern asmlinkage void handle_tlbs(void);
50 extern asmlinkage void handle_adel(void);
51 extern asmlinkage void handle_ades(void);
52 extern asmlinkage void handle_ibe(void);
53 extern asmlinkage void handle_dbe(void);
54 extern asmlinkage void handle_sys(void);
55 extern asmlinkage void handle_bp(void);
56 extern asmlinkage void handle_ri(void);
57 extern asmlinkage void handle_cpu(void);
58 extern asmlinkage void handle_ov(void);
59 extern asmlinkage void handle_tr(void);
60 extern asmlinkage void handle_fpe(void);
61 extern asmlinkage void handle_watch(void);
62 extern asmlinkage void handle_mcheck(void);
63 extern asmlinkage void handle_reserved(void);
64
65 extern int fpu_emulator_cop1Handler(struct pt_regs *);
66
67 char watch_available = 0;
68
69 void (*ibe_board_handler)(struct pt_regs *regs);
70 void (*dbe_board_handler)(struct pt_regs *regs);
71
72 int kstack_depth_to_print = 24;
73
74 /*
75 * These constant is for searching for possible module text segments.
76 * MODULE_RANGE is a guess of how much space is likely to be vmalloced.
77 */
78 #define MODULE_RANGE (8*1024*1024)
79
80 #ifndef CONFIG_CPU_HAS_LLSC
81 /*
82 * This stuff is needed for the userland ll-sc emulation for R2300
83 */
84 void simulate_ll(struct pt_regs *regs, unsigned int opcode);
85 void simulate_sc(struct pt_regs *regs, unsigned int opcode);
86
87 #define OPCODE 0xfc000000
88 #define BASE 0x03e00000
89 #define RT 0x001f0000
90 #define OFFSET 0x0000ffff
91 #define LL 0xc0000000
92 #define SC 0xe0000000
93 #endif
94
95 /*
96 * This routine abuses get_user()/put_user() to reference pointers
97 * with at least a bit of error checking ...
98 */
99 void show_stack(unsigned int *sp)
100 {
101 int i;
102 unsigned int *stack;
103
104 stack = sp;
105 i = 0;
106
107 printk("Stack:");
108 while ((unsigned long) stack & (PAGE_SIZE - 1)) {
109 unsigned long stackdata;
110
111 if (__get_user(stackdata, stack++)) {
112 printk(" (Bad stack address)");
113 break;
114 }
115
116 printk(" %08lx", stackdata);
117
118 if (++i > 40) {
119 printk(" ...");
120 break;
121 }
122
123 if (i % 8 == 0)
124 printk("\n ");
125 }
126 }
127
128 void show_trace(unsigned int *sp)
129 {
130 int i;
131 unsigned int *stack;
132 unsigned long kernel_start, kernel_end;
133 unsigned long module_start, module_end;
134 extern char _stext, _etext;
135
136 stack = sp;
137 i = 0;
138
139 kernel_start = (unsigned long) &_stext;
140 kernel_end = (unsigned long) &_etext;
141 module_start = VMALLOC_START;
142 module_end = module_start + MODULE_RANGE;
143
144 printk("\nCall Trace:");
145
146 while ((unsigned long) stack & (PAGE_SIZE -1)) {
147 unsigned long addr;
148
149 if (__get_user(addr, stack++)) {
150 printk(" (Bad stack address)\n");
151 break;
152 }
153
154 /*
155 * If the address is either in the text segment of the
156 * kernel, or in the region which contains vmalloc'ed
157 * memory, it *may* be the address of a calling
158 * routine; if so, print it so that someone tracing
159 * down the cause of the crash will be able to figure
160 * out the call path that was taken.
161 */
162
163 if ((addr >= kernel_start && addr < kernel_end) ||
164 (addr >= module_start && addr < module_end)) {
165
166 printk(" [<%08lx>]", addr);
167 if (++i > 40) {
168 printk(" ...");
169 break;
170 }
171 }
172 }
173 }
174
175 void show_code(unsigned int *pc)
176 {
177 long i;
178
179 printk("\nCode:");
180
181 for(i = -3 ; i < 6 ; i++) {
182 unsigned long insn;
183 if (__get_user(insn, pc + i)) {
184 printk(" (Bad address in epc)\n");
185 break;
186 }
187 printk("%c%08lx%c",(i?' ':'<'),insn,(i?' ':'>'));
188 }
189 }
190
191 spinlock_t die_lock;
192
193 extern void __die(const char * str, struct pt_regs * regs, const char *where,
194 unsigned long line)
195 {
196 console_verbose();
197 spin_lock_irq(&die_lock);
198 printk("%s", str);
199 if (where)
200 printk(" in %s, line %ld", where, line);
201 printk(":\n");
202 show_regs(regs);
203 printk("Process %s (pid: %d, stackpage=%08lx)\n",
204 current->comm, current->pid, (unsigned long) current);
205 show_stack((unsigned int *) regs->regs[29]);
206 show_trace((unsigned int *) regs->regs[29]);
207 show_code((unsigned int *) regs->cp0_epc);
208 printk("\n");
209 spin_unlock_irq(&die_lock);
210 do_exit(SIGSEGV);
211 }
212
213 void __die_if_kernel(const char * str, struct pt_regs * regs, const char *where,
214 unsigned long line)
215 {
216 if (!user_mode(regs))
217 __die(str, regs, where, line);
218 }
219
220 extern const struct exception_table_entry __start___dbe_table[];
221 extern const struct exception_table_entry __stop___dbe_table[];
222
223 void __declare_dbe_table(void)
224 {
225 __asm__ __volatile__(
226 ".section\t__dbe_table,\"a\"\n\t"
227 ".previous"
228 );
229 }
230
231 static inline unsigned long
232 search_one_table(const struct exception_table_entry *first,
233 const struct exception_table_entry *last,
234 unsigned long value)
235 {
236 const struct exception_table_entry *mid;
237 long diff;
238
239 while (first < last) {
240 mid = (last - first) / 2 + first;
241 diff = mid->insn - value;
242 if (diff < 0)
243 first = mid + 1;
244 else
245 last = mid;
246 }
247 return (first == last && first->insn == value) ? first->nextinsn : 0;
248 }
249
250 extern spinlock_t modlist_lock;
251
252 static inline unsigned long
253 search_dbe_table(unsigned long addr)
254 {
255 unsigned long ret = 0;
256
257 #ifndef CONFIG_MODULES
258 /* There is only the kernel to search. */
259 ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
260 return ret;
261 #else
262 unsigned long flags;
263
264 /* The kernel is the last "module" -- no need to treat it special. */
265 struct module *mp;
266 struct archdata *ap;
267
268 spin_lock_irqsave(&modlist_lock, flags);
269 for (mp = module_list; mp != NULL; mp = mp->next) {
270 if (!mod_member_present(mp, archdata_end) ||
271 !mod_archdata_member_present(mp, struct archdata,
272 dbe_table_end))
273 continue;
274 ap = (struct archdata *)(mp->archdata_start);
275
276 if (ap->dbe_table_start == NULL ||
277 !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
278 continue;
279 ret = search_one_table(ap->dbe_table_start,
280 ap->dbe_table_end - 1, addr);
281 if (ret)
282 break;
283 }
284 spin_unlock_irqrestore(&modlist_lock, flags);
285 return ret;
286 #endif
287 }
288
289 static void default_be_board_handler(struct pt_regs *regs)
290 {
291 unsigned long new_epc;
292 unsigned long fixup;
293 int data = regs->cp0_cause & 4;
294
295 if (data && !user_mode(regs)) {
296 fixup = search_dbe_table(regs->cp0_epc);
297 if (fixup) {
298 new_epc = fixup_exception(dpf_reg, fixup,
299 regs->cp0_epc);
300 regs->cp0_epc = new_epc;
301 return;
302 }
303 }
304
305 /*
306 * Assume it would be too dangerous to continue ...
307 */
308 printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
309 data ? "Data" : "Instruction",
310 regs->cp0_epc, regs->regs[31]);
311 die_if_kernel("Oops", regs);
312 force_sig(SIGBUS, current);
313 }
314
315 asmlinkage void do_ibe(struct pt_regs *regs)
316 {
317 ibe_board_handler(regs);
318 }
319
320 asmlinkage void do_dbe(struct pt_regs *regs)
321 {
322 dbe_board_handler(regs);
323 }
324
325 asmlinkage void do_ov(struct pt_regs *regs)
326 {
327 if (compute_return_epc(regs))
328 return;
329
330 force_sig(SIGFPE, current);
331 }
332
333 /*
334 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
335 */
336 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
337 {
338 if (fcr31 & FPU_CSR_UNI_X) {
339 extern void save_fp(struct task_struct *);
340 extern void restore_fp(struct task_struct *);
341 int sig;
342 /*
343 * Unimplemented operation exception. If we've got the
344 * full software emulator on-board, let's use it...
345 *
346 * Force FPU to dump state into task/thread context.
347 * We're moving a lot of data here for what is probably
348 * a single instruction, but the alternative is to
349 * pre-decode the FP register operands before invoking
350 * the emulator, which seems a bit extreme for what
351 * should be an infrequent event.
352 */
353 save_fp(current);
354
355 /* Run the emulator */
356 sig = fpu_emulator_cop1Handler(regs);
357
358 /*
359 * We can't allow the emulated instruction to leave the
360 * Unimplemented Operation bit set in $fcr31.
361 */
362 current->thread.fpu.soft.sr &= ~FPU_CSR_UNI_X;
363
364 /* Restore the hardware register state */
365 restore_fp(current);
366
367 /* If something went wrong, signal */
368 if (sig)
369 force_sig(sig, current);
370
371 return;
372 }
373
374 if (compute_return_epc(regs))
375 return;
376
377 force_sig(SIGFPE, current);
378 printk(KERN_DEBUG "Sent send SIGFPE to %s\n", current->comm);
379 }
380
381 static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
382 {
383 unsigned int *epc;
384
385 epc = (unsigned int *) regs->cp0_epc +
386 ((regs->cp0_cause & CAUSEF_BD) != 0);
387 if (!get_user(*opcode, epc))
388 return 0;
389
390 force_sig(SIGSEGV, current);
391 return 1;
392 }
393
394 asmlinkage void do_bp(struct pt_regs *regs)
395 {
396 siginfo_t info;
397 unsigned int opcode, bcode;
398 unsigned int *epc;
399
400 epc = (unsigned int *) regs->cp0_epc +
401 ((regs->cp0_cause & CAUSEF_BD) != 0);
402 if (get_user(opcode, epc))
403 goto sigsegv;
404
405 /*
406 * There is the ancient bug in the MIPS assemblers that the break
407 * code starts left to bit 16 instead to bit 6 in the opcode.
408 * Gas is bug-compatible ...
409 */
410 bcode = ((opcode >> 16) & ((1 << 20) - 1));
411
412 /*
413 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
414 * insns, even for break codes that indicate arithmetic failures.
415 * Weird ...)
416 * But should we continue the brokenness??? --macro
417 */
418 switch (bcode) {
419 case 6:
420 case 7:
421 if (bcode == 7)
422 info.si_code = FPE_INTDIV;
423 else
424 info.si_code = FPE_INTOVF;
425 info.si_signo = SIGFPE;
426 info.si_errno = 0;
427 info.si_addr = (void *)compute_return_epc(regs);
428 force_sig_info(SIGFPE, &info, current);
429 break;
430 default:
431 force_sig(SIGTRAP, current);
432 }
433 return;
434
435 sigsegv:
436 force_sig(SIGSEGV, current);
437 }
438
439 asmlinkage void do_tr(struct pt_regs *regs)
440 {
441 siginfo_t info;
442 unsigned int opcode, bcode;
443 unsigned *epc;
444
445 epc = (unsigned int *) regs->cp0_epc +
446 ((regs->cp0_cause & CAUSEF_BD) != 0);
447 if (get_user(opcode, epc))
448 goto sigsegv;
449
450 bcode = ((opcode >> 6) & ((1 << 20) - 1));
451
452 /*
453 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
454 * insns, even for break codes that indicate arithmetic failures.
455 * Weird ...)
456 * But should we continue the brokenness??? --macro
457 */
458 switch (bcode) {
459 case 6:
460 case 7:
461 if (bcode == 7)
462 info.si_code = FPE_INTDIV;
463 else
464 info.si_code = FPE_INTOVF;
465 info.si_signo = SIGFPE;
466 info.si_errno = 0;
467 info.si_addr = (void *)compute_return_epc(regs);
468 force_sig_info(SIGFPE, &info, current);
469 break;
470 default:
471 force_sig(SIGTRAP, current);
472 }
473 return;
474
475 sigsegv:
476 force_sig(SIGSEGV, current);
477 }
478
479 #ifndef CONFIG_CPU_HAS_LLSC
480
481 #ifdef CONFIG_SMP
482 #error "ll/sc emulation is not SMP safe"
483 #endif
484
485 /*
486 * userland emulation for R2300 CPUs
487 * needed for the multithreading part of glibc
488 *
489 * this implementation can handle only sychronization between 2 or more
490 * user contexts and is not SMP safe.
491 */
492 asmlinkage void do_ri(struct pt_regs *regs)
493 {
494 unsigned int opcode;
495
496 if (!user_mode(regs))
497 BUG();
498
499 if (!get_insn_opcode(regs, &opcode)) {
500 if ((opcode & OPCODE) == LL) {
501 simulate_ll(regs, opcode);
502 return;
503 }
504 if ((opcode & OPCODE) == SC) {
505 simulate_sc(regs, opcode);
506 return;
507 }
508 }
509
510 if (compute_return_epc(regs))
511 return;
512 force_sig(SIGILL, current);
513 }
514
515 /*
516 * The ll_bit is cleared by r*_switch.S
517 */
518
519 unsigned long ll_bit;
520 #ifdef CONFIG_PROC_FS
521 extern unsigned long ll_ops;
522 extern unsigned long sc_ops;
523 #endif
524
525 static struct task_struct *ll_task = NULL;
526
527 void simulate_ll(struct pt_regs *regp, unsigned int opcode)
528 {
529 unsigned long value, *vaddr;
530 long offset;
531 int signal = 0;
532
533 /*
534 * analyse the ll instruction that just caused a ri exception
535 * and put the referenced address to addr.
536 */
537
538 /* sign extend offset */
539 offset = opcode & OFFSET;
540 offset <<= 16;
541 offset >>= 16;
542
543 vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset);
544
545 #ifdef CONFIG_PROC_FS
546 ll_ops++;
547 #endif
548
549 if ((unsigned long)vaddr & 3)
550 signal = SIGBUS;
551 else if (get_user(value, vaddr))
552 signal = SIGSEGV;
553 else {
554 if (ll_task == NULL || ll_task == current) {
555 ll_bit = 1;
556 } else {
557 ll_bit = 0;
558 }
559 ll_task = current;
560 regp->regs[(opcode & RT) >> 16] = value;
561 }
562 if (compute_return_epc(regp))
563 return;
564 if (signal)
565 send_sig(signal, current, 1);
566 }
567
568 void simulate_sc(struct pt_regs *regp, unsigned int opcode)
569 {
570 unsigned long *vaddr, reg;
571 long offset;
572 int signal = 0;
573
574 /*
575 * analyse the sc instruction that just caused a ri exception
576 * and put the referenced address to addr.
577 */
578
579 /* sign extend offset */
580 offset = opcode & OFFSET;
581 offset <<= 16;
582 offset >>= 16;
583
584 vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset);
585 reg = (opcode & RT) >> 16;
586
587 #ifdef CONFIG_PROC_FS
588 sc_ops++;
589 #endif
590
591 if ((unsigned long)vaddr & 3)
592 signal = SIGBUS;
593 else if (ll_bit == 0 || ll_task != current)
594 regp->regs[reg] = 0;
595 else if (put_user(regp->regs[reg], vaddr))
596 signal = SIGSEGV;
597 else
598 regp->regs[reg] = 1;
599 if (compute_return_epc(regp))
600 return;
601 if (signal)
602 send_sig(signal, current, 1);
603 }
604
605 #else /* MIPS 2 or higher */
606
607 asmlinkage void do_ri(struct pt_regs *regs)
608 {
609 unsigned int opcode;
610
611 get_insn_opcode(regs, &opcode);
612 if (compute_return_epc(regs))
613 return;
614
615 force_sig(SIGILL, current);
616 }
617
618 #endif
619
620 asmlinkage void do_cpu(struct pt_regs *regs)
621 {
622 unsigned int cpid;
623 extern void lazy_fpu_switch(void *);
624 extern void init_fpu(void);
625 void fpu_emulator_init_fpu(void);
626 int sig;
627
628 cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
629 if (cpid != 1)
630 goto bad_cid;
631
632 if (!(mips_cpu.options & MIPS_CPU_FPU))
633 goto fp_emul;
634
635 regs->cp0_status |= ST0_CU1;
636 if (last_task_used_math == current)
637 return;
638
639 if (current->used_math) { /* Using the FPU again. */
640 lazy_fpu_switch(last_task_used_math);
641 } else { /* First time FPU user. */
642 init_fpu();
643 current->used_math = 1;
644 }
645 last_task_used_math = current;
646 return;
647
648 fp_emul:
649 if (last_task_used_math != current) {
650 if (!current->used_math) {
651 fpu_emulator_init_fpu();
652 current->used_math = 1;
653 }
654 }
655 sig = fpu_emulator_cop1Handler(regs);
656 last_task_used_math = current;
657 if (sig)
658 force_sig(sig, current);
659 return;
660
661 bad_cid:
662 force_sig(SIGILL, current);
663 }
664
665 asmlinkage void do_watch(struct pt_regs *regs)
666 {
667 /*
668 * We use the watch exception where available to detect stack
669 * overflows.
670 */
671 show_regs(regs);
672 panic("Caught WATCH exception - probably caused by stack overflow.");
673 }
674
675 asmlinkage void do_mcheck(struct pt_regs *regs)
676 {
677 show_regs(regs);
678 panic("Caught Machine Check exception - probably caused by multiple "
679 "matching entries in the TLB.");
680 }
681
682 asmlinkage void do_reserved(struct pt_regs *regs)
683 {
684 /*
685 * Game over - no way to handle this if it ever occurs. Most probably
686 * caused by a new unknown cpu type or after another deadly
687 * hard/software error.
688 */
689 show_regs(regs);
690 panic("Caught reserved exception - should not happen.");
691 }
692
693 static inline void watch_init(void)
694 {
695 if (mips_cpu.options & MIPS_CPU_WATCH ) {
696 set_except_vector(23, handle_watch);
697 watch_available = 1;
698 }
699 }
700
701 /*
702 * Some MIPS CPUs can enable/disable for cache parity detection, but do
703 * it different ways.
704 */
705 static inline void parity_protection_init(void)
706 {
707 switch (mips_cpu.cputype) {
708 case CPU_5KC:
709 /* Set the PE bit (bit 31) in the CP0_ECC register. */
710 printk(KERN_INFO "Enable the cache parity protection for "
711 "MIPS 5KC CPUs.\n");
712 write_32bit_cp0_register(CP0_ECC,
713 read_32bit_cp0_register(CP0_ECC)
714 | 0x80000000);
715 break;
716 default:
717 break;
718 }
719 }
720
721 asmlinkage void cache_parity_error(void)
722 {
723 unsigned int reg_val;
724
725 /* For the moment, report the problem and hang. */
726 reg_val = read_32bit_cp0_register(CP0_ERROREPC);
727 printk("Cache error exception:\n");
728 printk("cp0_errorepc == %08x\n", reg_val);
729 reg_val = read_32bit_cp0_register(CP0_CACHEERR);
730 printk("cp0_cacheerr == %08x\n", reg_val);
731
732 printk("Decoded CP0_CACHEERR: %s cache fault in %s reference.\n",
733 reg_val & (1<<30) ? "secondary" : "primary",
734 reg_val & (1<<31) ? "data" : "insn");
735 printk("Error bits: %s%s%s%s%s%s%s\n",
736 reg_val & (1<<29) ? "ED " : "",
737 reg_val & (1<<28) ? "ET " : "",
738 reg_val & (1<<26) ? "EE " : "",
739 reg_val & (1<<25) ? "EB " : "",
740 reg_val & (1<<24) ? "EI " : "",
741 reg_val & (1<<23) ? "E1 " : "",
742 reg_val & (1<<22) ? "E0 " : "");
743 printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
744
745 if (reg_val&(1<<22))
746 printk("DErrAddr0: 0x%08x\n",
747 read_32bit_cp0_set1_register(CP0_S1_DERRADDR0));
748
749 if (reg_val&(1<<23))
750 printk("DErrAddr1: 0x%08x\n",
751 read_32bit_cp0_set1_register(CP0_S1_DERRADDR1));
752
753 panic("Can't handle the cache error!");
754 }
755
756 unsigned long exception_handlers[32];
757
758 /*
759 * As a side effect of the way this is implemented we're limited
760 * to interrupt handlers in the address range from
761 * KSEG0 <= x < KSEG0 + 256mb on the Nevada. Oh well ...
762 */
763 void *set_except_vector(int n, void *addr)
764 {
765 unsigned handler = (unsigned long) addr;
766 unsigned old_handler = exception_handlers[n];
767 exception_handlers[n] = handler;
768
769 if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) {
770 *(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
771 (0x03ffffff & (handler >> 2));
772 flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
773 }
774 return (void *)old_handler;
775 }
776
777 asmlinkage int (*save_fp_context)(struct sigcontext *sc);
778 asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
779 extern asmlinkage int _save_fp_context(struct sigcontext *sc);
780 extern asmlinkage int _restore_fp_context(struct sigcontext *sc);
781
782 extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc);
783 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc);
784
785 void __init trap_init(void)
786 {
787 extern char except_vec0_nevada, except_vec0_r4000;
788 extern char except_vec0_r4600, except_vec0_r2300;
789 extern char except_vec1_generic, except_vec2_generic;
790 extern char except_vec3_generic, except_vec3_r4000;
791 extern char except_vec4;
792 extern char except_vec_ejtag_debug;
793 unsigned long i;
794
795 /* Some firmware leaves the BEV flag set, clear it. */
796 clear_cp0_status(ST0_BEV);
797
798 /* Copy the generic exception handler code to it's final destination. */
799 memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
800 memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
801 memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
802 flush_icache_range(KSEG0 + 0x80, KSEG0 + 0x200);
803 /*
804 * Setup default vectors
805 */
806 for (i = 0; i <= 31; i++)
807 set_except_vector(i, handle_reserved);
808
809 /*
810 * Copy the EJTAG debug exception vector handler code to it's final
811 * destination.
812 */
813 memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
814
815 /*
816 * Only some CPUs have the watch exceptions or a dedicated
817 * interrupt vector.
818 */
819 watch_init();
820
821 /*
822 * Some MIPS CPUs have a dedicated interrupt vector which reduces the
823 * interrupt processing overhead. Use it where available.
824 */
825 if (mips_cpu.options & MIPS_CPU_DIVEC) {
826 memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8);
827 set_cp0_cause(CAUSEF_IV);
828 }
829
830 /*
831 * Some CPUs can enable/disable for cache parity detection, but does
832 * it different ways.
833 */
834 parity_protection_init();
835
836 set_except_vector(1, handle_mod);
837 set_except_vector(2, handle_tlbl);
838 set_except_vector(3, handle_tlbs);
839 set_except_vector(4, handle_adel);
840 set_except_vector(5, handle_ades);
841
842 /*
843 * The Data Bus Error/ Instruction Bus Errors are signaled
844 * by external hardware. Therefore these two expection have
845 * board specific handlers.
846 */
847 set_except_vector(6, handle_ibe);
848 set_except_vector(7, handle_dbe);
849 ibe_board_handler = default_be_board_handler;
850 dbe_board_handler = default_be_board_handler;
851
852 set_except_vector(8, handle_sys);
853 set_except_vector(9, handle_bp);
854 set_except_vector(10, handle_ri);
855 set_except_vector(11, handle_cpu);
856 set_except_vector(12, handle_ov);
857 set_except_vector(13, handle_tr);
858
859 if (mips_cpu.options & MIPS_CPU_FPU)
860 set_except_vector(15, handle_fpe);
861
862 /*
863 * Handling the following exceptions depends mostly of the cpu type
864 */
865 if ((mips_cpu.options & MIPS_CPU_4KEX)
866 && (mips_cpu.options & MIPS_CPU_4KTLB)) {
867 if (mips_cpu.cputype == CPU_NEVADA) {
868 memcpy((void *)KSEG0, &except_vec0_nevada, 0x80);
869 } else if (mips_cpu.cputype == CPU_R4600)
870 memcpy((void *)KSEG0, &except_vec0_r4600, 0x80);
871 else
872 memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
873
874 /* Cache error vector already set above. */
875
876 if (mips_cpu.options & MIPS_CPU_VCE) {
877 memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
878 0x80);
879 } else {
880 memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
881 0x80);
882 }
883
884 if (mips_cpu.options & MIPS_CPU_FPU) {
885 save_fp_context = _save_fp_context;
886 restore_fp_context = _restore_fp_context;
887 } else {
888 save_fp_context = fpu_emulator_save_context;
889 restore_fp_context = fpu_emulator_restore_context;
890 }
891 } else switch (mips_cpu.cputype) {
892 case CPU_SB1:
893 /*
894 * XXX - This should be folded in to the "cleaner" handling,
895 * above
896 */
897 memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
898 memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80);
899 save_fp_context = _save_fp_context;
900 restore_fp_context = _restore_fp_context;
901
902 /* Enable timer interrupt and scd mapped interrupt */
903 clear_cp0_status(0xf000);
904 set_cp0_status(0xc00);
905 break;
906 case CPU_R6000:
907 case CPU_R6000A:
908 save_fp_context = _save_fp_context;
909 restore_fp_context = _restore_fp_context;
910
911 /*
912 * The R6000 is the only R-series CPU that features a machine
913 * check exception (similar to the R4000 cache error) and
914 * unaligned ldc1/sdc1 exception. The handlers have not been
915 * written yet. Well, anyway there is no R6000 machine on the
916 * current list of targets for Linux/MIPS.
917 * (Duh, crap, there is someone with a tripple R6k machine)
918 */
919 //set_except_vector(14, handle_mc);
920 //set_except_vector(15, handle_ndc);
921 case CPU_R2000:
922 case CPU_R3000:
923 case CPU_R3000A:
924 case CPU_R3041:
925 case CPU_R3051:
926 case CPU_R3052:
927 case CPU_R3081:
928 case CPU_R3081E:
929 case CPU_TX3912:
930 case CPU_TX3922:
931 case CPU_TX3927:
932 save_fp_context = _save_fp_context;
933 restore_fp_context = _restore_fp_context;
934 memcpy((void *)KSEG0, &except_vec0_r2300, 0x80);
935 memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
936 break;
937
938 case CPU_UNKNOWN:
939 default:
940 panic("Unknown CPU type");
941 }
942 flush_icache_range(KSEG0, KSEG0 + 0x200);
943
944 if (mips_cpu.isa_level == MIPS_CPU_ISA_IV)
945 set_cp0_status(ST0_XX);
946
947 atomic_inc(&init_mm.mm_count); /* XXX UP? */
948 current->active_mm = &init_mm;
949 write_32bit_cp0_register(CP0_CONTEXT, smp_processor_id()<<23);
950 current_pgd[0] = init_mm.pgd;
951 }
952