entry.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
  4. * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  5. */
  6. #ifndef __ASM_ARC_ENTRY_H
  7. #define __ASM_ARC_ENTRY_H
  8. #include <asm/unistd.h> /* For NR_syscalls defination */
  9. #include <asm/arcregs.h>
  10. #include <asm/ptrace.h>
  11. #include <asm/processor.h> /* For VMALLOC_START */
  12. #include <asm/mmu.h>
  13. #ifdef CONFIG_ISA_ARCOMPACT
  14. #include <asm/entry-compact.h> /* ISA specific bits */
  15. #else
  16. #include <asm/entry-arcv2.h>
  17. #endif
  18. /* Note on the LD/ST addr modes with addr reg wback
  19. *
  20. * LD.a same as LD.aw
  21. *
  22. * LD.a reg1, [reg2, x] => Pre Incr
  23. * Eff Addr for load = [reg2 + x]
  24. *
  25. * LD.ab reg1, [reg2, x] => Post Incr
  26. * Eff Addr for load = [reg2]
  27. */
  28. .macro PUSH reg
  29. st.a \reg, [sp, -4]
  30. .endm
  31. .macro PUSHAX aux
  32. lr r9, [\aux]
  33. PUSH r9
  34. .endm
  35. .macro POP reg
  36. ld.ab \reg, [sp, 4]
  37. .endm
  38. .macro POPAX aux
  39. POP r9
  40. sr r9, [\aux]
  41. .endm
  42. /*--------------------------------------------------------------
  43. * Helpers to save/restore Scratch Regs:
  44. * used by Interrupt/Exception Prologue/Epilogue
  45. *-------------------------------------------------------------*/
  46. .macro SAVE_R0_TO_R12
  47. PUSH r0
  48. PUSH r1
  49. PUSH r2
  50. PUSH r3
  51. PUSH r4
  52. PUSH r5
  53. PUSH r6
  54. PUSH r7
  55. PUSH r8
  56. PUSH r9
  57. PUSH r10
  58. PUSH r11
  59. PUSH r12
  60. .endm
  61. .macro RESTORE_R12_TO_R0
  62. POP r12
  63. POP r11
  64. POP r10
  65. POP r9
  66. POP r8
  67. POP r7
  68. POP r6
  69. POP r5
  70. POP r4
  71. POP r3
  72. POP r2
  73. POP r1
  74. POP r0
  75. .endm
  76. /*--------------------------------------------------------------
  77. * Helpers to save/restore callee-saved regs:
  78. * used by several macros below
  79. *-------------------------------------------------------------*/
  80. .macro SAVE_R13_TO_R24
  81. PUSH r13
  82. PUSH r14
  83. PUSH r15
  84. PUSH r16
  85. PUSH r17
  86. PUSH r18
  87. PUSH r19
  88. PUSH r20
  89. PUSH r21
  90. PUSH r22
  91. PUSH r23
  92. PUSH r24
  93. .endm
  94. .macro RESTORE_R24_TO_R13
  95. POP r24
  96. POP r23
  97. POP r22
  98. POP r21
  99. POP r20
  100. POP r19
  101. POP r18
  102. POP r17
  103. POP r16
  104. POP r15
  105. POP r14
  106. POP r13
  107. .endm
  108. /*--------------------------------------------------------------
  109. * Collect User Mode callee regs as struct callee_regs - needed by
  110. * fork/do_signal/unaligned-access-emulation.
  111. * (By default only scratch regs are saved on entry to kernel)
  112. *
  113. * Special handling for r25 if used for caching Task Pointer.
  114. * It would have been saved in task->thread.user_r25 already, but to keep
  115. * the interface same it is copied into regular r25 placeholder in
  116. * struct callee_regs.
  117. *-------------------------------------------------------------*/
  118. .macro SAVE_CALLEE_SAVED_USER
  119. mov r12, sp ; save SP as ref to pt_regs
  120. SAVE_R13_TO_R24
  121. #ifdef CONFIG_ARC_CURR_IN_REG
  122. ; Retrieve orig r25 and save it with rest of callee_regs
  123. ld r12, [r12, PT_user_r25]
  124. PUSH r12
  125. #else
  126. PUSH r25
  127. #endif
  128. .endm
  129. /*--------------------------------------------------------------
  130. * Save kernel Mode callee regs at the time of Contect Switch.
  131. *
  132. * Special handling for r25 if used for caching Task Pointer.
  133. * Kernel simply skips saving it since it will be loaded with
  134. * incoming task pointer anyways
  135. *-------------------------------------------------------------*/
  136. .macro SAVE_CALLEE_SAVED_KERNEL
  137. SAVE_R13_TO_R24
  138. #ifdef CONFIG_ARC_CURR_IN_REG
  139. sub sp, sp, 4
  140. #else
  141. PUSH r25
  142. #endif
  143. .endm
  144. /*--------------------------------------------------------------
  145. * Opposite of SAVE_CALLEE_SAVED_KERNEL
  146. *-------------------------------------------------------------*/
  147. .macro RESTORE_CALLEE_SAVED_KERNEL
  148. #ifdef CONFIG_ARC_CURR_IN_REG
  149. add sp, sp, 4 /* skip usual r25 placeholder */
  150. #else
  151. POP r25
  152. #endif
  153. RESTORE_R24_TO_R13
  154. .endm
  155. /*--------------------------------------------------------------
  156. * Opposite of SAVE_CALLEE_SAVED_USER
  157. *
  158. * ptrace tracer or unaligned-access fixup might have changed a user mode
  159. * callee reg which is saved back to usual r25 storage location
  160. *-------------------------------------------------------------*/
  161. .macro RESTORE_CALLEE_SAVED_USER
  162. #ifdef CONFIG_ARC_CURR_IN_REG
  163. POP r12
  164. #else
  165. POP r25
  166. #endif
  167. RESTORE_R24_TO_R13
  168. ; SP is back to start of pt_regs
  169. #ifdef CONFIG_ARC_CURR_IN_REG
  170. st r12, [sp, PT_user_r25]
  171. #endif
  172. .endm
  173. /*--------------------------------------------------------------
  174. * Super FAST Restore callee saved regs by simply re-adjusting SP
  175. *-------------------------------------------------------------*/
  176. .macro DISCARD_CALLEE_SAVED_USER
  177. add sp, sp, SZ_CALLEE_REGS
  178. .endm
  179. /*-------------------------------------------------------------
  180. * given a tsk struct, get to the base of it's kernel mode stack
  181. * tsk->thread_info is really a PAGE, whose bottom hoists stack
  182. * which grows upwards towards thread_info
  183. *------------------------------------------------------------*/
  184. .macro GET_TSK_STACK_BASE tsk, out
  185. /* Get task->thread_info (this is essentially start of a PAGE) */
  186. ld \out, [\tsk, TASK_THREAD_INFO]
  187. /* Go to end of page where stack begins (grows upwards) */
  188. add2 \out, \out, (THREAD_SIZE)/4
  189. .endm
  190. /*
  191. * @reg [OUT] thread_info->flags of "current"
  192. */
  193. .macro GET_CURR_THR_INFO_FLAGS reg
  194. GET_CURR_THR_INFO_FROM_SP \reg
  195. ld \reg, [\reg, THREAD_INFO_FLAGS]
  196. .endm
  197. #ifdef CONFIG_SMP
  198. /*-------------------------------------------------
  199. * Retrieve the current running task on this CPU
  200. * 1. Determine curr CPU id.
  201. * 2. Use it to index into _current_task[ ]
  202. */
  203. .macro GET_CURR_TASK_ON_CPU reg
  204. GET_CPU_ID \reg
  205. ld.as \reg, [@_current_task, \reg]
  206. .endm
  207. /*-------------------------------------------------
  208. * Save a new task as the "current" task on this CPU
  209. * 1. Determine curr CPU id.
  210. * 2. Use it to index into _current_task[ ]
  211. *
  212. * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS)
  213. * because ST r0, [r1, offset] can ONLY have s9 @offset
  214. * while LD can take s9 (4 byte insn) or LIMM (8 byte insn)
  215. */
  216. .macro SET_CURR_TASK_ON_CPU tsk, tmp
  217. GET_CPU_ID \tmp
  218. add2 \tmp, @_current_task, \tmp
  219. st \tsk, [\tmp]
  220. #ifdef CONFIG_ARC_CURR_IN_REG
  221. mov r25, \tsk
  222. #endif
  223. .endm
  224. #else /* Uniprocessor implementation of macros */
  225. .macro GET_CURR_TASK_ON_CPU reg
  226. ld \reg, [@_current_task]
  227. .endm
  228. .macro SET_CURR_TASK_ON_CPU tsk, tmp
  229. st \tsk, [@_current_task]
  230. #ifdef CONFIG_ARC_CURR_IN_REG
  231. mov r25, \tsk
  232. #endif
  233. .endm
  234. #endif /* SMP / UNI */
  235. /* ------------------------------------------------------------------
  236. * Get the ptr to some field of Current Task at @off in task struct
  237. * -Uses r25 for Current task ptr if that is enabled
  238. */
  239. #ifdef CONFIG_ARC_CURR_IN_REG
  240. .macro GET_CURR_TASK_FIELD_PTR off, reg
  241. add \reg, r25, \off
  242. .endm
  243. #else
  244. .macro GET_CURR_TASK_FIELD_PTR off, reg
  245. GET_CURR_TASK_ON_CPU \reg
  246. add \reg, \reg, \off
  247. .endm
  248. #endif /* CONFIG_ARC_CURR_IN_REG */
  249. #endif /* __ASM_ARC_ENTRY_H */