#define read_cpuid(reg) \
({ \
unsigned int __val; \
- asm("mrc%? p15, 0, %0, c0, c0, " __stringify(reg) \
- : "=r" (__val)); \
+ asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \
+ : "=r" (__val) \
+ : \
+ : "cc"); \
__val; \
})
+#define __cacheid_present(val) (val != read_cpuid(CPUID_ID))
+#define __cacheid_vivt(val) ((val & (15 << 25)) != (14 << 25))
+#define __cacheid_vipt(val) ((val & (15 << 25)) == (14 << 25))
+#define __cacheid_vipt_nonaliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25))
+#define __cacheid_vipt_aliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23))
+
+#define cache_is_vivt() \
+ ({ \
+ unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
+ (!__cacheid_present(__val)) || __cacheid_vivt(__val); \
+ })
+
+#define cache_is_vipt() \
+ ({ \
+ unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
+ __cacheid_present(__val) && __cacheid_vipt(__val); \
+ })
+
+#define cache_is_vipt_nonaliasing() \
+ ({ \
+ unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
+ __cacheid_present(__val) && \
+ __cacheid_vipt_nonaliasing(__val); \
+ })
+
+#define cache_is_vipt_aliasing() \
+ ({ \
+ unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
+ __cacheid_present(__val) && \
+ __cacheid_vipt_aliasing(__val); \
+ })
+
/*
* This is used to ensure the compiler did actually allocate the register we
* asked it for some inline assembly sequences. Apparently we can't trust
#ifndef __ASSEMBLY__
-#include <linux/kernel.h>
+#include <linux/linkage.h>
struct thread_info;
+struct task_struct;
/* information about the system we're running on */
extern unsigned int system_rev;
* `prev' will never be the same as `next'. schedule() itself
* contains the memory barrier to tell GCC not to cache `current'.
*/
-struct thread_info;
-struct task_struct;
extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
#define switch_to(prev,next,last) \