diff options
Diffstat (limited to 'arch/sh/kernel/cpu/init.c')
-rw-r--r-- | arch/sh/kernel/cpu/init.c | 74 |
1 files changed, 55 insertions, 19 deletions
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index c217c4bf0085..80a31329ead9 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/log2.h> | ||
16 | #include <asm/mmu_context.h> | 17 | #include <asm/mmu_context.h> |
17 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
18 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
@@ -20,9 +21,12 @@ | |||
20 | #include <asm/system.h> | 21 | #include <asm/system.h> |
21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
22 | #include <asm/cache.h> | 23 | #include <asm/cache.h> |
24 | #include <asm/elf.h> | ||
23 | #include <asm/io.h> | 25 | #include <asm/io.h> |
24 | #include <asm/ubc.h> | ||
25 | #include <asm/smp.h> | 26 | #include <asm/smp.h> |
27 | #ifdef CONFIG_SUPERH32 | ||
28 | #include <asm/ubc.h> | ||
29 | #endif | ||
26 | 30 | ||
27 | /* | 31 | /* |
28 | * Generic wrapper for command line arguments to disable on-chip | 32 | * Generic wrapper for command line arguments to disable on-chip |
@@ -61,25 +65,12 @@ static void __init speculative_execution_init(void) | |||
61 | /* | 65 | /* |
62 | * Generic first-level cache init | 66 | * Generic first-level cache init |
63 | */ | 67 | */ |
64 | static void __init cache_init(void) | 68 | #ifdef CONFIG_SUPERH32 |
69 | static void __uses_jump_to_uncached cache_init(void) | ||
65 | { | 70 | { |
66 | unsigned long ccr, flags; | 71 | unsigned long ccr, flags; |
67 | 72 | ||
68 | /* First setup the rest of the I-cache info */ | 73 | jump_to_uncached(); |
69 | current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr - | ||
70 | current_cpu_data.icache.linesz; | ||
71 | |||
72 | current_cpu_data.icache.way_size = current_cpu_data.icache.sets * | ||
73 | current_cpu_data.icache.linesz; | ||
74 | |||
75 | /* And the D-cache too */ | ||
76 | current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr - | ||
77 | current_cpu_data.dcache.linesz; | ||
78 | |||
79 | current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets * | ||
80 | current_cpu_data.dcache.linesz; | ||
81 | |||
82 | jump_to_P2(); | ||
83 | ccr = ctrl_inl(CCR); | 74 | ccr = ctrl_inl(CCR); |
84 | 75 | ||
85 | /* | 76 | /* |
@@ -156,7 +147,31 @@ static void __init cache_init(void) | |||
156 | #endif | 147 | #endif |
157 | 148 | ||
158 | ctrl_outl(flags, CCR); | 149 | ctrl_outl(flags, CCR); |
159 | back_to_P1(); | 150 | back_to_cached(); |
151 | } | ||
152 | #else | ||
153 | #define cache_init() do { } while (0) | ||
154 | #endif | ||
155 | |||
156 | #define CSHAPE(totalsize, linesize, assoc) \ | ||
157 | ((totalsize & ~0xff) | (linesize << 4) | assoc) | ||
158 | |||
159 | #define CACHE_DESC_SHAPE(desc) \ | ||
160 | CSHAPE((desc).way_size * (desc).ways, ilog2((desc).linesz), (desc).ways) | ||
161 | |||
162 | static void detect_cache_shape(void) | ||
163 | { | ||
164 | l1d_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.dcache); | ||
165 | |||
166 | if (current_cpu_data.dcache.flags & SH_CACHE_COMBINED) | ||
167 | l1i_cache_shape = l1d_cache_shape; | ||
168 | else | ||
169 | l1i_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.icache); | ||
170 | |||
171 | if (current_cpu_data.flags & CPU_HAS_L2_CACHE) | ||
172 | l2_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.scache); | ||
173 | else | ||
174 | l2_cache_shape = -1; /* No S-cache */ | ||
160 | } | 175 | } |
161 | 176 | ||
162 | #ifdef CONFIG_SH_DSP | 177 | #ifdef CONFIG_SH_DSP |
@@ -228,14 +243,32 @@ asmlinkage void __cpuinit sh_cpu_init(void) | |||
228 | if (current_cpu_data.type == CPU_SH_NONE) | 243 | if (current_cpu_data.type == CPU_SH_NONE) |
229 | panic("Unknown CPU"); | 244 | panic("Unknown CPU"); |
230 | 245 | ||
246 | /* First setup the rest of the I-cache info */ | ||
247 | current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr - | ||
248 | current_cpu_data.icache.linesz; | ||
249 | |||
250 | current_cpu_data.icache.way_size = current_cpu_data.icache.sets * | ||
251 | current_cpu_data.icache.linesz; | ||
252 | |||
253 | /* And the D-cache too */ | ||
254 | current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr - | ||
255 | current_cpu_data.dcache.linesz; | ||
256 | |||
257 | current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets * | ||
258 | current_cpu_data.dcache.linesz; | ||
259 | |||
231 | /* Init the cache */ | 260 | /* Init the cache */ |
232 | cache_init(); | 261 | cache_init(); |
233 | 262 | ||
234 | if (raw_smp_processor_id() == 0) | 263 | if (raw_smp_processor_id() == 0) { |
235 | shm_align_mask = max_t(unsigned long, | 264 | shm_align_mask = max_t(unsigned long, |
236 | current_cpu_data.dcache.way_size - 1, | 265 | current_cpu_data.dcache.way_size - 1, |
237 | PAGE_SIZE - 1); | 266 | PAGE_SIZE - 1); |
238 | 267 | ||
268 | /* Boot CPU sets the cache shape */ | ||
269 | detect_cache_shape(); | ||
270 | } | ||
271 | |||
239 | /* Disable the FPU */ | 272 | /* Disable the FPU */ |
240 | if (fpu_disabled) { | 273 | if (fpu_disabled) { |
241 | printk("FPU Disabled\n"); | 274 | printk("FPU Disabled\n"); |
@@ -273,7 +306,10 @@ asmlinkage void __cpuinit sh_cpu_init(void) | |||
273 | * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. | 306 | * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. |
274 | * we wake it up and hope that all is well. | 307 | * we wake it up and hope that all is well. |
275 | */ | 308 | */ |
309 | #ifdef CONFIG_SUPERH32 | ||
276 | if (raw_smp_processor_id() == 0) | 310 | if (raw_smp_processor_id() == 0) |
277 | ubc_wakeup(); | 311 | ubc_wakeup(); |
312 | #endif | ||
313 | |||
278 | speculative_execution_init(); | 314 | speculative_execution_init(); |
279 | } | 315 | } |