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