Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-block.git] / arch / h8300 / kernel / entry.S
CommitLineData
1da177e4
LT
1/* -*- mode: asm -*-
2 *
2fea299f 3 * linux/arch/h8300/platform/h8300h/entry.S
1da177e4
LT
4 *
5 * Yoshinori Sato <ysato@users.sourceforge.jp>
2fea299f 6 * David McCullough <davidm@snapgear.com>
1da177e4 7 *
1da177e4
LT
8 */
9
10/*
11 * entry.S
12 * include exception/interrupt gateway
13 * system call entry
14 */
15
16#include <linux/sys.h>
1da177e4
LT
17#include <asm/unistd.h>
18#include <asm/setup.h>
19#include <asm/segment.h>
20#include <asm/linkage.h>
21#include <asm/asm-offsets.h>
22#include <asm/thread_info.h>
23#include <asm/errno.h>
24
2fea299f
YS
25#if defined(CONFIG_CPU_H8300H)
26#define USERRET 8
27INTERRUPTS = 64
28 .h8300h
29 .macro SHLL2 reg
30 shll.l \reg
31 shll.l \reg
32 .endm
33 .macro SHLR2 reg
34 shlr.l \reg
35 shlr.l \reg
36 .endm
37 .macro SAVEREGS
38 mov.l er0,@-sp
39 mov.l er1,@-sp
40 mov.l er2,@-sp
41 mov.l er3,@-sp
42 .endm
43 .macro RESTOREREGS
44 mov.l @sp+,er3
45 mov.l @sp+,er2
46 .endm
47 .macro SAVEEXR
48 .endm
49 .macro RESTOREEXR
50 .endm
51#endif
52#if defined(CONFIG_CPU_H8S)
53#define USERRET 10
54#define USEREXR 8
55INTERRUPTS = 128
1da177e4 56 .h8300s
2fea299f
YS
57 .macro SHLL2 reg
58 shll.l #2,\reg
59 .endm
60 .macro SHLR2 reg
61 shlr.l #2,\reg
62 .endm
63 .macro SAVEREGS
64 stm.l er0-er3,@-sp
65 .endm
66 .macro RESTOREREGS
67 ldm.l @sp+,er2-er3
68 .endm
69 .macro SAVEEXR
70 mov.w @(USEREXR:16,er0),r1
71 mov.w r1,@(LEXR-LER3:16,sp) /* copy EXR */
72 .endm
73 .macro RESTOREEXR
74 mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */
75 mov.b r1l,r1h
76 mov.w r1,@(USEREXR:16,er0)
77 .endm
78#endif
79
1da177e4
LT
80
81/* CPU context save/restore macros. */
2fea299f 82
1da177e4
LT
83 .macro SAVE_ALL
84 mov.l er0,@-sp
1da177e4 85 stc ccr,r0l /* check kernel mode */
1da177e4
LT
86 btst #4,r0l
87 bne 5f
88
c728d604
YS
89 /* user mode */
90 mov.l sp,@SYMBOL_NAME(sw_usp)
91 mov.l @sp,er0 /* restore saved er0 */
92 orc #0x10,ccr /* switch kernel stack */
1da177e4 93 mov.l @SYMBOL_NAME(sw_ksp),sp
2fea299f
YS
94 sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
95 SAVEREGS
96 mov.l @SYMBOL_NAME(sw_usp),er0
97 mov.l @(USERRET:16,er0),er1 /* copy the RET addr */
98 mov.l er1,@(LRET-LER3:16,sp)
99 SAVEEXR
1da177e4 100
1da177e4
LT
101 mov.l @(LORIG-LER3:16,sp),er0
102 mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */
2fea299f
YS
103 mov.w e1,r1 /* e1 highbyte = ccr */
104 and #0xef,r1h /* mask mode? flag */
1da177e4
LT
105 bra 6f
1065:
c728d604
YS
107 /* kernel mode */
108 mov.l @sp,er0 /* restore saved er0 */
109 subs #2,sp /* set dummy ccr */
2fea299f 110 SAVEREGS
1da177e4 111 mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */
2fea299f 1126:
1da177e4
LT
113 mov.b r1h,r1l
114 mov.b #0,r1h
2fea299f 115 mov.w r1,@(LCCR-LER3:16,sp) /* set ccr */
1da177e4
LT
116 mov.l er6,@-sp /* syscall arg #6 */
117 mov.l er5,@-sp /* syscall arg #5 */
118 mov.l er4,@-sp /* syscall arg #4 */
2fea299f 119 .endm /* r1 = ccr */
1da177e4
LT
120
121 .macro RESTORE_ALL
122 mov.l @sp+,er4
123 mov.l @sp+,er5
124 mov.l @sp+,er6
2fea299f 125 RESTOREREGS
1da177e4
LT
126 mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */
127 btst #4,r0l
128 bne 7f
129
130 orc #0x80,ccr
131 mov.l @SYMBOL_NAME(sw_usp),er0
132 mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */
133 mov.l er1,@er0
2fea299f 134 RESTOREEXR
1da177e4
LT
135 mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */
136 mov.b r1l,r1h
137 mov.b @(LRET+1-LER1:16,sp),r1l
138 mov.w r1,e1
139 mov.w @(LRET+2-LER1:16,sp),r1
2fea299f 140 mov.l er1,@(USERRET:16,er0)
1da177e4
LT
141
142 mov.l @sp+,er1
2fea299f 143 add.l #(LRET-LER1),sp /* remove LORIG - LRET */
1da177e4 144 mov.l sp,@SYMBOL_NAME(sw_ksp)
c728d604 145 andc #0xef,ccr /* switch to user mode */
1da177e4
LT
146 mov.l er0,sp
147 bra 8f
1487:
149 mov.l @sp+,er1
150 adds #4,sp
151 adds #2,sp
1528:
153 mov.l @sp+,er0
154 adds #4,sp /* remove the sw created LVEC */
155 rte
156 .endm
2fea299f 157
1da177e4
LT
158.globl SYMBOL_NAME(system_call)
159.globl SYMBOL_NAME(ret_from_exception)
160.globl SYMBOL_NAME(ret_from_fork)
161.globl SYMBOL_NAME(ret_from_interrupt)
162.globl SYMBOL_NAME(interrupt_redirect_table)
163.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
164.globl SYMBOL_NAME(resume)
1da177e4 165.globl SYMBOL_NAME(interrupt_entry)
2fea299f
YS
166.globl SYMBOL_NAME(trace_break)
167
1da177e4
LT
168#if defined(CONFIG_ROMKERNEL)
169 .section .int_redirect,"ax"
170SYMBOL_NAME_LABEL(interrupt_redirect_table)
2fea299f 171#if defined(CONFIG_CPU_H8300H)
1da177e4
LT
172 .rept 7
173 .long 0
174 .endr
2fea299f
YS
175#endif
176#if defined(CONFIG_CPU_H8S)
177 .rept 5
178 .long 0
179 .endr
180 jmp @SYMBOL_NAME(trace_break)
181 .long 0
182#endif
183
1da177e4
LT
184 jsr @SYMBOL_NAME(interrupt_entry) /* NMI */
185 jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */
186 .long 0
187 .long 0
188 jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */
189 .rept INTERRUPTS-12
190 jsr @SYMBOL_NAME(interrupt_entry)
191 .endr
192#endif
193#if defined(CONFIG_RAMKERNEL)
194.globl SYMBOL_NAME(interrupt_redirect_table)
195 .section .bss
196SYMBOL_NAME_LABEL(interrupt_redirect_table)
197 .space 4
198#endif
2fea299f 199
1da177e4
LT
200 .section .text
201 .align 2
202SYMBOL_NAME_LABEL(interrupt_entry)
203 SAVE_ALL
2fea299f
YS
204 mov.l sp,er0
205 add.l #LVEC,er0
206 btst #4,r1l
1da177e4 207 bne 1f
2fea299f 208 /* user LVEC */
1da177e4 209 mov.l @SYMBOL_NAME(sw_usp),er0
2fea299f 210 adds #4,er0
1da177e4 2111:
2fea299f 212 mov.l @er0,er0 /* LVEC address */
1da177e4
LT
213#if defined(CONFIG_ROMKERNEL)
214 sub.l #SYMBOL_NAME(interrupt_redirect_table),er0
215#endif
216#if defined(CONFIG_RAMKERNEL)
217 mov.l @SYMBOL_NAME(interrupt_redirect_table),er1
218 sub.l er1,er0
219#endif
2fea299f 220 SHLR2 er0
1da177e4
LT
221 dec.l #1,er0
222 mov.l sp,er1
223 subs #4,er1 /* adjust ret_pc */
2fea299f
YS
224 jsr @SYMBOL_NAME(do_IRQ)
225 jmp @SYMBOL_NAME(ret_from_interrupt)
1da177e4
LT
226
227SYMBOL_NAME_LABEL(system_call)
228 subs #4,sp /* dummy LVEC */
229 SAVE_ALL
2fea299f 230 andc #0x7f,ccr
1da177e4 231 mov.l er0,er4
1da177e4
LT
232
233 /* save top of frame */
234 mov.l sp,er0
235 jsr @SYMBOL_NAME(set_esp0)
1da177e4
LT
236 mov.l sp,er2
237 and.w #0xe000,r2
2fea299f 238 mov.b @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
1da177e4 239 btst #(TIF_SYSCALL_TRACE & 7),r2l
2fea299f
YS
240 beq 1f
241 jsr @SYMBOL_NAME(do_syscall_trace)
2421:
243 cmp.l #NR_syscalls,er4
244 bcc badsys
245 SHLL2 er4
246 mov.l #SYMBOL_NAME(sys_call_table),er0
247 add.l er4,er0
248 mov.l @er0,er4
249 beq SYMBOL_NAME(ret_from_exception):16
1da177e4
LT
250 mov.l @(LER1:16,sp),er0
251 mov.l @(LER2:16,sp),er1
252 mov.l @(LER3:16,sp),er2
253 jsr @er4
2fea299f
YS
254 mov.l er0,@(LER0:16,sp) /* save the return value */
255 mov.l sp,er2
256 and.w #0xe000,r2
257 mov.b @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
258 btst #(TIF_SYSCALL_TRACE & 7),r2l
259 beq 2f
260 jsr @SYMBOL_NAME(do_syscall_trace)
2612:
1da177e4
LT
262#if defined(CONFIG_SYSCALL_PRINT)
263 jsr @SYMBOL_NAME(syscall_print)
264#endif
2fea299f
YS
265 orc #0x80,ccr
266 bra resume_userspace
1da177e4 267
2fea299f
YS
268badsys:
269 mov.l #-ENOSYS,er0
270 mov.l er0,@(LER0:16,sp)
271 bra resume_userspace
1da177e4 272
2fea299f
YS
273#if !defined(CONFIG_PREEMPT)
274#define resume_kernel restore_all
275#endif
1da177e4
LT
276
277SYMBOL_NAME_LABEL(ret_from_exception)
278#if defined(CONFIG_PREEMPT)
279 orc #0x80,ccr
280#endif
281SYMBOL_NAME_LABEL(ret_from_interrupt)
282 mov.b @(LCCR+1:16,sp),r0l
2fea299f
YS
283 btst #4,r0l
284 bne resume_kernel:8 /* return from kernel */
285resume_userspace:
1da177e4
LT
286 andc #0x7f,ccr
287 mov.l sp,er4
2fea299f 288 and.w #0xe000,r4 /* er4 <- current thread info */
1da177e4
LT
289 mov.l @(TI_FLAGS:16,er4),er1
290 and.l #_TIF_WORK_MASK,er1
2fea299f
YS
291 beq restore_all:8
292work_pending:
1da177e4 293 btst #TIF_NEED_RESCHED,r1l
2fea299f
YS
294 bne work_resched:8
295 /* work notifysig */
1da177e4 296 mov.l sp,er0
2fea299f
YS
297 subs #4,er0 /* er0: pt_regs */
298 jsr @SYMBOL_NAME(do_notify_resume)
299 bra restore_all:8
300work_resched:
301 mov.l sp,er0
302 jsr @SYMBOL_NAME(set_esp0)
303 jsr @SYMBOL_NAME(schedule)
304 bra resume_userspace:8
305restore_all:
306 RESTORE_ALL /* Does RTE */
307
1da177e4 308#if defined(CONFIG_PREEMPT)
2fea299f
YS
309resume_kernel:
310 mov.l @(TI_PRE_COUNT:16,er4),er0
311 bne restore_all:8
312need_resched:
313 mov.l @(TI_FLAGS:16,er4),er0
314 btst #TIF_NEED_RESCHED,r0l
315 beq restore_all:8
316 mov.b @(LCCR+1:16,sp),r0l /* Interrupt Enabled? */
317 bmi restore_all:8
318 mov.l #PREEMPT_ACTIVE,er0
319 mov.l er0,@(TI_PRE_COUNT:16,er4)
1da177e4 320 andc #0x7f,ccr
2fea299f
YS
321 mov.l sp,er0
322 jsr @SYMBOL_NAME(set_esp0)
1da177e4 323 jsr @SYMBOL_NAME(schedule)
1da177e4 324 orc #0x80,ccr
2fea299f 325 bra need_resched:8
1da177e4 326#endif
2fea299f
YS
327
328SYMBOL_NAME_LABEL(ret_from_fork)
329 mov.l er2,er0
330 jsr @SYMBOL_NAME(schedule_tail)
331 jmp @SYMBOL_NAME(ret_from_exception)
1da177e4
LT
332
333SYMBOL_NAME_LABEL(resume)
334 /*
2fea299f
YS
335 * Beware - when entering resume, offset of tss is in d1,
336 * prev (the current task) is in a0, next (the new task)
337 * is in a1 and d2.b is non-zero if the mm structure is
338 * shared between the tasks, so don't change these
339 * registers until their contents are no longer needed.
1da177e4
LT
340 */
341
342 /* save sr */
343 sub.w r3,r3
344 stc ccr,r3l
1da177e4
LT
345 mov.w r3,@(THREAD_CCR+2:16,er0)
346
347 /* disable interrupts */
348 orc #0x80,ccr
349 mov.l @SYMBOL_NAME(sw_usp),er3
350 mov.l er3,@(THREAD_USP:16,er0)
351 mov.l sp,@(THREAD_KSP:16,er0)
2fea299f 352
1da177e4
LT
353 /* Skip address space switching if they are the same. */
354 /* FIXME: what did we hack out of here, this does nothing! */
355
356 mov.l @(THREAD_USP:16,er1),er0
357 mov.l er0,@SYMBOL_NAME(sw_usp)
358 mov.l @(THREAD_KSP:16,er1),sp
2fea299f 359
1da177e4
LT
360 /* restore status register */
361 mov.w @(THREAD_CCR+2:16,er1),r3
362
363 ldc r3l,ccr
1da177e4
LT
364 rts
365
366SYMBOL_NAME_LABEL(trace_break)
2fea299f 367 subs #4,sp
1da177e4
LT
368 SAVE_ALL
369 sub.l er1,er1
370 dec.l #1,er1
2fea299f 371 mov.l er1,@(LORIG,sp)
1da177e4
LT
372 mov.l sp,er0
373 jsr @SYMBOL_NAME(set_esp0)
374 mov.l @SYMBOL_NAME(sw_usp),er0
375 mov.l @er0,er1
2fea299f
YS
376 mov.w @(-2:16,er1),r2
377 cmp.w #0x5730,r2
378 beq 1f
1da177e4 379 subs #2,er1
2fea299f
YS
380 mov.l er1,@er0
3811:
1da177e4
LT
382 and.w #0xff,e1
383 mov.l er1,er0
384 jsr @SYMBOL_NAME(trace_trap)
2fea299f 385 jmp @SYMBOL_NAME(ret_from_exception)
1da177e4
LT
386
387 .section .bss
388SYMBOL_NAME_LABEL(sw_ksp)
2fea299f 389 .space 4
1da177e4 390SYMBOL_NAME_LABEL(sw_usp)
2fea299f
YS
391 .space 4
392
393 .end