entry-arcv2.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_ARC_ENTRY_ARCV2_H
  3. #define __ASM_ARC_ENTRY_ARCV2_H
  4. #include <asm/asm-offsets.h>
  5. #include <asm/dsp-impl.h>
  6. #include <asm/irqflags-arcv2.h>
  7. #include <asm/thread_info.h> /* For THREAD_SIZE */
  8. /*
  9. * Interrupt/Exception stack layout (pt_regs) for ARCv2
  10. * (End of struct aligned to end of page [unless nested])
  11. *
  12. * INTERRUPT EXCEPTION
  13. *
  14. * manual --------------------- manual
  15. * | orig_r0 |
  16. * | event/ECR |
  17. * | bta |
  18. * | gp |
  19. * | fp |
  20. * | sp |
  21. * | r12 |
  22. * | r30 |
  23. * | r58 |
  24. * | r59 |
  25. * hw autosave ---------------------
  26. * optional | r0 |
  27. * | r1 |
  28. * ~ ~
  29. * | r9 |
  30. * | r10 |
  31. * | r11 |
  32. * | blink |
  33. * | lpe |
  34. * | lps |
  35. * | lpc |
  36. * | ei base |
  37. * | ldi base |
  38. * | jli base |
  39. * ---------------------
  40. * hw autosave | pc / eret |
  41. * mandatory | stat32 / erstatus |
  42. * ---------------------
  43. */
  44. /*------------------------------------------------------------------------*/
  45. .macro INTERRUPT_PROLOGUE
  46. ; Before jumping to Interrupt Vector, hardware micro-ops did following:
  47. ; 1. SP auto-switched to kernel mode stack
  48. ; 2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0)
  49. ; 3. Auto save: (mandatory) Push PC and STAT32 on stack
  50. ; hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE
  51. ; 4a. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI
  52. ;
  53. ; Now
  54. ; 4b. If Auto-save (optional) not enabled in hw, manually save them
  55. ; 5. Manually save: r12,r30, sp,fp,gp, ACCL pair
  56. ;
  57. ; At the end, SP points to pt_regs
  58. #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
  59. ; carve pt_regs on stack (case #3), PC/STAT32 already on stack
  60. sub sp, sp, SZ_PT_REGS - 8
  61. __SAVE_REGFILE_HARD
  62. #else
  63. ; carve pt_regs on stack (case #4), which grew partially already
  64. sub sp, sp, PT_r0
  65. #endif
  66. __SAVE_REGFILE_SOFT
  67. .endm
  68. /*------------------------------------------------------------------------*/
  69. .macro EXCEPTION_PROLOGUE_KEEP_AE
  70. ; Before jumping to Exception Vector, hardware micro-ops did following:
  71. ; 1. SP auto-switched to kernel mode stack
  72. ; 2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0)
  73. ;
  74. ; Now manually save rest of reg file
  75. ; At the end, SP points to pt_regs
  76. sub sp, sp, SZ_PT_REGS ; carve space for pt_regs
  77. ; _HARD saves r10 clobbered by _SOFT as scratch hence comes first
  78. __SAVE_REGFILE_HARD
  79. __SAVE_REGFILE_SOFT
  80. st r0, [sp] ; orig_r0
  81. lr r10, [eret]
  82. lr r11, [erstatus]
  83. ST2 r10, r11, PT_ret
  84. lr r10, [ecr]
  85. lr r11, [erbta]
  86. ST2 r10, r11, PT_event
  87. ; OUTPUT: r10 has ECR expected by EV_Trap
  88. .endm
  89. .macro EXCEPTION_PROLOGUE
  90. EXCEPTION_PROLOGUE_KEEP_AE ; return ECR in r10
  91. lr r0, [efa]
  92. mov r1, sp
  93. FAKE_RET_FROM_EXCPN ; clobbers r9
  94. .endm
  95. /*------------------------------------------------------------------------
  96. * This macro saves the registers manually which would normally be autosaved
  97. * by hardware on taken interrupts. It is used by
  98. * - exception handlers (which don't have autosave)
  99. * - interrupt autosave disabled due to CONFIG_ARC_IRQ_NO_AUTOSAVE
  100. */
  101. .macro __SAVE_REGFILE_HARD
  102. ST2 r0, r1, PT_r0
  103. ST2 r2, r3, PT_r2
  104. ST2 r4, r5, PT_r4
  105. ST2 r6, r7, PT_r6
  106. ST2 r8, r9, PT_r8
  107. ST2 r10, r11, PT_r10
  108. st blink, [sp, PT_blink]
  109. lr r10, [lp_end]
  110. lr r11, [lp_start]
  111. ST2 r10, r11, PT_lpe
  112. st lp_count, [sp, PT_lpc]
  113. ; skip JLI, LDI, EI for now
  114. .endm
  115. /*------------------------------------------------------------------------
  116. * This macros saves a bunch of other registers which can't be autosaved for
  117. * various reasons:
  118. * - r12: the last caller saved scratch reg since hardware saves in pairs so r0-r11
  119. * - r30: free reg, used by gcc as scratch
  120. * - ACCL/ACCH pair when they exist
  121. */
  122. .macro __SAVE_REGFILE_SOFT
  123. st fp, [sp, PT_fp] ; r27
  124. st r30, [sp, PT_r30]
  125. st r12, [sp, PT_r12]
  126. st r26, [sp, PT_r26] ; gp
  127. ; Saving pt_regs->sp correctly requires some extra work due to the way
  128. ; Auto stack switch works
  129. ; - U mode: retrieve it from AUX_USER_SP
  130. ; - K mode: add the offset from current SP where H/w starts auto push
  131. ;
  132. ; 1. Utilize the fact that Z bit is set if Intr taken in U mode
  133. ; 2. Upon entry SP is always saved (for any inspection, unwinding etc),
  134. ; but on return, restored only if U mode
  135. lr r10, [AUX_USER_SP] ; U mode SP
  136. ; ISA requires ADD.nz to have same dest and src reg operands
  137. mov.nz r10, sp
  138. add2.nz r10, r10, SZ_PT_REGS/4 ; K mode SP
  139. st r10, [sp, PT_sp] ; SP (pt_regs->sp)
  140. #ifdef CONFIG_ARC_HAS_ACCL_REGS
  141. ST2 r58, r59, PT_r58
  142. #endif
  143. /* clobbers r10, r11 registers pair */
  144. DSP_SAVE_REGFILE_IRQ
  145. #ifdef CONFIG_ARC_CURR_IN_REG
  146. GET_CURR_TASK_ON_CPU gp
  147. #endif
  148. .endm
  149. /*------------------------------------------------------------------------*/
  150. .macro __RESTORE_REGFILE_SOFT
  151. ld fp, [sp, PT_fp]
  152. ld r30, [sp, PT_r30]
  153. ld r12, [sp, PT_r12]
  154. ld r26, [sp, PT_r26]
  155. ; Restore SP (into AUX_USER_SP) only if returning to U mode
  156. ; - for K mode, it will be implicitly restored as stack is unwound
  157. ; - Z flag set on K is inverse of what hardware does on interrupt entry
  158. ; but that doesn't really matter
  159. bz 1f
  160. ld r10, [sp, PT_sp] ; SP (pt_regs->sp)
  161. sr r10, [AUX_USER_SP]
  162. 1:
  163. /* clobbers r10, r11 registers pair */
  164. DSP_RESTORE_REGFILE_IRQ
  165. #ifdef CONFIG_ARC_HAS_ACCL_REGS
  166. LD2 r58, r59, PT_r58
  167. #endif
  168. .endm
  169. /*------------------------------------------------------------------------*/
  170. .macro __RESTORE_REGFILE_HARD
  171. ld blink, [sp, PT_blink]
  172. LD2 r10, r11, PT_lpe
  173. sr r10, [lp_end]
  174. sr r11, [lp_start]
  175. ld r10, [sp, PT_lpc] ; lp_count can't be target of LD
  176. mov lp_count, r10
  177. LD2 r0, r1, PT_r0
  178. LD2 r2, r3, PT_r2
  179. LD2 r4, r5, PT_r4
  180. LD2 r6, r7, PT_r6
  181. LD2 r8, r9, PT_r8
  182. LD2 r10, r11, PT_r10
  183. .endm
  184. /*------------------------------------------------------------------------*/
  185. .macro INTERRUPT_EPILOGUE
  186. ; INPUT: r0 has STAT32 of calling context
  187. ; INPUT: Z flag set if returning to K mode
  188. ; _SOFT clobbers r10 restored by _HARD hence the order
  189. __RESTORE_REGFILE_SOFT
  190. #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
  191. __RESTORE_REGFILE_HARD
  192. ; SP points to PC/STAT32: hw restores them despite NO_AUTOSAVE
  193. add sp, sp, SZ_PT_REGS - 8
  194. #else
  195. add sp, sp, PT_r0
  196. #endif
  197. .endm
  198. /*------------------------------------------------------------------------*/
  199. .macro EXCEPTION_EPILOGUE
  200. ; INPUT: r0 has STAT32 of calling context
  201. btst r0, STATUS_U_BIT ; Z flag set if K, used in restoring SP
  202. ld r10, [sp, PT_bta]
  203. sr r10, [erbta]
  204. LD2 r10, r11, PT_ret
  205. sr r10, [eret]
  206. sr r11, [erstatus]
  207. __RESTORE_REGFILE_SOFT
  208. __RESTORE_REGFILE_HARD
  209. add sp, sp, SZ_PT_REGS
  210. .endm
  211. .macro FAKE_RET_FROM_EXCPN
  212. lr r9, [status32]
  213. bclr r9, r9, STATUS_AE_BIT
  214. bset r9, r9, STATUS_IE_BIT
  215. kflag r9
  216. .endm
  217. /* Get thread_info of "current" tsk */
  218. .macro GET_CURR_THR_INFO_FROM_SP reg
  219. bmskn \reg, sp, THREAD_SHIFT - 1
  220. .endm
  221. /* Get CPU-ID of this core */
  222. .macro GET_CPU_ID reg
  223. lr \reg, [identity]
  224. xbfu \reg, \reg, 0xE8 /* 00111 01000 */
  225. /* M = 8-1 N = 8 */
  226. .endm
  227. .macro SAVE_ABI_CALLEE_REGS
  228. push r13
  229. push r14
  230. push r15
  231. push r16
  232. push r17
  233. push r18
  234. push r19
  235. push r20
  236. push r21
  237. push r22
  238. push r23
  239. push r24
  240. push r25
  241. .endm
  242. .macro RESTORE_ABI_CALLEE_REGS
  243. pop r25
  244. pop r24
  245. pop r23
  246. pop r22
  247. pop r21
  248. pop r20
  249. pop r19
  250. pop r18
  251. pop r17
  252. pop r16
  253. pop r15
  254. pop r14
  255. pop r13
  256. .endm
  257. #endif