entry.S 3.9 KB

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