blob: d09f2dce648dcebf1e925f9e8c982af85b771ecc [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 Simek9b133f82011-06-10 11:03:44 +0200122 beqid r7, 0f /* zero size is not likely */
Michal Simekca3865b2010-03-22 20:31:26 +0100123 or r3, r5, r6 /* find if is any to/from unaligned */
Michal Simek782d4912011-06-10 11:08:57 +0200124 or r3, r3, r7 /* find if count is unaligned */
125 andi r3, r3, 0x3 /* mask last 3 bits */
126 bneid r3, bu1 /* if r3 is not zero then byte copying */
Michal Simekca3865b2010-03-22 20:31:26 +0100127 or r3, r0, r0
128
Michal Simekc83858b2011-06-10 11:07:55 +0200129w1: lw r4, r6, r3 /* at least one 4 byte copy */
130w2: sw r4, r5, r3
Michal Simekca3865b2010-03-22 20:31:26 +0100131 addik r7, r7, -4
Michal Simekc83858b2011-06-10 11:07:55 +0200132 bneid r7, w1
Michal Simekca3865b2010-03-22 20:31:26 +0100133 addik r3, r3, 4
134 addik r3, r7, 0
135 rtsd r15, 8
136 nop
Michal Simekeedac792011-06-10 11:05:45 +0200137
138 .section __ex_table,"a"
Michal Simekc83858b2011-06-10 11:07:55 +0200139 .word w1, 0f;
140 .word w2, 0f;
Michal Simekeedac792011-06-10 11:05:45 +0200141 .text
142
Michal Simekc83858b2011-06-10 11:07:55 +0200143bu1: lbu r4,r6,r3
144bu2: sb r4,r5,r3
Michal Simekca3865b2010-03-22 20:31:26 +0100145 addik r7,r7,-1
Michal Simekc83858b2011-06-10 11:07:55 +0200146 bneid r7,bu1
Michal Simekca3865b2010-03-22 20:31:26 +0100147 addik r3,r3,1 /* delay slot */
Michal Simek9b133f82011-06-10 11:03:44 +02001480:
Michal Simekca3865b2010-03-22 20:31:26 +0100149 addik r3,r7,0
Michal Simek0d6de952009-05-26 16:30:23 +0200150 rtsd r15,8
151 nop
Michal Simek13851962010-03-23 08:09:32 +0100152 .size __copy_tofrom_user, . - __copy_tofrom_user
Michal Simek0d6de952009-05-26 16:30:23 +0200153
Michal Simek0d6de952009-05-26 16:30:23 +0200154 .section __ex_table,"a"
Michal Simekc83858b2011-06-10 11:07:55 +0200155 .word bu1, 0b;
156 .word bu2, 0b;
Michal Simekeedac792011-06-10 11:05:45 +0200157 .text