aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2007-05-09 04:50:23 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-05-09 04:50:23 -0400
commit065cf519c32984b7a78777aae3859baf5f5fd3d3 (patch)
treea6d0fe57cfacb76bd90189101977ec8e6bab3ec0
parent56163fcf194fb688fcf3cefa9b90c5ad41f74059 (diff)
[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.c7
-rw-r--r--include/asm-arm/cacheflush.h15
2 files changed, 22 insertions, 0 deletions
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)
47 : "r" (0)); 47 : "r" (0));
48 isb(); 48 isb();
49 flush_tlb_all(); 49 flush_tlb_all();
50 if (icache_is_vivt_asid_tagged()) {
51 asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
52 "mcr p15, 0, %0, c7, c5, 6 @ flush BTAC/BTB\n"
53 :
54 : "r" (0));
55 dsb();
56 }
50 } 57 }
51 58
52 mm->context.id = asid; 59 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,
438#define __cacheid_vipt(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val)) 438#define __cacheid_vipt(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val))
439#define __cacheid_vipt_nonaliasing(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val)) 439#define __cacheid_vipt_nonaliasing(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val))
440#define __cacheid_vipt_aliasing(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val)) 440#define __cacheid_vipt_aliasing(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val))
441#define __cacheid_vivt_asid_tagged_instr(val) (__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0)
441 442
442#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) 443#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
443 444
@@ -445,6 +446,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
445#define cache_is_vipt() 0 446#define cache_is_vipt() 0
446#define cache_is_vipt_nonaliasing() 0 447#define cache_is_vipt_nonaliasing() 0
447#define cache_is_vipt_aliasing() 0 448#define cache_is_vipt_aliasing() 0
449#define icache_is_vivt_asid_tagged() 0
448 450
449#elif defined(CONFIG_CPU_CACHE_VIPT) 451#elif defined(CONFIG_CPU_CACHE_VIPT)
450 452
@@ -462,6 +464,12 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
462 __cacheid_vipt_aliasing(__val); \ 464 __cacheid_vipt_aliasing(__val); \
463 }) 465 })
464 466
467#define icache_is_vivt_asid_tagged() \
468 ({ \
469 unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
470 __cacheid_vivt_asid_tagged_instr(__val); \
471 })
472
465#else 473#else
466 474
467#define cache_is_vivt() \ 475#define cache_is_vivt() \
@@ -490,6 +498,13 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
490 __cacheid_vipt_aliasing(__val); \ 498 __cacheid_vipt_aliasing(__val); \
491 }) 499 })
492 500
501#define icache_is_vivt_asid_tagged() \
502 ({ \
503 unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
504 __cacheid_present(__val) && \
505 __cacheid_vivt_asid_tagged_instr(__val); \
506 })
507
493#endif 508#endif
494 509
495#endif 510#endif