114be4252SGreg Ungerer/* -*- mode: asm -*- 214be4252SGreg Ungerer * 314be4252SGreg Ungerer * linux/arch/m68k/kernel/entry.S 414be4252SGreg Ungerer * 514be4252SGreg Ungerer * Copyright (C) 1991, 1992 Linus Torvalds 614be4252SGreg Ungerer * 714be4252SGreg Ungerer * This file is subject to the terms and conditions of the GNU General Public 814be4252SGreg Ungerer * License. See the file README.legal in the main directory of this archive 914be4252SGreg Ungerer * for more details. 1014be4252SGreg Ungerer * 1114be4252SGreg Ungerer * Linux/m68k support by Hamish Macdonald 1214be4252SGreg Ungerer * 1314be4252SGreg Ungerer * 68060 fixes by Jesper Skov 1414be4252SGreg Ungerer * 1514be4252SGreg Ungerer */ 1614be4252SGreg Ungerer 1714be4252SGreg Ungerer/* 1814be4252SGreg Ungerer * entry.S contains the system-call and fault low-level handling routines. 1914be4252SGreg Ungerer * This also contains the timer-interrupt handler, as well as all interrupts 2014be4252SGreg Ungerer * and faults that can result in a task-switch. 2114be4252SGreg Ungerer * 2214be4252SGreg Ungerer * NOTE: This code handles signal-recognition, which happens every time 2314be4252SGreg Ungerer * after a timer-interrupt and after each system call. 2414be4252SGreg Ungerer * 2514be4252SGreg Ungerer */ 2614be4252SGreg Ungerer 2714be4252SGreg Ungerer/* 2814be4252SGreg Ungerer * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so 2914be4252SGreg Ungerer * all pointers that used to be 'current' are now entry 3014be4252SGreg Ungerer * number 0 in the 'current_set' list. 3114be4252SGreg Ungerer * 3214be4252SGreg Ungerer * 6/05/00 RZ: addedd writeback completion after return from sighandler 3314be4252SGreg Ungerer * for 68040 3414be4252SGreg Ungerer */ 3514be4252SGreg Ungerer 3614be4252SGreg Ungerer#include <linux/linkage.h> 3714be4252SGreg Ungerer#include <asm/errno.h> 3814be4252SGreg Ungerer#include <asm/setup.h> 3914be4252SGreg Ungerer#include <asm/traps.h> 4014be4252SGreg Ungerer#include <asm/unistd.h> 4114be4252SGreg Ungerer#include <asm/asm-offsets.h> 4214be4252SGreg Ungerer#include <asm/entry.h> 4314be4252SGreg Ungerer 4414be4252SGreg Ungerer.globl system_call, buserr, trap, resume 4514be4252SGreg Ungerer.globl sys_call_table 4620ecc91cSAl Viro.globl __sys_fork, __sys_clone, __sys_vfork 4709f90f66SThomas Gleixner.globl bad_interrupt 4814be4252SGreg Ungerer.globl auto_irqhandler_fixup 4914be4252SGreg Ungerer.globl user_irqvec_fixup 5014be4252SGreg Ungerer 5114be4252SGreg Ungerer.text 5220ecc91cSAl ViroENTRY(__sys_fork) 5314be4252SGreg Ungerer SAVE_SWITCH_STACK 5420ecc91cSAl Viro jbsr sys_fork 5520ecc91cSAl Viro lea %sp@(24),%sp 5614be4252SGreg Ungerer rts 5714be4252SGreg Ungerer 5820ecc91cSAl ViroENTRY(__sys_clone) 5914be4252SGreg Ungerer SAVE_SWITCH_STACK 6014be4252SGreg Ungerer pea %sp@(SWITCH_STACK_SIZE) 6114be4252SGreg Ungerer jbsr m68k_clone 6220ecc91cSAl Viro lea %sp@(28),%sp 6314be4252SGreg Ungerer rts 6414be4252SGreg Ungerer 6520ecc91cSAl ViroENTRY(__sys_vfork) 6614be4252SGreg Ungerer SAVE_SWITCH_STACK 6720ecc91cSAl Viro jbsr sys_vfork 6820ecc91cSAl Viro lea %sp@(24),%sp 6914be4252SGreg Ungerer rts 7014be4252SGreg Ungerer 71e8bb2a2aSKars de JongENTRY(__sys_clone3) 72e8bb2a2aSKars de Jong SAVE_SWITCH_STACK 73e8bb2a2aSKars de Jong pea %sp@(SWITCH_STACK_SIZE) 74e8bb2a2aSKars de Jong jbsr m68k_clone3 75e8bb2a2aSKars de Jong lea %sp@(28),%sp 76e8bb2a2aSKars de Jong rts 77e8bb2a2aSKars de Jong 7814be4252SGreg UngererENTRY(sys_sigreturn) 7914be4252SGreg Ungerer SAVE_SWITCH_STACK 800d20abdeSAl Viro movel %sp,%a1 | switch_stack pointer 810d20abdeSAl Viro lea %sp@(SWITCH_STACK_SIZE),%a0 | pt_regs pointer 820d20abdeSAl Viro lea %sp@(-84),%sp | leave a gap 830d20abdeSAl Viro movel %a1,%sp@- 840d20abdeSAl Viro movel %a0,%sp@- 8514be4252SGreg Ungerer jbsr do_sigreturn 860d20abdeSAl Viro jra 1f | shared with rt_sigreturn() 8714be4252SGreg Ungerer 8814be4252SGreg UngererENTRY(sys_rt_sigreturn) 8914be4252SGreg Ungerer SAVE_SWITCH_STACK 900d20abdeSAl Viro movel %sp,%a1 | switch_stack pointer 910d20abdeSAl Viro lea %sp@(SWITCH_STACK_SIZE),%a0 | pt_regs pointer 920d20abdeSAl Viro lea %sp@(-84),%sp | leave a gap 930d20abdeSAl Viro movel %a1,%sp@- 940d20abdeSAl Viro movel %a0,%sp@- 950d20abdeSAl Viro | stack contents: 960d20abdeSAl Viro | [original pt_regs address] [original switch_stack address] 970d20abdeSAl Viro | [gap] [switch_stack] [pt_regs] [exception frame] 9814be4252SGreg Ungerer jbsr do_rt_sigreturn 990d20abdeSAl Viro 1000d20abdeSAl Viro1: 1010d20abdeSAl Viro | stack contents now: 1020d20abdeSAl Viro | [original pt_regs address] [original switch_stack address] 1030d20abdeSAl Viro | [unused part of the gap] [moved switch_stack] [moved pt_regs] 1040d20abdeSAl Viro | [replacement exception frame] 1050d20abdeSAl Viro | return value of do_{rt_,}sigreturn() points to moved switch_stack. 1060d20abdeSAl Viro 1070d20abdeSAl Viro movel %d0,%sp | discard the leftover junk 10814be4252SGreg Ungerer RESTORE_SWITCH_STACK 1090d20abdeSAl Viro | stack contents now is just [syscall return address] [pt_regs] [frame] 1100d20abdeSAl Viro | return pt_regs.d0 1110d20abdeSAl Viro movel %sp@(PT_OFF_D0+4),%d0 11214be4252SGreg Ungerer rts 11314be4252SGreg Ungerer 11414be4252SGreg UngererENTRY(buserr) 11514be4252SGreg Ungerer SAVE_ALL_INT 11614be4252SGreg Ungerer GET_CURRENT(%d0) 11714be4252SGreg Ungerer movel %sp,%sp@- | stack frame pointer argument 11814be4252SGreg Ungerer jbsr buserr_c 11914be4252SGreg Ungerer addql #4,%sp 12014be4252SGreg Ungerer jra ret_from_exception 12114be4252SGreg Ungerer 12214be4252SGreg UngererENTRY(trap) 12314be4252SGreg Ungerer SAVE_ALL_INT 12414be4252SGreg Ungerer GET_CURRENT(%d0) 12514be4252SGreg Ungerer movel %sp,%sp@- | stack frame pointer argument 12614be4252SGreg Ungerer jbsr trap_c 12714be4252SGreg Ungerer addql #4,%sp 12814be4252SGreg Ungerer jra ret_from_exception 12914be4252SGreg Ungerer 13014be4252SGreg Ungerer | After a fork we jump here directly from resume, 13114be4252SGreg Ungerer | so that %d1 contains the previous task 13214be4252SGreg Ungerer | schedule_tail now used regardless of CONFIG_SMP 13314be4252SGreg UngererENTRY(ret_from_fork) 13414be4252SGreg Ungerer movel %d1,%sp@- 13514be4252SGreg Ungerer jsr schedule_tail 13614be4252SGreg Ungerer addql #4,%sp 13714be4252SGreg Ungerer jra ret_from_exception 13814be4252SGreg Ungerer 139533e6903SAl ViroENTRY(ret_from_kernel_thread) 140533e6903SAl Viro | a3 contains the kernel thread payload, d7 - its argument 141533e6903SAl Viro movel %d1,%sp@- 142533e6903SAl Viro jsr schedule_tail 143533e6903SAl Viro movel %d7,(%sp) 144533e6903SAl Viro jsr %a3@ 145533e6903SAl Viro addql #4,%sp 146d878d6daSAl Viro jra ret_from_exception 147d878d6daSAl Viro 14814be4252SGreg Ungerer#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU) 14914be4252SGreg Ungerer 15014be4252SGreg Ungerer#ifdef TRAP_DBG_INTERRUPT 15114be4252SGreg Ungerer 15214be4252SGreg Ungerer.globl dbginterrupt 15314be4252SGreg UngererENTRY(dbginterrupt) 15414be4252SGreg Ungerer SAVE_ALL_INT 15514be4252SGreg Ungerer GET_CURRENT(%d0) 15614be4252SGreg Ungerer movel %sp,%sp@- /* stack frame pointer argument */ 15714be4252SGreg Ungerer jsr dbginterrupt_c 15814be4252SGreg Ungerer addql #4,%sp 15914be4252SGreg Ungerer jra ret_from_exception 1601da177e4SLinus Torvalds#endif 16114be4252SGreg Ungerer 16214be4252SGreg UngererENTRY(reschedule) 16314be4252SGreg Ungerer /* save top of frame */ 16414be4252SGreg Ungerer pea %sp@ 16514be4252SGreg Ungerer jbsr set_esp0 16614be4252SGreg Ungerer addql #4,%sp 16714be4252SGreg Ungerer pea ret_from_exception 16814be4252SGreg Ungerer jmp schedule 16914be4252SGreg Ungerer 17014be4252SGreg UngererENTRY(ret_from_user_signal) 17114be4252SGreg Ungerer moveq #__NR_sigreturn,%d0 17214be4252SGreg Ungerer trap #0 17314be4252SGreg Ungerer 17414be4252SGreg UngererENTRY(ret_from_user_rt_signal) 17514be4252SGreg Ungerer movel #__NR_rt_sigreturn,%d0 17614be4252SGreg Ungerer trap #0 17714be4252SGreg Ungerer 17814be4252SGreg Ungerer#else 17914be4252SGreg Ungerer 18014be4252SGreg Ungererdo_trace_entry: 18114be4252SGreg Ungerer movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace 18214be4252SGreg Ungerer subql #4,%sp 18314be4252SGreg Ungerer SAVE_SWITCH_STACK 184c862fe70SMichael Schmitz jbsr syscall_trace_enter 18514be4252SGreg Ungerer RESTORE_SWITCH_STACK 18614be4252SGreg Ungerer addql #4,%sp 1872ca8a1deSMichael Schmitz addql #1,%d0 | optimization for cmpil #-1,%d0 1882ca8a1deSMichael Schmitz jeq ret_from_syscall 18914be4252SGreg Ungerer movel %sp@(PT_OFF_ORIG_D0),%d0 19014be4252SGreg Ungerer cmpl #NR_syscalls,%d0 19114be4252SGreg Ungerer jcs syscall 1922ca8a1deSMichael Schmitz jra ret_from_syscall 19314be4252SGreg Ungererbadsys: 19414be4252SGreg Ungerer movel #-ENOSYS,%sp@(PT_OFF_D0) 19514be4252SGreg Ungerer jra ret_from_syscall 19614be4252SGreg Ungerer 19714be4252SGreg Ungererdo_trace_exit: 19814be4252SGreg Ungerer subql #4,%sp 19914be4252SGreg Ungerer SAVE_SWITCH_STACK 200c862fe70SMichael Schmitz jbsr syscall_trace_leave 20114be4252SGreg Ungerer RESTORE_SWITCH_STACK 20214be4252SGreg Ungerer addql #4,%sp 20314be4252SGreg Ungerer jra .Lret_from_exception 20414be4252SGreg Ungerer 20514be4252SGreg UngererENTRY(system_call) 20614be4252SGreg Ungerer SAVE_ALL_SYS 20714be4252SGreg Ungerer 20814be4252SGreg Ungerer GET_CURRENT(%d1) 20914be4252SGreg Ungerer movel %d1,%a1 21014be4252SGreg Ungerer 21114be4252SGreg Ungerer | save top of frame 21214be4252SGreg Ungerer movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 21314be4252SGreg Ungerer 21414be4252SGreg Ungerer | syscall trace? 21514be4252SGreg Ungerer tstb %a1@(TINFO_FLAGS+2) 21614be4252SGreg Ungerer jmi do_trace_entry 2176baaade1SMichael Schmitz | seccomp filter active? 2186baaade1SMichael Schmitz btst #5,%a1@(TINFO_FLAGS+2) 2196baaade1SMichael Schmitz bnes do_trace_entry 22014be4252SGreg Ungerer cmpl #NR_syscalls,%d0 22114be4252SGreg Ungerer jcc badsys 22214be4252SGreg Ungerersyscall: 22314be4252SGreg Ungerer jbsr @(sys_call_table,%d0:l:4)@(0) 22414be4252SGreg Ungerer movel %d0,%sp@(PT_OFF_D0) | save the return value 22514be4252SGreg Ungererret_from_syscall: 22614be4252SGreg Ungerer |oriw #0x0700,%sr 22714be4252SGreg Ungerer movel %curptr@(TASK_STACK),%a1 22814be4252SGreg Ungerer movew %a1@(TINFO_FLAGS+2),%d0 22914be4252SGreg Ungerer jne syscall_exit_work 23014be4252SGreg Ungerer1: RESTORE_ALL 23114be4252SGreg Ungerer 23214be4252SGreg Ungerersyscall_exit_work: 23314be4252SGreg Ungerer btst #5,%sp@(PT_OFF_SR) | check if returning to kernel 23414be4252SGreg Ungerer bnes 1b | if so, skip resched, signals 23514be4252SGreg Ungerer lslw #1,%d0 23614be4252SGreg Ungerer jcs do_trace_exit 23714be4252SGreg Ungerer jmi do_delayed_trace 23814be4252SGreg Ungerer lslw #8,%d0 23914be4252SGreg Ungerer jne do_signal_return 24014be4252SGreg Ungerer pea resume_userspace 24114be4252SGreg Ungerer jra schedule 24214be4252SGreg Ungerer 24314be4252SGreg Ungerer 24414be4252SGreg UngererENTRY(ret_from_exception) 24514be4252SGreg Ungerer.Lret_from_exception: 24614be4252SGreg Ungerer btst #5,%sp@(PT_OFF_SR) | check if returning to kernel 24714be4252SGreg Ungerer bnes 1f | if so, skip resched, signals 24814be4252SGreg Ungerer | only allow interrupts when we are really the last one on the 24914be4252SGreg Ungerer | kernel stack, otherwise stack overflow can occur during 25014be4252SGreg Ungerer | heavy interrupt load 25114be4252SGreg Ungerer andw #ALLOWINT,%sr 25214be4252SGreg Ungerer 25314be4252SGreg Ungererresume_userspace: 25414be4252SGreg Ungerer movel %curptr@(TASK_STACK),%a1 25514be4252SGreg Ungerer moveb %a1@(TINFO_FLAGS+3),%d0 25614be4252SGreg Ungerer jne exit_work 25714be4252SGreg Ungerer1: RESTORE_ALL 25814be4252SGreg Ungerer 25914be4252SGreg Ungererexit_work: 26014be4252SGreg Ungerer | save top of frame 26114be4252SGreg Ungerer movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 26214be4252SGreg Ungerer lslb #1,%d0 26314be4252SGreg Ungerer jne do_signal_return 26414be4252SGreg Ungerer pea resume_userspace 26514be4252SGreg Ungerer jra schedule 26614be4252SGreg Ungerer 26714be4252SGreg Ungerer 26814be4252SGreg Ungererdo_signal_return: 26914be4252SGreg Ungerer |andw #ALLOWINT,%sr 27014be4252SGreg Ungerer subql #4,%sp | dummy return address 27114be4252SGreg Ungerer SAVE_SWITCH_STACK 27214be4252SGreg Ungerer pea %sp@(SWITCH_STACK_SIZE) 27314be4252SGreg Ungerer bsrl do_notify_resume 27414be4252SGreg Ungerer addql #4,%sp 27514be4252SGreg Ungerer RESTORE_SWITCH_STACK 27614be4252SGreg Ungerer addql #4,%sp 27714be4252SGreg Ungerer jbra resume_userspace 27814be4252SGreg Ungerer 27914be4252SGreg Ungererdo_delayed_trace: 28014be4252SGreg Ungerer bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR 28114be4252SGreg Ungerer pea 1 | send SIGTRAP 28214be4252SGreg Ungerer movel %curptr,%sp@- 28314be4252SGreg Ungerer pea LSIGTRAP 28414be4252SGreg Ungerer jbsr send_sig 28514be4252SGreg Ungerer addql #8,%sp 28614be4252SGreg Ungerer addql #4,%sp 28714be4252SGreg Ungerer jbra resume_userspace 28814be4252SGreg Ungerer 28914be4252SGreg Ungerer 29014be4252SGreg Ungerer/* This is the main interrupt handler for autovector interrupts */ 29114be4252SGreg Ungerer 29214be4252SGreg UngererENTRY(auto_inthandler) 29314be4252SGreg Ungerer SAVE_ALL_INT 29414be4252SGreg Ungerer GET_CURRENT(%d0) 29514be4252SGreg Ungerer | put exception # in d0 29614be4252SGreg Ungerer bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 29714be4252SGreg Ungerer subw #VEC_SPUR,%d0 29814be4252SGreg Ungerer 29914be4252SGreg Ungerer movel %sp,%sp@- 30014be4252SGreg Ungerer movel %d0,%sp@- | put vector # on stack 30114be4252SGreg Ungererauto_irqhandler_fixup = . + 2 30214be4252SGreg Ungerer jsr do_IRQ | process the IRQ 30314be4252SGreg Ungerer addql #8,%sp | pop parameters off stack 30409f90f66SThomas Gleixner jra ret_from_exception 30514be4252SGreg Ungerer 30614be4252SGreg Ungerer/* Handler for user defined interrupt vectors */ 30714be4252SGreg Ungerer 30814be4252SGreg UngererENTRY(user_inthandler) 30914be4252SGreg Ungerer SAVE_ALL_INT 31014be4252SGreg Ungerer GET_CURRENT(%d0) 31114be4252SGreg Ungerer | put exception # in d0 31214be4252SGreg Ungerer bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 31314be4252SGreg Ungereruser_irqvec_fixup = . + 2 31414be4252SGreg Ungerer subw #VEC_USER,%d0 31514be4252SGreg Ungerer 31614be4252SGreg Ungerer movel %sp,%sp@- 31714be4252SGreg Ungerer movel %d0,%sp@- | put vector # on stack 31814be4252SGreg Ungerer jsr do_IRQ | process the IRQ 31914be4252SGreg Ungerer addql #8,%sp | pop parameters off stack 32009f90f66SThomas Gleixner jra ret_from_exception 32114be4252SGreg Ungerer 32214be4252SGreg Ungerer/* Handler for uninitialized and spurious interrupts */ 32314be4252SGreg Ungerer 32414be4252SGreg UngererENTRY(bad_inthandler) 32514be4252SGreg Ungerer SAVE_ALL_INT 32614be4252SGreg Ungerer GET_CURRENT(%d0) 32714be4252SGreg Ungerer 32814be4252SGreg Ungerer movel %sp,%sp@- 32914be4252SGreg Ungerer jsr handle_badint 33014be4252SGreg Ungerer addql #4,%sp 33109f90f66SThomas Gleixner jra ret_from_exception 33214be4252SGreg Ungerer 33314be4252SGreg Ungererresume: 33414be4252SGreg Ungerer /* 33514be4252SGreg Ungerer * Beware - when entering resume, prev (the current task) is 33614be4252SGreg Ungerer * in a0, next (the new task) is in a1,so don't change these 33714be4252SGreg Ungerer * registers until their contents are no longer needed. 33814be4252SGreg Ungerer */ 33914be4252SGreg Ungerer 34014be4252SGreg Ungerer /* save sr */ 34114be4252SGreg Ungerer movew %sr,%a0@(TASK_THREAD+THREAD_SR) 34214be4252SGreg Ungerer 34314be4252SGreg Ungerer /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ 34414be4252SGreg Ungerer movec %sfc,%d0 3459fde0348SChristoph Hellwig movew %d0,%a0@(TASK_THREAD+THREAD_FC) 34614be4252SGreg Ungerer 34714be4252SGreg Ungerer /* save usp */ 34814be4252SGreg Ungerer /* it is better to use a movel here instead of a movew 8*) */ 34914be4252SGreg Ungerer movec %usp,%d0 35014be4252SGreg Ungerer movel %d0,%a0@(TASK_THREAD+THREAD_USP) 35114be4252SGreg Ungerer 35214be4252SGreg Ungerer /* save non-scratch registers on stack */ 35314be4252SGreg Ungerer SAVE_SWITCH_STACK 35414be4252SGreg Ungerer 35514be4252SGreg Ungerer /* save current kernel stack pointer */ 35614be4252SGreg Ungerer movel %sp,%a0@(TASK_THREAD+THREAD_KSP) 35714be4252SGreg Ungerer 35814be4252SGreg Ungerer /* save floating point context */ 35914be4252SGreg Ungerer#ifndef CONFIG_M68KFPU_EMU_ONLY 36014be4252SGreg Ungerer#ifdef CONFIG_M68KFPU_EMU 36114be4252SGreg Ungerer tstl m68k_fputype 36214be4252SGreg Ungerer jeq 3f 36314be4252SGreg Ungerer#endif 36414be4252SGreg Ungerer fsave %a0@(TASK_THREAD+THREAD_FPSTATE) 36514be4252SGreg Ungerer 36614be4252SGreg Ungerer#if defined(CONFIG_M68060) 36714be4252SGreg Ungerer#if !defined(CPU_M68060_ONLY) 36814be4252SGreg Ungerer btst #3,m68k_cputype+3 36914be4252SGreg Ungerer beqs 1f 37014be4252SGreg Ungerer#endif 37114be4252SGreg Ungerer /* The 060 FPU keeps status in bits 15-8 of the first longword */ 37214be4252SGreg Ungerer tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2) 37314be4252SGreg Ungerer jeq 3f 37414be4252SGreg Ungerer#if !defined(CPU_M68060_ONLY) 37514be4252SGreg Ungerer jra 2f 37614be4252SGreg Ungerer#endif 37714be4252SGreg Ungerer#endif /* CONFIG_M68060 */ 37814be4252SGreg Ungerer#if !defined(CPU_M68060_ONLY) 37914be4252SGreg Ungerer1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE) 38014be4252SGreg Ungerer jeq 3f 38114be4252SGreg Ungerer#endif 38214be4252SGreg Ungerer2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG) 38314be4252SGreg Ungerer fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL) 38414be4252SGreg Ungerer3: 38514be4252SGreg Ungerer#endif /* CONFIG_M68KFPU_EMU_ONLY */ 38614be4252SGreg Ungerer /* Return previous task in %d1 */ 38714be4252SGreg Ungerer movel %curptr,%d1 38814be4252SGreg Ungerer 38914be4252SGreg Ungerer /* switch to new task (a1 contains new task) */ 39014be4252SGreg Ungerer movel %a1,%curptr 39114be4252SGreg Ungerer 39214be4252SGreg Ungerer /* restore floating point context */ 39314be4252SGreg Ungerer#ifndef CONFIG_M68KFPU_EMU_ONLY 39414be4252SGreg Ungerer#ifdef CONFIG_M68KFPU_EMU 39514be4252SGreg Ungerer tstl m68k_fputype 39614be4252SGreg Ungerer jeq 4f 39714be4252SGreg Ungerer#endif 39814be4252SGreg Ungerer#if defined(CONFIG_M68060) 39914be4252SGreg Ungerer#if !defined(CPU_M68060_ONLY) 40014be4252SGreg Ungerer btst #3,m68k_cputype+3 40114be4252SGreg Ungerer beqs 1f 40214be4252SGreg Ungerer#endif 40314be4252SGreg Ungerer /* The 060 FPU keeps status in bits 15-8 of the first longword */ 40414be4252SGreg Ungerer tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2) 40514be4252SGreg Ungerer jeq 3f 40614be4252SGreg Ungerer#if !defined(CPU_M68060_ONLY) 40714be4252SGreg Ungerer jra 2f 40814be4252SGreg Ungerer#endif 40914be4252SGreg Ungerer#endif /* CONFIG_M68060 */ 41014be4252SGreg Ungerer#if !defined(CPU_M68060_ONLY) 41114be4252SGreg Ungerer1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE) 41214be4252SGreg Ungerer jeq 3f 41314be4252SGreg Ungerer#endif 41414be4252SGreg Ungerer2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7 41514be4252SGreg Ungerer fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar 41614be4252SGreg Ungerer3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE) 41714be4252SGreg Ungerer4: 41814be4252SGreg Ungerer#endif /* CONFIG_M68KFPU_EMU_ONLY */ 41914be4252SGreg Ungerer 42014be4252SGreg Ungerer /* restore the kernel stack pointer */ 42114be4252SGreg Ungerer movel %a1@(TASK_THREAD+THREAD_KSP),%sp 42214be4252SGreg Ungerer 42314be4252SGreg Ungerer /* restore non-scratch registers */ 42414be4252SGreg Ungerer RESTORE_SWITCH_STACK 42514be4252SGreg Ungerer 42614be4252SGreg Ungerer /* restore user stack pointer */ 42714be4252SGreg Ungerer movel %a1@(TASK_THREAD+THREAD_USP),%a0 42814be4252SGreg Ungerer movel %a0,%usp 42914be4252SGreg Ungerer 43014be4252SGreg Ungerer /* restore fs (sfc,%dfc) */ 4319fde0348SChristoph Hellwig movew %a1@(TASK_THREAD+THREAD_FC),%a0 43214be4252SGreg Ungerer movec %a0,%sfc 43314be4252SGreg Ungerer movec %a0,%dfc 43414be4252SGreg Ungerer 43514be4252SGreg Ungerer /* restore status register */ 436*f3baf0f4SMichael Schmitz movew %a1@(TASK_THREAD+THREAD_SR),%d0 437*f3baf0f4SMichael Schmitz oriw #0x0700,%d0 438*f3baf0f4SMichael Schmitz movew %d0,%sr 43914be4252SGreg Ungerer 44014be4252SGreg Ungerer rts 44114be4252SGreg Ungerer 44214be4252SGreg Ungerer#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */ 443