aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/init.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-01-12 22:51:40 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-01-12 22:51:40 -0500
commit0ea820cf9bf58f735ed40ec67947159c4f170012 (patch)
tree77320006b4dded5804c678c1a869571be5c0b95f /arch/sh/kernel/cpu/init.c
parenta3705799e2cc5fb69d88ad6a7f317a8f5597f18d (diff)
sh: Move over to dynamically allocated FPU context.
This follows the x86 xstate changes and implements a task_xstate slab cache that is dynamically sized to match one of hard FP/soft FP/FPU-less. This also tidies up and consolidates some of the SH-2A/SH-4 FPU fragmentation. Now fpu state restorers are commonly defined, with the init_fpu()/fpu_init() mess reworked to follow the x86 convention. The fpu_init() register initialization has been replaced by xstate setup followed by writing out to hardware via the standard restore path. As init_fpu() now performs a slab allocation a secondary lighterweight restorer is also introduced for the context switch. In the future the DSP state will be rolled in here, too. More work remains for math emulation and the SH-5 FPU, which presently uses its own special (UP-only) interfaces. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu/init.c')
-rw-r--r--arch/sh/kernel/cpu/init.c80
1 files changed, 48 insertions, 32 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 89b4b76c0d76..2e23422280a7 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -28,18 +28,30 @@
28#include <asm/ubc.h> 28#include <asm/ubc.h>
29#endif 29#endif
30 30
31#ifdef CONFIG_SH_FPU
32#define cpu_has_fpu 1
33#else
34#define cpu_has_fpu 0
35#endif
36
37#ifdef CONFIG_SH_DSP
38#define cpu_has_dsp 1
39#else
40#define cpu_has_dsp 0
41#endif
42
31/* 43/*
32 * Generic wrapper for command line arguments to disable on-chip 44 * Generic wrapper for command line arguments to disable on-chip
33 * peripherals (nofpu, nodsp, and so forth). 45 * peripherals (nofpu, nodsp, and so forth).
34 */ 46 */
35#define onchip_setup(x) \ 47#define onchip_setup(x) \
36static int x##_disabled __initdata = 0; \ 48static int x##_disabled __initdata = !cpu_has_##x; \
37 \ 49 \
38static int __init x##_setup(char *opts) \ 50static int __init x##_setup(char *opts) \
39{ \ 51{ \
40 x##_disabled = 1; \ 52 x##_disabled = 1; \
41 return 1; \ 53 return 1; \
42} \ 54} \
43__setup("no" __stringify(x), x##_setup); 55__setup("no" __stringify(x), x##_setup);
44 56
45onchip_setup(fpu); 57onchip_setup(fpu);
@@ -207,6 +219,18 @@ static void detect_cache_shape(void)
207 l2_cache_shape = -1; /* No S-cache */ 219 l2_cache_shape = -1; /* No S-cache */
208} 220}
209 221
222static void __init fpu_init(void)
223{
224 /* Disable the FPU */
225 if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) {
226 printk("FPU Disabled\n");
227 current_cpu_data.flags &= ~CPU_HAS_FPU;
228 }
229
230 disable_fpu();
231 clear_used_math();
232}
233
210#ifdef CONFIG_SH_DSP 234#ifdef CONFIG_SH_DSP
211static void __init release_dsp(void) 235static void __init release_dsp(void)
212{ 236{
@@ -244,9 +268,17 @@ static void __init dsp_init(void)
244 if (sr & SR_DSP) 268 if (sr & SR_DSP)
245 current_cpu_data.flags |= CPU_HAS_DSP; 269 current_cpu_data.flags |= CPU_HAS_DSP;
246 270
271 /* Disable the DSP */
272 if (dsp_disabled && (current_cpu_data.flags & CPU_HAS_DSP)) {
273 printk("DSP Disabled\n");
274 current_cpu_data.flags &= ~CPU_HAS_DSP;
275 }
276
247 /* Now that we've determined the DSP status, clear the DSP bit. */ 277 /* Now that we've determined the DSP status, clear the DSP bit. */
248 release_dsp(); 278 release_dsp();
249} 279}
280#else
281static inline void __init dsp_init(void) { }
250#endif /* CONFIG_SH_DSP */ 282#endif /* CONFIG_SH_DSP */
251 283
252/** 284/**
@@ -302,18 +334,8 @@ asmlinkage void __init sh_cpu_init(void)
302 detect_cache_shape(); 334 detect_cache_shape();
303 } 335 }
304 336
305 /* Disable the FPU */ 337 fpu_init();
306 if (fpu_disabled) { 338 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 339
318 /* 340 /*
319 * Initialize the per-CPU ASID cache very early, since the 341 * Initialize the per-CPU ASID cache very early, since the
@@ -321,18 +343,12 @@ asmlinkage void __init sh_cpu_init(void)
321 */ 343 */
322 current_cpu_data.asid_cache = NO_CONTEXT; 344 current_cpu_data.asid_cache = NO_CONTEXT;
323 345
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(); 346 speculative_execution_init();
337 expmask_init(); 347 expmask_init();
348
349 /*
350 * Boot processor to setup the FP and extended state context info.
351 */
352 if (raw_smp_processor_id() == 0)
353 init_thread_xstate();
338} 354}