1/* 2 * entry.S - non-mmu 68360 interrupt and exceptions entry points 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * Copyright (C) 2001 SED Systems, a Division of Calian Ltd. 6 * 7 * This file is subject to the terms and conditions of the GNU General Public 8 * License. See the file README.legal in the main directory of this archive 9 * for more details. 10 * 11 * Linux/m68k support by Hamish Macdonald 12 * M68360 Port by SED Systems, and Lineo. 13 */ 14 15#include <linux/linkage.h> 16#include <asm/thread_info.h> 17#include <asm/unistd.h> 18#include <asm/errno.h> 19#include <asm/setup.h> 20#include <asm/segment.h> 21#include <asm/traps.h> 22#include <asm/asm-offsets.h> 23#include <asm/entry.h> 24 25.text 26 27.globl system_call 28.globl resume 29.globl ret_from_exception 30.globl ret_from_signal 31.globl sys_call_table 32.globl bad_interrupt 33.globl inthandler 34 35badsys: 36 movel #-ENOSYS,%sp@(PT_OFF_D0) 37 jra ret_from_exception 38 39do_trace: 40 movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ 41 subql #4,%sp 42 SAVE_SWITCH_STACK 43 jbsr syscall_trace_enter 44 RESTORE_SWITCH_STACK 45 addql #4,%sp 46 movel %sp@(PT_OFF_ORIG_D0),%d1 47 movel #-ENOSYS,%d0 48 cmpl #NR_syscalls,%d1 49 jcc 1f 50 lsl #2,%d1 51 lea sys_call_table, %a0 52 jbsr %a0@(%d1) 53 541: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ 55 subql #4,%sp /* dummy return address */ 56 SAVE_SWITCH_STACK 57 jbsr syscall_trace_leave 58 59ret_from_signal: 60 RESTORE_SWITCH_STACK 61 addql #4,%sp 62 jra ret_from_exception 63 64ENTRY(system_call) 65 SAVE_ALL_SYS 66 67 /* save top of frame*/ 68 pea %sp@ 69 jbsr set_esp0 70 addql #4,%sp 71 72 movel %sp@(PT_OFF_ORIG_D0),%d0 73 74 movel %sp,%d1 /* get thread_info pointer */ 75 andl #-THREAD_SIZE,%d1 76 movel %d1,%a2 77 btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) 78 jne do_trace 79 cmpl #NR_syscalls,%d0 80 jcc badsys 81 lsl #2,%d0 82 lea sys_call_table,%a0 83 movel %a0@(%d0), %a0 84 jbsr %a0@ 85 movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ 86 87ret_from_exception: 88 btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ 89 jeq Luser_return /* if so, skip resched, signals*/ 90 91Lkernel_return: 92 RESTORE_ALL 93 94Luser_return: 95 /* only allow interrupts when we are really the last one on the*/ 96 /* kernel stack, otherwise stack overflow can occur during*/ 97 /* heavy interrupt load*/ 98 andw #ALLOWINT,%sr 99 100 movel %sp,%d1 /* get thread_info pointer */ 101 andl #-THREAD_SIZE,%d1 102 movel %d1,%a2 1031: 104 move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 105 jne Lwork_to_do 106 RESTORE_ALL 107 108Lwork_to_do: 109 movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 110 btst #TIF_NEED_RESCHED,%d1 111 jne reschedule 112 113Lsignal_return: 114 subql #4,%sp /* dummy return address*/ 115 SAVE_SWITCH_STACK 116 pea %sp@(SWITCH_STACK_SIZE) 117 bsrw do_notify_resume 118 addql #4,%sp 119 RESTORE_SWITCH_STACK 120 addql #4,%sp 121 jra 1b 122 123/* 124 * This is the main interrupt handler, responsible for calling do_IRQ() 125 */ 126inthandler: 127 SAVE_ALL_INT 128 movew %sp@(PT_OFF_FORMATVEC), %d0 129 and.l #0x3ff, %d0 130 lsr.l #0x02, %d0 131 132 movel %sp,%sp@- 133 movel %d0,%sp@- /* put vector # on stack*/ 134 jbsr do_IRQ /* process the IRQ */ 135 addql #8,%sp /* pop parameters off stack*/ 136 jra ret_from_exception 137 138/* 139 * Handler for uninitialized and spurious interrupts. 140 */ 141bad_interrupt: 142 addql #1,irq_err_count 143 rte 144 145/* 146 * Beware - when entering resume, prev (the current task) is 147 * in a0, next (the new task) is in a1, so don't change these 148 * registers until their contents are no longer needed. 149 */ 150ENTRY(resume) 151 movel %a0,%d1 /* save prev thread in d1 */ 152 movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */ 153 SAVE_SWITCH_STACK 154 movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */ 155 movel %usp,%a3 /* save usp */ 156 movel %a3,%a0@(TASK_THREAD+THREAD_USP) 157 158 movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */ 159 movel %a3,%usp 160 movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */ 161 RESTORE_SWITCH_STACK 162 movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */ 163 rts 164 165