xref: /netbsd/sys/arch/arc/arc/locore_machdep.S (revision 6550d01e)
1/*	$NetBSD: locore_machdep.S,v 1.16 2009/11/27 03:23:04 rmind Exp $	*/
2/*	$OpenBSD: locore.S,v 1.12 1997/04/19 17:19:43 pefo Exp $	*/
3
4/*
5 * Copyright (c) 1992, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Digital Equipment Corporation and Ralph Campbell.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * Copyright (C) 1989 Digital Equipment Corporation.
36 * Permission to use, copy, modify, and distribute this software and
37 * its documentation for any purpose and without fee is hereby granted,
38 * provided that the above copyright notice appears in all copies.
39 * Digital Equipment Corporation makes no representations about the
40 * suitability of this software for any purpose.  It is provided "as is"
41 * without express or implied warranty.
42 *
43 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
44 *	v 1.1 89/07/11 17:55:04 nelson Exp  SPRITE (DECWRL)
45 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
46 *	v 9.2 90/01/29 18:00:39 shirriff Exp  SPRITE (DECWRL)
47 * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
48 *	v 1.1 89/07/10 14:27:41 nelson Exp  SPRITE (DECWRL)
49 *
50 *	from: @(#)locore.s	8.5 (Berkeley) 1/4/94
51 */
52
53/*
54 * ARC-specific mips locore code
55 */
56
57#include <mips/asm.h>
58#include <mips/cpuregs.h>	/* XXX - misnomer? */
59#include <machine/endian.h>
60
61	.set	noreorder
62
63/*
64 * GCC2 seems to want to call __main in main() for some reason.
65 */
66LEAF(__main)
67	j	ra
68	nop
69END(__main)
70
71
72/*
73 *	Block I/O routines mainly used by I/O drivers.
74 *
75 *	Args as:	a0 = port
76 *			a1 = memory address
77 *			a2 = count
78 */
79LEAF(insb)
80	beq	a2, zero, 2f
81	addu	a2, a1
821:
83	lbu	v0, 0(a0)
84	addiu	a1, 1
85	bne	a1, a2, 1b
86	sb	v0, -1(a1)
872:
88	jr	ra
89	nop
90END(insb)
91
92LEAF(insw)
93	beq	a2, zero, 2f
94	addu	a2, a2
95	addu	a2, a1
961:
97	lhu	v0, 0(a0)
98	addiu	a1, 2
99	bne	a1, a2, 1b
100	sh	v0, -2(a1)
1012:
102	jr	ra
103	nop
104END(insw)
105
106LEAF(insl)
107	beq	a2, zero, 2f
108	sll	a2, 2
109	addu	a2, a1
1101:
111	lw	v0, 0(a0)
112	addiu	a1, 4
113	bne	a1, a2, 1b
114	sw	v0, -4(a1)
1152:
116	jr	ra
117	nop
118END(insl)
119
120LEAF(outsb)
121	beq	a2, zero, 2f
122	addu	a2, a1
1231:
124	lbu	v0, 0(a1)
125	addiu	a1, 1
126	bne	a1, a2, 1b
127	sb	v0, 0(a0)
1282:
129	jr	ra
130	nop
131END(outsb)
132
133LEAF(outsw)
134	beq	a2, zero, 2f
135	addu	a2, a2
136	li	v0, 1
137	and	v0, a1
138	bne	v0, zero, 3f		# arghh, unaligned.
139	addu	a2, a1
1401:
141	lhu	v0, 0(a1)
142	addiu	a1, 2
143	bne	a1, a2, 1b
144	sh	v0, 0(a0)
1452:
146	jr	ra
147	nop
1483:
149	LWHI	v0, 0(a1)
150	LWLO	v0, 3(a1)
151	addiu	a1, 2
152	bne	a1, a2, 3b
153	sh	v0, 0(a0)
154
155	jr	ra
156	nop
157END(outsw)
158
159LEAF(outsl)
160	beq	a2, zero, 2f
161	sll	a2, 2
162	li	v0, 3
163	and	v0, a1
164	bne	v0, zero, 3f		# arghh, unaligned.
165	addu	a2, a1
1661:
167	lw	v0, 0(a1)
168	addiu	a1, 4
169	bne	a1, a2, 1b
170	sw	v0, 0(a0)
1712:
172	jr	ra
173	nop
1743:
175	LWHI	v0, 0(a1)
176	LWLO	v0, 3(a1)
177	addiu	a1, 4
178	bne	a1, a2, 3b
179	sw	v0, 0(a0)
180
181	jr	ra
182	nop
183END(outsl)
184
185/*
186 * fillw(pat, addr, count)
187 */
188LEAF(fillw)
1891:
190	addiu	a2, a2, -1
191	sh	a0, 0(a1)
192	bne	a2,zero, 1b
193	addiu	a1, a1, 2
194
195	jr	ra
196	nop
197END(fillw)
198
199/*#ifdef DEBUG*/ /* for minidebug.c: fix trap() to use this */
200#if 0
201/*
202 * Read a long and return it.
203 * Note: addresses can be unaligned!
204 *
205 * long
206L* mdbpeek(addr)
207L*	caddt_t addr;
208L* {
209L*	return (*(long *)addr);
210L* }
211 */
212LEAF(mdbpeek)
213	li	v0, MDBERR
214	sw	v0, UADDR+PCB_ONFAULT
215	and	v0, a0, 3		# unaligned address?
216	bne	v0, zero, 1f
217	nop
218	b	2f
219	lw	v0, (a0)		# aligned access
2201:
221	LWHI	v0, 0(a0)		# get next 4 bytes (unaligned)
222	LWLO	v0, 3(a0)
2232:
224	j	ra			# made it w/o errors
225	sw	zero, UADDR+PCB_ONFAULT
226mdberr:
227	li	v0, 1			# trap sends us here
228	sw	v0, mdbmkfault
229	j	ra
230	nop
231END(mdbpeek)
232
233/*
234 * Write a long to 'addr'.
235 * Note: addresses can be unaligned!
236 *
237L* void
238L* mdbpoke(addr, value)
239L*	caddt_t addr;
240L*	long value;
241L* {
242L*	*(long *)addr = value;
243L* }
244 */
245LEAF(mdbpoke)
246	li	v0, MDBERR
247	sw	v0, UADDR+PCB_ONFAULT
248	and	v0, a0, 3		# unaligned address?
249	bne	v0, zero, 1f
250	nop
251	b	2f
252	sw	a1, (a0)		# aligned access
2531:
254	SWHI	a1, 0(a0)		# store next 4 bytes (unaligned)
255	SWLO	a1, 3(a0)
256	and	a0, a0, ~3		# align address for cache flush
2572:
258	sw	zero, UADDR+PCB_ONFAULT
259	b	R4K_FlushICache		# flush instruction cache
260	li	a1, 8
261END(mdbpoke)
262
263/*
264 * Save registers and state so we can do a 'mdbreset' (like longjmp) later.
265 * Always returns zero.
266 *
267L* int mdb_savearea[11];
268L*
269L* int
270L* mdbsetexit()
271L* {
272L*	mdb_savearea[0] = 0;
273L*	return (0);
274L* }
275 */
276	.comm	mdb_savearea, (11 * 4)
277
278LEAF(mdbsetexit)
279	la	a0, mdb_savearea
280	sw	s0, 0(a0)
281	sw	s1, 4(a0)
282	sw	s2, 8(a0)
283	sw	s3, 12(a0)
284	sw	s4, 16(a0)
285	sw	s5, 20(a0)
286	sw	s6, 24(a0)
287	sw	s7, 28(a0)
288	sw	sp, 32(a0)
289	sw	s8, 36(a0)
290	sw	ra, 40(a0)
291	j	ra
292	move	v0, zero
293END(mdbsetexit)
294
295/*
296 * Restore registers and state (like longjmp) and return x.
297 *
298L* int
299L* mdbreset(x)
300L* {
301L*	return (x);
302L* }
303 */
304LEAF(mdbreset)
305	la	v0, mdb_savearea
306	lw	ra, 40(v0)
307	lw	s0, 0(v0)
308	lw	s1, 4(v0)
309	lw	s2, 8(v0)
310	lw	s3, 12(v0)
311	lw	s4, 16(v0)
312	lw	s5, 20(v0)
313	lw	s6, 24(v0)
314	lw	s7, 28(v0)
315	lw	sp, 32(v0)
316	lw	s8, 36(v0)
317	j	ra
318	move	v0, a0
319END(mdbreset)
320
321/*
322 * Trap into the debugger.
323 *
324L* void
325L* mdbpanic()
326L* {
327L* }
328 */
329LEAF(mdbpanic)
330	break	BREAK_SOVER_VAL
331	j	ra
332	nop
333END(mdbpanic)
334#endif /* DEBUG */
335