swsusp_asm64.S 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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. #include <asm/feature-fixups.h>
  16. /*
  17. * Structure for storing CPU registers on the save area.
  18. */
  19. #define SL_r1 0x00 /* stack pointer */
  20. #define SL_PC 0x08
  21. #define SL_MSR 0x10
  22. #define SL_SDR1 0x18
  23. #define SL_XER 0x20
  24. #define SL_TB 0x40
  25. #define SL_r2 0x48
  26. #define SL_CR 0x50
  27. #define SL_LR 0x58
  28. #define SL_r12 0x60
  29. #define SL_r13 0x68
  30. #define SL_r14 0x70
  31. #define SL_r15 0x78
  32. #define SL_r16 0x80
  33. #define SL_r17 0x88
  34. #define SL_r18 0x90
  35. #define SL_r19 0x98
  36. #define SL_r20 0xa0
  37. #define SL_r21 0xa8
  38. #define SL_r22 0xb0
  39. #define SL_r23 0xb8
  40. #define SL_r24 0xc0
  41. #define SL_r25 0xc8
  42. #define SL_r26 0xd0
  43. #define SL_r27 0xd8
  44. #define SL_r28 0xe0
  45. #define SL_r29 0xe8
  46. #define SL_r30 0xf0
  47. #define SL_r31 0xf8
  48. #define SL_SPRG1 0x100
  49. #define SL_TCR 0x108
  50. #define SL_SIZE SL_TCR+8
  51. /* these macros rely on the save area being
  52. * pointed to by r11 */
  53. #define SAVE_SPR(register) \
  54. mfspr r0, SPRN_##register ;\
  55. std r0, SL_##register(r11)
  56. #define RESTORE_SPR(register) \
  57. ld r0, SL_##register(r11) ;\
  58. mtspr SPRN_##register, r0
  59. #define SAVE_SPECIAL(special) \
  60. mf##special r0 ;\
  61. std r0, SL_##special(r11)
  62. #define RESTORE_SPECIAL(special) \
  63. ld r0, SL_##special(r11) ;\
  64. mt##special r0
  65. #define SAVE_REGISTER(reg) \
  66. std reg, SL_##reg(r11)
  67. #define RESTORE_REGISTER(reg) \
  68. ld reg, SL_##reg(r11)
  69. /* space for storing cpu state */
  70. .section .data
  71. .align 5
  72. swsusp_save_area:
  73. .space SL_SIZE
  74. .section ".toc","aw"
  75. swsusp_save_area_ptr:
  76. .tc swsusp_save_area[TC],swsusp_save_area
  77. restore_pblist_ptr:
  78. .tc restore_pblist[TC],restore_pblist
  79. .section .text
  80. .align 5
  81. _GLOBAL(swsusp_arch_suspend)
  82. ld r11,swsusp_save_area_ptr@toc(r2)
  83. SAVE_SPECIAL(LR)
  84. SAVE_REGISTER(r1)
  85. SAVE_SPECIAL(CR)
  86. SAVE_SPECIAL(TB)
  87. SAVE_REGISTER(r2)
  88. SAVE_REGISTER(r12)
  89. SAVE_REGISTER(r13)
  90. SAVE_REGISTER(r14)
  91. SAVE_REGISTER(r15)
  92. SAVE_REGISTER(r16)
  93. SAVE_REGISTER(r17)
  94. SAVE_REGISTER(r18)
  95. SAVE_REGISTER(r19)
  96. SAVE_REGISTER(r20)
  97. SAVE_REGISTER(r21)
  98. SAVE_REGISTER(r22)
  99. SAVE_REGISTER(r23)
  100. SAVE_REGISTER(r24)
  101. SAVE_REGISTER(r25)
  102. SAVE_REGISTER(r26)
  103. SAVE_REGISTER(r27)
  104. SAVE_REGISTER(r28)
  105. SAVE_REGISTER(r29)
  106. SAVE_REGISTER(r30)
  107. SAVE_REGISTER(r31)
  108. SAVE_SPECIAL(MSR)
  109. SAVE_SPECIAL(XER)
  110. #ifdef CONFIG_PPC_BOOK3S_64
  111. BEGIN_FW_FTR_SECTION
  112. SAVE_SPECIAL(SDR1)
  113. END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
  114. #else
  115. SAVE_SPR(TCR)
  116. /* Save SPRG1, SPRG1 be used save paca */
  117. SAVE_SPR(SPRG1)
  118. #endif
  119. /* we push the stack up 128 bytes but don't store the
  120. * stack pointer on the stack like a real stackframe */
  121. addi r1,r1,-128
  122. bl _iommu_save
  123. bl swsusp_save
  124. /* restore LR */
  125. ld r11,swsusp_save_area_ptr@toc(r2)
  126. RESTORE_SPECIAL(LR)
  127. addi r1,r1,128
  128. blr
  129. /* Resume code */
  130. _GLOBAL(swsusp_arch_resume)
  131. /* Stop pending alitvec streams and memory accesses */
  132. BEGIN_FTR_SECTION
  133. DSSALL
  134. END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  135. sync
  136. ld r12,restore_pblist_ptr@toc(r2)
  137. ld r12,0(r12)
  138. cmpdi r12,0
  139. beq- nothing_to_copy
  140. li r15,PAGE_SIZE>>3
  141. copyloop:
  142. ld r13,pbe_address(r12)
  143. ld r14,pbe_orig_address(r12)
  144. mtctr r15
  145. li r10,0
  146. copy_page_loop:
  147. ldx r0,r10,r13
  148. stdx r0,r10,r14
  149. addi r10,r10,8
  150. bdnz copy_page_loop
  151. ld r12,pbe_next(r12)
  152. cmpdi r12,0
  153. bne+ copyloop
  154. nothing_to_copy:
  155. #ifdef CONFIG_PPC_BOOK3S_64
  156. /* flush caches */
  157. lis r3, 0x10
  158. mtctr r3
  159. li r3, 0
  160. ori r3, r3, CONFIG_KERNEL_START>>48
  161. li r0, 48
  162. sld r3, r3, r0
  163. li r0, 0
  164. 1:
  165. dcbf 0,r3
  166. addi r3,r3,0x20
  167. bdnz 1b
  168. sync
  169. tlbia
  170. #endif
  171. ld r11,swsusp_save_area_ptr@toc(r2)
  172. RESTORE_SPECIAL(CR)
  173. /* restore timebase */
  174. /* load saved tb */
  175. ld r1, SL_TB(r11)
  176. /* get upper 32 bits of it */
  177. srdi r2, r1, 32
  178. /* clear tb lower to avoid wrap */
  179. li r0, 0
  180. mttbl r0
  181. /* set tb upper */
  182. mttbu r2
  183. /* set tb lower */
  184. mttbl r1
  185. /* restore registers */
  186. RESTORE_REGISTER(r1)
  187. RESTORE_REGISTER(r2)
  188. RESTORE_REGISTER(r12)
  189. RESTORE_REGISTER(r13)
  190. RESTORE_REGISTER(r14)
  191. RESTORE_REGISTER(r15)
  192. RESTORE_REGISTER(r16)
  193. RESTORE_REGISTER(r17)
  194. RESTORE_REGISTER(r18)
  195. RESTORE_REGISTER(r19)
  196. RESTORE_REGISTER(r20)
  197. RESTORE_REGISTER(r21)
  198. RESTORE_REGISTER(r22)
  199. RESTORE_REGISTER(r23)
  200. RESTORE_REGISTER(r24)
  201. RESTORE_REGISTER(r25)
  202. RESTORE_REGISTER(r26)
  203. RESTORE_REGISTER(r27)
  204. RESTORE_REGISTER(r28)
  205. RESTORE_REGISTER(r29)
  206. RESTORE_REGISTER(r30)
  207. RESTORE_REGISTER(r31)
  208. #ifdef CONFIG_PPC_BOOK3S_64
  209. /* can't use RESTORE_SPECIAL(MSR) */
  210. ld r0, SL_MSR(r11)
  211. mtmsrd r0, 0
  212. BEGIN_FW_FTR_SECTION
  213. RESTORE_SPECIAL(SDR1)
  214. END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
  215. #else
  216. /* Restore SPRG1, be used to save paca */
  217. ld r0, SL_SPRG1(r11)
  218. mtsprg 1, r0
  219. RESTORE_SPECIAL(MSR)
  220. /* Restore TCR and clear any pending bits in TSR. */
  221. RESTORE_SPR(TCR)
  222. lis r0, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
  223. mtspr SPRN_TSR, r0
  224. /* Kick decrementer */
  225. li r0, 1
  226. mtdec r0
  227. /* Invalidate all tlbs */
  228. bl _tlbil_all
  229. #endif
  230. RESTORE_SPECIAL(XER)
  231. sync
  232. addi r1,r1,-128
  233. #ifdef CONFIG_PPC_BOOK3S_64
  234. bl slb_flush_and_rebolt
  235. #endif
  236. bl do_after_copyback
  237. addi r1,r1,128
  238. ld r11,swsusp_save_area_ptr@toc(r2)
  239. RESTORE_SPECIAL(LR)
  240. li r3, 0
  241. blr