Commit 7b9649bd authored by Catalin Marinas's avatar Catalin Marinas

Support for ASID-tagged VIVT I-cache on ARMv7

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: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent c38d71bc
...@@ -47,6 +47,13 @@ void __new_context(struct mm_struct *mm) ...@@ -47,6 +47,13 @@ void __new_context(struct mm_struct *mm)
: "r" (0)); : "r" (0));
isb(); isb();
flush_tlb_all(); 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; mm->context.id = asid;
......
...@@ -426,6 +426,7 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page ...@@ -426,6 +426,7 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
#define __cacheid_vipt(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val)) #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_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_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) #if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
...@@ -433,6 +434,7 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page ...@@ -433,6 +434,7 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
#define cache_is_vipt() 0 #define cache_is_vipt() 0
#define cache_is_vipt_nonaliasing() 0 #define cache_is_vipt_nonaliasing() 0
#define cache_is_vipt_aliasing() 0 #define cache_is_vipt_aliasing() 0
#define icache_is_vivt_asid_tagged() 0
#elif defined(CONFIG_CPU_CACHE_VIPT) #elif defined(CONFIG_CPU_CACHE_VIPT)
...@@ -450,6 +452,12 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page ...@@ -450,6 +452,12 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
__cacheid_vipt_aliasing(__val); \ __cacheid_vipt_aliasing(__val); \
}) })
#define icache_is_vivt_asid_tagged() \
({ \
unsigned int __val = read_cpuid(CPUID_CACHETYPE); \
__cacheid_vivt_asid_tagged_instr(__val); \
})
#else #else
#define cache_is_vivt() \ #define cache_is_vivt() \
...@@ -478,6 +486,13 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page ...@@ -478,6 +486,13 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
__cacheid_vipt_aliasing(__val); \ __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
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment