From 065cf519c32984b7a78777aae3859baf5f5fd3d3 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 9 May 2007 09:50:23 +0100 Subject: [PATCH] [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 Signed-off-by: Russell King --- arch/arm/mm/context.c | 7 +++++++ include/asm-arm/cacheflush.h | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 9da43a0fdcdf..c9e9a5586267 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 6832ef96bc16..d1294a46c70c 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