1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 #ifndef __ASM_TLB_H 6 #define __ASM_TLB_H 7 8 #include <linux/mm_types.h> 9 #include <asm/cpu-features.h> 10 #include <asm/loongarch.h> 11 12 /* 13 * TLB Invalidate Flush 14 */ 15 static inline void tlbclr(void) 16 { 17 __asm__ __volatile__("tlbclr"); 18 } 19 20 static inline void tlbflush(void) 21 { 22 __asm__ __volatile__("tlbflush"); 23 } 24 25 /* 26 * TLB R/W operations. 27 */ 28 static inline void tlb_probe(void) 29 { 30 __asm__ __volatile__("tlbsrch"); 31 } 32 33 static inline void tlb_read(void) 34 { 35 __asm__ __volatile__("tlbrd"); 36 } 37 38 static inline void tlb_write_indexed(void) 39 { 40 __asm__ __volatile__("tlbwr"); 41 } 42 43 static inline void tlb_write_random(void) 44 { 45 __asm__ __volatile__("tlbfill"); 46 } 47 48 enum invtlb_ops { 49 /* Invalid all tlb */ 50 INVTLB_ALL = 0x0, 51 /* Invalid current tlb */ 52 INVTLB_CURRENT_ALL = 0x1, 53 /* Invalid all global=1 lines in current tlb */ 54 INVTLB_CURRENT_GTRUE = 0x2, 55 /* Invalid all global=0 lines in current tlb */ 56 INVTLB_CURRENT_GFALSE = 0x3, 57 /* Invalid global=0 and matched asid lines in current tlb */ 58 INVTLB_GFALSE_AND_ASID = 0x4, 59 /* Invalid addr with global=0 and matched asid in current tlb */ 60 INVTLB_ADDR_GFALSE_AND_ASID = 0x5, 61 /* Invalid addr with global=1 or matched asid in current tlb */ 62 INVTLB_ADDR_GTRUE_OR_ASID = 0x6, 63 /* Invalid matched gid in guest tlb */ 64 INVGTLB_GID = 0x9, 65 /* Invalid global=1, matched gid in guest tlb */ 66 INVGTLB_GID_GTRUE = 0xa, 67 /* Invalid global=0, matched gid in guest tlb */ 68 INVGTLB_GID_GFALSE = 0xb, 69 /* Invalid global=0, matched gid and asid in guest tlb */ 70 INVGTLB_GID_GFALSE_ASID = 0xc, 71 /* Invalid global=0 , matched gid, asid and addr in guest tlb */ 72 INVGTLB_GID_GFALSE_ASID_ADDR = 0xd, 73 /* Invalid global=1 , matched gid, asid and addr in guest tlb */ 74 INVGTLB_GID_GTRUE_ASID_ADDR = 0xe, 75 /* Invalid all gid gva-->gpa guest tlb */ 76 INVGTLB_ALLGID_GVA_TO_GPA = 0x10, 77 /* Invalid all gid gpa-->hpa tlb */ 78 INVTLB_ALLGID_GPA_TO_HPA = 0x11, 79 /* Invalid all gid tlb, including gva-->gpa and gpa-->hpa */ 80 INVTLB_ALLGID = 0x12, 81 /* Invalid matched gid gva-->gpa guest tlb */ 82 INVGTLB_GID_GVA_TO_GPA = 0x13, 83 /* Invalid matched gid gpa-->hpa tlb */ 84 INVTLB_GID_GPA_TO_HPA = 0x14, 85 /* Invalid matched gid tlb,including gva-->gpa and gpa-->hpa */ 86 INVTLB_GID_ALL = 0x15, 87 /* Invalid matched gid and addr gpa-->hpa tlb */ 88 INVTLB_GID_ADDR = 0x16, 89 }; 90 91 static __always_inline void invtlb(u32 op, u32 info, u64 addr) 92 { 93 __asm__ __volatile__( 94 "invtlb %0, %1, %2\n\t" 95 : 96 : "i"(op), "r"(info), "r"(addr) 97 : "memory" 98 ); 99 } 100 101 static __always_inline void invtlb_addr(u32 op, u32 info, u64 addr) 102 { 103 BUILD_BUG_ON(!__builtin_constant_p(info) || info != 0); 104 __asm__ __volatile__( 105 "invtlb %0, $zero, %1\n\t" 106 : 107 : "i"(op), "r"(addr) 108 : "memory" 109 ); 110 } 111 112 static __always_inline void invtlb_info(u32 op, u32 info, u64 addr) 113 { 114 BUILD_BUG_ON(!__builtin_constant_p(addr) || addr != 0); 115 __asm__ __volatile__( 116 "invtlb %0, %1, $zero\n\t" 117 : 118 : "i"(op), "r"(info) 119 : "memory" 120 ); 121 } 122 123 static __always_inline void invtlb_all(u32 op, u32 info, u64 addr) 124 { 125 BUILD_BUG_ON(!__builtin_constant_p(info) || info != 0); 126 BUILD_BUG_ON(!__builtin_constant_p(addr) || addr != 0); 127 __asm__ __volatile__( 128 "invtlb %0, $zero, $zero\n\t" 129 : 130 : "i"(op) 131 : "memory" 132 ); 133 } 134 135 static void tlb_flush(struct mmu_gather *tlb); 136 137 #define tlb_flush tlb_flush 138 #include <asm-generic/tlb.h> 139 140 static inline void tlb_flush(struct mmu_gather *tlb) 141 { 142 struct vm_area_struct vma; 143 144 vma.vm_mm = tlb->mm; 145 vm_flags_init(&vma, 0); 146 if (tlb->fullmm) { 147 flush_tlb_mm(tlb->mm); 148 return; 149 } 150 151 flush_tlb_range(&vma, tlb->start, tlb->end); 152 } 153 154 extern void handle_tlb_load(void); 155 extern void handle_tlb_store(void); 156 extern void handle_tlb_modify(void); 157 extern void handle_tlb_refill(void); 158 extern void handle_tlb_protect(void); 159 extern void handle_tlb_load_ptw(void); 160 extern void handle_tlb_store_ptw(void); 161 extern void handle_tlb_modify_ptw(void); 162 163 extern void dump_tlb_all(void); 164 extern void dump_tlb_regs(void); 165 166 #endif /* __ASM_TLB_H */ 167