xref: /netbsd-src/sys/arch/arm/arm/copystr.S (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1/*	$NetBSD: copystr.S,v 1.11 2013/08/18 06:28:18 matt 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#include "opt_cpuoptions.h"
43
44#include "assym.h"
45
46#include <machine/asm.h>
47
48#include <arm/locore.h>
49
50RCSID("$NetBSD: copystr.S,v 1.11 2013/08/18 06:28:18 matt Exp $")
51
52#include <sys/errno.h>
53
54	.text
55	.align	0
56/*
57 * r0 - from
58 * r1 - to
59 * r2 - maxlens
60 * r3 - lencopied
61 *
62 * Copy string from r0 to r1
63 */
64ENTRY(copystr)
65	push	{r4-r5}			/* stack is 8 byte aligned */
66	teq	r2, #0x00000000
67	mov	r5, #0x00000000
68	moveq	r0, #ENAMETOOLONG
69	beq	2f
70
711:	ldrb	r4, [r0], #0x0001
72	add	r5, r5, #0x00000001
73	teq	r4, #0x00000000
74	strb	r4, [r1], #0x0001
75	teqne	r5, r2
76	bne	1b
77
78	teq	r4, #0x00000000
79	moveq	r0, #0x00000000
80	movne	r0, #ENAMETOOLONG
81
822:	teq	r3, #0x00000000
83	strne	r5, [r3]
84
85	pop	{r4-r5}			/* stack is 8 byte aligned */
86	RET
87END(copystr)
88
89#ifdef __PROG32
90#define SAVE_REGS	push	{r3-r6}
91#define RESTORE_REGS	pop	{r3-r6}
92#else
93/* Need to save R14_svc because it'll get trampled if we take a page fault. */
94#define SAVE_REGS	stmfd	sp!, {r4-r6, r14}
95#define RESTORE_REGS	ldmfd	sp!, {r4-r6, r14}
96#endif
97
98/*
99 * r0 - user space address
100 * r1 - kernel space address
101 * r2 - maxlens
102 * r3 - lencopied
103 *
104 * Copy string from user space to kernel space
105 */
106ENTRY(copyinstr)
107	SAVE_REGS
108
109	teq	r2, #0x00000000
110	mov	r6, #0x00000000
111	moveq	r0, #ENAMETOOLONG
112	beq	2f
113
114	GET_CURPCB(r4)
115
116#ifdef DIAGNOSTIC
117	teq	r4, #0x00000000
118	beq	.Lcopystrpcbfault
119#endif
120
121	adr	r5, .Lcopystrfault
122	str	r5, [r4, #PCB_ONFAULT]
123
1241:	ldrbt	r5, [r0], #0x0001
125	add	r6, r6, #0x00000001
126	teq	r5, #0x00000000
127	strb	r5, [r1], #0x0001
128	teqne	r6, r2
129	bne	1b
130
131	mov	r0, #0x00000000
132	str	r0, [r4, #PCB_ONFAULT]
133
134	teq	r5, #0x00000000
135	moveq	r0, #0x00000000
136	movne	r0, #ENAMETOOLONG
137
1382:	teq	r3, #0x00000000
139	strne	r6, [r3]
140
141	RESTORE_REGS
142	RET
143END(copyinstr)
144
145/*
146 * r0 - kernel space address
147 * r1 - user space address
148 * r2 - maxlens
149 * r3 - lencopied
150 *
151 * Copy string from kernel space to user space
152 */
153ENTRY(copyoutstr)
154	SAVE_REGS
155
156	teq	r2, #0x00000000
157	mov	r6, #0x00000000
158	moveq	r0, #ENAMETOOLONG
159	beq	2f
160
161	GET_CURPCB(r4)
162
163#ifdef DIAGNOSTIC
164	teq	r4, #0x00000000
165	beq	.Lcopystrpcbfault
166#endif
167
168	adr	r5, .Lcopystrfault
169	str	r5, [r4, #PCB_ONFAULT]
170
1711:	ldrb	r5, [r0], #0x0001
172	add	r6, r6, #0x00000001
173	teq	r5, #0x00000000
174	strbt	r5, [r1], #0x0001
175	teqne	r6, r2
176	bne	1b
177
178	mov	r0, #0x00000000
179	str	r0, [r4, #PCB_ONFAULT]
180
181	teq	r5, #0x00000000
182	moveq	r0, #0x00000000
183	movne	r0, #ENAMETOOLONG
184
1852:	teq	r3, #0x00000000
186	strne	r6, [r3]
187
188	RESTORE_REGS
189	RET
190
191/* A fault occurred during the copy */
192.Lcopystrfault:
193	mov	r1, #0x00000000
194	str	r1, [r4, #PCB_ONFAULT]
195	RESTORE_REGS
196	RET
197
198#ifdef DIAGNOSTIC
199.Lcopystrpcbfault:
200	mov	r2, r1
201	mov	r1, r0
202	adr	r0, .Lcopystrpcbfaulttext
203	bic	sp, sp, #7			/* align stack to 8 bytes */
204	b	_C_LABEL(panic)
205
206.Lcopystrpcbfaulttext:
207	.asciz	"No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n"
208	.align	0
209#endif
210END(copyoutstr)
211