18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/arm/include/asm/tlbflush.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1999-2003 Russell King 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef _ASMARM_TLBFLUSH_H 88c2ecf20Sopenharmony_ci#define _ASMARM_TLBFLUSH_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 118c2ecf20Sopenharmony_ci# include <linux/mm_types.h> 128c2ecf20Sopenharmony_ci#endif 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#ifdef CONFIG_MMU 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <asm/glue.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define TLB_V4_U_PAGE (1 << 1) 198c2ecf20Sopenharmony_ci#define TLB_V4_D_PAGE (1 << 2) 208c2ecf20Sopenharmony_ci#define TLB_V4_I_PAGE (1 << 3) 218c2ecf20Sopenharmony_ci#define TLB_V6_U_PAGE (1 << 4) 228c2ecf20Sopenharmony_ci#define TLB_V6_D_PAGE (1 << 5) 238c2ecf20Sopenharmony_ci#define TLB_V6_I_PAGE (1 << 6) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define TLB_V4_U_FULL (1 << 9) 268c2ecf20Sopenharmony_ci#define TLB_V4_D_FULL (1 << 10) 278c2ecf20Sopenharmony_ci#define TLB_V4_I_FULL (1 << 11) 288c2ecf20Sopenharmony_ci#define TLB_V6_U_FULL (1 << 12) 298c2ecf20Sopenharmony_ci#define TLB_V6_D_FULL (1 << 13) 308c2ecf20Sopenharmony_ci#define TLB_V6_I_FULL (1 << 14) 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define TLB_V6_U_ASID (1 << 16) 338c2ecf20Sopenharmony_ci#define TLB_V6_D_ASID (1 << 17) 348c2ecf20Sopenharmony_ci#define TLB_V6_I_ASID (1 << 18) 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define TLB_V6_BP (1 << 19) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci/* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */ 398c2ecf20Sopenharmony_ci#define TLB_V7_UIS_PAGE (1 << 20) 408c2ecf20Sopenharmony_ci#define TLB_V7_UIS_FULL (1 << 21) 418c2ecf20Sopenharmony_ci#define TLB_V7_UIS_ASID (1 << 22) 428c2ecf20Sopenharmony_ci#define TLB_V7_UIS_BP (1 << 23) 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define TLB_BARRIER (1 << 28) 458c2ecf20Sopenharmony_ci#define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ 468c2ecf20Sopenharmony_ci#define TLB_DCLEAN (1 << 30) 478c2ecf20Sopenharmony_ci#define TLB_WB (1 << 31) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci/* 508c2ecf20Sopenharmony_ci * MMU TLB Model 518c2ecf20Sopenharmony_ci * ============= 528c2ecf20Sopenharmony_ci * 538c2ecf20Sopenharmony_ci * We have the following to choose from: 548c2ecf20Sopenharmony_ci * v4 - ARMv4 without write buffer 558c2ecf20Sopenharmony_ci * v4wb - ARMv4 with write buffer without I TLB flush entry instruction 568c2ecf20Sopenharmony_ci * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction 578c2ecf20Sopenharmony_ci * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) 588c2ecf20Sopenharmony_ci * fa - Faraday (v4 with write buffer with UTLB) 598c2ecf20Sopenharmony_ci * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction 608c2ecf20Sopenharmony_ci * v7wbi - identical to v6wbi 618c2ecf20Sopenharmony_ci */ 628c2ecf20Sopenharmony_ci#undef _TLB 638c2ecf20Sopenharmony_ci#undef MULTI_TLB 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP_ON_UP 668c2ecf20Sopenharmony_ci#define MULTI_TLB 1 678c2ecf20Sopenharmony_ci#endif 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE) 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_TLB_V4WT 728c2ecf20Sopenharmony_ci# define v4_possible_flags v4_tlb_flags 738c2ecf20Sopenharmony_ci# define v4_always_flags v4_tlb_flags 748c2ecf20Sopenharmony_ci# ifdef _TLB 758c2ecf20Sopenharmony_ci# define MULTI_TLB 1 768c2ecf20Sopenharmony_ci# else 778c2ecf20Sopenharmony_ci# define _TLB v4 788c2ecf20Sopenharmony_ci# endif 798c2ecf20Sopenharmony_ci#else 808c2ecf20Sopenharmony_ci# define v4_possible_flags 0 818c2ecf20Sopenharmony_ci# define v4_always_flags (-1UL) 828c2ecf20Sopenharmony_ci#endif 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#define fa_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ 858c2ecf20Sopenharmony_ci TLB_V4_U_FULL | TLB_V4_U_PAGE) 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_TLB_FA 888c2ecf20Sopenharmony_ci# define fa_possible_flags fa_tlb_flags 898c2ecf20Sopenharmony_ci# define fa_always_flags fa_tlb_flags 908c2ecf20Sopenharmony_ci# ifdef _TLB 918c2ecf20Sopenharmony_ci# define MULTI_TLB 1 928c2ecf20Sopenharmony_ci# else 938c2ecf20Sopenharmony_ci# define _TLB fa 948c2ecf20Sopenharmony_ci# endif 958c2ecf20Sopenharmony_ci#else 968c2ecf20Sopenharmony_ci# define fa_possible_flags 0 978c2ecf20Sopenharmony_ci# define fa_always_flags (-1UL) 988c2ecf20Sopenharmony_ci#endif 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ 1018c2ecf20Sopenharmony_ci TLB_V4_I_FULL | TLB_V4_D_FULL | \ 1028c2ecf20Sopenharmony_ci TLB_V4_I_PAGE | TLB_V4_D_PAGE) 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_TLB_V4WBI 1058c2ecf20Sopenharmony_ci# define v4wbi_possible_flags v4wbi_tlb_flags 1068c2ecf20Sopenharmony_ci# define v4wbi_always_flags v4wbi_tlb_flags 1078c2ecf20Sopenharmony_ci# ifdef _TLB 1088c2ecf20Sopenharmony_ci# define MULTI_TLB 1 1098c2ecf20Sopenharmony_ci# else 1108c2ecf20Sopenharmony_ci# define _TLB v4wbi 1118c2ecf20Sopenharmony_ci# endif 1128c2ecf20Sopenharmony_ci#else 1138c2ecf20Sopenharmony_ci# define v4wbi_possible_flags 0 1148c2ecf20Sopenharmony_ci# define v4wbi_always_flags (-1UL) 1158c2ecf20Sopenharmony_ci#endif 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci#define fr_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_L2CLEAN_FR | \ 1188c2ecf20Sopenharmony_ci TLB_V4_I_FULL | TLB_V4_D_FULL | \ 1198c2ecf20Sopenharmony_ci TLB_V4_I_PAGE | TLB_V4_D_PAGE) 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_TLB_FEROCEON 1228c2ecf20Sopenharmony_ci# define fr_possible_flags fr_tlb_flags 1238c2ecf20Sopenharmony_ci# define fr_always_flags fr_tlb_flags 1248c2ecf20Sopenharmony_ci# ifdef _TLB 1258c2ecf20Sopenharmony_ci# define MULTI_TLB 1 1268c2ecf20Sopenharmony_ci# else 1278c2ecf20Sopenharmony_ci# define _TLB v4wbi 1288c2ecf20Sopenharmony_ci# endif 1298c2ecf20Sopenharmony_ci#else 1308c2ecf20Sopenharmony_ci# define fr_possible_flags 0 1318c2ecf20Sopenharmony_ci# define fr_always_flags (-1UL) 1328c2ecf20Sopenharmony_ci#endif 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci#define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \ 1358c2ecf20Sopenharmony_ci TLB_V4_I_FULL | TLB_V4_D_FULL | \ 1368c2ecf20Sopenharmony_ci TLB_V4_D_PAGE) 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_TLB_V4WB 1398c2ecf20Sopenharmony_ci# define v4wb_possible_flags v4wb_tlb_flags 1408c2ecf20Sopenharmony_ci# define v4wb_always_flags v4wb_tlb_flags 1418c2ecf20Sopenharmony_ci# ifdef _TLB 1428c2ecf20Sopenharmony_ci# define MULTI_TLB 1 1438c2ecf20Sopenharmony_ci# else 1448c2ecf20Sopenharmony_ci# define _TLB v4wb 1458c2ecf20Sopenharmony_ci# endif 1468c2ecf20Sopenharmony_ci#else 1478c2ecf20Sopenharmony_ci# define v4wb_possible_flags 0 1488c2ecf20Sopenharmony_ci# define v4wb_always_flags (-1UL) 1498c2ecf20Sopenharmony_ci#endif 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ 1528c2ecf20Sopenharmony_ci TLB_V6_I_FULL | TLB_V6_D_FULL | \ 1538c2ecf20Sopenharmony_ci TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ 1548c2ecf20Sopenharmony_ci TLB_V6_I_ASID | TLB_V6_D_ASID | \ 1558c2ecf20Sopenharmony_ci TLB_V6_BP) 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_TLB_V6 1588c2ecf20Sopenharmony_ci# define v6wbi_possible_flags v6wbi_tlb_flags 1598c2ecf20Sopenharmony_ci# define v6wbi_always_flags v6wbi_tlb_flags 1608c2ecf20Sopenharmony_ci# ifdef _TLB 1618c2ecf20Sopenharmony_ci# define MULTI_TLB 1 1628c2ecf20Sopenharmony_ci# else 1638c2ecf20Sopenharmony_ci# define _TLB v6wbi 1648c2ecf20Sopenharmony_ci# endif 1658c2ecf20Sopenharmony_ci#else 1668c2ecf20Sopenharmony_ci# define v6wbi_possible_flags 0 1678c2ecf20Sopenharmony_ci# define v6wbi_always_flags (-1UL) 1688c2ecf20Sopenharmony_ci#endif 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci#define v7wbi_tlb_flags_smp (TLB_WB | TLB_BARRIER | \ 1718c2ecf20Sopenharmony_ci TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | \ 1728c2ecf20Sopenharmony_ci TLB_V7_UIS_ASID | TLB_V7_UIS_BP) 1738c2ecf20Sopenharmony_ci#define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ 1748c2ecf20Sopenharmony_ci TLB_V6_U_FULL | TLB_V6_U_PAGE | \ 1758c2ecf20Sopenharmony_ci TLB_V6_U_ASID | TLB_V6_BP) 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_TLB_V7 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci# ifdef CONFIG_SMP_ON_UP 1808c2ecf20Sopenharmony_ci# define v7wbi_possible_flags (v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up) 1818c2ecf20Sopenharmony_ci# define v7wbi_always_flags (v7wbi_tlb_flags_smp & v7wbi_tlb_flags_up) 1828c2ecf20Sopenharmony_ci# elif defined(CONFIG_SMP) 1838c2ecf20Sopenharmony_ci# define v7wbi_possible_flags v7wbi_tlb_flags_smp 1848c2ecf20Sopenharmony_ci# define v7wbi_always_flags v7wbi_tlb_flags_smp 1858c2ecf20Sopenharmony_ci# else 1868c2ecf20Sopenharmony_ci# define v7wbi_possible_flags v7wbi_tlb_flags_up 1878c2ecf20Sopenharmony_ci# define v7wbi_always_flags v7wbi_tlb_flags_up 1888c2ecf20Sopenharmony_ci# endif 1898c2ecf20Sopenharmony_ci# ifdef _TLB 1908c2ecf20Sopenharmony_ci# define MULTI_TLB 1 1918c2ecf20Sopenharmony_ci# else 1928c2ecf20Sopenharmony_ci# define _TLB v7wbi 1938c2ecf20Sopenharmony_ci# endif 1948c2ecf20Sopenharmony_ci#else 1958c2ecf20Sopenharmony_ci# define v7wbi_possible_flags 0 1968c2ecf20Sopenharmony_ci# define v7wbi_always_flags (-1UL) 1978c2ecf20Sopenharmony_ci#endif 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci#ifndef _TLB 2008c2ecf20Sopenharmony_ci#error Unknown TLB model 2018c2ecf20Sopenharmony_ci#endif 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci#include <linux/sched.h> 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_cistruct cpu_tlb_fns { 2088c2ecf20Sopenharmony_ci void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *); 2098c2ecf20Sopenharmony_ci void (*flush_kern_range)(unsigned long, unsigned long); 2108c2ecf20Sopenharmony_ci unsigned long tlb_flags; 2118c2ecf20Sopenharmony_ci}; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci/* 2148c2ecf20Sopenharmony_ci * Select the calling method 2158c2ecf20Sopenharmony_ci */ 2168c2ecf20Sopenharmony_ci#ifdef MULTI_TLB 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range 2198c2ecf20Sopenharmony_ci#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci#else 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range) 2248c2ecf20Sopenharmony_ci#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range) 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ciextern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *); 2278c2ecf20Sopenharmony_ciextern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci#endif 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ciextern struct cpu_tlb_fns cpu_tlb; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci#define __cpu_tlb_flags cpu_tlb.tlb_flags 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci/* 2368c2ecf20Sopenharmony_ci * TLB Management 2378c2ecf20Sopenharmony_ci * ============== 2388c2ecf20Sopenharmony_ci * 2398c2ecf20Sopenharmony_ci * The arch/arm/mm/tlb-*.S files implement these methods. 2408c2ecf20Sopenharmony_ci * 2418c2ecf20Sopenharmony_ci * The TLB specific code is expected to perform whatever tests it 2428c2ecf20Sopenharmony_ci * needs to determine if it should invalidate the TLB for each 2438c2ecf20Sopenharmony_ci * call. Start addresses are inclusive and end addresses are 2448c2ecf20Sopenharmony_ci * exclusive; it is safe to round these addresses down. 2458c2ecf20Sopenharmony_ci * 2468c2ecf20Sopenharmony_ci * flush_tlb_all() 2478c2ecf20Sopenharmony_ci * 2488c2ecf20Sopenharmony_ci * Invalidate the entire TLB. 2498c2ecf20Sopenharmony_ci * 2508c2ecf20Sopenharmony_ci * flush_tlb_mm(mm) 2518c2ecf20Sopenharmony_ci * 2528c2ecf20Sopenharmony_ci * Invalidate all TLB entries in a particular address 2538c2ecf20Sopenharmony_ci * space. 2548c2ecf20Sopenharmony_ci * - mm - mm_struct describing address space 2558c2ecf20Sopenharmony_ci * 2568c2ecf20Sopenharmony_ci * flush_tlb_range(mm,start,end) 2578c2ecf20Sopenharmony_ci * 2588c2ecf20Sopenharmony_ci * Invalidate a range of TLB entries in the specified 2598c2ecf20Sopenharmony_ci * address space. 2608c2ecf20Sopenharmony_ci * - mm - mm_struct describing address space 2618c2ecf20Sopenharmony_ci * - start - start address (may not be aligned) 2628c2ecf20Sopenharmony_ci * - end - end address (exclusive, may not be aligned) 2638c2ecf20Sopenharmony_ci * 2648c2ecf20Sopenharmony_ci * flush_tlb_page(vaddr,vma) 2658c2ecf20Sopenharmony_ci * 2668c2ecf20Sopenharmony_ci * Invalidate the specified page in the specified address range. 2678c2ecf20Sopenharmony_ci * - vaddr - virtual address (may not be aligned) 2688c2ecf20Sopenharmony_ci * - vma - vma_struct describing address range 2698c2ecf20Sopenharmony_ci * 2708c2ecf20Sopenharmony_ci * flush_kern_tlb_page(kaddr) 2718c2ecf20Sopenharmony_ci * 2728c2ecf20Sopenharmony_ci * Invalidate the TLB entry for the specified page. The address 2738c2ecf20Sopenharmony_ci * will be in the kernels virtual memory space. Current uses 2748c2ecf20Sopenharmony_ci * only require the D-TLB to be invalidated. 2758c2ecf20Sopenharmony_ci * - kaddr - Kernel virtual memory address 2768c2ecf20Sopenharmony_ci */ 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci/* 2798c2ecf20Sopenharmony_ci * We optimise the code below by: 2808c2ecf20Sopenharmony_ci * - building a set of TLB flags that might be set in __cpu_tlb_flags 2818c2ecf20Sopenharmony_ci * - building a set of TLB flags that will always be set in __cpu_tlb_flags 2828c2ecf20Sopenharmony_ci * - if we're going to need __cpu_tlb_flags, access it once and only once 2838c2ecf20Sopenharmony_ci * 2848c2ecf20Sopenharmony_ci * This allows us to build optimal assembly for the single-CPU type case, 2858c2ecf20Sopenharmony_ci * and as close to optimal given the compiler constrants for multi-CPU 2868c2ecf20Sopenharmony_ci * case. We could do better for the multi-CPU case if the compiler 2878c2ecf20Sopenharmony_ci * implemented the "%?" method, but this has been discontinued due to too 2888c2ecf20Sopenharmony_ci * many people getting it wrong. 2898c2ecf20Sopenharmony_ci */ 2908c2ecf20Sopenharmony_ci#define possible_tlb_flags (v4_possible_flags | \ 2918c2ecf20Sopenharmony_ci v4wbi_possible_flags | \ 2928c2ecf20Sopenharmony_ci fr_possible_flags | \ 2938c2ecf20Sopenharmony_ci v4wb_possible_flags | \ 2948c2ecf20Sopenharmony_ci fa_possible_flags | \ 2958c2ecf20Sopenharmony_ci v6wbi_possible_flags | \ 2968c2ecf20Sopenharmony_ci v7wbi_possible_flags) 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci#define always_tlb_flags (v4_always_flags & \ 2998c2ecf20Sopenharmony_ci v4wbi_always_flags & \ 3008c2ecf20Sopenharmony_ci fr_always_flags & \ 3018c2ecf20Sopenharmony_ci v4wb_always_flags & \ 3028c2ecf20Sopenharmony_ci fa_always_flags & \ 3038c2ecf20Sopenharmony_ci v6wbi_always_flags & \ 3048c2ecf20Sopenharmony_ci v7wbi_always_flags) 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci#define __tlb_op(f, insnarg, arg) \ 3098c2ecf20Sopenharmony_ci do { \ 3108c2ecf20Sopenharmony_ci if (always_tlb_flags & (f)) \ 3118c2ecf20Sopenharmony_ci asm("mcr " insnarg \ 3128c2ecf20Sopenharmony_ci : : "r" (arg) : "cc"); \ 3138c2ecf20Sopenharmony_ci else if (possible_tlb_flags & (f)) \ 3148c2ecf20Sopenharmony_ci asm("tst %1, %2\n\t" \ 3158c2ecf20Sopenharmony_ci "mcrne " insnarg \ 3168c2ecf20Sopenharmony_ci : : "r" (arg), "r" (__tlb_flag), "Ir" (f) \ 3178c2ecf20Sopenharmony_ci : "cc"); \ 3188c2ecf20Sopenharmony_ci } while (0) 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci#define tlb_op(f, regs, arg) __tlb_op(f, "p15, 0, %0, " regs, arg) 3218c2ecf20Sopenharmony_ci#define tlb_l2_op(f, regs, arg) __tlb_op(f, "p15, 1, %0, " regs, arg) 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_cistatic inline void __local_flush_tlb_all(void) 3248c2ecf20Sopenharmony_ci{ 3258c2ecf20Sopenharmony_ci const int zero = 0; 3268c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); 3298c2ecf20Sopenharmony_ci tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); 3308c2ecf20Sopenharmony_ci tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); 3318c2ecf20Sopenharmony_ci} 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_all(void) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci const int zero = 0; 3368c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 3398c2ecf20Sopenharmony_ci dsb(nshst); 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci __local_flush_tlb_all(); 3428c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_FULL, "c8, c7, 0", zero); 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci if (tlb_flag(TLB_BARRIER)) { 3458c2ecf20Sopenharmony_ci dsb(nsh); 3468c2ecf20Sopenharmony_ci isb(); 3478c2ecf20Sopenharmony_ci } 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cistatic inline void __flush_tlb_all(void) 3518c2ecf20Sopenharmony_ci{ 3528c2ecf20Sopenharmony_ci const int zero = 0; 3538c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 3568c2ecf20Sopenharmony_ci dsb(ishst); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci __local_flush_tlb_all(); 3598c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero); 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci if (tlb_flag(TLB_BARRIER)) { 3628c2ecf20Sopenharmony_ci dsb(ish); 3638c2ecf20Sopenharmony_ci isb(); 3648c2ecf20Sopenharmony_ci } 3658c2ecf20Sopenharmony_ci} 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_cistatic inline void __local_flush_tlb_mm(struct mm_struct *mm) 3688c2ecf20Sopenharmony_ci{ 3698c2ecf20Sopenharmony_ci const int zero = 0; 3708c2ecf20Sopenharmony_ci const int asid = ASID(mm); 3718c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci if (possible_tlb_flags & (TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { 3748c2ecf20Sopenharmony_ci if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) { 3758c2ecf20Sopenharmony_ci tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); 3768c2ecf20Sopenharmony_ci tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); 3778c2ecf20Sopenharmony_ci tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci } 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid); 3828c2ecf20Sopenharmony_ci tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid); 3838c2ecf20Sopenharmony_ci tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid); 3848c2ecf20Sopenharmony_ci} 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_mm(struct mm_struct *mm) 3878c2ecf20Sopenharmony_ci{ 3888c2ecf20Sopenharmony_ci const int asid = ASID(mm); 3898c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 3928c2ecf20Sopenharmony_ci dsb(nshst); 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci __local_flush_tlb_mm(mm); 3958c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_ASID, "c8, c7, 2", asid); 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci if (tlb_flag(TLB_BARRIER)) 3988c2ecf20Sopenharmony_ci dsb(nsh); 3998c2ecf20Sopenharmony_ci} 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_cistatic inline void __flush_tlb_mm(struct mm_struct *mm) 4028c2ecf20Sopenharmony_ci{ 4038c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 4068c2ecf20Sopenharmony_ci dsb(ishst); 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci __local_flush_tlb_mm(mm); 4098c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM_ERRATA_720789 4108c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", 0); 4118c2ecf20Sopenharmony_ci#else 4128c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", ASID(mm)); 4138c2ecf20Sopenharmony_ci#endif 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci if (tlb_flag(TLB_BARRIER)) 4168c2ecf20Sopenharmony_ci dsb(ish); 4178c2ecf20Sopenharmony_ci} 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_cistatic inline void 4208c2ecf20Sopenharmony_ci__local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) 4218c2ecf20Sopenharmony_ci{ 4228c2ecf20Sopenharmony_ci const int zero = 0; 4238c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci if (possible_tlb_flags & (TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && 4288c2ecf20Sopenharmony_ci cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { 4298c2ecf20Sopenharmony_ci tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); 4308c2ecf20Sopenharmony_ci tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr); 4318c2ecf20Sopenharmony_ci tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr); 4328c2ecf20Sopenharmony_ci if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) 4338c2ecf20Sopenharmony_ci asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr); 4378c2ecf20Sopenharmony_ci tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr); 4388c2ecf20Sopenharmony_ci tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr); 4398c2ecf20Sopenharmony_ci} 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_cistatic inline void 4428c2ecf20Sopenharmony_cilocal_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) 4438c2ecf20Sopenharmony_ci{ 4448c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 4498c2ecf20Sopenharmony_ci dsb(nshst); 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci __local_flush_tlb_page(vma, uaddr); 4528c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_PAGE, "c8, c7, 1", uaddr); 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci if (tlb_flag(TLB_BARRIER)) 4558c2ecf20Sopenharmony_ci dsb(nsh); 4568c2ecf20Sopenharmony_ci} 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_cistatic inline void 4598c2ecf20Sopenharmony_ci__flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) 4608c2ecf20Sopenharmony_ci{ 4618c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 4668c2ecf20Sopenharmony_ci dsb(ishst); 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci __local_flush_tlb_page(vma, uaddr); 4698c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM_ERRATA_720789 4708c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK); 4718c2ecf20Sopenharmony_ci#else 4728c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", uaddr); 4738c2ecf20Sopenharmony_ci#endif 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci if (tlb_flag(TLB_BARRIER)) 4768c2ecf20Sopenharmony_ci dsb(ish); 4778c2ecf20Sopenharmony_ci} 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_cistatic inline void __local_flush_tlb_kernel_page(unsigned long kaddr) 4808c2ecf20Sopenharmony_ci{ 4818c2ecf20Sopenharmony_ci const int zero = 0; 4828c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); 4858c2ecf20Sopenharmony_ci tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); 4868c2ecf20Sopenharmony_ci tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); 4878c2ecf20Sopenharmony_ci if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) 4888c2ecf20Sopenharmony_ci asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr); 4918c2ecf20Sopenharmony_ci tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr); 4928c2ecf20Sopenharmony_ci tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr); 4938c2ecf20Sopenharmony_ci} 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_kernel_page(unsigned long kaddr) 4968c2ecf20Sopenharmony_ci{ 4978c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci kaddr &= PAGE_MASK; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 5028c2ecf20Sopenharmony_ci dsb(nshst); 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci __local_flush_tlb_kernel_page(kaddr); 5058c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_PAGE, "c8, c7, 1", kaddr); 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci if (tlb_flag(TLB_BARRIER)) { 5088c2ecf20Sopenharmony_ci dsb(nsh); 5098c2ecf20Sopenharmony_ci isb(); 5108c2ecf20Sopenharmony_ci } 5118c2ecf20Sopenharmony_ci} 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_cistatic inline void __flush_tlb_kernel_page(unsigned long kaddr) 5148c2ecf20Sopenharmony_ci{ 5158c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci kaddr &= PAGE_MASK; 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 5208c2ecf20Sopenharmony_ci dsb(ishst); 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci __local_flush_tlb_kernel_page(kaddr); 5238c2ecf20Sopenharmony_ci tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr); 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_ci if (tlb_flag(TLB_BARRIER)) { 5268c2ecf20Sopenharmony_ci dsb(ish); 5278c2ecf20Sopenharmony_ci isb(); 5288c2ecf20Sopenharmony_ci } 5298c2ecf20Sopenharmony_ci} 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci/* 5328c2ecf20Sopenharmony_ci * Branch predictor maintenance is paired with full TLB invalidation, so 5338c2ecf20Sopenharmony_ci * there is no need for any barriers here. 5348c2ecf20Sopenharmony_ci */ 5358c2ecf20Sopenharmony_cistatic inline void __local_flush_bp_all(void) 5368c2ecf20Sopenharmony_ci{ 5378c2ecf20Sopenharmony_ci const int zero = 0; 5388c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci if (tlb_flag(TLB_V6_BP)) 5418c2ecf20Sopenharmony_ci asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero)); 5428c2ecf20Sopenharmony_ci} 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_cistatic inline void local_flush_bp_all(void) 5458c2ecf20Sopenharmony_ci{ 5468c2ecf20Sopenharmony_ci const int zero = 0; 5478c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci __local_flush_bp_all(); 5508c2ecf20Sopenharmony_ci if (tlb_flag(TLB_V7_UIS_BP)) 5518c2ecf20Sopenharmony_ci asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero)); 5528c2ecf20Sopenharmony_ci} 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_cistatic inline void __flush_bp_all(void) 5558c2ecf20Sopenharmony_ci{ 5568c2ecf20Sopenharmony_ci const int zero = 0; 5578c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci __local_flush_bp_all(); 5608c2ecf20Sopenharmony_ci if (tlb_flag(TLB_V7_UIS_BP)) 5618c2ecf20Sopenharmony_ci asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero)); 5628c2ecf20Sopenharmony_ci} 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci/* 5658c2ecf20Sopenharmony_ci * flush_pmd_entry 5668c2ecf20Sopenharmony_ci * 5678c2ecf20Sopenharmony_ci * Flush a PMD entry (word aligned, or double-word aligned) to 5688c2ecf20Sopenharmony_ci * RAM if the TLB for the CPU we are running on requires this. 5698c2ecf20Sopenharmony_ci * This is typically used when we are creating PMD entries. 5708c2ecf20Sopenharmony_ci * 5718c2ecf20Sopenharmony_ci * clean_pmd_entry 5728c2ecf20Sopenharmony_ci * 5738c2ecf20Sopenharmony_ci * Clean (but don't drain the write buffer) if the CPU requires 5748c2ecf20Sopenharmony_ci * these operations. This is typically used when we are removing 5758c2ecf20Sopenharmony_ci * PMD entries. 5768c2ecf20Sopenharmony_ci */ 5778c2ecf20Sopenharmony_cistatic inline void flush_pmd_entry(void *pmd) 5788c2ecf20Sopenharmony_ci{ 5798c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd); 5828c2ecf20Sopenharmony_ci tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd); 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci if (tlb_flag(TLB_WB)) 5858c2ecf20Sopenharmony_ci dsb(ishst); 5868c2ecf20Sopenharmony_ci} 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_cistatic inline void clean_pmd_entry(void *pmd) 5898c2ecf20Sopenharmony_ci{ 5908c2ecf20Sopenharmony_ci const unsigned int __tlb_flag = __cpu_tlb_flags; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd); 5938c2ecf20Sopenharmony_ci tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd); 5948c2ecf20Sopenharmony_ci} 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci#undef tlb_op 5978c2ecf20Sopenharmony_ci#undef tlb_flag 5988c2ecf20Sopenharmony_ci#undef always_tlb_flags 5998c2ecf20Sopenharmony_ci#undef possible_tlb_flags 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci/* 6028c2ecf20Sopenharmony_ci * Convert calls to our calling convention. 6038c2ecf20Sopenharmony_ci */ 6048c2ecf20Sopenharmony_ci#define local_flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) 6058c2ecf20Sopenharmony_ci#define local_flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci#ifndef CONFIG_SMP 6088c2ecf20Sopenharmony_ci#define flush_tlb_all local_flush_tlb_all 6098c2ecf20Sopenharmony_ci#define flush_tlb_mm local_flush_tlb_mm 6108c2ecf20Sopenharmony_ci#define flush_tlb_page local_flush_tlb_page 6118c2ecf20Sopenharmony_ci#define flush_tlb_kernel_page local_flush_tlb_kernel_page 6128c2ecf20Sopenharmony_ci#define flush_tlb_range local_flush_tlb_range 6138c2ecf20Sopenharmony_ci#define flush_tlb_kernel_range local_flush_tlb_kernel_range 6148c2ecf20Sopenharmony_ci#define flush_bp_all local_flush_bp_all 6158c2ecf20Sopenharmony_ci#else 6168c2ecf20Sopenharmony_ciextern void flush_tlb_all(void); 6178c2ecf20Sopenharmony_ciextern void flush_tlb_mm(struct mm_struct *mm); 6188c2ecf20Sopenharmony_ciextern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr); 6198c2ecf20Sopenharmony_ciextern void flush_tlb_kernel_page(unsigned long kaddr); 6208c2ecf20Sopenharmony_ciextern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); 6218c2ecf20Sopenharmony_ciextern void flush_tlb_kernel_range(unsigned long start, unsigned long end); 6228c2ecf20Sopenharmony_ciextern void flush_bp_all(void); 6238c2ecf20Sopenharmony_ci#endif 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci/* 6268c2ecf20Sopenharmony_ci * If PG_dcache_clean is not set for the page, we need to ensure that any 6278c2ecf20Sopenharmony_ci * cache entries for the kernels virtual memory range are written 6288c2ecf20Sopenharmony_ci * back to the page. On ARMv6 and later, the cache coherency is handled via 6298c2ecf20Sopenharmony_ci * the set_pte_at() function. 6308c2ecf20Sopenharmony_ci */ 6318c2ecf20Sopenharmony_ci#if __LINUX_ARM_ARCH__ < 6 6328c2ecf20Sopenharmony_ciextern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, 6338c2ecf20Sopenharmony_ci pte_t *ptep); 6348c2ecf20Sopenharmony_ci#else 6358c2ecf20Sopenharmony_cistatic inline void update_mmu_cache(struct vm_area_struct *vma, 6368c2ecf20Sopenharmony_ci unsigned long addr, pte_t *ptep) 6378c2ecf20Sopenharmony_ci{ 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ci#endif 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0) 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci#endif 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_ci#elif defined(CONFIG_SMP) /* !CONFIG_MMU */ 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 6488c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_all(void) { } 6498c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_mm(struct mm_struct *mm) { } 6508c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) { } 6518c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_kernel_page(unsigned long kaddr) { } 6528c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { } 6538c2ecf20Sopenharmony_cistatic inline void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) { } 6548c2ecf20Sopenharmony_cistatic inline void local_flush_bp_all(void) { } 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ciextern void flush_tlb_all(void); 6578c2ecf20Sopenharmony_ciextern void flush_tlb_mm(struct mm_struct *mm); 6588c2ecf20Sopenharmony_ciextern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr); 6598c2ecf20Sopenharmony_ciextern void flush_tlb_kernel_page(unsigned long kaddr); 6608c2ecf20Sopenharmony_ciextern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); 6618c2ecf20Sopenharmony_ciextern void flush_tlb_kernel_range(unsigned long start, unsigned long end); 6628c2ecf20Sopenharmony_ciextern void flush_bp_all(void); 6638c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_ci#endif 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 6688c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM_ERRATA_798181 6698c2ecf20Sopenharmony_ciextern void erratum_a15_798181_init(void); 6708c2ecf20Sopenharmony_ci#else 6718c2ecf20Sopenharmony_cistatic inline void erratum_a15_798181_init(void) {} 6728c2ecf20Sopenharmony_ci#endif 6738c2ecf20Sopenharmony_ciextern bool (*erratum_a15_798181_handler)(void); 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_cistatic inline bool erratum_a15_798181(void) 6768c2ecf20Sopenharmony_ci{ 6778c2ecf20Sopenharmony_ci if (unlikely(IS_ENABLED(CONFIG_ARM_ERRATA_798181) && 6788c2ecf20Sopenharmony_ci erratum_a15_798181_handler)) 6798c2ecf20Sopenharmony_ci return erratum_a15_798181_handler(); 6808c2ecf20Sopenharmony_ci return false; 6818c2ecf20Sopenharmony_ci} 6828c2ecf20Sopenharmony_ci#endif 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci#endif 685