162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * entry.S -- non-mmu 68000 interrupt and exception entry points 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 1991, 1992 Linus Torvalds 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 762306a36Sopenharmony_ci * License. See the file README.legal in the main directory of this archive 862306a36Sopenharmony_ci * for more details. 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Linux/m68k support by Hamish Macdonald 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/linkage.h> 1462306a36Sopenharmony_ci#include <asm/thread_info.h> 1562306a36Sopenharmony_ci#include <asm/unistd.h> 1662306a36Sopenharmony_ci#include <asm/errno.h> 1762306a36Sopenharmony_ci#include <asm/setup.h> 1862306a36Sopenharmony_ci#include <asm/traps.h> 1962306a36Sopenharmony_ci#include <asm/asm-offsets.h> 2062306a36Sopenharmony_ci#include <asm/entry.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci.text 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci.globl system_call 2562306a36Sopenharmony_ci.globl resume 2662306a36Sopenharmony_ci.globl ret_from_exception 2762306a36Sopenharmony_ci.globl sys_call_table 2862306a36Sopenharmony_ci.globl bad_interrupt 2962306a36Sopenharmony_ci.globl inthandler1 3062306a36Sopenharmony_ci.globl inthandler2 3162306a36Sopenharmony_ci.globl inthandler3 3262306a36Sopenharmony_ci.globl inthandler4 3362306a36Sopenharmony_ci.globl inthandler5 3462306a36Sopenharmony_ci.globl inthandler6 3562306a36Sopenharmony_ci.globl inthandler7 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cibadsys: 3862306a36Sopenharmony_ci movel #-ENOSYS,%sp@(PT_OFF_D0) 3962306a36Sopenharmony_ci jra ret_from_exception 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cido_trace: 4262306a36Sopenharmony_ci movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ 4362306a36Sopenharmony_ci subql #4,%sp 4462306a36Sopenharmony_ci SAVE_SWITCH_STACK 4562306a36Sopenharmony_ci jbsr syscall_trace_enter 4662306a36Sopenharmony_ci RESTORE_SWITCH_STACK 4762306a36Sopenharmony_ci addql #4,%sp 4862306a36Sopenharmony_ci addql #1,%d0 4962306a36Sopenharmony_ci jeq ret_from_exception 5062306a36Sopenharmony_ci movel %sp@(PT_OFF_ORIG_D0),%d1 5162306a36Sopenharmony_ci movel #-ENOSYS,%d0 5262306a36Sopenharmony_ci cmpl #NR_syscalls,%d1 5362306a36Sopenharmony_ci jcc 1f 5462306a36Sopenharmony_ci lsl #2,%d1 5562306a36Sopenharmony_ci lea sys_call_table, %a0 5662306a36Sopenharmony_ci jbsr %a0@(%d1) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ 5962306a36Sopenharmony_ci subql #4,%sp /* dummy return address */ 6062306a36Sopenharmony_ci SAVE_SWITCH_STACK 6162306a36Sopenharmony_ci jbsr syscall_trace_leave 6262306a36Sopenharmony_ci RESTORE_SWITCH_STACK 6362306a36Sopenharmony_ci addql #4,%sp 6462306a36Sopenharmony_ci jra ret_from_exception 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ciENTRY(system_call) 6762306a36Sopenharmony_ci SAVE_ALL_SYS 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci /* save top of frame*/ 7062306a36Sopenharmony_ci pea %sp@ 7162306a36Sopenharmony_ci jbsr set_esp0 7262306a36Sopenharmony_ci addql #4,%sp 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci movel %sp@(PT_OFF_ORIG_D0),%d0 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci movel %sp,%d1 /* get thread_info pointer */ 7762306a36Sopenharmony_ci andl #-THREAD_SIZE,%d1 7862306a36Sopenharmony_ci movel %d1,%a2 7962306a36Sopenharmony_ci btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) 8062306a36Sopenharmony_ci jne do_trace 8162306a36Sopenharmony_ci cmpl #NR_syscalls,%d0 8262306a36Sopenharmony_ci jcc badsys 8362306a36Sopenharmony_ci lsl #2,%d0 8462306a36Sopenharmony_ci lea sys_call_table,%a0 8562306a36Sopenharmony_ci movel %a0@(%d0), %a0 8662306a36Sopenharmony_ci jbsr %a0@ 8762306a36Sopenharmony_ci movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciret_from_exception: 9062306a36Sopenharmony_ci btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ 9162306a36Sopenharmony_ci jeq Luser_return /* if so, skip resched, signals*/ 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ciLkernel_return: 9462306a36Sopenharmony_ci RESTORE_ALL 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ciLuser_return: 9762306a36Sopenharmony_ci /* only allow interrupts when we are really the last one on the*/ 9862306a36Sopenharmony_ci /* kernel stack, otherwise stack overflow can occur during*/ 9962306a36Sopenharmony_ci /* heavy interrupt load*/ 10062306a36Sopenharmony_ci andw #ALLOWINT,%sr 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci movel %sp,%d1 /* get thread_info pointer */ 10362306a36Sopenharmony_ci andl #-THREAD_SIZE,%d1 10462306a36Sopenharmony_ci movel %d1,%a2 10562306a36Sopenharmony_ci1: 10662306a36Sopenharmony_ci move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 10762306a36Sopenharmony_ci jne Lwork_to_do 10862306a36Sopenharmony_ci RESTORE_ALL 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ciLwork_to_do: 11162306a36Sopenharmony_ci movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 11262306a36Sopenharmony_ci btst #TIF_NEED_RESCHED,%d1 11362306a36Sopenharmony_ci jne reschedule 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ciLsignal_return: 11662306a36Sopenharmony_ci subql #4,%sp /* dummy return address*/ 11762306a36Sopenharmony_ci SAVE_SWITCH_STACK 11862306a36Sopenharmony_ci pea %sp@(SWITCH_STACK_SIZE) 11962306a36Sopenharmony_ci bsrw do_notify_resume 12062306a36Sopenharmony_ci addql #4,%sp 12162306a36Sopenharmony_ci RESTORE_SWITCH_STACK 12262306a36Sopenharmony_ci addql #4,%sp 12362306a36Sopenharmony_ci jra 1b 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci/* 12662306a36Sopenharmony_ci * This is the main interrupt handler, responsible for calling process_int() 12762306a36Sopenharmony_ci */ 12862306a36Sopenharmony_ciinthandler1: 12962306a36Sopenharmony_ci SAVE_ALL_INT 13062306a36Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 13162306a36Sopenharmony_ci and #0x3ff, %d0 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci movel %sp,%sp@- 13462306a36Sopenharmony_ci movel #65,%sp@- /* put vector # on stack*/ 13562306a36Sopenharmony_ci jbsr process_int /* process the IRQ*/ 13662306a36Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 13762306a36Sopenharmony_ci bra ret_from_exception 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ciinthandler2: 14062306a36Sopenharmony_ci SAVE_ALL_INT 14162306a36Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 14262306a36Sopenharmony_ci and #0x3ff, %d0 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci movel %sp,%sp@- 14562306a36Sopenharmony_ci movel #66,%sp@- /* put vector # on stack*/ 14662306a36Sopenharmony_ci jbsr process_int /* process the IRQ*/ 14762306a36Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 14862306a36Sopenharmony_ci bra ret_from_exception 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ciinthandler3: 15162306a36Sopenharmony_ci SAVE_ALL_INT 15262306a36Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 15362306a36Sopenharmony_ci and #0x3ff, %d0 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci movel %sp,%sp@- 15662306a36Sopenharmony_ci movel #67,%sp@- /* put vector # on stack*/ 15762306a36Sopenharmony_ci jbsr process_int /* process the IRQ*/ 15862306a36Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 15962306a36Sopenharmony_ci bra ret_from_exception 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ciinthandler4: 16262306a36Sopenharmony_ci SAVE_ALL_INT 16362306a36Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 16462306a36Sopenharmony_ci and #0x3ff, %d0 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci movel %sp,%sp@- 16762306a36Sopenharmony_ci movel #68,%sp@- /* put vector # on stack*/ 16862306a36Sopenharmony_ci jbsr process_int /* process the IRQ*/ 16962306a36Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 17062306a36Sopenharmony_ci bra ret_from_exception 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ciinthandler5: 17362306a36Sopenharmony_ci SAVE_ALL_INT 17462306a36Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 17562306a36Sopenharmony_ci and #0x3ff, %d0 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci movel %sp,%sp@- 17862306a36Sopenharmony_ci movel #69,%sp@- /* put vector # on stack*/ 17962306a36Sopenharmony_ci jbsr process_int /* process the IRQ*/ 18062306a36Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 18162306a36Sopenharmony_ci bra ret_from_exception 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ciinthandler6: 18462306a36Sopenharmony_ci SAVE_ALL_INT 18562306a36Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 18662306a36Sopenharmony_ci and #0x3ff, %d0 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci movel %sp,%sp@- 18962306a36Sopenharmony_ci movel #70,%sp@- /* put vector # on stack*/ 19062306a36Sopenharmony_ci jbsr process_int /* process the IRQ*/ 19162306a36Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 19262306a36Sopenharmony_ci bra ret_from_exception 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ciinthandler7: 19562306a36Sopenharmony_ci SAVE_ALL_INT 19662306a36Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 19762306a36Sopenharmony_ci and #0x3ff, %d0 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci movel %sp,%sp@- 20062306a36Sopenharmony_ci movel #71,%sp@- /* put vector # on stack*/ 20162306a36Sopenharmony_ci jbsr process_int /* process the IRQ*/ 20262306a36Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 20362306a36Sopenharmony_ci bra ret_from_exception 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ciinthandler: 20662306a36Sopenharmony_ci SAVE_ALL_INT 20762306a36Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 20862306a36Sopenharmony_ci and #0x3ff, %d0 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci movel %sp,%sp@- 21162306a36Sopenharmony_ci movel %d0,%sp@- /* put vector # on stack*/ 21262306a36Sopenharmony_ci jbsr process_int /* process the IRQ*/ 21362306a36Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 21462306a36Sopenharmony_ci bra ret_from_exception 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci/* 21762306a36Sopenharmony_ci * Handler for uninitialized and spurious interrupts. 21862306a36Sopenharmony_ci */ 21962306a36Sopenharmony_ciENTRY(bad_interrupt) 22062306a36Sopenharmony_ci addql #1,irq_err_count 22162306a36Sopenharmony_ci rte 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci/* 22462306a36Sopenharmony_ci * Beware - when entering resume, prev (the current task) is 22562306a36Sopenharmony_ci * in a0, next (the new task) is in a1, so don't change these 22662306a36Sopenharmony_ci * registers until their contents are no longer needed. 22762306a36Sopenharmony_ci */ 22862306a36Sopenharmony_ciENTRY(resume) 22962306a36Sopenharmony_ci movel %a0,%d1 /* save prev thread in d1 */ 23062306a36Sopenharmony_ci movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */ 23162306a36Sopenharmony_ci SAVE_SWITCH_STACK 23262306a36Sopenharmony_ci movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */ 23362306a36Sopenharmony_ci movel %usp,%a3 /* save usp */ 23462306a36Sopenharmony_ci movel %a3,%a0@(TASK_THREAD+THREAD_USP) 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */ 23762306a36Sopenharmony_ci movel %a3,%usp 23862306a36Sopenharmony_ci movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */ 23962306a36Sopenharmony_ci RESTORE_SWITCH_STACK 24062306a36Sopenharmony_ci movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */ 24162306a36Sopenharmony_ci rts 24262306a36Sopenharmony_ci 243