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
42129198Scognet#include "assym.s"
43129198Scognet#include <machine/asm.h>
44129198Scognet#include <machine/armreg.h>
45129198Scognet#include <machine/asmacros.h>
46129198Scognet__FBSDID("$FreeBSD$");
47129198Scognet
48129198Scognet#include <sys/errno.h>
49129198Scognet
50129198Scognet	.text
51129198Scognet	.align	0
52129198Scognet#ifdef MULTIPROCESSOR
53129198Scognet.Lcpu_info:
54129198Scognet	.word	_C_LABEL(cpu_info)
55129198Scognet#else
56129198Scognet.Lpcb:
57129198Scognet	.word	_C_LABEL(__pcpu) + PC_CURPCB
58129198Scognet#endif
59129198Scognet
60129198Scognet/*
61129198Scognet * r0 - from
62129198Scognet * r1 - to
63129198Scognet * r2 - maxlens
64129198Scognet * r3 - lencopied
65129198Scognet *
66129198Scognet * Copy string from r0 to r1
67129198Scognet */
68129198ScognetENTRY(copystr)
69129198Scognet	stmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
70129198Scognet	teq	r2, #0x00000000
71129198Scognet	mov	r5, #0x00000000
72129198Scognet	moveq	r0, #ENAMETOOLONG
73129198Scognet	beq	2f
74129198Scognet
75129198Scognet1:	ldrb	r4, [r0], #0x0001
76129198Scognet	add	r5, r5, #0x00000001
77129198Scognet	teq	r4, #0x00000000
78129198Scognet	strb	r4, [r1], #0x0001
79129198Scognet	teqne	r5, r2
80129198Scognet	bne	1b
81129198Scognet
82129198Scognet	teq	r4, #0x00000000
83129198Scognet	moveq	r0, #0x00000000
84129198Scognet	movne	r0, #ENAMETOOLONG
85129198Scognet
86129198Scognet2:	teq	r3, #0x00000000
87129198Scognet	strne	r5, [r3]
88129198Scognet
89129198Scognet	ldmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
90137463Scognet	RET
91129198Scognet
92129198Scognet#define SAVE_REGS	stmfd	sp!, {r4-r6}
93129198Scognet#define RESTORE_REGS	ldmfd	sp!, {r4-r6}
94129198Scognet
95129198Scognet/*
96129198Scognet * r0 - user space address
97129198Scognet * r1 - kernel space address
98129198Scognet * r2 - maxlens
99129198Scognet * r3 - lencopied
100129198Scognet *
101129198Scognet * Copy string from user space to kernel space
102129198Scognet */
103129198ScognetENTRY(copyinstr)
104129198Scognet	SAVE_REGS
105129198Scognet
106129198Scognet	teq	r2, #0x00000000
107129198Scognet	mov	r6, #0x00000000
108129198Scognet	moveq	r0, #ENAMETOOLONG
109129198Scognet	beq	2f
110129198Scognet
111129198Scognet#ifdef MULTIPROCESSOR
112129198Scognet	/* XXX Probably not appropriate for non-Hydra SMPs */
113129198Scognet	stmfd	sp!, {r0-r3, r14}
114129198Scognet	bl	_C_LABEL(cpu_number)
115129198Scognet	ldr	r4, .Lcpu_info
116129198Scognet	ldr	r4, [r4, r0, lsl #2]
117129198Scognet	ldr	r4, [r4, #CI_CURPCB]
118129198Scognet	ldmfd	sp!, {r0-r3, r14}
119129198Scognet#else
120129198Scognet	ldr	r4, .Lpcb
121129198Scognet	ldr	r4, [r4]
122129198Scognet#endif
123129198Scognet
124129198Scognet#ifdef DIAGNOSTIC
125129198Scognet	teq	r4, #0x00000000
126129198Scognet	beq	.Lcopystrpcbfault
127129198Scognet#endif
128129198Scognet
129129198Scognet	adr	r5, .Lcopystrfault
130129198Scognet	str	r5, [r4, #PCB_ONFAULT]
131129198Scognet
132129198Scognet1:	ldrbt	r5, [r0], #0x0001
133129198Scognet	add	r6, r6, #0x00000001
134129198Scognet	teq	r5, #0x00000000
135129198Scognet	strb	r5, [r1], #0x0001
136129198Scognet	teqne	r6, r2
137129198Scognet	bne	1b
138129198Scognet
139129198Scognet	mov	r0, #0x00000000
140129198Scognet	str	r0, [r4, #PCB_ONFAULT]
141129198Scognet
142129198Scognet	teq	r5, #0x00000000
143129198Scognet	moveq	r0, #0x00000000
144129198Scognet	movne	r0, #ENAMETOOLONG
145129198Scognet
146129198Scognet2:	teq	r3, #0x00000000
147129198Scognet	strne	r6, [r3]
148129198Scognet
149129198Scognet	RESTORE_REGS
150137463Scognet	RET
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
168129198Scognet#ifdef MULTIPROCESSOR
169129198Scognet	/* XXX Probably not appropriate for non-Hydra SMPs */
170129198Scognet	stmfd	sp!, {r0-r3, r14}
171129198Scognet	bl	_C_LABEL(cpu_number)
172129198Scognet	ldr	r4, .Lcpu_info
173129198Scognet	ldr	r4, [r4, r0, lsl #2]
174129198Scognet	ldr	r4, [r4, #CI_CURPCB]
175129198Scognet	ldmfd	sp!, {r0-r3, r14}
176129198Scognet#else
177129198Scognet	ldr	r4, .Lpcb
178129198Scognet	ldr	r4, [r4]
179129198Scognet#endif
180129198Scognet
181129198Scognet#ifdef DIAGNOSTIC
182129198Scognet	teq	r4, #0x00000000
183129198Scognet	beq	.Lcopystrpcbfault
184129198Scognet#endif
185129198Scognet
186129198Scognet	adr	r5, .Lcopystrfault
187129198Scognet	str	r5, [r4, #PCB_ONFAULT]
188129198Scognet
189129198Scognet1:	ldrb	r5, [r0], #0x0001
190129198Scognet	add	r6, r6, #0x00000001
191129198Scognet	teq	r5, #0x00000000
192129198Scognet	strbt	r5, [r1], #0x0001
193129198Scognet	teqne	r6, r2
194129198Scognet	bne	1b
195129198Scognet
196129198Scognet	mov	r0, #0x00000000
197129198Scognet	str	r0, [r4, #PCB_ONFAULT]
198129198Scognet
199129198Scognet	teq	r5, #0x00000000
200129198Scognet	moveq	r0, #0x00000000
201129198Scognet	movne	r0, #ENAMETOOLONG
202129198Scognet
203129198Scognet2:	teq	r3, #0x00000000
204129198Scognet	strne	r6, [r3]
205129198Scognet
206129198Scognet	RESTORE_REGS
207137463Scognet	RET
208129198Scognet
209129198Scognet/* A fault occurred during the copy */
210129198Scognet.Lcopystrfault:
211129198Scognet	mov	r1, #0x00000000
212129198Scognet	str	r1, [r4, #PCB_ONFAULT]
213129198Scognet	RESTORE_REGS
214137463Scognet	RET
215129198Scognet
216129198Scognet#ifdef DIAGNOSTIC
217129198Scognet.Lcopystrpcbfault:
218129198Scognet	mov	r2, r1
219129198Scognet	mov	r1, r0
220129198Scognet	adr	r0, Lcopystrpcbfaulttext
221129198Scognet	bic	sp, sp, #7			/* align stack to 8 bytes */
222129198Scognet	b	_C_LABEL(panic)
223129198Scognet
224129198ScognetLcopystrpcbfaulttext:
225129198Scognet	.asciz	"No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n"
226129198Scognet	.align	0
227129198Scognet#endif
228