switch_to.S 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. ###############################################################################
  2. #
  3. # MN10300 Context switch operation
  4. #
  5. # Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  6. # Written by David Howells (dhowells@redhat.com)
  7. #
  8. # This program is free software; you can redistribute it and/or
  9. # modify it under the terms of the GNU General Public Licence
  10. # as published by the Free Software Foundation; either version
  11. # 2 of the Licence, or (at your option) any later version.
  12. #
  13. ###############################################################################
  14. #include <linux/sys.h>
  15. #include <linux/linkage.h>
  16. #include <asm/thread_info.h>
  17. #include <asm/cpu-regs.h>
  18. #ifdef CONFIG_SMP
  19. #include <proc/smp-regs.h>
  20. #endif /* CONFIG_SMP */
  21. .text
  22. ###############################################################################
  23. #
  24. # struct task_struct *__switch_to(struct thread_struct *prev,
  25. # struct thread_struct *next,
  26. # struct task_struct *prev_task)
  27. #
  28. ###############################################################################
  29. ENTRY(__switch_to)
  30. movm [d2,d3,a2,a3,exreg1],(sp)
  31. or EPSW_NMID,epsw
  32. mov (44,sp),d2
  33. mov d0,a0
  34. mov d1,a1
  35. # save prev context
  36. mov __switch_back,d0
  37. mov sp,a2
  38. mov a2,(THREAD_SP,a0)
  39. mov a3,(THREAD_A3,a0)
  40. #ifdef CONFIG_KGDB
  41. btst 0xff,(kgdb_single_step)
  42. bne __switch_to__lift_sstep_bp
  43. __switch_to__continue:
  44. #endif
  45. mov d0,(THREAD_PC,a0)
  46. mov (THREAD_A3,a1),a3
  47. mov (THREAD_SP,a1),a2
  48. # switch
  49. mov a2,sp
  50. # load next context
  51. GET_THREAD_INFO a2
  52. mov a2,(__current_ti)
  53. mov (TI_task,a2),a2
  54. mov a2,(__current)
  55. #ifdef CONFIG_MN10300_CURRENT_IN_E2
  56. mov a2,e2
  57. #endif
  58. mov (THREAD_PC,a1),a2
  59. mov d2,d0 # for ret_from_fork
  60. mov d0,a0 # for __switch_to
  61. jmp (a2)
  62. __switch_back:
  63. and ~EPSW_NMID,epsw
  64. ret [d2,d3,a2,a3,exreg1],32
  65. #ifdef CONFIG_KGDB
  66. ###############################################################################
  67. #
  68. # Lift the single-step breakpoints when the task being traced is switched out
  69. # A0 = prev
  70. # A1 = next
  71. #
  72. ###############################################################################
  73. __switch_to__lift_sstep_bp:
  74. add -12,sp
  75. mov a0,e4
  76. mov a1,e5
  77. # Clear the single-step flag to prevent us coming this way until we get
  78. # switched back in
  79. bclr 0xff,(kgdb_single_step)
  80. # Remove first breakpoint
  81. mov (kgdb_sstep_bp_addr),a2
  82. cmp 0,a2
  83. beq 1f
  84. movbu (kgdb_sstep_bp),d0
  85. movbu d0,(a2)
  86. #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
  87. mov a2,d0
  88. mov a2,d1
  89. add 1,d1
  90. calls flush_icache_range
  91. #endif
  92. 1:
  93. # Remove second breakpoint
  94. mov (kgdb_sstep_bp_addr+4),a2
  95. cmp 0,a2
  96. beq 2f
  97. movbu (kgdb_sstep_bp+1),d0
  98. movbu d0,(a2)
  99. #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
  100. mov a2,d0
  101. mov a2,d1
  102. add 1,d1
  103. calls flush_icache_range
  104. #endif
  105. 2:
  106. # Change the resumption address and return
  107. mov __switch_back__reinstall_sstep_bp,d0
  108. mov e4,a0
  109. mov e5,a1
  110. add 12,sp
  111. bra __switch_to__continue
  112. ###############################################################################
  113. #
  114. # Reinstall the single-step breakpoints when the task being traced is switched
  115. # back in (A1 points to the new thread_struct).
  116. #
  117. ###############################################################################
  118. __switch_back__reinstall_sstep_bp:
  119. add -12,sp
  120. mov a0,e4 # save the return value
  121. mov 0xff,d3
  122. # Reinstall first breakpoint
  123. mov (kgdb_sstep_bp_addr),a2
  124. cmp 0,a2
  125. beq 1f
  126. movbu (a2),d0
  127. movbu d0,(kgdb_sstep_bp)
  128. movbu d3,(a2)
  129. #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
  130. mov a2,d0
  131. mov a2,d1
  132. add 1,d1
  133. calls flush_icache_range
  134. #endif
  135. 1:
  136. # Reinstall second breakpoint
  137. mov (kgdb_sstep_bp_addr+4),a2
  138. cmp 0,a2
  139. beq 2f
  140. movbu (a2),d0
  141. movbu d0,(kgdb_sstep_bp+1)
  142. movbu d3,(a2)
  143. #if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
  144. mov a2,d0
  145. mov a2,d1
  146. add 1,d1
  147. calls flush_icache_range
  148. #endif
  149. 2:
  150. mov d3,(kgdb_single_step)
  151. # Restore the return value (the previous thread_struct pointer)
  152. mov e4,a0
  153. mov a0,d0
  154. add 12,sp
  155. bra __switch_back
  156. #endif /* CONFIG_KGDB */