1405cb402SChristophe Leroy /* SPDX-License-Identifier: GPL-2.0 */
2405cb402SChristophe Leroy #ifndef _ASM_POWERPC_NOHASH_TLBFLUSH_H
3405cb402SChristophe Leroy #define _ASM_POWERPC_NOHASH_TLBFLUSH_H
4405cb402SChristophe Leroy 
5405cb402SChristophe Leroy /*
6405cb402SChristophe Leroy  * TLB flushing:
7405cb402SChristophe Leroy  *
8405cb402SChristophe Leroy  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
9405cb402SChristophe Leroy  *  - flush_tlb_page(vma, vmaddr) flushes one page
10405cb402SChristophe Leroy  *  - local_flush_tlb_mm(mm, full) flushes the specified mm context on
11405cb402SChristophe Leroy  *                           the local processor
12405cb402SChristophe Leroy  *  - local_flush_tlb_page(vma, vmaddr) flushes one page on the local processor
13405cb402SChristophe Leroy  *  - flush_tlb_range(vma, start, end) flushes a range of pages
14405cb402SChristophe Leroy  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
15405cb402SChristophe Leroy  *
16405cb402SChristophe Leroy  */
17405cb402SChristophe Leroy 
18405cb402SChristophe Leroy /*
19405cb402SChristophe Leroy  * TLB flushing for software loaded TLB chips
20405cb402SChristophe Leroy  *
21dfc3095cSChristophe Leroy  * TODO: (CONFIG_PPC_85xx) determine if flush_tlb_range &
22405cb402SChristophe Leroy  * flush_tlb_kernel_range are best implemented as tlbia vs
23405cb402SChristophe Leroy  * specific tlbie's
24405cb402SChristophe Leroy  */
25405cb402SChristophe Leroy 
26405cb402SChristophe Leroy struct vm_area_struct;
27405cb402SChristophe Leroy struct mm_struct;
28405cb402SChristophe Leroy 
29405cb402SChristophe Leroy #define MMU_NO_CONTEXT      	((unsigned int)-1)
30405cb402SChristophe Leroy 
31405cb402SChristophe Leroy extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
32405cb402SChristophe Leroy 			    unsigned long end);
33405cb402SChristophe Leroy 
3463f501e0SChristophe Leroy #ifdef CONFIG_PPC_8xx
local_flush_tlb_mm(struct mm_struct * mm)3563f501e0SChristophe Leroy static inline void local_flush_tlb_mm(struct mm_struct *mm)
3663f501e0SChristophe Leroy {
3763f501e0SChristophe Leroy 	unsigned int pid = READ_ONCE(mm->context.id);
3863f501e0SChristophe Leroy 
3963f501e0SChristophe Leroy 	if (pid != MMU_NO_CONTEXT)
4063f501e0SChristophe Leroy 		asm volatile ("sync; tlbia; isync" : : : "memory");
4163f501e0SChristophe Leroy }
4263f501e0SChristophe Leroy 
local_flush_tlb_page(struct vm_area_struct * vma,unsigned long vmaddr)4363f501e0SChristophe Leroy static inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
4463f501e0SChristophe Leroy {
4563f501e0SChristophe Leroy 	asm volatile ("tlbie %0; sync" : : "r" (vmaddr) : "memory");
4663f501e0SChristophe Leroy }
479290c379SChristophe Leroy 
local_flush_tlb_page_psize(struct mm_struct * mm,unsigned long vmaddr,int psize)48*274d842fSBenjamin Gray static inline void local_flush_tlb_page_psize(struct mm_struct *mm,
49*274d842fSBenjamin Gray 					      unsigned long vmaddr, int psize)
50*274d842fSBenjamin Gray {
51*274d842fSBenjamin Gray 	asm volatile ("tlbie %0; sync" : : "r" (vmaddr) : "memory");
52*274d842fSBenjamin Gray }
53*274d842fSBenjamin Gray 
flush_tlb_kernel_range(unsigned long start,unsigned long end)549290c379SChristophe Leroy static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
559290c379SChristophe Leroy {
569290c379SChristophe Leroy 	start &= PAGE_MASK;
579290c379SChristophe Leroy 
589290c379SChristophe Leroy 	if (end - start <= PAGE_SIZE)
599290c379SChristophe Leroy 		asm volatile ("tlbie %0; sync" : : "r" (start) : "memory");
609290c379SChristophe Leroy 	else
619290c379SChristophe Leroy 		asm volatile ("sync; tlbia; isync" : : : "memory");
629290c379SChristophe Leroy }
6363f501e0SChristophe Leroy #else
649290c379SChristophe Leroy extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
65405cb402SChristophe Leroy extern void local_flush_tlb_mm(struct mm_struct *mm);
66405cb402SChristophe Leroy extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
67*274d842fSBenjamin Gray void local_flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize);
68405cb402SChristophe Leroy 
69405cb402SChristophe Leroy extern void __local_flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
70405cb402SChristophe Leroy 				   int tsize, int ind);
7163f501e0SChristophe Leroy #endif
72405cb402SChristophe Leroy 
73405cb402SChristophe Leroy #ifdef CONFIG_SMP
74405cb402SChristophe Leroy extern void flush_tlb_mm(struct mm_struct *mm);
75405cb402SChristophe Leroy extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
76405cb402SChristophe Leroy extern void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
77405cb402SChristophe Leroy 			     int tsize, int ind);
78405cb402SChristophe Leroy #else
79405cb402SChristophe Leroy #define flush_tlb_mm(mm)		local_flush_tlb_mm(mm)
80405cb402SChristophe Leroy #define flush_tlb_page(vma,addr)	local_flush_tlb_page(vma,addr)
81405cb402SChristophe Leroy #define __flush_tlb_page(mm,addr,p,i)	__local_flush_tlb_page(mm,addr,p,i)
82405cb402SChristophe Leroy #endif
83405cb402SChristophe Leroy 
84405cb402SChristophe Leroy #endif /* _ASM_POWERPC_NOHASH_TLBFLUSH_H */
85