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