1#ifndef __ASM_SH64_MMU_CONTEXT_H
2#define __ASM_SH64_MMU_CONTEXT_H
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#ifndef __ASSEMBLY__
19
20
21
22
23
24
25
26
27extern unsigned long mmu_context_cache;
28
29#include <linux/config.h>
30#include <asm/page.h>
31
32
33
34extern pgd_t *mmu_pdtp_cache;
35
36#define SR_ASID_MASK 0xffffffffff00ffff
37#define SR_ASID_SHIFT 16
38
39#define MMU_CONTEXT_ASID_MASK 0x000000ff
40#define MMU_CONTEXT_VERSION_MASK 0xffffff00
41#define MMU_CONTEXT_FIRST_VERSION 0x00000100
42#define NO_CONTEXT 0
43
44
45#define MMU_NO_ASID 0x100
46
47
48
49
50
51#define MMU_VPN_MASK 0xfffff000
52
53extern __inline__ void
54get_new_mmu_context(struct mm_struct *mm)
55{
56 extern void flush_tlb_all(void);
57 extern void flush_cache_all(void);
58
59 unsigned long mc = ++mmu_context_cache;
60
61 if (!(mc & MMU_CONTEXT_ASID_MASK)) {
62
63
64 flush_tlb_all();
65
66
67 flush_cache_all();
68
69
70 if (!mc)
71 mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION;
72 }
73 mm->context = mc;
74}
75
76
77
78
79static __inline__ void
80get_mmu_context(struct mm_struct *mm)
81{
82 if (mm) {
83 unsigned long mc = mmu_context_cache;
84
85
86 if ((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK)
87 get_new_mmu_context(mm);
88 }
89}
90
91
92
93
94
95static __inline__ int init_new_context(struct task_struct *tsk,
96 struct mm_struct *mm)
97{
98 mm->context = NO_CONTEXT;
99 return 0;
100}
101
102
103
104
105
106static __inline__ void destroy_context(struct mm_struct *mm)
107{
108 extern void flush_tlb_mm(struct mm_struct *mm);
109
110
111 flush_tlb_mm(mm);
112}
113
114#endif
115
116
117#define TLB_STEP 0x00000010
118#define TLB_PTEH 0x00000000
119#define TLB_PTEL 0x00000008
120
121
122#define PTEH_ASID_SHIFT 2
123#define PTEH_VALID 0x0000000000000001
124#define PTEH_SHARED 0x0000000000000002
125#define PTEH_MATCH_ASID 0x00000000000003ff
126
127#ifndef __ASSEMBLY__
128
129
130extern void __do_tlb_refill(unsigned long address, unsigned long long is_text_not_data, pte_t *pte);
131
132
133#if (CONFIG_SH64_PROC_TLB)
134extern unsigned long long calls_to_do_fast_page_fault;
135#endif
136
137static inline unsigned long get_asid(void)
138{
139 unsigned long long sr;
140
141 asm volatile ("getcon " __c0 ", %0\n\t"
142 : "=r" (sr));
143
144 sr = (sr >> SR_ASID_SHIFT) & MMU_CONTEXT_ASID_MASK;
145 return (unsigned long) sr;
146}
147
148
149static inline void set_asid(unsigned long asid)
150{
151 unsigned long long sr, pc;
152
153 asm volatile ("getcon " __c0 ", %0" : "=r" (sr));
154
155 sr = (sr & SR_ASID_MASK) | (asid << SR_ASID_SHIFT);
156
157
158
159
160
161
162 asm volatile ("movi 1, %1\n\t"
163 "shlli %1, 28, %1\n\t"
164 "or %0, %1, %1\n\t"
165 "putcon %1, " __c0 "\n\t"
166 "putcon %0, " __c1 "\n\t"
167 "_loada 1f, %1\n\t"
168 "ori %1, 1 , %1\n\t"
169 "putcon %1, " __c8 "\n\t"
170 "rte\n"
171 "1:\n\t"
172 : "=r" (sr), "=r" (pc) : "0" (sr));
173}
174
175
176
177
178
179static __inline__ void activate_context(struct mm_struct *mm)
180{
181 get_mmu_context(mm);
182 set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
183}
184
185
186static __inline__ void switch_mm(struct mm_struct *prev,
187 struct mm_struct *next,
188 struct task_struct *tsk, unsigned int cpu)
189{
190 set_bit(cpu, &next->cpu_vm_mask);
191
192 if (prev != next) {
193 mmu_pdtp_cache = next->pgd;
194 activate_context(next);
195 clear_bit(cpu, &prev->cpu_vm_mask);
196 }
197}
198
199#define activate_mm(prev, next) \
200 switch_mm((prev),(next),NULL,smp_processor_id())
201
202static __inline__ void
203enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
204{
205}
206
207#endif
208
209#endif
210