initial commit
[freebsd-arm:freebsd-arm.git] / arm / arm / copystr.S
1 /*      $NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 bjh21 Exp $        */
2
3 /*-
4  * Copyright (c) 1995 Mark Brinicombe.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Mark Brinicombe.
18  * 4. The name of the company nor the name of the author may be used to
19  *    endorse or promote products derived from this software without specific
20  *    prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * copystr.S
35  *
36  * optimised and fault protected copystr functions
37  *
38  * Created      : 16/05/95
39  */
40
41         
42 #include "assym.s"
43 #include <machine/asm.h>
44 #include <machine/armreg.h>
45 #include <machine/asmacros.h>
46 __FBSDID("$FreeBSD$");
47
48 #include <sys/errno.h>
49
50         .text
51         .align  0
52 #ifdef MULTIPROCESSOR
53 .Lcpu_info:
54         .word   _C_LABEL(cpu_info)
55 #else
56 .Lpcb:
57         .word   _C_LABEL(__pcpu) + PC_CURPCB
58 #endif
59
60 /*
61  * r0 - from
62  * r1 - to
63  * r2 - maxlens
64  * r3 - lencopied
65  *
66  * Copy string from r0 to r1
67  */
68 ENTRY(copystr)
69         stmfd   sp!, {r4-r5}                    /* stack is 8 byte aligned */
70         teq     r2, #0x00000000
71         mov     r5, #0x00000000
72         moveq   r0, #ENAMETOOLONG
73         beq     2f
74
75 1:      ldrb    r4, [r0], #0x0001
76         add     r5, r5, #0x00000001
77         teq     r4, #0x00000000
78         strb    r4, [r1], #0x0001
79         teqne   r5, r2
80         bne     1b
81
82         teq     r4, #0x00000000
83         moveq   r0, #0x00000000
84         movne   r0, #ENAMETOOLONG
85
86 2:      teq     r3, #0x00000000
87         strne   r5, [r3]
88
89         ldmfd   sp!, {r4-r5}                    /* stack is 8 byte aligned */
90         RET
91
92 #define SAVE_REGS       stmfd   sp!, {r4-r6}
93 #define RESTORE_REGS    ldmfd   sp!, {r4-r6}
94
95 /*
96  * r0 - user space address
97  * r1 - kernel space address
98  * r2 - maxlens
99  * r3 - lencopied
100  *
101  * Copy string from user space to kernel space
102  */
103 ENTRY(copyinstr)
104         SAVE_REGS
105
106         teq     r2, #0x00000000
107         mov     r6, #0x00000000
108         moveq   r0, #ENAMETOOLONG
109         beq     2f
110
111 #ifdef MULTIPROCESSOR
112         /* XXX Probably not appropriate for non-Hydra SMPs */
113         stmfd   sp!, {r0-r3, r14}
114         bl      _C_LABEL(cpu_number)
115         ldr     r4, .Lcpu_info
116         ldr     r4, [r4, r0, lsl #2]
117         ldr     r4, [r4, #CI_CURPCB]
118         ldmfd   sp!, {r0-r3, r14}
119 #else
120         ldr     r4, .Lpcb
121         ldr     r4, [r4]
122 #endif
123
124 #ifdef DIAGNOSTIC
125         teq     r4, #0x00000000
126         beq     .Lcopystrpcbfault
127 #endif
128
129         adr     r5, .Lcopystrfault
130         str     r5, [r4, #PCB_ONFAULT]
131
132 1:      ldrbt   r5, [r0], #0x0001
133         add     r6, r6, #0x00000001
134         teq     r5, #0x00000000
135         strb    r5, [r1], #0x0001
136         teqne   r6, r2
137         bne     1b
138
139         mov     r0, #0x00000000
140         str     r0, [r4, #PCB_ONFAULT]
141
142         teq     r5, #0x00000000
143         moveq   r0, #0x00000000
144         movne   r0, #ENAMETOOLONG
145
146 2:      teq     r3, #0x00000000
147         strne   r6, [r3]
148
149         RESTORE_REGS
150         RET
151
152 /*
153  * r0 - kernel space address
154  * r1 - user space address
155  * r2 - maxlens
156  * r3 - lencopied
157  *
158  * Copy string from kernel space to user space
159  */
160 ENTRY(copyoutstr)
161         SAVE_REGS
162
163         teq     r2, #0x00000000
164         mov     r6, #0x00000000
165         moveq   r0, #ENAMETOOLONG
166         beq     2f
167
168 #ifdef MULTIPROCESSOR
169         /* XXX Probably not appropriate for non-Hydra SMPs */
170         stmfd   sp!, {r0-r3, r14}
171         bl      _C_LABEL(cpu_number)
172         ldr     r4, .Lcpu_info
173         ldr     r4, [r4, r0, lsl #2]
174         ldr     r4, [r4, #CI_CURPCB]
175         ldmfd   sp!, {r0-r3, r14}
176 #else
177         ldr     r4, .Lpcb
178         ldr     r4, [r4]
179 #endif
180
181 #ifdef DIAGNOSTIC
182         teq     r4, #0x00000000
183         beq     .Lcopystrpcbfault
184 #endif
185
186         adr     r5, .Lcopystrfault
187         str     r5, [r4, #PCB_ONFAULT]
188
189 1:      ldrb    r5, [r0], #0x0001
190         add     r6, r6, #0x00000001
191         teq     r5, #0x00000000
192         strbt   r5, [r1], #0x0001
193         teqne   r6, r2
194         bne     1b
195
196         mov     r0, #0x00000000
197         str     r0, [r4, #PCB_ONFAULT]
198
199         teq     r5, #0x00000000
200         moveq   r0, #0x00000000
201         movne   r0, #ENAMETOOLONG
202
203 2:      teq     r3, #0x00000000
204         strne   r6, [r3]
205
206         RESTORE_REGS
207         RET
208
209 /* A fault occurred during the copy */
210 .Lcopystrfault:
211         mov     r1, #0x00000000
212         str     r1, [r4, #PCB_ONFAULT]
213         RESTORE_REGS
214         RET
215
216 #ifdef DIAGNOSTIC
217 .Lcopystrpcbfault:
218         mov     r2, r1
219         mov     r1, r0
220         adr     r0, Lcopystrpcbfaulttext
221         bic     sp, sp, #7                      /* align stack to 8 bytes */
222         b       _C_LABEL(panic)
223
224 Lcopystrpcbfaulttext:
225         .asciz  "No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n"
226         .align  0
227 #endif