Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / arch / m68knommu / platform / 68328 / entry.S
1 /*
2  *  linux/arch/m68knommu/platform/68328/entry.S
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/sys.h>
14 #include <linux/linkage.h>
15 #include <asm/thread_info.h>
16 #include <asm/unistd.h>
17 #include <asm/errno.h>
18 #include <asm/setup.h>
19 #include <asm/segment.h>
20 #include <asm/traps.h>
21 #include <asm/asm-offsets.h>
22 #include <asm/entry.h>
23
24 .text
25
26 .globl system_call
27 .globl resume
28 .globl ret_from_exception
29 .globl ret_from_signal
30 .globl sys_call_table
31 .globl ret_from_interrupt
32 .globl bad_interrupt
33 .globl inthandler1
34 .globl inthandler2
35 .globl inthandler3
36 .globl inthandler4
37 .globl inthandler5
38 .globl inthandler6
39 .globl inthandler7
40
41 badsys:
42         movel   #-ENOSYS,%sp@(PT_D0)
43         jra     ret_from_exception
44
45 do_trace:
46         movel   #-ENOSYS,%sp@(PT_D0)    /* needed for strace*/
47         subql   #4,%sp
48         SAVE_SWITCH_STACK
49         jbsr    syscall_trace
50         RESTORE_SWITCH_STACK
51         addql   #4,%sp
52         movel   %sp@(PT_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_D0)         /* save the return value */
61         subql   #4,%sp                  /* dummy return address */
62         SAVE_SWITCH_STACK
63         jbsr    syscall_trace
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
72
73         /* save top of frame*/
74         pea     %sp@
75         jbsr    set_esp0
76         addql   #4,%sp
77
78         movel   %sp@(PT_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,%a2@(TI_FLAGS)
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_D0)         /* save the return value*/
92
93 ret_from_exception:
94         btst    #5,%sp@(PT_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         move    %a2@(TI_FLAGS),%d1      /* thread_info->flags */
110         andl    #_TIF_WORK_MASK,%d1
111         jne     Lwork_to_do
112         RESTORE_ALL
113
114 Lwork_to_do:
115         movel   %a2@(TI_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         clrl    %sp@-
124         bsrw    do_signal
125         addql   #8,%sp
126         RESTORE_SWITCH_STACK
127         addql   #4,%sp
128 Lreturn:
129         RESTORE_ALL
130
131 /*
132  * This is the main interrupt handler, responsible for calling process_int()
133  */
134 inthandler1:
135         SAVE_ALL
136         addql   #1,local_irq_count      /*  put exception # in d0*/
137         movew   %sp@(PT_VECTOR), %d0
138         and     #0x3ff, %d0
139
140         movel   %sp,%sp@-
141         movel   #65,%sp@-               /*  put vector # on stack*/
142         jbsr    process_int             /*  process the IRQ*/
143 3:      addql   #8,%sp                  /*  pop parameters off stack*/
144         bra     ret_from_interrupt
145
146 inthandler2:
147         SAVE_ALL
148         addql   #1,local_irq_count      /*  put exception # in d0*/
149         movew   %sp@(PT_VECTOR), %d0
150         and     #0x3ff, %d0
151
152         movel   %sp,%sp@-
153         movel   #66,%sp@-               /*  put vector # on stack*/
154         jbsr    process_int             /*  process the IRQ*/
155 3:      addql   #8,%sp                  /*  pop parameters off stack*/
156         bra     ret_from_interrupt
157
158 inthandler3:
159         SAVE_ALL
160         addql   #1,local_irq_count      /*  put exception # in d0*/
161         movew   %sp@(PT_VECTOR), %d0
162         and     #0x3ff, %d0
163
164         movel   %sp,%sp@-
165         movel   #67,%sp@-               /*  put vector # on stack*/
166         jbsr    process_int             /*  process the IRQ*/
167 3:      addql   #8,%sp                  /*  pop parameters off stack*/
168         bra     ret_from_interrupt
169
170 inthandler4:
171         SAVE_ALL
172         addql   #1,local_irq_count      /*  put exception # in d0*/
173         movew   %sp@(PT_VECTOR), %d0
174         and     #0x3ff, %d0
175
176         movel   %sp,%sp@-
177         movel   #68,%sp@-               /*  put vector # on stack*/
178         jbsr    process_int             /*  process the IRQ*/
179 3:      addql   #8,%sp                  /*  pop parameters off stack*/
180         bra     ret_from_interrupt
181
182 inthandler5:
183         SAVE_ALL
184         addql   #1,local_irq_count      /*  put exception # in d0*/
185         movew   %sp@(PT_VECTOR), %d0
186         and     #0x3ff, %d0
187
188         movel   %sp,%sp@-
189         movel   #69,%sp@-               /*  put vector # on stack*/
190         jbsr    process_int             /*  process the IRQ*/
191 3:      addql   #8,%sp                  /*  pop parameters off stack*/
192         bra     ret_from_interrupt
193
194 inthandler6:
195         SAVE_ALL
196         addql   #1,local_irq_count      /*  put exception # in d0*/
197         movew   %sp@(PT_VECTOR), %d0
198         and     #0x3ff, %d0
199
200         movel   %sp,%sp@-
201         movel   #70,%sp@-               /*  put vector # on stack*/
202         jbsr    process_int             /*  process the IRQ*/
203 3:      addql   #8,%sp                  /*  pop parameters off stack*/
204         bra     ret_from_interrupt
205
206 inthandler7:
207         SAVE_ALL
208         addql   #1,local_irq_count      /*  put exception # in d0*/
209         movew   %sp@(PT_VECTOR), %d0
210         and     #0x3ff, %d0
211
212         movel   %sp,%sp@-
213         movel   #71,%sp@-               /*  put vector # on stack*/
214         jbsr    process_int             /*  process the IRQ*/
215 3:      addql   #8,%sp                  /*  pop parameters off stack*/
216         bra     ret_from_interrupt
217
218 inthandler:
219         SAVE_ALL
220         addql   #1,local_irq_count      /*  put exception # in d0*/
221         movew   %sp@(PT_VECTOR), %d0
222         and     #0x3ff, %d0
223
224         movel   %sp,%sp@-
225         movel   %d0,%sp@-               /*  put vector # on stack*/
226         jbsr    process_int             /*  process the IRQ*/
227 3:      addql   #8,%sp                  /*  pop parameters off stack*/
228         bra     ret_from_interrupt
229
230 ret_from_interrupt:
231         subql   #1,local_irq_count
232         jeq     1f
233 2:
234         RESTORE_ALL
235 1:
236         moveb   %sp@(PT_SR), %d0
237         and     #7, %d0
238         jhi     2b
239
240         /* check if we need to do software interrupts */
241         movel   local_irq_count,%d0
242         jeq     ret_from_exception
243
244         pea     ret_from_exception
245         jra     do_softirq
246
247
248 /*
249  * Handler for uninitialized and spurious interrupts.
250  */
251 ENTRY(bad_interrupt)
252         addql   #1,num_spurious
253         rte
254
255 /*
256  * Beware - when entering resume, prev (the current task) is
257  * in a0, next (the new task) is in a1,so don't change these
258  * registers until their contents are no longer needed.
259  */
260 ENTRY(resume)
261         movel   %a0,%d1                         /* save prev thread in d1 */
262         movew   %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */
263         movel   %usp,%a2                        /* save usp */
264         movel   %a2,%a0@(TASK_THREAD+THREAD_USP)
265
266         SAVE_SWITCH_STACK
267         movel   %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
268         movel   %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
269         RESTORE_SWITCH_STACK
270
271         movel   %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore user stack */
272         movel   %a0,%usp
273         movew   %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */
274         rts
275