3 * linux/arch/h8300/platform/h8300h/entry.S
5 * Yoshinori Sato <ysato@users.sourceforge.jp>
6 * David McCullough <davidm@snapgear.com>
12 * include exception/interrupt gateway
16 #include <linux/sys.h>
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>
27 /* CPU context save/restore macros. */
32 stc ccr,r0l /* check kernel mode */
36 mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
39 mov.l @SYMBOL_NAME(sw_ksp),sp
40 sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
43 mov.l @SYMBOL_NAME(sw_usp),er0
44 mov.l @(8:16,er0),er1 /* copy the RET addr */
45 mov.l er1,@(LRET-LER1:16,sp)
47 mov.w e1,r1 /* e1 highbyte = ccr */
48 and #0xef,r1h /* mask mode? flag */
51 mov.w r0,@(LCCR-LER1:16,sp) /* copy ccr */
52 mov.l @(LORIG-LER1:16,sp),er0
53 mov.l er0,@(LER0-LER1:16,sp) /* copy ER0 */
56 mov.l @sp,er0 /* kernel mode */
57 subs #2,sp /* dummy ccr */
60 mov.w @(LRET-LER1:16,sp),r1 /* copy old ccr */
63 mov.w r1,@(LCCR-LER1:16,sp) /* set ccr */
67 mov.l er6,@-sp /* syscall arg #6 */
68 mov.l er5,@-sp /* syscall arg #5 */
69 mov.l er4,@-sp /* syscall arg #4 */
78 mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */
83 mov.l @SYMBOL_NAME(sw_usp),er0
84 mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */
86 mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */
88 mov.b @(LRET+1-LER1:16,sp),r1l
90 mov.w @(LRET+2-LER1:16,sp),r1
94 add.l #(LRET-LER1),sp /* remove LORIG - LRET */
95 mov.l sp,@SYMBOL_NAME(sw_ksp)
104 adds #4,sp /* remove the sw created LVEC */
108 .globl SYMBOL_NAME(system_call)
109 .globl SYMBOL_NAME(ret_from_exception)
110 .globl SYMBOL_NAME(ret_from_fork)
111 .globl SYMBOL_NAME(ret_from_interrupt)
112 .globl SYMBOL_NAME(interrupt_redirect_table)
113 .globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
114 .globl SYMBOL_NAME(resume)
115 .globl SYMBOL_NAME(interrupt_redirect_table)
116 .globl SYMBOL_NAME(interrupt_entry)
117 .globl SYMBOL_NAME(system_call)
118 .globl SYMBOL_NAME(trace_break)
120 #if defined(CONFIG_ROMKERNEL)
122 .section .int_redirect,"ax"
123 SYMBOL_NAME_LABEL(interrupt_redirect_table)
127 jsr @SYMBOL_NAME(interrupt_entry) /* NMI */
128 jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */
131 jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */
133 jsr @SYMBOL_NAME(interrupt_entry)
136 #if defined(CONFIG_RAMKERNEL)
137 .globl SYMBOL_NAME(interrupt_redirect_table)
139 SYMBOL_NAME_LABEL(interrupt_redirect_table)
145 SYMBOL_NAME_LABEL(interrupt_entry)
150 mov.l @SYMBOL_NAME(sw_usp),er0
151 mov.l @(4:16,er0),er0
156 #if defined(CONFIG_ROMKERNEL)
157 sub.l #SYMBOL_NAME(interrupt_redirect_table),er0
159 #if defined(CONFIG_RAMKERNEL)
160 mov.l @SYMBOL_NAME(interrupt_redirect_table),er1
167 subs #4,er1 /* adjust ret_pc */
168 jsr @SYMBOL_NAME(do_IRQ)
169 mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0
171 jsr @SYMBOL_NAME(do_softirq)
173 jmp @SYMBOL_NAME(ret_from_interrupt)
175 SYMBOL_NAME_LABEL(system_call)
176 subs #4,sp /* dummy LVEC */
178 mov.w @(LCCR:16,sp),r1
183 mov.l er0,@(LER0:16,sp)
185 /* save top of frame */
187 jsr @SYMBOL_NAME(set_esp0)
188 cmp.l #NR_syscalls,er4
189 bcc SYMBOL_NAME(ret_from_exception):16
192 mov.l #SYMBOL_NAME(sys_call_table),er0
195 beq SYMBOL_NAME(ret_from_exception):16
198 mov.b @((TASK_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
199 btst #(TIF_SYSCALL_TRACE & 7),r2l
201 mov.l @(LER1:16,sp),er0
202 mov.l @(LER2:16,sp),er1
203 mov.l @(LER3:16,sp),er2
205 mov.l er0,@(LER0:16,sp) /* save the return value */
206 #if defined(CONFIG_SYSCALL_PRINT)
207 jsr @SYMBOL_NAME(syscall_print)
209 bra SYMBOL_NAME(ret_from_exception):8
211 jsr SYMBOL_NAME(syscall_trace)
212 mov.l @(LER1:16,sp),er0
213 mov.l @(LER2:16,sp),er1
214 mov.l @(LER3:16,sp),er2
216 mov.l er0,@(LER0:16,sp) /* save the return value */
217 jsr @SYMBOL_NAME(syscall_trace)
218 bra SYMBOL_NAME(ret_from_exception):8
220 SYMBOL_NAME_LABEL(ret_from_fork)
222 jsr @SYMBOL_NAME(schedule_tail)
223 bra SYMBOL_NAME(ret_from_exception):8
225 SYMBOL_NAME_LABEL(reschedule)
226 /* save top of frame */
228 jsr @SYMBOL_NAME(set_esp0)
229 jsr @SYMBOL_NAME(schedule)
231 SYMBOL_NAME_LABEL(ret_from_exception)
232 #if defined(CONFIG_PREEMPT)
235 SYMBOL_NAME_LABEL(ret_from_interrupt)
236 mov.b @(LCCR+1:16,sp),r0l
237 btst #4,r0l /* check if returning to kernel */
238 bne done:8 /* if so, skip resched, signals */
242 mov.l @(TI_FLAGS:16,er4),er1
243 and.l #_TIF_WORK_MASK,er1
246 mov.l @(TI_FLAGS:16,er4),er1
247 btst #TIF_NEED_RESCHED,r1l
248 bne SYMBOL_NAME(reschedule):16
250 subs #4,er0 /* adjust retpc */
252 jsr @SYMBOL_NAME(do_signal)
253 #if defined(CONFIG_PREEMPT)
254 bra done:8 /* userspace thoru */
257 beq done:8 /* userspace thoru */
259 mov.l @(TI_PRE_COUNT:16,er4),er1
261 mov.l @(TI_FLAGS:16,er4),er1
262 btst #TIF_NEED_RESCHED,r1l
265 bpl done:8 /* interrupt off (exception path?) */
266 mov.l #PREEMPT_ACTIVE,er1
267 mov.l er1,@(TI_PRE_COUNT:16,er4)
269 jsr @SYMBOL_NAME(schedule)
271 mov.l er1,@(TI_PRE_COUNT:16,er4)
276 RESTORE_ALL /* Does RTE */
278 SYMBOL_NAME_LABEL(resume)
280 * Beware - when entering resume, offset of tss is in d1,
281 * prev (the current task) is in a0, next (the new task)
282 * is in a1 and d2.b is non-zero if the mm structure is
283 * shared between the tasks, so don't change these
284 * registers until their contents are no longer needed.
290 mov.w r3,@(THREAD_CCR+2:16,er0)
292 /* disable interrupts */
294 mov.l @SYMBOL_NAME(sw_usp),er3
295 mov.l er3,@(THREAD_USP:16,er0)
296 mov.l sp,@(THREAD_KSP:16,er0)
298 /* Skip address space switching if they are the same. */
299 /* FIXME: what did we hack out of here, this does nothing! */
301 mov.l @(THREAD_USP:16,er1),er0
302 mov.l er0,@SYMBOL_NAME(sw_usp)
303 mov.l @(THREAD_KSP:16,er1),sp
305 /* restore status register */
306 mov.w @(THREAD_CCR+2:16,er1),r3
311 SYMBOL_NAME_LABEL(trace_break)
316 mov.l er1,@(LORIG,sp)
318 jsr @SYMBOL_NAME(set_esp0)
319 mov.l @SYMBOL_NAME(sw_usp),er0
325 jsr @SYMBOL_NAME(trace_trap)
326 jmp @SYMBOL_NAME(ret_from_exception)
329 SYMBOL_NAME_LABEL(sw_ksp)
331 SYMBOL_NAME_LABEL(sw_usp)