import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / arm / lib / uaccess-armo.S
1 /*
2  *  linux/arch/arm/lib/uaccess-armo.S
3  *
4  *  Copyright (C) 1998 Russell King
5  *
6  *  Note!  Some code fragments found in here have a special calling
7  *  convention - they are not APCS compliant!
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 #include <linux/linkage.h>
14 #include <asm/assembler.h>
15
16                 .text
17
18                 .globl  SYMBOL_NAME(uaccess_user)
19 SYMBOL_NAME(uaccess_user):
20                 .word   uaccess_user_put_byte
21                 .word   uaccess_user_get_byte
22                 .word   uaccess_user_put_half
23                 .word   uaccess_user_get_half
24                 .word   uaccess_user_put_word
25                 .word   uaccess_user_get_word
26                 .word   __arch_copy_from_user
27                 .word   __arch_copy_to_user
28                 .word   __arch_clear_user
29                 .word   __arch_strncpy_from_user
30                 .word   __arch_strnlen_user
31
32
33 @ In : r0 = x, r1 = addr, r2 = error
34 @ Out: r2 = error
35 uaccess_user_put_byte:
36                 stmfd   sp!, {lr}
37 USER(           strbt   r0, [r1])
38                 ldmfd   sp!, {pc}^
39
40 @ In : r0 = x, r1 = addr, r2 = error
41 @ Out: r2 = error
42 uaccess_user_put_half:
43                 stmfd   sp!, {lr}
44 USER(           strbt   r0, [r1], #1)
45                 mov     r0, r0, lsr #8
46 USER(           strbt   r0, [r1])
47                 ldmfd   sp!, {pc}^
48
49 @ In : r0 = x, r1 = addr, r2 = error
50 @ Out: r2 = error
51 uaccess_user_put_word:
52                 stmfd   sp!, {lr}
53 USER(           strt    r0, [r1])
54                 ldmfd   sp!, {pc}^
55
56 9001:           mov     r2, #-EFAULT
57                 ldmfd   sp!, {pc}^
58
59 @ In : r0 = addr, r1 = error
60 @ Out: r0 = x, r1 = error
61 uaccess_user_get_byte:
62                 stmfd   sp!, {lr}
63 USER(           ldrbt   r0, [r0])
64                 ldmfd   sp!, {pc}^
65
66 @ In : r0 = addr, r1 = error
67 @ Out: r0 = x, r1 = error
68 uaccess_user_get_half:
69                 stmfd   sp!, {lr}
70 USER(           ldrt    r0, [r0])
71                 mov     r0, r0, lsl #16
72                 mov     r0, r0, lsr #16
73                 ldmfd   sp!, {pc}^
74
75 @ In : r0 = addr, r1 = error
76 @ Out: r0 = x, r1 = error
77 uaccess_user_get_word:
78                 stmfd   sp!, {lr}
79 USER(           ldrt    r0, [r0])
80                 ldmfd   sp!, {pc}^
81
82 9001:           mov     r1, #-EFAULT
83                 ldmfd   sp!, {pc}^
84
85
86
87                 .globl  SYMBOL_NAME(uaccess_kernel)
88 SYMBOL_NAME(uaccess_kernel):
89                 .word   uaccess_kernel_put_byte
90                 .word   uaccess_kernel_get_byte
91                 .word   uaccess_kernel_put_half
92                 .word   uaccess_kernel_get_half
93                 .word   uaccess_kernel_put_word
94                 .word   uaccess_kernel_get_word
95                 .word   uaccess_kernel_copy
96                 .word   uaccess_kernel_copy
97                 .word   uaccess_kernel_clear
98                 .word   uaccess_kernel_strncpy_from
99                 .word   uaccess_kernel_strnlen
100
101 @ In : r0 = x, r1 = addr, r2 = error
102 @ Out: r2 = error
103 uaccess_kernel_put_byte:
104                 stmfd   sp!, {lr}
105                 strb    r0, [r1]
106                 ldmfd   sp!, {pc}^
107
108 @ In : r0 = x, r1 = addr, r2 = error
109 @ Out: r2 = error
110 uaccess_kernel_put_half:
111                 stmfd   sp!, {lr}
112                 strb    r0, [r1]
113                 mov     r0, r0, lsr #8
114                 strb    r0, [r1, #1]
115                 ldmfd   sp!, {pc}^
116
117 @ In : r0 = x, r1 = addr, r2 = error
118 @ Out: r2 = error
119 uaccess_kernel_put_word:
120                 stmfd   sp!, {lr}
121                 str     r0, [r1]
122                 ldmfd   sp!, {pc}^
123
124 @ In : r0 = addr, r1 = error
125 @ Out: r0 = x, r1 = error
126 uaccess_kernel_get_byte:
127                 stmfd   sp!, {lr}
128                 ldrb    r0, [r0]
129                 ldmfd   sp!, {pc}^
130
131 @ In : r0 = addr, r1 = error
132 @ Out: r0 = x, r1 = error
133 uaccess_kernel_get_half:
134                 stmfd   sp!, {lr}
135                 ldr     r0, [r0]
136                 mov     r0, r0, lsl #16
137                 mov     r0, r0, lsr #16
138                 ldmfd   sp!, {pc}^
139
140 @ In : r0 = addr, r1 = error
141 @ Out: r0 = x, r1 = error
142 uaccess_kernel_get_word:
143                 stmfd   sp!, {lr}
144                 ldr     r0, [r0]
145                 ldmfd   sp!, {pc}^
146
147
148 /* Prototype: int uaccess_kernel_copy(void *to, const char *from, size_t n)
149  * Purpose  : copy a block to kernel memory from kernel memory
150  * Params   : to   - kernel memory
151  *          : from - kernel memory
152  *          : n    - number of bytes to copy
153  * Returns  : Number of bytes NOT copied.
154  */
155 uaccess_kernel_copy:
156                 stmfd   sp!, {lr}
157                 bl      SYMBOL_NAME(memcpy)
158                 mov     r0, #0
159                 ldmfd   sp!, {pc}^
160
161 /* Prototype: int uaccess_kernel_clear(void *addr, size_t sz)
162  * Purpose  : clear some kernel memory
163  * Params   : addr - kernel memory address to clear
164  *          : sz   - number of bytes to clear
165  * Returns  : number of bytes NOT cleared
166  */
167 uaccess_kernel_clear:
168                 stmfd   sp!, {lr}
169                 mov     r2, #0
170                 cmp     r1, #4
171                 blt     2f
172                 ands    ip, r0, #3
173                 beq     1f
174                 cmp     ip, #1
175                 strb    r2, [r0], #1
176                 strleb  r2, [r0], #1
177                 strltb  r2, [r0], #1
178                 rsb     ip, ip, #4
179                 sub     r1, r1, ip              @  7  6  5  4  3  2  1
180 1:              subs    r1, r1, #8              @ -1 -2 -3 -4 -5 -6 -7
181                 bmi     2f
182                 str     r2, [r0], #4
183                 str     r2, [r0], #4
184                 b       1b
185 2:              adds    r1, r1, #4              @  3  2  1  0 -1 -2 -3
186                 strpl   r2, [r0], #4
187                 tst     r1, #2                  @ 1x 1x 0x 0x 1x 1x 0x
188                 strneb  r2, [r0], #1
189                 strneb  r2, [r0], #1
190                 tst     r1, #1                  @ x1 x0 x1 x0 x1 x0 x1
191                 strneb  r2, [r0], #1
192                 mov     r0, #0
193                 ldmfd   sp!, {pc}^
194
195 /* Prototype: size_t uaccess_kernel_strncpy_from(char *dst, char *src, size_t len)
196  * Purpose  : copy a string from kernel memory to kernel memory
197  * Params   : dst - kernel memory destination
198  *          : src - kernel memory source
199  *          : len - maximum length of string
200  * Returns  : number of characters copied
201  */
202 uaccess_kernel_strncpy_from:
203                 stmfd   sp!, {lr}
204                 mov     ip, r2
205 1:              subs    r2, r2, #1
206                 bmi     2f
207                 ldrb    r3, [r1], #1
208                 strb    r3, [r0], #1
209                 teq     r3, #0
210                 bne     1b
211 2:              subs    r0, ip, r2
212                 ldmfd   sp!, {pc}^
213
214 /* Prototype: int uaccess_kernel_strlen(char *str, long n)
215  * Purpose  : get length of a string in kernel memory
216  * Params   : str - address of string in kernel memory
217  * Returns  : length of string *including terminator*,
218  *            or zero on exception, or n + 1 if too long
219  */
220 uaccess_kernel_strnlen:
221                 stmfd   sp!, {lr}
222                 mov     r2, r0
223 1:              ldrb    r1, [r0], #1
224                 teq     r1, #0
225                 beq     2f
226                 subs    r1, r1, #1
227                 bne     1b
228                 add     r0, r0, #1
229 2:              sub     r0, r0, r2
230                 ldmfd   sp!, {pc}^
231