1 #ifndef _M68K_TLBFLUSH_H 2 #define _M68K_TLBFLUSH_H 3 4 #ifdef CONFIG_MMU 5 #ifndef CONFIG_SUN3 6 7 #include <asm/current.h> 8 9 static inline void flush_tlb_kernel_page(void *addr) 10 { 11 if (CPU_IS_040_OR_060) { 12 mm_segment_t old_fs = get_fs(); 13 set_fs(KERNEL_DS); 14 __asm__ __volatile__(".chip 68040\n\t" 15 "pflush (%0)\n\t" 16 ".chip 68k" 17 : : "a" (addr)); 18 set_fs(old_fs); 19 } else if (CPU_IS_020_OR_030) 20 __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); 21 } 22 23 /* 24 * flush all user-space atc entries. 25 */ 26 static inline void __flush_tlb(void) 27 { 28 if (CPU_IS_040_OR_060) 29 __asm__ __volatile__(".chip 68040\n\t" 30 "pflushan\n\t" 31 ".chip 68k"); 32 else if (CPU_IS_020_OR_030) 33 __asm__ __volatile__("pflush #0,#4"); 34 } 35 36 static inline void __flush_tlb040_one(unsigned long addr) 37 { 38 __asm__ __volatile__(".chip 68040\n\t" 39 "pflush (%0)\n\t" 40 ".chip 68k" 41 : : "a" (addr)); 42 } 43 44 static inline void __flush_tlb_one(unsigned long addr) 45 { 46 if (CPU_IS_040_OR_060) 47 __flush_tlb040_one(addr); 48 else if (CPU_IS_020_OR_030) 49 __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); 50 } 51 52 #define flush_tlb() __flush_tlb() 53 54 /* 55 * flush all atc entries (both kernel and user-space entries). 56 */ 57 static inline void flush_tlb_all(void) 58 { 59 if (CPU_IS_040_OR_060) 60 __asm__ __volatile__(".chip 68040\n\t" 61 "pflusha\n\t" 62 ".chip 68k"); 63 else if (CPU_IS_020_OR_030) 64 __asm__ __volatile__("pflusha"); 65 } 66 67 static inline void flush_tlb_mm(struct mm_struct *mm) 68 { 69 if (mm == current->active_mm) 70 __flush_tlb(); 71 } 72 73 static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) 74 { 75 if (vma->vm_mm == current->active_mm) { 76 mm_segment_t old_fs = get_fs(); 77 set_fs(USER_DS); 78 __flush_tlb_one(addr); 79 set_fs(old_fs); 80 } 81 } 82 83 static inline void flush_tlb_range(struct vm_area_struct *vma, 84 unsigned long start, unsigned long end) 85 { 86 if (vma->vm_mm == current->active_mm) 87 __flush_tlb(); 88 } 89 90 static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) 91 { 92 flush_tlb_all(); 93 } 94 95 #else 96 97 98 /* Reserved PMEGs. */ 99 extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; 100 extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM]; 101 extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM]; 102 extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM]; 103 104 /* Flush all userspace mappings one by one... (why no flush command, 105 sun?) */ 106 static inline void flush_tlb_all(void) 107 { 108 unsigned long addr; 109 unsigned char ctx, oldctx; 110 111 oldctx = sun3_get_context(); 112 for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) { 113 for(ctx = 0; ctx < 8; ctx++) { 114 sun3_put_context(ctx); 115 sun3_put_segmap(addr, SUN3_INVALID_PMEG); 116 } 117 } 118 119 sun3_put_context(oldctx); 120 /* erase all of the userspace pmeg maps, we've clobbered them 121 all anyway */ 122 for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) { 123 if(pmeg_alloc[addr] == 1) { 124 pmeg_alloc[addr] = 0; 125 pmeg_ctx[addr] = 0; 126 pmeg_vaddr[addr] = 0; 127 } 128 } 129 130 } 131 132 /* Clear user TLB entries within the context named in mm */ 133 static inline void flush_tlb_mm (struct mm_struct *mm) 134 { 135 unsigned char oldctx; 136 unsigned char seg; 137 unsigned long i; 138 139 oldctx = sun3_get_context(); 140 sun3_put_context(mm->context); 141 142 for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) { 143 seg = sun3_get_segmap(i); 144 if(seg == SUN3_INVALID_PMEG) 145 continue; 146 147 sun3_put_segmap(i, SUN3_INVALID_PMEG); 148 pmeg_alloc[seg] = 0; 149 pmeg_ctx[seg] = 0; 150 pmeg_vaddr[seg] = 0; 151 } 152 153 sun3_put_context(oldctx); 154 155 } 156 157 /* Flush a single TLB page. In this case, we're limited to flushing a 158 single PMEG */ 159 static inline void flush_tlb_page (struct vm_area_struct *vma, 160 unsigned long addr) 161 { 162 unsigned char oldctx; 163 unsigned char i; 164 165 oldctx = sun3_get_context(); 166 sun3_put_context(vma->vm_mm->context); 167 addr &= ~SUN3_PMEG_MASK; 168 if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG) 169 { 170 pmeg_alloc[i] = 0; 171 pmeg_ctx[i] = 0; 172 pmeg_vaddr[i] = 0; 173 sun3_put_segmap (addr, SUN3_INVALID_PMEG); 174 } 175 sun3_put_context(oldctx); 176 177 } 178 /* Flush a range of pages from TLB. */ 179 180 static inline void flush_tlb_range (struct vm_area_struct *vma, 181 unsigned long start, unsigned long end) 182 { 183 struct mm_struct *mm = vma->vm_mm; 184 unsigned char seg, oldctx; 185 186 start &= ~SUN3_PMEG_MASK; 187 188 oldctx = sun3_get_context(); 189 sun3_put_context(mm->context); 190 191 while(start < end) 192 { 193 if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) 194 goto next; 195 if(pmeg_ctx[seg] == mm->context) { 196 pmeg_alloc[seg] = 0; 197 pmeg_ctx[seg] = 0; 198 pmeg_vaddr[seg] = 0; 199 } 200 sun3_put_segmap(start, SUN3_INVALID_PMEG); 201 next: 202 start += SUN3_PMEG_SIZE; 203 } 204 } 205 206 static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) 207 { 208 flush_tlb_all(); 209 } 210 211 /* Flush kernel page from TLB. */ 212 static inline void flush_tlb_kernel_page (unsigned long addr) 213 { 214 sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG); 215 } 216 217 #endif 218 219 #else /* !CONFIG_MMU */ 220 221 /* 222 * flush all user-space atc entries. 223 */ 224 static inline void __flush_tlb(void) 225 { 226 BUG(); 227 } 228 229 static inline void __flush_tlb_one(unsigned long addr) 230 { 231 BUG(); 232 } 233 234 #define flush_tlb() __flush_tlb() 235 236 /* 237 * flush all atc entries (both kernel and user-space entries). 238 */ 239 static inline void flush_tlb_all(void) 240 { 241 BUG(); 242 } 243 244 static inline void flush_tlb_mm(struct mm_struct *mm) 245 { 246 BUG(); 247 } 248 249 static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) 250 { 251 BUG(); 252 } 253 254 static inline void flush_tlb_range(struct mm_struct *mm, 255 unsigned long start, unsigned long end) 256 { 257 BUG(); 258 } 259 260 static inline void flush_tlb_kernel_page(unsigned long addr) 261 { 262 BUG(); 263 } 264 265 #endif /* CONFIG_MMU */ 266 267 #endif /* _M68K_TLBFLUSH_H */ 268