entry.S 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * linux/arch/m68knommu/platform/68360/entry.S
  3. *
  4. * Copyright (C) 1991, 1992 Linus Torvalds
  5. * Copyright (C) 2001 SED Systems, a Division of Calian Ltd.
  6. *
  7. * This file is subject to the terms and conditions of the GNU General Public
  8. * License. See the file README.legal in the main directory of this archive
  9. * for more details.
  10. *
  11. * Linux/m68k support by Hamish Macdonald
  12. * M68360 Port by SED Systems, and Lineo.
  13. */
  14. #include <linux/linkage.h>
  15. #include <asm/thread_info.h>
  16. #include <asm/unistd.h>
  17. #include <asm/errno.h>
  18. #include <asm/setup.h>
  19. #include <asm/segment.h>
  20. #include <asm/traps.h>
  21. #include <asm/asm-offsets.h>
  22. #include <asm/entry.h>
  23. .text
  24. .globl system_call
  25. .globl resume
  26. .globl ret_from_exception
  27. .globl ret_from_signal
  28. .globl sys_call_table
  29. .globl ret_from_interrupt
  30. .globl bad_interrupt
  31. .globl inthandler
  32. badsys:
  33. movel #-ENOSYS,%sp@(PT_OFF_D0)
  34. jra ret_from_exception
  35. do_trace:
  36. movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
  37. subql #4,%sp
  38. SAVE_SWITCH_STACK
  39. jbsr syscall_trace_enter
  40. RESTORE_SWITCH_STACK
  41. addql #4,%sp
  42. movel %sp@(PT_OFF_ORIG_D0),%d1
  43. movel #-ENOSYS,%d0
  44. cmpl #NR_syscalls,%d1
  45. jcc 1f
  46. lsl #2,%d1
  47. lea sys_call_table, %a0
  48. jbsr %a0@(%d1)
  49. 1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
  50. subql #4,%sp /* dummy return address */
  51. SAVE_SWITCH_STACK
  52. jbsr syscall_trace_leave
  53. ret_from_signal:
  54. RESTORE_SWITCH_STACK
  55. addql #4,%sp
  56. jra ret_from_exception
  57. ENTRY(system_call)
  58. SAVE_ALL
  59. /* save top of frame*/
  60. pea %sp@
  61. jbsr set_esp0
  62. addql #4,%sp
  63. movel %sp@(PT_OFF_ORIG_D0),%d0
  64. movel %sp,%d1 /* get thread_info pointer */
  65. andl #-THREAD_SIZE,%d1
  66. movel %d1,%a2
  67. btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
  68. jne do_trace
  69. cmpl #NR_syscalls,%d0
  70. jcc badsys
  71. lsl #2,%d0
  72. lea sys_call_table,%a0
  73. movel %a0@(%d0), %a0
  74. jbsr %a0@
  75. movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
  76. ret_from_exception:
  77. btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
  78. jeq Luser_return /* if so, skip resched, signals*/
  79. Lkernel_return:
  80. RESTORE_ALL
  81. Luser_return:
  82. /* only allow interrupts when we are really the last one on the*/
  83. /* kernel stack, otherwise stack overflow can occur during*/
  84. /* heavy interrupt load*/
  85. andw #ALLOWINT,%sr
  86. movel %sp,%d1 /* get thread_info pointer */
  87. andl #-THREAD_SIZE,%d1
  88. movel %d1,%a2
  89. 1:
  90. move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
  91. jne Lwork_to_do
  92. RESTORE_ALL
  93. Lwork_to_do:
  94. movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
  95. btst #TIF_NEED_RESCHED,%d1
  96. jne reschedule
  97. Lsignal_return:
  98. subql #4,%sp /* dummy return address*/
  99. SAVE_SWITCH_STACK
  100. pea %sp@(SWITCH_STACK_SIZE)
  101. bsrw do_signal
  102. addql #4,%sp
  103. RESTORE_SWITCH_STACK
  104. addql #4,%sp
  105. jra 1b
  106. /*
  107. * This is the main interrupt handler, responsible for calling do_IRQ()
  108. */
  109. inthandler:
  110. SAVE_ALL
  111. movew %sp@(PT_OFF_FORMATVEC), %d0
  112. and.l #0x3ff, %d0
  113. lsr.l #0x02, %d0
  114. movel %sp,%sp@-
  115. movel %d0,%sp@- /* put vector # on stack*/
  116. jbsr do_IRQ /* process the IRQ*/
  117. 3: addql #8,%sp /* pop parameters off stack*/
  118. bra ret_from_interrupt
  119. ret_from_interrupt:
  120. jeq 1f
  121. 2:
  122. RESTORE_ALL
  123. 1:
  124. moveb %sp@(PT_OFF_SR), %d0
  125. and #7, %d0
  126. jhi 2b
  127. /* check if we need to do software interrupts */
  128. movel irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
  129. jeq ret_from_exception
  130. pea ret_from_exception
  131. jra do_softirq
  132. /*
  133. * Handler for uninitialized and spurious interrupts.
  134. */
  135. bad_interrupt:
  136. addql #1,irq_err_count
  137. rte
  138. /*
  139. * Beware - when entering resume, prev (the current task) is
  140. * in a0, next (the new task) is in a1, so don't change these
  141. * registers until their contents are no longer needed.
  142. */
  143. ENTRY(resume)
  144. movel %a0,%d1 /* save prev thread in d1 */
  145. movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */
  146. SAVE_SWITCH_STACK
  147. movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
  148. movel %usp,%a3 /* save usp */
  149. movel %a3,%a0@(TASK_THREAD+THREAD_USP)
  150. movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */
  151. movel %a3,%usp
  152. movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
  153. RESTORE_SWITCH_STACK
  154. movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */
  155. rts