swsusp_asm64.S 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * PowerPC 64-bit swsusp implementation
  4. *
  5. * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
  6. */
  7. #include <linux/threads.h>
  8. #include <asm/processor.h>
  9. #include <asm/page.h>
  10. #include <asm/cputable.h>
  11. #include <asm/thread_info.h>
  12. #include <asm/ppc_asm.h>
  13. #include <asm/asm-offsets.h>
  14. #include <asm/feature-fixups.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_SPRG1 0x100
  48. #define SL_TCR 0x108
  49. #define SL_SIZE SL_TCR+8
  50. /* these macros rely on the save area being
  51. * pointed to by r11 */
  52. #define SAVE_SPR(register) \
  53. mfspr r0, SPRN_##register ;\
  54. std r0, SL_##register(r11)
  55. #define RESTORE_SPR(register) \
  56. ld r0, SL_##register(r11) ;\
  57. mtspr SPRN_##register, r0
  58. #define SAVE_SPECIAL(special) \
  59. mf##special r0 ;\
  60. std r0, SL_##special(r11)
  61. #define RESTORE_SPECIAL(special) \
  62. ld r0, SL_##special(r11) ;\
  63. mt##special r0
  64. #define SAVE_REGISTER(reg) \
  65. std reg, SL_##reg(r11)
  66. #define RESTORE_REGISTER(reg) \
  67. ld reg, SL_##reg(r11)
  68. /* space for storing cpu state */
  69. .section .data
  70. .align 5
  71. swsusp_save_area:
  72. .space SL_SIZE
  73. .section ".toc","aw"
  74. swsusp_save_area_ptr:
  75. .tc swsusp_save_area[TC],swsusp_save_area
  76. restore_pblist_ptr:
  77. .tc restore_pblist[TC],restore_pblist
  78. .section .text
  79. .align 5
  80. _GLOBAL(swsusp_arch_suspend)
  81. ld r11,swsusp_save_area_ptr@toc(r2)
  82. SAVE_SPECIAL(LR)
  83. SAVE_REGISTER(r1)
  84. SAVE_SPECIAL(CR)
  85. SAVE_SPECIAL(TB)
  86. SAVE_REGISTER(r2)
  87. SAVE_REGISTER(r12)
  88. SAVE_REGISTER(r13)
  89. SAVE_REGISTER(r14)
  90. SAVE_REGISTER(r15)
  91. SAVE_REGISTER(r16)
  92. SAVE_REGISTER(r17)
  93. SAVE_REGISTER(r18)
  94. SAVE_REGISTER(r19)
  95. SAVE_REGISTER(r20)
  96. SAVE_REGISTER(r21)
  97. SAVE_REGISTER(r22)
  98. SAVE_REGISTER(r23)
  99. SAVE_REGISTER(r24)
  100. SAVE_REGISTER(r25)
  101. SAVE_REGISTER(r26)
  102. SAVE_REGISTER(r27)
  103. SAVE_REGISTER(r28)
  104. SAVE_REGISTER(r29)
  105. SAVE_REGISTER(r30)
  106. SAVE_REGISTER(r31)
  107. SAVE_SPECIAL(MSR)
  108. SAVE_SPECIAL(XER)
  109. #ifdef CONFIG_PPC_BOOK3S_64
  110. BEGIN_FW_FTR_SECTION
  111. SAVE_SPECIAL(SDR1)
  112. END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
  113. #else
  114. SAVE_SPR(TCR)
  115. /* Save SPRG1, SPRG1 be used save paca */
  116. SAVE_SPR(SPRG1)
  117. #endif
  118. /* we push the stack up 128 bytes but don't store the
  119. * stack pointer on the stack like a real stackframe */
  120. addi r1,r1,-128
  121. bl _iommu_save
  122. bl swsusp_save
  123. /* restore LR */
  124. ld r11,swsusp_save_area_ptr@toc(r2)
  125. RESTORE_SPECIAL(LR)
  126. addi r1,r1,128
  127. blr
  128. /* Resume code */
  129. _GLOBAL(swsusp_arch_resume)
  130. /* Stop pending alitvec streams and memory accesses */
  131. BEGIN_FTR_SECTION
  132. DSSALL
  133. END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  134. sync
  135. ld r12,restore_pblist_ptr@toc(r2)
  136. ld r12,0(r12)
  137. cmpdi r12,0
  138. beq- nothing_to_copy
  139. li r15,PAGE_SIZE>>3
  140. copyloop:
  141. ld r13,pbe_address(r12)
  142. ld r14,pbe_orig_address(r12)
  143. mtctr r15
  144. li r10,0
  145. copy_page_loop:
  146. ldx r0,r10,r13
  147. stdx r0,r10,r14
  148. addi r10,r10,8
  149. bdnz copy_page_loop
  150. ld r12,pbe_next(r12)
  151. cmpdi r12,0
  152. bne+ copyloop
  153. nothing_to_copy:
  154. #ifdef CONFIG_PPC_BOOK3S_64
  155. /* flush caches */
  156. lis r3, 0x10
  157. mtctr r3
  158. li r3, 0
  159. ori r3, r3, CONFIG_KERNEL_START>>48
  160. li r0, 48
  161. sld r3, r3, r0
  162. li r0, 0
  163. 1:
  164. dcbf 0,r3
  165. addi r3,r3,0x20
  166. bdnz 1b
  167. sync
  168. tlbia
  169. #endif
  170. ld r11,swsusp_save_area_ptr@toc(r2)
  171. RESTORE_SPECIAL(CR)
  172. /* restore timebase */
  173. /* load saved tb */
  174. ld r1, SL_TB(r11)
  175. /* get upper 32 bits of it */
  176. srdi r2, r1, 32
  177. /* clear tb lower to avoid wrap */
  178. li r0, 0
  179. mttbl r0
  180. /* set tb upper */
  181. mttbu r2
  182. /* set tb lower */
  183. mttbl r1
  184. /* restore registers */
  185. RESTORE_REGISTER(r1)
  186. RESTORE_REGISTER(r2)
  187. RESTORE_REGISTER(r12)
  188. RESTORE_REGISTER(r13)
  189. RESTORE_REGISTER(r14)
  190. RESTORE_REGISTER(r15)
  191. RESTORE_REGISTER(r16)
  192. RESTORE_REGISTER(r17)
  193. RESTORE_REGISTER(r18)
  194. RESTORE_REGISTER(r19)
  195. RESTORE_REGISTER(r20)
  196. RESTORE_REGISTER(r21)
  197. RESTORE_REGISTER(r22)
  198. RESTORE_REGISTER(r23)
  199. RESTORE_REGISTER(r24)
  200. RESTORE_REGISTER(r25)
  201. RESTORE_REGISTER(r26)
  202. RESTORE_REGISTER(r27)
  203. RESTORE_REGISTER(r28)
  204. RESTORE_REGISTER(r29)
  205. RESTORE_REGISTER(r30)
  206. RESTORE_REGISTER(r31)
  207. #ifdef CONFIG_PPC_BOOK3S_64
  208. /* can't use RESTORE_SPECIAL(MSR) */
  209. ld r0, SL_MSR(r11)
  210. mtmsrd r0, 0
  211. BEGIN_FW_FTR_SECTION
  212. RESTORE_SPECIAL(SDR1)
  213. END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
  214. #else
  215. /* Restore SPRG1, be used to save paca */
  216. ld r0, SL_SPRG1(r11)
  217. mtsprg 1, r0
  218. RESTORE_SPECIAL(MSR)
  219. /* Restore TCR and clear any pending bits in TSR. */
  220. RESTORE_SPR(TCR)
  221. lis r0, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
  222. mtspr SPRN_TSR, r0
  223. /* Kick decrementer */
  224. li r0, 1
  225. mtdec r0
  226. /* Invalidate all tlbs */
  227. bl _tlbil_all
  228. #endif
  229. RESTORE_SPECIAL(XER)
  230. sync
  231. addi r1,r1,-128
  232. #ifdef CONFIG_PPC_BOOK3S_64
  233. bl slb_flush_and_restore_bolted
  234. #endif
  235. bl do_after_copyback
  236. addi r1,r1,128
  237. ld r11,swsusp_save_area_ptr@toc(r2)
  238. RESTORE_SPECIAL(LR)
  239. li r3, 0
  240. blr