1 /* 2 * entry.S -- non-mmu 68000 interrupt and exception entry points 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file README.legal in the main directory of this archive 8 * for more details. 9 * 10 * Linux/m68k support by Hamish Macdonald 11 */ 12 13 #include <linux/linkage.h> 14 #include <asm/thread_info.h> 15 #include <asm/unistd.h> 16 #include <asm/errno.h> 17 #include <asm/setup.h> 18 #include <asm/traps.h> 19 #include <asm/asm-offsets.h> 20 #include <asm/entry.h> 21 22 .text 23 24 .globl system_call 25 .globl resume 26 .globl ret_from_exception 27 .globl sys_call_table 28 .globl bad_interrupt 29 .globl inthandler1 30 .globl inthandler2 31 .globl inthandler3 32 .globl inthandler4 33 .globl inthandler5 34 .globl inthandler6 35 .globl inthandler7 36 37 badsys: 38 movel #-ENOSYS,%sp@(PT_OFF_D0) 39 jra ret_from_exception 40 41 do_trace: 42 movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ 43 subql #4,%sp 44 SAVE_SWITCH_STACK 45 jbsr syscall_trace_enter 46 RESTORE_SWITCH_STACK 47 addql #4,%sp 48 addql #1,%d0 49 jeq ret_from_exception 50 movel %sp@(PT_OFF_ORIG_D0),%d1 51 movel #-ENOSYS,%d0 52 cmpl #NR_syscalls,%d1 53 jcc 1f 54 lsl #2,%d1 55 lea sys_call_table, %a0 56 jbsr %a0@(%d1) 57 58 1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ 59 subql #4,%sp /* dummy return address */ 60 SAVE_SWITCH_STACK 61 jbsr syscall_trace_leave 62 RESTORE_SWITCH_STACK 63 addql #4,%sp 64 jra ret_from_exception 65 66 ENTRY(system_call) 67 SAVE_ALL_SYS 68 69 /* save top of frame*/ 70 pea %sp@ 71 jbsr set_esp0 72 addql #4,%sp 73 74 movel %sp@(PT_OFF_ORIG_D0),%d0 75 76 movel %sp,%d1 /* get thread_info pointer */ 77 andl #-THREAD_SIZE,%d1 78 movel %d1,%a2 79 btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) 80 jne do_trace 81 cmpl #NR_syscalls,%d0 82 jcc badsys 83 lsl #2,%d0 84 lea sys_call_table,%a0 85 movel %a0@(%d0), %a0 86 jbsr %a0@ 87 movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ 88 89 ret_from_exception: 90 btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ 91 jeq Luser_return /* if so, skip resched, signals*/ 92 93 Lkernel_return: 94 RESTORE_ALL 95 96 Luser_return: 97 /* only allow interrupts when we are really the last one on the*/ 98 /* kernel stack, otherwise stack overflow can occur during*/ 99 /* heavy interrupt load*/ 100 andw #ALLOWINT,%sr 101 102 movel %sp,%d1 /* get thread_info pointer */ 103 andl #-THREAD_SIZE,%d1 104 movel %d1,%a2 105 1: 106 move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 107 jne Lwork_to_do 108 RESTORE_ALL 109 110 Lwork_to_do: 111 movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 112 btst #TIF_NEED_RESCHED,%d1 113 jne reschedule 114 115 Lsignal_return: 116 subql #4,%sp /* dummy return address*/ 117 SAVE_SWITCH_STACK 118 pea %sp@(SWITCH_STACK_SIZE) 119 bsrw do_notify_resume 120 addql #4,%sp 121 RESTORE_SWITCH_STACK 122 addql #4,%sp 123 jra 1b 124 125 /* 126 * This is the main interrupt handler, responsible for calling process_int() 127 */ 128 inthandler1: 129 SAVE_ALL_INT 130 movew %sp@(PT_OFF_FORMATVEC), %d0 131 and #0x3ff, %d0 132 133 movel %sp,%sp@- 134 movel #65,%sp@- /* put vector # on stack*/ 135 jbsr process_int /* process the IRQ*/ 136 3: addql #8,%sp /* pop parameters off stack*/ 137 bra ret_from_exception 138 139 inthandler2: 140 SAVE_ALL_INT 141 movew %sp@(PT_OFF_FORMATVEC), %d0 142 and #0x3ff, %d0 143 144 movel %sp,%sp@- 145 movel #66,%sp@- /* put vector # on stack*/ 146 jbsr process_int /* process the IRQ*/ 147 3: addql #8,%sp /* pop parameters off stack*/ 148 bra ret_from_exception 149 150 inthandler3: 151 SAVE_ALL_INT 152 movew %sp@(PT_OFF_FORMATVEC), %d0 153 and #0x3ff, %d0 154 155 movel %sp,%sp@- 156 movel #67,%sp@- /* put vector # on stack*/ 157 jbsr process_int /* process the IRQ*/ 158 3: addql #8,%sp /* pop parameters off stack*/ 159 bra ret_from_exception 160 161 inthandler4: 162 SAVE_ALL_INT 163 movew %sp@(PT_OFF_FORMATVEC), %d0 164 and #0x3ff, %d0 165 166 movel %sp,%sp@- 167 movel #68,%sp@- /* put vector # on stack*/ 168 jbsr process_int /* process the IRQ*/ 169 3: addql #8,%sp /* pop parameters off stack*/ 170 bra ret_from_exception 171 172 inthandler5: 173 SAVE_ALL_INT 174 movew %sp@(PT_OFF_FORMATVEC), %d0 175 and #0x3ff, %d0 176 177 movel %sp,%sp@- 178 movel #69,%sp@- /* put vector # on stack*/ 179 jbsr process_int /* process the IRQ*/ 180 3: addql #8,%sp /* pop parameters off stack*/ 181 bra ret_from_exception 182 183 inthandler6: 184 SAVE_ALL_INT 185 movew %sp@(PT_OFF_FORMATVEC), %d0 186 and #0x3ff, %d0 187 188 movel %sp,%sp@- 189 movel #70,%sp@- /* put vector # on stack*/ 190 jbsr process_int /* process the IRQ*/ 191 3: addql #8,%sp /* pop parameters off stack*/ 192 bra ret_from_exception 193 194 inthandler7: 195 SAVE_ALL_INT 196 movew %sp@(PT_OFF_FORMATVEC), %d0 197 and #0x3ff, %d0 198 199 movel %sp,%sp@- 200 movel #71,%sp@- /* put vector # on stack*/ 201 jbsr process_int /* process the IRQ*/ 202 3: addql #8,%sp /* pop parameters off stack*/ 203 bra ret_from_exception 204 205 inthandler: 206 SAVE_ALL_INT 207 movew %sp@(PT_OFF_FORMATVEC), %d0 208 and #0x3ff, %d0 209 210 movel %sp,%sp@- 211 movel %d0,%sp@- /* put vector # on stack*/ 212 jbsr process_int /* process the IRQ*/ 213 3: addql #8,%sp /* pop parameters off stack*/ 214 bra ret_from_exception 215 216 /* 217 * Handler for uninitialized and spurious interrupts. 218 */ 219 ENTRY(bad_interrupt) 220 addql #1,irq_err_count 221 rte 222 223 /* 224 * Beware - when entering resume, prev (the current task) is 225 * in a0, next (the new task) is in a1, so don't change these 226 * registers until their contents are no longer needed. 227 */ 228 ENTRY(resume) 229 movel %a0,%d1 /* save prev thread in d1 */ 230 movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */ 231 SAVE_SWITCH_STACK 232 movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */ 233 movel %usp,%a3 /* save usp */ 234 movel %a3,%a0@(TASK_THREAD+THREAD_USP) 235 236 movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */ 237 movel %a3,%usp 238 movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */ 239 RESTORE_SWITCH_STACK 240 movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */ 241 rts 242 243