switchto.S 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * arch/sh/kernel/cpu/sh5/switchto.S
  3. *
  4. * sh64 context switch
  5. *
  6. * Copyright (C) 2004 Richard Curnow
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file "COPYING" in the main directory of this archive
  10. * for more details.
  11. */
  12. .section .text..SHmedia32,"ax"
  13. .little
  14. .balign 32
  15. .type sh64_switch_to,@function
  16. .global sh64_switch_to
  17. .global __sh64_switch_to_end
  18. sh64_switch_to:
  19. /* Incoming args
  20. r2 - prev
  21. r3 - &prev->thread
  22. r4 - next
  23. r5 - &next->thread
  24. Outgoing results
  25. r2 - last (=prev) : this just stays in r2 throughout
  26. Want to create a full (struct pt_regs) on the stack to allow backtracing
  27. functions to work. However, we only need to populate the callee-save
  28. register slots in this structure; since we're a function our ancestors must
  29. have themselves preserved all caller saved state in the stack. This saves
  30. some wasted effort since we won't need to look at the values.
  31. In particular, all caller-save registers are immediately available for
  32. scratch use.
  33. */
  34. #define FRAME_SIZE (76*8 + 8)
  35. movi FRAME_SIZE, r0
  36. sub.l r15, r0, r15
  37. ! Do normal-style register save to support backtrace
  38. st.l r15, 0, r18 ! save link reg
  39. st.l r15, 4, r14 ! save fp
  40. add.l r15, r63, r14 ! setup frame pointer
  41. ! hopefully this looks normal to the backtrace now.
  42. addi.l r15, 8, r1 ! base of pt_regs
  43. addi.l r1, 24, r0 ! base of pt_regs.regs
  44. addi.l r0, (63*8), r8 ! base of pt_regs.trregs
  45. /* Note : to be fixed?
  46. struct pt_regs is really designed for holding the state on entry
  47. to an exception, i.e. pc,sr,regs etc. However, for the context
  48. switch state, some of this is not required. But the unwinder takes
  49. struct pt_regs * as an arg so we have to build this structure
  50. to allow unwinding switched tasks in show_state() */
  51. st.q r0, ( 9*8), r9
  52. st.q r0, (10*8), r10
  53. st.q r0, (11*8), r11
  54. st.q r0, (12*8), r12
  55. st.q r0, (13*8), r13
  56. st.q r0, (14*8), r14 ! for unwind, want to look as though we took a trap at
  57. ! the point where the process is left in suspended animation, i.e. current
  58. ! fp here, not the saved one.
  59. st.q r0, (16*8), r16
  60. st.q r0, (24*8), r24
  61. st.q r0, (25*8), r25
  62. st.q r0, (26*8), r26
  63. st.q r0, (27*8), r27
  64. st.q r0, (28*8), r28
  65. st.q r0, (29*8), r29
  66. st.q r0, (30*8), r30
  67. st.q r0, (31*8), r31
  68. st.q r0, (32*8), r32
  69. st.q r0, (33*8), r33
  70. st.q r0, (34*8), r34
  71. st.q r0, (35*8), r35
  72. st.q r0, (44*8), r44
  73. st.q r0, (45*8), r45
  74. st.q r0, (46*8), r46
  75. st.q r0, (47*8), r47
  76. st.q r0, (48*8), r48
  77. st.q r0, (49*8), r49
  78. st.q r0, (50*8), r50
  79. st.q r0, (51*8), r51
  80. st.q r0, (52*8), r52
  81. st.q r0, (53*8), r53
  82. st.q r0, (54*8), r54
  83. st.q r0, (55*8), r55
  84. st.q r0, (56*8), r56
  85. st.q r0, (57*8), r57
  86. st.q r0, (58*8), r58
  87. st.q r0, (59*8), r59
  88. ! do this early as pta->gettr has no pipeline forwarding (=> 5 cycle latency)
  89. ! Use a local label to avoid creating a symbol that will confuse the !
  90. ! backtrace
  91. pta .Lsave_pc, tr0
  92. gettr tr5, r45
  93. gettr tr6, r46
  94. gettr tr7, r47
  95. st.q r8, (5*8), r45
  96. st.q r8, (6*8), r46
  97. st.q r8, (7*8), r47
  98. ! Now switch context
  99. gettr tr0, r9
  100. st.l r3, 0, r15 ! prev->thread.sp
  101. st.l r3, 8, r1 ! prev->thread.kregs
  102. st.l r3, 4, r9 ! prev->thread.pc
  103. st.q r1, 0, r9 ! save prev->thread.pc into pt_regs->pc
  104. ! Load PC for next task (init value or save_pc later)
  105. ld.l r5, 4, r18 ! next->thread.pc
  106. ! Switch stacks
  107. ld.l r5, 0, r15 ! next->thread.sp
  108. ptabs r18, tr0
  109. ! Update current
  110. ld.l r4, 4, r9 ! next->thread_info (2nd element of next task_struct)
  111. putcon r9, kcr0 ! current = next->thread_info
  112. ! go to save_pc for a reschedule, or the initial thread.pc for a new process
  113. blink tr0, r63
  114. ! Restore (when we come back to a previously saved task)
  115. .Lsave_pc:
  116. addi.l r15, 32, r0 ! r0 = next's regs
  117. addi.l r0, (63*8), r8 ! r8 = next's tr_regs
  118. ld.q r8, (5*8), r45
  119. ld.q r8, (6*8), r46
  120. ld.q r8, (7*8), r47
  121. ptabs r45, tr5
  122. ptabs r46, tr6
  123. ptabs r47, tr7
  124. ld.q r0, ( 9*8), r9
  125. ld.q r0, (10*8), r10
  126. ld.q r0, (11*8), r11
  127. ld.q r0, (12*8), r12
  128. ld.q r0, (13*8), r13
  129. ld.q r0, (14*8), r14
  130. ld.q r0, (16*8), r16
  131. ld.q r0, (24*8), r24
  132. ld.q r0, (25*8), r25
  133. ld.q r0, (26*8), r26
  134. ld.q r0, (27*8), r27
  135. ld.q r0, (28*8), r28
  136. ld.q r0, (29*8), r29
  137. ld.q r0, (30*8), r30
  138. ld.q r0, (31*8), r31
  139. ld.q r0, (32*8), r32
  140. ld.q r0, (33*8), r33
  141. ld.q r0, (34*8), r34
  142. ld.q r0, (35*8), r35
  143. ld.q r0, (44*8), r44
  144. ld.q r0, (45*8), r45
  145. ld.q r0, (46*8), r46
  146. ld.q r0, (47*8), r47
  147. ld.q r0, (48*8), r48
  148. ld.q r0, (49*8), r49
  149. ld.q r0, (50*8), r50
  150. ld.q r0, (51*8), r51
  151. ld.q r0, (52*8), r52
  152. ld.q r0, (53*8), r53
  153. ld.q r0, (54*8), r54
  154. ld.q r0, (55*8), r55
  155. ld.q r0, (56*8), r56
  156. ld.q r0, (57*8), r57
  157. ld.q r0, (58*8), r58
  158. ld.q r0, (59*8), r59
  159. ! epilogue
  160. ld.l r15, 0, r18
  161. ld.l r15, 4, r14
  162. ptabs r18, tr0
  163. movi FRAME_SIZE, r0
  164. add r15, r0, r15
  165. blink tr0, r63
  166. __sh64_switch_to_end:
  167. .LFE1:
  168. .size sh64_switch_to,.LFE1-sh64_switch_to