1/* -*- mode: asm -*- 2 * 3 * linux/arch/h8300/platform/h8300h/entry.S 4 * 5 * Yoshinori Sato <ysato@users.sourceforge.jp> 6 * David McCullough <davidm@snapgear.com> 7 * 8 */ 9 10/* 11 * entry.S 12 * include exception/interrupt gateway 13 * system call entry 14 */ 15 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> 24 25 .h8300h 26 27/* CPU context save/restore macros. */ 28 29 .macro SAVE_ALL 30 mov.l er0,@-sp 31 32 stc ccr,r0l /* check kernel mode */ 33 btst #4,r0l 34 bne 5f 35 36 mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */ 37 mov.l @sp,er0 38 orc #0x10,ccr 39 mov.l @SYMBOL_NAME(sw_ksp),sp 40 sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ 41 mov.l er0,@-sp 42 mov.l er1,@-sp 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) 46 47 mov.w e1,r1 /* e1 highbyte = ccr */ 48 and #0xef,r1h /* mask mode? flag */ 49 sub.w r0,r0 50 mov.b r1h,r0l 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 */ 54 bra 6f 555: 56 mov.l @sp,er0 /* kernel mode */ 57 subs #2,sp /* dummy ccr */ 58 mov.l er0,@-sp 59 mov.l er1,@-sp 60 mov.w @(LRET-LER1:16,sp),r1 /* copy old ccr */ 61 mov.b r1h,r1l 62 mov.b #0,r1h 63 mov.w r1,@(LCCR-LER1:16,sp) /* set ccr */ 646: 65 mov.l er2,@-sp 66 mov.l er3,@-sp 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 mov.l @sp+,er3 77 mov.l @sp+,er2 78 mov.w @(LCCR-LER1:16,sp),r0 /* check kernel mode */ 79 btst #4,r0l 80 bne 7f 81 82 orc #0x80,ccr 83 mov.l @SYMBOL_NAME(sw_usp),er0 84 mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */ 85 mov.l er1,@er0 86 mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */ 87 mov.b r1l,r1h 88 mov.b @(LRET+1-LER1:16,sp),r1l 89 mov.w r1,e1 90 mov.w @(LRET+2-LER1:16,sp),r1 91 mov.l er1,@(8:16,er0) 92 93 mov.l @sp+,er1 94 add.l #(LRET-LER1),sp /* remove LORIG - LRET */ 95 mov.l sp,@SYMBOL_NAME(sw_ksp) 96 mov.l er0,sp 97 bra 8f 987: 99 mov.l @sp+,er1 100 adds #4,sp 101 adds #2,sp 1028: 103 mov.l @sp+,er0 104 adds #4,sp /* remove the sw created LVEC */ 105 rte 106 .endm 107 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) 119 120#if defined(CONFIG_ROMKERNEL) 121INTERRUPTS = 64 122 .section .int_redirect,"ax" 123SYMBOL_NAME_LABEL(interrupt_redirect_table) 124 .rept 7 125 .long 0 126 .endr 127 jsr @SYMBOL_NAME(interrupt_entry) /* NMI */ 128 jmp @SYMBOL_NAME(system_call) /* TRAPA #0 (System call) */ 129 .long 0 130 .long 0 131 jmp @SYMBOL_NAME(trace_break) /* TRAPA #3 (breakpoint) */ 132 .rept INTERRUPTS-12 133 jsr @SYMBOL_NAME(interrupt_entry) 134 .endr 135#endif 136#if defined(CONFIG_RAMKERNEL) 137.globl SYMBOL_NAME(interrupt_redirect_table) 138 .section .bss 139SYMBOL_NAME_LABEL(interrupt_redirect_table) 140 .space 4 141#endif 142 143 .section .text 144 .align 2 145SYMBOL_NAME_LABEL(interrupt_entry) 146 SAVE_ALL 147 mov.w @(LCCR,sp),r0 148 btst #4,r0l 149 bne 1f 150 mov.l @SYMBOL_NAME(sw_usp),er0 151 mov.l @(4:16,er0),er0 152 bra 2f 1531: 154 mov.l @(LVEC,sp),er0 1552: 156#if defined(CONFIG_ROMKERNEL) 157 sub.l #SYMBOL_NAME(interrupt_redirect_table),er0 158#endif 159#if defined(CONFIG_RAMKERNEL) 160 mov.l @SYMBOL_NAME(interrupt_redirect_table),er1 161 sub.l er1,er0 162#endif 163 shlr.l er0 164 shlr.l er0 165 dec.l #1,er0 166 mov.l sp,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 170 beq 1f 171 jsr @SYMBOL_NAME(do_softirq) 1721: 173 jmp @SYMBOL_NAME(ret_from_interrupt) 174 175SYMBOL_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 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 er4 191 shll.l er4 192 mov.l #SYMBOL_NAME(sys_call_table),er0 193 add.l er4,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 bne 1f 201 mov.l @(LER1:16,sp),er0 202 mov.l @(LER2:16,sp),er1 203 mov.l @(LER3:16,sp),er2 204 jsr @er4 205 mov.l er0,@(LER0:16,sp) /* save the return value */ 206#if defined(CONFIG_SYSCALL_PRINT) 207 jsr @SYMBOL_NAME(syscall_print) 208#endif 209 bra SYMBOL_NAME(ret_from_exception):8 2101: 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 215 jsr @er4 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 219 220SYMBOL_NAME_LABEL(ret_from_fork) 221 mov.l er2,er0 222 jsr @SYMBOL_NAME(schedule_tail) 223 bra SYMBOL_NAME(ret_from_exception):8 224 225SYMBOL_NAME_LABEL(reschedule) 226 /* save top of frame */ 227 mov.l sp,er0 228 jsr @SYMBOL_NAME(set_esp0) 229 jsr @SYMBOL_NAME(schedule) 230 231SYMBOL_NAME_LABEL(ret_from_exception) 232#if defined(CONFIG_PREEMPT) 233 orc #0x80,ccr 234#endif 235SYMBOL_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 */ 239 andc #0x7f,ccr 240 mov.l sp,er4 241 and.w #0xe000,r4 242 mov.l @(TI_FLAGS:16,er4),er1 243 and.l #_TIF_WORK_MASK,er1 244 beq done:8 2451: 246 mov.l @(TI_FLAGS:16,er4),er1 247 btst #TIF_NEED_RESCHED,r1l 248 bne SYMBOL_NAME(reschedule):16 249 mov.l sp,er0 250 subs #4,er0 /* adjust retpc */ 251 mov.l er2,er1 252 jsr @SYMBOL_NAME(do_signal) 253#if defined(CONFIG_PREEMPT) 254 bra done:8 /* userspace thoru */ 2553: 256 btst #4,r0l 257 beq done:8 /* userspace thoru */ 2584: 259 mov.l @(TI_PRE_COUNT:16,er4),er1 260 bne done:8 261 mov.l @(TI_FLAGS:16,er4),er1 262 btst #TIF_NEED_RESCHED,r1l 263 beq done:8 264 mov.b r0l,r0l 265 bpl done:8 /* interrupt off (exception path?) */ 266 mov.l #PREEMPT_ACTIVE,er1 267 mov.l er1,@(TI_PRE_COUNT:16,er4) 268 andc #0x7f,ccr 269 jsr @SYMBOL_NAME(schedule) 270 sub.l er1,er1 271 mov.l er1,@(TI_PRE_COUNT:16,er4) 272 orc #0x80,ccr 273 bra 4b:8 274#endif 275done: 276 RESTORE_ALL /* Does RTE */ 277 278SYMBOL_NAME_LABEL(resume) 279 /* 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. 285 */ 286 287 /* save sr */ 288 sub.w r3,r3 289 stc ccr,r3l 290 mov.w r3,@(THREAD_CCR+2:16,er0) 291 292 /* disable interrupts */ 293 orc #0x80,ccr 294 mov.l @SYMBOL_NAME(sw_usp),er3 295 mov.l er3,@(THREAD_USP:16,er0) 296 mov.l sp,@(THREAD_KSP:16,er0) 297 298 /* Skip address space switching if they are the same. */ 299 300 mov.l @(THREAD_USP:16,er1),er0 301 mov.l er0,@SYMBOL_NAME(sw_usp) 302 mov.l @(THREAD_KSP:16,er1),sp 303 304 /* restore status register */ 305 mov.w @(THREAD_CCR+2:16,er1),r3 306 307 ldc r3l,ccr 308 rts 309 310SYMBOL_NAME_LABEL(trace_break) 311 subs #4,sp 312 SAVE_ALL 313 sub.l er1,er1 314 dec.l #1,er1 315 mov.l er1,@(LORIG,sp) 316 mov.l sp,er0 317 jsr @SYMBOL_NAME(set_esp0) 318 mov.l @SYMBOL_NAME(sw_usp),er0 319 mov.l @er0,er1 320 subs #2,er1 321 mov.l er1,@er0 322 and.w #0xff,e1 323 mov.l er1,er0 324 jsr @SYMBOL_NAME(trace_trap) 325 jmp @SYMBOL_NAME(ret_from_exception) 326 327 .section .bss 328SYMBOL_NAME_LABEL(sw_ksp) 329 .space 4 330SYMBOL_NAME_LABEL(sw_usp) 331 .space 4 332