entry-arcv2.h 4.0 KB

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