18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  entry.S -- non-mmu 68000 interrupt and exception entry points
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  Copyright (C) 1991, 1992  Linus Torvalds
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
78c2ecf20Sopenharmony_ci * License.  See the file README.legal in the main directory of this archive
88c2ecf20Sopenharmony_ci * for more details.
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * Linux/m68k support by Hamish Macdonald
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/linkage.h>
148c2ecf20Sopenharmony_ci#include <asm/thread_info.h>
158c2ecf20Sopenharmony_ci#include <asm/unistd.h>
168c2ecf20Sopenharmony_ci#include <asm/errno.h>
178c2ecf20Sopenharmony_ci#include <asm/setup.h>
188c2ecf20Sopenharmony_ci#include <asm/segment.h>
198c2ecf20Sopenharmony_ci#include <asm/traps.h>
208c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h>
218c2ecf20Sopenharmony_ci#include <asm/entry.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci.text
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci.globl system_call
268c2ecf20Sopenharmony_ci.globl resume
278c2ecf20Sopenharmony_ci.globl ret_from_exception
288c2ecf20Sopenharmony_ci.globl ret_from_signal
298c2ecf20Sopenharmony_ci.globl sys_call_table
308c2ecf20Sopenharmony_ci.globl bad_interrupt
318c2ecf20Sopenharmony_ci.globl inthandler1
328c2ecf20Sopenharmony_ci.globl inthandler2
338c2ecf20Sopenharmony_ci.globl inthandler3
348c2ecf20Sopenharmony_ci.globl inthandler4
358c2ecf20Sopenharmony_ci.globl inthandler5
368c2ecf20Sopenharmony_ci.globl inthandler6
378c2ecf20Sopenharmony_ci.globl inthandler7
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cibadsys:
408c2ecf20Sopenharmony_ci	movel	#-ENOSYS,%sp@(PT_OFF_D0)
418c2ecf20Sopenharmony_ci	jra	ret_from_exception
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cido_trace:
448c2ecf20Sopenharmony_ci	movel	#-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
458c2ecf20Sopenharmony_ci	subql	#4,%sp
468c2ecf20Sopenharmony_ci	SAVE_SWITCH_STACK
478c2ecf20Sopenharmony_ci	jbsr	syscall_trace_enter
488c2ecf20Sopenharmony_ci	RESTORE_SWITCH_STACK
498c2ecf20Sopenharmony_ci	addql	#4,%sp
508c2ecf20Sopenharmony_ci	addql	#1,%d0
518c2ecf20Sopenharmony_ci	jeq	ret_from_exception
528c2ecf20Sopenharmony_ci	movel	%sp@(PT_OFF_ORIG_D0),%d1
538c2ecf20Sopenharmony_ci	movel	#-ENOSYS,%d0
548c2ecf20Sopenharmony_ci	cmpl	#NR_syscalls,%d1
558c2ecf20Sopenharmony_ci	jcc	1f
568c2ecf20Sopenharmony_ci	lsl	#2,%d1
578c2ecf20Sopenharmony_ci	lea	sys_call_table, %a0
588c2ecf20Sopenharmony_ci	jbsr	%a0@(%d1)
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci1:	movel	%d0,%sp@(PT_OFF_D0)	/* save the return value */
618c2ecf20Sopenharmony_ci	subql	#4,%sp			/* dummy return address */
628c2ecf20Sopenharmony_ci	SAVE_SWITCH_STACK
638c2ecf20Sopenharmony_ci	jbsr	syscall_trace_leave
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ciret_from_signal:
668c2ecf20Sopenharmony_ci	RESTORE_SWITCH_STACK
678c2ecf20Sopenharmony_ci	addql	#4,%sp
688c2ecf20Sopenharmony_ci	jra	ret_from_exception
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ciENTRY(system_call)
718c2ecf20Sopenharmony_ci	SAVE_ALL_SYS
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	/* save top of frame*/
748c2ecf20Sopenharmony_ci	pea	%sp@
758c2ecf20Sopenharmony_ci	jbsr	set_esp0
768c2ecf20Sopenharmony_ci	addql	#4,%sp
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	movel	%sp@(PT_OFF_ORIG_D0),%d0
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	movel	%sp,%d1			/* get thread_info pointer */
818c2ecf20Sopenharmony_ci	andl	#-THREAD_SIZE,%d1
828c2ecf20Sopenharmony_ci	movel	%d1,%a2
838c2ecf20Sopenharmony_ci	btst	#(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
848c2ecf20Sopenharmony_ci	jne	do_trace
858c2ecf20Sopenharmony_ci	cmpl	#NR_syscalls,%d0
868c2ecf20Sopenharmony_ci	jcc	badsys
878c2ecf20Sopenharmony_ci	lsl	#2,%d0
888c2ecf20Sopenharmony_ci	lea	sys_call_table,%a0
898c2ecf20Sopenharmony_ci	movel	%a0@(%d0), %a0
908c2ecf20Sopenharmony_ci	jbsr	%a0@
918c2ecf20Sopenharmony_ci	movel	%d0,%sp@(PT_OFF_D0)	/* save the return value*/
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ciret_from_exception:
948c2ecf20Sopenharmony_ci	btst	#5,%sp@(PT_OFF_SR)	/* check if returning to kernel*/
958c2ecf20Sopenharmony_ci	jeq	Luser_return		/* if so, skip resched, signals*/
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ciLkernel_return:
988c2ecf20Sopenharmony_ci	RESTORE_ALL
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ciLuser_return:
1018c2ecf20Sopenharmony_ci	/* only allow interrupts when we are really the last one on the*/
1028c2ecf20Sopenharmony_ci	/* kernel stack, otherwise stack overflow can occur during*/
1038c2ecf20Sopenharmony_ci	/* heavy interrupt load*/
1048c2ecf20Sopenharmony_ci	andw	#ALLOWINT,%sr
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	movel	%sp,%d1			/* get thread_info pointer */
1078c2ecf20Sopenharmony_ci	andl	#-THREAD_SIZE,%d1
1088c2ecf20Sopenharmony_ci	movel	%d1,%a2
1098c2ecf20Sopenharmony_ci1:
1108c2ecf20Sopenharmony_ci	move	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
1118c2ecf20Sopenharmony_ci	jne	Lwork_to_do
1128c2ecf20Sopenharmony_ci	RESTORE_ALL
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ciLwork_to_do:
1158c2ecf20Sopenharmony_ci	movel	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
1168c2ecf20Sopenharmony_ci	btst	#TIF_NEED_RESCHED,%d1
1178c2ecf20Sopenharmony_ci	jne	reschedule
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ciLsignal_return:
1208c2ecf20Sopenharmony_ci	subql	#4,%sp			/* dummy return address*/
1218c2ecf20Sopenharmony_ci	SAVE_SWITCH_STACK
1228c2ecf20Sopenharmony_ci	pea	%sp@(SWITCH_STACK_SIZE)
1238c2ecf20Sopenharmony_ci	bsrw	do_notify_resume
1248c2ecf20Sopenharmony_ci	addql	#4,%sp
1258c2ecf20Sopenharmony_ci	RESTORE_SWITCH_STACK
1268c2ecf20Sopenharmony_ci	addql	#4,%sp
1278c2ecf20Sopenharmony_ci	jra	1b
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci/*
1308c2ecf20Sopenharmony_ci * This is the main interrupt handler, responsible for calling process_int()
1318c2ecf20Sopenharmony_ci */
1328c2ecf20Sopenharmony_ciinthandler1:
1338c2ecf20Sopenharmony_ci	SAVE_ALL_INT
1348c2ecf20Sopenharmony_ci	movew	%sp@(PT_OFF_FORMATVEC), %d0
1358c2ecf20Sopenharmony_ci	and	#0x3ff, %d0
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	movel	%sp,%sp@-
1388c2ecf20Sopenharmony_ci	movel	#65,%sp@- 		/*  put vector # on stack*/
1398c2ecf20Sopenharmony_ci	jbsr	process_int		/*  process the IRQ*/
1408c2ecf20Sopenharmony_ci3:     	addql	#8,%sp			/*  pop parameters off stack*/
1418c2ecf20Sopenharmony_ci	bra	ret_from_exception
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ciinthandler2:
1448c2ecf20Sopenharmony_ci	SAVE_ALL_INT
1458c2ecf20Sopenharmony_ci	movew	%sp@(PT_OFF_FORMATVEC), %d0
1468c2ecf20Sopenharmony_ci	and	#0x3ff, %d0
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	movel	%sp,%sp@-
1498c2ecf20Sopenharmony_ci	movel	#66,%sp@- 		/*  put vector # on stack*/
1508c2ecf20Sopenharmony_ci	jbsr	process_int		/*  process the IRQ*/
1518c2ecf20Sopenharmony_ci3:     	addql	#8,%sp			/*  pop parameters off stack*/
1528c2ecf20Sopenharmony_ci	bra	ret_from_exception
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ciinthandler3:
1558c2ecf20Sopenharmony_ci	SAVE_ALL_INT
1568c2ecf20Sopenharmony_ci	movew	%sp@(PT_OFF_FORMATVEC), %d0
1578c2ecf20Sopenharmony_ci	and	#0x3ff, %d0
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	movel	%sp,%sp@-
1608c2ecf20Sopenharmony_ci	movel	#67,%sp@- 		/*  put vector # on stack*/
1618c2ecf20Sopenharmony_ci	jbsr	process_int		/*  process the IRQ*/
1628c2ecf20Sopenharmony_ci3:     	addql	#8,%sp			/*  pop parameters off stack*/
1638c2ecf20Sopenharmony_ci	bra	ret_from_exception
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ciinthandler4:
1668c2ecf20Sopenharmony_ci	SAVE_ALL_INT
1678c2ecf20Sopenharmony_ci	movew	%sp@(PT_OFF_FORMATVEC), %d0
1688c2ecf20Sopenharmony_ci	and	#0x3ff, %d0
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	movel	%sp,%sp@-
1718c2ecf20Sopenharmony_ci	movel	#68,%sp@- 		/*  put vector # on stack*/
1728c2ecf20Sopenharmony_ci	jbsr	process_int		/*  process the IRQ*/
1738c2ecf20Sopenharmony_ci3:     	addql	#8,%sp			/*  pop parameters off stack*/
1748c2ecf20Sopenharmony_ci	bra	ret_from_exception
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ciinthandler5:
1778c2ecf20Sopenharmony_ci	SAVE_ALL_INT
1788c2ecf20Sopenharmony_ci	movew	%sp@(PT_OFF_FORMATVEC), %d0
1798c2ecf20Sopenharmony_ci	and	#0x3ff, %d0
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	movel	%sp,%sp@-
1828c2ecf20Sopenharmony_ci	movel	#69,%sp@- 		/*  put vector # on stack*/
1838c2ecf20Sopenharmony_ci	jbsr	process_int		/*  process the IRQ*/
1848c2ecf20Sopenharmony_ci3:     	addql	#8,%sp			/*  pop parameters off stack*/
1858c2ecf20Sopenharmony_ci	bra	ret_from_exception
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ciinthandler6:
1888c2ecf20Sopenharmony_ci	SAVE_ALL_INT
1898c2ecf20Sopenharmony_ci	movew	%sp@(PT_OFF_FORMATVEC), %d0
1908c2ecf20Sopenharmony_ci	and	#0x3ff, %d0
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	movel	%sp,%sp@-
1938c2ecf20Sopenharmony_ci	movel	#70,%sp@- 		/*  put vector # on stack*/
1948c2ecf20Sopenharmony_ci	jbsr	process_int		/*  process the IRQ*/
1958c2ecf20Sopenharmony_ci3:     	addql	#8,%sp			/*  pop parameters off stack*/
1968c2ecf20Sopenharmony_ci	bra	ret_from_exception
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ciinthandler7:
1998c2ecf20Sopenharmony_ci	SAVE_ALL_INT
2008c2ecf20Sopenharmony_ci	movew	%sp@(PT_OFF_FORMATVEC), %d0
2018c2ecf20Sopenharmony_ci	and	#0x3ff, %d0
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	movel	%sp,%sp@-
2048c2ecf20Sopenharmony_ci	movel	#71,%sp@- 		/*  put vector # on stack*/
2058c2ecf20Sopenharmony_ci	jbsr	process_int		/*  process the IRQ*/
2068c2ecf20Sopenharmony_ci3:     	addql	#8,%sp			/*  pop parameters off stack*/
2078c2ecf20Sopenharmony_ci	bra	ret_from_exception
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ciinthandler:
2108c2ecf20Sopenharmony_ci	SAVE_ALL_INT
2118c2ecf20Sopenharmony_ci	movew	%sp@(PT_OFF_FORMATVEC), %d0
2128c2ecf20Sopenharmony_ci	and	#0x3ff, %d0
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	movel	%sp,%sp@-
2158c2ecf20Sopenharmony_ci	movel	%d0,%sp@- 		/*  put vector # on stack*/
2168c2ecf20Sopenharmony_ci	jbsr	process_int		/*  process the IRQ*/
2178c2ecf20Sopenharmony_ci3:     	addql	#8,%sp			/*  pop parameters off stack*/
2188c2ecf20Sopenharmony_ci	bra	ret_from_exception
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci/*
2218c2ecf20Sopenharmony_ci * Handler for uninitialized and spurious interrupts.
2228c2ecf20Sopenharmony_ci */
2238c2ecf20Sopenharmony_ciENTRY(bad_interrupt)
2248c2ecf20Sopenharmony_ci	addql	#1,irq_err_count
2258c2ecf20Sopenharmony_ci	rte
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci/*
2288c2ecf20Sopenharmony_ci * Beware - when entering resume, prev (the current task) is
2298c2ecf20Sopenharmony_ci * in a0, next (the new task) is in a1, so don't change these
2308c2ecf20Sopenharmony_ci * registers until their contents are no longer needed.
2318c2ecf20Sopenharmony_ci */
2328c2ecf20Sopenharmony_ciENTRY(resume)
2338c2ecf20Sopenharmony_ci	movel	%a0,%d1				/* save prev thread in d1 */
2348c2ecf20Sopenharmony_ci	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)	/* save sr */
2358c2ecf20Sopenharmony_ci	SAVE_SWITCH_STACK
2368c2ecf20Sopenharmony_ci	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
2378c2ecf20Sopenharmony_ci	movel	%usp,%a3			/* save usp */
2388c2ecf20Sopenharmony_ci	movel	%a3,%a0@(TASK_THREAD+THREAD_USP)
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci	movel	%a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */
2418c2ecf20Sopenharmony_ci	movel	%a3,%usp
2428c2ecf20Sopenharmony_ci	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
2438c2ecf20Sopenharmony_ci	RESTORE_SWITCH_STACK
2448c2ecf20Sopenharmony_ci	movew	%a1@(TASK_THREAD+THREAD_SR),%sr	/* restore thread status reg */
2458c2ecf20Sopenharmony_ci	rts
2468c2ecf20Sopenharmony_ci
247