diff options
Diffstat (limited to 'arch/sh/kernel/cpu/init.c')
-rw-r--r-- | arch/sh/kernel/cpu/init.c | 125 |
1 files changed, 75 insertions, 50 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 89b4b76c0d76..c736422344eb 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c | |||
@@ -24,22 +24,32 @@ | |||
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 | #include <asm/sh_bios.h> |
28 | #include <asm/ubc.h> | 28 | |
29 | #ifdef CONFIG_SH_FPU | ||
30 | #define cpu_has_fpu 1 | ||
31 | #else | ||
32 | #define cpu_has_fpu 0 | ||
33 | #endif | ||
34 | |||
35 | #ifdef CONFIG_SH_DSP | ||
36 | #define cpu_has_dsp 1 | ||
37 | #else | ||
38 | #define cpu_has_dsp 0 | ||
29 | #endif | 39 | #endif |
30 | 40 | ||
31 | /* | 41 | /* |
32 | * Generic wrapper for command line arguments to disable on-chip | 42 | * Generic wrapper for command line arguments to disable on-chip |
33 | * peripherals (nofpu, nodsp, and so forth). | 43 | * peripherals (nofpu, nodsp, and so forth). |
34 | */ | 44 | */ |
35 | #define onchip_setup(x) \ | 45 | #define onchip_setup(x) \ |
36 | static int x##_disabled __initdata = 0; \ | 46 | static int x##_disabled __initdata = !cpu_has_##x; \ |
37 | \ | 47 | \ |
38 | static int __init x##_setup(char *opts) \ | 48 | static int __init x##_setup(char *opts) \ |
39 | { \ | 49 | { \ |
40 | x##_disabled = 1; \ | 50 | x##_disabled = 1; \ |
41 | return 1; \ | 51 | return 1; \ |
42 | } \ | 52 | } \ |
43 | __setup("no" __stringify(x), x##_setup); | 53 | __setup("no" __stringify(x), x##_setup); |
44 | 54 | ||
45 | onchip_setup(fpu); | 55 | onchip_setup(fpu); |
@@ -52,10 +62,10 @@ onchip_setup(dsp); | |||
52 | static void __init speculative_execution_init(void) | 62 | static void __init speculative_execution_init(void) |
53 | { | 63 | { |
54 | /* Clear RABD */ | 64 | /* Clear RABD */ |
55 | ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM); | 65 | __raw_writel(__raw_readl(CPUOPM) & ~CPUOPM_RABD, CPUOPM); |
56 | 66 | ||
57 | /* Flush the update */ | 67 | /* Flush the update */ |
58 | (void)ctrl_inl(CPUOPM); | 68 | (void)__raw_readl(CPUOPM); |
59 | ctrl_barrier(); | 69 | ctrl_barrier(); |
60 | } | 70 | } |
61 | #else | 71 | #else |
@@ -89,7 +99,7 @@ static void __init expmask_init(void) | |||
89 | #endif | 99 | #endif |
90 | 100 | ||
91 | /* 2nd-level cache init */ | 101 | /* 2nd-level cache init */ |
92 | void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void) | 102 | void __attribute__ ((weak)) l2_cache_init(void) |
93 | { | 103 | { |
94 | } | 104 | } |
95 | 105 | ||
@@ -97,12 +107,12 @@ void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void) | |||
97 | * Generic first-level cache init | 107 | * Generic first-level cache init |
98 | */ | 108 | */ |
99 | #ifdef CONFIG_SUPERH32 | 109 | #ifdef CONFIG_SUPERH32 |
100 | static void __uses_jump_to_uncached cache_init(void) | 110 | static void cache_init(void) |
101 | { | 111 | { |
102 | unsigned long ccr, flags; | 112 | unsigned long ccr, flags; |
103 | 113 | ||
104 | jump_to_uncached(); | 114 | jump_to_uncached(); |
105 | ccr = ctrl_inl(CCR); | 115 | ccr = __raw_readl(CCR); |
106 | 116 | ||
107 | /* | 117 | /* |
108 | * At this point we don't know whether the cache is enabled or not - a | 118 | * At this point we don't know whether the cache is enabled or not - a |
@@ -146,7 +156,7 @@ static void __uses_jump_to_uncached cache_init(void) | |||
146 | for (addr = addrstart; | 156 | for (addr = addrstart; |
147 | addr < addrstart + waysize; | 157 | addr < addrstart + waysize; |
148 | addr += current_cpu_data.dcache.linesz) | 158 | addr += current_cpu_data.dcache.linesz) |
149 | ctrl_outl(0, addr); | 159 | __raw_writel(0, addr); |
150 | 160 | ||
151 | addrstart += current_cpu_data.dcache.way_incr; | 161 | addrstart += current_cpu_data.dcache.way_incr; |
152 | } while (--ways); | 162 | } while (--ways); |
@@ -179,7 +189,7 @@ static void __uses_jump_to_uncached cache_init(void) | |||
179 | 189 | ||
180 | l2_cache_init(); | 190 | l2_cache_init(); |
181 | 191 | ||
182 | ctrl_outl(flags, CCR); | 192 | __raw_writel(flags, CCR); |
183 | back_to_cached(); | 193 | back_to_cached(); |
184 | } | 194 | } |
185 | #else | 195 | #else |
@@ -207,6 +217,18 @@ static void detect_cache_shape(void) | |||
207 | l2_cache_shape = -1; /* No S-cache */ | 217 | l2_cache_shape = -1; /* No S-cache */ |
208 | } | 218 | } |
209 | 219 | ||
220 | static void __init fpu_init(void) | ||
221 | { | ||
222 | /* Disable the FPU */ | ||
223 | if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) { | ||
224 | printk("FPU Disabled\n"); | ||
225 | current_cpu_data.flags &= ~CPU_HAS_FPU; | ||
226 | } | ||
227 | |||
228 | disable_fpu(); | ||
229 | clear_used_math(); | ||
230 | } | ||
231 | |||
210 | #ifdef CONFIG_SH_DSP | 232 | #ifdef CONFIG_SH_DSP |
211 | static void __init release_dsp(void) | 233 | static void __init release_dsp(void) |
212 | { | 234 | { |
@@ -244,28 +266,35 @@ static void __init dsp_init(void) | |||
244 | if (sr & SR_DSP) | 266 | if (sr & SR_DSP) |
245 | current_cpu_data.flags |= CPU_HAS_DSP; | 267 | current_cpu_data.flags |= CPU_HAS_DSP; |
246 | 268 | ||
269 | /* Disable the DSP */ | ||
270 | if (dsp_disabled && (current_cpu_data.flags & CPU_HAS_DSP)) { | ||
271 | printk("DSP Disabled\n"); | ||
272 | current_cpu_data.flags &= ~CPU_HAS_DSP; | ||
273 | } | ||
274 | |||
247 | /* Now that we've determined the DSP status, clear the DSP bit. */ | 275 | /* Now that we've determined the DSP status, clear the DSP bit. */ |
248 | release_dsp(); | 276 | release_dsp(); |
249 | } | 277 | } |
278 | #else | ||
279 | static inline void __init dsp_init(void) { } | ||
250 | #endif /* CONFIG_SH_DSP */ | 280 | #endif /* CONFIG_SH_DSP */ |
251 | 281 | ||
252 | /** | 282 | /** |
253 | * sh_cpu_init | 283 | * sh_cpu_init |
254 | * | 284 | * |
255 | * This is our initial entry point for each CPU, and is invoked on the boot | 285 | * 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 | 286 | * 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 | 287 | * this and start_secondary() will bring up each processor to a ready |
258 | * to hand forking the idle loop. | 288 | * state prior to hand forking the idle loop. |
259 | * | 289 | * |
260 | * We do all of the basic processor init here, including setting up the | 290 | * 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 | 291 | * the caches, FPU, DSP, etc. By the time start_kernel() is hit (and |
262 | * hit (and subsequently platform_setup()) things like determining the | 292 | * subsequently platform_setup()) things like determining the CPU |
263 | * CPU subtype and initial configuration will all be done. | 293 | * subtype and initial configuration will all be done. |
264 | * | 294 | * |
265 | * Each processor family is still responsible for doing its own probing | 295 | * Each processor family is still responsible for doing its own probing |
266 | * and cache configuration in detect_cpu_and_cache_system(). | 296 | * and cache configuration in detect_cpu_and_cache_system(). |
267 | */ | 297 | */ |
268 | |||
269 | asmlinkage void __init sh_cpu_init(void) | 298 | asmlinkage void __init sh_cpu_init(void) |
270 | { | 299 | { |
271 | current_thread_info()->cpu = hard_smp_processor_id(); | 300 | current_thread_info()->cpu = hard_smp_processor_id(); |
@@ -302,18 +331,8 @@ asmlinkage void __init sh_cpu_init(void) | |||
302 | detect_cache_shape(); | 331 | detect_cache_shape(); |
303 | } | 332 | } |
304 | 333 | ||
305 | /* Disable the FPU */ | 334 | fpu_init(); |
306 | if (fpu_disabled) { | 335 | 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 | 336 | ||
318 | /* | 337 | /* |
319 | * Initialize the per-CPU ASID cache very early, since the | 338 | * Initialize the per-CPU ASID cache very early, since the |
@@ -321,18 +340,24 @@ asmlinkage void __init sh_cpu_init(void) | |||
321 | */ | 340 | */ |
322 | current_cpu_data.asid_cache = NO_CONTEXT; | 341 | current_cpu_data.asid_cache = NO_CONTEXT; |
323 | 342 | ||
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(); | 343 | speculative_execution_init(); |
337 | expmask_init(); | 344 | expmask_init(); |
345 | |||
346 | /* Do the rest of the boot processor setup */ | ||
347 | if (raw_smp_processor_id() == 0) { | ||
348 | /* Save off the BIOS VBR, if there is one */ | ||
349 | sh_bios_vbr_init(); | ||
350 | |||
351 | /* | ||
352 | * Setup VBR for boot CPU. Secondary CPUs do this through | ||
353 | * start_secondary(). | ||
354 | */ | ||
355 | per_cpu_trap_init(); | ||
356 | |||
357 | /* | ||
358 | * Boot processor to setup the FP and extended state | ||
359 | * context info. | ||
360 | */ | ||
361 | init_thread_xstate(); | ||
362 | } | ||
338 | } | 363 | } |