aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile7
-rw-r--r--arch/sh/kernel/cpu/Makefile2
-rw-r--r--arch/sh/kernel/cpu/fpu.c82
-rw-r--r--arch/sh/kernel/cpu/init.c98
-rw-r--r--arch/sh/kernel/cpu/sh2a/fpu.c111
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S2
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c159
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile9
-rw-r--r--arch/sh/kernel/cpu/sh4a/ubc.c133
-rw-r--r--arch/sh/kernel/debugtraps.S1
-rw-r--r--arch/sh/kernel/early_printk.c85
-rw-r--r--arch/sh/kernel/head_64.S2
-rw-r--r--arch/sh/kernel/hw_breakpoint.c463
-rw-r--r--arch/sh/kernel/kgdb.c46
-rw-r--r--arch/sh/kernel/machine_kexec.c8
-rw-r--r--arch/sh/kernel/process.c100
-rw-r--r--arch/sh/kernel/process_32.c114
-rw-r--r--arch/sh/kernel/ptrace_32.c82
-rw-r--r--arch/sh/kernel/sh_bios.c129
-rw-r--r--arch/sh/kernel/signal_32.c4
-rw-r--r--arch/sh/kernel/traps_32.c182
21 files changed, 1176 insertions, 643 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 0d587da1ef12..56704a6d723a 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -13,8 +13,8 @@ CFLAGS_REMOVE_return_address.o = -pg
13 13
14obj-y := debugtraps.o dma-nommu.o dumpstack.o \ 14obj-y := debugtraps.o dma-nommu.o dumpstack.o \
15 idle.o io.o io_generic.o irq.o \ 15 idle.o io.o io_generic.o irq.o \
16 irq_$(BITS).o machvec.o nmi_debug.o process_$(BITS).o \ 16 irq_$(BITS).o machvec.o nmi_debug.o process.o \
17 ptrace_$(BITS).o return_address.o \ 17 process_$(BITS).o ptrace_$(BITS).o return_address.o \
18 setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \ 18 setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \
19 syscalls_$(BITS).o time.o topology.o traps.o \ 19 syscalls_$(BITS).o time.o topology.o traps.o \
20 traps_$(BITS).o unwinder.o 20 traps_$(BITS).o unwinder.o
@@ -22,7 +22,7 @@ obj-y := debugtraps.o dma-nommu.o dumpstack.o \
22obj-y += cpu/ 22obj-y += cpu/
23obj-$(CONFIG_VSYSCALL) += vsyscall/ 23obj-$(CONFIG_VSYSCALL) += vsyscall/
24obj-$(CONFIG_SMP) += smp.o 24obj-$(CONFIG_SMP) += smp.o
25obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o early_printk.o 25obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
26obj-$(CONFIG_KGDB) += kgdb.o 26obj-$(CONFIG_KGDB) += kgdb.o
27obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o 27obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
28obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o 28obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o
@@ -39,6 +39,7 @@ obj-$(CONFIG_HIBERNATION) += swsusp.o
39obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o 39obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
40obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o 40obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
41 41
42obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
42obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o 43obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
43 44
44EXTRA_CFLAGS += -Werror 45EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index d97c803719ec..0e48bc61c272 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -17,5 +17,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
17 17
18obj-$(CONFIG_SH_ADC) += adc.o 18obj-$(CONFIG_SH_ADC) += adc.o
19obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o 19obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o
20obj-$(CONFIG_SH_FPU) += fpu.o
21obj-$(CONFIG_SH_FPU_EMU) += fpu.o
20 22
21obj-y += irq/ init.o clock.o hwblk.o 23obj-y += irq/ init.o clock.o hwblk.o
diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c
new file mode 100644
index 000000000000..c23e6727002a
--- /dev/null
+++ b/arch/sh/kernel/cpu/fpu.c
@@ -0,0 +1,82 @@
1#include <linux/sched.h>
2#include <asm/processor.h>
3#include <asm/fpu.h>
4
5int init_fpu(struct task_struct *tsk)
6{
7 if (tsk_used_math(tsk)) {
8 if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
9 unlazy_fpu(tsk, task_pt_regs(tsk));
10 return 0;
11 }
12
13 /*
14 * Memory allocation at the first usage of the FPU and other state.
15 */
16 if (!tsk->thread.xstate) {
17 tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
18 GFP_KERNEL);
19 if (!tsk->thread.xstate)
20 return -ENOMEM;
21 }
22
23 if (boot_cpu_data.flags & CPU_HAS_FPU) {
24 struct sh_fpu_hard_struct *fp = &tsk->thread.xstate->hardfpu;
25 memset(fp, 0, xstate_size);
26 fp->fpscr = FPSCR_INIT;
27 } else {
28 struct sh_fpu_soft_struct *fp = &tsk->thread.xstate->softfpu;
29 memset(fp, 0, xstate_size);
30 fp->fpscr = FPSCR_INIT;
31 }
32
33 set_stopped_child_used_math(tsk);
34 return 0;
35}
36
37#ifdef CONFIG_SH_FPU
38void __fpu_state_restore(void)
39{
40 struct task_struct *tsk = current;
41
42 restore_fpu(tsk);
43
44 task_thread_info(tsk)->status |= TS_USEDFPU;
45 tsk->fpu_counter++;
46}
47
48void fpu_state_restore(struct pt_regs *regs)
49{
50 struct task_struct *tsk = current;
51
52 if (unlikely(!user_mode(regs))) {
53 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
54 BUG();
55 return;
56 }
57
58 if (!tsk_used_math(tsk)) {
59 /*
60 * does a slab alloc which can sleep
61 */
62 if (init_fpu(tsk)) {
63 /*
64 * ran out of memory!
65 */
66 do_group_exit(SIGKILL);
67 return;
68 }
69 }
70
71 grab_fpu(regs);
72
73 __fpu_state_restore();
74}
75
76BUILD_TRAP_HANDLER(fpu_state_restore)
77{
78 TRAP_HANDLER_DECL;
79
80 fpu_state_restore(regs);
81}
82#endif /* CONFIG_SH_FPU */
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 89b4b76c0d76..a5bb0550bbf3 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -24,22 +24,31 @@
24#include <asm/elf.h> 24#include <asm/elf.h>
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/smp.h> 26#include <asm/smp.h>
27#ifdef CONFIG_SUPERH32 27
28#include <asm/ubc.h> 28#ifdef CONFIG_SH_FPU
29#define cpu_has_fpu 1
30#else
31#define cpu_has_fpu 0
32#endif
33
34#ifdef CONFIG_SH_DSP
35#define cpu_has_dsp 1
36#else
37#define cpu_has_dsp 0
29#endif 38#endif
30 39
31/* 40/*
32 * Generic wrapper for command line arguments to disable on-chip 41 * Generic wrapper for command line arguments to disable on-chip
33 * peripherals (nofpu, nodsp, and so forth). 42 * peripherals (nofpu, nodsp, and so forth).
34 */ 43 */
35#define onchip_setup(x) \ 44#define onchip_setup(x) \
36static int x##_disabled __initdata = 0; \ 45static int x##_disabled __initdata = !cpu_has_##x; \
37 \ 46 \
38static int __init x##_setup(char *opts) \ 47static int __init x##_setup(char *opts) \
39{ \ 48{ \
40 x##_disabled = 1; \ 49 x##_disabled = 1; \
41 return 1; \ 50 return 1; \
42} \ 51} \
43__setup("no" __stringify(x), x##_setup); 52__setup("no" __stringify(x), x##_setup);
44 53
45onchip_setup(fpu); 54onchip_setup(fpu);
@@ -207,6 +216,18 @@ static void detect_cache_shape(void)
207 l2_cache_shape = -1; /* No S-cache */ 216 l2_cache_shape = -1; /* No S-cache */
208} 217}
209 218
219static void __init fpu_init(void)
220{
221 /* Disable the FPU */
222 if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) {
223 printk("FPU Disabled\n");
224 current_cpu_data.flags &= ~CPU_HAS_FPU;
225 }
226
227 disable_fpu();
228 clear_used_math();
229}
230
210#ifdef CONFIG_SH_DSP 231#ifdef CONFIG_SH_DSP
211static void __init release_dsp(void) 232static void __init release_dsp(void)
212{ 233{
@@ -244,28 +265,35 @@ static void __init dsp_init(void)
244 if (sr & SR_DSP) 265 if (sr & SR_DSP)
245 current_cpu_data.flags |= CPU_HAS_DSP; 266 current_cpu_data.flags |= CPU_HAS_DSP;
246 267
268 /* Disable the DSP */
269 if (dsp_disabled && (current_cpu_data.flags & CPU_HAS_DSP)) {
270 printk("DSP Disabled\n");
271 current_cpu_data.flags &= ~CPU_HAS_DSP;
272 }
273
247 /* Now that we've determined the DSP status, clear the DSP bit. */ 274 /* Now that we've determined the DSP status, clear the DSP bit. */
248 release_dsp(); 275 release_dsp();
249} 276}
277#else
278static inline void __init dsp_init(void) { }
250#endif /* CONFIG_SH_DSP */ 279#endif /* CONFIG_SH_DSP */
251 280
252/** 281/**
253 * sh_cpu_init 282 * sh_cpu_init
254 * 283 *
255 * This is our initial entry point for each CPU, and is invoked on the boot 284 * This is our initial entry point for each CPU, and is invoked on the
256 * CPU prior to calling start_kernel(). For SMP, a combination of this and 285 * boot CPU prior to calling start_kernel(). For SMP, a combination of
257 * start_secondary() will bring up each processor to a ready state prior 286 * this and start_secondary() will bring up each processor to a ready
258 * to hand forking the idle loop. 287 * state prior to hand forking the idle loop.
259 * 288 *
260 * We do all of the basic processor init here, including setting up the 289 * We do all of the basic processor init here, including setting up
261 * caches, FPU, DSP, kicking the UBC, etc. By the time start_kernel() is 290 * the caches, FPU, DSP, etc. By the time start_kernel() is hit (and
262 * hit (and subsequently platform_setup()) things like determining the 291 * subsequently platform_setup()) things like determining the CPU
263 * CPU subtype and initial configuration will all be done. 292 * subtype and initial configuration will all be done.
264 * 293 *
265 * Each processor family is still responsible for doing its own probing 294 * Each processor family is still responsible for doing its own probing
266 * and cache configuration in detect_cpu_and_cache_system(). 295 * and cache configuration in detect_cpu_and_cache_system().
267 */ 296 */
268
269asmlinkage void __init sh_cpu_init(void) 297asmlinkage void __init sh_cpu_init(void)
270{ 298{
271 current_thread_info()->cpu = hard_smp_processor_id(); 299 current_thread_info()->cpu = hard_smp_processor_id();
@@ -302,18 +330,8 @@ asmlinkage void __init sh_cpu_init(void)
302 detect_cache_shape(); 330 detect_cache_shape();
303 } 331 }
304 332
305 /* Disable the FPU */ 333 fpu_init();
306 if (fpu_disabled) { 334 dsp_init();
307 printk("FPU Disabled\n");
308 current_cpu_data.flags &= ~CPU_HAS_FPU;
309 }
310
311 /* FPU initialization */
312 disable_fpu();
313 if ((current_cpu_data.flags & CPU_HAS_FPU)) {
314 current_thread_info()->status &= ~TS_USEDFPU;
315 clear_used_math();
316 }
317 335
318 /* 336 /*
319 * Initialize the per-CPU ASID cache very early, since the 337 * Initialize the per-CPU ASID cache very early, since the
@@ -321,18 +339,12 @@ asmlinkage void __init sh_cpu_init(void)
321 */ 339 */
322 current_cpu_data.asid_cache = NO_CONTEXT; 340 current_cpu_data.asid_cache = NO_CONTEXT;
323 341
324#ifdef CONFIG_SH_DSP
325 /* Probe for DSP */
326 dsp_init();
327
328 /* Disable the DSP */
329 if (dsp_disabled) {
330 printk("DSP Disabled\n");
331 current_cpu_data.flags &= ~CPU_HAS_DSP;
332 release_dsp();
333 }
334#endif
335
336 speculative_execution_init(); 342 speculative_execution_init();
337 expmask_init(); 343 expmask_init();
344
345 /*
346 * Boot processor to setup the FP and extended state context info.
347 */
348 if (raw_smp_processor_id() == 0)
349 init_thread_xstate();
338} 350}
diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c
index d395ce5740e7..488d24e0cdf0 100644
--- a/arch/sh/kernel/cpu/sh2a/fpu.c
+++ b/arch/sh/kernel/cpu/sh2a/fpu.c
@@ -26,8 +26,7 @@
26/* 26/*
27 * Save FPU registers onto task structure. 27 * Save FPU registers onto task structure.
28 */ 28 */
29void 29void save_fpu(struct task_struct *tsk)
30save_fpu(struct task_struct *tsk)
31{ 30{
32 unsigned long dummy; 31 unsigned long dummy;
33 32
@@ -52,7 +51,7 @@ save_fpu(struct task_struct *tsk)
52 "fmov.s fr0, @-%0\n\t" 51 "fmov.s fr0, @-%0\n\t"
53 "lds %3, fpscr\n\t" 52 "lds %3, fpscr\n\t"
54 : "=r" (dummy) 53 : "=r" (dummy)
55 : "0" ((char *)(&tsk->thread.fpu.hard.status)), 54 : "0" ((char *)(&tsk->thread.xstate->hardfpu.status)),
56 "r" (FPSCR_RCHG), 55 "r" (FPSCR_RCHG),
57 "r" (FPSCR_INIT) 56 "r" (FPSCR_INIT)
58 : "memory"); 57 : "memory");
@@ -60,8 +59,7 @@ save_fpu(struct task_struct *tsk)
60 disable_fpu(); 59 disable_fpu();
61} 60}
62 61
63static void 62void restore_fpu(struct task_struct *tsk)
64restore_fpu(struct task_struct *tsk)
65{ 63{
66 unsigned long dummy; 64 unsigned long dummy;
67 65
@@ -85,45 +83,12 @@ restore_fpu(struct task_struct *tsk)
85 "lds.l @%0+, fpscr\n\t" 83 "lds.l @%0+, fpscr\n\t"
86 "lds.l @%0+, fpul\n\t" 84 "lds.l @%0+, fpul\n\t"
87 : "=r" (dummy) 85 : "=r" (dummy)
88 : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG) 86 : "0" (tsk->thread.xstate), "r" (FPSCR_RCHG)
89 : "memory"); 87 : "memory");
90 disable_fpu(); 88 disable_fpu();
91} 89}
92 90
93/* 91/*
94 * Load the FPU with signalling NANS. This bit pattern we're using
95 * has the property that no matter wether considered as single or as
96 * double precission represents signaling NANS.
97 */
98
99static void
100fpu_init(void)
101{
102 enable_fpu();
103 asm volatile("lds %0, fpul\n\t"
104 "fsts fpul, fr0\n\t"
105 "fsts fpul, fr1\n\t"
106 "fsts fpul, fr2\n\t"
107 "fsts fpul, fr3\n\t"
108 "fsts fpul, fr4\n\t"
109 "fsts fpul, fr5\n\t"
110 "fsts fpul, fr6\n\t"
111 "fsts fpul, fr7\n\t"
112 "fsts fpul, fr8\n\t"
113 "fsts fpul, fr9\n\t"
114 "fsts fpul, fr10\n\t"
115 "fsts fpul, fr11\n\t"
116 "fsts fpul, fr12\n\t"
117 "fsts fpul, fr13\n\t"
118 "fsts fpul, fr14\n\t"
119 "fsts fpul, fr15\n\t"
120 "lds %2, fpscr\n\t"
121 : /* no output */
122 : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
123 disable_fpu();
124}
125
126/*
127 * Emulate arithmetic ops on denormalized number for some FPU insns. 92 * Emulate arithmetic ops on denormalized number for some FPU insns.
128 */ 93 */
129 94
@@ -490,9 +455,9 @@ ieee_fpe_handler (struct pt_regs *regs)
490 if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ 455 if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
491 struct task_struct *tsk = current; 456 struct task_struct *tsk = current;
492 457
493 if ((tsk->thread.fpu.hard.fpscr & FPSCR_FPU_ERROR)) { 458 if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_FPU_ERROR)) {
494 /* FPU error */ 459 /* FPU error */
495 denormal_to_double (&tsk->thread.fpu.hard, 460 denormal_to_double (&tsk->thread.xstate->hardfpu,
496 (finsn >> 8) & 0xf); 461 (finsn >> 8) & 0xf);
497 } else 462 } else
498 return 0; 463 return 0;
@@ -507,9 +472,9 @@ ieee_fpe_handler (struct pt_regs *regs)
507 472
508 n = (finsn >> 8) & 0xf; 473 n = (finsn >> 8) & 0xf;
509 m = (finsn >> 4) & 0xf; 474 m = (finsn >> 4) & 0xf;
510 hx = tsk->thread.fpu.hard.fp_regs[n]; 475 hx = tsk->thread.xstate->hardfpu.fp_regs[n];
511 hy = tsk->thread.fpu.hard.fp_regs[m]; 476 hy = tsk->thread.xstate->hardfpu.fp_regs[m];
512 fpscr = tsk->thread.fpu.hard.fpscr; 477 fpscr = tsk->thread.xstate->hardfpu.fpscr;
513 prec = fpscr & (1 << 19); 478 prec = fpscr & (1 << 19);
514 479
515 if ((fpscr & FPSCR_FPU_ERROR) 480 if ((fpscr & FPSCR_FPU_ERROR)
@@ -519,15 +484,15 @@ ieee_fpe_handler (struct pt_regs *regs)
519 484
520 /* FPU error because of denormal */ 485 /* FPU error because of denormal */
521 llx = ((long long) hx << 32) 486 llx = ((long long) hx << 32)
522 | tsk->thread.fpu.hard.fp_regs[n+1]; 487 | tsk->thread.xstate->hardfpu.fp_regs[n+1];
523 lly = ((long long) hy << 32) 488 lly = ((long long) hy << 32)
524 | tsk->thread.fpu.hard.fp_regs[m+1]; 489 | tsk->thread.xstate->hardfpu.fp_regs[m+1];
525 if ((hx & 0x7fffffff) >= 0x00100000) 490 if ((hx & 0x7fffffff) >= 0x00100000)
526 llx = denormal_muld(lly, llx); 491 llx = denormal_muld(lly, llx);
527 else 492 else
528 llx = denormal_muld(llx, lly); 493 llx = denormal_muld(llx, lly);
529 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; 494 tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
530 tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff; 495 tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff;
531 } else if ((fpscr & FPSCR_FPU_ERROR) 496 } else if ((fpscr & FPSCR_FPU_ERROR)
532 && (!prec && ((hx & 0x7fffffff) < 0x00800000 497 && (!prec && ((hx & 0x7fffffff) < 0x00800000
533 || (hy & 0x7fffffff) < 0x00800000))) { 498 || (hy & 0x7fffffff) < 0x00800000))) {
@@ -536,7 +501,7 @@ ieee_fpe_handler (struct pt_regs *regs)
536 hx = denormal_mulf(hy, hx); 501 hx = denormal_mulf(hy, hx);
537 else 502 else
538 hx = denormal_mulf(hx, hy); 503 hx = denormal_mulf(hx, hy);
539 tsk->thread.fpu.hard.fp_regs[n] = hx; 504 tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
540 } else 505 } else
541 return 0; 506 return 0;
542 507
@@ -550,9 +515,9 @@ ieee_fpe_handler (struct pt_regs *regs)
550 515
551 n = (finsn >> 8) & 0xf; 516 n = (finsn >> 8) & 0xf;
552 m = (finsn >> 4) & 0xf; 517 m = (finsn >> 4) & 0xf;
553 hx = tsk->thread.fpu.hard.fp_regs[n]; 518 hx = tsk->thread.xstate->hardfpu.fp_regs[n];
554 hy = tsk->thread.fpu.hard.fp_regs[m]; 519 hy = tsk->thread.xstate->hardfpu.fp_regs[m];
555 fpscr = tsk->thread.fpu.hard.fpscr; 520 fpscr = tsk->thread.xstate->hardfpu.fpscr;
556 prec = fpscr & (1 << 19); 521 prec = fpscr & (1 << 19);
557 522
558 if ((fpscr & FPSCR_FPU_ERROR) 523 if ((fpscr & FPSCR_FPU_ERROR)
@@ -562,15 +527,15 @@ ieee_fpe_handler (struct pt_regs *regs)
562 527
563 /* FPU error because of denormal */ 528 /* FPU error because of denormal */
564 llx = ((long long) hx << 32) 529 llx = ((long long) hx << 32)
565 | tsk->thread.fpu.hard.fp_regs[n+1]; 530 | tsk->thread.xstate->hardfpu.fp_regs[n+1];
566 lly = ((long long) hy << 32) 531 lly = ((long long) hy << 32)
567 | tsk->thread.fpu.hard.fp_regs[m+1]; 532 | tsk->thread.xstate->hardfpu.fp_regs[m+1];
568 if ((finsn & 0xf00f) == 0xf000) 533 if ((finsn & 0xf00f) == 0xf000)
569 llx = denormal_addd(llx, lly); 534 llx = denormal_addd(llx, lly);
570 else 535 else
571 llx = denormal_addd(llx, lly ^ (1LL << 63)); 536 llx = denormal_addd(llx, lly ^ (1LL << 63));
572 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; 537 tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
573 tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff; 538 tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff;
574 } else if ((fpscr & FPSCR_FPU_ERROR) 539 } else if ((fpscr & FPSCR_FPU_ERROR)
575 && (!prec && ((hx & 0x7fffffff) < 0x00800000 540 && (!prec && ((hx & 0x7fffffff) < 0x00800000
576 || (hy & 0x7fffffff) < 0x00800000))) { 541 || (hy & 0x7fffffff) < 0x00800000))) {
@@ -579,7 +544,7 @@ ieee_fpe_handler (struct pt_regs *regs)
579 hx = denormal_addf(hx, hy); 544 hx = denormal_addf(hx, hy);
580 else 545 else
581 hx = denormal_addf(hx, hy ^ 0x80000000); 546 hx = denormal_addf(hx, hy ^ 0x80000000);
582 tsk->thread.fpu.hard.fp_regs[n] = hx; 547 tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
583 } else 548 } else
584 return 0; 549 return 0;
585 550
@@ -597,7 +562,7 @@ BUILD_TRAP_HANDLER(fpu_error)
597 562
598 __unlazy_fpu(tsk, regs); 563 __unlazy_fpu(tsk, regs);
599 if (ieee_fpe_handler(regs)) { 564 if (ieee_fpe_handler(regs)) {
600 tsk->thread.fpu.hard.fpscr &= 565 tsk->thread.xstate->hardfpu.fpscr &=
601 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); 566 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
602 grab_fpu(regs); 567 grab_fpu(regs);
603 restore_fpu(tsk); 568 restore_fpu(tsk);
@@ -607,33 +572,3 @@ BUILD_TRAP_HANDLER(fpu_error)
607 572
608 force_sig(SIGFPE, tsk); 573 force_sig(SIGFPE, tsk);
609} 574}
610
611void fpu_state_restore(struct pt_regs *regs)
612{
613 struct task_struct *tsk = current;
614
615 grab_fpu(regs);
616 if (unlikely(!user_mode(regs))) {
617 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
618 BUG();
619 return;
620 }
621
622 if (likely(used_math())) {
623 /* Using the FPU again. */
624 restore_fpu(tsk);
625 } else {
626 /* First time FPU user. */
627 fpu_init();
628 set_used_math();
629 }
630 task_thread_info(tsk)->status |= TS_USEDFPU;
631 tsk->fpu_counter++;
632}
633
634BUILD_TRAP_HANDLER(fpu_state_restore)
635{
636 TRAP_HANDLER_DECL;
637
638 fpu_state_restore(regs);
639}
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index 46610c35c232..99b4d020179a 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -49,7 +49,7 @@ ENTRY(exception_handling_table)
49 .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ 49 .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
50 .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ 50 .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
51 .long nmi_trap_handler /* 1C0 */ ! Allow trap to debugger 51 .long nmi_trap_handler /* 1C0 */ ! Allow trap to debugger
52 .long break_point_trap /* 1E0 */ 52 .long breakpoint_trap_handler /* 1E0 */
53 53
54 /* 54 /*
55 * Pad the remainder of the table out, exceptions residing in far 55 * Pad the remainder of the table out, exceptions residing in far
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index e97857aec8a0..447482d7f65e 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -85,14 +85,14 @@ void save_fpu(struct task_struct *tsk)
85 "fmov.s fr1, @-%0\n\t" 85 "fmov.s fr1, @-%0\n\t"
86 "fmov.s fr0, @-%0\n\t" 86 "fmov.s fr0, @-%0\n\t"
87 "lds %3, fpscr\n\t":"=r" (dummy) 87 "lds %3, fpscr\n\t":"=r" (dummy)
88 :"0"((char *)(&tsk->thread.fpu.hard.status)), 88 :"0"((char *)(&tsk->thread.xstate->hardfpu.status)),
89 "r"(FPSCR_RCHG), "r"(FPSCR_INIT) 89 "r"(FPSCR_RCHG), "r"(FPSCR_INIT)
90 :"memory"); 90 :"memory");
91 91
92 disable_fpu(); 92 disable_fpu();
93} 93}
94 94
95static void restore_fpu(struct task_struct *tsk) 95void restore_fpu(struct task_struct *tsk)
96{ 96{
97 unsigned long dummy; 97 unsigned long dummy;
98 98
@@ -135,62 +135,11 @@ static void restore_fpu(struct task_struct *tsk)
135 "lds.l @%0+, fpscr\n\t" 135 "lds.l @%0+, fpscr\n\t"
136 "lds.l @%0+, fpul\n\t" 136 "lds.l @%0+, fpul\n\t"
137 :"=r" (dummy) 137 :"=r" (dummy)
138 :"0"(&tsk->thread.fpu), "r"(FPSCR_RCHG) 138 :"0" (tsk->thread.xstate), "r" (FPSCR_RCHG)
139 :"memory"); 139 :"memory");
140 disable_fpu(); 140 disable_fpu();
141} 141}
142 142
143/*
144 * Load the FPU with signalling NANS. This bit pattern we're using
145 * has the property that no matter wether considered as single or as
146 * double precision represents signaling NANS.
147 */
148
149static void fpu_init(void)
150{
151 enable_fpu();
152 asm volatile ( "lds %0, fpul\n\t"
153 "lds %1, fpscr\n\t"
154 "fsts fpul, fr0\n\t"
155 "fsts fpul, fr1\n\t"
156 "fsts fpul, fr2\n\t"
157 "fsts fpul, fr3\n\t"
158 "fsts fpul, fr4\n\t"
159 "fsts fpul, fr5\n\t"
160 "fsts fpul, fr6\n\t"
161 "fsts fpul, fr7\n\t"
162 "fsts fpul, fr8\n\t"
163 "fsts fpul, fr9\n\t"
164 "fsts fpul, fr10\n\t"
165 "fsts fpul, fr11\n\t"
166 "fsts fpul, fr12\n\t"
167 "fsts fpul, fr13\n\t"
168 "fsts fpul, fr14\n\t"
169 "fsts fpul, fr15\n\t"
170 "frchg\n\t"
171 "fsts fpul, fr0\n\t"
172 "fsts fpul, fr1\n\t"
173 "fsts fpul, fr2\n\t"
174 "fsts fpul, fr3\n\t"
175 "fsts fpul, fr4\n\t"
176 "fsts fpul, fr5\n\t"
177 "fsts fpul, fr6\n\t"
178 "fsts fpul, fr7\n\t"
179 "fsts fpul, fr8\n\t"
180 "fsts fpul, fr9\n\t"
181 "fsts fpul, fr10\n\t"
182 "fsts fpul, fr11\n\t"
183 "fsts fpul, fr12\n\t"
184 "fsts fpul, fr13\n\t"
185 "fsts fpul, fr14\n\t"
186 "fsts fpul, fr15\n\t"
187 "frchg\n\t"
188 "lds %2, fpscr\n\t"
189 : /* no output */
190 :"r" (0), "r"(FPSCR_RCHG), "r"(FPSCR_INIT));
191 disable_fpu();
192}
193
194/** 143/**
195 * denormal_to_double - Given denormalized float number, 144 * denormal_to_double - Given denormalized float number,
196 * store double float 145 * store double float
@@ -282,9 +231,9 @@ static int ieee_fpe_handler(struct pt_regs *regs)
282 /* fcnvsd */ 231 /* fcnvsd */
283 struct task_struct *tsk = current; 232 struct task_struct *tsk = current;
284 233
285 if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)) 234 if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR))
286 /* FPU error */ 235 /* FPU error */
287 denormal_to_double(&tsk->thread.fpu.hard, 236 denormal_to_double(&tsk->thread.xstate->hardfpu,
288 (finsn >> 8) & 0xf); 237 (finsn >> 8) & 0xf);
289 else 238 else
290 return 0; 239 return 0;
@@ -300,9 +249,9 @@ static int ieee_fpe_handler(struct pt_regs *regs)
300 249
301 n = (finsn >> 8) & 0xf; 250 n = (finsn >> 8) & 0xf;
302 m = (finsn >> 4) & 0xf; 251 m = (finsn >> 4) & 0xf;
303 hx = tsk->thread.fpu.hard.fp_regs[n]; 252 hx = tsk->thread.xstate->hardfpu.fp_regs[n];
304 hy = tsk->thread.fpu.hard.fp_regs[m]; 253 hy = tsk->thread.xstate->hardfpu.fp_regs[m];
305 fpscr = tsk->thread.fpu.hard.fpscr; 254 fpscr = tsk->thread.xstate->hardfpu.fpscr;
306 prec = fpscr & FPSCR_DBL_PRECISION; 255 prec = fpscr & FPSCR_DBL_PRECISION;
307 256
308 if ((fpscr & FPSCR_CAUSE_ERROR) 257 if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -312,18 +261,18 @@ static int ieee_fpe_handler(struct pt_regs *regs)
312 261
313 /* FPU error because of denormal (doubles) */ 262 /* FPU error because of denormal (doubles) */
314 llx = ((long long)hx << 32) 263 llx = ((long long)hx << 32)
315 | tsk->thread.fpu.hard.fp_regs[n + 1]; 264 | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
316 lly = ((long long)hy << 32) 265 lly = ((long long)hy << 32)
317 | tsk->thread.fpu.hard.fp_regs[m + 1]; 266 | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
318 llx = float64_mul(llx, lly); 267 llx = float64_mul(llx, lly);
319 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; 268 tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
320 tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; 269 tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
321 } else if ((fpscr & FPSCR_CAUSE_ERROR) 270 } else if ((fpscr & FPSCR_CAUSE_ERROR)
322 && (!prec && ((hx & 0x7fffffff) < 0x00800000 271 && (!prec && ((hx & 0x7fffffff) < 0x00800000
323 || (hy & 0x7fffffff) < 0x00800000))) { 272 || (hy & 0x7fffffff) < 0x00800000))) {
324 /* FPU error because of denormal (floats) */ 273 /* FPU error because of denormal (floats) */
325 hx = float32_mul(hx, hy); 274 hx = float32_mul(hx, hy);
326 tsk->thread.fpu.hard.fp_regs[n] = hx; 275 tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
327 } else 276 } else
328 return 0; 277 return 0;
329 278
@@ -338,9 +287,9 @@ static int ieee_fpe_handler(struct pt_regs *regs)
338 287
339 n = (finsn >> 8) & 0xf; 288 n = (finsn >> 8) & 0xf;
340 m = (finsn >> 4) & 0xf; 289 m = (finsn >> 4) & 0xf;
341 hx = tsk->thread.fpu.hard.fp_regs[n]; 290 hx = tsk->thread.xstate->hardfpu.fp_regs[n];
342 hy = tsk->thread.fpu.hard.fp_regs[m]; 291 hy = tsk->thread.xstate->hardfpu.fp_regs[m];
343 fpscr = tsk->thread.fpu.hard.fpscr; 292 fpscr = tsk->thread.xstate->hardfpu.fpscr;
344 prec = fpscr & FPSCR_DBL_PRECISION; 293 prec = fpscr & FPSCR_DBL_PRECISION;
345 294
346 if ((fpscr & FPSCR_CAUSE_ERROR) 295 if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -350,15 +299,15 @@ static int ieee_fpe_handler(struct pt_regs *regs)
350 299
351 /* FPU error because of denormal (doubles) */ 300 /* FPU error because of denormal (doubles) */
352 llx = ((long long)hx << 32) 301 llx = ((long long)hx << 32)
353 | tsk->thread.fpu.hard.fp_regs[n + 1]; 302 | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
354 lly = ((long long)hy << 32) 303 lly = ((long long)hy << 32)
355 | tsk->thread.fpu.hard.fp_regs[m + 1]; 304 | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
356 if ((finsn & 0xf00f) == 0xf000) 305 if ((finsn & 0xf00f) == 0xf000)
357 llx = float64_add(llx, lly); 306 llx = float64_add(llx, lly);
358 else 307 else
359 llx = float64_sub(llx, lly); 308 llx = float64_sub(llx, lly);
360 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; 309 tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
361 tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; 310 tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
362 } else if ((fpscr & FPSCR_CAUSE_ERROR) 311 } else if ((fpscr & FPSCR_CAUSE_ERROR)
363 && (!prec && ((hx & 0x7fffffff) < 0x00800000 312 && (!prec && ((hx & 0x7fffffff) < 0x00800000
364 || (hy & 0x7fffffff) < 0x00800000))) { 313 || (hy & 0x7fffffff) < 0x00800000))) {
@@ -367,7 +316,7 @@ static int ieee_fpe_handler(struct pt_regs *regs)
367 hx = float32_add(hx, hy); 316 hx = float32_add(hx, hy);
368 else 317 else
369 hx = float32_sub(hx, hy); 318 hx = float32_sub(hx, hy);
370 tsk->thread.fpu.hard.fp_regs[n] = hx; 319 tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
371 } else 320 } else
372 return 0; 321 return 0;
373 322
@@ -382,9 +331,9 @@ static int ieee_fpe_handler(struct pt_regs *regs)
382 331
383 n = (finsn >> 8) & 0xf; 332 n = (finsn >> 8) & 0xf;
384 m = (finsn >> 4) & 0xf; 333 m = (finsn >> 4) & 0xf;
385 hx = tsk->thread.fpu.hard.fp_regs[n]; 334 hx = tsk->thread.xstate->hardfpu.fp_regs[n];
386 hy = tsk->thread.fpu.hard.fp_regs[m]; 335 hy = tsk->thread.xstate->hardfpu.fp_regs[m];
387 fpscr = tsk->thread.fpu.hard.fpscr; 336 fpscr = tsk->thread.xstate->hardfpu.fpscr;
388 prec = fpscr & FPSCR_DBL_PRECISION; 337 prec = fpscr & FPSCR_DBL_PRECISION;
389 338
390 if ((fpscr & FPSCR_CAUSE_ERROR) 339 if ((fpscr & FPSCR_CAUSE_ERROR)
@@ -394,20 +343,20 @@ static int ieee_fpe_handler(struct pt_regs *regs)
394 343
395 /* FPU error because of denormal (doubles) */ 344 /* FPU error because of denormal (doubles) */
396 llx = ((long long)hx << 32) 345 llx = ((long long)hx << 32)
397 | tsk->thread.fpu.hard.fp_regs[n + 1]; 346 | tsk->thread.xstate->hardfpu.fp_regs[n + 1];
398 lly = ((long long)hy << 32) 347 lly = ((long long)hy << 32)
399 | tsk->thread.fpu.hard.fp_regs[m + 1]; 348 | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
400 349
401 llx = float64_div(llx, lly); 350 llx = float64_div(llx, lly);
402 351
403 tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; 352 tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32;
404 tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; 353 tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff;
405 } else if ((fpscr & FPSCR_CAUSE_ERROR) 354 } else if ((fpscr & FPSCR_CAUSE_ERROR)
406 && (!prec && ((hx & 0x7fffffff) < 0x00800000 355 && (!prec && ((hx & 0x7fffffff) < 0x00800000
407 || (hy & 0x7fffffff) < 0x00800000))) { 356 || (hy & 0x7fffffff) < 0x00800000))) {
408 /* FPU error because of denormal (floats) */ 357 /* FPU error because of denormal (floats) */
409 hx = float32_div(hx, hy); 358 hx = float32_div(hx, hy);
410 tsk->thread.fpu.hard.fp_regs[n] = hx; 359 tsk->thread.xstate->hardfpu.fp_regs[n] = hx;
411 } else 360 } else
412 return 0; 361 return 0;
413 362
@@ -420,17 +369,17 @@ static int ieee_fpe_handler(struct pt_regs *regs)
420 unsigned int hx; 369 unsigned int hx;
421 370
422 m = (finsn >> 8) & 0x7; 371 m = (finsn >> 8) & 0x7;
423 hx = tsk->thread.fpu.hard.fp_regs[m]; 372 hx = tsk->thread.xstate->hardfpu.fp_regs[m];
424 373
425 if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR) 374 if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR)
426 && ((hx & 0x7fffffff) < 0x00100000)) { 375 && ((hx & 0x7fffffff) < 0x00100000)) {
427 /* subnormal double to float conversion */ 376 /* subnormal double to float conversion */
428 long long llx; 377 long long llx;
429 378
430 llx = ((long long)tsk->thread.fpu.hard.fp_regs[m] << 32) 379 llx = ((long long)tsk->thread.xstate->hardfpu.fp_regs[m] << 32)
431 | tsk->thread.fpu.hard.fp_regs[m + 1]; 380 | tsk->thread.xstate->hardfpu.fp_regs[m + 1];
432 381
433 tsk->thread.fpu.hard.fpul = float64_to_float32(llx); 382 tsk->thread.xstate->hardfpu.fpul = float64_to_float32(llx);
434 } else 383 } else
435 return 0; 384 return 0;
436 385
@@ -449,7 +398,7 @@ void float_raise(unsigned int flags)
449int float_rounding_mode(void) 398int float_rounding_mode(void)
450{ 399{
451 struct task_struct *tsk = current; 400 struct task_struct *tsk = current;
452 int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.fpu.hard.fpscr); 401 int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.xstate->hardfpu.fpscr);
453 return roundingMode; 402 return roundingMode;
454} 403}
455 404
@@ -461,16 +410,16 @@ BUILD_TRAP_HANDLER(fpu_error)
461 __unlazy_fpu(tsk, regs); 410 __unlazy_fpu(tsk, regs);
462 fpu_exception_flags = 0; 411 fpu_exception_flags = 0;
463 if (ieee_fpe_handler(regs)) { 412 if (ieee_fpe_handler(regs)) {
464 tsk->thread.fpu.hard.fpscr &= 413 tsk->thread.xstate->hardfpu.fpscr &=
465 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); 414 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
466 tsk->thread.fpu.hard.fpscr |= fpu_exception_flags; 415 tsk->thread.xstate->hardfpu.fpscr |= fpu_exception_flags;
467 /* Set the FPSCR flag as well as cause bits - simply 416 /* Set the FPSCR flag as well as cause bits - simply
468 * replicate the cause */ 417 * replicate the cause */
469 tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10); 418 tsk->thread.xstate->hardfpu.fpscr |= (fpu_exception_flags >> 10);
470 grab_fpu(regs); 419 grab_fpu(regs);
471 restore_fpu(tsk); 420 restore_fpu(tsk);
472 task_thread_info(tsk)->status |= TS_USEDFPU; 421 task_thread_info(tsk)->status |= TS_USEDFPU;
473 if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) & 422 if ((((tsk->thread.xstate->hardfpu.fpscr & FPSCR_ENABLE_MASK) >> 7) &
474 (fpu_exception_flags >> 2)) == 0) { 423 (fpu_exception_flags >> 2)) == 0) {
475 return; 424 return;
476 } 425 }
@@ -478,33 +427,3 @@ BUILD_TRAP_HANDLER(fpu_error)
478 427
479 force_sig(SIGFPE, tsk); 428 force_sig(SIGFPE, tsk);
480} 429}
481
482void fpu_state_restore(struct pt_regs *regs)
483{
484 struct task_struct *tsk = current;
485
486 grab_fpu(regs);
487 if (unlikely(!user_mode(regs))) {
488 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
489 BUG();
490 return;
491 }
492
493 if (likely(used_math())) {
494 /* Using the FPU again. */
495 restore_fpu(tsk);
496 } else {
497 /* First time FPU user. */
498 fpu_init();
499 set_used_math();
500 }
501 task_thread_info(tsk)->status |= TS_USEDFPU;
502 tsk->fpu_counter++;
503}
504
505BUILD_TRAP_HANDLER(fpu_state_restore)
506{
507 TRAP_HANDLER_DECL;
508
509 fpu_state_restore(regs);
510}
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 33bab477d2e2..b144e8af89dc 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -41,7 +41,8 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7757) := pinmux-sh7757.o
41pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o 41pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o
42pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o 42pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o
43 43
44obj-y += $(clock-y) 44obj-y += $(clock-y)
45obj-$(CONFIG_SMP) += $(smp-y) 45obj-$(CONFIG_SMP) += $(smp-y)
46obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y) 46obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y)
47obj-$(CONFIG_PERF_EVENTS) += perf_event.o 47obj-$(CONFIG_PERF_EVENTS) += perf_event.o
48obj-$(CONFIG_HAVE_HW_BREAKPOINT) += ubc.o
diff --git a/arch/sh/kernel/cpu/sh4a/ubc.c b/arch/sh/kernel/cpu/sh4a/ubc.c
new file mode 100644
index 000000000000..efb2745bcb36
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/ubc.c
@@ -0,0 +1,133 @@
1/*
2 * arch/sh/kernel/cpu/sh4a/ubc.c
3 *
4 * On-chip UBC support for SH-4A CPUs.
5 *
6 * Copyright (C) 2009 - 2010 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/err.h>
14#include <linux/clk.h>
15#include <linux/io.h>
16#include <asm/hw_breakpoint.h>
17
18#define UBC_CBR(idx) (0xff200000 + (0x20 * idx))
19#define UBC_CRR(idx) (0xff200004 + (0x20 * idx))
20#define UBC_CAR(idx) (0xff200008 + (0x20 * idx))
21#define UBC_CAMR(idx) (0xff20000c + (0x20 * idx))
22
23#define UBC_CCMFR 0xff200600
24#define UBC_CBCR 0xff200620
25
26/* CRR */
27#define UBC_CRR_PCB (1 << 1)
28#define UBC_CRR_BIE (1 << 0)
29
30/* CBR */
31#define UBC_CBR_CE (1 << 0)
32
33static struct sh_ubc sh4a_ubc;
34
35static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
36{
37 __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
38 __raw_writel(info->address, UBC_CAR(idx));
39}
40
41static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
42{
43 __raw_writel(0, UBC_CBR(idx));
44 __raw_writel(0, UBC_CAR(idx));
45}
46
47static void sh4a_ubc_enable_all(unsigned long mask)
48{
49 int i;
50
51 for (i = 0; i < sh4a_ubc.num_events; i++)
52 if (mask & (1 << i))
53 __raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
54 UBC_CBR(i));
55}
56
57static void sh4a_ubc_disable_all(void)
58{
59 int i;
60
61 for (i = 0; i < sh4a_ubc.num_events; i++)
62 __raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
63 UBC_CBR(i));
64}
65
66static unsigned long sh4a_ubc_active_mask(void)
67{
68 unsigned long active = 0;
69 int i;
70
71 for (i = 0; i < sh4a_ubc.num_events; i++)
72 if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
73 active |= (1 << i);
74
75 return active;
76}
77
78static unsigned long sh4a_ubc_triggered_mask(void)
79{
80 return __raw_readl(UBC_CCMFR);
81}
82
83static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
84{
85 __raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
86}
87
88static struct sh_ubc sh4a_ubc = {
89 .name = "SH-4A",
90 .num_events = 2,
91 .trap_nr = 0x1e0,
92 .enable = sh4a_ubc_enable,
93 .disable = sh4a_ubc_disable,
94 .enable_all = sh4a_ubc_enable_all,
95 .disable_all = sh4a_ubc_disable_all,
96 .active_mask = sh4a_ubc_active_mask,
97 .triggered_mask = sh4a_ubc_triggered_mask,
98 .clear_triggered_mask = sh4a_ubc_clear_triggered_mask,
99};
100
101static int __init sh4a_ubc_init(void)
102{
103 struct clk *ubc_iclk = clk_get(NULL, "ubc0");
104 int i;
105
106 /*
107 * The UBC MSTP bit is optional, as not all platforms will have
108 * it. Just ignore it if we can't find it.
109 */
110 if (IS_ERR(ubc_iclk))
111 ubc_iclk = NULL;
112
113 clk_enable(ubc_iclk);
114
115 __raw_writel(0, UBC_CBCR);
116
117 for (i = 0; i < sh4a_ubc.num_events; i++) {
118 __raw_writel(0, UBC_CAMR(i));
119 __raw_writel(0, UBC_CBR(i));
120
121 __raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i));
122
123 /* dummy read for write posting */
124 (void)__raw_readl(UBC_CRR(i));
125 }
126
127 clk_disable(ubc_iclk);
128
129 sh4a_ubc.clk = ubc_iclk;
130
131 return register_sh_ubc(&sh4a_ubc);
132}
133arch_initcall(sh4a_ubc_init);
diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S
index 591741383ee6..7a1b46fec0f4 100644
--- a/arch/sh/kernel/debugtraps.S
+++ b/arch/sh/kernel/debugtraps.S
@@ -13,7 +13,6 @@
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14 14
15#if !defined(CONFIG_KGDB) 15#if !defined(CONFIG_KGDB)
16#define breakpoint_trap_handler debug_trap_handler
17#define singlestep_trap_handler debug_trap_handler 16#define singlestep_trap_handler debug_trap_handler
18#endif 17#endif
19 18
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
deleted file mode 100644
index f8bb50c6e050..000000000000
--- a/arch/sh/kernel/early_printk.c
+++ /dev/null
@@ -1,85 +0,0 @@
1/*
2 * arch/sh/kernel/early_printk.c
3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2002 M. R. Brown
6 * Copyright (C) 2004 - 2007 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/console.h>
13#include <linux/tty.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17
18#include <asm/sh_bios.h>
19
20/*
21 * Print a string through the BIOS
22 */
23static void sh_console_write(struct console *co, const char *s,
24 unsigned count)
25{
26 sh_bios_console_write(s, count);
27}
28
29/*
30 * Setup initial baud/bits/parity. We do two things here:
31 * - construct a cflag setting for the first rs_open()
32 * - initialize the serial port
33 * Return non-zero if we didn't find a serial port.
34 */
35static int __init sh_console_setup(struct console *co, char *options)
36{
37 int cflag = CREAD | HUPCL | CLOCAL;
38
39 /*
40 * Now construct a cflag setting.
41 * TODO: this is a totally bogus cflag, as we have
42 * no idea what serial settings the BIOS is using, or
43 * even if its using the serial port at all.
44 */
45 cflag |= B115200 | CS8 | /*no parity*/0;
46
47 co->cflag = cflag;
48
49 return 0;
50}
51
52static struct console bios_console = {
53 .name = "bios",
54 .write = sh_console_write,
55 .setup = sh_console_setup,
56 .flags = CON_PRINTBUFFER,
57 .index = -1,
58};
59
60static struct console *early_console;
61
62static int __init setup_early_printk(char *buf)
63{
64 int keep_early = 0;
65
66 if (!buf)
67 return 0;
68
69 if (strstr(buf, "keep"))
70 keep_early = 1;
71
72 if (!strncmp(buf, "bios", 4))
73 early_console = &bios_console;
74
75 if (likely(early_console)) {
76 if (keep_early)
77 early_console->flags &= ~CON_BOOT;
78 else
79 early_console->flags |= CON_BOOT;
80 register_console(early_console);
81 }
82
83 return 0;
84}
85early_param("earlyprintk", setup_early_printk);
diff --git a/arch/sh/kernel/head_64.S b/arch/sh/kernel/head_64.S
index 3ea765844c74..defd851abefa 100644
--- a/arch/sh/kernel/head_64.S
+++ b/arch/sh/kernel/head_64.S
@@ -220,7 +220,6 @@ clear_DTLB:
220 add.l r22, r63, r22 /* Sign extend */ 220 add.l r22, r63, r22 /* Sign extend */
221 putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */ 221 putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */
222 222
223#ifdef CONFIG_EARLY_PRINTK
224 /* 223 /*
225 * Setup a DTLB translation for SCIF phys. 224 * Setup a DTLB translation for SCIF phys.
226 */ 225 */
@@ -231,7 +230,6 @@ clear_DTLB:
231 movi 0xfa03, r22 /* 0xfa030000, fixed SCIF virt */ 230 movi 0xfa03, r22 /* 0xfa030000, fixed SCIF virt */
232 shori 0x0003, r22 231 shori 0x0003, r22
233 putcfg r21, 0, r22 /* PTEH last */ 232 putcfg r21, 0, r22 /* PTEH last */
234#endif
235 233
236 /* 234 /*
237 * Set cache behaviours. 235 * Set cache behaviours.
diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..e2f1753d275c
--- /dev/null
+++ b/arch/sh/kernel/hw_breakpoint.c
@@ -0,0 +1,463 @@
1/*
2 * arch/sh/kernel/hw_breakpoint.c
3 *
4 * Unified kernel/user-space hardware breakpoint facility for the on-chip UBC.
5 *
6 * Copyright (C) 2009 - 2010 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/init.h>
13#include <linux/perf_event.h>
14#include <linux/hw_breakpoint.h>
15#include <linux/percpu.h>
16#include <linux/kallsyms.h>
17#include <linux/notifier.h>
18#include <linux/kprobes.h>
19#include <linux/kdebug.h>
20#include <linux/io.h>
21#include <linux/clk.h>
22#include <asm/hw_breakpoint.h>
23#include <asm/mmu_context.h>
24#include <asm/ptrace.h>
25
26/*
27 * Stores the breakpoints currently in use on each breakpoint address
28 * register for each cpus
29 */
30static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
31
32/*
33 * A dummy placeholder for early accesses until the CPUs get a chance to
34 * register their UBCs later in the boot process.
35 */
36static struct sh_ubc ubc_dummy = { .num_events = 0 };
37
38static struct sh_ubc *sh_ubc __read_mostly = &ubc_dummy;
39
40/*
41 * Install a perf counter breakpoint.
42 *
43 * We seek a free UBC channel and use it for this breakpoint.
44 *
45 * Atomic: we hold the counter->ctx->lock and we only handle variables
46 * and registers local to this cpu.
47 */
48int arch_install_hw_breakpoint(struct perf_event *bp)
49{
50 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
51 int i;
52
53 for (i = 0; i < sh_ubc->num_events; i++) {
54 struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
55
56 if (!*slot) {
57 *slot = bp;
58 break;
59 }
60 }
61
62 if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
63 return -EBUSY;
64
65 clk_enable(sh_ubc->clk);
66 sh_ubc->enable(info, i);
67
68 return 0;
69}
70
71/*
72 * Uninstall the breakpoint contained in the given counter.
73 *
74 * First we search the debug address register it uses and then we disable
75 * it.
76 *
77 * Atomic: we hold the counter->ctx->lock and we only handle variables
78 * and registers local to this cpu.
79 */
80void arch_uninstall_hw_breakpoint(struct perf_event *bp)
81{
82 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
83 int i;
84
85 for (i = 0; i < sh_ubc->num_events; i++) {
86 struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]);
87
88 if (*slot == bp) {
89 *slot = NULL;
90 break;
91 }
92 }
93
94 if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot"))
95 return;
96
97 sh_ubc->disable(info, i);
98 clk_disable(sh_ubc->clk);
99}
100
101static int get_hbp_len(u16 hbp_len)
102{
103 unsigned int len_in_bytes = 0;
104
105 switch (hbp_len) {
106 case SH_BREAKPOINT_LEN_1:
107 len_in_bytes = 1;
108 break;
109 case SH_BREAKPOINT_LEN_2:
110 len_in_bytes = 2;
111 break;
112 case SH_BREAKPOINT_LEN_4:
113 len_in_bytes = 4;
114 break;
115 case SH_BREAKPOINT_LEN_8:
116 len_in_bytes = 8;
117 break;
118 }
119 return len_in_bytes;
120}
121
122/*
123 * Check for virtual address in user space.
124 */
125int arch_check_va_in_userspace(unsigned long va, u16 hbp_len)
126{
127 unsigned int len;
128
129 len = get_hbp_len(hbp_len);
130
131 return (va <= TASK_SIZE - len);
132}
133
134/*
135 * Check for virtual address in kernel space.
136 */
137static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
138{
139 unsigned int len;
140
141 len = get_hbp_len(hbp_len);
142
143 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
144}
145
146/*
147 * Store a breakpoint's encoded address, length, and type.
148 */
149static int arch_store_info(struct perf_event *bp)
150{
151 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
152
153 /*
154 * User-space requests will always have the address field populated
155 * For kernel-addresses, either the address or symbol name can be
156 * specified.
157 */
158 if (info->name)
159 info->address = (unsigned long)kallsyms_lookup_name(info->name);
160 if (info->address)
161 return 0;
162
163 return -EINVAL;
164}
165
166int arch_bp_generic_fields(int sh_len, int sh_type,
167 int *gen_len, int *gen_type)
168{
169 /* Len */
170 switch (sh_len) {
171 case SH_BREAKPOINT_LEN_1:
172 *gen_len = HW_BREAKPOINT_LEN_1;
173 break;
174 case SH_BREAKPOINT_LEN_2:
175 *gen_len = HW_BREAKPOINT_LEN_2;
176 break;
177 case SH_BREAKPOINT_LEN_4:
178 *gen_len = HW_BREAKPOINT_LEN_4;
179 break;
180 case SH_BREAKPOINT_LEN_8:
181 *gen_len = HW_BREAKPOINT_LEN_8;
182 break;
183 default:
184 return -EINVAL;
185 }
186
187 /* Type */
188 switch (sh_type) {
189 case SH_BREAKPOINT_READ:
190 *gen_type = HW_BREAKPOINT_R;
191 case SH_BREAKPOINT_WRITE:
192 *gen_type = HW_BREAKPOINT_W;
193 break;
194 case SH_BREAKPOINT_RW:
195 *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
196 break;
197 default:
198 return -EINVAL;
199 }
200
201 return 0;
202}
203
204static int arch_build_bp_info(struct perf_event *bp)
205{
206 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
207
208 info->address = bp->attr.bp_addr;
209
210 /* Len */
211 switch (bp->attr.bp_len) {
212 case HW_BREAKPOINT_LEN_1:
213 info->len = SH_BREAKPOINT_LEN_1;
214 break;
215 case HW_BREAKPOINT_LEN_2:
216 info->len = SH_BREAKPOINT_LEN_2;
217 break;
218 case HW_BREAKPOINT_LEN_4:
219 info->len = SH_BREAKPOINT_LEN_4;
220 break;
221 case HW_BREAKPOINT_LEN_8:
222 info->len = SH_BREAKPOINT_LEN_8;
223 break;
224 default:
225 return -EINVAL;
226 }
227
228 /* Type */
229 switch (bp->attr.bp_type) {
230 case HW_BREAKPOINT_R:
231 info->type = SH_BREAKPOINT_READ;
232 break;
233 case HW_BREAKPOINT_W:
234 info->type = SH_BREAKPOINT_WRITE;
235 break;
236 case HW_BREAKPOINT_W | HW_BREAKPOINT_R:
237 info->type = SH_BREAKPOINT_RW;
238 break;
239 default:
240 return -EINVAL;
241 }
242
243 return 0;
244}
245
246/*
247 * Validate the arch-specific HW Breakpoint register settings
248 */
249int arch_validate_hwbkpt_settings(struct perf_event *bp,
250 struct task_struct *tsk)
251{
252 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
253 unsigned int align;
254 int ret;
255
256 ret = arch_build_bp_info(bp);
257 if (ret)
258 return ret;
259
260 ret = -EINVAL;
261
262 switch (info->len) {
263 case SH_BREAKPOINT_LEN_1:
264 align = 0;
265 break;
266 case SH_BREAKPOINT_LEN_2:
267 align = 1;
268 break;
269 case SH_BREAKPOINT_LEN_4:
270 align = 3;
271 break;
272 case SH_BREAKPOINT_LEN_8:
273 align = 7;
274 break;
275 default:
276 return ret;
277 }
278
279 ret = arch_store_info(bp);
280
281 if (ret < 0)
282 return ret;
283
284 /*
285 * Check that the low-order bits of the address are appropriate
286 * for the alignment implied by len.
287 */
288 if (info->address & align)
289 return -EINVAL;
290
291 /* Check that the virtual address is in the proper range */
292 if (tsk) {
293 if (!arch_check_va_in_userspace(info->address, info->len))
294 return -EFAULT;
295 } else {
296 if (!arch_check_va_in_kernelspace(info->address, info->len))
297 return -EFAULT;
298 }
299
300 return 0;
301}
302
303/*
304 * Release the user breakpoints used by ptrace
305 */
306void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
307{
308 int i;
309 struct thread_struct *t = &tsk->thread;
310
311 for (i = 0; i < sh_ubc->num_events; i++) {
312 unregister_hw_breakpoint(t->ptrace_bps[i]);
313 t->ptrace_bps[i] = NULL;
314 }
315}
316
317static int __kprobes hw_breakpoint_handler(struct die_args *args)
318{
319 int cpu, i, rc = NOTIFY_STOP;
320 struct perf_event *bp;
321 unsigned int cmf, resume_mask;
322
323 /*
324 * Do an early return if none of the channels triggered.
325 */
326 cmf = sh_ubc->triggered_mask();
327 if (unlikely(!cmf))
328 return NOTIFY_DONE;
329
330 /*
331 * By default, resume all of the active channels.
332 */
333 resume_mask = sh_ubc->active_mask();
334
335 /*
336 * Disable breakpoints during exception handling.
337 */
338 sh_ubc->disable_all();
339
340 cpu = get_cpu();
341 for (i = 0; i < sh_ubc->num_events; i++) {
342 unsigned long event_mask = (1 << i);
343
344 if (likely(!(cmf & event_mask)))
345 continue;
346
347 /*
348 * The counter may be concurrently released but that can only
349 * occur from a call_rcu() path. We can then safely fetch
350 * the breakpoint, use its callback, touch its counter
351 * while we are in an rcu_read_lock() path.
352 */
353 rcu_read_lock();
354
355 bp = per_cpu(bp_per_reg[i], cpu);
356 if (bp)
357 rc = NOTIFY_DONE;
358
359 /*
360 * Reset the condition match flag to denote completion of
361 * exception handling.
362 */
363 sh_ubc->clear_triggered_mask(event_mask);
364
365 /*
366 * bp can be NULL due to concurrent perf counter
367 * removing.
368 */
369 if (!bp) {
370 rcu_read_unlock();
371 break;
372 }
373
374 /*
375 * Don't restore the channel if the breakpoint is from
376 * ptrace, as it always operates in one-shot mode.
377 */
378 if (bp->overflow_handler == ptrace_triggered)
379 resume_mask &= ~(1 << i);
380
381 perf_bp_event(bp, args->regs);
382
383 /* Deliver the signal to userspace */
384 if (arch_check_va_in_userspace(bp->attr.bp_addr,
385 bp->attr.bp_len)) {
386 siginfo_t info;
387
388 info.si_signo = args->signr;
389 info.si_errno = notifier_to_errno(rc);
390 info.si_code = TRAP_HWBKPT;
391
392 force_sig_info(args->signr, &info, current);
393 }
394
395 rcu_read_unlock();
396 }
397
398 if (cmf == 0)
399 rc = NOTIFY_DONE;
400
401 sh_ubc->enable_all(resume_mask);
402
403 put_cpu();
404
405 return rc;
406}
407
408BUILD_TRAP_HANDLER(breakpoint)
409{
410 unsigned long ex = lookup_exception_vector();
411 TRAP_HANDLER_DECL;
412
413 notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP);
414}
415
416/*
417 * Handle debug exception notifications.
418 */
419int __kprobes hw_breakpoint_exceptions_notify(struct notifier_block *unused,
420 unsigned long val, void *data)
421{
422 struct die_args *args = data;
423
424 if (val != DIE_BREAKPOINT)
425 return NOTIFY_DONE;
426
427 /*
428 * If the breakpoint hasn't been triggered by the UBC, it's
429 * probably from a debugger, so don't do anything more here.
430 *
431 * This also permits the UBC interface clock to remain off for
432 * non-UBC breakpoints, as we don't need to check the triggered
433 * or active channel masks.
434 */
435 if (args->trapnr != sh_ubc->trap_nr)
436 return NOTIFY_DONE;
437
438 return hw_breakpoint_handler(data);
439}
440
441void hw_breakpoint_pmu_read(struct perf_event *bp)
442{
443 /* TODO */
444}
445
446void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
447{
448 /* TODO */
449}
450
451int register_sh_ubc(struct sh_ubc *ubc)
452{
453 /* Bail if it's already assigned */
454 if (sh_ubc != &ubc_dummy)
455 return -EBUSY;
456 sh_ubc = ubc;
457
458 pr_info("HW Breakpoints: %s UBC support registered\n", ubc->name);
459
460 WARN_ON(ubc->num_events > HBP_NUM);
461
462 return 0;
463}
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
index 3e532d0d4a5c..70c69659b846 100644
--- a/arch/sh/kernel/kgdb.c
+++ b/arch/sh/kernel/kgdb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SuperH KGDB support 2 * SuperH KGDB support
3 * 3 *
4 * Copyright (C) 2008 Paul Mundt 4 * Copyright (C) 2008 - 2009 Paul Mundt
5 * 5 *
6 * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel. 6 * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel.
7 * 7 *
@@ -251,24 +251,60 @@ BUILD_TRAP_HANDLER(singlestep)
251 local_irq_restore(flags); 251 local_irq_restore(flags);
252} 252}
253 253
254static int __kgdb_notify(struct die_args *args, unsigned long cmd)
255{
256 int ret;
257
258 switch (cmd) {
259 case DIE_BREAKPOINT:
260 /*
261 * This means a user thread is single stepping
262 * a system call which should be ignored
263 */
264 if (test_thread_flag(TIF_SINGLESTEP))
265 return NOTIFY_DONE;
266
267 ret = kgdb_handle_exception(args->trapnr & 0xff, args->signr,
268 args->err, args->regs);
269 if (ret)
270 return NOTIFY_DONE;
271
272 break;
273 }
254 274
255BUILD_TRAP_HANDLER(breakpoint) 275 return NOTIFY_STOP;
276}
277
278static int
279kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
256{ 280{
257 unsigned long flags; 281 unsigned long flags;
258 TRAP_HANDLER_DECL; 282 int ret;
259 283
260 local_irq_save(flags); 284 local_irq_save(flags);
261 kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs); 285 ret = __kgdb_notify(ptr, cmd);
262 local_irq_restore(flags); 286 local_irq_restore(flags);
287
288 return ret;
263} 289}
264 290
291static struct notifier_block kgdb_notifier = {
292 .notifier_call = kgdb_notify,
293
294 /*
295 * Lowest-prio notifier priority, we want to be notified last:
296 */
297 .priority = -INT_MAX,
298};
299
265int kgdb_arch_init(void) 300int kgdb_arch_init(void)
266{ 301{
267 return 0; 302 return register_die_notifier(&kgdb_notifier);
268} 303}
269 304
270void kgdb_arch_exit(void) 305void kgdb_arch_exit(void)
271{ 306{
307 unregister_die_notifier(&kgdb_notifier);
272} 308}
273 309
274struct kgdb_arch arch_kgdb_ops = { 310struct kgdb_arch arch_kgdb_ops = {
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 76f280223ebd..f52d8ed69e12 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -21,6 +21,7 @@
21#include <asm/mmu_context.h> 21#include <asm/mmu_context.h>
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24#include <asm/sh_bios.h>
24 25
25typedef void (*relocate_new_kernel_t)(unsigned long indirection_page, 26typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
26 unsigned long reboot_code_buffer, 27 unsigned long reboot_code_buffer,
@@ -28,7 +29,6 @@ typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
28 29
29extern const unsigned char relocate_new_kernel[]; 30extern const unsigned char relocate_new_kernel[];
30extern const unsigned int relocate_new_kernel_size; 31extern const unsigned int relocate_new_kernel_size;
31extern void *gdb_vbr_vector;
32extern void *vbr_base; 32extern void *vbr_base;
33 33
34void machine_shutdown(void) 34void machine_shutdown(void)
@@ -117,11 +117,7 @@ void machine_kexec(struct kimage *image)
117 kexec_info(image); 117 kexec_info(image);
118 flush_cache_all(); 118 flush_cache_all();
119 119
120#if defined(CONFIG_SH_STANDARD_BIOS) 120 sh_bios_vbr_reload();
121 asm volatile("ldc %0, vbr" :
122 : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
123 : "memory");
124#endif
125 121
126 /* now call it */ 122 /* now call it */
127 rnk = (relocate_new_kernel_t) reboot_code_buffer; 123 rnk = (relocate_new_kernel_t) reboot_code_buffer;
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
new file mode 100644
index 000000000000..81add9b9ea6e
--- /dev/null
+++ b/arch/sh/kernel/process.c
@@ -0,0 +1,100 @@
1#include <linux/mm.h>
2#include <linux/kernel.h>
3#include <linux/sched.h>
4
5struct kmem_cache *task_xstate_cachep = NULL;
6unsigned int xstate_size;
7
8int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
9{
10 *dst = *src;
11
12 if (src->thread.xstate) {
13 dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
14 GFP_KERNEL);
15 if (!dst->thread.xstate)
16 return -ENOMEM;
17 memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
18 }
19
20 return 0;
21}
22
23void free_thread_xstate(struct task_struct *tsk)
24{
25 if (tsk->thread.xstate) {
26 kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
27 tsk->thread.xstate = NULL;
28 }
29}
30
31#if THREAD_SHIFT < PAGE_SHIFT
32static struct kmem_cache *thread_info_cache;
33
34struct thread_info *alloc_thread_info(struct task_struct *tsk)
35{
36 struct thread_info *ti;
37
38 ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
39 if (unlikely(ti == NULL))
40 return NULL;
41#ifdef CONFIG_DEBUG_STACK_USAGE
42 memset(ti, 0, THREAD_SIZE);
43#endif
44 return ti;
45}
46
47void free_thread_info(struct thread_info *ti)
48{
49 free_thread_xstate(ti->task);
50 kmem_cache_free(thread_info_cache, ti);
51}
52
53void thread_info_cache_init(void)
54{
55 thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
56 THREAD_SIZE, SLAB_PANIC, NULL);
57}
58#else
59struct thread_info *alloc_thread_info(struct task_struct *tsk)
60{
61#ifdef CONFIG_DEBUG_STACK_USAGE
62 gfp_t mask = GFP_KERNEL | __GFP_ZERO;
63#else
64 gfp_t mask = GFP_KERNEL;
65#endif
66 return (struct thread_info *)__get_free_pages(mask, THREAD_SIZE_ORDER);
67}
68
69void free_thread_info(struct thread_info *ti)
70{
71 free_thread_xstate(ti->task);
72 free_pages((unsigned long)ti, THREAD_SIZE_ORDER);
73}
74#endif /* THREAD_SHIFT < PAGE_SHIFT */
75
76void arch_task_cache_init(void)
77{
78 if (!xstate_size)
79 return;
80
81 task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size,
82 __alignof__(union thread_xstate),
83 SLAB_PANIC | SLAB_NOTRACK, NULL);
84}
85
86#ifdef CONFIG_SH_FPU_EMU
87# define HAVE_SOFTFP 1
88#else
89# define HAVE_SOFTFP 0
90#endif
91
92void init_thread_xstate(void)
93{
94 if (boot_cpu_data.flags & CPU_HAS_FPU)
95 xstate_size = sizeof(struct sh_fpu_hard_struct);
96 else if (HAVE_SOFTFP)
97 xstate_size = sizeof(struct sh_fpu_soft_struct);
98 else
99 xstate_size = 0;
100}
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index d8af889366a4..856010f9ebc9 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -25,17 +25,15 @@
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/ftrace.h> 26#include <linux/ftrace.h>
27#include <linux/preempt.h> 27#include <linux/preempt.h>
28#include <linux/hw_breakpoint.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
29#include <asm/mmu_context.h> 30#include <asm/mmu_context.h>
30#include <asm/pgalloc.h> 31#include <asm/pgalloc.h>
31#include <asm/system.h> 32#include <asm/system.h>
32#include <asm/ubc.h>
33#include <asm/fpu.h> 33#include <asm/fpu.h>
34#include <asm/syscalls.h> 34#include <asm/syscalls.h>
35#include <asm/watchdog.h> 35#include <asm/watchdog.h>
36 36
37int ubc_usercnt = 0;
38
39#ifdef CONFIG_32BIT 37#ifdef CONFIG_32BIT
40static void watchdog_trigger_immediate(void) 38static void watchdog_trigger_immediate(void)
41{ 39{
@@ -147,21 +145,34 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
147} 145}
148EXPORT_SYMBOL(kernel_thread); 146EXPORT_SYMBOL(kernel_thread);
149 147
148void start_thread(struct pt_regs *regs, unsigned long new_pc,
149 unsigned long new_sp)
150{
151 set_fs(USER_DS);
152
153 regs->pr = 0;
154 regs->sr = SR_FD;
155 regs->pc = new_pc;
156 regs->regs[15] = new_sp;
157
158 free_thread_xstate(current);
159}
160EXPORT_SYMBOL(start_thread);
161
150/* 162/*
151 * Free current thread data structures etc.. 163 * Free current thread data structures etc..
152 */ 164 */
153void exit_thread(void) 165void exit_thread(void)
154{ 166{
155 if (current->thread.ubc_pc) {
156 current->thread.ubc_pc = 0;
157 ubc_usercnt -= 1;
158 }
159} 167}
160 168
161void flush_thread(void) 169void flush_thread(void)
162{ 170{
163#if defined(CONFIG_SH_FPU)
164 struct task_struct *tsk = current; 171 struct task_struct *tsk = current;
172
173 flush_ptrace_hw_breakpoint(tsk);
174
175#if defined(CONFIG_SH_FPU)
165 /* Forget lazy FPU state */ 176 /* Forget lazy FPU state */
166 clear_fpu(tsk, task_pt_regs(tsk)); 177 clear_fpu(tsk, task_pt_regs(tsk));
167 clear_used_math(); 178 clear_used_math();
@@ -209,11 +220,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
209{ 220{
210 struct thread_info *ti = task_thread_info(p); 221 struct thread_info *ti = task_thread_info(p);
211 struct pt_regs *childregs; 222 struct pt_regs *childregs;
223
212#if defined(CONFIG_SH_DSP) 224#if defined(CONFIG_SH_DSP)
213 struct task_struct *tsk = current; 225 struct task_struct *tsk = current;
214#endif
215 226
216#if defined(CONFIG_SH_DSP)
217 if (is_dsp_enabled(tsk)) { 227 if (is_dsp_enabled(tsk)) {
218 /* We can use the __save_dsp or just copy the struct: 228 /* We can use the __save_dsp or just copy the struct:
219 * __save_dsp(p); 229 * __save_dsp(p);
@@ -244,53 +254,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
244 p->thread.sp = (unsigned long) childregs; 254 p->thread.sp = (unsigned long) childregs;
245 p->thread.pc = (unsigned long) ret_from_fork; 255 p->thread.pc = (unsigned long) ret_from_fork;
246 256
247 p->thread.ubc_pc = 0; 257 memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
248 258
249 return 0; 259 return 0;
250} 260}
251 261
252/* Tracing by user break controller. */
253static void ubc_set_tracing(int asid, unsigned long pc)
254{
255#if defined(CONFIG_CPU_SH4A)
256 unsigned long val;
257
258 val = (UBC_CBR_ID_INST | UBC_CBR_RW_READ | UBC_CBR_CE);
259 val |= (UBC_CBR_AIE | UBC_CBR_AIV_SET(asid));
260
261 ctrl_outl(val, UBC_CBR0);
262 ctrl_outl(pc, UBC_CAR0);
263 ctrl_outl(0x0, UBC_CAMR0);
264 ctrl_outl(0x0, UBC_CBCR);
265
266 val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE);
267 ctrl_outl(val, UBC_CRR0);
268
269 /* Read UBC register that we wrote last, for checking update */
270 val = ctrl_inl(UBC_CRR0);
271
272#else /* CONFIG_CPU_SH4A */
273 ctrl_outl(pc, UBC_BARA);
274
275#ifdef CONFIG_MMU
276 ctrl_outb(asid, UBC_BASRA);
277#endif
278
279 ctrl_outl(0, UBC_BAMRA);
280
281 if (current_cpu_data.type == CPU_SH7729 ||
282 current_cpu_data.type == CPU_SH7710 ||
283 current_cpu_data.type == CPU_SH7712 ||
284 current_cpu_data.type == CPU_SH7203){
285 ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
286 ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
287 } else {
288 ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
289 ctrl_outw(BRCR_PCBA, UBC_BRCR);
290 }
291#endif /* CONFIG_CPU_SH4A */
292}
293
294/* 262/*
295 * switch_to(x,y) should switch tasks from x to y. 263 * switch_to(x,y) should switch tasks from x to y.
296 * 264 *
@@ -304,7 +272,7 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
304 272
305 /* we're going to use this soon, after a few expensive things */ 273 /* we're going to use this soon, after a few expensive things */
306 if (next->fpu_counter > 5) 274 if (next->fpu_counter > 5)
307 prefetch(&next_t->fpu.hard); 275 prefetch(next_t->xstate);
308 276
309#ifdef CONFIG_MMU 277#ifdef CONFIG_MMU
310 /* 278 /*
@@ -316,32 +284,13 @@ __switch_to(struct task_struct *prev, struct task_struct *next)
316 : "r" (task_thread_info(next))); 284 : "r" (task_thread_info(next)));
317#endif 285#endif
318 286
319 /* If no tasks are using the UBC, we're done */
320 if (ubc_usercnt == 0)
321 /* If no tasks are using the UBC, we're done */;
322 else if (next->thread.ubc_pc && next->mm) {
323 int asid = 0;
324#ifdef CONFIG_MMU
325 asid |= cpu_asid(smp_processor_id(), next->mm);
326#endif
327 ubc_set_tracing(asid, next->thread.ubc_pc);
328 } else {
329#if defined(CONFIG_CPU_SH4A)
330 ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
331 ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
332#else
333 ctrl_outw(0, UBC_BBRA);
334 ctrl_outw(0, UBC_BBRB);
335#endif
336 }
337
338 /* 287 /*
339 * If the task has used fpu the last 5 timeslices, just do a full 288 * If the task has used fpu the last 5 timeslices, just do a full
340 * restore of the math state immediately to avoid the trap; the 289 * restore of the math state immediately to avoid the trap; the
341 * chances of needing FPU soon are obviously high now 290 * chances of needing FPU soon are obviously high now
342 */ 291 */
343 if (next->fpu_counter > 5) 292 if (next->fpu_counter > 5)
344 fpu_state_restore(task_pt_regs(next)); 293 __fpu_state_restore();
345 294
346 return prev; 295 return prev;
347} 296}
@@ -434,20 +383,3 @@ unsigned long get_wchan(struct task_struct *p)
434 383
435 return pc; 384 return pc;
436} 385}
437
438asmlinkage void break_point_trap(void)
439{
440 /* Clear tracing. */
441#if defined(CONFIG_CPU_SH4A)
442 ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
443 ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
444#else
445 ctrl_outw(0, UBC_BBRA);
446 ctrl_outw(0, UBC_BBRB);
447 ctrl_outl(0, UBC_BRCR);
448#endif
449 current->thread.ubc_pc = 0;
450 ubc_usercnt -= 1;
451
452 force_sig(SIGTRAP, current);
453}
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 9be35f348093..c625cdab76dd 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -2,7 +2,7 @@
2 * SuperH process tracing 2 * SuperH process tracing
3 * 3 *
4 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka 4 * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
5 * Copyright (C) 2002 - 2008 Paul Mundt 5 * Copyright (C) 2002 - 2009 Paul Mundt
6 * 6 *
7 * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp> 7 * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp>
8 * 8 *
@@ -26,6 +26,7 @@
26#include <linux/tracehook.h> 26#include <linux/tracehook.h>
27#include <linux/elf.h> 27#include <linux/elf.h>
28#include <linux/regset.h> 28#include <linux/regset.h>
29#include <linux/hw_breakpoint.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30#include <asm/pgtable.h> 31#include <asm/pgtable.h>
31#include <asm/system.h> 32#include <asm/system.h>
@@ -63,33 +64,64 @@ static inline int put_stack_long(struct task_struct *task, int offset,
63 return 0; 64 return 0;
64} 65}
65 66
66void user_enable_single_step(struct task_struct *child) 67void ptrace_triggered(struct perf_event *bp, int nmi,
68 struct perf_sample_data *data, struct pt_regs *regs)
67{ 69{
68 /* Next scheduling will set up UBC */ 70 struct perf_event_attr attr;
69 if (child->thread.ubc_pc == 0) 71
70 ubc_usercnt += 1; 72 /*
73 * Disable the breakpoint request here since ptrace has defined a
74 * one-shot behaviour for breakpoint exceptions.
75 */
76 attr = bp->attr;
77 attr.disabled = true;
78 modify_user_hw_breakpoint(bp, &attr);
79}
80
81static int set_single_step(struct task_struct *tsk, unsigned long addr)
82{
83 struct thread_struct *thread = &tsk->thread;
84 struct perf_event *bp;
85 struct perf_event_attr attr;
86
87 bp = thread->ptrace_bps[0];
88 if (!bp) {
89 hw_breakpoint_init(&attr);
90
91 attr.bp_addr = addr;
92 attr.bp_len = HW_BREAKPOINT_LEN_2;
93 attr.bp_type = HW_BREAKPOINT_R;
94
95 bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk);
96 if (IS_ERR(bp))
97 return PTR_ERR(bp);
98
99 thread->ptrace_bps[0] = bp;
100 } else {
101 int err;
102
103 attr = bp->attr;
104 attr.bp_addr = addr;
105 err = modify_user_hw_breakpoint(bp, &attr);
106 if (unlikely(err))
107 return err;
108 }
109
110 return 0;
111}
71 112
72 child->thread.ubc_pc = get_stack_long(child, 113void user_enable_single_step(struct task_struct *child)
73 offsetof(struct pt_regs, pc)); 114{
115 unsigned long pc = get_stack_long(child, offsetof(struct pt_regs, pc));
74 116
75 set_tsk_thread_flag(child, TIF_SINGLESTEP); 117 set_tsk_thread_flag(child, TIF_SINGLESTEP);
118
119 set_single_step(child, pc);
76} 120}
77 121
78void user_disable_single_step(struct task_struct *child) 122void user_disable_single_step(struct task_struct *child)
79{ 123{
80 clear_tsk_thread_flag(child, TIF_SINGLESTEP); 124 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
81
82 /*
83 * Ensure the UBC is not programmed at the next context switch.
84 *
85 * Normally this is not needed but there are sequences such as
86 * singlestep, signal delivery, and continue that leave the
87 * ubc_pc non-zero leading to spurious SIGTRAPs.
88 */
89 if (child->thread.ubc_pc != 0) {
90 ubc_usercnt -= 1;
91 child->thread.ubc_pc = 0;
92 }
93} 125}
94 126
95/* 127/*
@@ -163,10 +195,10 @@ int fpregs_get(struct task_struct *target,
163 195
164 if ((boot_cpu_data.flags & CPU_HAS_FPU)) 196 if ((boot_cpu_data.flags & CPU_HAS_FPU))
165 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 197 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
166 &target->thread.fpu.hard, 0, -1); 198 &target->thread.xstate->hardfpu, 0, -1);
167 199
168 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 200 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
169 &target->thread.fpu.soft, 0, -1); 201 &target->thread.xstate->softfpu, 0, -1);
170} 202}
171 203
172static int fpregs_set(struct task_struct *target, 204static int fpregs_set(struct task_struct *target,
@@ -184,10 +216,10 @@ static int fpregs_set(struct task_struct *target,
184 216
185 if ((boot_cpu_data.flags & CPU_HAS_FPU)) 217 if ((boot_cpu_data.flags & CPU_HAS_FPU))
186 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 218 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
187 &target->thread.fpu.hard, 0, -1); 219 &target->thread.xstate->hardfpu, 0, -1);
188 220
189 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 221 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
190 &target->thread.fpu.soft, 0, -1); 222 &target->thread.xstate->softfpu, 0, -1);
191} 223}
192 224
193static int fpregs_active(struct task_struct *target, 225static int fpregs_active(struct task_struct *target,
@@ -333,7 +365,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
333 else 365 else
334 tmp = 0; 366 tmp = 0;
335 } else 367 } else
336 tmp = ((long *)&child->thread.fpu) 368 tmp = ((long *)child->thread.xstate)
337 [(addr - (long)&dummy->fpu) >> 2]; 369 [(addr - (long)&dummy->fpu) >> 2];
338 } else if (addr == (long) &dummy->u_fpvalid) 370 } else if (addr == (long) &dummy->u_fpvalid)
339 tmp = !!tsk_used_math(child); 371 tmp = !!tsk_used_math(child);
@@ -362,7 +394,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
362 else if (addr >= (long) &dummy->fpu && 394 else if (addr >= (long) &dummy->fpu &&
363 addr < (long) &dummy->u_fpvalid) { 395 addr < (long) &dummy->u_fpvalid) {
364 set_stopped_child_used_math(child); 396 set_stopped_child_used_math(child);
365 ((long *)&child->thread.fpu) 397 ((long *)child->thread.xstate)
366 [(addr - (long)&dummy->fpu) >> 2] = data; 398 [(addr - (long)&dummy->fpu) >> 2] = data;
367 ret = 0; 399 ret = 0;
368 } else if (addr == (long) &dummy->u_fpvalid) { 400 } else if (addr == (long) &dummy->u_fpvalid) {
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index c852f7805728..47475cca068a 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -1,19 +1,30 @@
1/* 1/*
2 * linux/arch/sh/kernel/sh_bios.c
3 * C interface for trapping into the standard LinuxSH BIOS. 2 * C interface for trapping into the standard LinuxSH BIOS.
4 * 3 *
5 * Copyright (C) 2000 Greg Banks, Mitch Davis 4 * Copyright (C) 2000 Greg Banks, Mitch Davis
5 * Copyright (C) 1999, 2000 Niibe Yutaka
6 * Copyright (C) 2002 M. R. Brown
7 * Copyright (C) 2004 - 2010 Paul Mundt
6 * 8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
7 */ 12 */
8#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/console.h>
15#include <linux/tty.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/delay.h>
9#include <asm/sh_bios.h> 19#include <asm/sh_bios.h>
10 20
11#define BIOS_CALL_CONSOLE_WRITE 0 21#define BIOS_CALL_CONSOLE_WRITE 0
12#define BIOS_CALL_ETH_NODE_ADDR 10 22#define BIOS_CALL_ETH_NODE_ADDR 10
13#define BIOS_CALL_SHUTDOWN 11 23#define BIOS_CALL_SHUTDOWN 11
14#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */
15#define BIOS_CALL_GDB_DETACH 0xff 24#define BIOS_CALL_GDB_DETACH 0xff
16 25
26void *gdb_vbr_vector = NULL;
27
17static inline long sh_bios_call(long func, long arg0, long arg1, long arg2, 28static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
18 long arg3) 29 long arg3)
19{ 30{
@@ -23,6 +34,9 @@ static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
23 register long r6 __asm__("r6") = arg2; 34 register long r6 __asm__("r6") = arg2;
24 register long r7 __asm__("r7") = arg3; 35 register long r7 __asm__("r7") = arg3;
25 36
37 if (!gdb_vbr_vector)
38 return -ENOSYS;
39
26 __asm__ __volatile__("trapa #0x3f":"=z"(r0) 40 __asm__ __volatile__("trapa #0x3f":"=z"(r0)
27 :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7) 41 :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
28 :"memory"); 42 :"memory");
@@ -34,11 +48,6 @@ void sh_bios_console_write(const char *buf, unsigned int len)
34 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0); 48 sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
35} 49}
36 50
37void sh_bios_char_out(char ch)
38{
39 sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
40}
41
42void sh_bios_gdb_detach(void) 51void sh_bios_gdb_detach(void)
43{ 52{
44 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); 53 sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
@@ -55,3 +64,109 @@ void sh_bios_shutdown(unsigned int how)
55{ 64{
56 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0); 65 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
57} 66}
67
68/*
69 * Read the old value of the VBR register to initialise the vector
70 * through which debug and BIOS traps are delegated by the Linux trap
71 * handler.
72 */
73void sh_bios_vbr_init(void)
74{
75 unsigned long vbr;
76
77 if (unlikely(gdb_vbr_vector))
78 return;
79
80 __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr));
81
82 if (vbr) {
83 gdb_vbr_vector = (void *)(vbr + 0x100);
84 printk(KERN_NOTICE "Setting GDB trap vector to %p\n",
85 gdb_vbr_vector);
86 } else
87 printk(KERN_NOTICE "SH-BIOS not detected\n");
88}
89
90/**
91 * sh_bios_vbr_reload - Re-load the system VBR from the BIOS vector.
92 *
93 * This can be used by save/restore code to reinitialize the system VBR
94 * from the fixed BIOS VBR. A no-op if no BIOS VBR is known.
95 */
96void sh_bios_vbr_reload(void)
97{
98 if (gdb_vbr_vector)
99 __asm__ __volatile__ (
100 "ldc %0, vbr"
101 :
102 : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
103 : "memory"
104 );
105}
106
107/*
108 * Print a string through the BIOS
109 */
110static void sh_console_write(struct console *co, const char *s,
111 unsigned count)
112{
113 sh_bios_console_write(s, count);
114}
115
116/*
117 * Setup initial baud/bits/parity. We do two things here:
118 * - construct a cflag setting for the first rs_open()
119 * - initialize the serial port
120 * Return non-zero if we didn't find a serial port.
121 */
122static int __init sh_console_setup(struct console *co, char *options)
123{
124 int cflag = CREAD | HUPCL | CLOCAL;
125
126 /*
127 * Now construct a cflag setting.
128 * TODO: this is a totally bogus cflag, as we have
129 * no idea what serial settings the BIOS is using, or
130 * even if its using the serial port at all.
131 */
132 cflag |= B115200 | CS8 | /*no parity*/0;
133
134 co->cflag = cflag;
135
136 return 0;
137}
138
139static struct console bios_console = {
140 .name = "bios",
141 .write = sh_console_write,
142 .setup = sh_console_setup,
143 .flags = CON_PRINTBUFFER,
144 .index = -1,
145};
146
147static struct console *early_console;
148
149static int __init setup_early_printk(char *buf)
150{
151 int keep_early = 0;
152
153 if (!buf)
154 return 0;
155
156 if (strstr(buf, "keep"))
157 keep_early = 1;
158
159 if (!strncmp(buf, "bios", 4))
160 early_console = &bios_console;
161
162 if (likely(early_console)) {
163 if (keep_early)
164 early_console->flags &= ~CON_BOOT;
165 else
166 early_console->flags |= CON_BOOT;
167 register_console(early_console);
168 }
169
170 return 0;
171}
172early_param("earlyprintk", setup_early_printk);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 12815ce01ecd..6a7cce79eb4e 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -150,7 +150,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
150 return 0; 150 return 0;
151 151
152 set_used_math(); 152 set_used_math();
153 return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0], 153 return __copy_from_user(&tsk->thread.xstate->hardfpu, &sc->sc_fpregs[0],
154 sizeof(long)*(16*2+2)); 154 sizeof(long)*(16*2+2));
155} 155}
156 156
@@ -175,7 +175,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
175 clear_used_math(); 175 clear_used_math();
176 176
177 unlazy_fpu(tsk, regs); 177 unlazy_fpu(tsk, regs);
178 return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard, 178 return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.xstate->hardfpu,
179 sizeof(long)*(16*2+2)); 179 sizeof(long)*(16*2+2));
180} 180}
181#endif /* CONFIG_SH_FPU */ 181#endif /* CONFIG_SH_FPU */
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 86639beac3a2..9c090cb68878 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -24,13 +24,13 @@
24#include <linux/kdebug.h> 24#include <linux/kdebug.h>
25#include <linux/kexec.h> 25#include <linux/kexec.h>
26#include <linux/limits.h> 26#include <linux/limits.h>
27#include <linux/proc_fs.h>
28#include <linux/seq_file.h>
29#include <linux/sysfs.h> 27#include <linux/sysfs.h>
28#include <linux/uaccess.h>
30#include <asm/system.h> 29#include <asm/system.h>
31#include <asm/uaccess.h> 30#include <asm/alignment.h>
32#include <asm/fpu.h> 31#include <asm/fpu.h>
33#include <asm/kprobes.h> 32#include <asm/kprobes.h>
33#include <asm/sh_bios.h>
34 34
35#ifdef CONFIG_CPU_SH2 35#ifdef CONFIG_CPU_SH2
36# define TRAP_RESERVED_INST 4 36# define TRAP_RESERVED_INST 4
@@ -47,73 +47,6 @@
47#define TRAP_ILLEGAL_SLOT_INST 13 47#define TRAP_ILLEGAL_SLOT_INST 13
48#endif 48#endif
49 49
50static unsigned long se_user;
51static unsigned long se_sys;
52static unsigned long se_half;
53static unsigned long se_word;
54static unsigned long se_dword;
55static unsigned long se_multi;
56/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
57 valid! */
58static int se_usermode = 3;
59/* 0: no warning 1: print a warning message, disabled by default */
60static int se_kernmode_warn;
61
62#ifdef CONFIG_PROC_FS
63static const char *se_usermode_action[] = {
64 "ignored",
65 "warn",
66 "fixup",
67 "fixup+warn",
68 "signal",
69 "signal+warn"
70};
71
72static int alignment_proc_show(struct seq_file *m, void *v)
73{
74 seq_printf(m, "User:\t\t%lu\n", se_user);
75 seq_printf(m, "System:\t\t%lu\n", se_sys);
76 seq_printf(m, "Half:\t\t%lu\n", se_half);
77 seq_printf(m, "Word:\t\t%lu\n", se_word);
78 seq_printf(m, "DWord:\t\t%lu\n", se_dword);
79 seq_printf(m, "Multi:\t\t%lu\n", se_multi);
80 seq_printf(m, "User faults:\t%i (%s)\n", se_usermode,
81 se_usermode_action[se_usermode]);
82 seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
83 se_kernmode_warn ? "+warn" : "");
84 return 0;
85}
86
87static int alignment_proc_open(struct inode *inode, struct file *file)
88{
89 return single_open(file, alignment_proc_show, NULL);
90}
91
92static ssize_t alignment_proc_write(struct file *file,
93 const char __user *buffer, size_t count, loff_t *pos)
94{
95 int *data = PDE(file->f_path.dentry->d_inode)->data;
96 char mode;
97
98 if (count > 0) {
99 if (get_user(mode, buffer))
100 return -EFAULT;
101 if (mode >= '0' && mode <= '5')
102 *data = mode - '0';
103 }
104 return count;
105}
106
107static const struct file_operations alignment_proc_fops = {
108 .owner = THIS_MODULE,
109 .open = alignment_proc_open,
110 .read = seq_read,
111 .llseek = seq_lseek,
112 .release = single_release,
113 .write = alignment_proc_write,
114};
115#endif
116
117static void dump_mem(const char *str, unsigned long bottom, unsigned long top) 50static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
118{ 51{
119 unsigned long p; 52 unsigned long p;
@@ -265,10 +198,10 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
265 count = 1<<(instruction&3); 198 count = 1<<(instruction&3);
266 199
267 switch (count) { 200 switch (count) {
268 case 1: se_half += 1; break; 201 case 1: inc_unaligned_byte_access(); break;
269 case 2: se_word += 1; break; 202 case 2: inc_unaligned_word_access(); break;
270 case 4: se_dword += 1; break; 203 case 4: inc_unaligned_dword_access(); break;
271 case 8: se_multi += 1; break; /* ??? */ 204 case 8: inc_unaligned_multi_access(); break;
272 } 205 }
273 206
274 ret = -EFAULT; 207 ret = -EFAULT;
@@ -452,18 +385,8 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
452 rm = regs->regs[index]; 385 rm = regs->regs[index];
453 386
454 /* shout about fixups */ 387 /* shout about fixups */
455 if (!expected) { 388 if (!expected)
456 if (user_mode(regs) && (se_usermode & 1) && printk_ratelimit()) 389 unaligned_fixups_notify(current, instruction, regs);
457 pr_notice("Fixing up unaligned userspace access "
458 "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
459 current->comm, task_pid_nr(current),
460 (void *)regs->pc, instruction);
461 else if (se_kernmode_warn && printk_ratelimit())
462 pr_notice("Fixing up unaligned kernel access "
463 "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
464 current->comm, task_pid_nr(current),
465 (void *)regs->pc, instruction);
466 }
467 390
468 ret = -EFAULT; 391 ret = -EFAULT;
469 switch (instruction&0xF000) { 392 switch (instruction&0xF000) {
@@ -616,10 +539,10 @@ asmlinkage void do_address_error(struct pt_regs *regs,
616 539
617 if (user_mode(regs)) { 540 if (user_mode(regs)) {
618 int si_code = BUS_ADRERR; 541 int si_code = BUS_ADRERR;
542 unsigned int user_action;
619 543
620 local_irq_enable(); 544 local_irq_enable();
621 545 inc_unaligned_user_access();
622 se_user += 1;
623 546
624 set_fs(USER_DS); 547 set_fs(USER_DS);
625 if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1), 548 if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1),
@@ -630,16 +553,12 @@ asmlinkage void do_address_error(struct pt_regs *regs,
630 set_fs(oldfs); 553 set_fs(oldfs);
631 554
632 /* shout about userspace fixups */ 555 /* shout about userspace fixups */
633 if (se_usermode & 1) 556 unaligned_fixups_notify(current, instruction, regs);
634 printk(KERN_NOTICE "Unaligned userspace access "
635 "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
636 current->comm, current->pid, (void *)regs->pc,
637 instruction);
638 557
639 if (se_usermode & 2) 558 user_action = unaligned_user_action();
559 if (user_action & UM_FIXUP)
640 goto fixup; 560 goto fixup;
641 561 if (user_action & UM_SIGNAL)
642 if (se_usermode & 4)
643 goto uspace_segv; 562 goto uspace_segv;
644 else { 563 else {
645 /* ignore */ 564 /* ignore */
@@ -659,7 +578,7 @@ fixup:
659 &user_mem_access, 0); 578 &user_mem_access, 0);
660 set_fs(oldfs); 579 set_fs(oldfs);
661 580
662 if (tmp==0) 581 if (tmp == 0)
663 return; /* sorted */ 582 return; /* sorted */
664uspace_segv: 583uspace_segv:
665 printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned " 584 printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
@@ -672,7 +591,7 @@ uspace_segv:
672 info.si_addr = (void __user *)address; 591 info.si_addr = (void __user *)address;
673 force_sig_info(SIGBUS, &info, current); 592 force_sig_info(SIGBUS, &info, current);
674 } else { 593 } else {
675 se_sys += 1; 594 inc_unaligned_kernel_access();
676 595
677 if (regs->pc & 1) 596 if (regs->pc & 1)
678 die("unaligned program counter", regs, error_code); 597 die("unaligned program counter", regs, error_code);
@@ -687,11 +606,7 @@ uspace_segv:
687 die("insn faulting in do_address_error", regs, 0); 606 die("insn faulting in do_address_error", regs, 0);
688 } 607 }
689 608
690 if (se_kernmode_warn) 609 unaligned_fixups_notify(current, instruction, regs);
691 printk(KERN_NOTICE "Unaligned kernel access "
692 "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
693 current->comm, current->pid, (void *)regs->pc,
694 instruction);
695 610
696 handle_unaligned_access(instruction, regs, 611 handle_unaligned_access(instruction, regs,
697 &user_mem_access, 0); 612 &user_mem_access, 0);
@@ -876,35 +791,10 @@ asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
876 die_if_kernel("exception", regs, ex); 791 die_if_kernel("exception", regs, ex);
877} 792}
878 793
879#if defined(CONFIG_SH_STANDARD_BIOS)
880void *gdb_vbr_vector;
881
882static inline void __init gdb_vbr_init(void)
883{
884 register unsigned long vbr;
885
886 /*
887 * Read the old value of the VBR register to initialise
888 * the vector through which debug and BIOS traps are
889 * delegated by the Linux trap handler.
890 */
891 asm volatile("stc vbr, %0" : "=r" (vbr));
892
893 gdb_vbr_vector = (void *)(vbr + 0x100);
894 printk("Setting GDB trap vector to 0x%08lx\n",
895 (unsigned long)gdb_vbr_vector);
896}
897#endif
898
899void __cpuinit per_cpu_trap_init(void) 794void __cpuinit per_cpu_trap_init(void)
900{ 795{
901 extern void *vbr_base; 796 extern void *vbr_base;
902 797
903#ifdef CONFIG_SH_STANDARD_BIOS
904 if (raw_smp_processor_id() == 0)
905 gdb_vbr_init();
906#endif
907
908 /* NOTE: The VBR value should be at P1 798 /* NOTE: The VBR value should be at P1
909 (or P2, virtural "fixed" address space). 799 (or P2, virtural "fixed" address space).
910 It's definitely should not in physical address. */ 800 It's definitely should not in physical address. */
@@ -956,9 +846,12 @@ void __init trap_init(void)
956#endif 846#endif
957 847
958#ifdef TRAP_UBC 848#ifdef TRAP_UBC
959 set_exception_table_vec(TRAP_UBC, break_point_trap); 849 set_exception_table_vec(TRAP_UBC, breakpoint_trap_handler);
960#endif 850#endif
961 851
852 /* Save off the BIOS VBR, if there is one */
853 sh_bios_vbr_init();
854
962 /* Setup VBR for boot cpu */ 855 /* Setup VBR for boot cpu */
963 per_cpu_trap_init(); 856 per_cpu_trap_init();
964} 857}
@@ -985,34 +878,3 @@ void dump_stack(void)
985 show_stack(NULL, NULL); 878 show_stack(NULL, NULL);
986} 879}
987EXPORT_SYMBOL(dump_stack); 880EXPORT_SYMBOL(dump_stack);
988
989#ifdef CONFIG_PROC_FS
990/*
991 * This needs to be done after sysctl_init, otherwise sys/ will be
992 * overwritten. Actually, this shouldn't be in sys/ at all since
993 * it isn't a sysctl, and it doesn't contain sysctl information.
994 * We now locate it in /proc/cpu/alignment instead.
995 */
996static int __init alignment_init(void)
997{
998 struct proc_dir_entry *dir, *res;
999
1000 dir = proc_mkdir("cpu", NULL);
1001 if (!dir)
1002 return -ENOMEM;
1003
1004 res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir,
1005 &alignment_proc_fops, &se_usermode);
1006 if (!res)
1007 return -ENOMEM;
1008
1009 res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir,
1010 &alignment_proc_fops, &se_kernmode_warn);
1011 if (!res)
1012 return -ENOMEM;
1013
1014 return 0;
1015}
1016
1017fs_initcall(alignment_init);
1018#endif