xref: /minix3/minix/kernel/arch/earm/phys_memset.S (revision 5ae1a533c727d9e9ec344c83a96d06835d941004)
1*5ae1a533SBen Gras/*	$NetBSD: memset.S,v 1.7 2013/12/02 21:21:33 joerg Exp $	*/
2433d6423SLionel Sambuc
3433d6423SLionel Sambuc/*
4433d6423SLionel Sambuc * Copyright 2003 Wasabi Systems, Inc.
5433d6423SLionel Sambuc * All rights reserved.
6433d6423SLionel Sambuc *
7433d6423SLionel Sambuc * Written by Steve C. Woodford for Wasabi Systems, Inc.
8433d6423SLionel Sambuc *
9433d6423SLionel Sambuc * Redistribution and use in source and binary forms, with or without
10433d6423SLionel Sambuc * modification, are permitted provided that the following conditions
11433d6423SLionel Sambuc * are met:
12433d6423SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
13433d6423SLionel Sambuc *    notice, this list of conditions and the following disclaimer.
14433d6423SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
15433d6423SLionel Sambuc *    notice, this list of conditions and the following disclaimer in the
16433d6423SLionel Sambuc *    documentation and/or other materials provided with the distribution.
17433d6423SLionel Sambuc * 3. All advertising materials mentioning features or use of this software
18433d6423SLionel Sambuc *    must display the following acknowledgement:
19433d6423SLionel Sambuc *      This product includes software developed for the NetBSD Project by
20433d6423SLionel Sambuc *      Wasabi Systems, Inc.
21433d6423SLionel Sambuc * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22433d6423SLionel Sambuc *    or promote products derived from this software without specific prior
23433d6423SLionel Sambuc *    written permission.
24433d6423SLionel Sambuc *
25433d6423SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26433d6423SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27433d6423SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28433d6423SLionel Sambuc * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29433d6423SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30433d6423SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31433d6423SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32433d6423SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33433d6423SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34433d6423SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35433d6423SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE.
36433d6423SLionel Sambuc */
37433d6423SLionel Sambuc/*
38433d6423SLionel Sambuc * Copyright (c) 1995 Mark Brinicombe.
39433d6423SLionel Sambuc * All rights reserved.
40433d6423SLionel Sambuc *
41433d6423SLionel Sambuc * Redistribution and use in source and binary forms, with or without
42433d6423SLionel Sambuc * modification, are permitted provided that the following conditions
43433d6423SLionel Sambuc * are met:
44433d6423SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
45433d6423SLionel Sambuc *    notice, this list of conditions and the following disclaimer.
46433d6423SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
47433d6423SLionel Sambuc *    notice, this list of conditions and the following disclaimer in the
48433d6423SLionel Sambuc *    documentation and/or other materials provided with the distribution.
49433d6423SLionel Sambuc * 3. All advertising materials mentioning features or use of this software
50433d6423SLionel Sambuc *    must display the following acknowledgement:
51433d6423SLionel Sambuc *	This product includes software developed by Mark Brinicombe.
52433d6423SLionel Sambuc * 4. The name of the company nor the name of the author may be used to
53433d6423SLionel Sambuc *    endorse or promote products derived from this software without specific
54433d6423SLionel Sambuc *    prior written permission.
55433d6423SLionel Sambuc *
56433d6423SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
57433d6423SLionel Sambuc * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
58433d6423SLionel Sambuc * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
59433d6423SLionel Sambuc * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
60433d6423SLionel Sambuc * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61433d6423SLionel Sambuc * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62433d6423SLionel Sambuc * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63433d6423SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64433d6423SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65433d6423SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66433d6423SLionel Sambuc * SUCH DAMAGE.
67433d6423SLionel Sambuc */
68433d6423SLionel Sambuc
69433d6423SLionel Sambuc#include <machine/asm.h>
70433d6423SLionel Sambuc
71*5ae1a533SBen Gras#if 0  && defined(__minix)
72*5ae1a533SBen Gras#if defined(__ARM_EABI__) && !defined(_BZERO)
73*5ae1a533SBen GrasENTRY(__aeabi_memset)
74*5ae1a533SBen Gras	mov	r3, r1
75*5ae1a533SBen Gras	mov	r1, r2
76*5ae1a533SBen Gras	mov	r2, r3
77*5ae1a533SBen Gras	b	memset
78*5ae1a533SBen GrasEND(__aeabi_memset)
79*5ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memset4, __aeabi_memset)
80*5ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memset8, __aeabi_memset)
81*5ae1a533SBen Gras
82*5ae1a533SBen GrasENTRY(__aeabi_memclr)
83*5ae1a533SBen Gras	mov	r2, r1
84*5ae1a533SBen Gras	mov	r1, #0
85*5ae1a533SBen Gras	b	memset
86*5ae1a533SBen GrasEND(__aeabi_memclr)
87*5ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr)
88*5ae1a533SBen GrasSTRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr)
89*5ae1a533SBen Gras#endif
90*5ae1a533SBen Gras#endif /* #if 0  && defined(__minix) */
91*5ae1a533SBen Gras
92433d6423SLionel Sambuc/*
93433d6423SLionel Sambuc * memset: Sets a block of memory to the specified value
94433d6423SLionel Sambuc *
95433d6423SLionel Sambuc * On entry:
96433d6423SLionel Sambuc *   r0 - dest address
97433d6423SLionel Sambuc *   r1 - byte to write
98433d6423SLionel Sambuc *   r2 - number of bytes to write
99433d6423SLionel Sambuc *
100433d6423SLionel Sambuc * On exit:
101433d6423SLionel Sambuc *   r0 - dest address
102433d6423SLionel Sambuc */
103433d6423SLionel Sambuc#ifdef _BZERO
104433d6423SLionel Sambuc/* LINTSTUB: Func: void bzero(void *, size_t) */
105433d6423SLionel SambucENTRY(bzero)
106433d6423SLionel Sambuc	mov	r3, #0x00
107433d6423SLionel Sambuc#else
108433d6423SLionel Sambuc#if defined(__minix)
109433d6423SLionel Sambuc/* LINTSTUB: Func: void *phys_memset(void *, int, size_t) */
110433d6423SLionel SambucENTRY(phys_memset)
111433d6423SLionel Sambuc#else
112433d6423SLionel Sambuc/* LINTSTUB: Func: void *memset(void *, int, size_t) */
113433d6423SLionel SambucENTRY(memset)
114433d6423SLionel Sambuc#endif
115433d6423SLionel Sambuc	and	r3, r1, #0xff		/* We deal with bytes */
116433d6423SLionel Sambuc	mov	r1, r2
117433d6423SLionel Sambuc#endif
118433d6423SLionel Sambuc	cmp	r1, #0x04		/* Do we have less than 4 bytes */
119433d6423SLionel Sambuc	mov	ip, r0
120433d6423SLionel Sambuc	blt	.Lmemset_lessthanfour
121433d6423SLionel Sambuc
122433d6423SLionel Sambuc	/* Ok first we will word align the address */
123433d6423SLionel Sambuc	ands	r2, ip, #0x03		/* Get the bottom two bits */
124433d6423SLionel Sambuc	bne	.Lmemset_wordunaligned	/* The address is not word aligned */
125433d6423SLionel Sambuc
126433d6423SLionel Sambuc	/* We are now word aligned */
127433d6423SLionel Sambuc.Lmemset_wordaligned:
128433d6423SLionel Sambuc#ifndef _BZERO
129433d6423SLionel Sambuc	orr	r3, r3, r3, lsl #8	/* Extend value to 16-bits */
130433d6423SLionel Sambuc#endif
131*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK
132433d6423SLionel Sambuc	tst	ip, #0x04		/* Quad-align for Xscale */
133433d6423SLionel Sambuc#else
134433d6423SLionel Sambuc	cmp	r1, #0x10
135433d6423SLionel Sambuc#endif
136433d6423SLionel Sambuc#ifndef _BZERO
137433d6423SLionel Sambuc	orr	r3, r3, r3, lsl #16	/* Extend value to 32-bits */
138433d6423SLionel Sambuc#endif
139*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK
140433d6423SLionel Sambuc	subne	r1, r1, #0x04		/* Quad-align if necessary */
141433d6423SLionel Sambuc	strne	r3, [ip], #0x04
142433d6423SLionel Sambuc	cmp	r1, #0x10
143433d6423SLionel Sambuc#endif
144433d6423SLionel Sambuc	blt	.Lmemset_loop4		/* If less than 16 then use words */
145433d6423SLionel Sambuc	mov	r2, r3			/* Duplicate data */
146433d6423SLionel Sambuc	cmp	r1, #0x80		/* If < 128 then skip the big loop */
147433d6423SLionel Sambuc	blt	.Lmemset_loop32
148433d6423SLionel Sambuc
149433d6423SLionel Sambuc	/* Do 128 bytes at a time */
150433d6423SLionel Sambuc.Lmemset_loop128:
151433d6423SLionel Sambuc	subs	r1, r1, #0x80
152*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK
153*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
154*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
155*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
156*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
157*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
158*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
159*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
160*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
161*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
162*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
163*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
164*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
165*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
166*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
167*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
168*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
169433d6423SLionel Sambuc#else
170*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
171*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
172*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
173*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
174*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
175*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
176*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
177*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
178*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
179*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
180*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
181*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
182*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
183*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
184*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
185*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
186433d6423SLionel Sambuc#endif
187433d6423SLionel Sambuc	bgt	.Lmemset_loop128
188433d6423SLionel Sambuc#if defined(__minix)
189433d6423SLionel Sambuc	moveq	r0, #0
190433d6423SLionel Sambuc#endif
191433d6423SLionel Sambuc	RETc(eq)			/* Zero length so just exit */
192433d6423SLionel Sambuc
193433d6423SLionel Sambuc	add	r1, r1, #0x80		/* Adjust for extra sub */
194433d6423SLionel Sambuc
195433d6423SLionel Sambuc	/* Do 32 bytes at a time */
196433d6423SLionel Sambuc.Lmemset_loop32:
197433d6423SLionel Sambuc	subs	r1, r1, #0x20
198*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK
199*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
200*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
201*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
202*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
203433d6423SLionel Sambuc#else
204*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
205*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
206*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
207*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
208433d6423SLionel Sambuc#endif
209433d6423SLionel Sambuc	bgt	.Lmemset_loop32
210433d6423SLionel Sambuc#if defined(__minix)
211433d6423SLionel Sambuc	moveq	r0, #0
212433d6423SLionel Sambuc#endif
213433d6423SLionel Sambuc	RETc(eq)			/* Zero length so just exit */
214433d6423SLionel Sambuc
215433d6423SLionel Sambuc	adds	r1, r1, #0x10		/* Partially adjust for extra sub */
216433d6423SLionel Sambuc
217433d6423SLionel Sambuc	/* Deal with 16 bytes or more */
218*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK
219*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
220*5ae1a533SBen Gras	strdge	r2, r3, [ip], #0x08
221433d6423SLionel Sambuc#else
222*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
223*5ae1a533SBen Gras	stmiage	ip!, {r2-r3}
224433d6423SLionel Sambuc#endif
225433d6423SLionel Sambuc#if defined(__minix)
226433d6423SLionel Sambuc	moveq   r0, #0
227433d6423SLionel Sambuc#endif
228433d6423SLionel Sambuc	RETc(eq)			/* Zero length so just exit */
229433d6423SLionel Sambuc
230433d6423SLionel Sambuc	addlt	r1, r1, #0x10		/* Possibly adjust for extra sub */
231433d6423SLionel Sambuc
232433d6423SLionel Sambuc	/* We have at least 4 bytes so copy as words */
233433d6423SLionel Sambuc.Lmemset_loop4:
234433d6423SLionel Sambuc	subs	r1, r1, #0x04
235433d6423SLionel Sambuc	strge	r3, [ip], #0x04
236433d6423SLionel Sambuc	bgt	.Lmemset_loop4
237433d6423SLionel Sambuc#if defined(__minix)
238433d6423SLionel Sambuc	moveq	r0, #0
239433d6423SLionel Sambuc#endif
240433d6423SLionel Sambuc	RETc(eq)			/* Zero length so just exit */
241433d6423SLionel Sambuc
242*5ae1a533SBen Gras#ifdef _ARM_ARCH_DWORD_OK
243433d6423SLionel Sambuc	/* Compensate for 64-bit alignment check */
244433d6423SLionel Sambuc	adds	r1, r1, #0x04
245433d6423SLionel Sambuc#if defined(__minix)
246433d6423SLionel Sambuc	moveq	r0, #0
247433d6423SLionel Sambuc#endif
248433d6423SLionel Sambuc	RETc(eq)
249433d6423SLionel Sambuc	cmp	r1, #2
250433d6423SLionel Sambuc#else
251433d6423SLionel Sambuc	cmp	r1, #-2
252433d6423SLionel Sambuc#endif
253433d6423SLionel Sambuc
254433d6423SLionel Sambuc	strb	r3, [ip], #0x01		/* Set 1 byte */
255*5ae1a533SBen Gras	strbge	r3, [ip], #0x01		/* Set another byte */
256*5ae1a533SBen Gras	strbgt	r3, [ip]		/* and a third */
257433d6423SLionel Sambuc#if defined(__minix)
258433d6423SLionel Sambuc	mov	r0, #0
259433d6423SLionel Sambuc#endif
260433d6423SLionel Sambuc	RET				/* Exit */
261433d6423SLionel Sambuc
262433d6423SLionel Sambuc.Lmemset_wordunaligned:
263433d6423SLionel Sambuc	rsb	r2, r2, #0x004
264433d6423SLionel Sambuc	strb	r3, [ip], #0x01		/* Set 1 byte */
265433d6423SLionel Sambuc	cmp	r2, #0x02
266*5ae1a533SBen Gras	strbge	r3, [ip], #0x01		/* Set another byte */
267433d6423SLionel Sambuc	sub	r1, r1, r2
268*5ae1a533SBen Gras	strbgt	r3, [ip], #0x01		/* and a third */
269433d6423SLionel Sambuc	cmp	r1, #0x04		/* More than 4 bytes left? */
270433d6423SLionel Sambuc	bge	.Lmemset_wordaligned	/* Yup */
271433d6423SLionel Sambuc
272433d6423SLionel Sambuc.Lmemset_lessthanfour:
273433d6423SLionel Sambuc	cmp	r1, #0x00
274433d6423SLionel Sambuc#if defined(__minix)
275433d6423SLionel Sambuc	moveq	r0, #0
276433d6423SLionel Sambuc#endif
277433d6423SLionel Sambuc	RETc(eq)				/* Zero length so exit */
278433d6423SLionel Sambuc	strb	r3, [ip], #0x01		/* Set 1 byte */
279433d6423SLionel Sambuc	cmp	r1, #0x02
280*5ae1a533SBen Gras	strbge	r3, [ip], #0x01		/* Set another byte */
281*5ae1a533SBen Gras	strbgt	r3, [ip]		/* and a third */
282433d6423SLionel Sambuc#if defined(__minix)
283433d6423SLionel Sambuc	mov     r0, #0
284433d6423SLionel Sambuc#endif
285433d6423SLionel Sambuc	RET				/* Exit */
286*5ae1a533SBen Gras#ifdef _BZERO
287*5ae1a533SBen GrasEND(bzero)
288*5ae1a533SBen Gras#else
289*5ae1a533SBen Gras#if !defined(__minix)
290*5ae1a533SBen GrasEND(memset)
291*5ae1a533SBen Gras#else
292*5ae1a533SBen GrasEND(phys_memset)
293*5ae1a533SBen Gras#endif
294*5ae1a533SBen Gras#endif
295433d6423SLionel Sambuc
296433d6423SLionel Sambuc#if defined(__minix)
297433d6423SLionel SambucLABEL(memset_fault)		/* kernel can send us here */
298433d6423SLionel Sambuc	mov	r0, #0
299433d6423SLionel Sambuc	RET
300433d6423SLionel Sambuc
301433d6423SLionel SambucLABEL(memset_fault_in_kernel)	/* kernel can send us here */
302433d6423SLionel Sambuc	mrc	p15, 0, r0, c6, c0, 0	/* Read DFAR */
303433d6423SLionel Sambuc	RET
304433d6423SLionel Sambuc#endif
305