xref: /openbmc/linux/arch/m68k/68000/entry.S (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
118cb3fafSGreg Ungerer/*
26f4a8856SGreg Ungerer *  entry.S -- non-mmu 68000 interrupt and exception entry points
318cb3fafSGreg Ungerer *
418cb3fafSGreg Ungerer *  Copyright (C) 1991, 1992  Linus Torvalds
518cb3fafSGreg Ungerer *
618cb3fafSGreg Ungerer * This file is subject to the terms and conditions of the GNU General Public
718cb3fafSGreg Ungerer * License.  See the file README.legal in the main directory of this archive
818cb3fafSGreg Ungerer * for more details.
918cb3fafSGreg Ungerer *
1018cb3fafSGreg Ungerer * Linux/m68k support by Hamish Macdonald
1118cb3fafSGreg Ungerer */
1218cb3fafSGreg Ungerer
1318cb3fafSGreg Ungerer#include <linux/linkage.h>
1418cb3fafSGreg Ungerer#include <asm/thread_info.h>
1518cb3fafSGreg Ungerer#include <asm/unistd.h>
1618cb3fafSGreg Ungerer#include <asm/errno.h>
1718cb3fafSGreg Ungerer#include <asm/setup.h>
1818cb3fafSGreg Ungerer#include <asm/traps.h>
1918cb3fafSGreg Ungerer#include <asm/asm-offsets.h>
2018cb3fafSGreg Ungerer#include <asm/entry.h>
2118cb3fafSGreg Ungerer
2218cb3fafSGreg Ungerer.text
2318cb3fafSGreg Ungerer
2418cb3fafSGreg Ungerer.globl system_call
2518cb3fafSGreg Ungerer.globl resume
2618cb3fafSGreg Ungerer.globl ret_from_exception
2718cb3fafSGreg Ungerer.globl sys_call_table
2818cb3fafSGreg Ungerer.globl bad_interrupt
2918cb3fafSGreg Ungerer.globl inthandler1
3018cb3fafSGreg Ungerer.globl inthandler2
3118cb3fafSGreg Ungerer.globl inthandler3
3218cb3fafSGreg Ungerer.globl inthandler4
3318cb3fafSGreg Ungerer.globl inthandler5
3418cb3fafSGreg Ungerer.globl inthandler6
3518cb3fafSGreg Ungerer.globl inthandler7
3618cb3fafSGreg Ungerer
3718cb3fafSGreg Ungererbadsys:
3818cb3fafSGreg Ungerer	movel	#-ENOSYS,%sp@(PT_OFF_D0)
3918cb3fafSGreg Ungerer	jra	ret_from_exception
4018cb3fafSGreg Ungerer
4118cb3fafSGreg Ungererdo_trace:
4218cb3fafSGreg Ungerer	movel	#-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
4318cb3fafSGreg Ungerer	subql	#4,%sp
4418cb3fafSGreg Ungerer	SAVE_SWITCH_STACK
4518cb3fafSGreg Ungerer	jbsr	syscall_trace_enter
4618cb3fafSGreg Ungerer	RESTORE_SWITCH_STACK
4718cb3fafSGreg Ungerer	addql	#4,%sp
48*2ca8a1deSMichael Schmitz	addql	#1,%d0
49*2ca8a1deSMichael Schmitz	jeq	ret_from_exception
5018cb3fafSGreg Ungerer	movel	%sp@(PT_OFF_ORIG_D0),%d1
5118cb3fafSGreg Ungerer	movel	#-ENOSYS,%d0
5218cb3fafSGreg Ungerer	cmpl	#NR_syscalls,%d1
5318cb3fafSGreg Ungerer	jcc	1f
5418cb3fafSGreg Ungerer	lsl	#2,%d1
5518cb3fafSGreg Ungerer	lea	sys_call_table, %a0
5618cb3fafSGreg Ungerer	jbsr	%a0@(%d1)
5718cb3fafSGreg Ungerer
5818cb3fafSGreg Ungerer1:	movel	%d0,%sp@(PT_OFF_D0)	/* save the return value */
5918cb3fafSGreg Ungerer	subql	#4,%sp			/* dummy return address */
6018cb3fafSGreg Ungerer	SAVE_SWITCH_STACK
6118cb3fafSGreg Ungerer	jbsr	syscall_trace_leave
6218cb3fafSGreg Ungerer	RESTORE_SWITCH_STACK
6318cb3fafSGreg Ungerer	addql	#4,%sp
6418cb3fafSGreg Ungerer	jra	ret_from_exception
6518cb3fafSGreg Ungerer
6618cb3fafSGreg UngererENTRY(system_call)
6718cb3fafSGreg Ungerer	SAVE_ALL_SYS
6818cb3fafSGreg Ungerer
6918cb3fafSGreg Ungerer	/* save top of frame*/
7018cb3fafSGreg Ungerer	pea	%sp@
7118cb3fafSGreg Ungerer	jbsr	set_esp0
7218cb3fafSGreg Ungerer	addql	#4,%sp
7318cb3fafSGreg Ungerer
7418cb3fafSGreg Ungerer	movel	%sp@(PT_OFF_ORIG_D0),%d0
7518cb3fafSGreg Ungerer
7618cb3fafSGreg Ungerer	movel	%sp,%d1			/* get thread_info pointer */
7718cb3fafSGreg Ungerer	andl	#-THREAD_SIZE,%d1
7818cb3fafSGreg Ungerer	movel	%d1,%a2
7918cb3fafSGreg Ungerer	btst	#(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
8018cb3fafSGreg Ungerer	jne	do_trace
8118cb3fafSGreg Ungerer	cmpl	#NR_syscalls,%d0
8218cb3fafSGreg Ungerer	jcc	badsys
8318cb3fafSGreg Ungerer	lsl	#2,%d0
8418cb3fafSGreg Ungerer	lea	sys_call_table,%a0
8518cb3fafSGreg Ungerer	movel	%a0@(%d0), %a0
8618cb3fafSGreg Ungerer	jbsr	%a0@
8718cb3fafSGreg Ungerer	movel	%d0,%sp@(PT_OFF_D0)	/* save the return value*/
8818cb3fafSGreg Ungerer
8918cb3fafSGreg Ungererret_from_exception:
9018cb3fafSGreg Ungerer	btst	#5,%sp@(PT_OFF_SR)	/* check if returning to kernel*/
9118cb3fafSGreg Ungerer	jeq	Luser_return		/* if so, skip resched, signals*/
9218cb3fafSGreg Ungerer
9318cb3fafSGreg UngererLkernel_return:
9418cb3fafSGreg Ungerer	RESTORE_ALL
9518cb3fafSGreg Ungerer
9618cb3fafSGreg UngererLuser_return:
9718cb3fafSGreg Ungerer	/* only allow interrupts when we are really the last one on the*/
9818cb3fafSGreg Ungerer	/* kernel stack, otherwise stack overflow can occur during*/
9918cb3fafSGreg Ungerer	/* heavy interrupt load*/
10018cb3fafSGreg Ungerer	andw	#ALLOWINT,%sr
10118cb3fafSGreg Ungerer
10218cb3fafSGreg Ungerer	movel	%sp,%d1			/* get thread_info pointer */
10318cb3fafSGreg Ungerer	andl	#-THREAD_SIZE,%d1
10418cb3fafSGreg Ungerer	movel	%d1,%a2
10518cb3fafSGreg Ungerer1:
10618cb3fafSGreg Ungerer	move	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
10718cb3fafSGreg Ungerer	jne	Lwork_to_do
10818cb3fafSGreg Ungerer	RESTORE_ALL
10918cb3fafSGreg Ungerer
11018cb3fafSGreg UngererLwork_to_do:
11118cb3fafSGreg Ungerer	movel	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
11218cb3fafSGreg Ungerer	btst	#TIF_NEED_RESCHED,%d1
11318cb3fafSGreg Ungerer	jne	reschedule
11418cb3fafSGreg Ungerer
11518cb3fafSGreg UngererLsignal_return:
11618cb3fafSGreg Ungerer	subql	#4,%sp			/* dummy return address*/
11718cb3fafSGreg Ungerer	SAVE_SWITCH_STACK
11818cb3fafSGreg Ungerer	pea	%sp@(SWITCH_STACK_SIZE)
11918cb3fafSGreg Ungerer	bsrw	do_notify_resume
12018cb3fafSGreg Ungerer	addql	#4,%sp
12118cb3fafSGreg Ungerer	RESTORE_SWITCH_STACK
12218cb3fafSGreg Ungerer	addql	#4,%sp
12318cb3fafSGreg Ungerer	jra	1b
12418cb3fafSGreg Ungerer
12518cb3fafSGreg Ungerer/*
12618cb3fafSGreg Ungerer * This is the main interrupt handler, responsible for calling process_int()
12718cb3fafSGreg Ungerer */
12818cb3fafSGreg Ungererinthandler1:
12918cb3fafSGreg Ungerer	SAVE_ALL_INT
13018cb3fafSGreg Ungerer	movew	%sp@(PT_OFF_FORMATVEC), %d0
13118cb3fafSGreg Ungerer	and	#0x3ff, %d0
13218cb3fafSGreg Ungerer
13318cb3fafSGreg Ungerer	movel	%sp,%sp@-
13418cb3fafSGreg Ungerer	movel	#65,%sp@- 		/*  put vector # on stack*/
13518cb3fafSGreg Ungerer	jbsr	process_int		/*  process the IRQ*/
13618cb3fafSGreg Ungerer3:     	addql	#8,%sp			/*  pop parameters off stack*/
13718cb3fafSGreg Ungerer	bra	ret_from_exception
13818cb3fafSGreg Ungerer
13918cb3fafSGreg Ungererinthandler2:
14018cb3fafSGreg Ungerer	SAVE_ALL_INT
14118cb3fafSGreg Ungerer	movew	%sp@(PT_OFF_FORMATVEC), %d0
14218cb3fafSGreg Ungerer	and	#0x3ff, %d0
14318cb3fafSGreg Ungerer
14418cb3fafSGreg Ungerer	movel	%sp,%sp@-
14518cb3fafSGreg Ungerer	movel	#66,%sp@- 		/*  put vector # on stack*/
14618cb3fafSGreg Ungerer	jbsr	process_int		/*  process the IRQ*/
14718cb3fafSGreg Ungerer3:     	addql	#8,%sp			/*  pop parameters off stack*/
14818cb3fafSGreg Ungerer	bra	ret_from_exception
14918cb3fafSGreg Ungerer
15018cb3fafSGreg Ungererinthandler3:
15118cb3fafSGreg Ungerer	SAVE_ALL_INT
15218cb3fafSGreg Ungerer	movew	%sp@(PT_OFF_FORMATVEC), %d0
15318cb3fafSGreg Ungerer	and	#0x3ff, %d0
15418cb3fafSGreg Ungerer
15518cb3fafSGreg Ungerer	movel	%sp,%sp@-
15618cb3fafSGreg Ungerer	movel	#67,%sp@- 		/*  put vector # on stack*/
15718cb3fafSGreg Ungerer	jbsr	process_int		/*  process the IRQ*/
15818cb3fafSGreg Ungerer3:     	addql	#8,%sp			/*  pop parameters off stack*/
15918cb3fafSGreg Ungerer	bra	ret_from_exception
16018cb3fafSGreg Ungerer
16118cb3fafSGreg Ungererinthandler4:
16218cb3fafSGreg Ungerer	SAVE_ALL_INT
16318cb3fafSGreg Ungerer	movew	%sp@(PT_OFF_FORMATVEC), %d0
16418cb3fafSGreg Ungerer	and	#0x3ff, %d0
16518cb3fafSGreg Ungerer
16618cb3fafSGreg Ungerer	movel	%sp,%sp@-
16718cb3fafSGreg Ungerer	movel	#68,%sp@- 		/*  put vector # on stack*/
16818cb3fafSGreg Ungerer	jbsr	process_int		/*  process the IRQ*/
16918cb3fafSGreg Ungerer3:     	addql	#8,%sp			/*  pop parameters off stack*/
17018cb3fafSGreg Ungerer	bra	ret_from_exception
17118cb3fafSGreg Ungerer
17218cb3fafSGreg Ungererinthandler5:
17318cb3fafSGreg Ungerer	SAVE_ALL_INT
17418cb3fafSGreg Ungerer	movew	%sp@(PT_OFF_FORMATVEC), %d0
17518cb3fafSGreg Ungerer	and	#0x3ff, %d0
17618cb3fafSGreg Ungerer
17718cb3fafSGreg Ungerer	movel	%sp,%sp@-
17818cb3fafSGreg Ungerer	movel	#69,%sp@- 		/*  put vector # on stack*/
17918cb3fafSGreg Ungerer	jbsr	process_int		/*  process the IRQ*/
18018cb3fafSGreg Ungerer3:     	addql	#8,%sp			/*  pop parameters off stack*/
18118cb3fafSGreg Ungerer	bra	ret_from_exception
18218cb3fafSGreg Ungerer
18318cb3fafSGreg Ungererinthandler6:
18418cb3fafSGreg Ungerer	SAVE_ALL_INT
18518cb3fafSGreg Ungerer	movew	%sp@(PT_OFF_FORMATVEC), %d0
18618cb3fafSGreg Ungerer	and	#0x3ff, %d0
18718cb3fafSGreg Ungerer
18818cb3fafSGreg Ungerer	movel	%sp,%sp@-
18918cb3fafSGreg Ungerer	movel	#70,%sp@- 		/*  put vector # on stack*/
19018cb3fafSGreg Ungerer	jbsr	process_int		/*  process the IRQ*/
19118cb3fafSGreg Ungerer3:     	addql	#8,%sp			/*  pop parameters off stack*/
19218cb3fafSGreg Ungerer	bra	ret_from_exception
19318cb3fafSGreg Ungerer
19418cb3fafSGreg Ungererinthandler7:
19518cb3fafSGreg Ungerer	SAVE_ALL_INT
19618cb3fafSGreg Ungerer	movew	%sp@(PT_OFF_FORMATVEC), %d0
19718cb3fafSGreg Ungerer	and	#0x3ff, %d0
19818cb3fafSGreg Ungerer
19918cb3fafSGreg Ungerer	movel	%sp,%sp@-
20018cb3fafSGreg Ungerer	movel	#71,%sp@- 		/*  put vector # on stack*/
20118cb3fafSGreg Ungerer	jbsr	process_int		/*  process the IRQ*/
20218cb3fafSGreg Ungerer3:     	addql	#8,%sp			/*  pop parameters off stack*/
20318cb3fafSGreg Ungerer	bra	ret_from_exception
20418cb3fafSGreg Ungerer
20518cb3fafSGreg Ungererinthandler:
20618cb3fafSGreg Ungerer	SAVE_ALL_INT
20718cb3fafSGreg Ungerer	movew	%sp@(PT_OFF_FORMATVEC), %d0
20818cb3fafSGreg Ungerer	and	#0x3ff, %d0
20918cb3fafSGreg Ungerer
21018cb3fafSGreg Ungerer	movel	%sp,%sp@-
21118cb3fafSGreg Ungerer	movel	%d0,%sp@- 		/*  put vector # on stack*/
21218cb3fafSGreg Ungerer	jbsr	process_int		/*  process the IRQ*/
21318cb3fafSGreg Ungerer3:     	addql	#8,%sp			/*  pop parameters off stack*/
21418cb3fafSGreg Ungerer	bra	ret_from_exception
21518cb3fafSGreg Ungerer
21618cb3fafSGreg Ungerer/*
21718cb3fafSGreg Ungerer * Handler for uninitialized and spurious interrupts.
21818cb3fafSGreg Ungerer */
21918cb3fafSGreg UngererENTRY(bad_interrupt)
22018cb3fafSGreg Ungerer	addql	#1,irq_err_count
22118cb3fafSGreg Ungerer	rte
22218cb3fafSGreg Ungerer
22318cb3fafSGreg Ungerer/*
22418cb3fafSGreg Ungerer * Beware - when entering resume, prev (the current task) is
22518cb3fafSGreg Ungerer * in a0, next (the new task) is in a1, so don't change these
22618cb3fafSGreg Ungerer * registers until their contents are no longer needed.
22718cb3fafSGreg Ungerer */
22818cb3fafSGreg UngererENTRY(resume)
22918cb3fafSGreg Ungerer	movel	%a0,%d1				/* save prev thread in d1 */
23018cb3fafSGreg Ungerer	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)	/* save sr */
23118cb3fafSGreg Ungerer	SAVE_SWITCH_STACK
23218cb3fafSGreg Ungerer	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
23318cb3fafSGreg Ungerer	movel	%usp,%a3			/* save usp */
23418cb3fafSGreg Ungerer	movel	%a3,%a0@(TASK_THREAD+THREAD_USP)
23518cb3fafSGreg Ungerer
23618cb3fafSGreg Ungerer	movel	%a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */
23718cb3fafSGreg Ungerer	movel	%a3,%usp
23818cb3fafSGreg Ungerer	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
23918cb3fafSGreg Ungerer	RESTORE_SWITCH_STACK
24018cb3fafSGreg Ungerer	movew	%a1@(TASK_THREAD+THREAD_SR),%sr	/* restore thread status reg */
24118cb3fafSGreg Ungerer	rts
24218cb3fafSGreg Ungerer
243