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>
This commit is contained in:
parent
0744a3ee37
commit
7f94e9cc5e
@ -7,6 +7,7 @@
|
|||||||
#define CACHEID_VIPT (CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING)
|
#define CACHEID_VIPT (CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING)
|
||||||
#define CACHEID_ASID_TAGGED (1 << 3)
|
#define CACHEID_ASID_TAGGED (1 << 3)
|
||||||
#define CACHEID_VIPT_I_ALIASING (1 << 4)
|
#define CACHEID_VIPT_I_ALIASING (1 << 4)
|
||||||
|
#define CACHEID_PIPT (1 << 5)
|
||||||
|
|
||||||
extern unsigned int cacheid;
|
extern unsigned int cacheid;
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ extern unsigned int cacheid;
|
|||||||
#define cache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_ALIASING)
|
#define cache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_ALIASING)
|
||||||
#define icache_is_vivt_asid_tagged() cacheid_is(CACHEID_ASID_TAGGED)
|
#define icache_is_vivt_asid_tagged() cacheid_is(CACHEID_ASID_TAGGED)
|
||||||
#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING)
|
#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING)
|
||||||
|
#define icache_is_pipt() cacheid_is(CACHEID_PIPT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
|
* __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
|
||||||
@ -26,7 +28,8 @@ extern unsigned int cacheid;
|
|||||||
#if __LINUX_ARM_ARCH__ >= 7
|
#if __LINUX_ARM_ARCH__ >= 7
|
||||||
#define __CACHEID_ARCH_MIN (CACHEID_VIPT_NONALIASING |\
|
#define __CACHEID_ARCH_MIN (CACHEID_VIPT_NONALIASING |\
|
||||||
CACHEID_ASID_TAGGED |\
|
CACHEID_ASID_TAGGED |\
|
||||||
CACHEID_VIPT_I_ALIASING)
|
CACHEID_VIPT_I_ALIASING |\
|
||||||
|
CACHEID_PIPT)
|
||||||
#elif __LINUX_ARM_ARCH__ >= 6
|
#elif __LINUX_ARM_ARCH__ >= 6
|
||||||
#define __CACHEID_ARCH_MIN (~CACHEID_VIVT)
|
#define __CACHEID_ARCH_MIN (~CACHEID_VIVT)
|
||||||
#else
|
#else
|
||||||
|
@ -265,6 +265,10 @@ static int cpu_has_aliasing_icache(unsigned int arch)
|
|||||||
int aliasing_icache;
|
int aliasing_icache;
|
||||||
unsigned int id_reg, num_sets, line_size;
|
unsigned int id_reg, num_sets, line_size;
|
||||||
|
|
||||||
|
/* PIPT caches never alias. */
|
||||||
|
if (icache_is_pipt())
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* arch specifies the register format */
|
/* arch specifies the register format */
|
||||||
switch (arch) {
|
switch (arch) {
|
||||||
case CPU_ARCH_ARMv7:
|
case CPU_ARCH_ARMv7:
|
||||||
@ -299,8 +303,14 @@ static void __init cacheid_init(void)
|
|||||||
/* ARMv7 register format */
|
/* ARMv7 register format */
|
||||||
arch = CPU_ARCH_ARMv7;
|
arch = CPU_ARCH_ARMv7;
|
||||||
cacheid = CACHEID_VIPT_NONALIASING;
|
cacheid = CACHEID_VIPT_NONALIASING;
|
||||||
if ((cachetype & (3 << 14)) == 1 << 14)
|
switch (cachetype & (3 << 14)) {
|
||||||
|
case (1 << 14):
|
||||||
cacheid |= CACHEID_ASID_TAGGED;
|
cacheid |= CACHEID_ASID_TAGGED;
|
||||||
|
break;
|
||||||
|
case (3 << 14):
|
||||||
|
cacheid |= CACHEID_PIPT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
arch = CPU_ARCH_ARMv6;
|
arch = CPU_ARCH_ARMv6;
|
||||||
if (cachetype & (1 << 23))
|
if (cachetype & (1 << 23))
|
||||||
@ -317,10 +327,11 @@ static void __init cacheid_init(void)
|
|||||||
printk("CPU: %s data cache, %s instruction cache\n",
|
printk("CPU: %s data cache, %s instruction cache\n",
|
||||||
cache_is_vivt() ? "VIVT" :
|
cache_is_vivt() ? "VIVT" :
|
||||||
cache_is_vipt_aliasing() ? "VIPT aliasing" :
|
cache_is_vipt_aliasing() ? "VIPT aliasing" :
|
||||||
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
|
cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown",
|
||||||
cache_is_vivt() ? "VIVT" :
|
cache_is_vivt() ? "VIVT" :
|
||||||
icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
|
icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
|
||||||
icache_is_vipt_aliasing() ? "VIPT aliasing" :
|
icache_is_vipt_aliasing() ? "VIPT aliasing" :
|
||||||
|
icache_is_pipt() ? "PIPT" :
|
||||||
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
|
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user