diff options
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/cachetype.h | 118 |
1 files changed, 37 insertions, 81 deletions
diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h index b52386bfd505..d3a4c2cb9f2f 100644 --- a/arch/arm/include/asm/cachetype.h +++ b/arch/arm/include/asm/cachetype.h | |||
@@ -1,96 +1,52 @@ | |||
1 | #ifndef __ASM_ARM_CACHETYPE_H | 1 | #ifndef __ASM_ARM_CACHETYPE_H |
2 | #define __ASM_ARM_CACHETYPE_H | 2 | #define __ASM_ARM_CACHETYPE_H |
3 | 3 | ||
4 | #include <asm/cputype.h> | 4 | #define CACHEID_VIVT (1 << 0) |
5 | #define CACHEID_VIPT_NONALIASING (1 << 1) | ||
6 | #define CACHEID_VIPT_ALIASING (1 << 2) | ||
7 | #define CACHEID_VIPT (CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING) | ||
8 | #define CACHEID_ASID_TAGGED (1 << 3) | ||
5 | 9 | ||
6 | #define __cacheid_present(val) (val != read_cpuid_id()) | 10 | extern unsigned int cacheid; |
7 | #define __cacheid_type_v7(val) ((val & (7 << 29)) == (4 << 29)) | ||
8 | 11 | ||
9 | #define __cacheid_vivt_prev7(val) ((val & (15 << 25)) != (14 << 25)) | 12 | #define cache_is_vivt() cacheid_is(CACHEID_VIVT) |
10 | #define __cacheid_vipt_prev7(val) ((val & (15 << 25)) == (14 << 25)) | 13 | #define cache_is_vipt() cacheid_is(CACHEID_VIPT) |
11 | #define __cacheid_vipt_nonaliasing_prev7(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25)) | 14 | #define cache_is_vipt_nonaliasing() cacheid_is(CACHEID_VIPT_NONALIASING) |
12 | #define __cacheid_vipt_aliasing_prev7(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23)) | 15 | #define cache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_ALIASING) |
16 | #define icache_is_vivt_asid_tagged() cacheid_is(CACHEID_ASID_TAGGED) | ||
13 | 17 | ||
14 | #define __cacheid_vivt(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vivt_prev7(val)) | ||
15 | #define __cacheid_vipt(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val)) | ||
16 | #define __cacheid_vipt_nonaliasing(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val)) | ||
17 | #define __cacheid_vipt_aliasing(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val)) | ||
18 | #define __cacheid_vivt_asid_tagged_instr(val) (__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0) | ||
19 | |||
20 | #if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) | ||
21 | /* | 18 | /* |
22 | * VIVT caches only | 19 | * __LINUX_ARM_ARCH__ is the minimum supported CPU architecture |
20 | * Mask out support which will never be present on newer CPUs. | ||
21 | * - v6+ is never VIVT | ||
22 | * - v7+ VIPT never aliases | ||
23 | */ | 23 | */ |
24 | #define cache_is_vivt() 1 | 24 | #if __LINUX_ARM_ARCH__ >= 7 |
25 | #define cache_is_vipt() 0 | 25 | #define __CACHEID_ARCH_MIN (CACHEID_VIPT_NONALIASING | CACHEID_ASID_TAGGED) |
26 | #define cache_is_vipt_nonaliasing() 0 | 26 | #elif __LINUX_ARM_ARCH__ >= 6 |
27 | #define cache_is_vipt_aliasing() 0 | 27 | #define __CACHEID_ARCH_MIN (~CACHEID_VIVT) |
28 | #define icache_is_vivt_asid_tagged() 0 | 28 | #else |
29 | #define __CACHEID_ARCH_MIN (~0) | ||
30 | #endif | ||
29 | 31 | ||
30 | #elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT) | ||
31 | /* | 32 | /* |
32 | * VIPT caches only | 33 | * Mask out support which isn't configured |
33 | */ | 34 | */ |
34 | #define cache_is_vivt() 0 | 35 | #if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) |
35 | #define cache_is_vipt() 1 | 36 | #define __CACHEID_ALWAYS (CACHEID_VIVT) |
36 | #define cache_is_vipt_nonaliasing() \ | 37 | #define __CACHEID_NEVER (~CACHEID_VIVT) |
37 | ({ \ | 38 | #elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT) |
38 | unsigned int __val = read_cpuid_cachetype(); \ | 39 | #define __CACHEID_ALWAYS (0) |
39 | __cacheid_vipt_nonaliasing(__val); \ | 40 | #define __CACHEID_NEVER (CACHEID_VIVT) |
40 | }) | ||
41 | |||
42 | #define cache_is_vipt_aliasing() \ | ||
43 | ({ \ | ||
44 | unsigned int __val = read_cpuid_cachetype(); \ | ||
45 | __cacheid_vipt_aliasing(__val); \ | ||
46 | }) | ||
47 | |||
48 | #define icache_is_vivt_asid_tagged() \ | ||
49 | ({ \ | ||
50 | unsigned int __val = read_cpuid_cachetype(); \ | ||
51 | __cacheid_vivt_asid_tagged_instr(__val); \ | ||
52 | }) | ||
53 | |||
54 | #else | 41 | #else |
55 | /* | 42 | #define __CACHEID_ALWAYS (0) |
56 | * VIVT or VIPT caches. Note that this is unreliable since ARM926 | 43 | #define __CACHEID_NEVER (0) |
57 | * and V6 CPUs satisfy the "(val & (15 << 25)) == (14 << 25)" test. | ||
58 | * There's no way to tell from the CacheType register what type (!) | ||
59 | * the cache is. | ||
60 | */ | ||
61 | #define cache_is_vivt() \ | ||
62 | ({ \ | ||
63 | unsigned int __val = read_cpuid_cachetype(); \ | ||
64 | (!__cacheid_present(__val)) || __cacheid_vivt(__val); \ | ||
65 | }) | ||
66 | |||
67 | #define cache_is_vipt() \ | ||
68 | ({ \ | ||
69 | unsigned int __val = read_cpuid_cachetype(); \ | ||
70 | __cacheid_present(__val) && __cacheid_vipt(__val); \ | ||
71 | }) | ||
72 | |||
73 | #define cache_is_vipt_nonaliasing() \ | ||
74 | ({ \ | ||
75 | unsigned int __val = read_cpuid_cachetype(); \ | ||
76 | __cacheid_present(__val) && \ | ||
77 | __cacheid_vipt_nonaliasing(__val); \ | ||
78 | }) | ||
79 | |||
80 | #define cache_is_vipt_aliasing() \ | ||
81 | ({ \ | ||
82 | unsigned int __val = read_cpuid_cachetype(); \ | ||
83 | __cacheid_present(__val) && \ | ||
84 | __cacheid_vipt_aliasing(__val); \ | ||
85 | }) | ||
86 | |||
87 | #define icache_is_vivt_asid_tagged() \ | ||
88 | ({ \ | ||
89 | unsigned int __val = read_cpuid_cachetype(); \ | ||
90 | __cacheid_present(__val) && \ | ||
91 | __cacheid_vivt_asid_tagged_instr(__val); \ | ||
92 | }) | ||
93 | |||
94 | #endif | 44 | #endif |
95 | 45 | ||
46 | static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask) | ||
47 | { | ||
48 | return (__CACHEID_ALWAYS & mask) | | ||
49 | (~__CACHEID_NEVER & __CACHEID_ARCH_MIN & mask & cacheid); | ||
50 | } | ||
51 | |||
96 | #endif | 52 | #endif |