This source file includes following definitions.
- __put_user
- __get_user
- get_user_byte
- get_user_word
- get_user_long
- put_user_byte
- put_user_word
- put_user_long
- __generic_memcpy_tofs
- __constant_memcpy_tofs
- __generic_memcpy_fromfs
- __constant_memcpy_fromfs
- get_fs
- get_ds
- set_fs
1 #ifndef _M68K_SEGMENT_H
2 #define _M68K_SEGMENT_H
3
4
5
6 #define USER_DATA (1)
7 #ifndef USER_DS
8 #define USER_DS (USER_DATA)
9 #endif
10 #define USER_PROGRAM (2)
11 #define SUPER_DATA (5)
12 #ifndef KERNEL_DS
13 #define KERNEL_DS (SUPER_DATA)
14 #endif
15 #define SUPER_PROGRAM (6)
16 #define CPU_SPACE (7)
17
18 #ifndef __ASSEMBLY__
19
20
21
22
23
24
25 #define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
26 #define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
27
28
29
30
31
32
33 extern int bad_user_access_length(void);
34
35 #define __ptr(x) ((unsigned long *)(x))
36
37 static inline void __put_user(unsigned long x, void * y, int size)
38 {
39 switch (size) {
40 case 1:
41 __asm__ ("movesb %0,%1"
42 :
43 :"r" (x),"m" (*__ptr(y)) : "memory");
44 break;
45 case 2:
46 __asm__ ("movesw %0,%1"
47 :
48 :"r" (x),"m" (*__ptr(y)) : "memory");
49 break;
50 case 4:
51 __asm__ ("movesl %0,%1"
52 :
53 :"r" (x),"m" (*__ptr(y)) : "memory");
54 break;
55 default:
56 bad_user_access_length();
57 }
58 }
59
60 static inline unsigned long __get_user(const void * y, int size)
61 {
62 unsigned long result;
63
64 switch (size) {
65 case 1:
66 __asm__ ("movesb %1,%0"
67 :"=r" (result)
68 :"m" (*__ptr(y)));
69 return (unsigned char) result;
70 case 2:
71 __asm__ ("movesw %1,%0"
72 :"=r" (result)
73 :"m" (*__ptr(y)));
74 return (unsigned short) result;
75 case 4:
76 __asm__ ("movesl %1,%0"
77 :"=r" (result)
78 :"m" (*__ptr(y)));
79 return result;
80 default:
81 return bad_user_access_length();
82 }
83 }
84 #undef __ptr
85
86
87
88
89
90
91
92 #define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
93 #define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
94 #define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
95
96 #define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
97 #define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
98 #define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
99
100 #ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
101
102 static inline unsigned char get_user_byte(const char * addr)
103 {
104 return __get_user(addr,1);
105 }
106
107 static inline unsigned short get_user_word(const short *addr)
108 {
109 return __get_user(addr,2);
110 }
111
112 static inline unsigned long get_user_long(const int *addr)
113 {
114 return __get_user(addr,4);
115 }
116
117 static inline void put_user_byte(char val,char *addr)
118 {
119 __put_user(val, addr, 1);
120 }
121
122 static inline void put_user_word(short val,short * addr)
123 {
124 __put_user(val, addr, 2);
125 }
126
127 static inline void put_user_long(unsigned long val,int * addr)
128 {
129 __put_user(val, addr, 4);
130 }
131
132 #endif
133
134 static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
135 {
136 unsigned long tmp;
137 if (n == 0) return;
138 tmp = n;
139 n >>= 2;
140 if (n != 0)
141 __asm__ ("1:\t"
142 "movel %1@+,%/d0\n\t"
143 "movesl %/d0,%2@+\n\t"
144 "dbra %0,1b\n\t"
145 "clrw %0\n\t"
146 "subql #1,%0\n\t"
147 "bccs 1b\n\t"
148 : "=d" (n), "=a" (from), "=a" (to)
149 : "0" (n-1), "1" (from), "2" (to)
150 : "d0", "memory");
151 if (tmp & 2)
152 __asm__ ("movew %0@+,%/d0\n\t"
153 "movesw %/d0,%1@+\n\t"
154 : "=a" (from), "=a" (to)
155 : "0" (from), "1" (to)
156 : "d0", "memory");
157 if (tmp & 1)
158 __asm__ ("moveb %0@,%/d0\n\t"
159 "movesb %/d0,%1@\n\t"
160 :
161 : "a" (from), "a" (to)
162 : "d0", "memory");
163 }
164
165 static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
166 {
167 switch (n) {
168 case 0:
169 return;
170 case 1:
171 __put_user(*(const char *) from, (char *) to, 1);
172 return;
173 case 2:
174 __put_user(*(const short *) from, (short *) to, 2);
175 return;
176 case 3:
177 __put_user(*(const short *) from, (short *) to, 2);
178 __put_user(*(2+(const char *) from), 2+(char *) to, 1);
179 return;
180 case 4:
181 __put_user(*(const int *) from, (int *) to, 4);
182 return;
183 case 8:
184 __put_user(*(const int *) from, (int *) to, 4);
185 __put_user(*(1+(const int *) from), 1+(int *) to, 4);
186 return;
187 case 12:
188 __put_user(*(const int *) from, (int *) to, 4);
189 __put_user(*(1+(const int *) from), 1+(int *) to, 4);
190 __put_user(*(2+(const int *) from), 2+(int *) to, 4);
191 return;
192 case 16:
193 __put_user(*(const int *) from, (int *) to, 4);
194 __put_user(*(1+(const int *) from), 1+(int *) to, 4);
195 __put_user(*(2+(const int *) from), 2+(int *) to, 4);
196 __put_user(*(3+(const int *) from), 3+(int *) to, 4);
197 return;
198 }
199 #define COMMON(x) \
200 __asm__ __volatile__ ("1:\n\t" \
201 "movel %1@+,%/d0\n\t" \
202 "movesl %/d0,%2@+\n\t" \
203 "dbra %0,1b\n\t" \
204 "clrw %0\n\t" \
205 "subql #1,%0\n\t" \
206 "bccs 1b\n\t" \
207 x \
208 : "=d" (n), "=a" (from), "=a" (to) \
209 : "1" (from), "2" (to), "0" (n/4-1) \
210 : "d0", "memory");
211
212 switch (n % 4) {
213 case 0:
214 COMMON("");
215 return;
216 case 1:
217 COMMON("moveb %1@+,%/d0; movesb %/d0,%2@+");
218 return;
219 case 2:
220 COMMON("movew %1@+,%/d0; movesw %/d0,%2@+");
221 return;
222 case 3:
223 COMMON("movew %1@+,%/d0; movesw %/d0,%2@+\n\t"
224 "moveb %1@+,%/d0; movesb %/d0,%2@+");
225 return;
226 }
227 #undef COMMON
228 }
229
230 static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
231 {
232 unsigned long tmp;
233 if (n == 0) return;
234 tmp = n;
235 n >>= 2;
236 if (n != 0)
237 __asm__ ("1:\t"
238 "movesl %1@+,%/d0\n\t"
239 "movel %/d0,%2@+\n\t"
240 "dbra %0,1b\n\t"
241 "clrw %0\n\t"
242 "subql #1,%0\n\t"
243 "bccs 1b\n\t"
244 : "=d" (n), "=a" (from), "=a" (to)
245 : "0" (n-1), "1" (from), "2" (to)
246 : "d0", "memory");
247 if (tmp & 2)
248 __asm__ ("movesw %0@+,%/d0\n\t"
249 "movew %/d0,%1@+\n\t"
250 : "=a" (from), "=a" (to)
251 : "0" (from), "1" (to)
252 : "d0", "memory");
253 if (tmp & 1)
254 __asm__ ("movesb %0@,%/d0\n\t"
255 "moveb %/d0,%1@\n\t"
256 :
257 : "a" (from), "a" (to)
258 : "d0", "memory");
259 }
260
261 static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
262 {
263 switch (n) {
264 case 0:
265 return;
266 case 1:
267 *(char *)to = __get_user((const char *) from, 1);
268 return;
269 case 2:
270 *(short *)to = __get_user((const short *) from, 2);
271 return;
272 case 3:
273 *(short *) to = __get_user((const short *) from, 2);
274 *((char *) to + 2) = __get_user(2+(const char *) from, 1);
275 return;
276 case 4:
277 *(int *) to = __get_user((const int *) from, 4);
278 return;
279 case 8:
280 *(int *) to = __get_user((const int *) from, 4);
281 *(1+(int *) to) = __get_user(1+(const int *) from, 4);
282 return;
283 case 12:
284 *(int *) to = __get_user((const int *) from, 4);
285 *(1+(int *) to) = __get_user(1+(const int *) from, 4);
286 *(2+(int *) to) = __get_user(2+(const int *) from, 4);
287 return;
288 case 16:
289 *(int *) to = __get_user((const int *) from, 4);
290 *(1+(int *) to) = __get_user(1+(const int *) from, 4);
291 *(2+(int *) to) = __get_user(2+(const int *) from, 4);
292 *(3+(int *) to) = __get_user(3+(const int *) from, 4);
293 return;
294 }
295 #define COMMON(x) \
296 __asm__ __volatile__ ("1:\n\t" \
297 "movesl %1@+,%/d0\n\t" \
298 "movel %/d0,%2@+\n\t" \
299 "dbra %0,1b\n\t" \
300 "clrw %0\n\t" \
301 "subql #1,%0\n\t" \
302 "bccs 1b\n\t" \
303 x \
304 : "=d" (n), "=a" (from), "=a" (to) \
305 : "1" (from), "2" (to), "0" (n/4-1) \
306 : "d0", "memory");
307
308 switch (n % 4) {
309 case 0:
310 COMMON("");
311 return;
312 case 1:
313 COMMON("movesb %1@+,%/d0; moveb %/d0,%2@+");
314 return;
315 case 2:
316 COMMON("movesw %1@+,%/d0; movew %/d0,%2@+");
317 return;
318 case 3:
319 COMMON("movesw %1@+,%/d0; movew %/d0,%2@+\n\t"
320 "movesb %1@+,%/d0; moveb %/d0,%2@+");
321 return;
322 }
323 #undef COMMON
324 }
325
326 #define memcpy_fromfs(to, from, n) \
327 (__builtin_constant_p(n) ? \
328 __constant_memcpy_fromfs((to),(from),(n)) : \
329 __generic_memcpy_fromfs((to),(from),(n)))
330
331 #define memcpy_tofs(to, from, n) \
332 (__builtin_constant_p(n) ? \
333 __constant_memcpy_tofs((to),(from),(n)) : \
334 __generic_memcpy_tofs((to),(from),(n)))
335
336
337
338
339
340 static inline unsigned long get_fs(void)
341 {
342 unsigned long _v;
343 __asm__ ("movec %/dfc,%0":"=r" (_v):);
344
345 return _v;
346 }
347
348 static inline unsigned long get_ds(void)
349 {
350
351 return KERNEL_DS;
352 }
353
354 static inline void set_fs(unsigned long val)
355 {
356 __asm__ __volatile__ ("movec %0,%/sfc\n\t"
357 "movec %0,%/dfc\n\t"
358 : : "r" (val) : "memory");
359 }
360
361 #endif
362
363 #endif