118cb3fafSGreg Ungerer/* 26f4a8856SGreg Ungerer * entry.S -- non-mmu 68000 interrupt and exception entry points 318cb3fafSGreg Ungerer * 418cb3fafSGreg Ungerer * Copyright (C) 1991, 1992 Linus Torvalds 518cb3fafSGreg Ungerer * 618cb3fafSGreg Ungerer * This file is subject to the terms and conditions of the GNU General Public 718cb3fafSGreg Ungerer * License. See the file README.legal in the main directory of this archive 818cb3fafSGreg Ungerer * for more details. 918cb3fafSGreg Ungerer * 1018cb3fafSGreg Ungerer * Linux/m68k support by Hamish Macdonald 1118cb3fafSGreg Ungerer */ 1218cb3fafSGreg Ungerer 1318cb3fafSGreg Ungerer#include <linux/linkage.h> 1418cb3fafSGreg Ungerer#include <asm/thread_info.h> 1518cb3fafSGreg Ungerer#include <asm/unistd.h> 1618cb3fafSGreg Ungerer#include <asm/errno.h> 1718cb3fafSGreg Ungerer#include <asm/setup.h> 1818cb3fafSGreg Ungerer#include <asm/traps.h> 1918cb3fafSGreg Ungerer#include <asm/asm-offsets.h> 2018cb3fafSGreg Ungerer#include <asm/entry.h> 2118cb3fafSGreg Ungerer 2218cb3fafSGreg Ungerer.text 2318cb3fafSGreg Ungerer 2418cb3fafSGreg Ungerer.globl system_call 2518cb3fafSGreg Ungerer.globl resume 2618cb3fafSGreg Ungerer.globl ret_from_exception 2718cb3fafSGreg Ungerer.globl sys_call_table 2818cb3fafSGreg Ungerer.globl bad_interrupt 2918cb3fafSGreg Ungerer.globl inthandler1 3018cb3fafSGreg Ungerer.globl inthandler2 3118cb3fafSGreg Ungerer.globl inthandler3 3218cb3fafSGreg Ungerer.globl inthandler4 3318cb3fafSGreg Ungerer.globl inthandler5 3418cb3fafSGreg Ungerer.globl inthandler6 3518cb3fafSGreg Ungerer.globl inthandler7 3618cb3fafSGreg Ungerer 3718cb3fafSGreg Ungererbadsys: 3818cb3fafSGreg Ungerer movel #-ENOSYS,%sp@(PT_OFF_D0) 3918cb3fafSGreg Ungerer jra ret_from_exception 4018cb3fafSGreg Ungerer 4118cb3fafSGreg Ungererdo_trace: 4218cb3fafSGreg Ungerer movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ 4318cb3fafSGreg Ungerer subql #4,%sp 4418cb3fafSGreg Ungerer SAVE_SWITCH_STACK 4518cb3fafSGreg Ungerer jbsr syscall_trace_enter 4618cb3fafSGreg Ungerer RESTORE_SWITCH_STACK 4718cb3fafSGreg Ungerer addql #4,%sp 48*2ca8a1deSMichael Schmitz addql #1,%d0 49*2ca8a1deSMichael Schmitz jeq ret_from_exception 5018cb3fafSGreg Ungerer movel %sp@(PT_OFF_ORIG_D0),%d1 5118cb3fafSGreg Ungerer movel #-ENOSYS,%d0 5218cb3fafSGreg Ungerer cmpl #NR_syscalls,%d1 5318cb3fafSGreg Ungerer jcc 1f 5418cb3fafSGreg Ungerer lsl #2,%d1 5518cb3fafSGreg Ungerer lea sys_call_table, %a0 5618cb3fafSGreg Ungerer jbsr %a0@(%d1) 5718cb3fafSGreg Ungerer 5818cb3fafSGreg Ungerer1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ 5918cb3fafSGreg Ungerer subql #4,%sp /* dummy return address */ 6018cb3fafSGreg Ungerer SAVE_SWITCH_STACK 6118cb3fafSGreg Ungerer jbsr syscall_trace_leave 6218cb3fafSGreg Ungerer RESTORE_SWITCH_STACK 6318cb3fafSGreg Ungerer addql #4,%sp 6418cb3fafSGreg Ungerer jra ret_from_exception 6518cb3fafSGreg Ungerer 6618cb3fafSGreg UngererENTRY(system_call) 6718cb3fafSGreg Ungerer SAVE_ALL_SYS 6818cb3fafSGreg Ungerer 6918cb3fafSGreg Ungerer /* save top of frame*/ 7018cb3fafSGreg Ungerer pea %sp@ 7118cb3fafSGreg Ungerer jbsr set_esp0 7218cb3fafSGreg Ungerer addql #4,%sp 7318cb3fafSGreg Ungerer 7418cb3fafSGreg Ungerer movel %sp@(PT_OFF_ORIG_D0),%d0 7518cb3fafSGreg Ungerer 7618cb3fafSGreg Ungerer movel %sp,%d1 /* get thread_info pointer */ 7718cb3fafSGreg Ungerer andl #-THREAD_SIZE,%d1 7818cb3fafSGreg Ungerer movel %d1,%a2 7918cb3fafSGreg Ungerer btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) 8018cb3fafSGreg Ungerer jne do_trace 8118cb3fafSGreg Ungerer cmpl #NR_syscalls,%d0 8218cb3fafSGreg Ungerer jcc badsys 8318cb3fafSGreg Ungerer lsl #2,%d0 8418cb3fafSGreg Ungerer lea sys_call_table,%a0 8518cb3fafSGreg Ungerer movel %a0@(%d0), %a0 8618cb3fafSGreg Ungerer jbsr %a0@ 8718cb3fafSGreg Ungerer movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ 8818cb3fafSGreg Ungerer 8918cb3fafSGreg Ungererret_from_exception: 9018cb3fafSGreg Ungerer btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ 9118cb3fafSGreg Ungerer jeq Luser_return /* if so, skip resched, signals*/ 9218cb3fafSGreg Ungerer 9318cb3fafSGreg UngererLkernel_return: 9418cb3fafSGreg Ungerer RESTORE_ALL 9518cb3fafSGreg Ungerer 9618cb3fafSGreg UngererLuser_return: 9718cb3fafSGreg Ungerer /* only allow interrupts when we are really the last one on the*/ 9818cb3fafSGreg Ungerer /* kernel stack, otherwise stack overflow can occur during*/ 9918cb3fafSGreg Ungerer /* heavy interrupt load*/ 10018cb3fafSGreg Ungerer andw #ALLOWINT,%sr 10118cb3fafSGreg Ungerer 10218cb3fafSGreg Ungerer movel %sp,%d1 /* get thread_info pointer */ 10318cb3fafSGreg Ungerer andl #-THREAD_SIZE,%d1 10418cb3fafSGreg Ungerer movel %d1,%a2 10518cb3fafSGreg Ungerer1: 10618cb3fafSGreg Ungerer move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 10718cb3fafSGreg Ungerer jne Lwork_to_do 10818cb3fafSGreg Ungerer RESTORE_ALL 10918cb3fafSGreg Ungerer 11018cb3fafSGreg UngererLwork_to_do: 11118cb3fafSGreg Ungerer movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 11218cb3fafSGreg Ungerer btst #TIF_NEED_RESCHED,%d1 11318cb3fafSGreg Ungerer jne reschedule 11418cb3fafSGreg Ungerer 11518cb3fafSGreg UngererLsignal_return: 11618cb3fafSGreg Ungerer subql #4,%sp /* dummy return address*/ 11718cb3fafSGreg Ungerer SAVE_SWITCH_STACK 11818cb3fafSGreg Ungerer pea %sp@(SWITCH_STACK_SIZE) 11918cb3fafSGreg Ungerer bsrw do_notify_resume 12018cb3fafSGreg Ungerer addql #4,%sp 12118cb3fafSGreg Ungerer RESTORE_SWITCH_STACK 12218cb3fafSGreg Ungerer addql #4,%sp 12318cb3fafSGreg Ungerer jra 1b 12418cb3fafSGreg Ungerer 12518cb3fafSGreg Ungerer/* 12618cb3fafSGreg Ungerer * This is the main interrupt handler, responsible for calling process_int() 12718cb3fafSGreg Ungerer */ 12818cb3fafSGreg Ungererinthandler1: 12918cb3fafSGreg Ungerer SAVE_ALL_INT 13018cb3fafSGreg Ungerer movew %sp@(PT_OFF_FORMATVEC), %d0 13118cb3fafSGreg Ungerer and #0x3ff, %d0 13218cb3fafSGreg Ungerer 13318cb3fafSGreg Ungerer movel %sp,%sp@- 13418cb3fafSGreg Ungerer movel #65,%sp@- /* put vector # on stack*/ 13518cb3fafSGreg Ungerer jbsr process_int /* process the IRQ*/ 13618cb3fafSGreg Ungerer3: addql #8,%sp /* pop parameters off stack*/ 13718cb3fafSGreg Ungerer bra ret_from_exception 13818cb3fafSGreg Ungerer 13918cb3fafSGreg Ungererinthandler2: 14018cb3fafSGreg Ungerer SAVE_ALL_INT 14118cb3fafSGreg Ungerer movew %sp@(PT_OFF_FORMATVEC), %d0 14218cb3fafSGreg Ungerer and #0x3ff, %d0 14318cb3fafSGreg Ungerer 14418cb3fafSGreg Ungerer movel %sp,%sp@- 14518cb3fafSGreg Ungerer movel #66,%sp@- /* put vector # on stack*/ 14618cb3fafSGreg Ungerer jbsr process_int /* process the IRQ*/ 14718cb3fafSGreg Ungerer3: addql #8,%sp /* pop parameters off stack*/ 14818cb3fafSGreg Ungerer bra ret_from_exception 14918cb3fafSGreg Ungerer 15018cb3fafSGreg Ungererinthandler3: 15118cb3fafSGreg Ungerer SAVE_ALL_INT 15218cb3fafSGreg Ungerer movew %sp@(PT_OFF_FORMATVEC), %d0 15318cb3fafSGreg Ungerer and #0x3ff, %d0 15418cb3fafSGreg Ungerer 15518cb3fafSGreg Ungerer movel %sp,%sp@- 15618cb3fafSGreg Ungerer movel #67,%sp@- /* put vector # on stack*/ 15718cb3fafSGreg Ungerer jbsr process_int /* process the IRQ*/ 15818cb3fafSGreg Ungerer3: addql #8,%sp /* pop parameters off stack*/ 15918cb3fafSGreg Ungerer bra ret_from_exception 16018cb3fafSGreg Ungerer 16118cb3fafSGreg Ungererinthandler4: 16218cb3fafSGreg Ungerer SAVE_ALL_INT 16318cb3fafSGreg Ungerer movew %sp@(PT_OFF_FORMATVEC), %d0 16418cb3fafSGreg Ungerer and #0x3ff, %d0 16518cb3fafSGreg Ungerer 16618cb3fafSGreg Ungerer movel %sp,%sp@- 16718cb3fafSGreg Ungerer movel #68,%sp@- /* put vector # on stack*/ 16818cb3fafSGreg Ungerer jbsr process_int /* process the IRQ*/ 16918cb3fafSGreg Ungerer3: addql #8,%sp /* pop parameters off stack*/ 17018cb3fafSGreg Ungerer bra ret_from_exception 17118cb3fafSGreg Ungerer 17218cb3fafSGreg Ungererinthandler5: 17318cb3fafSGreg Ungerer SAVE_ALL_INT 17418cb3fafSGreg Ungerer movew %sp@(PT_OFF_FORMATVEC), %d0 17518cb3fafSGreg Ungerer and #0x3ff, %d0 17618cb3fafSGreg Ungerer 17718cb3fafSGreg Ungerer movel %sp,%sp@- 17818cb3fafSGreg Ungerer movel #69,%sp@- /* put vector # on stack*/ 17918cb3fafSGreg Ungerer jbsr process_int /* process the IRQ*/ 18018cb3fafSGreg Ungerer3: addql #8,%sp /* pop parameters off stack*/ 18118cb3fafSGreg Ungerer bra ret_from_exception 18218cb3fafSGreg Ungerer 18318cb3fafSGreg Ungererinthandler6: 18418cb3fafSGreg Ungerer SAVE_ALL_INT 18518cb3fafSGreg Ungerer movew %sp@(PT_OFF_FORMATVEC), %d0 18618cb3fafSGreg Ungerer and #0x3ff, %d0 18718cb3fafSGreg Ungerer 18818cb3fafSGreg Ungerer movel %sp,%sp@- 18918cb3fafSGreg Ungerer movel #70,%sp@- /* put vector # on stack*/ 19018cb3fafSGreg Ungerer jbsr process_int /* process the IRQ*/ 19118cb3fafSGreg Ungerer3: addql #8,%sp /* pop parameters off stack*/ 19218cb3fafSGreg Ungerer bra ret_from_exception 19318cb3fafSGreg Ungerer 19418cb3fafSGreg Ungererinthandler7: 19518cb3fafSGreg Ungerer SAVE_ALL_INT 19618cb3fafSGreg Ungerer movew %sp@(PT_OFF_FORMATVEC), %d0 19718cb3fafSGreg Ungerer and #0x3ff, %d0 19818cb3fafSGreg Ungerer 19918cb3fafSGreg Ungerer movel %sp,%sp@- 20018cb3fafSGreg Ungerer movel #71,%sp@- /* put vector # on stack*/ 20118cb3fafSGreg Ungerer jbsr process_int /* process the IRQ*/ 20218cb3fafSGreg Ungerer3: addql #8,%sp /* pop parameters off stack*/ 20318cb3fafSGreg Ungerer bra ret_from_exception 20418cb3fafSGreg Ungerer 20518cb3fafSGreg Ungererinthandler: 20618cb3fafSGreg Ungerer SAVE_ALL_INT 20718cb3fafSGreg Ungerer movew %sp@(PT_OFF_FORMATVEC), %d0 20818cb3fafSGreg Ungerer and #0x3ff, %d0 20918cb3fafSGreg Ungerer 21018cb3fafSGreg Ungerer movel %sp,%sp@- 21118cb3fafSGreg Ungerer movel %d0,%sp@- /* put vector # on stack*/ 21218cb3fafSGreg Ungerer jbsr process_int /* process the IRQ*/ 21318cb3fafSGreg Ungerer3: addql #8,%sp /* pop parameters off stack*/ 21418cb3fafSGreg Ungerer bra ret_from_exception 21518cb3fafSGreg Ungerer 21618cb3fafSGreg Ungerer/* 21718cb3fafSGreg Ungerer * Handler for uninitialized and spurious interrupts. 21818cb3fafSGreg Ungerer */ 21918cb3fafSGreg UngererENTRY(bad_interrupt) 22018cb3fafSGreg Ungerer addql #1,irq_err_count 22118cb3fafSGreg Ungerer rte 22218cb3fafSGreg Ungerer 22318cb3fafSGreg Ungerer/* 22418cb3fafSGreg Ungerer * Beware - when entering resume, prev (the current task) is 22518cb3fafSGreg Ungerer * in a0, next (the new task) is in a1, so don't change these 22618cb3fafSGreg Ungerer * registers until their contents are no longer needed. 22718cb3fafSGreg Ungerer */ 22818cb3fafSGreg UngererENTRY(resume) 22918cb3fafSGreg Ungerer movel %a0,%d1 /* save prev thread in d1 */ 23018cb3fafSGreg Ungerer movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */ 23118cb3fafSGreg Ungerer SAVE_SWITCH_STACK 23218cb3fafSGreg Ungerer movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */ 23318cb3fafSGreg Ungerer movel %usp,%a3 /* save usp */ 23418cb3fafSGreg Ungerer movel %a3,%a0@(TASK_THREAD+THREAD_USP) 23518cb3fafSGreg Ungerer 23618cb3fafSGreg Ungerer movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */ 23718cb3fafSGreg Ungerer movel %a3,%usp 23818cb3fafSGreg Ungerer movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */ 23918cb3fafSGreg Ungerer RESTORE_SWITCH_STACK 24018cb3fafSGreg Ungerer movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */ 24118cb3fafSGreg Ungerer rts 24218cb3fafSGreg Ungerer 243