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