swsusp_asm64.S 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * PowerPC 64-bit swsusp implementation
  3. *
  4. * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
  5. *
  6. * GPLv2
  7. */
  8. #include <linux/threads.h>
  9. #include <asm/processor.h>
  10. #include <asm/page.h>
  11. #include <asm/cputable.h>
  12. #include <asm/thread_info.h>
  13. #include <asm/ppc_asm.h>
  14. #include <asm/asm-offsets.h>
  15. /*
  16. * Structure for storing CPU registers on the save area.
  17. */
  18. #define SL_r1 0x00 /* stack pointer */
  19. #define SL_PC 0x08
  20. #define SL_MSR 0x10
  21. #define SL_SDR1 0x18
  22. #define SL_XER 0x20
  23. #define SL_TB 0x40
  24. #define SL_r2 0x48
  25. #define SL_CR 0x50
  26. #define SL_LR 0x58
  27. #define SL_r12 0x60
  28. #define SL_r13 0x68
  29. #define SL_r14 0x70
  30. #define SL_r15 0x78
  31. #define SL_r16 0x80
  32. #define SL_r17 0x88
  33. #define SL_r18 0x90
  34. #define SL_r19 0x98
  35. #define SL_r20 0xa0
  36. #define SL_r21 0xa8
  37. #define SL_r22 0xb0
  38. #define SL_r23 0xb8
  39. #define SL_r24 0xc0
  40. #define SL_r25 0xc8
  41. #define SL_r26 0xd0
  42. #define SL_r27 0xd8
  43. #define SL_r28 0xe0
  44. #define SL_r29 0xe8
  45. #define SL_r30 0xf0
  46. #define SL_r31 0xf8
  47. #define SL_SIZE SL_r31+8
  48. /* these macros rely on the save area being
  49. * pointed to by r11 */
  50. #define SAVE_SPECIAL(special) \
  51. mf##special r0 ;\
  52. std r0, SL_##special(r11)
  53. #define RESTORE_SPECIAL(special) \
  54. ld r0, SL_##special(r11) ;\
  55. mt##special r0
  56. #define SAVE_REGISTER(reg) \
  57. std reg, SL_##reg(r11)
  58. #define RESTORE_REGISTER(reg) \
  59. ld reg, SL_##reg(r11)
  60. /* space for storing cpu state */
  61. .section .data
  62. .align 5
  63. swsusp_save_area:
  64. .space SL_SIZE
  65. .section ".toc","aw"
  66. swsusp_save_area_ptr:
  67. .tc swsusp_save_area[TC],swsusp_save_area
  68. restore_pblist_ptr:
  69. .tc restore_pblist[TC],restore_pblist
  70. .section .text
  71. .align 5
  72. _GLOBAL(swsusp_arch_suspend)
  73. ld r11,swsusp_save_area_ptr@toc(r2)
  74. SAVE_SPECIAL(LR)
  75. SAVE_REGISTER(r1)
  76. SAVE_SPECIAL(CR)
  77. SAVE_SPECIAL(TB)
  78. SAVE_REGISTER(r2)
  79. SAVE_REGISTER(r12)
  80. SAVE_REGISTER(r13)
  81. SAVE_REGISTER(r14)
  82. SAVE_REGISTER(r15)
  83. SAVE_REGISTER(r16)
  84. SAVE_REGISTER(r17)
  85. SAVE_REGISTER(r18)
  86. SAVE_REGISTER(r19)
  87. SAVE_REGISTER(r20)
  88. SAVE_REGISTER(r21)
  89. SAVE_REGISTER(r22)
  90. SAVE_REGISTER(r23)
  91. SAVE_REGISTER(r24)
  92. SAVE_REGISTER(r25)
  93. SAVE_REGISTER(r26)
  94. SAVE_REGISTER(r27)
  95. SAVE_REGISTER(r28)
  96. SAVE_REGISTER(r29)
  97. SAVE_REGISTER(r30)
  98. SAVE_REGISTER(r31)
  99. SAVE_SPECIAL(MSR)
  100. SAVE_SPECIAL(SDR1)
  101. SAVE_SPECIAL(XER)
  102. /* we push the stack up 128 bytes but don't store the
  103. * stack pointer on the stack like a real stackframe */
  104. addi r1,r1,-128
  105. bl _iommu_save
  106. bl swsusp_save
  107. /* restore LR */
  108. ld r11,swsusp_save_area_ptr@toc(r2)
  109. RESTORE_SPECIAL(LR)
  110. addi r1,r1,128
  111. blr
  112. /* Resume code */
  113. _GLOBAL(swsusp_arch_resume)
  114. /* Stop pending alitvec streams and memory accesses */
  115. BEGIN_FTR_SECTION
  116. DSSALL
  117. END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  118. sync
  119. ld r12,restore_pblist_ptr@toc(r2)
  120. ld r12,0(r12)
  121. cmpdi r12,0
  122. beq- nothing_to_copy
  123. li r15,PAGE_SIZE>>3
  124. copyloop:
  125. ld r13,pbe_address(r12)
  126. ld r14,pbe_orig_address(r12)
  127. mtctr r15
  128. li r10,0
  129. copy_page_loop:
  130. ldx r0,r10,r13
  131. stdx r0,r10,r14
  132. addi r10,r10,8
  133. bdnz copy_page_loop
  134. ld r12,pbe_next(r12)
  135. cmpdi r12,0
  136. bne+ copyloop
  137. nothing_to_copy:
  138. /* flush caches */
  139. lis r3, 0x10
  140. mtctr r3
  141. li r3, 0
  142. ori r3, r3, CONFIG_KERNEL_START>>48
  143. li r0, 48
  144. sld r3, r3, r0
  145. li r0, 0
  146. 1:
  147. dcbf r0,r3
  148. addi r3,r3,0x20
  149. bdnz 1b
  150. sync
  151. tlbia
  152. ld r11,swsusp_save_area_ptr@toc(r2)
  153. RESTORE_SPECIAL(CR)
  154. /* restore timebase */
  155. /* load saved tb */
  156. ld r1, SL_TB(r11)
  157. /* get upper 32 bits of it */
  158. srdi r2, r1, 32
  159. /* clear tb lower to avoid wrap */
  160. li r0, 0
  161. mttbl r0
  162. /* set tb upper */
  163. mttbu r2
  164. /* set tb lower */
  165. mttbl r1
  166. /* restore registers */
  167. RESTORE_REGISTER(r1)
  168. RESTORE_REGISTER(r2)
  169. RESTORE_REGISTER(r12)
  170. RESTORE_REGISTER(r13)
  171. RESTORE_REGISTER(r14)
  172. RESTORE_REGISTER(r15)
  173. RESTORE_REGISTER(r16)
  174. RESTORE_REGISTER(r17)
  175. RESTORE_REGISTER(r18)
  176. RESTORE_REGISTER(r19)
  177. RESTORE_REGISTER(r20)
  178. RESTORE_REGISTER(r21)
  179. RESTORE_REGISTER(r22)
  180. RESTORE_REGISTER(r23)
  181. RESTORE_REGISTER(r24)
  182. RESTORE_REGISTER(r25)
  183. RESTORE_REGISTER(r26)
  184. RESTORE_REGISTER(r27)
  185. RESTORE_REGISTER(r28)
  186. RESTORE_REGISTER(r29)
  187. RESTORE_REGISTER(r30)
  188. RESTORE_REGISTER(r31)
  189. /* can't use RESTORE_SPECIAL(MSR) */
  190. ld r0, SL_MSR(r11)
  191. mtmsrd r0, 0
  192. RESTORE_SPECIAL(SDR1)
  193. RESTORE_SPECIAL(XER)
  194. sync
  195. addi r1,r1,-128
  196. bl slb_flush_and_rebolt
  197. bl do_after_copyback
  198. addi r1,r1,128
  199. ld r11,swsusp_save_area_ptr@toc(r2)
  200. RESTORE_SPECIAL(LR)
  201. li r3, 0
  202. blr