aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2011-01-05 06:47:57 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-01-05 06:47:29 -0500
commit1de3447a41ea72972966b4896a9f8d2b064bd23f (patch)
tree83683c7202f17797a09697956243a2b4745aab86 /arch/s390/kernel/entry.S
parentce322ccd53f2505cf8b0ed204631d6ac054ac66a (diff)
[S390] 31 bit entry.S update.
Make the code in the 31 bit entry.S code as similar as possible to the 64 bit version in entry64.S. That makes it easier to add new code to the first level interrupt handler that affects both 31 and 64 bit kernels. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S212
1 files changed, 109 insertions, 103 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 68d1a02db6be..af8bd3b90a26 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -9,7 +9,6 @@
9 * Heiko Carstens <heiko.carstens@de.ibm.com> 9 * Heiko Carstens <heiko.carstens@de.ibm.com>
10 */ 10 */
11 11
12#include <linux/sys.h>
13#include <linux/linkage.h> 12#include <linux/linkage.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <asm/cache.h> 14#include <asm/cache.h>
@@ -110,31 +109,36 @@ STACK_SIZE = 1 << STACK_SHIFT
1101: stm %r10,%r11,\lc_sum 1091: stm %r10,%r11,\lc_sum
111 .endm 110 .endm
112 111
113 .macro SAVE_ALL_BASE savearea 112 .macro SAVE_ALL_SVC psworg,savearea
114 stm %r12,%r15,\savearea 113 stm %r12,%r15,\savearea
115 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 114 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
115 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
116 s %r15,BASED(.Lc_spsize) # make room for registers & psw
116 .endm 117 .endm
117 118
118 .macro SAVE_ALL_SVC psworg,savearea 119 .macro SAVE_ALL_BASE savearea
119 la %r12,\psworg 120 stm %r12,%r15,\savearea
120 l %r15,__LC_KERNEL_STACK # problem state -> load ksp 121 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
121 .endm 122 .endm
122 123
123 .macro SAVE_ALL_SYNC psworg,savearea 124 .macro SAVE_ALL_PGM psworg,savearea
124 la %r12,\psworg
125 tm \psworg+1,0x01 # test problem state bit 125 tm \psworg+1,0x01 # test problem state bit
126 bz BASED(2f) # skip stack setup save
127 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
128#ifdef CONFIG_CHECK_STACK 126#ifdef CONFIG_CHECK_STACK
129 b BASED(3f) 127 bnz BASED(1f)
1302: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 128 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
131 bz BASED(stack_overflow) 129 bnz BASED(2f)
1323: 130 la %r12,\psworg
131 b BASED(stack_overflow)
132#else
133 bz BASED(2f)
133#endif 134#endif
1342: 1351: l %r15,__LC_KERNEL_STACK # problem state -> load ksp
1362: s %r15,BASED(.Lc_spsize) # make room for registers & psw
135 .endm 137 .endm
136 138
137 .macro SAVE_ALL_ASYNC psworg,savearea 139 .macro SAVE_ALL_ASYNC psworg,savearea
140 stm %r12,%r15,\savearea
141 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
138 la %r12,\psworg 142 la %r12,\psworg
139 tm \psworg+1,0x01 # test problem state bit 143 tm \psworg+1,0x01 # test problem state bit
140 bnz BASED(1f) # from user -> load async stack 144 bnz BASED(1f) # from user -> load async stack
@@ -149,27 +153,23 @@ STACK_SIZE = 1 << STACK_SHIFT
1490: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? 1530: l %r14,__LC_ASYNC_STACK # are we already on the async stack ?
150 slr %r14,%r15 154 slr %r14,%r15
151 sra %r14,STACK_SHIFT 155 sra %r14,STACK_SHIFT
152 be BASED(2f)
1531: l %r15,__LC_ASYNC_STACK
154#ifdef CONFIG_CHECK_STACK 156#ifdef CONFIG_CHECK_STACK
155 b BASED(3f) 157 bnz BASED(1f)
1562: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 158 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
157 bz BASED(stack_overflow) 159 bnz BASED(2f)
1583: 160 b BASED(stack_overflow)
161#else
162 bz BASED(2f)
159#endif 163#endif
1602: 1641: l %r15,__LC_ASYNC_STACK
1652: s %r15,BASED(.Lc_spsize) # make room for registers & psw
161 .endm 166 .endm
162 167
163 .macro CREATE_STACK_FRAME psworg,savearea 168 .macro CREATE_STACK_FRAME savearea
164 s %r15,BASED(.Lc_spsize) # make room for registers & psw 169 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
165 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
166 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 170 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
167 icm %r12,12,__LC_SVC_ILC
168 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
169 st %r12,SP_ILC(%r15)
170 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack 171 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
171 la %r12,0 172 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
172 st %r12,__SF_BACKCHAIN(%r15) # clear back chain
173 .endm 173 .endm
174 174
175 .macro RESTORE_ALL psworg,sync 175 .macro RESTORE_ALL psworg,sync
@@ -237,10 +237,11 @@ __critical_start:
237system_call: 237system_call:
238 stpt __LC_SYNC_ENTER_TIMER 238 stpt __LC_SYNC_ENTER_TIMER
239sysc_saveall: 239sysc_saveall:
240 SAVE_ALL_BASE __LC_SAVE_AREA
241 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 240 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
242 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 241 CREATE_STACK_FRAME __LC_SAVE_AREA
243 lh %r7,0x8a # get svc number from lowcore 242 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
243 mvc SP_ILC(4,%r15),__LC_SVC_ILC
244 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
244sysc_vtime: 245sysc_vtime:
245 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 246 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
246sysc_stime: 247sysc_stime:
@@ -248,20 +249,20 @@ sysc_stime:
248sysc_update: 249sysc_update:
249 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 250 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
250sysc_do_svc: 251sysc_do_svc:
251 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 252 xr %r7,%r7
252 ltr %r7,%r7 # test for svc 0 253 icm %r7,3,SP_SVCNR(%r15) # load svc number and test for svc 0
253 bnz BASED(sysc_nr_ok) # svc number > 0 254 bnz BASED(sysc_nr_ok) # svc number > 0
254 # svc 0: system call number in %r1 255 # svc 0: system call number in %r1
255 cl %r1,BASED(.Lnr_syscalls) 256 cl %r1,BASED(.Lnr_syscalls)
256 bnl BASED(sysc_nr_ok) 257 bnl BASED(sysc_nr_ok)
258 sth %r1,SP_SVCNR(%r15)
257 lr %r7,%r1 # copy svc number to %r7 259 lr %r7,%r1 # copy svc number to %r7
258sysc_nr_ok: 260sysc_nr_ok:
259 sth %r7,SP_SVCNR(%r15)
260 sll %r7,2 # svc number *4 261 sll %r7,2 # svc number *4
261 l %r8,BASED(.Lsysc_table) 262 l %r10,BASED(.Lsysc_table)
262 tm __TI_flags+2(%r9),_TIF_SYSCALL 263 tm __TI_flags+2(%r12),_TIF_SYSCALL
263 mvc SP_ARGS(4,%r15),SP_R7(%r15) 264 mvc SP_ARGS(4,%r15),SP_R7(%r15)
264 l %r8,0(%r7,%r8) # get system call addr. 265 l %r8,0(%r7,%r10) # get system call addr.
265 bnz BASED(sysc_tracesys) 266 bnz BASED(sysc_tracesys)
266 basr %r14,%r8 # call sys_xxxx 267 basr %r14,%r8 # call sys_xxxx
267 st %r2,SP_R2(%r15) # store return value (change R2 on stack) 268 st %r2,SP_R2(%r15) # store return value (change R2 on stack)
@@ -269,7 +270,7 @@ sysc_nr_ok:
269sysc_return: 270sysc_return:
270 LOCKDEP_SYS_EXIT 271 LOCKDEP_SYS_EXIT
271sysc_tif: 272sysc_tif:
272 tm __TI_flags+3(%r9),_TIF_WORK_SVC 273 tm __TI_flags+3(%r12),_TIF_WORK_SVC
273 bnz BASED(sysc_work) # there is work to do (signals etc.) 274 bnz BASED(sysc_work) # there is work to do (signals etc.)
274sysc_restore: 275sysc_restore:
275 RESTORE_ALL __LC_RETURN_PSW,1 276 RESTORE_ALL __LC_RETURN_PSW,1
@@ -286,17 +287,17 @@ sysc_work:
286# One of the work bits is on. Find out which one. 287# One of the work bits is on. Find out which one.
287# 288#
288sysc_work_tif: 289sysc_work_tif:
289 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING 290 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
290 bo BASED(sysc_mcck_pending) 291 bo BASED(sysc_mcck_pending)
291 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 292 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
292 bo BASED(sysc_reschedule) 293 bo BASED(sysc_reschedule)
293 tm __TI_flags+3(%r9),_TIF_SIGPENDING 294 tm __TI_flags+3(%r12),_TIF_SIGPENDING
294 bo BASED(sysc_sigpending) 295 bo BASED(sysc_sigpending)
295 tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME 296 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
296 bo BASED(sysc_notify_resume) 297 bo BASED(sysc_notify_resume)
297 tm __TI_flags+3(%r9),_TIF_RESTART_SVC 298 tm __TI_flags+3(%r12),_TIF_RESTART_SVC
298 bo BASED(sysc_restart) 299 bo BASED(sysc_restart)
299 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP 300 tm __TI_flags+3(%r12),_TIF_SINGLE_STEP
300 bo BASED(sysc_singlestep) 301 bo BASED(sysc_singlestep)
301 b BASED(sysc_return) # beware of critical section cleanup 302 b BASED(sysc_return) # beware of critical section cleanup
302 303
@@ -320,13 +321,13 @@ sysc_mcck_pending:
320# _TIF_SIGPENDING is set, call do_signal 321# _TIF_SIGPENDING is set, call do_signal
321# 322#
322sysc_sigpending: 323sysc_sigpending:
323 ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP 324 ni __TI_flags+3(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
324 la %r2,SP_PTREGS(%r15) # load pt_regs 325 la %r2,SP_PTREGS(%r15) # load pt_regs
325 l %r1,BASED(.Ldo_signal) 326 l %r1,BASED(.Ldo_signal)
326 basr %r14,%r1 # call do_signal 327 basr %r14,%r1 # call do_signal
327 tm __TI_flags+3(%r9),_TIF_RESTART_SVC 328 tm __TI_flags+3(%r12),_TIF_RESTART_SVC
328 bo BASED(sysc_restart) 329 bo BASED(sysc_restart)
329 tm __TI_flags+3(%r9),_TIF_SINGLE_STEP 330 tm __TI_flags+3(%r12),_TIF_SINGLE_STEP
330 bo BASED(sysc_singlestep) 331 bo BASED(sysc_singlestep)
331 b BASED(sysc_return) 332 b BASED(sysc_return)
332 333
@@ -344,19 +345,19 @@ sysc_notify_resume:
344# _TIF_RESTART_SVC is set, set up registers and restart svc 345# _TIF_RESTART_SVC is set, set up registers and restart svc
345# 346#
346sysc_restart: 347sysc_restart:
347 ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC 348 ni __TI_flags+3(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
348 l %r7,SP_R2(%r15) # load new svc number 349 l %r7,SP_R2(%r15) # load new svc number
349 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument 350 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
350 lm %r2,%r6,SP_R2(%r15) # load svc arguments 351 lm %r2,%r6,SP_R2(%r15) # load svc arguments
352 sth %r7,SP_SVCNR(%r15)
351 b BASED(sysc_nr_ok) # restart svc 353 b BASED(sysc_nr_ok) # restart svc
352 354
353# 355#
354# _TIF_SINGLE_STEP is set, call do_single_step 356# _TIF_SINGLE_STEP is set, call do_single_step
355# 357#
356sysc_singlestep: 358sysc_singlestep:
357 ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP 359 ni __TI_flags+3(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
358 mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check 360 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
359 mvi SP_SVCNR+1(%r15),0xff
360 la %r2,SP_PTREGS(%r15) # address of register-save area 361 la %r2,SP_PTREGS(%r15) # address of register-save area
361 l %r1,BASED(.Lhandle_per) # load adr. of per handler 362 l %r1,BASED(.Lhandle_per) # load adr. of per handler
362 la %r14,BASED(sysc_return) # load adr. of system return 363 la %r14,BASED(sysc_return) # load adr. of system return
@@ -370,15 +371,15 @@ sysc_tracesys:
370 l %r1,BASED(.Ltrace_entry) 371 l %r1,BASED(.Ltrace_entry)
371 la %r2,SP_PTREGS(%r15) # load pt_regs 372 la %r2,SP_PTREGS(%r15) # load pt_regs
372 la %r3,0 373 la %r3,0
373 srl %r7,2 374 xr %r0,%r0
374 st %r7,SP_R2(%r15) 375 icm %r0,3,SP_SVCNR(%r15)
376 st %r0,SP_R2(%r15)
375 basr %r14,%r1 377 basr %r14,%r1
376 cl %r2,BASED(.Lnr_syscalls) 378 cl %r2,BASED(.Lnr_syscalls)
377 bnl BASED(sysc_tracenogo) 379 bnl BASED(sysc_tracenogo)
378 l %r8,BASED(.Lsysc_table)
379 lr %r7,%r2 380 lr %r7,%r2
380 sll %r7,2 # svc number *4 381 sll %r7,2 # svc number *4
381 l %r8,0(%r7,%r8) 382 l %r8,0(%r7,%r10)
382sysc_tracego: 383sysc_tracego:
383 lm %r3,%r6,SP_R3(%r15) 384 lm %r3,%r6,SP_R3(%r15)
384 mvc SP_ARGS(4,%r15),SP_R7(%r15) 385 mvc SP_ARGS(4,%r15),SP_R7(%r15)
@@ -386,7 +387,7 @@ sysc_tracego:
386 basr %r14,%r8 # call sys_xxx 387 basr %r14,%r8 # call sys_xxx
387 st %r2,SP_R2(%r15) # store return value 388 st %r2,SP_R2(%r15) # store return value
388sysc_tracenogo: 389sysc_tracenogo:
389 tm __TI_flags+2(%r9),_TIF_SYSCALL 390 tm __TI_flags+2(%r12),_TIF_SYSCALL
390 bz BASED(sysc_return) 391 bz BASED(sysc_return)
391 l %r1,BASED(.Ltrace_exit) 392 l %r1,BASED(.Ltrace_exit)
392 la %r2,SP_PTREGS(%r15) # load pt_regs 393 la %r2,SP_PTREGS(%r15) # load pt_regs
@@ -399,7 +400,7 @@ sysc_tracenogo:
399 .globl ret_from_fork 400 .globl ret_from_fork
400ret_from_fork: 401ret_from_fork:
401 l %r13,__LC_SVC_NEW_PSW+4 402 l %r13,__LC_SVC_NEW_PSW+4
402 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 403 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
403 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 404 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ?
404 bo BASED(0f) 405 bo BASED(0f)
405 st %r15,SP_R15(%r15) # store stack pointer for new kthread 406 st %r15,SP_R15(%r15) # store stack pointer for new kthread
@@ -434,8 +435,8 @@ kernel_execve:
4340: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 4350: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
435 l %r15,__LC_KERNEL_STACK # load ksp 436 l %r15,__LC_KERNEL_STACK # load ksp
436 s %r15,BASED(.Lc_spsize) # make room for registers & psw 437 s %r15,BASED(.Lc_spsize) # make room for registers & psw
437 l %r9,__LC_THREAD_INFO
438 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 438 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
439 l %r12,__LC_THREAD_INFO
439 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 440 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
440 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 441 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
441 l %r1,BASED(.Lexecve_tail) 442 l %r1,BASED(.Lexecve_tail)
@@ -465,26 +466,27 @@ pgm_check_handler:
465 SAVE_ALL_BASE __LC_SAVE_AREA 466 SAVE_ALL_BASE __LC_SAVE_AREA
466 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 467 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
467 bnz BASED(pgm_per) # got per exception -> special case 468 bnz BASED(pgm_per) # got per exception -> special case
468 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA 469 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
469 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 470 CREATE_STACK_FRAME __LC_SAVE_AREA
471 xc SP_ILC(4,%r15),SP_ILC(%r15)
472 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
473 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
470 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 474 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
471 bz BASED(pgm_no_vtime) 475 bz BASED(pgm_no_vtime)
472 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 476 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
473 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 477 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
474 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 478 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
475pgm_no_vtime: 479pgm_no_vtime:
476 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
477 l %r3,__LC_PGM_ILC # load program interruption code 480 l %r3,__LC_PGM_ILC # load program interruption code
478 l %r4,__LC_TRANS_EXC_CODE 481 l %r4,__LC_TRANS_EXC_CODE
479 REENABLE_IRQS 482 REENABLE_IRQS
480 la %r8,0x7f 483 la %r8,0x7f
481 nr %r8,%r3 484 nr %r8,%r3
482pgm_do_call:
483 l %r7,BASED(.Ljump_table)
484 sll %r8,2 485 sll %r8,2
485 l %r7,0(%r8,%r7) # load address of handler routine 486 l %r1,BASED(.Ljump_table)
487 l %r1,0(%r8,%r1) # load address of handler routine
486 la %r2,SP_PTREGS(%r15) # address of register-save area 488 la %r2,SP_PTREGS(%r15) # address of register-save area
487 basr %r14,%r7 # branch to interrupt-handler 489 basr %r14,%r1 # branch to interrupt-handler
488pgm_exit: 490pgm_exit:
489 b BASED(sysc_return) 491 b BASED(sysc_return)
490 492
@@ -505,33 +507,34 @@ pgm_per:
505# Normal per exception 507# Normal per exception
506# 508#
507pgm_per_std: 509pgm_per_std:
508 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA 510 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
509 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 511 CREATE_STACK_FRAME __LC_SAVE_AREA
512 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
513 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
510 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 514 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
511 bz BASED(pgm_no_vtime2) 515 bz BASED(pgm_no_vtime2)
512 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 516 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
513 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 517 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
514 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 518 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
515pgm_no_vtime2: 519pgm_no_vtime2:
516 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 520 l %r1,__TI_task(%r12)
517 l %r1,__TI_task(%r9)
518 tm SP_PSW+1(%r15),0x01 # kernel per event ? 521 tm SP_PSW+1(%r15),0x01 # kernel per event ?
519 bz BASED(kernel_per) 522 bz BASED(kernel_per)
520 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 523 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
521 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 524 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
522 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 525 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
523 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 526 oi __TI_flags+3(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
524 l %r3,__LC_PGM_ILC # load program interruption code 527 l %r3,__LC_PGM_ILC # load program interruption code
525 l %r4,__LC_TRANS_EXC_CODE 528 l %r4,__LC_TRANS_EXC_CODE
526 REENABLE_IRQS 529 REENABLE_IRQS
527 la %r8,0x7f 530 la %r8,0x7f
528 nr %r8,%r3 # clear per-event-bit and ilc 531 nr %r8,%r3 # clear per-event-bit and ilc
529 be BASED(pgm_exit2) # only per or per+check ? 532 be BASED(pgm_exit2) # only per or per+check ?
530 l %r7,BASED(.Ljump_table)
531 sll %r8,2 533 sll %r8,2
532 l %r7,0(%r8,%r7) # load address of handler routine 534 l %r1,BASED(.Ljump_table)
535 l %r1,0(%r8,%r1) # load address of handler routine
533 la %r2,SP_PTREGS(%r15) # address of register-save area 536 la %r2,SP_PTREGS(%r15) # address of register-save area
534 basr %r14,%r7 # branch to interrupt-handler 537 basr %r14,%r1 # branch to interrupt-handler
535pgm_exit2: 538pgm_exit2:
536 b BASED(sysc_return) 539 b BASED(sysc_return)
537 540
@@ -539,18 +542,19 @@ pgm_exit2:
539# it was a single stepped SVC that is causing all the trouble 542# it was a single stepped SVC that is causing all the trouble
540# 543#
541pgm_svcper: 544pgm_svcper:
542 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 545 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA
543 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 546 CREATE_STACK_FRAME __LC_SAVE_AREA
547 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
548 mvc SP_ILC(4,%r15),__LC_SVC_ILC
549 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
544 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 550 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
545 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 551 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
546 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 552 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
547 lh %r7,0x8a # get svc number from lowcore 553 l %r8,__TI_task(%r12)
548 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
549 l %r8,__TI_task(%r9)
550 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID 554 mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
551 mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS 555 mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS
552 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID 556 mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
553 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 557 oi __TI_flags+3(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
554 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 558 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
555 lm %r2,%r6,SP_R2(%r15) # load svc arguments 559 lm %r2,%r6,SP_R2(%r15) # load svc arguments
556 b BASED(sysc_do_svc) 560 b BASED(sysc_do_svc)
@@ -560,8 +564,7 @@ pgm_svcper:
560# 564#
561kernel_per: 565kernel_per:
562 REENABLE_IRQS 566 REENABLE_IRQS
563 mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check 567 xc SP_SVCNR(2,%r15),SP_SVCNR(%r15)
564 mvi SP_SVCNR+1(%r15),0xff
565 la %r2,SP_PTREGS(%r15) # address of register-save area 568 la %r2,SP_PTREGS(%r15) # address of register-save area
566 l %r1,BASED(.Lhandle_per) # load adr. of per handler 569 l %r1,BASED(.Lhandle_per) # load adr. of per handler
567 basr %r14,%r1 # branch to do_single_step 570 basr %r14,%r1 # branch to do_single_step
@@ -575,9 +578,10 @@ kernel_per:
575io_int_handler: 578io_int_handler:
576 stck __LC_INT_CLOCK 579 stck __LC_INT_CLOCK
577 stpt __LC_ASYNC_ENTER_TIMER 580 stpt __LC_ASYNC_ENTER_TIMER
578 SAVE_ALL_BASE __LC_SAVE_AREA+16
579 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 581 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
580 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 582 CREATE_STACK_FRAME __LC_SAVE_AREA+16
583 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
584 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
581 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 585 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
582 bz BASED(io_no_vtime) 586 bz BASED(io_no_vtime)
583 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 587 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -585,7 +589,6 @@ io_int_handler:
585 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 589 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
586io_no_vtime: 590io_no_vtime:
587 TRACE_IRQS_OFF 591 TRACE_IRQS_OFF
588 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
589 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 592 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
590 la %r2,SP_PTREGS(%r15) # address of register-save area 593 la %r2,SP_PTREGS(%r15) # address of register-save area
591 basr %r14,%r1 # branch to standard irq handler 594 basr %r14,%r1 # branch to standard irq handler
@@ -593,7 +596,7 @@ io_return:
593 LOCKDEP_SYS_EXIT 596 LOCKDEP_SYS_EXIT
594 TRACE_IRQS_ON 597 TRACE_IRQS_ON
595io_tif: 598io_tif:
596 tm __TI_flags+3(%r9),_TIF_WORK_INT 599 tm __TI_flags+3(%r12),_TIF_WORK_INT
597 bnz BASED(io_work) # there is work to do (signals etc.) 600 bnz BASED(io_work) # there is work to do (signals etc.)
598io_restore: 601io_restore:
599 RESTORE_ALL __LC_RETURN_PSW,0 602 RESTORE_ALL __LC_RETURN_PSW,0
@@ -611,9 +614,9 @@ io_work:
611 bo BASED(io_work_user) # yes -> do resched & signal 614 bo BASED(io_work_user) # yes -> do resched & signal
612#ifdef CONFIG_PREEMPT 615#ifdef CONFIG_PREEMPT
613 # check for preemptive scheduling 616 # check for preemptive scheduling
614 icm %r0,15,__TI_precount(%r9) 617 icm %r0,15,__TI_precount(%r12)
615 bnz BASED(io_restore) # preemption disabled 618 bnz BASED(io_restore) # preemption disabled
616 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 619 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
617 bno BASED(io_restore) 620 bno BASED(io_restore)
618 # switch to kernel stack 621 # switch to kernel stack
619 l %r1,SP_R15(%r15) 622 l %r1,SP_R15(%r15)
@@ -647,13 +650,13 @@ io_work_user:
647# and _TIF_MCCK_PENDING 650# and _TIF_MCCK_PENDING
648# 651#
649io_work_tif: 652io_work_tif:
650 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING 653 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
651 bo BASED(io_mcck_pending) 654 bo BASED(io_mcck_pending)
652 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 655 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
653 bo BASED(io_reschedule) 656 bo BASED(io_reschedule)
654 tm __TI_flags+3(%r9),_TIF_SIGPENDING 657 tm __TI_flags+3(%r12),_TIF_SIGPENDING
655 bo BASED(io_sigpending) 658 bo BASED(io_sigpending)
656 tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME 659 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
657 bo BASED(io_notify_resume) 660 bo BASED(io_notify_resume)
658 b BASED(io_return) # beware of critical section cleanup 661 b BASED(io_return) # beware of critical section cleanup
659 662
@@ -713,16 +716,16 @@ io_notify_resume:
713ext_int_handler: 716ext_int_handler:
714 stck __LC_INT_CLOCK 717 stck __LC_INT_CLOCK
715 stpt __LC_ASYNC_ENTER_TIMER 718 stpt __LC_ASYNC_ENTER_TIMER
716 SAVE_ALL_BASE __LC_SAVE_AREA+16
717 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 719 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
718 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 720 CREATE_STACK_FRAME __LC_SAVE_AREA+16
721 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
722 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
719 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 723 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
720 bz BASED(ext_no_vtime) 724 bz BASED(ext_no_vtime)
721 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 725 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
722 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 726 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
723 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 727 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
724ext_no_vtime: 728ext_no_vtime:
725 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
726 TRACE_IRQS_OFF 729 TRACE_IRQS_OFF
727 la %r2,SP_PTREGS(%r15) # address of register-save area 730 la %r2,SP_PTREGS(%r15) # address of register-save area
728 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 731 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
@@ -777,7 +780,10 @@ mcck_int_main:
777 sra %r14,PAGE_SHIFT 780 sra %r14,PAGE_SHIFT
778 be BASED(0f) 781 be BASED(0f)
779 l %r15,__LC_PANIC_STACK # load panic stack 782 l %r15,__LC_PANIC_STACK # load panic stack
7800: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 7830: s %r15,BASED(.Lc_spsize) # make room for registers & psw
784 CREATE_STACK_FRAME __LC_SAVE_AREA+32
785 mvc SP_PSW(8,%r15),0(%r12)
786 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
781 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? 787 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
782 bno BASED(mcck_no_vtime) # no -> skip cleanup critical 788 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
783 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 789 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -786,7 +792,6 @@ mcck_int_main:
786 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 792 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
787 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER 793 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
788mcck_no_vtime: 794mcck_no_vtime:
789 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
790 la %r2,SP_PTREGS(%r15) # load pt_regs 795 la %r2,SP_PTREGS(%r15) # load pt_regs
791 l %r1,BASED(.Ls390_mcck) 796 l %r1,BASED(.Ls390_mcck)
792 basr %r14,%r1 # call machine check handler 797 basr %r14,%r1 # call machine check handler
@@ -798,7 +803,7 @@ mcck_no_vtime:
798 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 803 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
799 lr %r15,%r1 804 lr %r15,%r1
800 stosm __SF_EMPTY(%r15),0x04 # turn dat on 805 stosm __SF_EMPTY(%r15),0x04 # turn dat on
801 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING 806 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
802 bno BASED(mcck_return) 807 bno BASED(mcck_return)
803 TRACE_IRQS_OFF 808 TRACE_IRQS_OFF
804 l %r1,BASED(.Ls390_handle_mcck) 809 l %r1,BASED(.Ls390_handle_mcck)
@@ -947,12 +952,13 @@ cleanup_system_call:
947 bh BASED(0f) 952 bh BASED(0f)
948 mvc __LC_SAVE_AREA(16),0(%r12) 953 mvc __LC_SAVE_AREA(16),0(%r12)
9490: st %r13,4(%r12) 9540: st %r13,4(%r12)
950 st %r12,__LC_SAVE_AREA+48 # argh 955 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
951 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 956 s %r15,BASED(.Lc_spsize) # make room for registers & psw
952 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
953 l %r12,__LC_SAVE_AREA+48 # argh
954 st %r15,12(%r12) 957 st %r15,12(%r12)
955 lh %r7,0x8a 958 CREATE_STACK_FRAME __LC_SAVE_AREA
959 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW
960 mvc SP_ILC(4,%r15),__LC_SVC_ILC
961 mvc 0(4,%r12),__LC_THREAD_INFO
956cleanup_vtime: 962cleanup_vtime:
957 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 963 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
958 bhe BASED(cleanup_stime) 964 bhe BASED(cleanup_stime)