2 * linux/arch/sh/traps.c
4 * SuperH version: Copyright (C) 1999 Niibe Yutaka
8 * 'Traps.c' handles hardware traps and faults after we have saved some
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/string.h>
14 #include <linux/errno.h>
15 #include <linux/ptrace.h>
16 #include <linux/timer.h>
18 #include <linux/smp.h>
19 #include <linux/smp_lock.h>
20 #include <linux/init.h>
21 #include <linux/delay.h>
22 #include <linux/spinlock.h>
24 #include <asm/system.h>
25 #include <asm/uaccess.h>
27 #include <asm/atomic.h>
29 static inline void console_verbose(void)
31 extern int console_loglevel
;
32 console_loglevel
= 15;
35 #define DO_ERROR(trapnr, signr, str, name, tsk) \
36 asmlinkage void do_##name(unsigned long r4, unsigned long r5, \
37 unsigned long r6, unsigned long r7, \
38 struct pt_regs regs) \
40 unsigned long error_code; \
42 asm volatile("stc r2_bank,%0": "=r" (error_code)); \
44 regs.syscall_nr = -1; \
45 tsk->thread.error_code = error_code; \
46 tsk->thread.trap_no = trapnr; \
47 force_sig(signr, tsk); \
48 die_if_no_fixup(str,®s,error_code); \
52 * These constants are for searching for possible module text
53 * segments. VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
54 * a guess of how much space is likely to be vmalloced.
56 #define VMALLOC_OFFSET (8*1024*1024)
57 #define MODULE_RANGE (8*1024*1024)
59 static void show_registers(struct pt_regs
*regs
)
60 {/* Not implemented yet. */
65 void die(const char * str
, struct pt_regs
* regs
, long err
)
68 spin_lock_irq(&die_lock
);
69 printk("%s: %04lx\n", str
, err
& 0xffff);
71 spin_unlock_irq(&die_lock
);
75 static inline void die_if_kernel(const char * str
, struct pt_regs
* regs
, long err
)
81 static void die_if_no_fixup(const char * str
, struct pt_regs
* regs
, long err
)
86 fixup
= search_exception_table(regs
->pc
);
95 DO_ERROR( 7, SIGSEGV
, "address error (load)", address_error_load
, current
)
96 DO_ERROR( 8, SIGSEGV
, "address error (store)", address_error_store
, current
)
97 DO_ERROR(12, SIGILL
, "reserved instruction", reserved_inst
, current
)
98 DO_ERROR(13, SIGILL
, "illegal slot instruction", illegal_slot_inst
, current
)
100 asmlinkage
void do_exception_error (unsigned long r4
, unsigned long r5
,
101 unsigned long r6
, unsigned long r7
,
105 asm volatile("stc r2_bank,%0" : "=r" (ex
));
106 die_if_kernel("exception", ®s
, ex
);
109 void __init
trap_init(void)
111 extern void *vbr_base
;
112 extern void *exception_handling_table
[14];
114 exception_handling_table
[7] = (void *)do_address_error_load
;
115 exception_handling_table
[8] = (void *)do_address_error_store
;
116 exception_handling_table
[12] = (void *)do_reserved_inst
;
117 exception_handling_table
[13] = (void *)do_illegal_slot_inst
;
119 /* NOTE: The VBR value should be at P1
120 (or P2, virtural "fixed" address space).
121 It's definitely should not in physical address. */
123 asm volatile("ldc %0,vbr"