xref: /openbmc/linux/arch/m68k/68000/entry.S (revision 0d20abde)
1/*
2 *  entry.S -- non-mmu 68000 interrupt and exception entry points
3 *
4 *  Copyright (C) 1991, 1992  Linus Torvalds
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License.  See the file README.legal in the main directory of this archive
8 * for more details.
9 *
10 * Linux/m68k support by Hamish Macdonald
11 */
12
13#include <linux/linkage.h>
14#include <asm/thread_info.h>
15#include <asm/unistd.h>
16#include <asm/errno.h>
17#include <asm/setup.h>
18#include <asm/segment.h>
19#include <asm/traps.h>
20#include <asm/asm-offsets.h>
21#include <asm/entry.h>
22
23.text
24
25.globl system_call
26.globl resume
27.globl ret_from_exception
28.globl sys_call_table
29.globl bad_interrupt
30.globl inthandler1
31.globl inthandler2
32.globl inthandler3
33.globl inthandler4
34.globl inthandler5
35.globl inthandler6
36.globl inthandler7
37
38badsys:
39	movel	#-ENOSYS,%sp@(PT_OFF_D0)
40	jra	ret_from_exception
41
42do_trace:
43	movel	#-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
44	subql	#4,%sp
45	SAVE_SWITCH_STACK
46	jbsr	syscall_trace_enter
47	RESTORE_SWITCH_STACK
48	addql	#4,%sp
49	movel	%sp@(PT_OFF_ORIG_D0),%d1
50	movel	#-ENOSYS,%d0
51	cmpl	#NR_syscalls,%d1
52	jcc	1f
53	lsl	#2,%d1
54	lea	sys_call_table, %a0
55	jbsr	%a0@(%d1)
56
571:	movel	%d0,%sp@(PT_OFF_D0)	/* save the return value */
58	subql	#4,%sp			/* dummy return address */
59	SAVE_SWITCH_STACK
60	jbsr	syscall_trace_leave
61	RESTORE_SWITCH_STACK
62	addql	#4,%sp
63	jra	ret_from_exception
64
65ENTRY(system_call)
66	SAVE_ALL_SYS
67
68	/* save top of frame*/
69	pea	%sp@
70	jbsr	set_esp0
71	addql	#4,%sp
72
73	movel	%sp@(PT_OFF_ORIG_D0),%d0
74
75	movel	%sp,%d1			/* get thread_info pointer */
76	andl	#-THREAD_SIZE,%d1
77	movel	%d1,%a2
78	btst	#(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
79	jne	do_trace
80	cmpl	#NR_syscalls,%d0
81	jcc	badsys
82	lsl	#2,%d0
83	lea	sys_call_table,%a0
84	movel	%a0@(%d0), %a0
85	jbsr	%a0@
86	movel	%d0,%sp@(PT_OFF_D0)	/* save the return value*/
87
88ret_from_exception:
89	btst	#5,%sp@(PT_OFF_SR)	/* check if returning to kernel*/
90	jeq	Luser_return		/* if so, skip resched, signals*/
91
92Lkernel_return:
93	RESTORE_ALL
94
95Luser_return:
96	/* only allow interrupts when we are really the last one on the*/
97	/* kernel stack, otherwise stack overflow can occur during*/
98	/* heavy interrupt load*/
99	andw	#ALLOWINT,%sr
100
101	movel	%sp,%d1			/* get thread_info pointer */
102	andl	#-THREAD_SIZE,%d1
103	movel	%d1,%a2
1041:
105	move	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
106	jne	Lwork_to_do
107	RESTORE_ALL
108
109Lwork_to_do:
110	movel	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
111	btst	#TIF_NEED_RESCHED,%d1
112	jne	reschedule
113
114Lsignal_return:
115	subql	#4,%sp			/* dummy return address*/
116	SAVE_SWITCH_STACK
117	pea	%sp@(SWITCH_STACK_SIZE)
118	bsrw	do_notify_resume
119	addql	#4,%sp
120	RESTORE_SWITCH_STACK
121	addql	#4,%sp
122	jra	1b
123
124/*
125 * This is the main interrupt handler, responsible for calling process_int()
126 */
127inthandler1:
128	SAVE_ALL_INT
129	movew	%sp@(PT_OFF_FORMATVEC), %d0
130	and	#0x3ff, %d0
131
132	movel	%sp,%sp@-
133	movel	#65,%sp@- 		/*  put vector # on stack*/
134	jbsr	process_int		/*  process the IRQ*/
1353:     	addql	#8,%sp			/*  pop parameters off stack*/
136	bra	ret_from_exception
137
138inthandler2:
139	SAVE_ALL_INT
140	movew	%sp@(PT_OFF_FORMATVEC), %d0
141	and	#0x3ff, %d0
142
143	movel	%sp,%sp@-
144	movel	#66,%sp@- 		/*  put vector # on stack*/
145	jbsr	process_int		/*  process the IRQ*/
1463:     	addql	#8,%sp			/*  pop parameters off stack*/
147	bra	ret_from_exception
148
149inthandler3:
150	SAVE_ALL_INT
151	movew	%sp@(PT_OFF_FORMATVEC), %d0
152	and	#0x3ff, %d0
153
154	movel	%sp,%sp@-
155	movel	#67,%sp@- 		/*  put vector # on stack*/
156	jbsr	process_int		/*  process the IRQ*/
1573:     	addql	#8,%sp			/*  pop parameters off stack*/
158	bra	ret_from_exception
159
160inthandler4:
161	SAVE_ALL_INT
162	movew	%sp@(PT_OFF_FORMATVEC), %d0
163	and	#0x3ff, %d0
164
165	movel	%sp,%sp@-
166	movel	#68,%sp@- 		/*  put vector # on stack*/
167	jbsr	process_int		/*  process the IRQ*/
1683:     	addql	#8,%sp			/*  pop parameters off stack*/
169	bra	ret_from_exception
170
171inthandler5:
172	SAVE_ALL_INT
173	movew	%sp@(PT_OFF_FORMATVEC), %d0
174	and	#0x3ff, %d0
175
176	movel	%sp,%sp@-
177	movel	#69,%sp@- 		/*  put vector # on stack*/
178	jbsr	process_int		/*  process the IRQ*/
1793:     	addql	#8,%sp			/*  pop parameters off stack*/
180	bra	ret_from_exception
181
182inthandler6:
183	SAVE_ALL_INT
184	movew	%sp@(PT_OFF_FORMATVEC), %d0
185	and	#0x3ff, %d0
186
187	movel	%sp,%sp@-
188	movel	#70,%sp@- 		/*  put vector # on stack*/
189	jbsr	process_int		/*  process the IRQ*/
1903:     	addql	#8,%sp			/*  pop parameters off stack*/
191	bra	ret_from_exception
192
193inthandler7:
194	SAVE_ALL_INT
195	movew	%sp@(PT_OFF_FORMATVEC), %d0
196	and	#0x3ff, %d0
197
198	movel	%sp,%sp@-
199	movel	#71,%sp@- 		/*  put vector # on stack*/
200	jbsr	process_int		/*  process the IRQ*/
2013:     	addql	#8,%sp			/*  pop parameters off stack*/
202	bra	ret_from_exception
203
204inthandler:
205	SAVE_ALL_INT
206	movew	%sp@(PT_OFF_FORMATVEC), %d0
207	and	#0x3ff, %d0
208
209	movel	%sp,%sp@-
210	movel	%d0,%sp@- 		/*  put vector # on stack*/
211	jbsr	process_int		/*  process the IRQ*/
2123:     	addql	#8,%sp			/*  pop parameters off stack*/
213	bra	ret_from_exception
214
215/*
216 * Handler for uninitialized and spurious interrupts.
217 */
218ENTRY(bad_interrupt)
219	addql	#1,irq_err_count
220	rte
221
222/*
223 * Beware - when entering resume, prev (the current task) is
224 * in a0, next (the new task) is in a1, so don't change these
225 * registers until their contents are no longer needed.
226 */
227ENTRY(resume)
228	movel	%a0,%d1				/* save prev thread in d1 */
229	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)	/* save sr */
230	SAVE_SWITCH_STACK
231	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
232	movel	%usp,%a3			/* save usp */
233	movel	%a3,%a0@(TASK_THREAD+THREAD_USP)
234
235	movel	%a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */
236	movel	%a3,%usp
237	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
238	RESTORE_SWITCH_STACK
239	movew	%a1@(TASK_THREAD+THREAD_SR),%sr	/* restore thread status reg */
240	rts
241
242