a38f435fba7b7b0a923fc4c2042e1da4444e2522
2 * arch/score/kernel/traps.c
4 * Score Processor version.
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <linux/module.h>
27 #include <linux/sched.h>
29 #include <asm/cacheflush.h>
31 #include <asm/irq_regs.h>
33 unsigned long exception_handlers
[32];
36 * The architecture-independent show_stack generator
38 void show_stack(struct task_struct
*task
, unsigned long *sp
)
43 sp
= sp
? sp
: (unsigned long *)&sp
;
45 printk(KERN_NOTICE
"Stack: ");
47 while ((long) sp
& (PAGE_SIZE
- 1)) {
48 if (i
&& ((i
% 8) == 0))
49 printk(KERN_NOTICE
"\n");
51 printk(KERN_NOTICE
" ...");
55 if (__get_user(stackdata
, sp
++)) {
56 printk(KERN_NOTICE
" (Bad stack address)");
60 printk(KERN_NOTICE
" %08lx", stackdata
);
63 printk(KERN_NOTICE
"\n");
66 static void show_trace(long *sp
)
71 sp
= sp
? sp
: (long *) &sp
;
73 printk(KERN_NOTICE
"Call Trace: ");
75 while ((long) sp
& (PAGE_SIZE
- 1)) {
76 if (__get_user(addr
, sp
++)) {
77 if (i
&& ((i
% 6) == 0))
78 printk(KERN_NOTICE
"\n");
79 printk(KERN_NOTICE
" (Bad stack address)\n");
83 if (kernel_text_address(addr
)) {
84 if (i
&& ((i
% 6) == 0))
85 printk(KERN_NOTICE
"\n");
87 printk(KERN_NOTICE
" ...");
91 printk(KERN_NOTICE
" [<%08lx>]", addr
);
95 printk(KERN_NOTICE
"\n");
98 static void show_code(unsigned int *pc
)
102 printk(KERN_NOTICE
"\nCode:");
104 for (i
= -3; i
< 6; i
++) {
106 if (__get_user(insn
, pc
+ i
)) {
107 printk(KERN_NOTICE
" (Bad address in epc)\n");
110 printk(KERN_NOTICE
"%c%08lx%c", (i
? ' ' : '<'),
111 insn
, (i
? ' ' : '>'));
116 * FIXME: really the generic show_regs should take a const pointer argument.
118 void show_regs(struct pt_regs
*regs
)
120 printk("r0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
121 regs
->regs
[0], regs
->regs
[1], regs
->regs
[2], regs
->regs
[3],
122 regs
->regs
[4], regs
->regs
[5], regs
->regs
[6], regs
->regs
[7]);
123 printk("r8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
124 regs
->regs
[8], regs
->regs
[9], regs
->regs
[10], regs
->regs
[11],
125 regs
->regs
[12], regs
->regs
[13], regs
->regs
[14], regs
->regs
[15]);
126 printk("r16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
127 regs
->regs
[16], regs
->regs
[17], regs
->regs
[18], regs
->regs
[19],
128 regs
->regs
[20], regs
->regs
[21], regs
->regs
[22], regs
->regs
[23]);
129 printk("r24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
130 regs
->regs
[24], regs
->regs
[25], regs
->regs
[26], regs
->regs
[27],
131 regs
->regs
[28], regs
->regs
[29], regs
->regs
[30], regs
->regs
[31]);
133 printk("CEH : %08lx\n", regs
->ceh
);
134 printk("CEL : %08lx\n", regs
->cel
);
136 printk("EMA:%08lx, epc:%08lx %s\nPSR: %08lx\nECR:%08lx\nCondition : %08lx\n",
137 regs
->cp0_ema
, regs
->cp0_epc
, print_tainted(), regs
->cp0_psr
,
138 regs
->cp0_ecr
, regs
->cp0_condition
);
141 static void show_registers(struct pt_regs
*regs
)
144 printk(KERN_NOTICE
"Process %s (pid: %d, stackpage=%08lx)\n",
145 current
->comm
, current
->pid
, (unsigned long) current
);
146 show_stack(current_thread_info()->task
, (long *) regs
->regs
[0]);
147 show_trace((long *) regs
->regs
[0]);
148 show_code((unsigned int *) regs
->cp0_epc
);
149 printk(KERN_NOTICE
"\n");
152 void __die(const char *str
, struct pt_regs
*regs
, const char *file
,
153 const char *func
, unsigned long line
)
158 printk(" in %s:%s, line %ld", file
, func
, line
);
160 show_registers(regs
);
164 void __die_if_kernel(const char *str
, struct pt_regs
*regs
,
165 const char *file
, const char *func
, unsigned long line
)
167 if (!user_mode(regs
))
168 __die(str
, regs
, file
, func
, line
);
171 asmlinkage
void do_adelinsn(struct pt_regs
*regs
)
173 printk("do_ADE-linsn:ema:0x%08lx:epc:0x%08lx\n",
174 regs
->cp0_ema
, regs
->cp0_epc
);
175 die_if_kernel("do_ade execution Exception\n", regs
);
176 force_sig(SIGBUS
, current
);
179 asmlinkage
void do_adedata(struct pt_regs
*regs
)
181 const struct exception_table_entry
*fixup
;
182 fixup
= search_exception_tables(regs
->cp0_epc
);
184 regs
->cp0_epc
= fixup
->fixup
;
187 printk("do_ADE-data:ema:0x%08lx:epc:0x%08lx\n",
188 regs
->cp0_ema
, regs
->cp0_epc
);
189 die_if_kernel("do_ade execution Exception\n", regs
);
190 force_sig(SIGBUS
, current
);
193 asmlinkage
void do_pel(struct pt_regs
*regs
)
195 die_if_kernel("do_pel execution Exception", regs
);
196 force_sig(SIGFPE
, current
);
199 asmlinkage
void do_cee(struct pt_regs
*regs
)
201 die_if_kernel("do_cee execution Exception", regs
);
202 force_sig(SIGFPE
, current
);
205 asmlinkage
void do_cpe(struct pt_regs
*regs
)
207 die_if_kernel("do_cpe execution Exception", regs
);
208 force_sig(SIGFPE
, current
);
211 asmlinkage
void do_be(struct pt_regs
*regs
)
213 die_if_kernel("do_be execution Exception", regs
);
214 force_sig(SIGBUS
, current
);
217 asmlinkage
void do_ov(struct pt_regs
*regs
)
221 die_if_kernel("do_ov execution Exception", regs
);
223 info
.si_code
= FPE_INTOVF
;
224 info
.si_signo
= SIGFPE
;
226 info
.si_addr
= (void *)regs
->cp0_epc
;
227 force_sig_info(SIGFPE
, &info
, current
);
230 asmlinkage
void do_tr(struct pt_regs
*regs
)
232 die_if_kernel("do_tr execution Exception", regs
);
233 force_sig(SIGTRAP
, current
);
236 asmlinkage
void do_ri(struct pt_regs
*regs
)
238 unsigned long epc_insn
;
239 unsigned long epc
= regs
->cp0_epc
;
241 read_tsk_long(current
, epc
, &epc_insn
);
242 if (current
->thread
.single_step
== 1) {
243 if ((epc
== current
->thread
.addr1
) ||
244 (epc
== current
->thread
.addr2
)) {
245 user_disable_single_step(current
);
246 force_sig(SIGTRAP
, current
);
250 } else if ((epc_insn
== BREAKPOINT32_INSN
) ||
251 ((epc_insn
& 0x0000FFFF) == 0x7002) ||
252 ((epc_insn
& 0xFFFF0000) == 0x70020000)) {
253 force_sig(SIGTRAP
, current
);
256 die_if_kernel("do_ri execution Exception", regs
);
257 force_sig(SIGILL
, current
);
261 asmlinkage
void do_ccu(struct pt_regs
*regs
)
263 die_if_kernel("do_ccu execution Exception", regs
);
264 force_sig(SIGILL
, current
);
267 asmlinkage
void do_reserved(struct pt_regs
*regs
)
270 * Game over - no way to handle this if it ever occurs. Most probably
271 * caused by a new unknown cpu type or after another deadly
272 * hard/software error.
274 die_if_kernel("do_reserved execution Exception", regs
);
276 panic("Caught reserved exception - should not happen.");
280 * NMI exception handler.
282 void nmi_exception_handler(struct pt_regs
*regs
)
284 die_if_kernel("nmi_exception_handler execution Exception", regs
);
288 /* Install CPU exception handler */
289 void *set_except_vector(int n
, void *addr
)
291 unsigned long handler
= (unsigned long) addr
;
292 unsigned long old_handler
= exception_handlers
[n
];
294 exception_handlers
[n
] = handler
;
295 return (void *)old_handler
;
298 void __init
trap_init(void)
302 pgd_current
= (unsigned long)init_mm
.pgd
;
303 /* DEBUG EXCEPTION */
304 memcpy((void *)DEBUG_VECTOR_BASE_ADDR
,
305 &debug_exception_vector
, DEBUG_VECTOR_SIZE
);
307 memcpy((void *)GENERAL_VECTOR_BASE_ADDR
,
308 &general_exception_vector
, GENERAL_VECTOR_SIZE
);
311 * Initialise exception handlers
313 for (i
= 0; i
<= 31; i
++)
314 set_except_vector(i
, handle_reserved
);
316 set_except_vector(1, handle_nmi
);
317 set_except_vector(2, handle_adelinsn
);
318 set_except_vector(3, handle_tlb_refill
);
319 set_except_vector(4, handle_tlb_invaild
);
320 set_except_vector(5, handle_ibe
);
321 set_except_vector(6, handle_pel
);
322 set_except_vector(7, handle_sys
);
323 set_except_vector(8, handle_ccu
);
324 set_except_vector(9, handle_ri
);
325 set_except_vector(10, handle_tr
);
326 set_except_vector(11, handle_adedata
);
327 set_except_vector(12, handle_adedata
);
328 set_except_vector(13, handle_tlb_refill
);
329 set_except_vector(14, handle_tlb_invaild
);
330 set_except_vector(15, handle_mod
);
331 set_except_vector(16, handle_cee
);
332 set_except_vector(17, handle_cpe
);
333 set_except_vector(18, handle_dbe
);
334 flush_icache_range(DEBUG_VECTOR_BASE_ADDR
, IRQ_VECTOR_BASE_ADDR
);
336 atomic_inc(&init_mm
.mm_count
);
337 current
->active_mm
= &init_mm
;
This page took 0.038553 seconds and 5 git commands to generate.