netfilter: nfnetlink: silence warning if CONFIG_PROVE_RCU isn't set
[cascardo/linux.git] / arch / microblaze / lib / uaccess_old.S
1 /*
2  * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
3  * Copyright (C) 2009 PetaLogix
4  * Copyright (C) 2007 LynuxWorks, Inc.
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file "COPYING" in the main directory of this archive
8  * for more details.
9  */
10
11 #include <linux/errno.h>
12 #include <linux/linkage.h>
13 #include <asm/page.h>
14
15 /*
16  * int __strncpy_user(char *to, char *from, int len);
17  *
18  * Returns:
19  *  -EFAULT  for an exception
20  *  len      if we hit the buffer limit
21  *  bytes copied
22  */
23
24         .text
25 .globl __strncpy_user;
26 .type  __strncpy_user, @function
27 .align 4;
28 __strncpy_user:
29
30         /*
31          * r5 - to
32          * r6 - from
33          * r7 - len
34          * r3 - temp count
35          * r4 - temp val
36          */
37         beqid   r7,3f
38         addik   r3,r7,0         /* temp_count = len */
39 1:
40         lbu     r4,r6,r0
41         sb      r4,r5,r0
42
43         addik   r3,r3,-1
44         beqi    r3,2f           /* break on len */
45
46         addik   r5,r5,1
47         bneid   r4,1b
48         addik   r6,r6,1         /* delay slot */
49         addik   r3,r3,1         /* undo "temp_count--" */
50 2:
51         rsubk   r3,r3,r7        /* temp_count = len - temp_count */
52 3:
53         rtsd    r15,8
54         nop
55         .size   __strncpy_user, . - __strncpy_user
56
57         .section        .fixup, "ax"
58         .align  2
59 4:
60         brid    3b
61         addik   r3,r0, -EFAULT
62
63         .section        __ex_table, "a"
64         .word   1b,4b
65
66 /*
67  * int __strnlen_user(char __user *str, int maxlen);
68  *
69  * Returns:
70  *  0 on error
71  *  maxlen + 1  if no NUL byte found within maxlen bytes
72  *  size of the string (including NUL byte)
73  */
74
75         .text
76 .globl __strnlen_user;
77 .type  __strnlen_user, @function
78 .align 4;
79 __strnlen_user:
80         beqid   r6,3f
81         addik   r3,r6,0
82 1:
83         lbu     r4,r5,r0
84         beqid   r4,2f           /* break on NUL */
85         addik   r3,r3,-1        /* delay slot */
86
87         bneid   r3,1b
88         addik   r5,r5,1         /* delay slot */
89
90         addik   r3,r3,-1        /* for break on len */
91 2:
92         rsubk   r3,r3,r6
93 3:
94         rtsd    r15,8
95         nop
96         .size   __strnlen_user, . - __strnlen_user
97
98         .section        .fixup,"ax"
99 4:
100         brid    3b
101         addk    r3,r0,r0
102
103         .section        __ex_table,"a"
104         .word   1b,4b
105
106 /* Loop unrolling for __copy_tofrom_user */
107 #define COPY(offset)    \
108 1:      lwi     r4 , r6, 0x0000 + offset;       \
109 2:      lwi     r19, r6, 0x0004 + offset;       \
110 3:      lwi     r20, r6, 0x0008 + offset;       \
111 4:      lwi     r21, r6, 0x000C + offset;       \
112 5:      lwi     r22, r6, 0x0010 + offset;       \
113 6:      lwi     r23, r6, 0x0014 + offset;       \
114 7:      lwi     r24, r6, 0x0018 + offset;       \
115 8:      lwi     r25, r6, 0x001C + offset;       \
116 9:      swi     r4 , r5, 0x0000 + offset;       \
117 10:     swi     r19, r5, 0x0004 + offset;       \
118 11:     swi     r20, r5, 0x0008 + offset;       \
119 12:     swi     r21, r5, 0x000C + offset;       \
120 13:     swi     r22, r5, 0x0010 + offset;       \
121 14:     swi     r23, r5, 0x0014 + offset;       \
122 15:     swi     r24, r5, 0x0018 + offset;       \
123 16:     swi     r25, r5, 0x001C + offset;       \
124         .section __ex_table,"a";                \
125         .word   1b, 33f;                        \
126         .word   2b, 33f;                        \
127         .word   3b, 33f;                        \
128         .word   4b, 33f;                        \
129         .word   5b, 33f;                        \
130         .word   6b, 33f;                        \
131         .word   7b, 33f;                        \
132         .word   8b, 33f;                        \
133         .word   9b, 33f;                        \
134         .word   10b, 33f;                       \
135         .word   11b, 33f;                       \
136         .word   12b, 33f;                       \
137         .word   13b, 33f;                       \
138         .word   14b, 33f;                       \
139         .word   15b, 33f;                       \
140         .word   16b, 33f;                       \
141         .text
142
143 #define COPY_80(offset) \
144         COPY(0x00 + offset);\
145         COPY(0x20 + offset);\
146         COPY(0x40 + offset);\
147         COPY(0x60 + offset);
148
149 /*
150  * int __copy_tofrom_user(char *to, char *from, int len)
151  * Return:
152  *   0 on success
153  *   number of not copied bytes on error
154  */
155         .text
156 .globl __copy_tofrom_user;
157 .type  __copy_tofrom_user, @function
158 .align 4;
159 __copy_tofrom_user:
160         /*
161          * r5 - to
162          * r6 - from
163          * r7, r3 - count
164          * r4 - tempval
165          */
166         beqid   r7, 0f /* zero size is not likely */
167         or      r3, r5, r6 /* find if is any to/from unaligned */
168         or      r3, r3, r7 /* find if count is unaligned */
169         andi    r3, r3, 0x3 /* mask last 3 bits */
170         bneid   r3, bu1 /* if r3 is not zero then byte copying */
171         or      r3, r0, r0
172
173         rsubi   r3, r7, PAGE_SIZE /* detect PAGE_SIZE */
174         beqid   r3, page;
175         or      r3, r0, r0
176
177 w1:     lw      r4, r6, r3 /* at least one 4 byte copy */
178 w2:     sw      r4, r5, r3
179         addik   r7, r7, -4
180         bneid   r7, w1
181         addik   r3, r3, 4
182         addik   r3, r7, 0
183         rtsd    r15, 8
184         nop
185
186         .section        __ex_table,"a"
187         .word   w1, 0f;
188         .word   w2, 0f;
189         .text
190
191 .align 4 /* Alignment is important to keep icache happy */
192 page:   /* Create room on stack and save registers for storign values */
193         addik   r1, r1, -40
194         swi     r5, r1, 0
195         swi     r6, r1, 4
196         swi     r7, r1, 8
197         swi     r19, r1, 12
198         swi     r20, r1, 16
199         swi     r21, r1, 20
200         swi     r22, r1, 24
201         swi     r23, r1, 28
202         swi     r24, r1, 32
203         swi     r25, r1, 36
204 loop:   /* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */
205         /* Loop unrolling to get performance boost */
206         COPY_80(0x000);
207         COPY_80(0x080);
208         COPY_80(0x100);
209         COPY_80(0x180);
210         /* copy loop */
211         addik   r6, r6, 0x200
212         addik   r7, r7, -0x200
213         bneid   r7, loop
214         addik   r5, r5, 0x200
215
216         /* Restore register content */
217         lwi     r5, r1, 0
218         lwi     r6, r1, 4
219         lwi     r7, r1, 8
220         lwi     r19, r1, 12
221         lwi     r20, r1, 16
222         lwi     r21, r1, 20
223         lwi     r22, r1, 24
224         lwi     r23, r1, 28
225         lwi     r24, r1, 32
226         lwi     r25, r1, 36
227         addik   r1, r1, 40
228         /* return back */
229         addik   r3, r0, 0
230         rtsd    r15, 8
231         nop
232
233 /* Fault case - return temp count */
234 33:
235         addik   r3, r7, 0
236         /* Restore register content */
237         lwi     r5, r1, 0
238         lwi     r6, r1, 4
239         lwi     r7, r1, 8
240         lwi     r19, r1, 12
241         lwi     r20, r1, 16
242         lwi     r21, r1, 20
243         lwi     r22, r1, 24
244         lwi     r23, r1, 28
245         lwi     r24, r1, 32
246         lwi     r25, r1, 36
247         addik   r1, r1, 40
248         /* return back */
249         rtsd    r15, 8
250         nop
251
252 .align 4 /* Alignment is important to keep icache happy */
253 bu1:    lbu     r4,r6,r3
254 bu2:    sb      r4,r5,r3
255         addik   r7,r7,-1
256         bneid   r7,bu1
257         addik   r3,r3,1         /* delay slot */
258 0:
259         addik   r3,r7,0
260         rtsd    r15,8
261         nop
262         .size   __copy_tofrom_user, . - __copy_tofrom_user
263
264         .section        __ex_table,"a"
265         .word   bu1, 0b;
266         .word   bu2, 0b;
267         .text