linux/arch/mips/kernel/entry.S
<<
>>
Prefs
   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#define resume_kernel   restore_all
  25#else
  26#define __ret_from_irq  ret_from_exception
  27#endif
  28
  29        .text
  30        .align  5
  31#ifndef CONFIG_PREEMPT
  32FEXPORT(ret_from_exception)
  33        local_irq_disable                       # preempt stop
  34        b       __ret_from_irq
  35#endif
  36FEXPORT(ret_from_irq)
  37        LONG_S  s0, TI_REGS($28)
  38FEXPORT(__ret_from_irq)
  39        LONG_L  t0, PT_STATUS(sp)               # returning to kernel mode?
  40        andi    t0, t0, KU_USER
  41        beqz    t0, resume_kernel
  42
  43resume_userspace:
  44        local_irq_disable               # make sure we dont miss an
  45                                        # interrupt setting need_resched
  46                                        # between sampling and return
  47        LONG_L  a2, TI_FLAGS($28)       # current->work
  48        andi    t0, a2, _TIF_WORK_MASK  # (ignoring syscall_trace)
  49        bnez    t0, work_pending
  50        j       restore_all
  51
  52#ifdef CONFIG_PREEMPT
  53resume_kernel:
  54        local_irq_disable
  55        lw      t0, TI_PRE_COUNT($28)
  56        bnez    t0, restore_all
  57need_resched:
  58        LONG_L  t0, TI_FLAGS($28)
  59        andi    t1, t0, _TIF_NEED_RESCHED
  60        beqz    t1, restore_all
  61        LONG_L  t0, PT_STATUS(sp)               # Interrupts off?
  62        andi    t0, 1
  63        beqz    t0, restore_all
  64        jal     preempt_schedule_irq
  65        b       need_resched
  66#endif
  67
  68FEXPORT(ret_from_fork)
  69        jal     schedule_tail           # a0 = struct task_struct *prev
  70
  71FEXPORT(syscall_exit)
  72        local_irq_disable               # make sure need_resched and
  73                                        # signals dont change between
  74                                        # sampling and return
  75        LONG_L  a2, TI_FLAGS($28)       # current->work
  76        li      t0, _TIF_ALLWORK_MASK
  77        and     t0, a2, t0
  78        bnez    t0, syscall_exit_work
  79
  80FEXPORT(restore_all)                    # restore full frame
  81#ifdef CONFIG_MIPS_MT_SMTC
  82#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
  83/* Re-arm any temporarily masked interrupts not explicitly "acked" */
  84        mfc0    v0, CP0_TCSTATUS
  85        ori     v1, v0, TCSTATUS_IXMT
  86        mtc0    v1, CP0_TCSTATUS
  87        andi    v0, TCSTATUS_IXMT
  88        _ehb
  89        mfc0    t0, CP0_TCCONTEXT
  90        DMT     9                               # dmt t1
  91        jal     mips_ihb
  92        mfc0    t2, CP0_STATUS
  93        andi    t3, t0, 0xff00
  94        or      t2, t2, t3
  95        mtc0    t2, CP0_STATUS
  96        _ehb
  97        andi    t1, t1, VPECONTROL_TE
  98        beqz    t1, 1f
  99        EMT
 1001:
 101        mfc0    v1, CP0_TCSTATUS
 102        /* We set IXMT above, XOR should clear it here */
 103        xori    v1, v1, TCSTATUS_IXMT
 104        or      v1, v0, v1
 105        mtc0    v1, CP0_TCSTATUS
 106        _ehb
 107        xor     t0, t0, t3
 108        mtc0    t0, CP0_TCCONTEXT
 109#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
 110/* Detect and execute deferred IPI "interrupts" */
 111        LONG_L  s0, TI_REGS($28)
 112        LONG_S  sp, TI_REGS($28)
 113        jal     deferred_smtc_ipi
 114        LONG_S  s0, TI_REGS($28)
 115#endif /* CONFIG_MIPS_MT_SMTC */
 116        .set    noat
 117        RESTORE_TEMP
 118        RESTORE_AT
 119        RESTORE_STATIC
 120FEXPORT(restore_partial)                # restore partial frame
 121#ifdef CONFIG_TRACE_IRQFLAGS
 122        SAVE_STATIC
 123        SAVE_AT
 124        SAVE_TEMP
 125        LONG_L  v0, PT_STATUS(sp)
 126#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 127        and     v0, ST0_IEP
 128#else
 129        and     v0, ST0_IE
 130#endif
 131        beqz    v0, 1f
 132        jal     trace_hardirqs_on
 133        b       2f
 1341:      jal     trace_hardirqs_off
 1352:
 136        RESTORE_TEMP
 137        RESTORE_AT
 138        RESTORE_STATIC
 139#endif
 140        RESTORE_SOME
 141        RESTORE_SP_AND_RET
 142        .set    at
 143
 144work_pending:
 145        andi    t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
 146        beqz    t0, work_notifysig
 147work_resched:
 148        jal     schedule
 149
 150        local_irq_disable               # make sure need_resched and
 151                                        # signals dont change between
 152                                        # sampling and return
 153        LONG_L  a2, TI_FLAGS($28)
 154        andi    t0, a2, _TIF_WORK_MASK  # is there any work to be done
 155                                        # other than syscall tracing?
 156        beqz    t0, restore_all
 157        andi    t0, a2, _TIF_NEED_RESCHED
 158        bnez    t0, work_resched
 159
 160work_notifysig:                         # deal with pending signals and
 161                                        # notify-resume requests
 162        move    a0, sp
 163        li      a1, 0
 164        jal     do_notify_resume        # a2 already loaded
 165        j       resume_userspace
 166
 167FEXPORT(syscall_exit_work_partial)
 168        SAVE_STATIC
 169syscall_exit_work:
 170        li      t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
 171        and     t0, a2                  # a2 is preloaded with TI_FLAGS
 172        beqz    t0, work_pending        # trace bit set?
 173        local_irq_enable                # could let do_syscall_trace()
 174                                        # call schedule() instead
 175        move    a0, sp
 176        li      a1, 1
 177        jal     do_syscall_trace
 178        b       resume_userspace
 179
 180#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT)
 181
 182/*
 183 * MIPS32R2 Instruction Hazard Barrier - must be called
 184 *
 185 * For C code use the inline version named instruction_hazard().
 186 */
 187LEAF(mips_ihb)
 188        .set    mips32r2
 189        jr.hb   ra
 190        nop
 191        END(mips_ihb)
 192
 193#endif /* CONFIG_CPU_MIPSR2 or CONFIG_MIPS_MT */
 194