entry-arcv2.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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/irqflags-arcv2.h>
  6. #include <asm/thread_info.h> /* For THREAD_SIZE */
  7. /*------------------------------------------------------------------------*/
  8. .macro INTERRUPT_PROLOGUE called_from
  9. ; Before jumping to Interrupt Vector, hardware micro-ops did following:
  10. ; 1. SP auto-switched to kernel mode stack
  11. ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1, K:0)
  12. ; 3. Auto saved: r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI, PC, STAT32
  13. ;
  14. ; Now manually save: r12, sp, fp, gp, r25
  15. #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
  16. .ifnc \called_from, exception
  17. st.as r9, [sp, -10] ; save r9 in it's final stack slot
  18. sub sp, sp, 12 ; skip JLI, LDI, EI
  19. PUSH lp_count
  20. PUSHAX lp_start
  21. PUSHAX lp_end
  22. PUSH blink
  23. PUSH r11
  24. PUSH r10
  25. sub sp, sp, 4 ; skip r9
  26. PUSH r8
  27. PUSH r7
  28. PUSH r6
  29. PUSH r5
  30. PUSH r4
  31. PUSH r3
  32. PUSH r2
  33. PUSH r1
  34. PUSH r0
  35. .endif
  36. #endif
  37. #ifdef CONFIG_ARC_HAS_ACCL_REGS
  38. PUSH r59
  39. PUSH r58
  40. #endif
  41. PUSH r30
  42. PUSH r12
  43. ; Saving pt_regs->sp correctly requires some extra work due to the way
  44. ; Auto stack switch works
  45. ; - U mode: retrieve it from AUX_USER_SP
  46. ; - K mode: add the offset from current SP where H/w starts auto push
  47. ;
  48. ; Utilize the fact that Z bit is set if Intr taken in U mode
  49. mov.nz r9, sp
  50. add.nz r9, r9, SZ_PT_REGS - PT_sp - 4
  51. bnz 1f
  52. lr r9, [AUX_USER_SP]
  53. 1:
  54. PUSH r9 ; SP
  55. PUSH fp
  56. PUSH gp
  57. #ifdef CONFIG_ARC_CURR_IN_REG
  58. PUSH r25 ; user_r25
  59. GET_CURR_TASK_ON_CPU r25
  60. #else
  61. sub sp, sp, 4
  62. #endif
  63. .ifnc \called_from, exception
  64. sub sp, sp, 12 ; BTA/ECR/orig_r0 placeholder per pt_regs
  65. .endif
  66. .endm
  67. /*------------------------------------------------------------------------*/
  68. .macro INTERRUPT_EPILOGUE called_from
  69. .ifnc \called_from, exception
  70. add sp, sp, 12 ; skip BTA/ECR/orig_r0 placeholderss
  71. .endif
  72. #ifdef CONFIG_ARC_CURR_IN_REG
  73. POP r25
  74. #else
  75. add sp, sp, 4
  76. #endif
  77. POP gp
  78. POP fp
  79. ; Don't touch AUX_USER_SP if returning to K mode (Z bit set)
  80. ; (Z bit set on K mode is inverse of INTERRUPT_PROLOGUE)
  81. add.z sp, sp, 4
  82. bz 1f
  83. POPAX AUX_USER_SP
  84. 1:
  85. POP r12
  86. POP r30
  87. #ifdef CONFIG_ARC_HAS_ACCL_REGS
  88. POP r58
  89. POP r59
  90. #endif
  91. #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
  92. .ifnc \called_from, exception
  93. POP r0
  94. POP r1
  95. POP r2
  96. POP r3
  97. POP r4
  98. POP r5
  99. POP r6
  100. POP r7
  101. POP r8
  102. POP r9
  103. POP r10
  104. POP r11
  105. POP blink
  106. POPAX lp_end
  107. POPAX lp_start
  108. POP r9
  109. mov lp_count, r9
  110. add sp, sp, 12 ; skip JLI, LDI, EI
  111. ld.as r9, [sp, -10] ; reload r9 which got clobbered
  112. .endif
  113. #endif
  114. .endm
  115. /*------------------------------------------------------------------------*/
  116. .macro EXCEPTION_PROLOGUE
  117. ; Before jumping to Exception Vector, hardware micro-ops did following:
  118. ; 1. SP auto-switched to kernel mode stack
  119. ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1,K:0)
  120. ;
  121. ; Now manually save the complete reg file
  122. PUSH r9 ; freeup a register: slot of erstatus
  123. PUSHAX eret
  124. sub sp, sp, 12 ; skip JLI, LDI, EI
  125. PUSH lp_count
  126. PUSHAX lp_start
  127. PUSHAX lp_end
  128. PUSH blink
  129. PUSH r11
  130. PUSH r10
  131. ld.as r9, [sp, 10] ; load stashed r9 (status32 stack slot)
  132. lr r10, [erstatus]
  133. st.as r10, [sp, 10] ; save status32 at it's right stack slot
  134. PUSH r9
  135. PUSH r8
  136. PUSH r7
  137. PUSH r6
  138. PUSH r5
  139. PUSH r4
  140. PUSH r3
  141. PUSH r2
  142. PUSH r1
  143. PUSH r0
  144. ; -- for interrupts, regs above are auto-saved by h/w in that order --
  145. ; Now do what ISR prologue does (manually save r12, sp, fp, gp, r25)
  146. ;
  147. ; Set Z flag if this was from U mode (expected by INTERRUPT_PROLOGUE)
  148. ; Although H/w exception micro-ops do set Z flag for U mode (just like
  149. ; for interrupts), it could get clobbered in case we soft land here from
  150. ; a TLB Miss exception handler (tlbex.S)
  151. and r10, r10, STATUS_U_MASK
  152. xor.f 0, r10, STATUS_U_MASK
  153. INTERRUPT_PROLOGUE exception
  154. PUSHAX erbta
  155. PUSHAX ecr ; r9 contains ECR, expected by EV_Trap
  156. PUSH r0 ; orig_r0
  157. .endm
  158. /*------------------------------------------------------------------------*/
  159. .macro EXCEPTION_EPILOGUE
  160. ; Assumes r0 has PT_status32
  161. btst r0, STATUS_U_BIT ; Z flag set if K, used in INTERRUPT_EPILOGUE
  162. add sp, sp, 8 ; orig_r0/ECR don't need restoring
  163. POPAX erbta
  164. INTERRUPT_EPILOGUE exception
  165. POP r0
  166. POP r1
  167. POP r2
  168. POP r3
  169. POP r4
  170. POP r5
  171. POP r6
  172. POP r7
  173. POP r8
  174. POP r9
  175. POP r10
  176. POP r11
  177. POP blink
  178. POPAX lp_end
  179. POPAX lp_start
  180. POP r9
  181. mov lp_count, r9
  182. add sp, sp, 12 ; skip JLI, LDI, EI
  183. POPAX eret
  184. POPAX erstatus
  185. ld.as r9, [sp, -12] ; reload r9 which got clobbered
  186. .endm
  187. .macro FAKE_RET_FROM_EXCPN
  188. lr r9, [status32]
  189. bic r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK)
  190. or r9, r9, STATUS_IE_MASK
  191. kflag r9
  192. .endm
  193. /* Get thread_info of "current" tsk */
  194. .macro GET_CURR_THR_INFO_FROM_SP reg
  195. bmskn \reg, sp, THREAD_SHIFT - 1
  196. .endm
  197. /* Get CPU-ID of this core */
  198. .macro GET_CPU_ID reg
  199. lr \reg, [identity]
  200. xbfu \reg, \reg, 0xE8 /* 00111 01000 */
  201. /* M = 8-1 N = 8 */
  202. .endm
  203. #endif