^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * entry.S -- interrupt and exception processing for ColdFire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Kenneth Albanowski <kjahds@kjahds.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Based on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * linux/arch/m68k/kernel/entry.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * License. See the file README.legal in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Linux/m68k support by Hamish Macdonald
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * 68060 fixes by Jesper Skov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * ColdFire support by Greg Ungerer (gerg@snapgear.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * 5307 fixes by David W. Miller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * linux 2.4 support David McCullough <davidm@snapgear.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/segment.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/entry.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifdef CONFIG_COLDFIRE_SW_A7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Define software copies of the supervisor and user stack pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .bss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) sw_ksp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) sw_usp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #endif /* CONFIG_COLDFIRE_SW_A7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .globl system_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .globl resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .globl ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .globl ret_from_signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .globl sys_call_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .globl inthandler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) enosys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) mov.l #sys_ni_syscall,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) bra 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ENTRY(system_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) SAVE_ALL_SYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) move #0x2000,%sr /* enable intrs again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) GET_CURRENT(%d2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) cmpl #NR_syscalls,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) jcc enosys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) lea sys_call_table,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) lsll #2,%d0 /* movel %a0@(%d0:l:4),%d3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) movel %a0@(%d0),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) jeq enosys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) movel %sp,%d2 /* get thread_info pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) andl #-THREAD_SIZE,%d2 /* at start of kernel stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) movel %d2,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) movel %a0@,%a1 /* save top of frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) movel %sp,%a1@(TASK_THREAD+THREAD_ESP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) btst #(TIF_SYSCALL_TRACE%8),%a0@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) bnes 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) movel %d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) jbsr %a0@
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) movel %d0,%sp@(PT_OFF_D0) /* save the return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) jra ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_OFF_D0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) movel %d2,PT_OFF_D0(%sp) /* on syscall entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) subql #4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) jbsr syscall_trace_enter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) addql #4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) movel %d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) jbsr %a0@
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) movel %d0,%sp@(PT_OFF_D0) /* save the return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) subql #4,%sp /* dummy return address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) jbsr syscall_trace_leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ret_from_signal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) addql #4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ret_from_exception:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) move #0x2700,%sr /* disable intrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) jeq Luser_return /* if so, skip resched, signals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #ifdef CONFIG_PREEMPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) movel %sp,%d1 /* get thread_info pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) movel %d1,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) andl #(1<<TIF_NEED_RESCHED),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) jeq Lkernel_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) movel %a0@(TINFO_PREEMPT),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cmpl #0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) jne Lkernel_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pea Lkernel_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) jmp preempt_schedule_irq /* preempt the kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) Lkernel_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) moveml %sp@,%d1-%d5/%a0-%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) lea %sp@(32),%sp /* space for 8 regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) movel %sp@+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) addql #4,%sp /* orig d0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) addl %sp@+,%sp /* stk adj */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) rte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) Luser_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) movel %sp,%d1 /* get thread_info pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) movel %d1,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) moveb %a0@(TINFO_FLAGS+3),%d1 /* thread_info->flags (low 8 bits) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) jne Lwork_to_do /* still work to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) Lreturn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) RESTORE_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) Lwork_to_do:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) move #0x2000,%sr /* enable intrs again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) btst #TIF_NEED_RESCHED,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) jne reschedule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) Lsignal_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) subql #4,%sp /* dummy return address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) pea %sp@(SWITCH_STACK_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) jsr do_notify_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) addql #4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) addql #4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) jmp Luser_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * This is the generic interrupt handler (for all hardware interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * sources). Calls up to high level code to do all the work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ENTRY(inthandler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) SAVE_ALL_INT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) GET_CURRENT(%d2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) andl #0x03fc,%d0 /* mask out vector only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) movel %sp,%sp@- /* push regs arg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) lsrl #2,%d0 /* calculate real vector # */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) movel %d0,%sp@- /* push vector number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) jbsr do_IRQ /* call high level irq handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) lea %sp@(8),%sp /* pop args off stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) bra ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * Beware - when entering resume, prev (the current task) is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * in a0, next (the new task) is in a1, so don't change these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * registers until their contents are no longer needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ENTRY(resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) movew %sr,%d1 /* save current status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) movew %d1,%a0@(TASK_THREAD+THREAD_SR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) movel %a0,%d1 /* get prev thread in d1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) SAVE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) RDUSP /* movel %usp,%a3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) movel %a3,%a0@(TASK_THREAD+THREAD_USP) /* save thread user stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) movel %a1,%a2 /* set new current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore thread user stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) WRUSP /* movel %a3,%usp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new kernel stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) movew %a1@(TASK_THREAD+THREAD_SR),%d7 /* restore new status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) movew %d7,%sr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) RESTORE_SWITCH_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)