diff options
| author | Catalin Marinas <catalin.marinas@arm.com> | 2007-05-09 09:50:23 +0100 | 
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-05-09 09:50:23 +0100 | 
| commit | 065cf519c32984b7a78777aae3859baf5f5fd3d3 (patch) | |
| tree | a6d0fe57cfacb76bd90189101977ec8e6bab3ec0 | |
| parent | 56163fcf194fb688fcf3cefa9b90c5ad41f74059 (diff) | |
| download | olio-linux-3.10-065cf519c32984b7a78777aae3859baf5f5fd3d3.tar.xz olio-linux-3.10-065cf519c32984b7a78777aae3859baf5f5fd3d3.zip  | |
[ARM] armv7: add support for asid-tagged VIVT I-cache
ARMv7 can have VIPT, PIPT or ASID-tagged VIVT I-cache. This patch
adds the necessary invalidation of the I-cache when the ASID numbers
are re-used.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | arch/arm/mm/context.c | 7 | ||||
| -rw-r--r-- | include/asm-arm/cacheflush.h | 15 | 
2 files changed, 22 insertions, 0 deletions
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 9da43a0fdcd..c9e9a558626 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -47,6 +47,13 @@ void __new_context(struct mm_struct *mm)  		    : "r" (0));  		isb();  		flush_tlb_all(); +		if (icache_is_vivt_asid_tagged()) { +			asm("mcr	p15, 0, %0, c7, c5, 0	@ invalidate I-cache\n" +			    "mcr	p15, 0, %0, c7, c5, 6	@ flush BTAC/BTB\n" +			    : +			    : "r" (0)); +			dsb(); +		}  	}  	mm->context.id = asid; diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 6832ef96bc1..d1294a46c70 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -438,6 +438,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,  #define __cacheid_vipt(val)			(__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val))  #define __cacheid_vipt_nonaliasing(val)		(__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val))  #define __cacheid_vipt_aliasing(val)		(__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val)) +#define __cacheid_vivt_asid_tagged_instr(val)	(__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0)  #if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) @@ -445,6 +446,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,  #define cache_is_vipt()			0  #define cache_is_vipt_nonaliasing()	0  #define cache_is_vipt_aliasing()	0 +#define icache_is_vivt_asid_tagged()	0  #elif defined(CONFIG_CPU_CACHE_VIPT) @@ -462,6 +464,12 @@ static inline void flush_anon_page(struct vm_area_struct *vma,  		__cacheid_vipt_aliasing(__val);				\  	}) +#define icache_is_vivt_asid_tagged()					\ +	({								\ +		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\ +		__cacheid_vivt_asid_tagged_instr(__val);		\ +	}) +  #else  #define cache_is_vivt()							\ @@ -490,6 +498,13 @@ static inline void flush_anon_page(struct vm_area_struct *vma,  		 __cacheid_vipt_aliasing(__val);			\  	}) +#define icache_is_vivt_asid_tagged()					\ +	({								\ +		unsigned int __val = read_cpuid(CPUID_CACHETYPE);	\ +		__cacheid_present(__val) &&				\ +		 __cacheid_vivt_asid_tagged_instr(__val);		\ +	}) +  #endif  #endif  |