diff options
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r-- | arch/arm/kernel/setup.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index d5231ae7355a..336f14e0e5c2 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/procinfo.h> | 36 | #include <asm/procinfo.h> |
37 | #include <asm/sections.h> | 37 | #include <asm/sections.h> |
38 | #include <asm/setup.h> | 38 | #include <asm/setup.h> |
39 | #include <asm/smp_plat.h> | ||
39 | #include <asm/mach-types.h> | 40 | #include <asm/mach-types.h> |
40 | #include <asm/cacheflush.h> | 41 | #include <asm/cacheflush.h> |
41 | #include <asm/cachetype.h> | 42 | #include <asm/cachetype.h> |
@@ -238,6 +239,35 @@ int cpu_architecture(void) | |||
238 | return cpu_arch; | 239 | return cpu_arch; |
239 | } | 240 | } |
240 | 241 | ||
242 | static int cpu_has_aliasing_icache(unsigned int arch) | ||
243 | { | ||
244 | int aliasing_icache; | ||
245 | unsigned int id_reg, num_sets, line_size; | ||
246 | |||
247 | /* arch specifies the register format */ | ||
248 | switch (arch) { | ||
249 | case CPU_ARCH_ARMv7: | ||
250 | asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR" | ||
251 | : /* No output operands */ | ||
252 | : "r" (1)); | ||
253 | isb(); | ||
254 | asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR" | ||
255 | : "=r" (id_reg)); | ||
256 | line_size = 4 << ((id_reg & 0x7) + 2); | ||
257 | num_sets = ((id_reg >> 13) & 0x7fff) + 1; | ||
258 | aliasing_icache = (line_size * num_sets) > PAGE_SIZE; | ||
259 | break; | ||
260 | case CPU_ARCH_ARMv6: | ||
261 | aliasing_icache = read_cpuid_cachetype() & (1 << 11); | ||
262 | break; | ||
263 | default: | ||
264 | /* I-cache aliases will be handled by D-cache aliasing code */ | ||
265 | aliasing_icache = 0; | ||
266 | } | ||
267 | |||
268 | return aliasing_icache; | ||
269 | } | ||
270 | |||
241 | static void __init cacheid_init(void) | 271 | static void __init cacheid_init(void) |
242 | { | 272 | { |
243 | unsigned int cachetype = read_cpuid_cachetype(); | 273 | unsigned int cachetype = read_cpuid_cachetype(); |
@@ -249,10 +279,15 @@ static void __init cacheid_init(void) | |||
249 | cacheid = CACHEID_VIPT_NONALIASING; | 279 | cacheid = CACHEID_VIPT_NONALIASING; |
250 | if ((cachetype & (3 << 14)) == 1 << 14) | 280 | if ((cachetype & (3 << 14)) == 1 << 14) |
251 | cacheid |= CACHEID_ASID_TAGGED; | 281 | cacheid |= CACHEID_ASID_TAGGED; |
252 | } else if (cachetype & (1 << 23)) | 282 | else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7)) |
283 | cacheid |= CACHEID_VIPT_I_ALIASING; | ||
284 | } else if (cachetype & (1 << 23)) { | ||
253 | cacheid = CACHEID_VIPT_ALIASING; | 285 | cacheid = CACHEID_VIPT_ALIASING; |
254 | else | 286 | } else { |
255 | cacheid = CACHEID_VIPT_NONALIASING; | 287 | cacheid = CACHEID_VIPT_NONALIASING; |
288 | if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6)) | ||
289 | cacheid |= CACHEID_VIPT_I_ALIASING; | ||
290 | } | ||
256 | } else { | 291 | } else { |
257 | cacheid = CACHEID_VIVT; | 292 | cacheid = CACHEID_VIVT; |
258 | } | 293 | } |
@@ -263,7 +298,7 @@ static void __init cacheid_init(void) | |||
263 | cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown", | 298 | cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown", |
264 | cache_is_vivt() ? "VIVT" : | 299 | cache_is_vivt() ? "VIVT" : |
265 | icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" : | 300 | icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" : |
266 | cache_is_vipt_aliasing() ? "VIPT aliasing" : | 301 | icache_is_vipt_aliasing() ? "VIPT aliasing" : |
267 | cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown"); | 302 | cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown"); |
268 | } | 303 | } |
269 | 304 | ||
@@ -490,7 +525,7 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) | |||
490 | 525 | ||
491 | kernel_code.start = virt_to_phys(_text); | 526 | kernel_code.start = virt_to_phys(_text); |
492 | kernel_code.end = virt_to_phys(_etext - 1); | 527 | kernel_code.end = virt_to_phys(_etext - 1); |
493 | kernel_data.start = virt_to_phys(_data); | 528 | kernel_data.start = virt_to_phys(_sdata); |
494 | kernel_data.end = virt_to_phys(_end - 1); | 529 | kernel_data.end = virt_to_phys(_end - 1); |
495 | 530 | ||
496 | for (i = 0; i < mi->nr_banks; i++) { | 531 | for (i = 0; i < mi->nr_banks; i++) { |
@@ -825,7 +860,8 @@ void __init setup_arch(char **cmdline_p) | |||
825 | request_standard_resources(&meminfo, mdesc); | 860 | request_standard_resources(&meminfo, mdesc); |
826 | 861 | ||
827 | #ifdef CONFIG_SMP | 862 | #ifdef CONFIG_SMP |
828 | smp_init_cpus(); | 863 | if (is_smp()) |
864 | smp_init_cpus(); | ||
829 | #endif | 865 | #endif |
830 | reserve_crashkernel(); | 866 | reserve_crashkernel(); |
831 | 867 | ||