xref: /netbsd-src/sys/arch/arm/arm/copystr.S (revision d710132b4b8ce7f7cccaaf660cb16aa16b4077a0)
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#include "opt_multiprocessor.h"
42
43#include "assym.h"
44#include <machine/asm.h>
45
46RCSID("$NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 bjh21 Exp $")
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.Lcurpcb:
57	.word	_C_LABEL(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 */
68ENTRY(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
751:	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
862:	teq	r3, #0x00000000
87	strne	r5, [r3]
88
89	ldmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
90	mov	pc, lr
91
92#ifdef __PROG32
93#define SAVE_REGS	stmfd	sp!, {r4-r6}
94#define RESTORE_REGS	ldmfd	sp!, {r4-r6}
95#else
96/* Need to save R14_svc because it'll get trampled if we take a page fault. */
97#define SAVE_REGS	stmfd	sp!, {r4-r6, r14}
98#define RESTORE_REGS	ldmfd	sp!, {r4-r6, r14}
99#endif
100
101/*
102 * r0 - user space address
103 * r1 - kernel space address
104 * r2 - maxlens
105 * r3 - lencopied
106 *
107 * Copy string from user space to kernel space
108 */
109ENTRY(copyinstr)
110	SAVE_REGS
111
112	teq	r2, #0x00000000
113	mov	r6, #0x00000000
114	moveq	r0, #ENAMETOOLONG
115	beq	2f
116
117#ifdef MULTIPROCESSOR
118	/* XXX Probably not appropriate for non-Hydra SMPs */
119	stmfd	sp!, {r0-r3, r14}
120	bl	_C_LABEL(cpu_number)
121	ldr	r4, .Lcpu_info
122	ldr	r4, [r4, r0, lsl #2]
123	ldr	r4, [r4, #CI_CURPCB]
124	ldmfd	sp!, {r0-r3, r14}
125#else
126	ldr	r4, .Lcurpcb
127	ldr	r4, [r4]
128#endif
129
130#ifdef DIAGNOSTIC
131	teq	r4, #0x00000000
132	beq	.Lcopystrpcbfault
133#endif
134
135	adr	r5, .Lcopystrfault
136	str	r5, [r4, #PCB_ONFAULT]
137
1381:	ldrbt	r5, [r0], #0x0001
139	add	r6, r6, #0x00000001
140	teq	r5, #0x00000000
141	strb	r5, [r1], #0x0001
142	teqne	r6, r2
143	bne	1b
144
145	mov	r0, #0x00000000
146	str	r0, [r4, #PCB_ONFAULT]
147
148	teq	r5, #0x00000000
149	moveq	r0, #0x00000000
150	movne	r0, #ENAMETOOLONG
151
1522:	teq	r3, #0x00000000
153	strne	r6, [r3]
154
155	RESTORE_REGS
156	mov	pc, lr
157
158/*
159 * r0 - kernel space address
160 * r1 - user space address
161 * r2 - maxlens
162 * r3 - lencopied
163 *
164 * Copy string from kernel space to user space
165 */
166ENTRY(copyoutstr)
167	SAVE_REGS
168
169	teq	r2, #0x00000000
170	mov	r6, #0x00000000
171	moveq	r0, #ENAMETOOLONG
172	beq	2f
173
174#ifdef MULTIPROCESSOR
175	/* XXX Probably not appropriate for non-Hydra SMPs */
176	stmfd	sp!, {r0-r3, r14}
177	bl	_C_LABEL(cpu_number)
178	ldr	r4, .Lcpu_info
179	ldr	r4, [r4, r0, lsl #2]
180	ldr	r4, [r4, #CI_CURPCB]
181	ldmfd	sp!, {r0-r3, r14}
182#else
183	ldr	r4, .Lcurpcb
184	ldr	r4, [r4]
185#endif
186
187#ifdef DIAGNOSTIC
188	teq	r4, #0x00000000
189	beq	.Lcopystrpcbfault
190#endif
191
192	adr	r5, .Lcopystrfault
193	str	r5, [r4, #PCB_ONFAULT]
194
1951:	ldrb	r5, [r0], #0x0001
196	add	r6, r6, #0x00000001
197	teq	r5, #0x00000000
198	strbt	r5, [r1], #0x0001
199	teqne	r6, r2
200	bne	1b
201
202	mov	r0, #0x00000000
203	str	r0, [r4, #PCB_ONFAULT]
204
205	teq	r5, #0x00000000
206	moveq	r0, #0x00000000
207	movne	r0, #ENAMETOOLONG
208
2092:	teq	r3, #0x00000000
210	strne	r6, [r3]
211
212	RESTORE_REGS
213	mov	pc, lr
214
215/* A fault occurred during the copy */
216.Lcopystrfault:
217	mov	r1, #0x00000000
218	str	r1, [r4, #PCB_ONFAULT]
219	RESTORE_REGS
220	mov	pc, lr
221
222#ifdef DIAGNOSTIC
223.Lcopystrpcbfault:
224	mov	r2, r1
225	mov	r1, r0
226	adr	r0, Lcopystrpcbfaulttext
227	bic	sp, sp, #7			/* align stack to 8 bytes */
228	b	_C_LABEL(panic)
229
230Lcopystrpcbfaulttext:
231	.asciz	"No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n"
232	.align	0
233#endif
234