^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2001 MIPS Technologies, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/regdef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/stackframe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/isadep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/war.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #ifndef CONFIG_PREEMPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define resume_kernel restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define __ret_from_irq ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #ifndef CONFIG_PREEMPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) FEXPORT(ret_from_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) local_irq_disable # preempt stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) b __ret_from_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) FEXPORT(ret_from_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) LONG_S s0, TI_REGS($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) FEXPORT(__ret_from_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * We can be coming here from a syscall done in the kernel space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * e.g. a failed kernel_execve().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) resume_userspace_check:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) andi t0, t0, KU_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) beqz t0, resume_kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) resume_userspace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) local_irq_disable # make sure we dont miss an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) # interrupt setting need_resched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) # between sampling and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) LONG_L a2, TI_FLAGS($28) # current->work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) bnez t0, work_pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) j restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #ifdef CONFIG_PREEMPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) resume_kernel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) local_irq_disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) lw t0, TI_PRE_COUNT($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) bnez t0, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) LONG_L t0, TI_FLAGS($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) andi t1, t0, _TIF_NEED_RESCHED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) beqz t1, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) LONG_L t0, PT_STATUS(sp) # Interrupts off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) andi t0, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) beqz t0, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) PTR_LA ra, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) j preempt_schedule_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) FEXPORT(ret_from_kernel_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) jal schedule_tail # a0 = struct task_struct *prev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) move a0, s1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) jal s0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) j syscall_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) FEXPORT(ret_from_fork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) jal schedule_tail # a0 = struct task_struct *prev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) FEXPORT(syscall_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #ifdef CONFIG_DEBUG_RSEQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) move a0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) jal rseq_syscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) local_irq_disable # make sure need_resched and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) # signals dont change between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) # sampling and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) LONG_L a2, TI_FLAGS($28) # current->work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) li t0, _TIF_ALLWORK_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) and t0, a2, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) bnez t0, syscall_exit_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) restore_all: # restore full frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) RESTORE_TEMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) RESTORE_AT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) RESTORE_STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) restore_partial: # restore partial frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #ifdef CONFIG_TRACE_IRQFLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) SAVE_STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) SAVE_AT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) SAVE_TEMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) LONG_L v0, PT_STATUS(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) and v0, ST0_IEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) and v0, ST0_IE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) beqz v0, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) jal trace_hardirqs_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) b 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 1: jal trace_hardirqs_off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) RESTORE_TEMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) RESTORE_AT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) RESTORE_STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) RESTORE_SOME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) RESTORE_SP_AND_RET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .set at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) work_pending:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) beqz t0, work_notifysig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) work_resched:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) TRACE_IRQS_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) jal schedule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) local_irq_disable # make sure need_resched and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) # signals dont change between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) # sampling and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) LONG_L a2, TI_FLAGS($28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) andi t0, a2, _TIF_WORK_MASK # is there any work to be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) # other than syscall tracing?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) beqz t0, restore_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) andi t0, a2, _TIF_NEED_RESCHED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) bnez t0, work_resched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) work_notifysig: # deal with pending signals and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) # notify-resume requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) move a0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) li a1, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) jal do_notify_resume # a2 already loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) j resume_userspace_check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) FEXPORT(syscall_exit_partial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #ifdef CONFIG_DEBUG_RSEQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) move a0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) jal rseq_syscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) local_irq_disable # make sure need_resched doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) # change between and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) LONG_L a2, TI_FLAGS($28) # current->work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) li t0, _TIF_ALLWORK_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) and t0, a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) beqz t0, restore_partial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) SAVE_STATIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) syscall_exit_work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) andi t0, t0, KU_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) beqz t0, resume_kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) li t0, _TIF_WORK_SYSCALL_EXIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) and t0, a2 # a2 is preloaded with TI_FLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) beqz t0, work_pending # trace bit set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) local_irq_enable # could let syscall_trace_leave()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) # call schedule() instead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) TRACE_IRQS_ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) move a0, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) jal syscall_trace_leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) b resume_userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_MIPS_MT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * MIPS32R2 Instruction Hazard Barrier - must be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * For C code use the inline version named instruction_hazard().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) LEAF(mips_ihb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .set MIPS_ISA_LEVEL_RAW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) jr.hb ra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) END(mips_ihb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #endif /* CONFIG_CPU_MIPSR2 - CONFIG_CPU_MIPSR6 or CONFIG_MIPS_MT */