diff options
Diffstat (limited to 'arch/arm/include/asm/tlbflush.h')
-rw-r--r-- | arch/arm/include/asm/tlbflush.h | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index b543a054a17e..a62218013c78 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define TLB_V6_D_ASID (1 << 17) | 39 | #define TLB_V6_D_ASID (1 << 17) |
40 | #define TLB_V6_I_ASID (1 << 18) | 40 | #define TLB_V6_I_ASID (1 << 18) |
41 | 41 | ||
42 | #define TLB_BTB (1 << 28) | ||
42 | #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ | 43 | #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ |
43 | #define TLB_DCLEAN (1 << 30) | 44 | #define TLB_DCLEAN (1 << 30) |
44 | #define TLB_WB (1 << 31) | 45 | #define TLB_WB (1 << 31) |
@@ -53,6 +54,7 @@ | |||
53 | * v4wb - ARMv4 with write buffer without I TLB flush entry instruction | 54 | * v4wb - ARMv4 with write buffer without I TLB flush entry instruction |
54 | * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction | 55 | * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction |
55 | * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) | 56 | * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) |
57 | * fa - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB)) | ||
56 | * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction | 58 | * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction |
57 | * v7wbi - identical to v6wbi | 59 | * v7wbi - identical to v6wbi |
58 | */ | 60 | */ |
@@ -89,6 +91,22 @@ | |||
89 | # define v4_always_flags (-1UL) | 91 | # define v4_always_flags (-1UL) |
90 | #endif | 92 | #endif |
91 | 93 | ||
94 | #define fa_tlb_flags (TLB_WB | TLB_BTB | TLB_DCLEAN | \ | ||
95 | TLB_V4_U_FULL | TLB_V4_U_PAGE) | ||
96 | |||
97 | #ifdef CONFIG_CPU_TLB_FA | ||
98 | # define fa_possible_flags fa_tlb_flags | ||
99 | # define fa_always_flags fa_tlb_flags | ||
100 | # ifdef _TLB | ||
101 | # define MULTI_TLB 1 | ||
102 | # else | ||
103 | # define _TLB fa | ||
104 | # endif | ||
105 | #else | ||
106 | # define fa_possible_flags 0 | ||
107 | # define fa_always_flags (-1UL) | ||
108 | #endif | ||
109 | |||
92 | #define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ | 110 | #define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ |
93 | TLB_V4_I_FULL | TLB_V4_D_FULL | \ | 111 | TLB_V4_I_FULL | TLB_V4_D_FULL | \ |
94 | TLB_V4_I_PAGE | TLB_V4_D_PAGE) | 112 | TLB_V4_I_PAGE | TLB_V4_D_PAGE) |
@@ -140,7 +158,7 @@ | |||
140 | # define v4wb_always_flags (-1UL) | 158 | # define v4wb_always_flags (-1UL) |
141 | #endif | 159 | #endif |
142 | 160 | ||
143 | #define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ | 161 | #define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ |
144 | TLB_V6_I_FULL | TLB_V6_D_FULL | \ | 162 | TLB_V6_I_FULL | TLB_V6_D_FULL | \ |
145 | TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ | 163 | TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ |
146 | TLB_V6_I_ASID | TLB_V6_D_ASID) | 164 | TLB_V6_I_ASID | TLB_V6_D_ASID) |
@@ -267,6 +285,7 @@ extern struct cpu_tlb_fns cpu_tlb; | |||
267 | v4wbi_possible_flags | \ | 285 | v4wbi_possible_flags | \ |
268 | fr_possible_flags | \ | 286 | fr_possible_flags | \ |
269 | v4wb_possible_flags | \ | 287 | v4wb_possible_flags | \ |
288 | fa_possible_flags | \ | ||
270 | v6wbi_possible_flags | \ | 289 | v6wbi_possible_flags | \ |
271 | v7wbi_possible_flags) | 290 | v7wbi_possible_flags) |
272 | 291 | ||
@@ -275,6 +294,7 @@ extern struct cpu_tlb_fns cpu_tlb; | |||
275 | v4wbi_always_flags & \ | 294 | v4wbi_always_flags & \ |
276 | fr_always_flags & \ | 295 | fr_always_flags & \ |
277 | v4wb_always_flags & \ | 296 | v4wb_always_flags & \ |
297 | fa_always_flags & \ | ||
278 | v6wbi_always_flags & \ | 298 | v6wbi_always_flags & \ |
279 | v7wbi_always_flags) | 299 | v7wbi_always_flags) |
280 | 300 | ||
@@ -297,9 +317,7 @@ static inline void local_flush_tlb_all(void) | |||
297 | if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) | 317 | if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) |
298 | asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); | 318 | asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); |
299 | 319 | ||
300 | if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | | 320 | if (tlb_flag(TLB_BTB)) { |
301 | TLB_V6_I_PAGE | TLB_V6_D_PAGE | | ||
302 | TLB_V6_I_ASID | TLB_V6_D_ASID)) { | ||
303 | /* flush the branch target cache */ | 321 | /* flush the branch target cache */ |
304 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | 322 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); |
305 | dsb(); | 323 | dsb(); |
@@ -334,9 +352,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) | |||
334 | if (tlb_flag(TLB_V6_I_ASID)) | 352 | if (tlb_flag(TLB_V6_I_ASID)) |
335 | asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); | 353 | asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); |
336 | 354 | ||
337 | if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | | 355 | if (tlb_flag(TLB_BTB)) { |
338 | TLB_V6_I_PAGE | TLB_V6_D_PAGE | | ||
339 | TLB_V6_I_ASID | TLB_V6_D_ASID)) { | ||
340 | /* flush the branch target cache */ | 356 | /* flush the branch target cache */ |
341 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | 357 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); |
342 | dsb(); | 358 | dsb(); |
@@ -374,9 +390,7 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | |||
374 | if (tlb_flag(TLB_V6_I_PAGE)) | 390 | if (tlb_flag(TLB_V6_I_PAGE)) |
375 | asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); | 391 | asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); |
376 | 392 | ||
377 | if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | | 393 | if (tlb_flag(TLB_BTB)) { |
378 | TLB_V6_I_PAGE | TLB_V6_D_PAGE | | ||
379 | TLB_V6_I_ASID | TLB_V6_D_ASID)) { | ||
380 | /* flush the branch target cache */ | 394 | /* flush the branch target cache */ |
381 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | 395 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); |
382 | dsb(); | 396 | dsb(); |
@@ -411,9 +425,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | |||
411 | if (tlb_flag(TLB_V6_I_PAGE)) | 425 | if (tlb_flag(TLB_V6_I_PAGE)) |
412 | asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); | 426 | asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); |
413 | 427 | ||
414 | if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | | 428 | if (tlb_flag(TLB_BTB)) { |
415 | TLB_V6_I_PAGE | TLB_V6_D_PAGE | | ||
416 | TLB_V6_I_ASID | TLB_V6_D_ASID)) { | ||
417 | /* flush the branch target cache */ | 429 | /* flush the branch target cache */ |
418 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | 430 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); |
419 | dsb(); | 431 | dsb(); |