entry-arcv2.h 4.2 KB

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