entry.S 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * entry.S - non-mmu 68360 interrupt and exceptions entry points
  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 bad_interrupt
  30. .globl inthandler
  31. badsys:
  32. movel #-ENOSYS,%sp@(PT_OFF_D0)
  33. jra ret_from_exception
  34. do_trace:
  35. movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
  36. subql #4,%sp
  37. SAVE_SWITCH_STACK
  38. jbsr syscall_trace_enter
  39. RESTORE_SWITCH_STACK
  40. addql #4,%sp
  41. movel %sp@(PT_OFF_ORIG_D0),%d1
  42. movel #-ENOSYS,%d0
  43. cmpl #NR_syscalls,%d1
  44. jcc 1f
  45. lsl #2,%d1
  46. lea sys_call_table, %a0
  47. jbsr %a0@(%d1)
  48. 1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
  49. subql #4,%sp /* dummy return address */
  50. SAVE_SWITCH_STACK
  51. jbsr syscall_trace_leave
  52. ret_from_signal:
  53. RESTORE_SWITCH_STACK
  54. addql #4,%sp
  55. jra ret_from_exception
  56. ENTRY(system_call)
  57. SAVE_ALL_SYS
  58. /* save top of frame*/
  59. pea %sp@
  60. jbsr set_esp0
  61. addql #4,%sp
  62. movel %sp@(PT_OFF_ORIG_D0),%d0
  63. movel %sp,%d1 /* get thread_info pointer */
  64. andl #-THREAD_SIZE,%d1
  65. movel %d1,%a2
  66. btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
  67. jne do_trace
  68. cmpl #NR_syscalls,%d0
  69. jcc badsys
  70. lsl #2,%d0
  71. lea sys_call_table,%a0
  72. movel %a0@(%d0), %a0
  73. jbsr %a0@
  74. movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
  75. ret_from_exception:
  76. btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
  77. jeq Luser_return /* if so, skip resched, signals*/
  78. Lkernel_return:
  79. RESTORE_ALL
  80. Luser_return:
  81. /* only allow interrupts when we are really the last one on the*/
  82. /* kernel stack, otherwise stack overflow can occur during*/
  83. /* heavy interrupt load*/
  84. andw #ALLOWINT,%sr
  85. movel %sp,%d1 /* get thread_info pointer */
  86. andl #-THREAD_SIZE,%d1
  87. movel %d1,%a2
  88. 1:
  89. move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
  90. jne Lwork_to_do
  91. RESTORE_ALL
  92. Lwork_to_do:
  93. movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
  94. btst #TIF_NEED_RESCHED,%d1
  95. jne reschedule
  96. Lsignal_return:
  97. subql #4,%sp /* dummy return address*/
  98. SAVE_SWITCH_STACK
  99. pea %sp@(SWITCH_STACK_SIZE)
  100. bsrw do_notify_resume
  101. addql #4,%sp
  102. RESTORE_SWITCH_STACK
  103. addql #4,%sp
  104. jra 1b
  105. /*
  106. * This is the main interrupt handler, responsible for calling do_IRQ()
  107. */
  108. inthandler:
  109. SAVE_ALL_INT
  110. movew %sp@(PT_OFF_FORMATVEC), %d0
  111. and.l #0x3ff, %d0
  112. lsr.l #0x02, %d0
  113. movel %sp,%sp@-
  114. movel %d0,%sp@- /* put vector # on stack*/
  115. jbsr do_IRQ /* process the IRQ */
  116. addql #8,%sp /* pop parameters off stack*/
  117. jra ret_from_exception
  118. /*
  119. * Handler for uninitialized and spurious interrupts.
  120. */
  121. bad_interrupt:
  122. addql #1,irq_err_count
  123. rte
  124. /*
  125. * Beware - when entering resume, prev (the current task) is
  126. * in a0, next (the new task) is in a1, so don't change these
  127. * registers until their contents are no longer needed.
  128. */
  129. ENTRY(resume)
  130. movel %a0,%d1 /* save prev thread in d1 */
  131. movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */
  132. SAVE_SWITCH_STACK
  133. movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
  134. movel %usp,%a3 /* save usp */
  135. movel %a3,%a0@(TASK_THREAD+THREAD_USP)
  136. movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */
  137. movel %a3,%usp
  138. movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
  139. RESTORE_SWITCH_STACK
  140. movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */
  141. rts