xref: /netbsd/sys/arch/arc/arc/locore_machdep.S (revision bf9ec67e)
1/*	$NetBSD: locore_machdep.S,v 1.8 2000/06/09 05:07:32 soda 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. All advertising materials mentioning features or use of this software
20 *    must display the following acknowledgement:
21 *	This product includes software developed by the University of
22 *	California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 *    may be used to endorse or promote products derived from this software
25 *    without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * Copyright (C) 1989 Digital Equipment Corporation.
40 * Permission to use, copy, modify, and distribute this software and
41 * its documentation for any purpose and without fee is hereby granted,
42 * provided that the above copyright notice appears in all copies.
43 * Digital Equipment Corporation makes no representations about the
44 * suitability of this software for any purpose.  It is provided "as is"
45 * without express or implied warranty.
46 *
47 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
48 *	v 1.1 89/07/11 17:55:04 nelson Exp  SPRITE (DECWRL)
49 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
50 *	v 9.2 90/01/29 18:00:39 shirriff Exp  SPRITE (DECWRL)
51 * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
52 *	v 1.1 89/07/10 14:27:41 nelson Exp  SPRITE (DECWRL)
53 *
54 *	from: @(#)locore.s	8.5 (Berkeley) 1/4/94
55 */
56
57/*
58 * ARC-specific mips locore code
59 */
60
61#include <mips/asm.h>
62#include <mips/cpuregs.h>	/* XXX - misnomer? */
63#include <machine/endian.h>
64
65	.set	noreorder
66
67/*
68 * GCC2 seems to want to call __main in main() for some reason.
69 */
70LEAF(__main)
71	j	ra
72	nop
73END(__main)
74
75
76/*
77 *	Block I/O routines mainly used by I/O drivers.
78 *
79 *	Args as:	a0 = port
80 *			a1 = memory address
81 *			a2 = count
82 */
83LEAF(insb)
84	beq	a2, zero, 2f
85	addu	a2, a1
861:
87	lbu	v0, 0(a0)
88	addiu	a1, 1
89	bne	a1, a2, 1b
90	sb	v0, -1(a1)
912:
92	jr	ra
93	nop
94END(insb)
95
96LEAF(insw)
97	beq	a2, zero, 2f
98	addu	a2, a2
99	addu	a2, a1
1001:
101	lhu	v0, 0(a0)
102	addiu	a1, 2
103	bne	a1, a2, 1b
104	sh	v0, -2(a1)
1052:
106	jr	ra
107	nop
108END(insw)
109
110LEAF(insl)
111	beq	a2, zero, 2f
112	sll	a2, 2
113	addu	a2, a1
1141:
115	lw	v0, 0(a0)
116	addiu	a1, 4
117	bne	a1, a2, 1b
118	sw	v0, -4(a1)
1192:
120	jr	ra
121	nop
122END(insl)
123
124LEAF(outsb)
125	beq	a2, zero, 2f
126	addu	a2, a1
1271:
128	lbu	v0, 0(a1)
129	addiu	a1, 1
130	bne	a1, a2, 1b
131	sb	v0, 0(a0)
1322:
133	jr	ra
134	nop
135END(outsb)
136
137LEAF(outsw)
138	beq	a2, zero, 2f
139	addu	a2, a2
140	li	v0, 1
141	and	v0, a1
142	bne	v0, zero, 3f		# arghh, unaligned.
143	addu	a2, a1
1441:
145	lhu	v0, 0(a1)
146	addiu	a1, 2
147	bne	a1, a2, 1b
148	sh	v0, 0(a0)
1492:
150	jr	ra
151	nop
1523:
153	LWHI	v0, 0(a1)
154	LWLO	v0, 3(a1)
155	addiu	a1, 2
156	bne	a1, a2, 3b
157	sh	v0, 0(a0)
158
159	jr	ra
160	nop
161END(outsw)
162
163LEAF(outsl)
164	beq	a2, zero, 2f
165	sll	a2, 2
166	li	v0, 3
167	and	v0, a1
168	bne	v0, zero, 3f		# arghh, unaligned.
169	addu	a2, a1
1701:
171	lw	v0, 0(a1)
172	addiu	a1, 4
173	bne	a1, a2, 1b
174	sw	v0, 0(a0)
1752:
176	jr	ra
177	nop
1783:
179	LWHI	v0, 0(a1)
180	LWLO	v0, 3(a1)
181	addiu	a1, 4
182	bne	a1, a2, 3b
183	sw	v0, 0(a0)
184
185	jr	ra
186	nop
187END(outsl)
188
189/*
190 * fillw(pat, addr, count)
191 */
192LEAF(fillw)
1931:
194	addiu	a2, a2, -1
195	sh	a0, 0(a1)
196	bne	a2,zero, 1b
197	addiu	a1, a1, 2
198
199	jr	ra
200	nop
201END(fillw)
202
203/*#ifdef DEBUG*/ /* for minidebug.c: fix trap() to use this */
204#if 0
205/*
206 * Read a long and return it.
207 * Note: addresses can be unaligned!
208 *
209 * long
210L* mdbpeek(addr)
211L*	caddt_t addr;
212L* {
213L*	return (*(long *)addr);
214L* }
215 */
216LEAF(mdbpeek)
217	li	v0, MDBERR
218	sw	v0, UADDR+U_PCB_ONFAULT
219	and	v0, a0, 3		# unaligned address?
220	bne	v0, zero, 1f
221	nop
222	b	2f
223	lw	v0, (a0)		# aligned access
2241:
225	LWHI	v0, 0(a0)		# get next 4 bytes (unaligned)
226	LWLO	v0, 3(a0)
2272:
228	j	ra			# made it w/o errors
229	sw	zero, UADDR+U_PCB_ONFAULT
230mdberr:
231	li	v0, 1			# trap sends us here
232	sw	v0, mdbmkfault
233	j	ra
234	nop
235END(mdbpeek)
236
237/*
238 * Write a long to 'addr'.
239 * Note: addresses can be unaligned!
240 *
241L* void
242L* mdbpoke(addr, value)
243L*	caddt_t addr;
244L*	long value;
245L* {
246L*	*(long *)addr = value;
247L* }
248 */
249LEAF(mdbpoke)
250	li	v0, MDBERR
251	sw	v0, UADDR+U_PCB_ONFAULT
252	and	v0, a0, 3		# unaligned address?
253	bne	v0, zero, 1f
254	nop
255	b	2f
256	sw	a1, (a0)		# aligned access
2571:
258	SWHI	a1, 0(a0)		# store next 4 bytes (unaligned)
259	SWLO	a1, 3(a0)
260	and	a0, a0, ~3		# align address for cache flush
2612:
262	sw	zero, UADDR+U_PCB_ONFAULT
263	b	R4K_FlushICache		# flush instruction cache
264	li	a1, 8
265END(mdbpoke)
266
267/*
268 * Save registers and state so we can do a 'mdbreset' (like longjmp) later.
269 * Always returns zero.
270 *
271L* int mdb_savearea[11];
272L*
273L* int
274L* mdbsetexit()
275L* {
276L*	mdb_savearea[0] = 0;
277L*	return (0);
278L* }
279 */
280	.comm	mdb_savearea, (11 * 4)
281
282LEAF(mdbsetexit)
283	la	a0, mdb_savearea
284	sw	s0, 0(a0)
285	sw	s1, 4(a0)
286	sw	s2, 8(a0)
287	sw	s3, 12(a0)
288	sw	s4, 16(a0)
289	sw	s5, 20(a0)
290	sw	s6, 24(a0)
291	sw	s7, 28(a0)
292	sw	sp, 32(a0)
293	sw	s8, 36(a0)
294	sw	ra, 40(a0)
295	j	ra
296	move	v0, zero
297END(mdbsetexit)
298
299/*
300 * Restore registers and state (like longjmp) and return x.
301 *
302L* int
303L* mdbreset(x)
304L* {
305L*	return (x);
306L* }
307 */
308LEAF(mdbreset)
309	la	v0, mdb_savearea
310	lw	ra, 40(v0)
311	lw	s0, 0(v0)
312	lw	s1, 4(v0)
313	lw	s2, 8(v0)
314	lw	s3, 12(v0)
315	lw	s4, 16(v0)
316	lw	s5, 20(v0)
317	lw	s6, 24(v0)
318	lw	s7, 28(v0)
319	lw	sp, 32(v0)
320	lw	s8, 36(v0)
321	j	ra
322	move	v0, a0
323END(mdbreset)
324
325/*
326 * Trap into the debugger.
327 *
328L* void
329L* mdbpanic()
330L* {
331L* }
332 */
333LEAF(mdbpanic)
334	break	BREAK_SOVER_VAL
335	j	ra
336	nop
337END(mdbpanic)
338#endif /* DEBUG */
339
340	.set	mips3
341
342/*--------------------------------------------------------------------------
343 *
344 * mips3_TLBWriteIndexedVPS --
345 *
346 *	Write the given entry into the TLB at the given index.
347 *	Pass full r4000 tlb info including variable page size mask.
348 *
349 *	mips3_TLBWriteIndexed(index, tlb)
350 *		unsigned index;
351 *		tlb *tlb;
352 *
353 * Results:
354 *	None.
355 *
356 * Side effects:
357 *	TLB entry set.
358 *
359 *--------------------------------------------------------------------------
360 */
361LEAF(mips3_TLBWriteIndexedVPS)
362	mfc0	v1, MIPS_COP_0_STATUS_REG	# Save the status register.
363	mtc0	zero, MIPS_COP_0_STATUS_REG	# Disable interrupts
364	nop
365	lw	a2, 8(a1)
366	lw	a3, 12(a1)
367	dmfc0	v0, MIPS_COP_0_TLB_PG_MASK	# Save current page mask.
368	dmfc0	t0, MIPS_COP_0_TLB_HI		# Save the current PID.
369
370	dmtc0	a2, MIPS_COP_0_TLB_LO0		# Set up entry low0.
371	dmtc0	a3, MIPS_COP_0_TLB_LO1		# Set up entry low1.
372	nop
373	lw	a2, 0(a1)
374	lw	a3, 4(a1)
375	nop
376	mtc0	a0, MIPS_COP_0_TLB_INDEX	# Set the index.
377	dmtc0	a2, MIPS_COP_0_TLB_PG_MASK	# Set up entry mask.
378	dmtc0	a3, MIPS_COP_0_TLB_HI		# Set up entry high.
379	nop
380	tlbwi					# Write the TLB
381	nop
382	nop
383	nop					# Delay for effect
384	nop
385
386	dmtc0	t0, MIPS_COP_0_TLB_HI		# Restore the PID.
387	nop
388	dmtc0	v0, MIPS_COP_0_TLB_PG_MASK	# Restore page mask.
389	j	ra
390	mtc0	v1, MIPS_COP_0_STATUS_REG	# Restore the status register
391END(mips3_TLBWriteIndexedVPS)
392
393
394/*
395 * Interrupt counters for vmstat.
396 */
397	.data
398	.globl _C_LABEL(intrcnt)
399	.globl _C_LABEL(eintrcnt)
400	.globl _C_LABEL(intrnames)
401	.globl _C_LABEL(eintrnames)
402_C_LABEL(intrnames):
403	.asciiz	"softclock"
404	.asciiz	"softnet"
405	.asciiz	"fpu"
406_C_LABEL(eintrnames):
407	.align	3
408_C_LABEL(intrcnt):
409	.word	0,0,0
410_C_LABEL(eintrcnt):
411