diff options
author | Greg Ungerer <gerg@uclinux.org> | 2009-03-11 02:44:39 -0400 |
---|---|---|
committer | Greg Ungerer <gerg@uclinux.org> | 2009-03-24 01:17:45 -0400 |
commit | da4f4a02abebb8b6f49e1585acbb23921a5da410 (patch) | |
tree | d144b3967f2f36d93f49d0d4bf423514e30ad350 /arch/m68k/include/asm/tlbflush.h | |
parent | facdf0ed4f594485fb2a1d2d024a150924c6b01c (diff) |
m68k: merge the mmu and non-mmu versions of tlbflush.h
Simple merge of the mmu and non-mmu versions of tlbflush.h
Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Diffstat (limited to 'arch/m68k/include/asm/tlbflush.h')
-rw-r--r-- | arch/m68k/include/asm/tlbflush.h | 268 |
1 files changed, 265 insertions, 3 deletions
diff --git a/arch/m68k/include/asm/tlbflush.h b/arch/m68k/include/asm/tlbflush.h index b6f93b30951e..a6b4ed4fc90f 100644 --- a/arch/m68k/include/asm/tlbflush.h +++ b/arch/m68k/include/asm/tlbflush.h | |||
@@ -1,5 +1,267 @@ | |||
1 | #ifdef __uClinux__ | 1 | #ifndef _M68K_TLBFLUSH_H |
2 | #include "tlbflush_no.h" | 2 | #define _M68K_TLBFLUSH_H |
3 | |||
4 | #ifdef CONFIG_MMU | ||
5 | #ifndef CONFIG_SUN3 | ||
6 | |||
7 | #include <asm/current.h> | ||
8 | |||
9 | static inline void flush_tlb_kernel_page(void *addr) | ||
10 | { | ||
11 | if (CPU_IS_040_OR_060) { | ||
12 | mm_segment_t old_fs = get_fs(); | ||
13 | set_fs(KERNEL_DS); | ||
14 | __asm__ __volatile__(".chip 68040\n\t" | ||
15 | "pflush (%0)\n\t" | ||
16 | ".chip 68k" | ||
17 | : : "a" (addr)); | ||
18 | set_fs(old_fs); | ||
19 | } else if (CPU_IS_020_OR_030) | ||
20 | __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); | ||
21 | } | ||
22 | |||
23 | /* | ||
24 | * flush all user-space atc entries. | ||
25 | */ | ||
26 | static inline void __flush_tlb(void) | ||
27 | { | ||
28 | if (CPU_IS_040_OR_060) | ||
29 | __asm__ __volatile__(".chip 68040\n\t" | ||
30 | "pflushan\n\t" | ||
31 | ".chip 68k"); | ||
32 | else if (CPU_IS_020_OR_030) | ||
33 | __asm__ __volatile__("pflush #0,#4"); | ||
34 | } | ||
35 | |||
36 | static inline void __flush_tlb040_one(unsigned long addr) | ||
37 | { | ||
38 | __asm__ __volatile__(".chip 68040\n\t" | ||
39 | "pflush (%0)\n\t" | ||
40 | ".chip 68k" | ||
41 | : : "a" (addr)); | ||
42 | } | ||
43 | |||
44 | static inline void __flush_tlb_one(unsigned long addr) | ||
45 | { | ||
46 | if (CPU_IS_040_OR_060) | ||
47 | __flush_tlb040_one(addr); | ||
48 | else if (CPU_IS_020_OR_030) | ||
49 | __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); | ||
50 | } | ||
51 | |||
52 | #define flush_tlb() __flush_tlb() | ||
53 | |||
54 | /* | ||
55 | * flush all atc entries (both kernel and user-space entries). | ||
56 | */ | ||
57 | static inline void flush_tlb_all(void) | ||
58 | { | ||
59 | if (CPU_IS_040_OR_060) | ||
60 | __asm__ __volatile__(".chip 68040\n\t" | ||
61 | "pflusha\n\t" | ||
62 | ".chip 68k"); | ||
63 | else if (CPU_IS_020_OR_030) | ||
64 | __asm__ __volatile__("pflusha"); | ||
65 | } | ||
66 | |||
67 | static inline void flush_tlb_mm(struct mm_struct *mm) | ||
68 | { | ||
69 | if (mm == current->active_mm) | ||
70 | __flush_tlb(); | ||
71 | } | ||
72 | |||
73 | static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) | ||
74 | { | ||
75 | if (vma->vm_mm == current->active_mm) { | ||
76 | mm_segment_t old_fs = get_fs(); | ||
77 | set_fs(USER_DS); | ||
78 | __flush_tlb_one(addr); | ||
79 | set_fs(old_fs); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
84 | unsigned long start, unsigned long end) | ||
85 | { | ||
86 | if (vma->vm_mm == current->active_mm) | ||
87 | __flush_tlb(); | ||
88 | } | ||
89 | |||
90 | static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
91 | { | ||
92 | flush_tlb_all(); | ||
93 | } | ||
94 | |||
3 | #else | 95 | #else |
4 | #include "tlbflush_mm.h" | 96 | |
97 | |||
98 | /* Reserved PMEGs. */ | ||
99 | extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; | ||
100 | extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM]; | ||
101 | extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM]; | ||
102 | extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM]; | ||
103 | |||
104 | /* Flush all userspace mappings one by one... (why no flush command, | ||
105 | sun?) */ | ||
106 | static inline void flush_tlb_all(void) | ||
107 | { | ||
108 | unsigned long addr; | ||
109 | unsigned char ctx, oldctx; | ||
110 | |||
111 | oldctx = sun3_get_context(); | ||
112 | for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) { | ||
113 | for(ctx = 0; ctx < 8; ctx++) { | ||
114 | sun3_put_context(ctx); | ||
115 | sun3_put_segmap(addr, SUN3_INVALID_PMEG); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | sun3_put_context(oldctx); | ||
120 | /* erase all of the userspace pmeg maps, we've clobbered them | ||
121 | all anyway */ | ||
122 | for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) { | ||
123 | if(pmeg_alloc[addr] == 1) { | ||
124 | pmeg_alloc[addr] = 0; | ||
125 | pmeg_ctx[addr] = 0; | ||
126 | pmeg_vaddr[addr] = 0; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | } | ||
131 | |||
132 | /* Clear user TLB entries within the context named in mm */ | ||
133 | static inline void flush_tlb_mm (struct mm_struct *mm) | ||
134 | { | ||
135 | unsigned char oldctx; | ||
136 | unsigned char seg; | ||
137 | unsigned long i; | ||
138 | |||
139 | oldctx = sun3_get_context(); | ||
140 | sun3_put_context(mm->context); | ||
141 | |||
142 | for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) { | ||
143 | seg = sun3_get_segmap(i); | ||
144 | if(seg == SUN3_INVALID_PMEG) | ||
145 | continue; | ||
146 | |||
147 | sun3_put_segmap(i, SUN3_INVALID_PMEG); | ||
148 | pmeg_alloc[seg] = 0; | ||
149 | pmeg_ctx[seg] = 0; | ||
150 | pmeg_vaddr[seg] = 0; | ||
151 | } | ||
152 | |||
153 | sun3_put_context(oldctx); | ||
154 | |||
155 | } | ||
156 | |||
157 | /* Flush a single TLB page. In this case, we're limited to flushing a | ||
158 | single PMEG */ | ||
159 | static inline void flush_tlb_page (struct vm_area_struct *vma, | ||
160 | unsigned long addr) | ||
161 | { | ||
162 | unsigned char oldctx; | ||
163 | unsigned char i; | ||
164 | |||
165 | oldctx = sun3_get_context(); | ||
166 | sun3_put_context(vma->vm_mm->context); | ||
167 | addr &= ~SUN3_PMEG_MASK; | ||
168 | if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG) | ||
169 | { | ||
170 | pmeg_alloc[i] = 0; | ||
171 | pmeg_ctx[i] = 0; | ||
172 | pmeg_vaddr[i] = 0; | ||
173 | sun3_put_segmap (addr, SUN3_INVALID_PMEG); | ||
174 | } | ||
175 | sun3_put_context(oldctx); | ||
176 | |||
177 | } | ||
178 | /* Flush a range of pages from TLB. */ | ||
179 | |||
180 | static inline void flush_tlb_range (struct vm_area_struct *vma, | ||
181 | unsigned long start, unsigned long end) | ||
182 | { | ||
183 | struct mm_struct *mm = vma->vm_mm; | ||
184 | unsigned char seg, oldctx; | ||
185 | |||
186 | start &= ~SUN3_PMEG_MASK; | ||
187 | |||
188 | oldctx = sun3_get_context(); | ||
189 | sun3_put_context(mm->context); | ||
190 | |||
191 | while(start < end) | ||
192 | { | ||
193 | if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) | ||
194 | goto next; | ||
195 | if(pmeg_ctx[seg] == mm->context) { | ||
196 | pmeg_alloc[seg] = 0; | ||
197 | pmeg_ctx[seg] = 0; | ||
198 | pmeg_vaddr[seg] = 0; | ||
199 | } | ||
200 | sun3_put_segmap(start, SUN3_INVALID_PMEG); | ||
201 | next: | ||
202 | start += SUN3_PMEG_SIZE; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
207 | { | ||
208 | flush_tlb_all(); | ||
209 | } | ||
210 | |||
211 | /* Flush kernel page from TLB. */ | ||
212 | static inline void flush_tlb_kernel_page (unsigned long addr) | ||
213 | { | ||
214 | sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG); | ||
215 | } | ||
216 | |||
5 | #endif | 217 | #endif |
218 | |||
219 | #else /* !CONFIG_MMU */ | ||
220 | |||
221 | /* | ||
222 | * flush all user-space atc entries. | ||
223 | */ | ||
224 | static inline void __flush_tlb(void) | ||
225 | { | ||
226 | BUG(); | ||
227 | } | ||
228 | |||
229 | static inline void __flush_tlb_one(unsigned long addr) | ||
230 | { | ||
231 | BUG(); | ||
232 | } | ||
233 | |||
234 | #define flush_tlb() __flush_tlb() | ||
235 | |||
236 | /* | ||
237 | * flush all atc entries (both kernel and user-space entries). | ||
238 | */ | ||
239 | static inline void flush_tlb_all(void) | ||
240 | { | ||
241 | BUG(); | ||
242 | } | ||
243 | |||
244 | static inline void flush_tlb_mm(struct mm_struct *mm) | ||
245 | { | ||
246 | BUG(); | ||
247 | } | ||
248 | |||
249 | static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) | ||
250 | { | ||
251 | BUG(); | ||
252 | } | ||
253 | |||
254 | static inline void flush_tlb_range(struct mm_struct *mm, | ||
255 | unsigned long start, unsigned long end) | ||
256 | { | ||
257 | BUG(); | ||
258 | } | ||
259 | |||
260 | static inline void flush_tlb_kernel_page(unsigned long addr) | ||
261 | { | ||
262 | BUG(); | ||
263 | } | ||
264 | |||
265 | #endif /* CONFIG_MMU */ | ||
266 | |||
267 | #endif /* _M68K_TLBFLUSH_H */ | ||