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