diff options
author | Will Deacon <will.deacon@arm.com> | 2011-08-23 17:22:11 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-10-17 04:13:41 -0400 |
commit | 7f94e9cc5e965519d865bf20215036f359a1e299 (patch) | |
tree | 0c3e4254e4d11255b15c64dcc613599f0a149f83 /arch/arm/kernel | |
parent | 0744a3ee37784dfda0025963716a36c3f1e3adcc (diff) |
ARM: 7062/1: cache: detect PIPT I-cache using CTR
The Cache Type Register L1Ip field identifies I-caches with a PIPT
policy using the encoding 11b.
This patch extends the cache policy parsing to identify PIPT I-caches
correctly and prevent them from being treated as VIPT aliasing in cases
where they are sufficiently large.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/setup.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 93e39a3d2c1e..3fe93f75b55a 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -265,6 +265,10 @@ static int cpu_has_aliasing_icache(unsigned int arch) | |||
265 | int aliasing_icache; | 265 | int aliasing_icache; |
266 | unsigned int id_reg, num_sets, line_size; | 266 | unsigned int id_reg, num_sets, line_size; |
267 | 267 | ||
268 | /* PIPT caches never alias. */ | ||
269 | if (icache_is_pipt()) | ||
270 | return 0; | ||
271 | |||
268 | /* arch specifies the register format */ | 272 | /* arch specifies the register format */ |
269 | switch (arch) { | 273 | switch (arch) { |
270 | case CPU_ARCH_ARMv7: | 274 | case CPU_ARCH_ARMv7: |
@@ -299,8 +303,14 @@ static void __init cacheid_init(void) | |||
299 | /* ARMv7 register format */ | 303 | /* ARMv7 register format */ |
300 | arch = CPU_ARCH_ARMv7; | 304 | arch = CPU_ARCH_ARMv7; |
301 | cacheid = CACHEID_VIPT_NONALIASING; | 305 | cacheid = CACHEID_VIPT_NONALIASING; |
302 | if ((cachetype & (3 << 14)) == 1 << 14) | 306 | switch (cachetype & (3 << 14)) { |
307 | case (1 << 14): | ||
303 | cacheid |= CACHEID_ASID_TAGGED; | 308 | cacheid |= CACHEID_ASID_TAGGED; |
309 | break; | ||
310 | case (3 << 14): | ||
311 | cacheid |= CACHEID_PIPT; | ||
312 | break; | ||
313 | } | ||
304 | } else { | 314 | } else { |
305 | arch = CPU_ARCH_ARMv6; | 315 | arch = CPU_ARCH_ARMv6; |
306 | if (cachetype & (1 << 23)) | 316 | if (cachetype & (1 << 23)) |
@@ -317,10 +327,11 @@ static void __init cacheid_init(void) | |||
317 | printk("CPU: %s data cache, %s instruction cache\n", | 327 | printk("CPU: %s data cache, %s instruction cache\n", |
318 | cache_is_vivt() ? "VIVT" : | 328 | cache_is_vivt() ? "VIVT" : |
319 | cache_is_vipt_aliasing() ? "VIPT aliasing" : | 329 | cache_is_vipt_aliasing() ? "VIPT aliasing" : |
320 | cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown", | 330 | cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown", |
321 | cache_is_vivt() ? "VIVT" : | 331 | cache_is_vivt() ? "VIVT" : |
322 | icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" : | 332 | icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" : |
323 | icache_is_vipt_aliasing() ? "VIPT aliasing" : | 333 | icache_is_vipt_aliasing() ? "VIPT aliasing" : |
334 | icache_is_pipt() ? "PIPT" : | ||
324 | cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown"); | 335 | cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown"); |
325 | } | 336 | } |
326 | 337 | ||