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.S91
1 files changed, 63 insertions, 28 deletions
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index fc056810a017..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 */
@@ -105,12 +109,7 @@ swsusp_arch_resume:
105 /* Make all free pages stable */ 109 /* Make all free pages stable */
106 lghi %r2,1 110 lghi %r2,1
107 brasl %r14,arch_set_page_states 111 brasl %r14,arch_set_page_states
108#ifdef CONFIG_SMP 112
109 /* Save boot cpu number */
110 brasl %r14,smp_get_phys_cpu_id
111 larl %r1,saved_cpu_id
112 st %r2,0(%r1)
113#endif
114 /* Deactivate DAT */ 113 /* Deactivate DAT */
115 stnsm __SF_EMPTY(%r15),0xfb 114 stnsm __SF_EMPTY(%r15),0xfb
116 115
@@ -139,12 +138,10 @@ swsusp_arch_resume:
139 138
140 /* Reset System */ 139 /* Reset System */
141 larl %r1,restart_entry 140 larl %r1,restart_entry
142 larl %r2,restart_psw 141 larl %r2,.Lrestart_diag308_psw
143 og %r1,0(%r2) 142 og %r1,0(%r2)
144 stg %r1,0(%r0) 143 stg %r1,0(%r0)
145 larl %r1,saved_pgm_check_psw 144 larl %r1,.Lnew_pgm_check_psw
146 mvc 0(16,%r1),__LC_PGM_NEW_PSW(%r0)
147 larl %r1,new_pgm_check_psw
148 epsw %r2,%r3 145 epsw %r2,%r3
149 stm %r2,%r3,0(%r1) 146 stm %r2,%r3,0(%r1)
150 mvc __LC_PGM_NEW_PSW(16,%r0),0(%r1) 147 mvc __LC_PGM_NEW_PSW(16,%r0),0(%r1)
@@ -154,12 +151,54 @@ restart_entry:
154 lhi %r1,1 151 lhi %r1,1
155 sigp %r1,%r0,0x12 152 sigp %r1,%r0,0x12
156 sam64 153 sam64
157 larl %r1,new_pgm_check_psw 154 larl %r1,.Lnew_pgm_check_psw
158 lpswe 0(%r1) 155 lpswe 0(%r1)
159pgm_check_entry: 156pgm_check_entry:
160 larl %r1,saved_pgm_check_psw
161 mvc __LC_PGM_NEW_PSW(16,%r0),0(%r1)
162 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:
163 /* Restore registers */ 202 /* Restore registers */
164 lghi %r13,0x1000 /* %r1 = pointer to save arae */ 203 lghi %r13,0x1000 /* %r1 = pointer to save arae */
165 204
@@ -193,13 +232,6 @@ pgm_check_entry:
193 /* Pointer to save area */ 232 /* Pointer to save area */
194 lghi %r13,0x1000 233 lghi %r13,0x1000
195 234
196#ifdef CONFIG_SMP
197 /* Switch CPUs */
198 larl %r1,saved_cpu_id
199 llgf %r2,0(%r1)
200 llgf %r3,0x318(%r13)
201 brasl %r14,smp_switch_boot_cpu_in_resume
202#endif
203 /* Restore prefix register */ 235 /* Restore prefix register */
204 spx 0x318(%r13) 236 spx 0x318(%r13)
205 237
@@ -217,13 +249,16 @@ pgm_check_entry:
217 249
218 .section .data.nosave,"aw",@progbits 250 .section .data.nosave,"aw",@progbits
219 .align 8 251 .align 8
220restart_psw: 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:
221 .long 0x00080000,0x80000000 258 .long 0x00080000,0x80000000
222new_pgm_check_psw: 259.Lrestart_suspend_psw:
260 .quad 0x0000000180000000,restart_suspend
261.Lnew_pgm_check_psw:
223 .quad 0,pgm_check_entry 262 .quad 0,pgm_check_entry
224saved_pgm_check_psw: 263.Lresume_cpu:
225 .quad 0,0 264 .byte 0,0
226#ifdef CONFIG_SMP
227saved_cpu_id:
228 .long 0
229#endif