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