aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/swsusp_asm64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/swsusp_asm64.S')
-rw-r--r--arch/s390/kernel/swsusp_asm64.S102
1 files changed, 91 insertions, 11 deletions
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index 7cd6b096f0d1..fe927d0bc20b 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -9,6 +9,7 @@
9 9
10#include <asm/page.h> 10#include <asm/page.h>
11#include <asm/ptrace.h> 11#include <asm/ptrace.h>
12#include <asm/thread_info.h>
12#include <asm/asm-offsets.h> 13#include <asm/asm-offsets.h>
13 14
14/* 15/*
@@ -41,6 +42,9 @@ swsusp_arch_suspend:
41 /* Get pointer to save area */ 42 /* Get pointer to save area */
42 lghi %r1,0x1000 43 lghi %r1,0x1000
43 44
45 /* Save CPU address */
46 stap __LC_CPU_ADDRESS(%r1)
47
44 /* Store registers */ 48 /* Store registers */
45 mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ 49 mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */
46 stfpc 0x31c(%r1) /* store fpu control */ 50 stfpc 0x31c(%r1) /* store fpu control */
@@ -102,11 +106,10 @@ swsusp_arch_resume:
102 aghi %r15,-STACK_FRAME_OVERHEAD 106 aghi %r15,-STACK_FRAME_OVERHEAD
103 stg %r1,__SF_BACKCHAIN(%r15) 107 stg %r1,__SF_BACKCHAIN(%r15)
104 108
105#ifdef CONFIG_SMP 109 /* Make all free pages stable */
106 /* Save boot cpu number */ 110 lghi %r2,1
107 brasl %r14,smp_get_phys_cpu_id 111 brasl %r14,arch_set_page_states
108 lgr %r10,%r2 112
109#endif
110 /* Deactivate DAT */ 113 /* Deactivate DAT */
111 stnsm __SF_EMPTY(%r15),0xfb 114 stnsm __SF_EMPTY(%r15),0xfb
112 115
@@ -133,6 +136,69 @@ swsusp_arch_resume:
1332: 1362:
134 ptlb /* flush tlb */ 137 ptlb /* flush tlb */
135 138
139 /* Reset System */
140 larl %r1,restart_entry
141 larl %r2,.Lrestart_diag308_psw
142 og %r1,0(%r2)
143 stg %r1,0(%r0)
144 larl %r1,.Lnew_pgm_check_psw
145 epsw %r2,%r3
146 stm %r2,%r3,0(%r1)
147 mvc __LC_PGM_NEW_PSW(16,%r0),0(%r1)
148 lghi %r0,0
149 diag %r0,%r0,0x308
150restart_entry:
151 lhi %r1,1
152 sigp %r1,%r0,0x12
153 sam64
154 larl %r1,.Lnew_pgm_check_psw
155 lpswe 0(%r1)
156pgm_check_entry:
157
158 /* Switch to original suspend CPU */
159 larl %r1,.Lresume_cpu /* Resume CPU address: r2 */
160 stap 0(%r1)
161 llgh %r2,0(%r1)
162 lghi %r3,0x1000
163 llgh %r1,__LC_CPU_ADDRESS(%r3) /* Suspend CPU address: r1 */
164 cgr %r1,%r2
165 je restore_registers /* r1 = r2 -> nothing to do */
166 larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */
167 mvc __LC_RESTART_PSW(16,%r0),0(%r4)
1683:
169 sigp %r9,%r1,__SIGP_INITIAL_CPU_RESET
170 brc 8,4f /* accepted */
171 brc 2,3b /* busy, try again */
172
173 /* Suspend CPU not available -> panic */
174 larl %r15,init_thread_union
175 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER)
176 larl %r2,.Lpanic_string
177 larl %r3,_sclp_print_early
178 lghi %r1,0
179 sam31
180 sigp %r1,%r0,0x12
181 basr %r14,%r3
182 larl %r3,.Ldisabled_wait_31
183 lpsw 0(%r3)
1844:
185 /* Switch to suspend CPU */
186 sigp %r9,%r1,__SIGP_RESTART /* start suspend CPU */
187 brc 2,4b /* busy, try again */
1885:
189 sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */
1906: j 6b
191
192restart_suspend:
193 larl %r1,.Lresume_cpu
194 llgh %r2,0(%r1)
1957:
196 sigp %r9,%r2,__SIGP_SENSE /* Wait for resume CPU */
197 brc 2,7b /* busy, try again */
198 tmll %r9,0x40 /* Test if resume CPU is stopped */
199 jz 7b
200
201restore_registers:
136 /* Restore registers */ 202 /* Restore registers */
137 lghi %r13,0x1000 /* %r1 = pointer to save arae */ 203 lghi %r13,0x1000 /* %r1 = pointer to save arae */
138 204
@@ -166,19 +232,33 @@ swsusp_arch_resume:
166 /* Pointer to save area */ 232 /* Pointer to save area */
167 lghi %r13,0x1000 233 lghi %r13,0x1000
168 234
169#ifdef CONFIG_SMP
170 /* Switch CPUs */
171 lgr %r2,%r10 /* get cpu id */
172 llgf %r3,0x318(%r13)
173 brasl %r14,smp_switch_boot_cpu_in_resume
174#endif
175 /* Restore prefix register */ 235 /* Restore prefix register */
176 spx 0x318(%r13) 236 spx 0x318(%r13)
177 237
178 /* Activate DAT */ 238 /* Activate DAT */
179 stosm __SF_EMPTY(%r15),0x04 239 stosm __SF_EMPTY(%r15),0x04
180 240
241 /* Make all free pages unstable */
242 lghi %r2,0
243 brasl %r14,arch_set_page_states
244
181 /* Return 0 */ 245 /* Return 0 */
182 lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) 246 lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
183 lghi %r2,0 247 lghi %r2,0
184 br %r14 248 br %r14
249
250 .section .data.nosave,"aw",@progbits
251 .align 8
252.Ldisabled_wait_31:
253 .long 0x000a0000,0x00000000
254.Lpanic_string:
255 .asciz "Resume not possible because suspend CPU is no longer available"
256 .align 8
257.Lrestart_diag308_psw:
258 .long 0x00080000,0x80000000
259.Lrestart_suspend_psw:
260 .quad 0x0000000180000000,restart_suspend
261.Lnew_pgm_check_psw:
262 .quad 0,pgm_check_entry
263.Lresume_cpu:
264 .byte 0,0