vserver 1.9.5.x5
[linux-2.6.git] / include / asm-mips / mmu_context.h
index e427941..48b77c9 100644 (file)
 #include <asm/tlbflush.h>
 
 /*
- * For the fast tlb miss handlers, we currently keep a per cpu array
- * of pointers to the current pgd for each processor. Also, the proc.
- * id is stuffed into the context register. This should be changed to
- * use the processor id via current->processor, where current is stored
- * in watchhi/lo. The context register should be used to contiguously
- * map the page tables.
+ * 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
+ * into the context register.
  */
+extern unsigned long pgd_current[];
+
 #define TLBMISS_HANDLER_SETUP_PGD(pgd) \
        pgd_current[smp_processor_id()] = (unsigned long)(pgd)
+
 #ifdef CONFIG_MIPS32
-#define TLBMISS_HANDLER_SETUP() \
-       write_c0_context((unsigned long) smp_processor_id() << 23); \
+#define TLBMISS_HANDLER_SETUP()                                                \
+       write_c0_context((unsigned long) smp_processor_id() << 23);     \
        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-#ifdef CONFIG_MIPS64
-#define TLBMISS_HANDLER_SETUP() \
+#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
+#define TLBMISS_HANDLER_SETUP()                                                \
        write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \
        TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
 #endif
-extern unsigned long pgd_current[];
+#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
+#define TLBMISS_HANDLER_SETUP()                                                \
+       write_c0_context((unsigned long) smp_processor_id() << 23);     \
+       TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+#endif
 
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
 #define ASID_INC       0x40
 #define ASID_MASK      0xfc0
 
+#elif defined(CONFIG_CPU_R8000)
+
+#define ASID_INC       0x10
+#define ASID_MASK      0xff0
+
 #elif defined(CONFIG_CPU_RM9000)
 
 #define ASID_INC       0x1
 #define ASID_MASK      0xfff
 
-#else /* FIXME: not correct for R6000, R8000 */
+#else /* FIXME: not correct for R6000 */
 
 #define ASID_INC       0x1
 #define ASID_MASK      0xff
@@ -78,9 +87,8 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
        unsigned long asid = asid_cache(cpu);
 
        if (! ((asid += ASID_INC) & ASID_MASK) ) {
-#ifdef CONFIG_VTAG_ICACHE
-               flush_icache_all();
-#endif
+               if (cpu_has_vtag_icache)
+                       flush_icache_all();
                local_flush_tlb_all();  /* start new asid cycle */
                if (!asid)              /* fix version if needed */
                        asid = ASID_FIRST_VERSION;
@@ -122,8 +130,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
         * Mark current->active_mm as not "active" anymore.
         * We don't want to mislead possible IPI tlb flush routines.
         */
-       clear_bit(cpu, &prev->cpu_vm_mask);
-       set_bit(cpu, &next->cpu_vm_mask);
+       cpu_clear(cpu, prev->cpu_vm_mask);
+       cpu_set(cpu, next->cpu_vm_mask);
 
        local_irq_restore(flags);
 }
@@ -146,7 +154,7 @@ static inline void
 activate_mm(struct mm_struct *prev, struct mm_struct *next)
 {
        unsigned long flags;
-       int cpu = smp_processor_id();
+       unsigned int cpu = smp_processor_id();
 
        local_irq_save(flags);
 
@@ -157,8 +165,8 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
        TLBMISS_HANDLER_SETUP_PGD(next->pgd);
 
        /* mark mmu ownership change */
-       clear_bit(cpu, &prev->cpu_vm_mask);
-       set_bit(cpu, &next->cpu_vm_mask);
+       cpu_clear(cpu, prev->cpu_vm_mask);
+       cpu_set(cpu, next->cpu_vm_mask);
 
        local_irq_restore(flags);
 }
@@ -174,7 +182,7 @@ drop_mmu_context(struct mm_struct *mm, unsigned cpu)
 
        local_irq_save(flags);
 
-       if (test_bit(cpu, &mm->cpu_vm_mask))  {
+       if (cpu_isset(cpu, mm->cpu_vm_mask))  {
                get_new_mmu_context(mm, cpu);
                write_c0_entryhi(cpu_asid(cpu, mm));
        } else {