aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/mmu_context.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/include/asm/mmu_context.h')
-rw-r--r--arch/mips/include/asm/mmu_context.h41
1 files changed, 18 insertions, 23 deletions
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index 45914b59824c..fc57e135cb0a 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -65,37 +65,32 @@ extern unsigned long pgd_current[];
65 back_to_back_c0_hazard(); \ 65 back_to_back_c0_hazard(); \
66 TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) 66 TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
67#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ 67#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
68#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
69 68
70#define ASID_INC 0x40 69/*
71#define ASID_MASK 0xfc0 70 * All unused by hardware upper bits will be considered
72 71 * as a software asid extension.
73#elif defined(CONFIG_CPU_R8000) 72 */
74 73static unsigned long asid_version_mask(unsigned int cpu)
75#define ASID_INC 0x10 74{
76#define ASID_MASK 0xff0 75 unsigned long asid_mask = cpu_asid_mask(&cpu_data[cpu]);
77
78#else /* FIXME: not correct for R6000 */
79 76
80#define ASID_INC 0x1 77 return ~(asid_mask | (asid_mask - 1));
81#define ASID_MASK 0xff 78}
82 79
83#endif 80static unsigned long asid_first_version(unsigned int cpu)
81{
82 return ~asid_version_mask(cpu) + 1;
83}
84 84
85#define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) 85#define cpu_context(cpu, mm) ((mm)->context.asid[cpu])
86#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
87#define asid_cache(cpu) (cpu_data[cpu].asid_cache) 86#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
87#define cpu_asid(cpu, mm) \
88 (cpu_context((cpu), (mm)) & cpu_asid_mask(&cpu_data[cpu]))
88 89
89static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) 90static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
90{ 91{
91} 92}
92 93
93/*
94 * All unused by hardware upper bits will be considered
95 * as a software asid extension.
96 */
97#define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
98#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
99 94
100/* Normal, classic MIPS get_new_mmu_context */ 95/* Normal, classic MIPS get_new_mmu_context */
101static inline void 96static inline void
@@ -104,7 +99,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
104 extern void kvm_local_flush_tlb_all(void); 99 extern void kvm_local_flush_tlb_all(void);
105 unsigned long asid = asid_cache(cpu); 100 unsigned long asid = asid_cache(cpu);
106 101
107 if (! ((asid += ASID_INC) & ASID_MASK) ) { 102 if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) {
108 if (cpu_has_vtag_icache) 103 if (cpu_has_vtag_icache)
109 flush_icache_all(); 104 flush_icache_all();
110#ifdef CONFIG_KVM 105#ifdef CONFIG_KVM
@@ -113,7 +108,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
113 local_flush_tlb_all(); /* start new asid cycle */ 108 local_flush_tlb_all(); /* start new asid cycle */
114#endif 109#endif
115 if (!asid) /* fix version if needed */ 110 if (!asid) /* fix version if needed */
116 asid = ASID_FIRST_VERSION; 111 asid = asid_first_version(cpu);
117 } 112 }
118 113
119 cpu_context(cpu, mm) = asid_cache(cpu) = asid; 114 cpu_context(cpu, mm) = asid_cache(cpu) = asid;
@@ -145,7 +140,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
145 140
146 htw_stop(); 141 htw_stop();
147 /* Check if our ASID is of an older version and thus invalid */ 142 /* Check if our ASID is of an older version and thus invalid */
148 if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) 143 if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & asid_version_mask(cpu))
149 get_new_mmu_context(next, cpu); 144 get_new_mmu_context(next, cpu);
150 write_c0_entryhi(cpu_asid(cpu, next)); 145 write_c0_entryhi(cpu_asid(cpu, next));
151 TLBMISS_HANDLER_SETUP_PGD(next->pgd); 146 TLBMISS_HANDLER_SETUP_PGD(next->pgd);