aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m32r/kernel/traps.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2018-03-07 15:36:19 -0500
committerArnd Bergmann <arnd@arndb.de>2018-03-09 17:20:00 -0500
commit553b085c2075f6a4a2591108554f830fa61e881f (patch)
tree68d63911f2c12e0fb9fa23498df9300442a88f92 /arch/m32r/kernel/traps.c
parentfd8773f9f544955f6f47dc2ac3ab85ad64376b7f (diff)
arch: remove m32r port
The Mitsubishi/Renesas m32r architecture has been around for many years, but the Linux port has been obsolete for a very long time as well, with the last significant updates done for linux-2.6.14. While some m32r microcontrollers are still being marketed by Renesas, those are apparently no longer possible to support, mainly due to the lack of an external memory interface. Hirokazu Takata was the maintainer until the architecture got marked Orphaned in 2014. Link: http://www.linux-m32r.org/ Link: https://www.renesas.com/en-eu/products/microcontrollers-microprocessors/m32r.html Cc: Hirokazu Takata <takata@linux-m32r.org> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/m32r/kernel/traps.c')
-rw-r--r--arch/m32r/kernel/traps.c324
1 files changed, 0 insertions, 324 deletions
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
deleted file mode 100644
index a6f300a208bd..000000000000
--- a/arch/m32r/kernel/traps.c
+++ /dev/null
@@ -1,324 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * linux/arch/m32r/kernel/traps.c
4 *
5 * Copyright (C) 2001, 2002 Hirokazu Takata, Hiroyuki Kondo,
6 * Hitoshi Yamamoto
7 */
8
9/*
10 * 'traps.c' handles hardware traps and faults after we have saved some
11 * state in 'entry.S'.
12 */
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/kallsyms.h>
16#include <linux/stddef.h>
17#include <linux/ptrace.h>
18#include <linux/sched/debug.h>
19#include <linux/sched/task_stack.h>
20#include <linux/mm.h>
21#include <linux/cpu.h>
22
23#include <asm/page.h>
24#include <asm/processor.h>
25
26#include <linux/uaccess.h>
27#include <asm/io.h>
28#include <linux/atomic.h>
29
30#include <asm/smp.h>
31
32#include <linux/module.h>
33
34asmlinkage void alignment_check(void);
35asmlinkage void ei_handler(void);
36asmlinkage void rie_handler(void);
37asmlinkage void debug_trap(void);
38asmlinkage void cache_flushing_handler(void);
39asmlinkage void ill_trap(void);
40
41#ifdef CONFIG_SMP
42extern void smp_reschedule_interrupt(void);
43extern void smp_invalidate_interrupt(void);
44extern void smp_call_function_interrupt(void);
45extern void smp_ipi_timer_interrupt(void);
46extern void smp_flush_cache_all_interrupt(void);
47extern void smp_call_function_single_interrupt(void);
48
49/*
50 * for Boot AP function
51 */
52asm (
53 " .section .eit_vector4,\"ax\" \n"
54 " .global _AP_RE \n"
55 " .global startup_AP \n"
56 "_AP_RE: \n"
57 " .fill 32, 4, 0 \n"
58 "_AP_EI: bra startup_AP \n"
59 " .previous \n"
60);
61#endif /* CONFIG_SMP */
62
63extern unsigned long eit_vector[];
64#define BRA_INSN(func, entry) \
65 ((unsigned long)func - (unsigned long)eit_vector - entry*4)/4 \
66 + 0xff000000UL
67
68static void set_eit_vector_entries(void)
69{
70 extern void default_eit_handler(void);
71 extern void system_call(void);
72 extern void pie_handler(void);
73 extern void ace_handler(void);
74 extern void tme_handler(void);
75 extern void _flush_cache_copyback_all(void);
76
77 eit_vector[0] = 0xd0c00001; /* seth r0, 0x01 */
78 eit_vector[1] = BRA_INSN(default_eit_handler, 1);
79 eit_vector[4] = 0xd0c00010; /* seth r0, 0x10 */
80 eit_vector[5] = BRA_INSN(default_eit_handler, 5);
81 eit_vector[8] = BRA_INSN(rie_handler, 8);
82 eit_vector[12] = BRA_INSN(alignment_check, 12);
83 eit_vector[16] = BRA_INSN(ill_trap, 16);
84 eit_vector[17] = BRA_INSN(debug_trap, 17);
85 eit_vector[18] = BRA_INSN(system_call, 18);
86 eit_vector[19] = BRA_INSN(ill_trap, 19);
87 eit_vector[20] = BRA_INSN(ill_trap, 20);
88 eit_vector[21] = BRA_INSN(ill_trap, 21);
89 eit_vector[22] = BRA_INSN(ill_trap, 22);
90 eit_vector[23] = BRA_INSN(ill_trap, 23);
91 eit_vector[24] = BRA_INSN(ill_trap, 24);
92 eit_vector[25] = BRA_INSN(ill_trap, 25);
93 eit_vector[26] = BRA_INSN(ill_trap, 26);
94 eit_vector[27] = BRA_INSN(ill_trap, 27);
95 eit_vector[28] = BRA_INSN(cache_flushing_handler, 28);
96 eit_vector[29] = BRA_INSN(ill_trap, 29);
97 eit_vector[30] = BRA_INSN(ill_trap, 30);
98 eit_vector[31] = BRA_INSN(ill_trap, 31);
99 eit_vector[32] = BRA_INSN(ei_handler, 32);
100 eit_vector[64] = BRA_INSN(pie_handler, 64);
101#ifdef CONFIG_MMU
102 eit_vector[68] = BRA_INSN(ace_handler, 68);
103 eit_vector[72] = BRA_INSN(tme_handler, 72);
104#endif /* CONFIG_MMU */
105#ifdef CONFIG_SMP
106 eit_vector[184] = (unsigned long)smp_reschedule_interrupt;
107 eit_vector[185] = (unsigned long)smp_invalidate_interrupt;
108 eit_vector[186] = (unsigned long)smp_call_function_interrupt;
109 eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt;
110 eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt;
111 eit_vector[189] = 0; /* CPU_BOOT_IPI */
112 eit_vector[190] = (unsigned long)smp_call_function_single_interrupt;
113 eit_vector[191] = 0;
114#endif
115 _flush_cache_copyback_all();
116}
117
118void __init trap_init(void)
119{
120 set_eit_vector_entries();
121
122 /*
123 * Should be a barrier for any external CPU state.
124 */
125 cpu_init();
126}
127
128static int kstack_depth_to_print = 24;
129
130static void show_trace(struct task_struct *task, unsigned long *stack)
131{
132 unsigned long addr;
133
134 if (!stack)
135 stack = (unsigned long*)&stack;
136
137 printk("Call Trace: ");
138 while (!kstack_end(stack)) {
139 addr = *stack++;
140 if (__kernel_text_address(addr))
141 printk("[<%08lx>] %pSR\n", addr, (void *)addr);
142 }
143 printk("\n");
144}
145
146void show_stack(struct task_struct *task, unsigned long *sp)
147{
148 unsigned long *stack;
149 int i;
150
151 /*
152 * debugging aid: "show_stack(NULL);" prints the
153 * back trace for this cpu.
154 */
155
156 if(sp==NULL) {
157 if (task)
158 sp = (unsigned long *)task->thread.sp;
159 else
160 sp=(unsigned long*)&sp;
161 }
162
163 stack = sp;
164 for(i=0; i < kstack_depth_to_print; i++) {
165 if (kstack_end(stack))
166 break;
167 if (i && ((i % 4) == 0))
168 printk("\n ");
169 printk("%08lx ", *stack++);
170 }
171 printk("\n");
172 show_trace(task, sp);
173}
174
175static void show_registers(struct pt_regs *regs)
176{
177 int i = 0;
178 int in_kernel = 1;
179 unsigned long sp;
180
181 printk("CPU: %d\n", smp_processor_id());
182 show_regs(regs);
183
184 sp = (unsigned long) (1+regs);
185 if (user_mode(regs)) {
186 in_kernel = 0;
187 sp = regs->spu;
188 printk("SPU: %08lx\n", sp);
189 } else {
190 printk("SPI: %08lx\n", sp);
191 }
192 printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
193 current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
194
195 /*
196 * When in-kernel, we also print out the stack and code at the
197 * time of the fault..
198 */
199 if (in_kernel) {
200 printk("\nStack: ");
201 show_stack(current, (unsigned long*) sp);
202
203 printk("\nCode: ");
204 if (regs->bpc < PAGE_OFFSET)
205 goto bad;
206
207 for(i=0;i<20;i++) {
208 unsigned char c;
209 if (__get_user(c, &((unsigned char*)regs->bpc)[i])) {
210bad:
211 printk(" Bad PC value.");
212 break;
213 }
214 printk("%02x ", c);
215 }
216 }
217 printk("\n");
218}
219
220static DEFINE_SPINLOCK(die_lock);
221
222void die(const char * str, struct pt_regs * regs, long err)
223{
224 console_verbose();
225 spin_lock_irq(&die_lock);
226 bust_spinlocks(1);
227 printk("%s: %04lx\n", str, err & 0xffff);
228 show_registers(regs);
229 bust_spinlocks(0);
230 spin_unlock_irq(&die_lock);
231 do_exit(SIGSEGV);
232}
233
234static __inline__ void die_if_kernel(const char * str,
235 struct pt_regs * regs, long err)
236{
237 if (!user_mode(regs))
238 die(str, regs, err);
239}
240
241static __inline__ void do_trap(int trapnr, int signr, const char * str,
242 struct pt_regs * regs, long error_code, siginfo_t *info)
243{
244 if (user_mode(regs)) {
245 /* trap_signal */
246 struct task_struct *tsk = current;
247 tsk->thread.error_code = error_code;
248 tsk->thread.trap_no = trapnr;
249 if (info)
250 force_sig_info(signr, info, tsk);
251 else
252 force_sig(signr, tsk);
253 return;
254 } else {
255 /* kernel_trap */
256 if (!fixup_exception(regs))
257 die(str, regs, error_code);
258 return;
259 }
260}
261
262#define DO_ERROR(trapnr, signr, str, name) \
263asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
264{ \
265 do_trap(trapnr, signr, NULL, regs, error_code, NULL); \
266}
267
268#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
269asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
270{ \
271 siginfo_t info; \
272 info.si_signo = signr; \
273 info.si_errno = 0; \
274 info.si_code = sicode; \
275 info.si_addr = (void __user *)siaddr; \
276 do_trap(trapnr, signr, str, regs, error_code, &info); \
277}
278
279DO_ERROR( 1, SIGTRAP, "debug trap", debug_trap)
280DO_ERROR_INFO(0x20, SIGILL, "reserved instruction ", rie_handler, ILL_ILLOPC, regs->bpc)
281DO_ERROR_INFO(0x100, SIGILL, "privileged instruction", pie_handler, ILL_PRVOPC, regs->bpc)
282DO_ERROR_INFO(-1, SIGILL, "illegal trap", ill_trap, ILL_ILLTRP, regs->bpc)
283
284extern int handle_unaligned_access(unsigned long, struct pt_regs *);
285
286/* This code taken from arch/sh/kernel/traps.c */
287asmlinkage void do_alignment_check(struct pt_regs *regs, long error_code)
288{
289 mm_segment_t oldfs;
290 unsigned long insn;
291 int tmp;
292
293 oldfs = get_fs();
294
295 if (user_mode(regs)) {
296 local_irq_enable();
297 current->thread.error_code = error_code;
298 current->thread.trap_no = 0x17;
299
300 set_fs(USER_DS);
301 if (copy_from_user(&insn, (void *)regs->bpc, 4)) {
302 set_fs(oldfs);
303 goto uspace_segv;
304 }
305 tmp = handle_unaligned_access(insn, regs);
306 set_fs(oldfs);
307
308 if (!tmp)
309 return;
310
311 uspace_segv:
312 printk(KERN_NOTICE "Killing process \"%s\" due to unaligned "
313 "access\n", current->comm);
314 force_sig(SIGSEGV, current);
315 } else {
316 set_fs(KERNEL_DS);
317 if (copy_from_user(&insn, (void *)regs->bpc, 4)) {
318 set_fs(oldfs);
319 die("insn faulting in do_address_error", regs, 0);
320 }
321 handle_unaligned_access(insn, regs);
322 set_fs(oldfs);
323 }
324}