diff options
Diffstat (limited to 'include/asm-s390/processor.h')
-rw-r--r-- | include/asm-s390/processor.h | 57 |
1 files changed, 24 insertions, 33 deletions
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index fb46e9090b50..4ec652ebb3b1 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h | |||
@@ -203,10 +203,25 @@ unsigned long get_wchan(struct task_struct *p); | |||
203 | # define cpu_relax() asm volatile ("diag 0,0,68" : : : "memory") | 203 | # define cpu_relax() asm volatile ("diag 0,0,68" : : : "memory") |
204 | #else /* __s390x__ */ | 204 | #else /* __s390x__ */ |
205 | # define cpu_relax() \ | 205 | # define cpu_relax() \ |
206 | asm volatile ("ex 0,%0" : : "i" (__LC_DIAG44_OPCODE) : "memory") | 206 | do { \ |
207 | if (MACHINE_HAS_DIAG44) \ | ||
208 | asm volatile ("diag 0,0,68" : : : "memory"); \ | ||
209 | } while (0) | ||
207 | #endif /* __s390x__ */ | 210 | #endif /* __s390x__ */ |
208 | 211 | ||
209 | /* | 212 | /* |
213 | * Set PSW to specified value. | ||
214 | */ | ||
215 | static inline void __load_psw(psw_t psw) | ||
216 | { | ||
217 | #ifndef __s390x__ | ||
218 | asm volatile ("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
219 | #else | ||
220 | asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
221 | #endif | ||
222 | } | ||
223 | |||
224 | /* | ||
210 | * Set PSW mask to specified value, while leaving the | 225 | * Set PSW mask to specified value, while leaving the |
211 | * PSW addr pointing to the next instruction. | 226 | * PSW addr pointing to the next instruction. |
212 | */ | 227 | */ |
@@ -214,8 +229,8 @@ unsigned long get_wchan(struct task_struct *p); | |||
214 | static inline void __load_psw_mask (unsigned long mask) | 229 | static inline void __load_psw_mask (unsigned long mask) |
215 | { | 230 | { |
216 | unsigned long addr; | 231 | unsigned long addr; |
217 | |||
218 | psw_t psw; | 232 | psw_t psw; |
233 | |||
219 | psw.mask = mask; | 234 | psw.mask = mask; |
220 | 235 | ||
221 | #ifndef __s390x__ | 236 | #ifndef __s390x__ |
@@ -241,30 +256,8 @@ static inline void __load_psw_mask (unsigned long mask) | |||
241 | */ | 256 | */ |
242 | static inline void enabled_wait(void) | 257 | static inline void enabled_wait(void) |
243 | { | 258 | { |
244 | unsigned long reg; | 259 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | |
245 | psw_t wait_psw; | 260 | PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY); |
246 | |||
247 | wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | | ||
248 | PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY; | ||
249 | #ifndef __s390x__ | ||
250 | asm volatile ( | ||
251 | " basr %0,0\n" | ||
252 | "0: la %0,1f-0b(%0)\n" | ||
253 | " st %0,4(%1)\n" | ||
254 | " oi 4(%1),0x80\n" | ||
255 | " lpsw 0(%1)\n" | ||
256 | "1:" | ||
257 | : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw) | ||
258 | : "memory", "cc" ); | ||
259 | #else /* __s390x__ */ | ||
260 | asm volatile ( | ||
261 | " larl %0,0f\n" | ||
262 | " stg %0,8(%1)\n" | ||
263 | " lpswe 0(%1)\n" | ||
264 | "0:" | ||
265 | : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw) | ||
266 | : "memory", "cc" ); | ||
267 | #endif /* __s390x__ */ | ||
268 | } | 261 | } |
269 | 262 | ||
270 | /* | 263 | /* |
@@ -273,13 +266,11 @@ static inline void enabled_wait(void) | |||
273 | 266 | ||
274 | static inline void disabled_wait(unsigned long code) | 267 | static inline void disabled_wait(unsigned long code) |
275 | { | 268 | { |
276 | char psw_buffer[2*sizeof(psw_t)]; | ||
277 | unsigned long ctl_buf; | 269 | unsigned long ctl_buf; |
278 | psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1) | 270 | psw_t dw_psw; |
279 | & -sizeof(psw_t)); | ||
280 | 271 | ||
281 | dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT; | 272 | dw_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; |
282 | dw_psw->addr = code; | 273 | dw_psw.addr = code; |
283 | /* | 274 | /* |
284 | * Store status and then load disabled wait psw, | 275 | * Store status and then load disabled wait psw, |
285 | * the processor is dead afterwards | 276 | * the processor is dead afterwards |
@@ -301,7 +292,7 @@ static inline void disabled_wait(unsigned long code) | |||
301 | " oi 0x1c0,0x10\n" /* fake protection bit */ | 292 | " oi 0x1c0,0x10\n" /* fake protection bit */ |
302 | " lpsw 0(%1)" | 293 | " lpsw 0(%1)" |
303 | : "=m" (ctl_buf) | 294 | : "=m" (ctl_buf) |
304 | : "a" (dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); | 295 | : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); |
305 | #else /* __s390x__ */ | 296 | #else /* __s390x__ */ |
306 | asm volatile (" stctg 0,0,0(%2)\n" | 297 | asm volatile (" stctg 0,0,0(%2)\n" |
307 | " ni 4(%2),0xef\n" /* switch off protection */ | 298 | " ni 4(%2),0xef\n" /* switch off protection */ |
@@ -333,7 +324,7 @@ static inline void disabled_wait(unsigned long code) | |||
333 | " oi 0x384(1),0x10\n" /* fake protection bit */ | 324 | " oi 0x384(1),0x10\n" /* fake protection bit */ |
334 | " lpswe 0(%1)" | 325 | " lpswe 0(%1)" |
335 | : "=m" (ctl_buf) | 326 | : "=m" (ctl_buf) |
336 | : "a" (dw_psw), "a" (&ctl_buf), | 327 | : "a" (&dw_psw), "a" (&ctl_buf), |
337 | "m" (dw_psw) : "cc", "0", "1"); | 328 | "m" (dw_psw) : "cc", "0", "1"); |
338 | #endif /* __s390x__ */ | 329 | #endif /* __s390x__ */ |
339 | } | 330 | } |