1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_POWERPC_BOOK3S_32_TLBFLUSH_H
3#define _ASM_POWERPC_BOOK3S_32_TLBFLUSH_H
4
5#include <linux/build_bug.h>
6
7#define MMU_NO_CONTEXT      (0)
8/*
9 * TLB flushing for "classic" hash-MMU 32-bit CPUs, 6xx, 7xx, 7xxx
10 */
11void hash__flush_tlb_mm(struct mm_struct *mm);
12void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
13void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end);
14
15#ifdef CONFIG_SMP
16void _tlbie(unsigned long address);
17#else
18static inline void _tlbie(unsigned long address)
19{
20	asm volatile ("tlbie %0; sync" : : "r" (address) : "memory");
21}
22#endif
23void _tlbia(void);
24
25/*
26 * Called at the end of a mmu_gather operation to make sure the
27 * TLB flush is completely done.
28 */
29static inline void tlb_flush(struct mmu_gather *tlb)
30{
31	/* 603 needs to flush the whole TLB here since it doesn't use a hash table. */
32	if (!mmu_has_feature(MMU_FTR_HPTE_TABLE))
33		_tlbia();
34}
35
36static inline void flush_range(struct mm_struct *mm, unsigned long start, unsigned long end)
37{
38	start &= PAGE_MASK;
39	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
40		hash__flush_range(mm, start, end);
41	else if (end - start <= PAGE_SIZE)
42		_tlbie(start);
43	else
44		_tlbia();
45}
46
47static inline void flush_tlb_mm(struct mm_struct *mm)
48{
49	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
50		hash__flush_tlb_mm(mm);
51	else
52		_tlbia();
53}
54
55static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
56{
57	if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
58		hash__flush_tlb_page(vma, vmaddr);
59	else
60		_tlbie(vmaddr);
61}
62
63static inline void
64flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
65{
66	flush_range(vma->vm_mm, start, end);
67}
68
69static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
70{
71	flush_range(&init_mm, start, end);
72}
73
74static inline void local_flush_tlb_page(struct vm_area_struct *vma,
75					unsigned long vmaddr)
76{
77	flush_tlb_page(vma, vmaddr);
78}
79
80static inline void local_flush_tlb_page_psize(struct mm_struct *mm,
81					      unsigned long vmaddr, int psize)
82{
83	flush_range(mm, vmaddr, vmaddr);
84}
85
86static inline void local_flush_tlb_mm(struct mm_struct *mm)
87{
88	flush_tlb_mm(mm);
89}
90
91#endif /* _ASM_POWERPC_BOOK3S_32_TLBFLUSH_H */
92