]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - arch/m68k/lib/uaccess.c
Fixes (asm, entry, irq, linker, defconfig)
[mcf548x/linux.git] / arch / m68k / lib / uaccess.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file COPYING in the main directory of this archive
4  * for more details.
5  */
6
7 #include <linux/module.h>
8 #ifndef CONFIG_COLDFIRE
9 #include <asm/uaccess.h>
10
11 unsigned long __generic_copy_from_user(void *to, const void __user *from,
12                                        unsigned long n)
13 {
14         unsigned long tmp, res;
15
16         asm volatile ("\n"
17                 "       tst.l   %0\n"
18                 "       jeq     2f\n"
19                 "1:     moves.l (%1)+,%3\n"
20                 "       move.l  %3,(%2)+\n"
21                 "       subq.l  #1,%0\n"
22                 "       jne     1b\n"
23                 "2:     btst    #1,%5\n"
24                 "       jeq     4f\n"
25                 "3:     moves.w (%1)+,%3\n"
26                 "       move.w  %3,(%2)+\n"
27                 "4:     btst    #0,%5\n"
28                 "       jeq     6f\n"
29                 "5:     moves.b (%1)+,%3\n"
30                 "       move.b  %3,(%2)+\n"
31                 "6:\n"
32                 "       .section .fixup,\"ax\"\n"
33                 "       .even\n"
34                 "10:    move.l  %0,%3\n"
35                 "7:     clr.l   (%2)+\n"
36                 "       subq.l  #1,%3\n"
37                 "       jne     7b\n"
38                 "       lsl.l   #2,%0\n"
39                 "       btst    #1,%5\n"
40                 "       jeq     8f\n"
41                 "30:    clr.w   (%2)+\n"
42                 "       addq.l  #2,%0\n"
43                 "8:     btst    #0,%5\n"
44                 "       jeq     6b\n"
45                 "50:    clr.b   (%2)+\n"
46                 "       addq.l  #1,%0\n"
47                 "       jra     6b\n"
48                 "       .previous\n"
49                 "\n"
50                 "       .section __ex_table,\"a\"\n"
51                 "       .align  4\n"
52                 "       .long   1b,10b\n"
53                 "       .long   3b,30b\n"
54                 "       .long   5b,50b\n"
55                 "       .previous"
56                 : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
57                 : "0" (n / 4), "d" (n & 3));
58
59         return res;
60 }
61 EXPORT_SYMBOL(__generic_copy_from_user);
62
63 unsigned long __generic_copy_to_user(void __user *to, const void *from,
64                                      unsigned long n)
65 {
66         unsigned long tmp, res;
67
68         asm volatile ("\n"
69                 "       tst.l   %0\n"
70                 "       jeq     4f\n"
71                 "1:     move.l  (%1)+,%3\n"
72                 "2:     moves.l %3,(%2)+\n"
73                 "3:     subq.l  #1,%0\n"
74                 "       jne     1b\n"
75                 "4:     btst    #1,%5\n"
76                 "       jeq     6f\n"
77                 "       move.w  (%1)+,%3\n"
78                 "5:     moves.w %3,(%2)+\n"
79                 "6:     btst    #0,%5\n"
80                 "       jeq     8f\n"
81                 "       move.b  (%1)+,%3\n"
82                 "7:     moves.b  %3,(%2)+\n"
83                 "8:\n"
84                 "       .section .fixup,\"ax\"\n"
85                 "       .even\n"
86                 "20:    lsl.l   #2,%0\n"
87                 "50:    add.l   %5,%0\n"
88                 "       jra     8b\n"
89                 "       .previous\n"
90                 "\n"
91                 "       .section __ex_table,\"a\"\n"
92                 "       .align  4\n"
93                 "       .long   2b,20b\n"
94                 "       .long   3b,20b\n"
95                 "       .long   5b,50b\n"
96                 "       .long   6b,50b\n"
97                 "       .long   7b,50b\n"
98                 "       .long   8b,50b\n"
99                 "       .previous"
100                 : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
101                 : "0" (n / 4), "d" (n & 3));
102
103         return res;
104 }
105 EXPORT_SYMBOL(__generic_copy_to_user);
106
107 /*
108  * Copy a null terminated string from userspace.
109  */
110 long strncpy_from_user(char *dst, const char __user *src, long count)
111 {
112         long res;
113         char c;
114
115         if (count <= 0)
116                 return count;
117
118         asm volatile ("\n"
119                 "1:     moves.b (%2)+,%4\n"
120                 "       move.b  %4,(%1)+\n"
121                 "       jeq     2f\n"
122                 "       subq.l  #1,%3\n"
123                 "       jne     1b\n"
124                 "2:     sub.l   %3,%0\n"
125                 "3:\n"
126                 "       .section .fixup,\"ax\"\n"
127                 "       .even\n"
128                 "10:    move.l  %5,%0\n"
129                 "       jra     3b\n"
130                 "       .previous\n"
131                 "\n"
132                 "       .section __ex_table,\"a\"\n"
133                 "       .align  4\n"
134                 "       .long   1b,10b\n"
135                 "       .previous"
136                 : "=d" (res), "+a" (dst), "+a" (src), "+r" (count), "=&d" (c)
137                 : "i" (-EFAULT), "0" (count));
138
139         return res;
140 }
141 EXPORT_SYMBOL(strncpy_from_user);
142
143 /*
144  * Return the size of a string (including the ending 0)
145  *
146  * Return 0 on exception, a value greater than N if too long
147  */
148 long strnlen_user(const char __user *src, long n)
149 {
150         char c;
151         long res;
152
153         asm volatile ("\n"
154                 "1:     subq.l  #1,%1\n"
155                 "       jmi     3f\n"
156                 "2:     moves.b (%0)+,%2\n"
157                 "       tst.b   %2\n"
158                 "       jne     1b\n"
159                 "       jra     4f\n"
160                 "\n"
161                 "3:     addq.l  #1,%0\n"
162                 "4:     sub.l   %4,%0\n"
163                 "5:\n"
164                 "       .section .fixup,\"ax\"\n"
165                 "       .even\n"
166                 "20:    sub.l   %0,%0\n"
167                 "       jra     5b\n"
168                 "       .previous\n"
169                 "\n"
170                 "       .section __ex_table,\"a\"\n"
171                 "       .align  4\n"
172                 "       .long   2b,20b\n"
173                 "       .previous\n"
174                 : "=&a" (res), "+d" (n), "=&d" (c)
175                 : "0" (src), "r" (src));
176
177         return res;
178 }
179 EXPORT_SYMBOL(strnlen_user);
180
181 /*
182  * Zero Userspace
183  */
184
185 unsigned long __clear_user(void __user *to, unsigned long n)
186 {
187         unsigned long res;
188
189         asm volatile ("\n"
190                 "       tst.l   %0\n"
191                 "       jeq     3f\n"
192                 "1:     moves.l %2,(%1)+\n"
193                 "2:     subq.l  #1,%0\n"
194                 "       jne     1b\n"
195                 "3:     btst    #1,%4\n"
196                 "       jeq     5f\n"
197                 "4:     moves.w %2,(%1)+\n"
198                 "5:     btst    #0,%4\n"
199                 "       jeq     7f\n"
200                 "6:     moves.b %2,(%1)\n"
201                 "7:\n"
202                 "       .section .fixup,\"ax\"\n"
203                 "       .even\n"
204                 "10:    lsl.l   #2,%0\n"
205                 "40:    add.l   %4,%0\n"
206                 "       jra     7b\n"
207                 "       .previous\n"
208                 "\n"
209                 "       .section __ex_table,\"a\"\n"
210                 "       .align  4\n"
211                 "       .long   1b,10b\n"
212                 "       .long   2b,10b\n"
213                 "       .long   4b,40b\n"
214                 "       .long   5b,40b\n"
215                 "       .long   6b,40b\n"
216                 "       .long   7b,40b\n"
217                 "       .previous"
218                 : "=d" (res), "+a" (to)
219                 : "r" (0), "0" (n / 4), "d" (n & 3));
220
221     return res;
222 }
223 EXPORT_SYMBOL(__clear_user);
224
225 #else /* CONFIG_COLDFIRE */
226
227 #include <asm/uaccess_coldfire.h>
228
229 unsigned long __generic_copy_from_user(void *to, const void *from,
230                 unsigned long n)
231 {
232     unsigned long tmp;
233     __asm__ __volatile__
234         ("   tstl %2\n"
235          "   jeq 2f\n"
236          "1: movel (%1)+,%3\n"
237          "   movel %3,(%0)+\n"
238          "   subql #1,%2\n"
239          "   jne 1b\n"
240          "2: movel %4,%2\n"
241          "   bclr #1,%2\n"
242          "   jeq 4f\n"
243          "3: movew (%1)+,%3\n"
244          "   movew %3,(%0)+\n"
245          "4: bclr #0,%2\n"
246          "   jeq 6f\n"
247          "5: moveb (%1)+,%3\n"
248          "   moveb %3,(%0)+\n"
249          "6:\n"
250          ".section .fixup,\"ax\"\n"
251          "   .even\n"
252          "7: movel %2,%%d0\n"
253          "71:clrl (%0)+\n"
254          "   subql #1,%%d0\n"
255          "   jne 71b\n"
256          "   lsll #2,%2\n"
257          "   addl %4,%2\n"
258          "   btst #1,%4\n"
259          "   jne 81f\n"
260          "   btst #0,%4\n"
261          "   jne 91f\n"
262          "   jra 6b\n"
263          "8: addql #2,%2\n"
264          "81:clrw (%0)+\n"
265          "   btst #0,%4\n"
266          "   jne 91f\n"
267          "   jra 6b\n"
268          "9: addql #1,%2\n"
269          "91:clrb (%0)+\n"
270          "   jra 6b\n"
271          ".previous\n"
272          ".section __ex_table,\"a\"\n"
273          "   .align 4\n"
274          "   .long 1b,7b\n"
275          "   .long 3b,8b\n"
276          "   .long 5b,9b\n"
277          ".previous"
278          : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
279          : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
280          : "d0", "memory");
281     return n;
282 }
283 EXPORT_SYMBOL(__generic_copy_from_user);
284
285
286 unsigned long __generic_copy_to_user(void *to, const void *from,
287                 unsigned long n)
288 {
289     unsigned long tmp;
290     __asm__ __volatile__
291         ("   tstl %2\n"
292          "   jeq 3f\n"
293          "1: movel (%1)+,%3\n"
294          "22:movel %3,(%0)+\n"
295          "2: subql #1,%2\n"
296          "   jne 1b\n"
297          "3: movel %4,%2\n"
298          "   bclr #1,%2\n"
299          "   jeq 4f\n"
300          "   movew (%1)+,%3\n"
301          "24:movew %3,(%0)+\n"
302          "4: bclr #0,%2\n"
303          "   jeq 5f\n"
304          "   moveb (%1)+,%3\n"
305          "25:moveb %3,(%0)+\n"
306          "5:\n"
307          ".section .fixup,\"ax\"\n"
308          "   .even\n"
309          "60:addql #1,%2\n"
310          "6: lsll #2,%2\n"
311          "   addl %4,%2\n"
312          "   jra 5b\n"
313          "7: addql #2,%2\n"
314          "   jra 5b\n"
315          "8: addql #1,%2\n"
316          "   jra 5b\n"
317          ".previous\n"
318          ".section __ex_table,\"a\"\n"
319          "   .align 4\n"
320          "   .long 1b,60b\n"
321          "   .long 22b,6b\n"
322          "   .long 2b,6b\n"
323          "   .long 24b,7b\n"
324          "   .long 3b,60b\n"
325          "   .long 4b,7b\n"
326          "   .long 25b,8b\n"
327          "   .long 5b,8b\n"
328          ".previous"
329          : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
330          : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
331          : "memory");
332     return n;
333 }
334 EXPORT_SYMBOL(__generic_copy_to_user);
335
336 /*
337  * Copy a null terminated string from userspace.
338  */
339
340 long strncpy_from_user(char *dst, const char *src, long count)
341 {
342         long res = -EFAULT;
343         if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
344                 return res;
345     if (count == 0) return count;
346     __asm__ __volatile__
347         ("1: moveb (%2)+,%%d0\n"
348          "12:moveb %%d0,(%1)+\n"
349          "   jeq 2f\n"
350          "   subql #1,%3\n"
351          "   jne 1b\n"
352          "2: subl %3,%0\n"
353          "3:\n"
354          ".section .fixup,\"ax\"\n"
355          "   .even\n"
356          "4: movel %4,%0\n"
357          "   jra 3b\n"
358          ".previous\n"
359          ".section __ex_table,\"a\"\n"
360          "   .align 4\n"
361          "   .long 1b,4b\n"
362          "   .long 12b,4b\n"
363          ".previous"
364          : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
365          : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
366          : "d0", "memory");
367     return res;
368 }
369 EXPORT_SYMBOL(strncpy_from_user);
370
371 /*
372  * Return the size of a string (including the ending 0)
373  *
374  * Return 0 on exception, a value greater than N if too long
375  */
376 long strnlen_user(const char *src, long n)
377 {
378     long res = -EFAULT;
379     if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
380         return res;
381
382         res = -(long)src;
383         __asm__ __volatile__
384                 ("1:\n"
385                  "   tstl %2\n"
386                  "   jeq 3f\n"
387                  "2: moveb (%1)+,%%d0\n"
388                  "22:\n"
389                  "   subql #1,%2\n"
390                  "   tstb %%d0\n"
391                  "   jne 1b\n"
392                  "   jra 4f\n"
393                  "3:\n"
394                  "   addql #1,%0\n"
395                  "4:\n"
396                  "   addl %1,%0\n"
397                  "5:\n"
398                  ".section .fixup,\"ax\"\n"
399                  "   .even\n"
400                  "6: moveq %3,%0\n"
401                  "   jra 5b\n"
402                  ".previous\n"
403                  ".section __ex_table,\"a\"\n"
404                  "   .align 4\n"
405                  "   .long 2b,6b\n"
406                  "   .long 22b,6b\n"
407                  ".previous"
408                  : "=d"(res), "=a"(src), "=d"(n)
409                  : "i"(0), "0"(res), "1"(src), "2"(n)
410                  : "d0");
411         return res;
412 }
413 EXPORT_SYMBOL(strnlen_user);
414
415
416 /*
417  * Zero Userspace
418  */
419
420 unsigned long __clear_user(void *to, unsigned long n)
421 {
422     __asm__ __volatile__
423         ("   tstl %1\n"
424          "   jeq 3f\n"
425          "1: movel %3,(%0)+\n"
426          "2: subql #1,%1\n"
427          "   jne 1b\n"
428          "3: movel %2,%1\n"
429          "   bclr #1,%1\n"
430          "   jeq 4f\n"
431          "24:movew %3,(%0)+\n"
432          "4: bclr #0,%1\n"
433          "   jeq 5f\n"
434          "25:moveb %3,(%0)+\n"
435          "5:\n"
436          ".section .fixup,\"ax\"\n"
437          "   .even\n"
438          "61:addql #1,%1\n"
439          "6: lsll #2,%1\n"
440          "   addl %2,%1\n"
441          "   jra 5b\n"
442          "7: addql #2,%1\n"
443          "   jra 5b\n"
444          "8: addql #1,%1\n"
445          "   jra 5b\n"
446          ".previous\n"
447          ".section __ex_table,\"a\"\n"
448          "   .align 4\n"
449          "   .long 1b,61b\n"
450          "   .long 2b,6b\n"
451          "   .long 3b,61b\n"
452          "   .long 24b,7b\n"
453          "   .long 4b,7b\n"
454          "   .long 25b,8b\n"
455          "   .long 5b,8b\n"
456          ".previous"
457          : "=a"(to), "=d"(n)
458          : "r"(n & 3), "d"(0), "0"(to), "1"(n/4));
459     return n;
460 }
461 EXPORT_SYMBOL(__clear_user);
462
463 #endif /* CONFIG_COLDFIRE */