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 | } |
