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