entry.S 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3. #include <linux/linkage.h>
  4. #include <abi/entry.h>
  5. #include <abi/pgtable-bits.h>
  6. #include <asm/errno.h>
  7. #include <asm/setup.h>
  8. #include <asm/unistd.h>
  9. #include <asm/asm-offsets.h>
  10. #include <linux/threads.h>
  11. #include <asm/page.h>
  12. #include <asm/thread_info.h>
  13. .macro zero_fp
  14. #ifdef CONFIG_STACKTRACE
  15. movi r8, 0
  16. #endif
  17. .endm
  18. .macro context_tracking
  19. #ifdef CONFIG_CONTEXT_TRACKING_USER
  20. mfcr a0, epsr
  21. btsti a0, 31
  22. bt 1f
  23. jbsr user_exit_callable
  24. ldw a0, (sp, LSAVE_A0)
  25. ldw a1, (sp, LSAVE_A1)
  26. ldw a2, (sp, LSAVE_A2)
  27. ldw a3, (sp, LSAVE_A3)
  28. #if defined(__CSKYABIV1__)
  29. ldw r6, (sp, LSAVE_A4)
  30. ldw r7, (sp, LSAVE_A5)
  31. #endif
  32. 1:
  33. #endif
  34. .endm
  35. .text
  36. ENTRY(csky_pagefault)
  37. SAVE_ALL 0
  38. zero_fp
  39. context_tracking
  40. psrset ee
  41. mov a0, sp
  42. jbsr do_page_fault
  43. jmpi ret_from_exception
  44. ENTRY(csky_systemcall)
  45. SAVE_ALL TRAP0_SIZE
  46. zero_fp
  47. context_tracking
  48. psrset ee, ie
  49. lrw r9, __NR_syscalls
  50. cmphs syscallid, r9 /* Check nr of syscall */
  51. bt 1f
  52. lrw r9, sys_call_table
  53. ixw r9, syscallid
  54. ldw syscallid, (r9)
  55. cmpnei syscallid, 0
  56. bf ret_from_exception
  57. mov r9, sp
  58. bmaski r10, THREAD_SHIFT
  59. andn r9, r10
  60. ldw r10, (r9, TINFO_FLAGS)
  61. lrw r9, _TIF_SYSCALL_WORK
  62. and r10, r9
  63. cmpnei r10, 0
  64. bt csky_syscall_trace
  65. #if defined(__CSKYABIV2__)
  66. subi sp, 8
  67. stw r5, (sp, 0x4)
  68. stw r4, (sp, 0x0)
  69. jsr syscallid /* Do system call */
  70. addi sp, 8
  71. #else
  72. jsr syscallid
  73. #endif
  74. stw a0, (sp, LSAVE_A0) /* Save return value */
  75. 1:
  76. #ifdef CONFIG_DEBUG_RSEQ
  77. mov a0, sp
  78. jbsr rseq_syscall
  79. #endif
  80. jmpi ret_from_exception
  81. csky_syscall_trace:
  82. mov a0, sp /* sp = pt_regs pointer */
  83. jbsr syscall_trace_enter
  84. cmpnei a0, 0
  85. bt 1f
  86. /* Prepare args before do system call */
  87. ldw a0, (sp, LSAVE_A0)
  88. ldw a1, (sp, LSAVE_A1)
  89. ldw a2, (sp, LSAVE_A2)
  90. ldw a3, (sp, LSAVE_A3)
  91. #if defined(__CSKYABIV2__)
  92. subi sp, 8
  93. ldw r9, (sp, LSAVE_A4)
  94. stw r9, (sp, 0x0)
  95. ldw r9, (sp, LSAVE_A5)
  96. stw r9, (sp, 0x4)
  97. jsr syscallid /* Do system call */
  98. addi sp, 8
  99. #else
  100. ldw r6, (sp, LSAVE_A4)
  101. ldw r7, (sp, LSAVE_A5)
  102. jsr syscallid /* Do system call */
  103. #endif
  104. stw a0, (sp, LSAVE_A0) /* Save return value */
  105. 1:
  106. #ifdef CONFIG_DEBUG_RSEQ
  107. mov a0, sp
  108. jbsr rseq_syscall
  109. #endif
  110. mov a0, sp /* right now, sp --> pt_regs */
  111. jbsr syscall_trace_exit
  112. br ret_from_exception
  113. ENTRY(ret_from_kernel_thread)
  114. jbsr schedule_tail
  115. mov a0, r10
  116. jsr r9
  117. jbsr ret_from_exception
  118. ENTRY(ret_from_fork)
  119. jbsr schedule_tail
  120. mov r9, sp
  121. bmaski r10, THREAD_SHIFT
  122. andn r9, r10
  123. ldw r10, (r9, TINFO_FLAGS)
  124. lrw r9, _TIF_SYSCALL_WORK
  125. and r10, r9
  126. cmpnei r10, 0
  127. bf ret_from_exception
  128. mov a0, sp /* sp = pt_regs pointer */
  129. jbsr syscall_trace_exit
  130. ret_from_exception:
  131. psrclr ie
  132. ld r9, (sp, LSAVE_PSR)
  133. btsti r9, 31
  134. bt 1f
  135. /*
  136. * Load address of current->thread_info, Then get address of task_struct
  137. * Get task_needreshed in task_struct
  138. */
  139. mov r9, sp
  140. bmaski r10, THREAD_SHIFT
  141. andn r9, r10
  142. ldw r10, (r9, TINFO_FLAGS)
  143. lrw r9, _TIF_WORK_MASK
  144. and r10, r9
  145. cmpnei r10, 0
  146. bt exit_work
  147. #ifdef CONFIG_CONTEXT_TRACKING_USER
  148. jbsr user_enter_callable
  149. #endif
  150. 1:
  151. #ifdef CONFIG_PREEMPTION
  152. mov r9, sp
  153. bmaski r10, THREAD_SHIFT
  154. andn r9, r10
  155. ldw r10, (r9, TINFO_PREEMPT)
  156. cmpnei r10, 0
  157. bt 2f
  158. jbsr preempt_schedule_irq /* irq en/disable is done inside */
  159. 2:
  160. #endif
  161. #ifdef CONFIG_TRACE_IRQFLAGS
  162. ld r10, (sp, LSAVE_PSR)
  163. btsti r10, 6
  164. bf 2f
  165. jbsr trace_hardirqs_on
  166. 2:
  167. #endif
  168. RESTORE_ALL
  169. exit_work:
  170. lrw r9, ret_from_exception
  171. mov lr, r9
  172. btsti r10, TIF_NEED_RESCHED
  173. bt work_resched
  174. psrset ie
  175. mov a0, sp
  176. mov a1, r10
  177. jmpi do_notify_resume
  178. work_resched:
  179. jmpi schedule
  180. ENTRY(csky_trap)
  181. SAVE_ALL 0
  182. zero_fp
  183. context_tracking
  184. psrset ee
  185. mov a0, sp /* Push Stack pointer arg */
  186. jbsr trap_c /* Call C-level trap handler */
  187. jmpi ret_from_exception
  188. /*
  189.  * Prototype from libc for abiv1:
  190.  * register unsigned int __result asm("a0");
  191.  * asm( "trap 3" :"=r"(__result)::);
  192.  */
  193. ENTRY(csky_get_tls)
  194. USPTOKSP
  195. RD_MEH a0
  196. WR_MEH a0
  197. /* increase epc for continue */
  198. mfcr a0, epc
  199. addi a0, TRAP0_SIZE
  200. mtcr a0, epc
  201. /* get current task thread_info with kernel 8K stack */
  202. bmaski a0, THREAD_SHIFT
  203. not a0
  204. subi sp, 1
  205. and a0, sp
  206. addi sp, 1
  207. /* get tls */
  208. ldw a0, (a0, TINFO_TP_VALUE)
  209. KSPTOUSP
  210. rte
  211. ENTRY(csky_irq)
  212. SAVE_ALL 0
  213. zero_fp
  214. context_tracking
  215. psrset ee
  216. #ifdef CONFIG_TRACE_IRQFLAGS
  217. jbsr trace_hardirqs_off
  218. #endif
  219. mov a0, sp
  220. jbsr generic_handle_arch_irq
  221. jmpi ret_from_exception
  222. /*
  223. * a0 = prev task_struct *
  224. * a1 = next task_struct *
  225. * a0 = return next
  226. */
  227. ENTRY(__switch_to)
  228. lrw a3, TASK_THREAD
  229. addu a3, a0
  230. SAVE_SWITCH_STACK
  231. stw sp, (a3, THREAD_KSP)
  232. /* Set up next process to run */
  233. lrw a3, TASK_THREAD
  234. addu a3, a1
  235. ldw sp, (a3, THREAD_KSP) /* Set next kernel sp */
  236. #if defined(__CSKYABIV2__)
  237. addi a3, a1, TASK_THREAD_INFO
  238. ldw tls, (a3, TINFO_TP_VALUE)
  239. #endif
  240. RESTORE_SWITCH_STACK
  241. rts
  242. ENDPROC(__switch_to)