blob: ca7431690300a15fe5dc3ed0b61ad35756d363fd [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* -*- mode: asm -*-
2 *
Yoshinori Sato2fea2992007-07-15 23:38:36 -07003 * linux/arch/h8300/platform/h8300h/entry.S
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
5 * Yoshinori Sato <ysato@users.sourceforge.jp>
Yoshinori Sato2fea2992007-07-15 23:38:36 -07006 * David McCullough <davidm@snapgear.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 */
9
10/*
11 * entry.S
12 * include exception/interrupt gateway
13 * system call entry
14 */
15
16#include <linux/sys.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#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
Yoshinori Sato2fea2992007-07-15 23:38:36 -070025#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
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 .h8300s
Yoshinori Sato2fea2992007-07-15 23:38:36 -070057 .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
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
81/* CPU context save/restore macros. */
Yoshinori Sato2fea2992007-07-15 23:38:36 -070082
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 .macro SAVE_ALL
84 mov.l er0,@-sp
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 stc ccr,r0l /* check kernel mode */
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 btst #4,r0l
87 bne 5f
88
Yoshinori Satoc728d602007-05-06 14:50:35 -070089 /* 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 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 mov.l @SYMBOL_NAME(sw_ksp),sp
Yoshinori Sato2fea2992007-07-15 23:38:36 -070094 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 mov.l @(LORIG-LER3:16,sp),er0
102 mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700103 mov.w e1,r1 /* e1 highbyte = ccr */
104 and #0xef,r1h /* mask mode? flag */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 bra 6f
1065:
Yoshinori Satoc728d602007-05-06 14:50:35 -0700107 /* kernel mode */
108 mov.l @sp,er0 /* restore saved er0 */
109 subs #2,sp /* set dummy ccr */
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700110 SAVEREGS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */
Yoshinori Sato2fea2992007-07-15 23:38:36 -07001126:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 mov.b r1h,r1l
114 mov.b #0,r1h
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700115 mov.w r1,@(LCCR-LER3:16,sp) /* set ccr */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 mov.l er6,@-sp /* syscall arg #6 */
117 mov.l er5,@-sp /* syscall arg #5 */
118 mov.l er4,@-sp /* syscall arg #4 */
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700119 .endm /* r1 = ccr */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
121 .macro RESTORE_ALL
122 mov.l @sp+,er4
123 mov.l @sp+,er5
124 mov.l @sp+,er6
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700125 RESTOREREGS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 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
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700134 RESTOREEXR
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 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
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700140 mov.l er1,@(USERRET:16,er0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142 mov.l @sp+,er1
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700143 add.l #(LRET-LER1),sp /* remove LORIG - LRET */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 mov.l sp,@SYMBOL_NAME(sw_ksp)
Yoshinori Satoc728d602007-05-06 14:50:35 -0700145 andc #0xef,ccr /* switch to user mode */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 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
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158.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)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165.globl SYMBOL_NAME(interrupt_entry)
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700166.globl SYMBOL_NAME(trace_break)
167
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168#if defined(CONFIG_ROMKERNEL)
169 .section .int_redirect,"ax"
170SYMBOL_NAME_LABEL(interrupt_redirect_table)
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700171#if defined(CONFIG_CPU_H8300H)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 .rept 7
173 .long 0
174 .endr
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700175#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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 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
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700199
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 .section .text
201 .align 2
202SYMBOL_NAME_LABEL(interrupt_entry)
203 SAVE_ALL
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700204 mov.l sp,er0
205 add.l #LVEC,er0
206 btst #4,r1l
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 bne 1f
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700208 /* user LVEC */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 mov.l @SYMBOL_NAME(sw_usp),er0
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700210 adds #4,er0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111:
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700212 mov.l @er0,er0 /* LVEC address */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213#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
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700220 SHLR2 er0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 dec.l #1,er0
222 mov.l sp,er1
223 subs #4,er1 /* adjust ret_pc */
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700224 jsr @SYMBOL_NAME(do_IRQ)
225 jmp @SYMBOL_NAME(ret_from_interrupt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226
227SYMBOL_NAME_LABEL(system_call)
228 subs #4,sp /* dummy LVEC */
229 SAVE_ALL
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700230 andc #0x7f,ccr
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 mov.l er0,er4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232
233 /* save top of frame */
234 mov.l sp,er0
235 jsr @SYMBOL_NAME(set_esp0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 mov.l sp,er2
237 and.w #0xe000,r2
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700238 mov.b @((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 btst #(TIF_SYSCALL_TRACE & 7),r2l
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700240 beq 1f
241 jsr @SYMBOL_NAME(do_syscall_trace)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421:
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700243 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 mov.l @(LER1:16,sp),er0
251 mov.l @(LER2:16,sp),er1
252 mov.l @(LER3:16,sp),er2
253 jsr @er4
254 mov.l er0,@(LER0:16,sp) /* save the return value */
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700255 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:
262#if defined(CONFIG_SYSCALL_PRINT)
263 jsr @SYMBOL_NAME(syscall_print)
264#endif
265 orc #0x80,ccr
266 bra resume_userspace
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700268badsys:
269 mov.l #-ENOSYS,er0
270 mov.l er0,@(LER0:16,sp)
271 bra resume_userspace
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700273#if !defined(CONFIG_PREEMPT)
274#define resume_kernel restore_all
275#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276
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
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700283 btst #4,r0l
284 bne resume_kernel:8 /* return from kernel */
285resume_userspace:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 andc #0x7f,ccr
287 mov.l sp,er4
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700288 and.w #0xe000,r4 /* er4 <- current thread info */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 mov.l @(TI_FLAGS:16,er4),er1
290 and.l #_TIF_WORK_MASK,er1
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700291 beq restore_all:8
292work_pending:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 btst #TIF_NEED_RESCHED,r1l
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700294 bne work_resched:8
295 /* work notifysig */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 mov.l sp,er0
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700297 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)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 jsr @SYMBOL_NAME(schedule)
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700304 bra resume_userspace:8
305restore_all:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 RESTORE_ALL /* Does RTE */
307
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700308#if defined(CONFIG_PREEMPT)
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)
320 andc #0x7f,ccr
321 mov.l sp,er0
322 jsr @SYMBOL_NAME(set_esp0)
323 jsr @SYMBOL_NAME(schedule)
324 orc #0x80,ccr
325 bra need_resched:8
326#endif
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)
332
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333SYMBOL_NAME_LABEL(resume)
334 /*
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700335 * 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.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 */
341
342 /* save sr */
343 sub.w r3,r3
344 stc ccr,r3l
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 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)
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 /* 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
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700359
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 /* restore status register */
361 mov.w @(THREAD_CCR+2:16,er1),r3
362
363 ldc r3l,ccr
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 rts
365
366SYMBOL_NAME_LABEL(trace_break)
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700367 subs #4,sp
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 SAVE_ALL
369 sub.l er1,er1
370 dec.l #1,er1
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700371 mov.l er1,@(LORIG,sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 mov.l sp,er0
373 jsr @SYMBOL_NAME(set_esp0)
374 mov.l @SYMBOL_NAME(sw_usp),er0
375 mov.l @er0,er1
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700376 mov.w @(-2:16,er1),r2
377 cmp.w #0x5730,r2
378 beq 1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 subs #2,er1
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700380 mov.l er1,@er0
3811:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 and.w #0xff,e1
383 mov.l er1,er0
384 jsr @SYMBOL_NAME(trace_trap)
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700385 jmp @SYMBOL_NAME(ret_from_exception)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
387 .section .bss
388SYMBOL_NAME_LABEL(sw_ksp)
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700389 .space 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390SYMBOL_NAME_LABEL(sw_usp)
Yoshinori Sato2fea2992007-07-15 23:38:36 -0700391 .space 4
392
393 .end