fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / asm-arm / tlbflush.h
index 8a864b1..cd10a0b 100644 (file)
 #ifndef _ASMARM_TLBFLUSH_H
 #define _ASMARM_TLBFLUSH_H
 
-#include <linux/config.h>
+
+#ifndef CONFIG_MMU
+
+#define tlb_flush(tlb) ((void) tlb)
+
+#else /* CONFIG_MMU */
+
 #include <asm/glue.h>
 
 #define TLB_V3_PAGE    (1 << 0)
@@ -235,54 +241,54 @@ extern struct cpu_tlb_fns cpu_tlb;
 
 #define tlb_flag(f)    ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
 
-static inline void flush_tlb_all(void)
+static inline void local_flush_tlb_all(void)
 {
        const int zero = 0;
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
 
        if (tlb_flag(TLB_V3_FULL))
-               asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
        if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL))
-               asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
        if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL))
-               asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
        if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
-               asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
 }
 
-static inline void flush_tlb_mm(struct mm_struct *mm)
+static inline void local_flush_tlb_mm(struct mm_struct *mm)
 {
        const int zero = 0;
        const int asid = ASID(mm);
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
 
        if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) {
                if (tlb_flag(TLB_V3_FULL))
-                       asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
                if (tlb_flag(TLB_V4_U_FULL))
-                       asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
                if (tlb_flag(TLB_V4_D_FULL))
-                       asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
                if (tlb_flag(TLB_V4_I_FULL))
-                       asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
        }
 
        if (tlb_flag(TLB_V6_U_ASID))
-               asm("mcr%? p15, 0, %0, c8, c7, 2" : : "r" (asid));
+               asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc");
        if (tlb_flag(TLB_V6_D_ASID))
-               asm("mcr%? p15, 0, %0, c8, c6, 2" : : "r" (asid));
+               asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
        if (tlb_flag(TLB_V6_I_ASID))
-               asm("mcr%? p15, 0, %0, c8, c5, 2" : : "r" (asid));
+               asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
 }
 
 static inline void
-flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
 {
        const int zero = 0;
        const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -290,30 +296,30 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
        uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
 
        if (tlb_flag(TLB_WB))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero));
 
        if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
                if (tlb_flag(TLB_V3_PAGE))
-                       asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (uaddr));
+                       asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc");
                if (tlb_flag(TLB_V4_U_PAGE))
-                       asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
+                       asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
                if (tlb_flag(TLB_V4_D_PAGE))
-                       asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
+                       asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
                if (tlb_flag(TLB_V4_I_PAGE))
-                       asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
+                       asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
                if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
-                       asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+                       asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
        }
 
        if (tlb_flag(TLB_V6_U_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
+               asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
        if (tlb_flag(TLB_V6_D_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
+               asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
        if (tlb_flag(TLB_V6_I_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
+               asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
 }
 
-static inline void flush_tlb_kernel_page(unsigned long kaddr)
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
 {
        const int zero = 0;
        const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -321,25 +327,31 @@ static inline void flush_tlb_kernel_page(unsigned long kaddr)
        kaddr &= PAGE_MASK;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
 
        if (tlb_flag(TLB_V3_PAGE))
-               asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V4_U_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V4_D_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V4_I_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
        if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
-               asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+               asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
 
        if (tlb_flag(TLB_V6_U_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V6_D_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
        if (tlb_flag(TLB_V6_I_PAGE))
-               asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
+               asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
+
+       /* The ARM ARM states that the completion of a TLB maintenance
+        * operation is only guaranteed by a DSB instruction
+        */
+       if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE))
+               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
 }
 
 /*
@@ -361,11 +373,11 @@ static inline void flush_pmd_entry(pmd_t *pmd)
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_DCLEAN))
-               asm("mcr%?      p15, 0, %0, c7, c10, 1  @ flush_pmd"
-                       : : "r" (pmd));
+               asm("mcr        p15, 0, %0, c7, c10, 1  @ flush_pmd"
+                       : : "r" (pmd) : "cc");
        if (tlb_flag(TLB_WB))
-               asm("mcr%?      p15, 0, %0, c7, c10, 4  @ flush_pmd"
-                       : : "r" (zero));
+               asm("mcr        p15, 0, %0, c7, c10, 4  @ flush_pmd"
+                       : : "r" (zero) : "cc");
 }
 
 static inline void clean_pmd_entry(pmd_t *pmd)
@@ -373,8 +385,8 @@ static inline void clean_pmd_entry(pmd_t *pmd)
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_DCLEAN))
-               asm("mcr%?      p15, 0, %0, c7, c10, 1  @ flush_pmd"
-                       : : "r" (pmd));
+               asm("mcr        p15, 0, %0, c7, c10, 1  @ flush_pmd"
+                       : : "r" (pmd) : "cc");
 }
 
 #undef tlb_flag
@@ -384,8 +396,24 @@ static inline void clean_pmd_entry(pmd_t *pmd)
 /*
  * Convert calls to our calling convention.
  */
-#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
-#define flush_tlb_kernel_range(s,e)    __cpu_flush_kern_tlb_range(s,e)
+#define local_flush_tlb_range(vma,start,end)   __cpu_flush_user_tlb_range(start,end,vma)
+#define local_flush_tlb_kernel_range(s,e)      __cpu_flush_kern_tlb_range(s,e)
+
+#ifndef CONFIG_SMP
+#define flush_tlb_all          local_flush_tlb_all
+#define flush_tlb_mm           local_flush_tlb_mm
+#define flush_tlb_page         local_flush_tlb_page
+#define flush_tlb_kernel_page  local_flush_tlb_kernel_page
+#define flush_tlb_range                local_flush_tlb_range
+#define flush_tlb_kernel_range local_flush_tlb_kernel_range
+#else
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
+extern void flush_tlb_kernel_page(unsigned long kaddr);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+#endif
 
 /*
  * if PG_dcache_dirty is set for the page, we need to ensure that any
@@ -401,4 +429,6 @@ extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte
 
 #endif
 
+#endif /* CONFIG_MMU */
+
 #endif