entry.S 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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 ret_from_exception
  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. jmpi ret_from_exception
  76. csky_syscall_trace:
  77. mov a0, sp /* sp = pt_regs pointer */
  78. jbsr syscall_trace_enter
  79. cmpnei a0, 0
  80. bt 1f
  81. /* Prepare args before do system call */
  82. ldw a0, (sp, LSAVE_A0)
  83. ldw a1, (sp, LSAVE_A1)
  84. ldw a2, (sp, LSAVE_A2)
  85. ldw a3, (sp, LSAVE_A3)
  86. #if defined(__CSKYABIV2__)
  87. subi sp, 8
  88. ldw r9, (sp, LSAVE_A4)
  89. stw r9, (sp, 0x0)
  90. ldw r9, (sp, LSAVE_A5)
  91. stw r9, (sp, 0x4)
  92. jsr syscallid /* Do system call */
  93. addi sp, 8
  94. #else
  95. ldw r6, (sp, LSAVE_A4)
  96. ldw r7, (sp, LSAVE_A5)
  97. jsr syscallid /* Do system call */
  98. #endif
  99. stw a0, (sp, LSAVE_A0) /* Save return value */
  100. 1:
  101. mov a0, sp /* right now, sp --> pt_regs */
  102. jbsr syscall_trace_exit
  103. br ret_from_exception
  104. ENTRY(ret_from_kernel_thread)
  105. jbsr schedule_tail
  106. mov a0, r10
  107. jsr r9
  108. jbsr ret_from_exception
  109. ENTRY(ret_from_fork)
  110. jbsr schedule_tail
  111. mov r9, sp
  112. bmaski r10, THREAD_SHIFT
  113. andn r9, r10
  114. ldw r10, (r9, TINFO_FLAGS)
  115. lrw r9, _TIF_SYSCALL_WORK
  116. and r10, r9
  117. cmpnei r10, 0
  118. bf ret_from_exception
  119. mov a0, sp /* sp = pt_regs pointer */
  120. jbsr syscall_trace_exit
  121. ret_from_exception:
  122. psrclr ie
  123. ld r9, (sp, LSAVE_PSR)
  124. btsti r9, 31
  125. bt 1f
  126. /*
  127. * Load address of current->thread_info, Then get address of task_struct
  128. * Get task_needreshed in task_struct
  129. */
  130. mov r9, sp
  131. bmaski r10, THREAD_SHIFT
  132. andn r9, r10
  133. ldw r10, (r9, TINFO_FLAGS)
  134. lrw r9, _TIF_WORK_MASK
  135. and r10, r9
  136. cmpnei r10, 0
  137. bt exit_work
  138. #ifdef CONFIG_CONTEXT_TRACKING_USER
  139. jbsr user_enter_callable
  140. #endif
  141. 1:
  142. #ifdef CONFIG_PREEMPTION
  143. mov r9, sp
  144. bmaski r10, THREAD_SHIFT
  145. andn r9, r10
  146. ldw r10, (r9, TINFO_PREEMPT)
  147. cmpnei r10, 0
  148. bt 2f
  149. jbsr preempt_schedule_irq /* irq en/disable is done inside */
  150. 2:
  151. #endif
  152. #ifdef CONFIG_TRACE_IRQFLAGS
  153. ld r10, (sp, LSAVE_PSR)
  154. btsti r10, 6
  155. bf 2f
  156. jbsr trace_hardirqs_on
  157. 2:
  158. #endif
  159. RESTORE_ALL
  160. exit_work:
  161. lrw r9, ret_from_exception
  162. mov lr, r9
  163. btsti r10, TIF_NEED_RESCHED
  164. bt work_resched
  165. psrset ie
  166. mov a0, sp
  167. mov a1, r10
  168. jmpi do_notify_resume
  169. work_resched:
  170. jmpi schedule
  171. ENTRY(csky_trap)
  172. SAVE_ALL 0
  173. zero_fp
  174. context_tracking
  175. psrset ee
  176. mov a0, sp /* Push Stack pointer arg */
  177. jbsr trap_c /* Call C-level trap handler */
  178. jmpi ret_from_exception
  179. /*
  180.  * Prototype from libc for abiv1:
  181.  * register unsigned int __result asm("a0");
  182.  * asm( "trap 3" :"=r"(__result)::);
  183.  */
  184. ENTRY(csky_get_tls)
  185. USPTOKSP
  186. RD_MEH a0
  187. WR_MEH a0
  188. /* increase epc for continue */
  189. mfcr a0, epc
  190. addi a0, TRAP0_SIZE
  191. mtcr a0, epc
  192. /* get current task thread_info with kernel 8K stack */
  193. bmaski a0, THREAD_SHIFT
  194. not a0
  195. subi sp, 1
  196. and a0, sp
  197. addi sp, 1
  198. /* get tls */
  199. ldw a0, (a0, TINFO_TP_VALUE)
  200. KSPTOUSP
  201. rte
  202. ENTRY(csky_irq)
  203. SAVE_ALL 0
  204. zero_fp
  205. context_tracking
  206. psrset ee
  207. #ifdef CONFIG_TRACE_IRQFLAGS
  208. jbsr trace_hardirqs_off
  209. #endif
  210. mov a0, sp
  211. jbsr generic_handle_arch_irq
  212. jmpi ret_from_exception
  213. /*
  214. * a0 = prev task_struct *
  215. * a1 = next task_struct *
  216. * a0 = return next
  217. */
  218. ENTRY(__switch_to)
  219. lrw a3, TASK_THREAD
  220. addu a3, a0
  221. SAVE_SWITCH_STACK
  222. stw sp, (a3, THREAD_KSP)
  223. /* Set up next process to run */
  224. lrw a3, TASK_THREAD
  225. addu a3, a1
  226. ldw sp, (a3, THREAD_KSP) /* Set next kernel sp */
  227. #if defined(__CSKYABIV2__)
  228. addi a3, a1, TASK_THREAD_INFO
  229. ldw tls, (a3, TINFO_TP_VALUE)
  230. #endif
  231. RESTORE_SWITCH_STACK
  232. rts
  233. ENDPROC(__switch_to)