Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[cascardo/linux.git] / arch / mips / include / asm / mmu_context.h
index d974353..145bb81 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/smp.h>
 #include <linux/slab.h>
 #include <asm/cacheflush.h>
+#include <asm/hazards.h>
 #include <asm/tlbflush.h>
 #ifdef CONFIG_MIPS_MT_SMTC
 #include <asm/mipsmtregs.h>
 #endif /* SMTC */
 #include <asm-generic/mm_hooks.h>
 
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+
+#define TLBMISS_HANDLER_SETUP_PGD(pgd)                         \
+       tlbmiss_handler_setup_pgd((unsigned long)(pgd))
+
+static inline void tlbmiss_handler_setup_pgd(unsigned long pgd)
+{
+       /* Check for swapper_pg_dir and convert to physical address. */
+       if ((pgd & CKSEG3) == CKSEG0)
+               pgd = CPHYSADDR(pgd);
+       write_c0_context(pgd << 11);
+}
+
+#define TLBMISS_HANDLER_SETUP()                                                \
+       do {                                                            \
+               TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);              \
+               write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
+       } while (0)
+
+
+static inline unsigned long get_current_pgd(void)
+{
+       return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL);
+}
+
+#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
+
 /*
  * For the fast tlb miss handlers, we keep a per cpu array of pointers
  * to the current pgd for each processor. Also, the proc. id is stuffed
@@ -36,14 +64,16 @@ extern unsigned long pgd_current[];
 #ifdef CONFIG_32BIT
 #define TLBMISS_HANDLER_SETUP()                                                \
        write_c0_context((unsigned long) smp_processor_id() << 25);     \
+       back_to_back_c0_hazard();                                       \
        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
 #ifdef CONFIG_64BIT
 #define TLBMISS_HANDLER_SETUP()                                                \
        write_c0_context((unsigned long) smp_processor_id() << 26);     \
+       back_to_back_c0_hazard();                                       \
        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
 #define ASID_INC       0x40
@@ -165,12 +195,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
         * having ASID_MASK smaller than the hardware maximum,
         * make sure no "soft" bits become "hard"...
         */
-       write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK)
-                       | (cpu_context(cpu, next) & ASID_MASK));
+       write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
+                        cpu_asid(cpu, next));
        ehb(); /* Make sure it propagates to TCStatus */
        evpe(mtflags);
 #else
-       write_c0_entryhi(cpu_context(cpu, next));
+       write_c0_entryhi(cpu_asid(cpu, next));
 #endif /* CONFIG_MIPS_MT_SMTC */
        TLBMISS_HANDLER_SETUP_PGD(next->pgd);
 
@@ -226,11 +256,11 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
        }
        /* See comments for similar code above */
        write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
-                        (cpu_context(cpu, next) & ASID_MASK));
+                        cpu_asid(cpu, next));
        ehb(); /* Make sure it propagates to TCStatus */
        evpe(mtflags);
 #else
-       write_c0_entryhi(cpu_context(cpu, next));
+       write_c0_entryhi(cpu_asid(cpu, next));
 #endif /* CONFIG_MIPS_MT_SMTC */
        TLBMISS_HANDLER_SETUP_PGD(next->pgd);