1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 2001 MIPS Technologies, Inc. 9 */ 10 11#include <asm/asm.h> 12#include <asm/asmmacro.h> 13#include <asm/regdef.h> 14#include <asm/mipsregs.h> 15#include <asm/stackframe.h> 16#include <asm/isadep.h> 17#include <asm/thread_info.h> 18#include <asm/war.h> 19#ifdef CONFIG_MIPS_MT_SMTC 20#include <asm/mipsmtregs.h> 21#endif 22 23#ifndef CONFIG_PREEMPT 24 .macro preempt_stop 25 local_irq_disable 26 .endm 27#define resume_kernel restore_all 28#endif 29 30 .text 31 .align 5 32FEXPORT(ret_from_irq) 33 LONG_S s0, TI_REGS($28) 34#ifdef CONFIG_PREEMPT 35FEXPORT(ret_from_exception) 36#else 37 b _ret_from_irq 38FEXPORT(ret_from_exception) 39 preempt_stop 40#endif 41FEXPORT(_ret_from_irq) 42 LONG_L t0, PT_STATUS(sp) # returning to kernel mode? 43 andi t0, t0, KU_USER 44 beqz t0, resume_kernel 45 46resume_userspace: 47 local_irq_disable # make sure we dont miss an 48 # interrupt setting need_resched 49 # between sampling and return 50 LONG_L a2, TI_FLAGS($28) # current->work 51 andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace) 52 bnez t0, work_pending 53 j restore_all 54 55#ifdef CONFIG_PREEMPT 56resume_kernel: 57 local_irq_disable 58 lw t0, TI_PRE_COUNT($28) 59 bnez t0, restore_all 60need_resched: 61 LONG_L t0, TI_FLAGS($28) 62 andi t1, t0, _TIF_NEED_RESCHED 63 beqz t1, restore_all 64 LONG_L t0, PT_STATUS(sp) # Interrupts off? 65 andi t0, 1 66 beqz t0, restore_all 67 jal preempt_schedule_irq 68 b need_resched 69#endif 70 71FEXPORT(ret_from_fork) 72 jal schedule_tail # a0 = struct task_struct *prev 73 74FEXPORT(syscall_exit) 75 local_irq_disable # make sure need_resched and 76 # signals dont change between 77 # sampling and return 78 LONG_L a2, TI_FLAGS($28) # current->work 79 li t0, _TIF_ALLWORK_MASK 80 and t0, a2, t0 81 bnez t0, syscall_exit_work 82 83FEXPORT(restore_all) # restore full frame 84#ifdef CONFIG_MIPS_MT_SMTC 85/* Detect and execute deferred IPI "interrupts" */ 86 LONG_L s0, TI_REGS($28) 87 LONG_S sp, TI_REGS($28) 88 jal deferred_smtc_ipi 89 LONG_S s0, TI_REGS($28) 90/* Re-arm any temporarily masked interrupts not explicitly "acked" */ 91 mfc0 v0, CP0_TCSTATUS 92 ori v1, v0, TCSTATUS_IXMT 93 mtc0 v1, CP0_TCSTATUS 94 andi v0, TCSTATUS_IXMT 95 _ehb 96 mfc0 t0, CP0_TCCONTEXT 97 DMT 9 # dmt t1 98 jal mips_ihb 99 mfc0 t2, CP0_STATUS 100 andi t3, t0, 0xff00 101 or t2, t2, t3 102 mtc0 t2, CP0_STATUS 103 _ehb 104 andi t1, t1, VPECONTROL_TE 105 beqz t1, 1f 106 EMT 1071: 108 mfc0 v1, CP0_TCSTATUS 109 /* We set IXMT above, XOR should clear it here */ 110 xori v1, v1, TCSTATUS_IXMT 111 or v1, v0, v1 112 mtc0 v1, CP0_TCSTATUS 113 _ehb 114 xor t0, t0, t3 115 mtc0 t0, CP0_TCCONTEXT 116#endif /* CONFIG_MIPS_MT_SMTC */ 117 .set noat 118 RESTORE_TEMP 119 RESTORE_AT 120 RESTORE_STATIC 121FEXPORT(restore_partial) # restore partial frame 122#ifdef CONFIG_TRACE_IRQFLAGS 123 SAVE_STATIC 124 SAVE_AT 125 SAVE_TEMP 126 LONG_L v0, PT_STATUS(sp) 127 and v0, 1 128 beqz v0, 1f 129 jal trace_hardirqs_on 130 b 2f 1311: jal trace_hardirqs_off 1322: 133 RESTORE_TEMP 134 RESTORE_AT 135 RESTORE_STATIC 136#endif 137 RESTORE_SOME 138 RESTORE_SP_AND_RET 139 .set at 140 141work_pending: 142 andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS 143 beqz t0, work_notifysig 144work_resched: 145 jal schedule 146 147 local_irq_disable # make sure need_resched and 148 # signals dont change between 149 # sampling and return 150 LONG_L a2, TI_FLAGS($28) 151 andi t0, a2, _TIF_WORK_MASK # is there any work to be done 152 # other than syscall tracing? 153 beqz t0, restore_all 154 andi t0, a2, _TIF_NEED_RESCHED 155 bnez t0, work_resched 156 157work_notifysig: # deal with pending signals and 158 # notify-resume requests 159 move a0, sp 160 li a1, 0 161 jal do_notify_resume # a2 already loaded 162 j resume_userspace 163 164FEXPORT(syscall_exit_work_partial) 165 SAVE_STATIC 166syscall_exit_work: 167 li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT 168 and t0, a2 # a2 is preloaded with TI_FLAGS 169 beqz t0, work_pending # trace bit set? 170 local_irq_enable # could let do_syscall_trace() 171 # call schedule() instead 172 move a0, sp 173 li a1, 1 174 jal do_syscall_trace 175 b resume_userspace 176 177#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT) 178 179/* 180 * MIPS32R2 Instruction Hazard Barrier - must be called 181 * 182 * For C code use the inline version named instruction_hazard(). 183 */ 184LEAF(mips_ihb) 185 .set mips32r2 186 jr.hb ra 187 nop 188 END(mips_ihb) 189 190#endif /* CONFIG_CPU_MIPSR2 or CONFIG_MIPS_MT */ 191