Import 2.1.116pre2
[davej-history.git] / include / asm-m68k / uaccess.h
blob64b8be7bdc136e84dae60ef5b0faf1b73040a73d
1 #ifndef __M68K_UACCESS_H
2 #define __M68K_UACCESS_H
4 /*
5 * User space memory access functions
6 */
7 #include <linux/sched.h>
8 #include <asm/segment.h>
10 #define VERIFY_READ 0
11 #define VERIFY_WRITE 1
13 /* We let the MMU do all checking */
14 #define access_ok(type,addr,size) 1
16 extern inline int verify_area(int type, const void * addr, unsigned long size)
18 return access_ok(type,addr,size)?0:-EFAULT;
22 * The exception table consists of pairs of addresses: the first is the
23 * address of an instruction that is allowed to fault, and the second is
24 * the address at which the program should continue. No registers are
25 * modified, so it is entirely up to the continuation code to figure out
26 * what to do.
28 * All the routines below use bits of fixup code that are out of line
29 * with the main instruction path. This means when everything is well,
30 * we don't even have to jump over them. Further, they do not intrude
31 * on our cache or tlb entries.
34 struct exception_table_entry
36 unsigned long insn, fixup;
39 /* Returns 0 if exception not found and fixup otherwise. */
40 extern unsigned long search_exception_table(unsigned long);
44 * These are the main single-value transfer routines. They automatically
45 * use the right size if we just have the right pointer type.
48 #define put_user(x, ptr) \
49 ({ \
50 int __pu_err; \
51 typeof(*(ptr)) __pu_val = (x); \
52 switch (sizeof (*(ptr))) { \
53 case 1: \
54 __put_user_asm(__pu_err, __pu_val, ptr, b); \
55 break; \
56 case 2: \
57 __put_user_asm(__pu_err, __pu_val, ptr, w); \
58 break; \
59 case 4: \
60 __put_user_asm(__pu_err, __pu_val, ptr, l); \
61 break; \
62 default: \
63 __pu_err = __put_user_bad(); \
64 break; \
65 } \
66 __pu_err; \
68 #define __put_user(x, ptr) put_user(x, ptr)
70 extern int __put_user_bad(void);
73 * Tell gcc we read from memory instead of writing: this is because
74 * we do not write to any memory gcc knows about, so there are no
75 * aliasing issues.
77 #define __put_user_asm(err,x,ptr,bwl) \
78 __asm__ __volatile__ \
79 ("21:moves" #bwl " %2,%1\n" \
80 "1:\n" \
81 ".section .fixup,\"ax\"\n" \
82 " .even\n" \
83 "2: movel %3,%0\n" \
84 " jra 1b\n" \
85 ".previous\n" \
86 ".section __ex_table,\"a\"\n" \
87 " .align 4\n" \
88 " .long 21b,2b\n" \
89 " .long 1b,2b\n" \
90 ".previous" \
91 : "=d"(err) \
92 : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
94 #define get_user(x, ptr) \
95 ({ \
96 int __gu_err; \
97 typeof(*(ptr)) __gu_val; \
98 switch (sizeof(*(ptr))) { \
99 case 1: \
100 __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \
101 break; \
102 case 2: \
103 __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \
104 break; \
105 case 4: \
106 __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \
107 break; \
108 default: \
109 __gu_val = 0; \
110 __gu_err = __get_user_bad(); \
111 break; \
113 (x) = __gu_val; \
114 __gu_err; \
116 #define __get_user(x, ptr) get_user(x, ptr)
118 extern int __get_user_bad(void);
120 #define __get_user_asm(err,x,ptr,bwl,reg) \
121 __asm__ __volatile__ \
122 ("1: moves" #bwl " %2,%1\n" \
123 "2:\n" \
124 ".section .fixup,\"ax\"\n" \
125 " .even\n" \
126 "3: movel %3,%0\n" \
127 " sub" #bwl " %1,%1\n" \
128 " jra 2b\n" \
129 ".previous\n" \
130 ".section __ex_table,\"a\"\n" \
131 " .align 4\n" \
132 " .long 1b,3b\n" \
133 ".previous" \
134 : "=d"(err), reg(x) \
135 : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
137 static inline unsigned long
138 __generic_copy_from_user(void *to, const void *from, unsigned long n)
140 unsigned long tmp;
141 __asm__ __volatile__
142 (" tstl %2\n"
143 " jeq 2f\n"
144 "1: movesl (%1)+,%3\n"
145 " movel %3,(%0)+\n"
146 " subql #1,%2\n"
147 " jne 1b\n"
148 "2: movel %4,%2\n"
149 " bclr #1,%2\n"
150 " jeq 4f\n"
151 "3: movesw (%1)+,%3\n"
152 " movew %3,(%0)+\n"
153 "4: bclr #0,%2\n"
154 " jeq 6f\n"
155 "5: movesb (%1)+,%3\n"
156 " moveb %3,(%0)+\n"
157 "6:\n"
158 ".section .fixup,\"ax\"\n"
159 " .even\n"
160 "7: lsll #2,%2\n"
161 " addl %4,%2\n"
162 " jra 6b\n"
163 "8: addql #2,%2\n"
164 " jra 6b\n"
165 "9: addql #1,%2\n"
166 " jra 6b\n"
167 ".previous\n"
168 ".section __ex_table,\"a\"\n"
169 " .align 4\n"
170 " .long 1b,7b\n"
171 " .long 3b,8b\n"
172 " .long 5b,9b\n"
173 ".previous"
174 : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
175 : "r"(n & 3), "0"(to), "1"(from), "2"(n/4)
176 : "d0", "memory");
177 return n;
180 static inline unsigned long
181 __generic_copy_to_user(void *to, const void *from, unsigned long n)
183 unsigned long tmp;
184 __asm__ __volatile__
185 (" tstl %2\n"
186 " jeq 3f\n"
187 "1: movel (%1)+,%3\n"
188 "22:movesl %3,(%0)+\n"
189 "2: subql #1,%2\n"
190 " jne 1b\n"
191 "3: movel %4,%2\n"
192 " bclr #1,%2\n"
193 " jeq 4f\n"
194 " movew (%1)+,%3\n"
195 "24:movesw %3,(%0)+\n"
196 "4: bclr #0,%2\n"
197 " jeq 5f\n"
198 " moveb (%1)+,%3\n"
199 "25:movesb %3,(%0)+\n"
200 "5:\n"
201 ".section .fixup,\"ax\"\n"
202 " .even\n"
203 "60:addql #1,%2\n"
204 "6: lsll #2,%2\n"
205 " addl %4,%2\n"
206 " jra 5b\n"
207 "7: addql #2,%2\n"
208 " jra 5b\n"
209 "8: addql #1,%2\n"
210 " jra 5b\n"
211 ".previous\n"
212 ".section __ex_table,\"a\"\n"
213 " .align 4\n"
214 " .long 1b,60b\n"
215 " .long 22b,6b\n"
216 " .long 2b,6b\n"
217 " .long 24b,7b\n"
218 " .long 3b,60b\n"
219 " .long 4b,7b\n"
220 " .long 25b,8b\n"
221 " .long 5b,8b\n"
222 ".previous"
223 : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
224 : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4));
225 return n;
228 #define __copy_from_user_big(to, from, n, fixup, copy) \
229 __asm__ __volatile__ \
230 ("10: movesl (%1)+,%%d0\n" \
231 " movel %%d0,(%0)+\n" \
232 " subql #1,%2\n" \
233 " jne 10b\n" \
234 ".section .fixup,\"ax\"\n" \
235 " .even\n" \
236 "11: lsll #2,%2\n" \
237 fixup "\n" \
238 " jra 12f\n" \
239 ".previous\n" \
240 ".section __ex_table,\"a\"\n" \
241 " .align 4\n" \
242 " .long 10b,11b\n" \
243 ".previous\n" \
244 copy "\n" \
245 "12:" \
246 : "=a"(to), "=a"(from), "=d"(n) \
247 : "0"(to), "1"(from), "2"(n/4) \
248 : "d0", "memory")
250 static inline unsigned long
251 __constant_copy_from_user(void *to, const void *from, unsigned long n)
253 switch (n) {
254 case 0:
255 break;
256 case 1:
257 __asm__ __volatile__
258 ("1: movesb (%1)+,%%d0\n"
259 " moveb %%d0,(%0)+\n"
260 "2:\n"
261 ".section .fixup,\"ax\"\n"
262 " .even\n"
263 "3: addql #1,%2\n"
264 " jra 2b\n"
265 ".previous\n"
266 ".section __ex_table,\"a\"\n"
267 " .align 4\n"
268 " .long 1b,3b\n"
269 ".previous"
270 : "=a"(to), "=a"(from), "=d"(n)
271 : "0"(to), "1"(from), "2"(0)
272 : "d0", "memory");
273 break;
274 case 2:
275 __asm__ __volatile__
276 ("1: movesw (%1)+,%%d0\n"
277 " movew %%d0,(%0)+\n"
278 "2:\n"
279 ".section .fixup,\"ax\"\n"
280 " .even\n"
281 "3: addql #2,%2\n"
282 " jra 2b\n"
283 ".previous\n"
284 ".section __ex_table,\"a\"\n"
285 " .align 4\n"
286 " .long 1b,3b\n"
287 ".previous"
288 : "=a"(to), "=a"(from), "=d"(n)
289 : "0"(to), "1"(from), "2"(0)
290 : "d0", "memory");
291 break;
292 case 3:
293 __asm__ __volatile__
294 ("1: movesw (%1)+,%%d0\n"
295 " movew %%d0,(%0)+\n"
296 "2: movesb (%1)+,%%d0\n"
297 " moveb %%d0,(%0)+\n"
298 "3:"
299 ".section .fixup,\"ax\"\n"
300 " .even\n"
301 "4: addql #2,%2\n"
302 "5: addql #1,%2\n"
303 " jra 3b\n"
304 ".previous\n"
305 ".section __ex_table,\"a\"\n"
306 " .align 4\n"
307 " .long 1b,4b\n"
308 " .long 2b,5b\n"
309 ".previous"
310 : "=a"(to), "=a"(from), "=d"(n)
311 : "0"(to), "1"(from), "2"(0)
312 : "d0", "memory");
313 break;
314 case 4:
315 __asm__ __volatile__
316 ("1: movesl (%1)+,%%d0\n"
317 " movel %%d0,(%0)+\n"
318 "2:"
319 ".section .fixup,\"ax\"\n"
320 " .even\n"
321 "3: addql #4,%2\n"
322 " jra 2b\n"
323 ".previous\n"
324 ".section __ex_table,\"a\"\n"
325 " .align 4\n"
326 " .long 1b,3b\n"
327 ".previous"
328 : "=a"(to), "=a"(from), "=d"(n)
329 : "0"(to), "1"(from), "2"(0)
330 : "d0", "memory");
331 break;
332 case 8:
333 __asm__ __volatile__
334 ("1: movesl (%1)+,%%d0\n"
335 " movel %%d0,(%0)+\n"
336 "2: movesl (%1)+,%%d0\n"
337 " movel %%d0,(%0)+\n"
338 "3:"
339 ".section .fixup,\"ax\"\n"
340 " .even\n"
341 "4: addql #4,%2\n"
342 "5: addql #4,%2\n"
343 " jra 3b\n"
344 ".previous\n"
345 ".section __ex_table,\"a\"\n"
346 " .align 4\n"
347 " .long 1b,4b\n"
348 " .long 2b,5b\n"
349 ".previous"
350 : "=a"(to), "=a"(from), "=d"(n)
351 : "0"(to), "1"(from), "2"(0)
352 : "d0", "memory");
353 break;
354 case 12:
355 __asm__ __volatile__
356 ("1: movesl (%1)+,%%d0\n"
357 " movel %%d0,(%0)+\n"
358 "2: movesl (%1)+,%%d0\n"
359 " movel %%d0,(%0)+\n"
360 "3: movesl (%1)+,%%d0\n"
361 " movel %%d0,(%0)+\n"
362 "4:"
363 ".section .fixup,\"ax\"\n"
364 " .even\n"
365 "5: addql #4,%2\n"
366 "6: addql #4,%2\n"
367 "7: addql #4,%2\n"
368 " jra 4b\n"
369 ".previous\n"
370 ".section __ex_table,\"a\"\n"
371 " .align 4\n"
372 " .long 1b,5b\n"
373 " .long 2b,6b\n"
374 " .long 3b,7b\n"
375 ".previous"
376 : "=a"(to), "=a"(from), "=d"(n)
377 : "0"(to), "1"(from), "2"(0)
378 : "d0", "memory");
379 break;
380 case 16:
381 __asm__ __volatile__
382 ("1: movesl (%1)+,%%d0\n"
383 " movel %%d0,(%0)+\n"
384 "2: movesl (%1)+,%%d0\n"
385 " movel %%d0,(%0)+\n"
386 "3: movesl (%1)+,%%d0\n"
387 " movel %%d0,(%0)+\n"
388 "4: movesl (%1)+,%%d0\n"
389 " movel %%d0,(%0)+\n"
390 "5:"
391 ".section .fixup,\"ax\"\n"
392 " .even\n"
393 "6: addql #4,%2\n"
394 "7: addql #4,%2\n"
395 "8: addql #4,%2\n"
396 "9: addql #4,%2\n"
397 " jra 5b\n"
398 ".previous\n"
399 ".section __ex_table,\"a\"\n"
400 " .align 4\n"
401 " .long 1b,6b\n"
402 " .long 2b,7b\n"
403 " .long 3b,8b\n"
404 " .long 4b,9b\n"
405 ".previous"
406 : "=a"(to), "=a"(from), "=d"(n)
407 : "0"(to), "1"(from), "2"(0)
408 : "d0", "memory");
409 break;
410 default:
411 switch (n & 3) {
412 case 0:
413 __copy_from_user_big(to, from, n, "", "");
414 break;
415 case 1:
416 __copy_from_user_big(to, from, n,
417 /* fixup */
418 "1: addql #1,%2",
419 /* copy */
420 "2: movesb (%1)+,%%d0\n"
421 " moveb %%d0,(%0)+\n"
422 ".section __ex_table,\"a\"\n"
423 " .long 2b,1b\n"
424 ".previous");
425 break;
426 case 2:
427 __copy_from_user_big(to, from, n,
428 /* fixup */
429 "1: addql #2,%2",
430 /* copy */
431 "2: movesw (%1)+,%%d0\n"
432 " movew %%d0,(%0)+\n"
433 ".section __ex_table,\"a\"\n"
434 " .long 2b,1b\n"
435 ".previous");
436 break;
437 case 3:
438 __copy_from_user_big(to, from, n,
439 /* fixup */
440 "1: addql #2,%2\n"
441 "2: addql #1,%2",
442 /* copy */
443 "3: movesw (%1)+,%%d0\n"
444 " movew %%d0,(%0)+\n"
445 "4: movesb (%1)+,%%d0\n"
446 " moveb %%d0,(%0)+\n"
447 ".section __ex_table,\"a\"\n"
448 " .long 3b,1b\n"
449 " .long 4b,2b\n"
450 ".previous");
451 break;
453 break;
455 return n;
458 #define __copy_to_user_big(to, from, n, fixup, copy) \
459 __asm__ __volatile__ \
460 ("10: movel (%1)+,%%d0\n" \
461 "31: movesl %%d0,(%0)+\n" \
462 "11: subql #1,%2\n" \
463 " jne 10b\n" \
464 "41:\n" \
465 ".section .fixup,\"ax\"\n" \
466 " .even\n" \
467 "22: addql #1,%2\n" \
468 "12: lsll #2,%2\n" \
469 fixup "\n" \
470 " jra 13f\n" \
471 ".previous\n" \
472 ".section __ex_table,\"a\"\n" \
473 " .align 4\n" \
474 " .long 10b,22b\n" \
475 " .long 31b,12b\n" \
476 " .long 11b,12b\n" \
477 " .long 41b,22b\n" \
478 ".previous\n" \
479 copy "\n" \
480 "13:" \
481 : "=a"(to), "=a"(from), "=d"(n) \
482 : "0"(to), "1"(from), "2"(n/4) \
483 : "d0")
485 static inline unsigned long
486 __constant_copy_to_user(void *to, const void *from, unsigned long n)
488 switch (n) {
489 case 0:
490 break;
491 case 1:
492 __asm__ __volatile__
493 (" moveb (%1)+,%%d0\n"
494 "21:movesb %%d0,(%0)+\n"
495 "1:\n"
496 ".section .fixup,\"ax\"\n"
497 " .even\n"
498 "2: addql #1,%2\n"
499 " jra 1b\n"
500 ".previous\n"
501 ".section __ex_table,\"a\"\n"
502 " .align 4\n "
503 " .long 21b,2b\n"
504 " .long 1b,2b\n"
505 ".previous"
506 : "=a"(to), "=a"(from), "=d"(n)
507 : "0"(to), "1"(from), "2"(0)
508 : "d0", "memory");
509 break;
510 case 2:
511 __asm__ __volatile__
512 (" movew (%1)+,%%d0\n"
513 "21:movesw %%d0,(%0)+\n"
514 "1:\n"
515 ".section .fixup,\"ax\"\n"
516 " .even\n"
517 "2: addql #2,%2\n"
518 " jra 1b\n"
519 ".previous\n"
520 ".section __ex_table,\"a\"\n"
521 " .align 4\n"
522 " .long 21b,2b\n"
523 " .long 1b,2b\n"
524 ".previous"
525 : "=a"(to), "=a"(from), "=d"(n)
526 : "0"(to), "1"(from), "2"(0)
527 : "d0", "memory");
528 break;
529 case 3:
530 __asm__ __volatile__
531 (" movew (%1)+,%%d0\n"
532 "21:movesw %%d0,(%0)+\n"
533 "1: moveb (%1)+,%%d0\n"
534 "22:movesb %%d0,(%0)+\n"
535 "2:\n"
536 ".section .fixup,\"ax\"\n"
537 " .even\n"
538 "3: addql #2,%2\n"
539 "4: addql #1,%2\n"
540 " jra 2b\n"
541 ".previous\n"
542 ".section __ex_table,\"a\"\n"
543 " .align 4\n"
544 " .long 21b,3b\n"
545 " .long 1b,3b\n"
546 " .long 22b,4b\n"
547 " .long 2b,4b\n"
548 ".previous"
549 : "=a"(to), "=a"(from), "=d"(n)
550 : "0"(to), "1"(from), "2"(0)
551 : "d0", "memory");
552 break;
553 case 4:
554 __asm__ __volatile__
555 (" movel (%1)+,%%d0\n"
556 "21:movesl %%d0,(%0)+\n"
557 "1:\n"
558 ".section .fixup,\"ax\"\n"
559 " .even\n"
560 "2: addql #4,%2\n"
561 " jra 1b\n"
562 ".previous\n"
563 ".section __ex_table,\"a\"\n"
564 " .align 4\n"
565 " .long 21b,2b\n"
566 " .long 1b,2b\n"
567 ".previous"
568 : "=a"(to), "=a"(from), "=d"(n)
569 : "0"(to), "1"(from), "2"(0)
570 : "d0", "memory");
571 break;
572 case 8:
573 __asm__ __volatile__
574 (" movel (%1)+,%%d0\n"
575 "21:movesl %%d0,(%0)+\n"
576 "1: movel (%1)+,%%d0\n"
577 "22:movesl %%d0,(%0)+\n"
578 "2:\n"
579 ".section .fixup,\"ax\"\n"
580 " .even\n"
581 "3: addql #4,%2\n"
582 "4: addql #4,%2\n"
583 " jra 2b\n"
584 ".previous\n"
585 ".section __ex_table,\"a\"\n"
586 " .align 4\n"
587 " .long 21b,3b\n"
588 " .long 1b,3b\n"
589 " .long 22b,4b\n"
590 " .long 2b,4b\n"
591 ".previous"
592 : "=a"(to), "=a"(from), "=d"(n)
593 : "0"(to), "1"(from), "2"(0)
594 : "d0", "memory");
595 break;
596 case 12:
597 __asm__ __volatile__
598 (" movel (%1)+,%%d0\n"
599 "21:movesl %%d0,(%0)+\n"
600 "1: movel (%1)+,%%d0\n"
601 "22:movesl %%d0,(%0)+\n"
602 "2: movel (%1)+,%%d0\n"
603 "23:movesl %%d0,(%0)+\n"
604 "3:\n"
605 ".section .fixup,\"ax\"\n"
606 " .even\n"
607 "4: addql #4,%2\n"
608 "5: addql #4,%2\n"
609 "6: addql #4,%2\n"
610 " jra 3b\n"
611 ".previous\n"
612 ".section __ex_table,\"a\"\n"
613 " .align 4\n"
614 " .long 21b,4b\n"
615 " .long 1b,4b\n"
616 " .long 22b,5b\n"
617 " .long 2b,5b\n"
618 " .long 23b,6b\n"
619 " .long 3b,6b\n"
620 ".previous"
621 : "=a"(to), "=a"(from), "=d"(n)
622 : "0"(to), "1"(from), "2"(0)
623 : "d0", "memory");
624 break;
625 case 16:
626 __asm__ __volatile__
627 (" movel (%1)+,%%d0\n"
628 "21:movesl %%d0,(%0)+\n"
629 "1: movel (%1)+,%%d0\n"
630 "22:movesl %%d0,(%0)+\n"
631 "2: movel (%1)+,%%d0\n"
632 "23:movesl %%d0,(%0)+\n"
633 "3: movel (%1)+,%%d0\n"
634 "24:movesl %%d0,(%0)+\n"
635 "4:"
636 ".section .fixup,\"ax\"\n"
637 " .even\n"
638 "5: addql #4,%2\n"
639 "6: addql #4,%2\n"
640 "7: addql #4,%2\n"
641 "8: addql #4,%2\n"
642 " jra 4b\n"
643 ".previous\n"
644 ".section __ex_table,\"a\"\n"
645 " .align 4\n"
646 " .long 21b,5b\n"
647 " .long 1b,5b\n"
648 " .long 22b,6b\n"
649 " .long 2b,6b\n"
650 " .long 23b,7b\n"
651 " .long 3b,7b\n"
652 " .long 24b,8b\n"
653 " .long 4b,8b\n"
654 ".previous"
655 : "=a"(to), "=a"(from), "=d"(n)
656 : "0"(to), "1"(from), "2"(0)
657 : "d0", "memory");
658 break;
659 default:
660 switch (n & 3) {
661 case 0:
662 __copy_to_user_big(to, from, n, "", "");
663 break;
664 case 1:
665 __copy_to_user_big(to, from, n,
666 /* fixup */
667 "1: addql #1,%2",
668 /* copy */
669 " moveb (%1)+,%%d0\n"
670 "22:movesb %%d0,(%0)+\n"
671 "2:"
672 ".section __ex_table,\"a\"\n"
673 " .long 22b,1b\n"
674 " .long 2b,1b\n"
675 ".previous");
676 break;
677 case 2:
678 __copy_to_user_big(to, from, n,
679 /* fixup */
680 "1: addql #2,%2",
681 /* copy */
682 " movew (%1)+,%%d0\n"
683 "22:movesw %%d0,(%0)+\n"
684 "2:"
685 ".section __ex_table,\"a\"\n"
686 " .long 22b,1b\n"
687 " .long 2b,1b\n"
688 ".previous");
689 break;
690 case 3:
691 __copy_to_user_big(to, from, n,
692 /* fixup */
693 "1: addql #2,%2\n"
694 "2: addql #1,%2",
695 /* copy */
696 " movew (%1)+,%%d0\n"
697 "23:movesw %%d0,(%0)+\n"
698 "3: moveb (%1)+,%%d0\n"
699 "24:movesb %%d0,(%0)+\n"
700 "4:"
701 ".section __ex_table,\"a\"\n"
702 " .long 23b,1b\n"
703 " .long 3b,1b\n"
704 " .long 24b,2b\n"
705 " .long 4b,2b\n"
706 ".previous");
707 break;
709 break;
711 return n;
714 #define copy_from_user(to, from, n) \
715 (__builtin_constant_p(n) ? \
716 __constant_copy_from_user(to, from, n) : \
717 __generic_copy_from_user(to, from, n))
719 #define copy_to_user(to, from, n) \
720 (__builtin_constant_p(n) ? \
721 __constant_copy_to_user(to, from, n) : \
722 __generic_copy_to_user(to, from, n))
724 #define __copy_from_user(to, from, n) copy_from_user(to, from, n)
725 #define __copy_to_user(to, from, n) copy_to_user(to, from, n)
728 * Copy a null terminated string from userspace.
731 static inline long
732 strncpy_from_user(char *dst, const char *src, long count)
734 long res;
735 if (count == 0) return count;
736 __asm__ __volatile__
737 ("1: movesb (%2)+,%%d0\n"
738 "12:moveb %%d0,(%1)+\n"
739 " jeq 2f\n"
740 " subql #1,%3\n"
741 " jne 1b\n"
742 "2: subl %3,%0\n"
743 "3:\n"
744 ".section .fixup,\"ax\"\n"
745 " .even\n"
746 "4: movel %4,%0\n"
747 " jra 3b\n"
748 ".previous\n"
749 ".section __ex_table,\"a\"\n"
750 " .align 4\n"
751 " .long 1b,4b\n"
752 " .long 12b,4b\n"
753 ".previous"
754 : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
755 : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
756 : "d0", "memory");
757 return res;
761 * Return the size of a string (including the ending 0)
763 * Return 0 for error
765 static inline long strlen_user(const char * src)
767 long res = -(long) src;
768 __asm__ __volatile__
769 ("1: movesb (%1)+,%%d0\n"
770 "12:tstb %%d0\n"
771 " jne 1b\n"
772 " addl %1,%0\n"
773 "2:\n"
774 ".section .fixup,\"ax\"\n"
775 " .even\n"
776 "3: moveq %2,%0\n"
777 " jra 2b\n"
778 ".previous\n"
779 ".section __ex_table,\"a\"\n"
780 " .align 4\n"
781 " .long 1b,3b\n"
782 " .long 12b,3b\n"
783 ".previous"
784 : "=d"(res), "=a"(src)
785 : "i"(0), "0"(res), "1"(src)
786 : "d0");
787 return res;
791 * Zero Userspace
794 static inline unsigned long
795 clear_user(void *to, unsigned long n)
797 __asm__ __volatile__
798 (" tstl %1\n"
799 " jeq 3f\n"
800 "1: movesl %3,(%0)+\n"
801 "2: subql #1,%1\n"
802 " jne 1b\n"
803 "3: movel %2,%1\n"
804 " bclr #1,%1\n"
805 " jeq 4f\n"
806 "24:movesw %3,(%0)+\n"
807 "4: bclr #0,%1\n"
808 " jeq 5f\n"
809 "25:movesb %3,(%0)+\n"
810 "5:\n"
811 ".section .fixup,\"ax\"\n"
812 " .even\n"
813 "61:addql #1,%1\n"
814 "6: lsll #2,%1\n"
815 " addl %2,%1\n"
816 " jra 5b\n"
817 "7: addql #2,%1\n"
818 " jra 5b\n"
819 "8: addql #1,%1\n"
820 " jra 5b\n"
821 ".previous\n"
822 ".section __ex_table,\"a\"\n"
823 " .align 4\n"
824 " .long 1b,61b\n"
825 " .long 2b,6b\n"
826 " .long 3b,61b\n"
827 " .long 24b,7b\n"
828 " .long 4b,7b\n"
829 " .long 25b,8b\n"
830 " .long 5b,8b\n"
831 ".previous"
832 : "=a"(to), "=d"(n)
833 : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
834 return n;
837 #endif /* _M68K_UACCESS_H */