GNU Linux-libre 4.14.313-gnu1
[releases.git] / arch / m68k / 68000 / entry.S
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 ret_from_signal
29 .globl sys_call_table
30 .globl bad_interrupt
31 .globl inthandler1
32 .globl inthandler2
33 .globl inthandler3
34 .globl inthandler4
35 .globl inthandler5
36 .globl inthandler6
37 .globl inthandler7
38
39 badsys:
40         movel   #-ENOSYS,%sp@(PT_OFF_D0)
41         jra     ret_from_exception
42
43 do_trace:
44         movel   #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
45         subql   #4,%sp
46         SAVE_SWITCH_STACK
47         jbsr    syscall_trace_enter
48         RESTORE_SWITCH_STACK
49         addql   #4,%sp
50         addql   #1,%d0
51         jeq     ret_from_exception
52         movel   %sp@(PT_OFF_ORIG_D0),%d1
53         movel   #-ENOSYS,%d0
54         cmpl    #NR_syscalls,%d1
55         jcc     1f
56         lsl     #2,%d1
57         lea     sys_call_table, %a0
58         jbsr    %a0@(%d1)
59
60 1:      movel   %d0,%sp@(PT_OFF_D0)     /* save the return value */
61         subql   #4,%sp                  /* dummy return address */
62         SAVE_SWITCH_STACK
63         jbsr    syscall_trace_leave
64
65 ret_from_signal:
66         RESTORE_SWITCH_STACK
67         addql   #4,%sp
68         jra     ret_from_exception
69
70 ENTRY(system_call)
71         SAVE_ALL_SYS
72
73         /* save top of frame*/
74         pea     %sp@
75         jbsr    set_esp0
76         addql   #4,%sp
77
78         movel   %sp@(PT_OFF_ORIG_D0),%d0
79
80         movel   %sp,%d1                 /* get thread_info pointer */
81         andl    #-THREAD_SIZE,%d1
82         movel   %d1,%a2
83         btst    #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
84         jne     do_trace
85         cmpl    #NR_syscalls,%d0
86         jcc     badsys
87         lsl     #2,%d0
88         lea     sys_call_table,%a0
89         movel   %a0@(%d0), %a0
90         jbsr    %a0@
91         movel   %d0,%sp@(PT_OFF_D0)     /* save the return value*/
92
93 ret_from_exception:
94         btst    #5,%sp@(PT_OFF_SR)      /* check if returning to kernel*/
95         jeq     Luser_return            /* if so, skip resched, signals*/
96
97 Lkernel_return:
98         RESTORE_ALL
99
100 Luser_return:
101         /* only allow interrupts when we are really the last one on the*/
102         /* kernel stack, otherwise stack overflow can occur during*/
103         /* heavy interrupt load*/
104         andw    #ALLOWINT,%sr
105
106         movel   %sp,%d1                 /* get thread_info pointer */
107         andl    #-THREAD_SIZE,%d1
108         movel   %d1,%a2
109 1:
110         move    %a2@(TINFO_FLAGS),%d1   /* thread_info->flags */
111         jne     Lwork_to_do
112         RESTORE_ALL
113
114 Lwork_to_do:
115         movel   %a2@(TINFO_FLAGS),%d1   /* thread_info->flags */
116         btst    #TIF_NEED_RESCHED,%d1
117         jne     reschedule
118
119 Lsignal_return:
120         subql   #4,%sp                  /* dummy return address*/
121         SAVE_SWITCH_STACK
122         pea     %sp@(SWITCH_STACK_SIZE)
123         bsrw    do_notify_resume
124         addql   #4,%sp
125         RESTORE_SWITCH_STACK
126         addql   #4,%sp
127         jra     1b
128
129 /*
130  * This is the main interrupt handler, responsible for calling process_int()
131  */
132 inthandler1:
133         SAVE_ALL_INT
134         movew   %sp@(PT_OFF_FORMATVEC), %d0
135         and     #0x3ff, %d0
136
137         movel   %sp,%sp@-
138         movel   #65,%sp@-               /*  put vector # on stack*/
139         jbsr    process_int             /*  process the IRQ*/
140 3:      addql   #8,%sp                  /*  pop parameters off stack*/
141         bra     ret_from_exception
142
143 inthandler2:
144         SAVE_ALL_INT
145         movew   %sp@(PT_OFF_FORMATVEC), %d0
146         and     #0x3ff, %d0
147
148         movel   %sp,%sp@-
149         movel   #66,%sp@-               /*  put vector # on stack*/
150         jbsr    process_int             /*  process the IRQ*/
151 3:      addql   #8,%sp                  /*  pop parameters off stack*/
152         bra     ret_from_exception
153
154 inthandler3:
155         SAVE_ALL_INT
156         movew   %sp@(PT_OFF_FORMATVEC), %d0
157         and     #0x3ff, %d0
158
159         movel   %sp,%sp@-
160         movel   #67,%sp@-               /*  put vector # on stack*/
161         jbsr    process_int             /*  process the IRQ*/
162 3:      addql   #8,%sp                  /*  pop parameters off stack*/
163         bra     ret_from_exception
164
165 inthandler4:
166         SAVE_ALL_INT
167         movew   %sp@(PT_OFF_FORMATVEC), %d0
168         and     #0x3ff, %d0
169
170         movel   %sp,%sp@-
171         movel   #68,%sp@-               /*  put vector # on stack*/
172         jbsr    process_int             /*  process the IRQ*/
173 3:      addql   #8,%sp                  /*  pop parameters off stack*/
174         bra     ret_from_exception
175
176 inthandler5:
177         SAVE_ALL_INT
178         movew   %sp@(PT_OFF_FORMATVEC), %d0
179         and     #0x3ff, %d0
180
181         movel   %sp,%sp@-
182         movel   #69,%sp@-               /*  put vector # on stack*/
183         jbsr    process_int             /*  process the IRQ*/
184 3:      addql   #8,%sp                  /*  pop parameters off stack*/
185         bra     ret_from_exception
186
187 inthandler6:
188         SAVE_ALL_INT
189         movew   %sp@(PT_OFF_FORMATVEC), %d0
190         and     #0x3ff, %d0
191
192         movel   %sp,%sp@-
193         movel   #70,%sp@-               /*  put vector # on stack*/
194         jbsr    process_int             /*  process the IRQ*/
195 3:      addql   #8,%sp                  /*  pop parameters off stack*/
196         bra     ret_from_exception
197
198 inthandler7:
199         SAVE_ALL_INT
200         movew   %sp@(PT_OFF_FORMATVEC), %d0
201         and     #0x3ff, %d0
202
203         movel   %sp,%sp@-
204         movel   #71,%sp@-               /*  put vector # on stack*/
205         jbsr    process_int             /*  process the IRQ*/
206 3:      addql   #8,%sp                  /*  pop parameters off stack*/
207         bra     ret_from_exception
208
209 inthandler:
210         SAVE_ALL_INT
211         movew   %sp@(PT_OFF_FORMATVEC), %d0
212         and     #0x3ff, %d0
213
214         movel   %sp,%sp@-
215         movel   %d0,%sp@-               /*  put vector # on stack*/
216         jbsr    process_int             /*  process the IRQ*/
217 3:      addql   #8,%sp                  /*  pop parameters off stack*/
218         bra     ret_from_exception
219
220 /*
221  * Handler for uninitialized and spurious interrupts.
222  */
223 ENTRY(bad_interrupt)
224         addql   #1,irq_err_count
225         rte
226
227 /*
228  * Beware - when entering resume, prev (the current task) is
229  * in a0, next (the new task) is in a1, so don't change these
230  * registers until their contents are no longer needed.
231  */
232 ENTRY(resume)
233         movel   %a0,%d1                         /* save prev thread in d1 */
234         movew   %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */
235         SAVE_SWITCH_STACK
236         movel   %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
237         movel   %usp,%a3                        /* save usp */
238         movel   %a3,%a0@(TASK_THREAD+THREAD_USP)
239
240         movel   %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */
241         movel   %a3,%usp
242         movel   %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
243         RESTORE_SWITCH_STACK
244         movew   %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */
245         rts
246