linux/arch/unicore32/include/asm/tlbflush.h
<<
>>
Prefs
   1/*
   2 * linux/arch/unicore32/include/asm/tlbflush.h
   3 *
   4 * Code specific to PKUnity SoC and UniCore ISA
   5 *
   6 * Copyright (C) 2001-2010 GUAN Xue-tao
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12#ifndef __UNICORE_TLBFLUSH_H__
  13#define __UNICORE_TLBFLUSH_H__
  14
  15#ifndef __ASSEMBLY__
  16
  17#include <linux/sched.h>
  18
  19extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long,
  20                                        struct vm_area_struct *);
  21extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
  22
  23/*
  24 *      TLB Management
  25 *      ==============
  26 *
  27 *      The arch/unicore/mm/tlb-*.S files implement these methods.
  28 *
  29 *      The TLB specific code is expected to perform whatever tests it
  30 *      needs to determine if it should invalidate the TLB for each
  31 *      call.  Start addresses are inclusive and end addresses are
  32 *      exclusive; it is safe to round these addresses down.
  33 *
  34 *      flush_tlb_all()
  35 *
  36 *              Invalidate the entire TLB.
  37 *
  38 *      flush_tlb_mm(mm)
  39 *
  40 *              Invalidate all TLB entries in a particular address
  41 *              space.
  42 *              - mm    - mm_struct describing address space
  43 *
  44 *      flush_tlb_range(mm,start,end)
  45 *
  46 *              Invalidate a range of TLB entries in the specified
  47 *              address space.
  48 *              - mm    - mm_struct describing address space
  49 *              - start - start address (may not be aligned)
  50 *              - end   - end address (exclusive, may not be aligned)
  51 *
  52 *      flush_tlb_page(vaddr,vma)
  53 *
  54 *              Invalidate the specified page in the specified address range.
  55 *              - vaddr - virtual address (may not be aligned)
  56 *              - vma   - vma_struct describing address range
  57 *
  58 *      flush_kern_tlb_page(kaddr)
  59 *
  60 *              Invalidate the TLB entry for the specified page.  The address
  61 *              will be in the kernels virtual memory space.  Current uses
  62 *              only require the D-TLB to be invalidated.
  63 *              - kaddr - Kernel virtual memory address
  64 */
  65
  66static inline void local_flush_tlb_all(void)
  67{
  68        const int zero = 0;
  69
  70        /* TLB invalidate all */
  71        asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
  72                : : "r" (zero) : "cc");
  73}
  74
  75static inline void local_flush_tlb_mm(struct mm_struct *mm)
  76{
  77        const int zero = 0;
  78
  79        if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
  80                /* TLB invalidate all */
  81                asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
  82                        : : "r" (zero) : "cc");
  83        }
  84        put_cpu();
  85}
  86
  87static inline void
  88local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
  89{
  90        if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
  91#ifndef CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE
  92                /* iTLB invalidate page */
  93                asm("movc p0.c6, %0, #5; nop; nop; nop; nop; nop; nop; nop; nop"
  94                        : : "r" (uaddr & PAGE_MASK) : "cc");
  95                /* dTLB invalidate page */
  96                asm("movc p0.c6, %0, #3; nop; nop; nop; nop; nop; nop; nop; nop"
  97                        : : "r" (uaddr & PAGE_MASK) : "cc");
  98#else
  99                /* TLB invalidate all */
 100                asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
 101                        : : "r" (uaddr & PAGE_MASK) : "cc");
 102#endif
 103        }
 104}
 105
 106static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
 107{
 108#ifndef CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE
 109        /* iTLB invalidate page */
 110        asm("movc p0.c6, %0, #5; nop; nop; nop; nop; nop; nop; nop; nop"
 111                : : "r" (kaddr & PAGE_MASK) : "cc");
 112        /* dTLB invalidate page */
 113        asm("movc p0.c6, %0, #3; nop; nop; nop; nop; nop; nop; nop; nop"
 114                : : "r" (kaddr & PAGE_MASK) : "cc");
 115#else
 116        /* TLB invalidate all */
 117        asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop"
 118                : : "r" (kaddr & PAGE_MASK) : "cc");
 119#endif
 120}
 121
 122/*
 123 *      flush_pmd_entry
 124 *
 125 *      Flush a PMD entry (word aligned, or double-word aligned) to
 126 *      RAM if the TLB for the CPU we are running on requires this.
 127 *      This is typically used when we are creating PMD entries.
 128 *
 129 *      clean_pmd_entry
 130 *
 131 *      Clean (but don't drain the write buffer) if the CPU requires
 132 *      these operations.  This is typically used when we are removing
 133 *      PMD entries.
 134 */
 135static inline void flush_pmd_entry(pmd_t *pmd)
 136{
 137#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
 138        /* flush dcache line, see dcacheline_flush in proc-macros.S */
 139        asm("mov        r1, %0 << #20\n"
 140                "ldw    r2, =_stext\n"
 141                "add    r2, r2, r1 >> #20\n"
 142                "ldw    r1, [r2+], #0x0000\n"
 143                "ldw    r1, [r2+], #0x1000\n"
 144                "ldw    r1, [r2+], #0x2000\n"
 145                "ldw    r1, [r2+], #0x3000\n"
 146                : : "r" (pmd) : "r1", "r2");
 147#else
 148        /* flush dcache all */
 149        asm("movc p0.c5, %0, #14; nop; nop; nop; nop; nop; nop; nop; nop"
 150                : : "r" (pmd) : "cc");
 151#endif
 152}
 153
 154static inline void clean_pmd_entry(pmd_t *pmd)
 155{
 156#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
 157        /* clean dcache line */
 158        asm("movc p0.c5, %0, #11; nop; nop; nop; nop; nop; nop; nop; nop"
 159                : : "r" (__pa(pmd) & ~(L1_CACHE_BYTES - 1)) : "cc");
 160#else
 161        /* clean dcache all */
 162        asm("movc p0.c5, %0, #10; nop; nop; nop; nop; nop; nop; nop; nop"
 163                : : "r" (pmd) : "cc");
 164#endif
 165}
 166
 167/*
 168 * Convert calls to our calling convention.
 169 */
 170#define local_flush_tlb_range(vma, start, end)  \
 171        __cpu_flush_user_tlb_range(start, end, vma)
 172#define local_flush_tlb_kernel_range(s, e)      \
 173        __cpu_flush_kern_tlb_range(s, e)
 174
 175#define flush_tlb_all           local_flush_tlb_all
 176#define flush_tlb_mm            local_flush_tlb_mm
 177#define flush_tlb_page          local_flush_tlb_page
 178#define flush_tlb_kernel_page   local_flush_tlb_kernel_page
 179#define flush_tlb_range         local_flush_tlb_range
 180#define flush_tlb_kernel_range  local_flush_tlb_kernel_range
 181
 182/*
 183 * if PG_dcache_clean is not set for the page, we need to ensure that any
 184 * cache entries for the kernels virtual memory range are written
 185 * back to the page.
 186 */
 187extern void update_mmu_cache(struct vm_area_struct *vma,
 188                unsigned long addr, pte_t *ptep);
 189
 190extern void do_bad_area(unsigned long addr, unsigned int fsr,
 191                struct pt_regs *regs);
 192
 193#endif
 194
 195#endif
 196