blob: 5810cec54a7a36e356d5c48b4ad29923ee0829e4 [file] [log] [blame]
Michal Simek0d6de952009-05-26 16:30:23 +02001/*
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
14/*
15 * int __strncpy_user(char *to, char *from, int len);
16 *
17 * Returns:
18 * -EFAULT for an exception
19 * len if we hit the buffer limit
20 * bytes copied
21 */
22
23 .text
24.globl __strncpy_user;
Michal Simek13851962010-03-23 08:09:32 +010025.type __strncpy_user, @function
Michal Simek0d6de952009-05-26 16:30:23 +020026.align 4;
27__strncpy_user:
28
29 /*
30 * r5 - to
31 * r6 - from
32 * r7 - len
33 * r3 - temp count
34 * r4 - temp val
35 */
36 addik r3,r7,0 /* temp_count = len */
37 beqi r3,3f
381:
39 lbu r4,r6,r0
40 sb r4,r5,r0
41
42 addik r3,r3,-1
43 beqi r3,2f /* break on len */
44
45 addik r5,r5,1
46 bneid r4,1b
47 addik r6,r6,1 /* delay slot */
48 addik r3,r3,1 /* undo "temp_count--" */
492:
50 rsubk r3,r3,r7 /* temp_count = len - temp_count */
513:
52 rtsd r15,8
53 nop
Michal Simek13851962010-03-23 08:09:32 +010054 .size __strncpy_user, . - __strncpy_user
Michal Simek0d6de952009-05-26 16:30:23 +020055
Michal Simek0d6de952009-05-26 16:30:23 +020056 .section .fixup, "ax"
57 .align 2
584:
59 brid 3b
60 addik r3,r0, -EFAULT
61
62 .section __ex_table, "a"
63 .word 1b,4b
64
65/*
66 * int __strnlen_user(char __user *str, int maxlen);
67 *
68 * Returns:
69 * 0 on error
70 * maxlen + 1 if no NUL byte found within maxlen bytes
71 * size of the string (including NUL byte)
72 */
73
74 .text
75.globl __strnlen_user;
Michal Simek13851962010-03-23 08:09:32 +010076.type __strnlen_user, @function
Michal Simek0d6de952009-05-26 16:30:23 +020077.align 4;
78__strnlen_user:
79 addik r3,r6,0
80 beqi r3,3f
811:
82 lbu r4,r5,r0
83 beqid r4,2f /* break on NUL */
84 addik r3,r3,-1 /* delay slot */
85
86 bneid r3,1b
87 addik r5,r5,1 /* delay slot */
88
89 addik r3,r3,-1 /* for break on len */
902:
91 rsubk r3,r3,r6
923:
93 rtsd r15,8
94 nop
Michal Simek13851962010-03-23 08:09:32 +010095 .size __strnlen_user, . - __strnlen_user
Michal Simek0d6de952009-05-26 16:30:23 +020096
Michal Simek0d6de952009-05-26 16:30:23 +020097 .section .fixup,"ax"
984:
99 brid 3b
100 addk r3,r0,r0
101
102 .section __ex_table,"a"
103 .word 1b,4b
104
105/*
106 * int __copy_tofrom_user(char *to, char *from, int len)
107 * Return:
108 * 0 on success
109 * number of not copied bytes on error
110 */
111 .text
112.globl __copy_tofrom_user;
Michal Simek13851962010-03-23 08:09:32 +0100113.type __copy_tofrom_user, @function
Michal Simek0d6de952009-05-26 16:30:23 +0200114.align 4;
115__copy_tofrom_user:
116 /*
117 * r5 - to
118 * r6 - from
119 * r7, r3 - count
120 * r4 - tempval
121 */
Michal Simekca3865b2010-03-22 20:31:26 +0100122 beqid r7, 3f /* zero size is not likely */
123 andi r3, r7, 0x3 /* filter add count */
124 bneid r3, 4f /* if is odd value then byte copying */
125 or r3, r5, r6 /* find if is any to/from unaligned */
126 andi r3, r3, 0x3 /* mask unaligned */
127 bneid r3, 1f /* it is unaligned -> then jump */
128 or r3, r0, r0
129
130/* at least one 4 byte copy */
1315: lw r4, r6, r3
1326: sw r4, r5, r3
133 addik r7, r7, -4
134 bneid r7, 5b
135 addik r3, r3, 4
136 addik r3, r7, 0
137 rtsd r15, 8
138 nop
1394: or r3, r0, r0
1401: lbu r4,r6,r3
1412: sb r4,r5,r3
142 addik r7,r7,-1
143 bneid r7,1b
144 addik r3,r3,1 /* delay slot */
Michal Simek0d6de952009-05-26 16:30:23 +02001453:
Michal Simekca3865b2010-03-22 20:31:26 +0100146 addik r3,r7,0
Michal Simek0d6de952009-05-26 16:30:23 +0200147 rtsd r15,8
148 nop
Michal Simek13851962010-03-23 08:09:32 +0100149 .size __copy_tofrom_user, . - __copy_tofrom_user
Michal Simek0d6de952009-05-26 16:30:23 +0200150
Michal Simek0d6de952009-05-26 16:30:23 +0200151 .section __ex_table,"a"
Michal Simekca3865b2010-03-22 20:31:26 +0100152 .word 1b,3b,2b,3b,5b,3b,6b,3b