1129198Scognet/*	$NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 bjh21 Exp $	*/
2129198Scognet
3139735Simp/*-
4129198Scognet * Copyright (c) 1995 Mark Brinicombe.
5129198Scognet * All rights reserved.
6129198Scognet *
7129198Scognet * Redistribution and use in source and binary forms, with or without
8129198Scognet * modification, are permitted provided that the following conditions
9129198Scognet * are met:
10129198Scognet * 1. Redistributions of source code must retain the above copyright
11129198Scognet *    notice, this list of conditions and the following disclaimer.
12129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
13129198Scognet *    notice, this list of conditions and the following disclaimer in the
14129198Scognet *    documentation and/or other materials provided with the distribution.
15129198Scognet * 3. All advertising materials mentioning features or use of this software
16129198Scognet *    must display the following acknowledgement:
17129198Scognet *	This product includes software developed by Mark Brinicombe.
18129198Scognet * 4. The name of the company nor the name of the author may be used to
19129198Scognet *    endorse or promote products derived from this software without specific
20129198Scognet *    prior written permission.
21129198Scognet *
22129198Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23129198Scognet * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24129198Scognet * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25129198Scognet * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32129198Scognet * SUCH DAMAGE.
33129198Scognet *
34129198Scognet * copystr.S
35129198Scognet *
36129198Scognet * optimised and fault protected copystr functions
37129198Scognet *
38129198Scognet * Created      : 16/05/95
39129198Scognet */
40129198Scognet
41129198Scognet#include "assym.s"
42129198Scognet#include <machine/asm.h>
43129198Scognet#include <machine/armreg.h>
44129198Scognet__FBSDID("$FreeBSD$");
45129198Scognet
46129198Scognet#include <sys/errno.h>
47129198Scognet
48129198Scognet	.text
49276596Sian	.align	2
50239268Sgonzo
51284264Sandrew#if __ARM_ARCH >= 6
52239268Sgonzo#define GET_PCB(tmp) \
53239268Sgonzo	mrc p15, 0, tmp, c13, c0, 4; \
54261415Scognet	add	tmp, tmp, #(TD_PCB)
55129198Scognet#else
56129198Scognet.Lpcb:
57129198Scognet	.word	_C_LABEL(__pcpu) + PC_CURPCB
58239268Sgonzo
59239268Sgonzo#define GET_PCB(tmp) \
60239268Sgonzo	ldr	tmp, .Lpcb
61129198Scognet#endif
62129198Scognet
63129198Scognet/*
64129198Scognet * r0 - from
65129198Scognet * r1 - to
66129198Scognet * r2 - maxlens
67129198Scognet * r3 - lencopied
68129198Scognet *
69129198Scognet * Copy string from r0 to r1
70129198Scognet */
71129198ScognetENTRY(copystr)
72129198Scognet	stmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
73129198Scognet	teq	r2, #0x00000000
74129198Scognet	mov	r5, #0x00000000
75129198Scognet	moveq	r0, #ENAMETOOLONG
76129198Scognet	beq	2f
77129198Scognet
78129198Scognet1:	ldrb	r4, [r0], #0x0001
79129198Scognet	add	r5, r5, #0x00000001
80129198Scognet	teq	r4, #0x00000000
81129198Scognet	strb	r4, [r1], #0x0001
82129198Scognet	teqne	r5, r2
83129198Scognet	bne	1b
84129198Scognet
85129198Scognet	teq	r4, #0x00000000
86129198Scognet	moveq	r0, #0x00000000
87129198Scognet	movne	r0, #ENAMETOOLONG
88129198Scognet
89129198Scognet2:	teq	r3, #0x00000000
90129198Scognet	strne	r5, [r3]
91129198Scognet
92129198Scognet	ldmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
93137463Scognet	RET
94248361SandrewEND(copystr)
95129198Scognet
96129198Scognet#define SAVE_REGS	stmfd	sp!, {r4-r6}
97129198Scognet#define RESTORE_REGS	ldmfd	sp!, {r4-r6}
98129198Scognet
99129198Scognet/*
100129198Scognet * r0 - user space address
101129198Scognet * r1 - kernel space address
102129198Scognet * r2 - maxlens
103129198Scognet * r3 - lencopied
104129198Scognet *
105129198Scognet * Copy string from user space to kernel space
106129198Scognet */
107129198ScognetENTRY(copyinstr)
108129198Scognet	SAVE_REGS
109129198Scognet
110129198Scognet	teq	r2, #0x00000000
111129198Scognet	mov	r6, #0x00000000
112129198Scognet	moveq	r0, #ENAMETOOLONG
113129198Scognet	beq	2f
114129198Scognet
115289372Skib	ldr	r12, =VM_MAXUSER_ADDRESS
116289372Skib
117239268Sgonzo	GET_PCB(r4)
118129198Scognet	ldr	r4, [r4]
119129198Scognet
120129198Scognet#ifdef DIAGNOSTIC
121129198Scognet	teq	r4, #0x00000000
122129198Scognet	beq	.Lcopystrpcbfault
123129198Scognet#endif
124129198Scognet
125129198Scognet	adr	r5, .Lcopystrfault
126129198Scognet	str	r5, [r4, #PCB_ONFAULT]
127129198Scognet
128289372Skib1:
129289372Skib	cmp	r0, r12
130289372Skib	bcs	.Lcopystrfault
131289372Skib	ldrbt	r5, [r0], #0x0001
132129198Scognet	add	r6, r6, #0x00000001
133129198Scognet	teq	r5, #0x00000000
134129198Scognet	strb	r5, [r1], #0x0001
135129198Scognet	teqne	r6, r2
136129198Scognet	bne	1b
137129198Scognet
138129198Scognet	mov	r0, #0x00000000
139129198Scognet	str	r0, [r4, #PCB_ONFAULT]
140129198Scognet
141129198Scognet	teq	r5, #0x00000000
142129198Scognet	moveq	r0, #0x00000000
143129198Scognet	movne	r0, #ENAMETOOLONG
144129198Scognet
145129198Scognet2:	teq	r3, #0x00000000
146129198Scognet	strne	r6, [r3]
147129198Scognet
148129198Scognet	RESTORE_REGS
149137463Scognet	RET
150248361SandrewEND(copyinstr)
151129198Scognet
152129198Scognet/*
153129198Scognet * r0 - kernel space address
154129198Scognet * r1 - user space address
155129198Scognet * r2 - maxlens
156129198Scognet * r3 - lencopied
157129198Scognet *
158129198Scognet * Copy string from kernel space to user space
159129198Scognet */
160129198ScognetENTRY(copyoutstr)
161129198Scognet	SAVE_REGS
162129198Scognet
163129198Scognet	teq	r2, #0x00000000
164129198Scognet	mov	r6, #0x00000000
165129198Scognet	moveq	r0, #ENAMETOOLONG
166129198Scognet	beq	2f
167129198Scognet
168289372Skib	ldr	r12, =VM_MAXUSER_ADDRESS
169289372Skib
170239268Sgonzo	GET_PCB(r4)
171129198Scognet	ldr	r4, [r4]
172129198Scognet
173129198Scognet#ifdef DIAGNOSTIC
174129198Scognet	teq	r4, #0x00000000
175129198Scognet	beq	.Lcopystrpcbfault
176129198Scognet#endif
177129198Scognet
178129198Scognet	adr	r5, .Lcopystrfault
179129198Scognet	str	r5, [r4, #PCB_ONFAULT]
180129198Scognet
181289372Skib1:
182289372Skib	cmp	r0, r12
183289372Skib	bcs	.Lcopystrfault
184289372Skib	ldrb	r5, [r0], #0x0001
185129198Scognet	add	r6, r6, #0x00000001
186129198Scognet	teq	r5, #0x00000000
187129198Scognet	strbt	r5, [r1], #0x0001
188129198Scognet	teqne	r6, r2
189129198Scognet	bne	1b
190129198Scognet
191129198Scognet	mov	r0, #0x00000000
192129198Scognet	str	r0, [r4, #PCB_ONFAULT]
193129198Scognet
194129198Scognet	teq	r5, #0x00000000
195129198Scognet	moveq	r0, #0x00000000
196129198Scognet	movne	r0, #ENAMETOOLONG
197129198Scognet
198129198Scognet2:	teq	r3, #0x00000000
199129198Scognet	strne	r6, [r3]
200129198Scognet
201129198Scognet	RESTORE_REGS
202137463Scognet	RET
203248361SandrewEND(copyoutstr)
204129198Scognet
205129198Scognet/* A fault occurred during the copy */
206129198Scognet.Lcopystrfault:
207129198Scognet	mov	r1, #0x00000000
208129198Scognet	str	r1, [r4, #PCB_ONFAULT]
209289372Skib	mov	r0, #EFAULT
210129198Scognet	RESTORE_REGS
211137463Scognet	RET
212129198Scognet
213129198Scognet#ifdef DIAGNOSTIC
214129198Scognet.Lcopystrpcbfault:
215129198Scognet	mov	r2, r1
216129198Scognet	mov	r1, r0
217129198Scognet	adr	r0, Lcopystrpcbfaulttext
218129198Scognet	bic	sp, sp, #7			/* align stack to 8 bytes */
219129198Scognet	b	_C_LABEL(panic)
220129198Scognet
221129198ScognetLcopystrpcbfaulttext:
222129198Scognet	.asciz	"No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n"
223276596Sian	.align	2
224129198Scognet#endif
225