|
@@ -238,6 +238,34 @@ int cpu_architecture(void)
|
|
|
return cpu_arch;
|
|
|
}
|
|
|
|
|
|
+static int cpu_has_aliasing_icache(unsigned int arch)
|
|
|
+{
|
|
|
+ int aliasing_icache;
|
|
|
+ unsigned int id_reg, num_sets, line_size;
|
|
|
+
|
|
|
+ /* arch specifies the register format */
|
|
|
+ switch (arch) {
|
|
|
+ case CPU_ARCH_ARMv7:
|
|
|
+ asm("mcr p15, 2, %1, c0, c0, 0 @ set CSSELR\n"
|
|
|
+ "isb\n"
|
|
|
+ "mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR"
|
|
|
+ : "=r" (id_reg)
|
|
|
+ : "r" (1));
|
|
|
+ line_size = 4 << ((id_reg & 0x7) + 2);
|
|
|
+ num_sets = ((id_reg >> 13) & 0x7fff) + 1;
|
|
|
+ aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
|
|
|
+ break;
|
|
|
+ case CPU_ARCH_ARMv6:
|
|
|
+ aliasing_icache = read_cpuid_cachetype() & (1 << 11);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ /* I-cache aliases will be handled by D-cache aliasing code */
|
|
|
+ aliasing_icache = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return aliasing_icache;
|
|
|
+}
|
|
|
+
|
|
|
static void __init cacheid_init(void)
|
|
|
{
|
|
|
unsigned int cachetype = read_cpuid_cachetype();
|
|
@@ -249,10 +277,15 @@ static void __init cacheid_init(void)
|
|
|
cacheid = CACHEID_VIPT_NONALIASING;
|
|
|
if ((cachetype & (3 << 14)) == 1 << 14)
|
|
|
cacheid |= CACHEID_ASID_TAGGED;
|
|
|
- } else if (cachetype & (1 << 23))
|
|
|
+ else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7))
|
|
|
+ cacheid |= CACHEID_VIPT_I_ALIASING;
|
|
|
+ } else if (cachetype & (1 << 23)) {
|
|
|
cacheid = CACHEID_VIPT_ALIASING;
|
|
|
- else
|
|
|
+ } else {
|
|
|
cacheid = CACHEID_VIPT_NONALIASING;
|
|
|
+ if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6))
|
|
|
+ cacheid |= CACHEID_VIPT_I_ALIASING;
|
|
|
+ }
|
|
|
} else {
|
|
|
cacheid = CACHEID_VIVT;
|
|
|
}
|
|
@@ -263,7 +296,7 @@ static void __init cacheid_init(void)
|
|
|
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
|
|
|
cache_is_vivt() ? "VIVT" :
|
|
|
icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
|
|
|
- cache_is_vipt_aliasing() ? "VIPT aliasing" :
|
|
|
+ icache_is_vipt_aliasing() ? "VIPT aliasing" :
|
|
|
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
|
|
|
}
|
|
|
|