2 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
3 * Copyright (C) 2009 PetaLogix
4 * Copyright (C) 2007 LynuxWorks, Inc.
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
11 #include <linux/errno.h>
12 #include <linux/linkage.h>
16 * int __strncpy_user(char *to, char *from, int len);
19 * -EFAULT for an exception
20 * len if we hit the buffer limit
25 .globl __strncpy_user;
26 .type __strncpy_user, @function
38 addik r3,r7,0 /* temp_count = len */
45 addik r6,r6,1 /* delay slot */
48 bnei r3,1b /* break on len */
50 rsubk r3,r3,r7 /* temp_count = len - temp_count */
54 .size __strncpy_user, . - __strncpy_user
62 .section __ex_table, "a"
66 * int __strnlen_user(char __user *str, int maxlen);
70 * maxlen + 1 if no NUL byte found within maxlen bytes
71 * size of the string (including NUL byte)
75 .globl __strnlen_user;
76 .type __strnlen_user, @function
83 beqid r4,2f /* break on NUL */
84 addik r3,r3,-1 /* delay slot */
87 addik r5,r5,1 /* delay slot */
89 addik r3,r3,-1 /* for break on len */
95 .size __strnlen_user, . - __strnlen_user
102 .section __ex_table,"a"
105 /* Loop unrolling for __copy_tofrom_user */
106 #define COPY(offset) \
107 1: lwi r4 , r6, 0x0000 + offset; \
108 2: lwi r19, r6, 0x0004 + offset; \
109 3: lwi r20, r6, 0x0008 + offset; \
110 4: lwi r21, r6, 0x000C + offset; \
111 5: lwi r22, r6, 0x0010 + offset; \
112 6: lwi r23, r6, 0x0014 + offset; \
113 7: lwi r24, r6, 0x0018 + offset; \
114 8: lwi r25, r6, 0x001C + offset; \
115 9: swi r4 , r5, 0x0000 + offset; \
116 10: swi r19, r5, 0x0004 + offset; \
117 11: swi r20, r5, 0x0008 + offset; \
118 12: swi r21, r5, 0x000C + offset; \
119 13: swi r22, r5, 0x0010 + offset; \
120 14: swi r23, r5, 0x0014 + offset; \
121 15: swi r24, r5, 0x0018 + offset; \
122 16: swi r25, r5, 0x001C + offset; \
123 .section __ex_table,"a"; \
142 #define COPY_80(offset) \
143 COPY(0x00 + offset);\
144 COPY(0x20 + offset);\
145 COPY(0x40 + offset);\
149 * int __copy_tofrom_user(char *to, char *from, int len)
152 * number of not copied bytes on error
155 .globl __copy_tofrom_user;
156 .type __copy_tofrom_user, @function
165 beqid r7, 0f /* zero size is not likely */
166 or r3, r5, r6 /* find if is any to/from unaligned */
167 or r3, r3, r7 /* find if count is unaligned */
168 andi r3, r3, 0x3 /* mask last 3 bits */
169 bneid r3, bu1 /* if r3 is not zero then byte copying */
172 rsubi r3, r7, PAGE_SIZE /* detect PAGE_SIZE */
176 w1: lw r4, r6, r3 /* at least one 4 byte copy */
185 .section __ex_table,"a"
190 .align 4 /* Alignment is important to keep icache happy */
191 page: /* Create room on stack and save registers for storign values */
203 loop: /* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */
204 /* Loop unrolling to get performance boost */
215 /* Restore register content */
232 /* Fault case - return temp count */
235 /* Restore register content */
251 .align 4 /* Alignment is important to keep icache happy */
256 addik r3,r3,1 /* delay slot */
261 .size __copy_tofrom_user, . - __copy_tofrom_user
263 .section __ex_table,"a"