diff options
Diffstat (limited to 'arch/s390/kernel/swsusp_asm64.S')
-rw-r--r-- | arch/s390/kernel/swsusp_asm64.S | 91 |
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) |
159 | pgm_check_entry: | 156 | pgm_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) | ||
168 | 3: | ||
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) | ||
184 | 4: | ||
185 | /* Switch to suspend CPU */ | ||
186 | sigp %r9,%r1,__SIGP_RESTART /* start suspend CPU */ | ||
187 | brc 2,4b /* busy, try again */ | ||
188 | 5: | ||
189 | sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */ | ||
190 | 6: j 6b | ||
191 | |||
192 | restart_suspend: | ||
193 | larl %r1,.Lresume_cpu | ||
194 | llgh %r2,0(%r1) | ||
195 | 7: | ||
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 | |||
201 | restore_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 |
220 | restart_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 |
222 | new_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 |
224 | saved_pgm_check_psw: | 263 | .Lresume_cpu: |
225 | .quad 0,0 | 264 | .byte 0,0 |
226 | #ifdef CONFIG_SMP | ||
227 | saved_cpu_id: | ||
228 | .long 0 | ||
229 | #endif | ||