entry-arcv2.h 4.0 KB

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