root/arch/m68k/include/asm/tlbflush.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. flush_tlb_kernel_page
  2. __flush_tlb
  3. __flush_tlb040_one
  4. __flush_tlb_one
  5. flush_tlb_all
  6. flush_tlb_mm
  7. flush_tlb_page
  8. flush_tlb_range
  9. flush_tlb_kernel_range
  10. flush_tlb_all
  11. flush_tlb_mm
  12. flush_tlb_page
  13. flush_tlb_range
  14. flush_tlb_kernel_range
  15. flush_tlb_kernel_page
  16. __flush_tlb
  17. __flush_tlb_one
  18. flush_tlb_all
  19. flush_tlb_mm
  20. flush_tlb_page
  21. flush_tlb_range
  22. flush_tlb_kernel_page

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

/* [<][>][^][v][top][bottom][index][help] */