aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/cachetype.h118
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()) 10extern 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
46static 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