f7bc80a60e0fe645ea6faa8a4e2cb6ceb5eb48f4
[pandora-kernel.git] / arch / m68knommu / platform / 68360 / entry.S
1 /*
2  *  linux/arch/m68knommu/platform/68360/entry.S
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *  Copyright (C) 2001 SED Systems, a Division of Calian Ltd.
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License.  See the file README.legal in the main directory of this archive
9  * for more details.
10  *
11  * Linux/m68k support by Hamish Macdonald
12  * M68360 Port by SED Systems, and Lineo.
13  */
14
15 #include <linux/config.h>
16 #include <linux/sys.h>
17 #include <linux/linkage.h>
18 #include <asm/thread_info.h>
19 #include <asm/unistd.h>
20 #include <asm/errno.h>
21 #include <asm/setup.h>
22 #include <asm/segment.h>
23 #include <asm/traps.h>
24 #include <asm/asm-offsets.h>
25 #include <asm/entry.h>
26
27 .text
28
29 .globl system_call
30 .globl resume
31 .globl ret_from_exception
32 .globl ret_from_signal
33 .globl sys_call_table
34 .globl ret_from_interrupt
35 .globl bad_interrupt
36 .globl inthandler
37
38 badsys:
39         movel   #-ENOSYS,%sp@(PT_D0)
40         jra     ret_from_exception
41
42 do_trace:
43         movel   #-ENOSYS,%sp@(PT_D0)    /* needed for strace*/
44         subql   #4,%sp
45         SAVE_SWITCH_STACK
46         jbsr    syscall_trace
47         RESTORE_SWITCH_STACK
48         addql   #4,%sp
49         movel   %sp@(PT_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
57 1:      movel   %d0,%sp@(PT_D0)         /* save the return value */
58         subql   #4,%sp                  /* dummy return address */
59         SAVE_SWITCH_STACK
60         jbsr    syscall_trace
61
62 ret_from_signal:
63         RESTORE_SWITCH_STACK
64         addql   #4,%sp
65         jra     ret_from_exception
66
67 ENTRY(system_call)
68         SAVE_ALL
69
70         /* save top of frame*/
71         pea     %sp@
72         jbsr    set_esp0
73         addql   #4,%sp
74
75         btst    #PF_TRACESYS_BIT,%a2@(TASK_FLAGS+PF_TRACESYS_OFF)
76         jne     do_trace
77         cmpl    #NR_syscalls,%d0
78         jcc     badsys
79         lsl     #2,%d0
80         lea     sys_call_table,%a0
81         movel   %a0@(%d0), %a0
82         jbsr    %a0@
83         movel   %d0,%sp@(PT_D0)         /* save the return value*/
84
85 ret_from_exception:
86         btst    #5,%sp@(PT_SR)          /* check if returning to kernel*/
87         jeq     Luser_return            /* if so, skip resched, signals*/
88
89 Lkernel_return:
90         RESTORE_ALL
91
92 Luser_return:
93         /* only allow interrupts when we are really the last one on the*/
94         /* kernel stack, otherwise stack overflow can occur during*/
95         /* heavy interrupt load*/
96         andw    #ALLOWINT,%sr
97
98         movel   %sp,%d1                 /* get thread_info pointer */
99         andl    #0xffffe000,%d1
100         movel   %d1,%a2
101         move    %a2@(TI_FLAGS),%d1      /* thread_info->flags */
102         andl    #_TIF_WORK_MASK,%d1
103         jne     Lwork_to_do
104         RESTORE_ALL
105
106 Lwork_to_do:
107         movel   %a2@(TI_FLAGS),%d1      /* thread_info->flags */
108         btst    #TIF_NEED_RESCHED,%d1
109         jne     reschedule
110
111 Lsignal_return:
112         subql   #4,%sp                  /* dummy return address*/
113         SAVE_SWITCH_STACK
114         pea     %sp@(SWITCH_STACK_SIZE)
115         clrl    %sp@-
116         bsrw    do_signal
117         addql   #8,%sp
118         RESTORE_SWITCH_STACK
119         addql   #4,%sp
120 Lreturn:
121         RESTORE_ALL
122
123 /*
124  * This is the main interrupt handler, responsible for calling process_int()
125  */
126 inthandler:
127         SAVE_ALL
128         addql   #1,local_irq_count      /*  put exception # in d0*/
129         movew   %sp@(PT_VECTOR), %d0
130         and.l   #0x3ff, %d0
131         lsr.l   #0x02,  %d0
132
133         movel   %sp,%sp@-
134         movel   %d0,%sp@-               /*  put vector # on stack*/
135         jbsr    process_int             /*  process the IRQ*/
136 3:      addql   #8,%sp                  /*  pop parameters off stack*/
137         bra     ret_from_interrupt
138
139 ret_from_interrupt:
140         subql   #1,local_irq_count
141         jeq     1f
142 2:
143         RESTORE_ALL
144 1:
145         moveb   %sp@(PT_SR), %d0
146         and     #7, %d0
147         jhi     2b
148         /* check if we need to do software interrupts */
149
150         movel   irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
151         jeq     ret_from_exception
152
153         pea     ret_from_exception
154         jra     do_softirq
155
156
157 /*
158  * Handler for uninitialized and spurious interrupts.
159  */
160 bad_interrupt:
161         addql   #1,num_spurious
162         rte
163
164 /*
165  * Beware - when entering resume, prev (the current task) is
166  * in a0, next (the new task) is in a1,so don't change these
167  * registers until their contents are no longer needed.
168  */
169 ENTRY(resume)
170         movel   %a0,%d1                         /* save prev thread in d1 */
171         movew   %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */
172         movel   %usp,%a2                        /* save usp */
173         movel   %a2,%a0@(TASK_THREAD+THREAD_USP)
174
175         SAVE_SWITCH_STACK
176         movel   %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
177         movel   %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
178         RESTORE_SWITCH_STACK
179
180         movel   %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore user stack */
181         movel   %a0,%usp
182         movew   %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */
183         rts
184