Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[linux-2.6] / arch / h8300 / platform / h8s / entry.S
1 /* -*- mode: asm -*-
2  *
3  *  linux/arch/h8300/platform/h8s/entry.S
4  *
5  *  Yoshinori Sato <ysato@users.sourceforge.jp>
6  *
7  *      fairly heavy changes to fix syscall args and signal processing
8  *      by David McCullough <davidm@snapgear.com>
9  */
10
11 /*
12  *  entry.S
13  *  include exception/interrupt gateway
14  *          system call entry
15  */
16
17 #include <linux/sys.h>
18 #include <asm/unistd.h>
19 #include <asm/setup.h>
20 #include <asm/segment.h>
21 #include <asm/linkage.h>
22 #include <asm/asm-offsets.h>
23 #include <asm/thread_info.h>
24 #include <asm/errno.h>
25
26         .h8300s
27
28 /* CPU context save/restore macros. */
29         
30         .macro  SAVE_ALL
31         mov.l   er0,@-sp
32
33         stc     ccr,r0l                         /* check kernel mode */
34         orc     #0x10,ccr
35         btst    #4,r0l
36         bne     5f
37
38         mov.l   sp,@SYMBOL_NAME(sw_usp)         /* user mode */
39         mov.l   @sp,er0
40         mov.l   @SYMBOL_NAME(sw_ksp),sp
41         sub.l   #(LRET-LORIG),sp                /* allocate LORIG - LRET */ 
42         stm.l   er0-er3,@-sp
43         mov.l   @SYMBOL_NAME(sw_usp),er0
44         mov.l   @(10:16,er0),er1                /* copy the RET addr */
45         mov.l   er1,@(LRET-LER3:16,sp)
46         mov.w   @(8:16,er0),r1
47         mov.w   r1,@(LEXR-LER3:16,sp)           /* copy EXR */
48
49         mov.w   e1,r1                           /* e1 highbyte = ccr */
50         and     #0xef,r1h                       /* mask mode? flag */
51         sub.w   r0,r0
52         mov.b   r1h,r0l
53         mov.w   r0,@(LCCR-LER3:16,sp)           /* copy ccr */
54         mov.l   @(LORIG-LER3:16,sp),er0
55         mov.l   er0,@(LER0-LER3:16,sp)          /* copy ER0 */
56         bra     6f
57 5:
58         mov.l   @sp,er0                         /* kernel mode */
59         subs    #2,sp                           /* dummy ccr */
60         stm.l   er0-er3,@-sp
61         mov.w   @(LRET-LER3:16,sp),r1           /* copy old ccr */
62         mov.b   r1h,r1l
63         mov.b   #0,r1h
64         mov.w   r1,@(LCCR-LER3:16,sp)
65 6:      
66         mov.l   er6,@-sp                        /* syscall arg #6 */
67         mov.l   er5,@-sp                        /* syscall arg #5 */
68         mov.l   er4,@-sp                        /* syscall arg #4 */
69         .endm
70
71         .macro  RESTORE_ALL
72         mov.l   @sp+,er4
73         mov.l   @sp+,er5
74         mov.l   @sp+,er6
75         ldm.l   @sp+,er2-er3
76         mov.w   @(LCCR-LER1:16,sp),r0           /* check kernel mode */
77         btst    #4,r0l
78         bne     7f
79
80         orc     #0x80,ccr
81         mov.l   @SYMBOL_NAME(sw_usp),er0
82         mov.l   @(LER0-LER1:16,sp),er1          /* restore ER0 */
83         mov.l   er1,@er0
84         mov.w   @(LEXR-LER1:16,sp),r1           /* restore EXR */
85         mov.b   r1l,r1h
86         mov.w   r1,@(8:16,er0)
87         mov.w   @(LCCR-LER1:16,sp),r1           /* restore the RET addr */
88         mov.b   r1l,r1h
89         mov.b   @(LRET+1-LER1:16,sp),r1l
90         mov.w   r1,e1
91         mov.w   @(LRET+2-LER1:16,sp),r1
92         mov.l   er1,@(10:16,er0)
93
94         mov.l   @sp+,er1
95         add.l   #(LRET-LER1),sp                 /* remove LORIG - LRET */ 
96         mov.l   sp,@SYMBOL_NAME(sw_ksp)
97         mov.l   er0,sp
98         bra     8f
99 7:
100         mov.l   @sp+,er1
101         adds    #4,sp
102         adds    #2,sp
103 8:
104         mov.l   @sp+,er0
105         adds    #4,sp                           /* remove the sw created LVEC */
106         rte
107         .endm
108         
109 .globl SYMBOL_NAME(system_call)
110 .globl SYMBOL_NAME(ret_from_exception)
111 .globl SYMBOL_NAME(ret_from_fork)
112 .globl SYMBOL_NAME(ret_from_interrupt)
113 .globl SYMBOL_NAME(interrupt_redirect_table)
114 .globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
115 .globl SYMBOL_NAME(resume)
116 .globl SYMBOL_NAME(trace_break)
117 .globl SYMBOL_NAME(interrupt_entry)
118                 
119 INTERRUPTS = 128
120 #if defined(CONFIG_ROMKERNEL)
121         .section .int_redirect,"ax"
122 SYMBOL_NAME_LABEL(interrupt_redirect_table)
123         .rept   7
124         .long   0
125         .endr
126         jsr     @SYMBOL_NAME(interrupt_entry)   /* NMI */
127         jmp     @SYMBOL_NAME(system_call)       /* TRAPA #0 (System call) */
128         .long   0
129         .long   0
130         jmp     @SYMBOL_NAME(trace_break)       /* TRAPA #3 (breakpoint) */
131         .rept   INTERRUPTS-12
132         jsr     @SYMBOL_NAME(interrupt_entry)
133         .endr
134 #endif
135 #if defined(CONFIG_RAMKERNEL)
136 .globl SYMBOL_NAME(interrupt_redirect_table)
137         .section .bss
138 SYMBOL_NAME_LABEL(interrupt_redirect_table)
139         .space  4
140 #endif
141         
142         .section .text
143         .align  2
144 SYMBOL_NAME_LABEL(interrupt_entry)
145         SAVE_ALL
146         mov.w   @(LCCR,sp),r0
147         btst    #4,r0l
148         bne     1f
149         mov.l   @SYMBOL_NAME(sw_usp),er0
150         mov.l   @(4:16,er0),er0
151         bra     2f
152 1:
153         mov.l   @(LVEC:16,sp),er0
154 2:
155 #if defined(CONFIG_ROMKERNEL)
156         sub.l   #SYMBOL_NAME(interrupt_redirect_table),er0
157 #endif
158 #if defined(CONFIG_RAMKERNEL)
159         mov.l   @SYMBOL_NAME(interrupt_redirect_table),er1
160         sub.l   er1,er0
161 #endif
162         shlr.l  #2,er0
163         dec.l   #1,er0
164         mov.l   sp,er1
165         subs    #4,er1                          /* adjust ret_pc */
166         jsr     @SYMBOL_NAME(process_int)
167         mov.l   @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0
168         beq     1f
169         jsr     @SYMBOL_NAME(do_softirq)
170 1:
171         jmp     @SYMBOL_NAME(ret_from_exception)
172
173 SYMBOL_NAME_LABEL(system_call)
174         subs    #4,sp                           /* dummy LVEC */
175         SAVE_ALL
176         mov.w   @(LCCR:16,sp),r1
177         bset    #4,r1l
178         ldc     r1l,ccr                         /* restore ccr */
179         mov.l   er0,er4
180         mov.l   #-ENOSYS,er0
181         mov.l   er0,@(LER0:16,sp)
182
183         /* save top of frame */
184         mov.l   sp,er0
185         jsr     @SYMBOL_NAME(set_esp0)
186         cmp.l   #NR_syscalls,er4
187         bcc     SYMBOL_NAME(ret_from_exception):16
188         shll.l  #2,er4
189         mov.l   #SYMBOL_NAME(sys_call_table),er0
190         add.l   er4,er0
191         mov.l   @er0,er0
192         mov.l   er0,er4
193         beq     SYMBOL_NAME(ret_from_exception):16      
194         mov.l   sp,er2
195         and.w   #0xe000,r2
196         mov.b   @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
197         btst    #(TIF_SYSCALL_TRACE & 7),r2l
198         mov.l   @(LER1:16,sp),er0
199         mov.l   @(LER2:16,sp),er1
200         mov.l   @(LER3:16,sp),er2
201         jsr     @er4
202         mov.l   er0,@(LER0:16,sp)                       /* save the return value */
203 #if defined(CONFIG_SYSCALL_PRINT)
204         jsr     @SYMBOL_NAME(syscall_print)
205 #endif
206         bra     SYMBOL_NAME(ret_from_exception):8
207 1:
208         jsr     SYMBOL_NAME(syscall_trace)
209         mov.l   @(LER1:16,sp),er0
210         mov.l   @(LER2:16,sp),er1
211         mov.l   @(LER3:16,sp),er2
212         jsr     @er4
213         mov.l   er0,@(LER0:16,sp)               /* save the return value */
214         jsr     @SYMBOL_NAME(syscall_trace)
215         bra     SYMBOL_NAME(ret_from_exception):8
216
217 SYMBOL_NAME_LABEL(ret_from_fork)
218         mov.l   er2,er0
219         jsr     @SYMBOL_NAME(schedule_tail)
220         bra     SYMBOL_NAME(ret_from_exception):8
221
222 SYMBOL_NAME_LABEL(reschedule)
223         /* save top of frame */
224         mov.l   sp,er0
225         jsr     @SYMBOL_NAME(set_esp0)
226         jsr     @SYMBOL_NAME(schedule)
227
228 SYMBOL_NAME_LABEL(ret_from_exception)
229 #if defined(CONFIG_PREEMPT)
230         orc     #0x80,ccr
231 #endif
232 SYMBOL_NAME_LABEL(ret_from_interrupt)
233         mov.b   @(LCCR+1:16,sp),r0l
234         btst    #4,r0l                  /* check if returning to kernel */
235         bne     done:8                  /* if so, skip resched, signals */
236         andc    #0x7f,ccr
237         mov.l   sp,er4
238         and.w   #0xe000,r4
239         mov.l   @(TI_FLAGS:16,er4),er1
240         and.l   #_TIF_WORK_MASK,er1
241         beq     done:8
242 1:
243         mov.l   @(TI_FLAGS:16,er4),er1
244         btst    #TIF_NEED_RESCHED,r1l
245         bne     SYMBOL_NAME(reschedule):16
246         mov.l   sp,er0
247         subs    #4,er0                  /* adjust retpc */
248         mov.l   er2,er1
249         jsr     @SYMBOL_NAME(do_signal)
250 #if defined(CONFIG_PREEMPT)
251         bra     done:8                  /* userspace thoru */
252 3:
253         btst    #4,r0l
254         beq     done:8                  /* userspace thoru */
255 4:
256         mov.l   @(TI_PRE_COUNT:16,er4),er1
257         bne     done:8
258         mov.l   @(TI_FLAGS:16,er4),er1
259         btst    #TIF_NEED_RESCHED,r1l
260         beq     done:8
261         mov.b   r0l,r0l
262         bpl     done:8                  /* interrupt off (exception path?) */
263         mov.l   #PREEMPT_ACTIVE,er1
264         mov.l   er1,@(TI_PRE_COUNT:16,er4)
265         andc    #0x7f,ccr
266         jsr     @SYMBOL_NAME(schedule)
267         sub.l   er1,er1
268         mov.l   er1,@(TI_PRE_COUNT:16,er4)
269         orc     #0x80,ccr
270         bra     4b:8
271 #endif
272 done:
273         RESTORE_ALL                     /* Does RTE */
274
275 SYMBOL_NAME_LABEL(resume)
276         /*
277          *      er0 = prev
278          *      er1 = next
279          *      return last in er2
280          */
281
282         /* save sr */
283         sub.w   r3,r3
284         stc     ccr,r3l
285         stc     exr,r3h
286         mov.w   r3,@(THREAD_CCR+2:16,er0)
287
288         /* disable interrupts */
289         orc     #0x80,ccr
290         mov.l   @SYMBOL_NAME(sw_usp),er3
291         mov.l   er3,@(THREAD_USP:16,er0)
292         mov.l   sp,@(THREAD_KSP:16,er0)
293         
294         /* Skip address space switching if they are the same. */
295         /* FIXME: what did we hack out of here, this does nothing! */
296
297         mov.l   @(THREAD_USP:16,er1),er0
298         mov.l   er0,@SYMBOL_NAME(sw_usp)
299         mov.l   @(THREAD_KSP:16,er1),sp
300                         
301         /* restore status register */
302         mov.w   @(THREAD_CCR+2:16,er1),r3
303
304         ldc     r3l,ccr
305         ldc     r3h,exr
306
307         rts
308
309 SYMBOL_NAME_LABEL(trace_break)
310         subs    #4,sp                   /* dummy LVEC */
311         SAVE_ALL
312         sub.l   er1,er1
313         dec.l   #1,er1
314         mov.l   er1,@(LORIG,sp) 
315         mov.l   sp,er0
316         jsr     @SYMBOL_NAME(set_esp0)
317         mov.l   @SYMBOL_NAME(sw_usp),er0
318         mov.l   @er0,er1
319         subs    #2,er1
320         mov.l   er1,@er0        
321         and.w   #0xff,e1
322         mov.l   er1,er0
323         jsr     @SYMBOL_NAME(trace_trap)
324         jmp     @SYMBOL_NAME(ret_from_exception)        
325
326         .section        .bss
327 SYMBOL_NAME_LABEL(sw_ksp)
328         .space  4       
329 SYMBOL_NAME_LABEL(sw_usp)
330         .space  4