^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2003 - 2008 Paul Mundt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) ! NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) ! to be jumped is too far, but it causes illegal slot exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * entry.S contains the system-call and fault low-level handling routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This also contains the timer-interrupt handler, as well as all interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * and faults that can result in a task-switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * NOTE: This code handles signal-recognition, which happens every time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * after a timer-interrupt and after each system call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * NOTE: This code uses a convention that instructions in the delay slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * of a transfer-control instruction are indented by an extra space, thus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * jmp @k0 ! control-transfer instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * ldc k1, ssr ! delay slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Stack layout in 'ret_from_syscall':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * ptrace needs to have all regs on the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * if the order here is changed, it needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * updated in ptrace.c and ptrace.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * r15 = stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * spc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * pr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * ssr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * gbr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * mach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * macl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * syscall #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/dwarf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #if defined(CONFIG_PREEMPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) # define preempt_stop() cli ; TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) # define preempt_stop()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) # define resume_kernel __restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ENTRY(exception_error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) TRACE_IRQS_ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) sti
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mov.l 1f, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) jmp @r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 1: .long do_exception_error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ret_from_exception:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) CFI_STARTPROC simple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) CFI_DEF_CFA r14, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) CFI_REL_OFFSET 17, 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) CFI_REL_OFFSET 15, 60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) CFI_REL_OFFSET 14, 56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) CFI_REL_OFFSET 13, 52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) CFI_REL_OFFSET 12, 48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) CFI_REL_OFFSET 11, 44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) CFI_REL_OFFSET 10, 40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) CFI_REL_OFFSET 9, 36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) CFI_REL_OFFSET 8, 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) preempt_stop()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ENTRY(ret_from_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) mov #OFF_SR, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) mov.l @(r0,r15), r0 ! get status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) shll r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) shll r0 ! kernel space?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) get_current_thread_info r8, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) bt resume_kernel ! Yes, it's from kernel, go back soon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #ifdef CONFIG_PREEMPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) bra resume_userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ENTRY(resume_kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) cli
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) tst r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) bf noresched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) need_resched:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) bt noresched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) mov #OFF_SR, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mov.l @(r0,r15), r0 ! get status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) shlr r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) and #(0xf0>>1), r0 ! interrupts off (exception path)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) cmp/eq #(0xf0>>1), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) bt noresched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) mov.l 1f, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) jsr @r0 ! call preempt_schedule_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bra need_resched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) noresched:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bra __restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 1: .long preempt_schedule_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ENTRY(resume_userspace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ! r8: current_thread_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) cli
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) tst #(_TIF_WORK_MASK & 0xff), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) bt/s __restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) tst #_TIF_NEED_RESCHED, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) work_pending:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ! r0: current_thread_info->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ! r8: current_thread_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ! t: result of "tst #_TIF_NEED_RESCHED, r0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) bf/s work_resched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) tst #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) work_notifysig:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) bt/s __restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) mov r15, r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) mov r12, r5 ! set arg1(save_r0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mov r0, r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) sti
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mov.l 2f, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) mov.l 3f, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) jmp @r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) lds r0, pr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) work_resched:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mov.l 1f, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) jsr @r1 ! schedule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) cli
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) tst #(_TIF_WORK_MASK & 0xff), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) bt __restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) bra work_pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) tst #_TIF_NEED_RESCHED, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 1: .long schedule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 2: .long do_notify_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 3: .long resume_userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) syscall_exit_work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ! r0: current_thread_info->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ! r8: current_thread_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) bt/s work_pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) tst #_TIF_NEED_RESCHED, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) TRACE_IRQS_ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) sti
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) mov r15, r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mov.l 8f, r0 ! do_syscall_trace_leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) jsr @r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) bra resume_userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) __restore_all:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) mov #OFF_SR, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) mov.l @(r0,r15), r0 ! get status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) shlr2 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) and #0x3c, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) cmp/eq #0x3c, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) bt 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) TRACE_IRQS_ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bra 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) mov.l 3f, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) jmp @r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 3: .long restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) syscall_badsys: ! Bad syscall number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) get_current_thread_info r8, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) mov #-ENOSYS, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) bra resume_userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) mov.l r0, @(OFF_R0,r15) ! Return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * The main debug trap handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * r8=TRA (not the trap number!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Note: This assumes that the trapa value is left in its original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * form (without the shlr2 shift) so the calculation for the jump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * call table offset remains a simple in place mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) debug_trap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) mov r8, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) and #(0xf << 2), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) mov.l 1f, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) add r0, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mov.l @r8, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) jsr @r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) bra ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) CFI_ENDPROC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 1: .long debug_trap_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Syscall interface:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Syscall #: R3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * Arguments #0 to #3: R4--R7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * Arguments #4 to #6: R0, R1, R2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * TRA: See following table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * (TRA>>2) Purpose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * -------- -------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * 0x00-0x0f original SH-3/4 syscall ABI (not in general use).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * 0x10-0x1f general SH-3/4 syscall ABI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * 0x1f unified SH-2/3/4 syscall ABI (preferred).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * 0x20-0x2f original SH-2 syscall ABI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * 0x30-0x3f debug traps used by the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * 0x40-0xff Not supported by all parts, so left unhandled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * For making system calls, any trap number in the range for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * given cpu model may be used, but the unified trap number 0x1f is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * preferred for compatibility with all models.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * The low bits of the trap number were once documented as matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * the number of arguments, but they were never actually used as such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * by the kernel. SH-2 originally used its own separate trap range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * because several hardware exceptions fell in the range used for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * SH-3/4 syscall ABI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * This code also handles delegating other traps to the BIOS/gdb stub.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * Note: When we're first called, the TRA value must be shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * right 2 bits in order to get the value that was used as the "trapa"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .globl ret_from_fork
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret_from_fork:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) mov.l 1f, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) jsr @r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) mov r0, r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) bra syscall_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .globl ret_from_kernel_thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ret_from_kernel_thread:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) mov.l 1f, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) jsr @r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) mov r0, r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mov.l @(OFF_R5,r15), r5 ! fn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) jsr @r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mov.l @(OFF_R4,r15), r4 ! arg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) bra syscall_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 1: .long schedule_tail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * The poorly named main trapa decode and dispatch routine, for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * system calls and debug traps through their respective jump tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ENTRY(system_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) setup_frame_reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #if !defined(CONFIG_CPU_SH2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) mov.l 1f, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) mov.l @r9, r8 ! Read from TRA (Trap Address) Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) mov #OFF_TRA, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) add r15, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) mov.l r8, @r10 ! set TRA value to tra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * Check the trap type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) mov #((0x20 << 2) - 1), r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) cmp/hi r9, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) bt/s debug_trap ! it's a debug trap..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) TRACE_IRQS_ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) sti
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) get_current_thread_info r8, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) mov.l @(TI_FLAGS,r8), r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) mov #(_TIF_WORK_SYSCALL_MASK & 0xff), r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mov #(_TIF_WORK_SYSCALL_MASK >> 8), r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) tst r10, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) shll8 r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) bf syscall_trace_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) tst r9, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) bf syscall_trace_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) mov.l 6f, r8 ! Number of syscalls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) cmp/hs r8, r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) bt syscall_badsys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) syscall_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) shll2 r3 ! x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mov.l 3f, r8 ! Load the address of sys_call_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) add r8, r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) mov.l @r3, r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) mov.l @(OFF_R2,r15), r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) mov.l @(OFF_R1,r15), r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) mov.l @(OFF_R0,r15), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) mov.l r2, @-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) mov.l r1, @-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mov.l r0, @-r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) jsr @r8 ! jump to specific syscall handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) add #12, r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) mov.l @(OFF_R0,r15), r12 ! save r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) mov.l r0, @(OFF_R0,r15) ! save the return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) syscall_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) cli
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) get_current_thread_info r8, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) tst #(_TIF_ALLWORK_MASK & 0xff), r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) mov #(_TIF_ALLWORK_MASK >> 8), r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) bf syscall_exit_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) shlr8 r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) tst r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) bf syscall_exit_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) bra __restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) syscall_trace_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ! Yes it is traced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) mov r15, r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) mov.l 7f, r11 ! Call do_syscall_trace_enter which notifies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) jsr @r11 ! superior (will chomp R[0-7])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) cmp/eq #-1, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) bt syscall_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ! Reload R0-R4 from kernel stack, where the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ! parent may have modified them using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ! ptrace(POKEUSR). (Note that R0-R2 are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ! reloaded from the kernel stack by syscall_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ! below, so don't need to be reloaded here.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ! This allows the parent to rewrite system calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ! and args on the fly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) mov.l @(OFF_R4,r15), r4 ! arg0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mov.l @(OFF_R5,r15), r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) mov.l @(OFF_R6,r15), r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mov.l @(OFF_R7,r15), r7 ! arg3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) mov.l @(OFF_R3,r15), r3 ! syscall_nr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mov.l 6f, r10 ! Number of syscalls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) cmp/hs r10, r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) bf syscall_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) mov #-ENOSYS, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) bra syscall_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) mov.l r0, @(OFF_R0,r15) ! Return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .align 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #if !defined(CONFIG_CPU_SH2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 1: .long TRA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 6: .long NR_syscalls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 3: .long sys_call_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 7: .long do_syscall_trace_enter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 8: .long do_syscall_trace_leave