diff options
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 329 |
1 files changed, 149 insertions, 180 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index e8ef21c51bbe..bea9ee37ac9d 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <asm/cache.h> | 15 | #include <asm/cache.h> |
16 | #include <asm/lowcore.h> | ||
17 | #include <asm/errno.h> | 16 | #include <asm/errno.h> |
18 | #include <asm/ptrace.h> | 17 | #include <asm/ptrace.h> |
19 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
@@ -74,21 +73,24 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
74 | basr %r14,%r1 | 73 | basr %r14,%r1 |
75 | .endm | 74 | .endm |
76 | 75 | ||
77 | .macro TRACE_IRQS_CHECK | 76 | .macro TRACE_IRQS_CHECK_ON |
78 | basr %r2,%r0 | ||
79 | tm SP_PSW(%r15),0x03 # irqs enabled? | 77 | tm SP_PSW(%r15),0x03 # irqs enabled? |
80 | jz 0f | 78 | bz BASED(0f) |
81 | l %r1,BASED(.Ltrace_irq_on_caller) | 79 | TRACE_IRQS_ON |
82 | basr %r14,%r1 | 80 | 0: |
83 | j 1f | 81 | .endm |
84 | 0: l %r1,BASED(.Ltrace_irq_off_caller) | 82 | |
85 | basr %r14,%r1 | 83 | .macro TRACE_IRQS_CHECK_OFF |
86 | 1: | 84 | tm SP_PSW(%r15),0x03 # irqs enabled? |
85 | bz BASED(0f) | ||
86 | TRACE_IRQS_OFF | ||
87 | 0: | ||
87 | .endm | 88 | .endm |
88 | #else | 89 | #else |
89 | #define TRACE_IRQS_ON | 90 | #define TRACE_IRQS_ON |
90 | #define TRACE_IRQS_OFF | 91 | #define TRACE_IRQS_OFF |
91 | #define TRACE_IRQS_CHECK | 92 | #define TRACE_IRQS_CHECK_ON |
93 | #define TRACE_IRQS_CHECK_OFF | ||
92 | #endif | 94 | #endif |
93 | 95 | ||
94 | #ifdef CONFIG_LOCKDEP | 96 | #ifdef CONFIG_LOCKDEP |
@@ -178,9 +180,9 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
178 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 180 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
179 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | 181 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack |
180 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 | 182 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 |
181 | icm %r12,3,__LC_SVC_ILC | 183 | icm %r12,12,__LC_SVC_ILC |
182 | stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack | 184 | stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack |
183 | st %r12,SP_SVCNR(%r15) | 185 | st %r12,SP_ILC(%r15) |
184 | mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack | 186 | mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack |
185 | la %r12,0 | 187 | la %r12,0 |
186 | st %r12,__SF_BACKCHAIN(%r15) # clear back chain | 188 | st %r12,__SF_BACKCHAIN(%r15) # clear back chain |
@@ -274,66 +276,45 @@ sysc_do_restart: | |||
274 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) | 276 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) |
275 | 277 | ||
276 | sysc_return: | 278 | sysc_return: |
279 | LOCKDEP_SYS_EXIT | ||
280 | sysc_tif: | ||
277 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | 281 | tm __TI_flags+3(%r9),_TIF_WORK_SVC |
278 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 282 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
279 | sysc_restore: | 283 | sysc_restore: |
280 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
281 | la %r1,BASED(sysc_restore_trace_psw_addr) | ||
282 | l %r1,0(%r1) | ||
283 | lpsw 0(%r1) | ||
284 | sysc_restore_trace: | ||
285 | TRACE_IRQS_CHECK | ||
286 | LOCKDEP_SYS_EXIT | ||
287 | #endif | ||
288 | sysc_leave: | ||
289 | RESTORE_ALL __LC_RETURN_PSW,1 | 284 | RESTORE_ALL __LC_RETURN_PSW,1 |
290 | sysc_done: | 285 | sysc_done: |
291 | 286 | ||
292 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
293 | sysc_restore_trace_psw_addr: | ||
294 | .long sysc_restore_trace_psw | ||
295 | |||
296 | .section .data,"aw",@progbits | ||
297 | .align 8 | ||
298 | .globl sysc_restore_trace_psw | ||
299 | sysc_restore_trace_psw: | ||
300 | .long 0, sysc_restore_trace + 0x80000000 | ||
301 | .previous | ||
302 | #endif | ||
303 | |||
304 | # | 287 | # |
305 | # recheck if there is more work to do | 288 | # There is work to do, but first we need to check if we return to userspace. |
306 | # | ||
307 | sysc_work_loop: | ||
308 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | ||
309 | bz BASED(sysc_restore) # there is no work to do | ||
310 | # | ||
311 | # One of the work bits is on. Find out which one. | ||
312 | # | 289 | # |
313 | sysc_work: | 290 | sysc_work: |
314 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 291 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
315 | bno BASED(sysc_restore) | 292 | bno BASED(sysc_restore) |
293 | |||
294 | # | ||
295 | # One of the work bits is on. Find out which one. | ||
296 | # | ||
297 | sysc_work_tif: | ||
316 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 298 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING |
317 | bo BASED(sysc_mcck_pending) | 299 | bo BASED(sysc_mcck_pending) |
318 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 300 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
319 | bo BASED(sysc_reschedule) | 301 | bo BASED(sysc_reschedule) |
320 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 302 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
321 | bnz BASED(sysc_sigpending) | 303 | bo BASED(sysc_sigpending) |
322 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | 304 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME |
323 | bnz BASED(sysc_notify_resume) | 305 | bo BASED(sysc_notify_resume) |
324 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC | 306 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC |
325 | bo BASED(sysc_restart) | 307 | bo BASED(sysc_restart) |
326 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 308 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP |
327 | bo BASED(sysc_singlestep) | 309 | bo BASED(sysc_singlestep) |
328 | b BASED(sysc_restore) | 310 | b BASED(sysc_return) # beware of critical section cleanup |
329 | sysc_work_done: | ||
330 | 311 | ||
331 | # | 312 | # |
332 | # _TIF_NEED_RESCHED is set, call schedule | 313 | # _TIF_NEED_RESCHED is set, call schedule |
333 | # | 314 | # |
334 | sysc_reschedule: | 315 | sysc_reschedule: |
335 | l %r1,BASED(.Lschedule) | 316 | l %r1,BASED(.Lschedule) |
336 | la %r14,BASED(sysc_work_loop) | 317 | la %r14,BASED(sysc_return) |
337 | br %r1 # call scheduler | 318 | br %r1 # call scheduler |
338 | 319 | ||
339 | # | 320 | # |
@@ -341,7 +322,7 @@ sysc_reschedule: | |||
341 | # | 322 | # |
342 | sysc_mcck_pending: | 323 | sysc_mcck_pending: |
343 | l %r1,BASED(.Ls390_handle_mcck) | 324 | l %r1,BASED(.Ls390_handle_mcck) |
344 | la %r14,BASED(sysc_work_loop) | 325 | la %r14,BASED(sysc_return) |
345 | br %r1 # TIF bit will be cleared by handler | 326 | br %r1 # TIF bit will be cleared by handler |
346 | 327 | ||
347 | # | 328 | # |
@@ -356,7 +337,7 @@ sysc_sigpending: | |||
356 | bo BASED(sysc_restart) | 337 | bo BASED(sysc_restart) |
357 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 338 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP |
358 | bo BASED(sysc_singlestep) | 339 | bo BASED(sysc_singlestep) |
359 | b BASED(sysc_work_loop) | 340 | b BASED(sysc_return) |
360 | 341 | ||
361 | # | 342 | # |
362 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume | 343 | # _TIF_NOTIFY_RESUME is set, call do_notify_resume |
@@ -364,7 +345,7 @@ sysc_sigpending: | |||
364 | sysc_notify_resume: | 345 | sysc_notify_resume: |
365 | la %r2,SP_PTREGS(%r15) # load pt_regs | 346 | la %r2,SP_PTREGS(%r15) # load pt_regs |
366 | l %r1,BASED(.Ldo_notify_resume) | 347 | l %r1,BASED(.Ldo_notify_resume) |
367 | la %r14,BASED(sysc_work_loop) | 348 | la %r14,BASED(sysc_return) |
368 | br %r1 # call do_notify_resume | 349 | br %r1 # call do_notify_resume |
369 | 350 | ||
370 | 351 | ||
@@ -459,11 +440,13 @@ kernel_execve: | |||
459 | br %r14 | 440 | br %r14 |
460 | # execve succeeded. | 441 | # execve succeeded. |
461 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts | 442 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts |
443 | TRACE_IRQS_OFF | ||
462 | l %r15,__LC_KERNEL_STACK # load ksp | 444 | l %r15,__LC_KERNEL_STACK # load ksp |
463 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 445 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
464 | l %r9,__LC_THREAD_INFO | 446 | l %r9,__LC_THREAD_INFO |
465 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs | 447 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs |
466 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 448 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
449 | TRACE_IRQS_ON | ||
467 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 450 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
468 | l %r1,BASED(.Lexecve_tail) | 451 | l %r1,BASED(.Lexecve_tail) |
469 | basr %r14,%r1 | 452 | basr %r14,%r1 |
@@ -500,8 +483,8 @@ pgm_check_handler: | |||
500 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 483 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
501 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 484 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
502 | pgm_no_vtime: | 485 | pgm_no_vtime: |
486 | TRACE_IRQS_CHECK_OFF | ||
503 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 487 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
504 | TRACE_IRQS_OFF | ||
505 | l %r3,__LC_PGM_ILC # load program interruption code | 488 | l %r3,__LC_PGM_ILC # load program interruption code |
506 | la %r8,0x7f | 489 | la %r8,0x7f |
507 | nr %r8,%r3 | 490 | nr %r8,%r3 |
@@ -510,8 +493,10 @@ pgm_do_call: | |||
510 | sll %r8,2 | 493 | sll %r8,2 |
511 | l %r7,0(%r8,%r7) # load address of handler routine | 494 | l %r7,0(%r8,%r7) # load address of handler routine |
512 | la %r2,SP_PTREGS(%r15) # address of register-save area | 495 | la %r2,SP_PTREGS(%r15) # address of register-save area |
513 | la %r14,BASED(sysc_return) | 496 | basr %r14,%r7 # branch to interrupt-handler |
514 | br %r7 # branch to interrupt-handler | 497 | pgm_exit: |
498 | TRACE_IRQS_CHECK_ON | ||
499 | b BASED(sysc_return) | ||
515 | 500 | ||
516 | # | 501 | # |
517 | # handle per exception | 502 | # handle per exception |
@@ -538,20 +523,28 @@ pgm_per_std: | |||
538 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 523 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
539 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 524 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
540 | pgm_no_vtime2: | 525 | pgm_no_vtime2: |
526 | TRACE_IRQS_CHECK_OFF | ||
541 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 527 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
542 | TRACE_IRQS_OFF | ||
543 | l %r1,__TI_task(%r9) | 528 | l %r1,__TI_task(%r9) |
529 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | ||
530 | bz BASED(kernel_per) | ||
544 | mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID | 531 | mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID |
545 | mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS | 532 | mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS |
546 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID | 533 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID |
547 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 534 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
548 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | ||
549 | bz BASED(kernel_per) | ||
550 | l %r3,__LC_PGM_ILC # load program interruption code | 535 | l %r3,__LC_PGM_ILC # load program interruption code |
551 | la %r8,0x7f | 536 | la %r8,0x7f |
552 | nr %r8,%r3 # clear per-event-bit and ilc | 537 | nr %r8,%r3 # clear per-event-bit and ilc |
553 | be BASED(sysc_return) # only per or per+check ? | 538 | be BASED(pgm_exit2) # only per or per+check ? |
554 | b BASED(pgm_do_call) | 539 | l %r7,BASED(.Ljump_table) |
540 | sll %r8,2 | ||
541 | l %r7,0(%r8,%r7) # load address of handler routine | ||
542 | la %r2,SP_PTREGS(%r15) # address of register-save area | ||
543 | basr %r14,%r7 # branch to interrupt-handler | ||
544 | pgm_exit2: | ||
545 | TRACE_IRQS_ON | ||
546 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | ||
547 | b BASED(sysc_return) | ||
555 | 548 | ||
556 | # | 549 | # |
557 | # it was a single stepped SVC that is causing all the trouble | 550 | # it was a single stepped SVC that is causing all the trouble |
@@ -571,8 +564,8 @@ pgm_svcper: | |||
571 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID | 564 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID |
572 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 565 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
573 | TRACE_IRQS_ON | 566 | TRACE_IRQS_ON |
574 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | ||
575 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 567 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
568 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | ||
576 | b BASED(sysc_do_svc) | 569 | b BASED(sysc_do_svc) |
577 | 570 | ||
578 | # | 571 | # |
@@ -583,8 +576,8 @@ kernel_per: | |||
583 | mvi SP_SVCNR+1(%r15),0xff | 576 | mvi SP_SVCNR+1(%r15),0xff |
584 | la %r2,SP_PTREGS(%r15) # address of register-save area | 577 | la %r2,SP_PTREGS(%r15) # address of register-save area |
585 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 578 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
586 | la %r14,BASED(sysc_restore)# load adr. of system return | 579 | basr %r14,%r1 # branch to do_single_step |
587 | br %r1 # branch to do_single_step | 580 | b BASED(pgm_exit) |
588 | 581 | ||
589 | /* | 582 | /* |
590 | * IO interrupt handler routine | 583 | * IO interrupt handler routine |
@@ -603,134 +596,126 @@ io_int_handler: | |||
603 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 596 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
604 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 597 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
605 | io_no_vtime: | 598 | io_no_vtime: |
606 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
607 | TRACE_IRQS_OFF | 599 | TRACE_IRQS_OFF |
600 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
608 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ | 601 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ |
609 | la %r2,SP_PTREGS(%r15) # address of register-save area | 602 | la %r2,SP_PTREGS(%r15) # address of register-save area |
610 | basr %r14,%r1 # branch to standard irq handler | 603 | basr %r14,%r1 # branch to standard irq handler |
611 | io_return: | 604 | io_return: |
605 | LOCKDEP_SYS_EXIT | ||
606 | TRACE_IRQS_ON | ||
607 | io_tif: | ||
612 | tm __TI_flags+3(%r9),_TIF_WORK_INT | 608 | tm __TI_flags+3(%r9),_TIF_WORK_INT |
613 | bnz BASED(io_work) # there is work to do (signals etc.) | 609 | bnz BASED(io_work) # there is work to do (signals etc.) |
614 | io_restore: | 610 | io_restore: |
615 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
616 | la %r1,BASED(io_restore_trace_psw_addr) | ||
617 | l %r1,0(%r1) | ||
618 | lpsw 0(%r1) | ||
619 | io_restore_trace: | ||
620 | TRACE_IRQS_CHECK | ||
621 | LOCKDEP_SYS_EXIT | ||
622 | #endif | ||
623 | io_leave: | ||
624 | RESTORE_ALL __LC_RETURN_PSW,0 | 611 | RESTORE_ALL __LC_RETURN_PSW,0 |
625 | io_done: | 612 | io_done: |
626 | 613 | ||
627 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
628 | io_restore_trace_psw_addr: | ||
629 | .long io_restore_trace_psw | ||
630 | |||
631 | .section .data,"aw",@progbits | ||
632 | .align 8 | ||
633 | .globl io_restore_trace_psw | ||
634 | io_restore_trace_psw: | ||
635 | .long 0, io_restore_trace + 0x80000000 | ||
636 | .previous | ||
637 | #endif | ||
638 | |||
639 | # | 614 | # |
640 | # switch to kernel stack, then check the TIF bits | 615 | # There is work todo, find out in which context we have been interrupted: |
616 | # 1) if we return to user space we can do all _TIF_WORK_INT work | ||
617 | # 2) if we return to kernel code and preemptive scheduling is enabled check | ||
618 | # the preemption counter and if it is zero call preempt_schedule_irq | ||
619 | # Before any work can be done, a switch to the kernel stack is required. | ||
641 | # | 620 | # |
642 | io_work: | 621 | io_work: |
643 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 622 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
644 | #ifndef CONFIG_PREEMPT | 623 | bo BASED(io_work_user) # yes -> do resched & signal |
645 | bno BASED(io_restore) # no-> skip resched & signal | 624 | #ifdef CONFIG_PREEMPT |
646 | #else | ||
647 | bnz BASED(io_work_user) # no -> check for preemptive scheduling | ||
648 | # check for preemptive scheduling | 625 | # check for preemptive scheduling |
649 | icm %r0,15,__TI_precount(%r9) | 626 | icm %r0,15,__TI_precount(%r9) |
650 | bnz BASED(io_restore) # preemption disabled | 627 | bnz BASED(io_restore) # preemption disabled |
628 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | ||
629 | bno BASED(io_restore) | ||
630 | # switch to kernel stack | ||
651 | l %r1,SP_R15(%r15) | 631 | l %r1,SP_R15(%r15) |
652 | s %r1,BASED(.Lc_spsize) | 632 | s %r1,BASED(.Lc_spsize) |
653 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 633 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
654 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 634 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
655 | lr %r15,%r1 | 635 | lr %r15,%r1 |
656 | io_resume_loop: | 636 | # TRACE_IRQS_ON already done at io_return, call |
657 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 637 | # TRACE_IRQS_OFF to keep things symmetrical |
658 | bno BASED(io_restore) | 638 | TRACE_IRQS_OFF |
659 | l %r1,BASED(.Lpreempt_schedule_irq) | 639 | l %r1,BASED(.Lpreempt_schedule_irq) |
660 | la %r14,BASED(io_resume_loop) | 640 | basr %r14,%r1 # call preempt_schedule_irq |
661 | br %r1 # call schedule | 641 | b BASED(io_return) |
642 | #else | ||
643 | b BASED(io_restore) | ||
662 | #endif | 644 | #endif |
663 | 645 | ||
646 | # | ||
647 | # Need to do work before returning to userspace, switch to kernel stack | ||
648 | # | ||
664 | io_work_user: | 649 | io_work_user: |
665 | l %r1,__LC_KERNEL_STACK | 650 | l %r1,__LC_KERNEL_STACK |
666 | s %r1,BASED(.Lc_spsize) | 651 | s %r1,BASED(.Lc_spsize) |
667 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 652 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
668 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 653 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
669 | lr %r15,%r1 | 654 | lr %r15,%r1 |
655 | |||
670 | # | 656 | # |
671 | # One of the work bits is on. Find out which one. | 657 | # One of the work bits is on. Find out which one. |
672 | # Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED | 658 | # Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED |
673 | # and _TIF_MCCK_PENDING | 659 | # and _TIF_MCCK_PENDING |
674 | # | 660 | # |
675 | io_work_loop: | 661 | io_work_tif: |
676 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 662 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING |
677 | bo BASED(io_mcck_pending) | 663 | bo BASED(io_mcck_pending) |
678 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 664 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
679 | bo BASED(io_reschedule) | 665 | bo BASED(io_reschedule) |
680 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 666 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
681 | bnz BASED(io_sigpending) | 667 | bo BASED(io_sigpending) |
682 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | 668 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME |
683 | bnz BASED(io_notify_resume) | 669 | bo BASED(io_notify_resume) |
684 | b BASED(io_restore) | 670 | b BASED(io_return) # beware of critical section cleanup |
685 | io_work_done: | ||
686 | 671 | ||
687 | # | 672 | # |
688 | # _TIF_MCCK_PENDING is set, call handler | 673 | # _TIF_MCCK_PENDING is set, call handler |
689 | # | 674 | # |
690 | io_mcck_pending: | 675 | io_mcck_pending: |
676 | # TRACE_IRQS_ON already done at io_return | ||
691 | l %r1,BASED(.Ls390_handle_mcck) | 677 | l %r1,BASED(.Ls390_handle_mcck) |
692 | basr %r14,%r1 # TIF bit will be cleared by handler | 678 | basr %r14,%r1 # TIF bit will be cleared by handler |
693 | b BASED(io_work_loop) | 679 | TRACE_IRQS_OFF |
680 | b BASED(io_return) | ||
694 | 681 | ||
695 | # | 682 | # |
696 | # _TIF_NEED_RESCHED is set, call schedule | 683 | # _TIF_NEED_RESCHED is set, call schedule |
697 | # | 684 | # |
698 | io_reschedule: | 685 | io_reschedule: |
699 | TRACE_IRQS_ON | 686 | # TRACE_IRQS_ON already done at io_return |
700 | l %r1,BASED(.Lschedule) | 687 | l %r1,BASED(.Lschedule) |
701 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 688 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
702 | basr %r14,%r1 # call scheduler | 689 | basr %r14,%r1 # call scheduler |
703 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 690 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
704 | TRACE_IRQS_OFF | 691 | TRACE_IRQS_OFF |
705 | tm __TI_flags+3(%r9),_TIF_WORK_INT | 692 | b BASED(io_return) |
706 | bz BASED(io_restore) # there is no work to do | ||
707 | b BASED(io_work_loop) | ||
708 | 693 | ||
709 | # | 694 | # |
710 | # _TIF_SIGPENDING is set, call do_signal | 695 | # _TIF_SIGPENDING is set, call do_signal |
711 | # | 696 | # |
712 | io_sigpending: | 697 | io_sigpending: |
713 | TRACE_IRQS_ON | 698 | # TRACE_IRQS_ON already done at io_return |
714 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 699 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
715 | la %r2,SP_PTREGS(%r15) # load pt_regs | 700 | la %r2,SP_PTREGS(%r15) # load pt_regs |
716 | l %r1,BASED(.Ldo_signal) | 701 | l %r1,BASED(.Ldo_signal) |
717 | basr %r14,%r1 # call do_signal | 702 | basr %r14,%r1 # call do_signal |
718 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 703 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
719 | TRACE_IRQS_OFF | 704 | TRACE_IRQS_OFF |
720 | b BASED(io_work_loop) | 705 | b BASED(io_return) |
721 | 706 | ||
722 | # | 707 | # |
723 | # _TIF_SIGPENDING is set, call do_signal | 708 | # _TIF_SIGPENDING is set, call do_signal |
724 | # | 709 | # |
725 | io_notify_resume: | 710 | io_notify_resume: |
726 | TRACE_IRQS_ON | 711 | # TRACE_IRQS_ON already done at io_return |
727 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 712 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
728 | la %r2,SP_PTREGS(%r15) # load pt_regs | 713 | la %r2,SP_PTREGS(%r15) # load pt_regs |
729 | l %r1,BASED(.Ldo_notify_resume) | 714 | l %r1,BASED(.Ldo_notify_resume) |
730 | basr %r14,%r1 # call do_signal | 715 | basr %r14,%r1 # call do_signal |
731 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 716 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
732 | TRACE_IRQS_OFF | 717 | TRACE_IRQS_OFF |
733 | b BASED(io_work_loop) | 718 | b BASED(io_return) |
734 | 719 | ||
735 | /* | 720 | /* |
736 | * External interrupt handler routine | 721 | * External interrupt handler routine |
@@ -765,15 +750,14 @@ __critical_end: | |||
765 | 750 | ||
766 | .globl mcck_int_handler | 751 | .globl mcck_int_handler |
767 | mcck_int_handler: | 752 | mcck_int_handler: |
768 | stck __LC_INT_CLOCK | 753 | stck __LC_MCCK_CLOCK |
769 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer | 754 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer |
770 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs | 755 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs |
771 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 756 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
772 | la %r12,__LC_MCK_OLD_PSW | 757 | la %r12,__LC_MCK_OLD_PSW |
773 | tm __LC_MCCK_CODE,0x80 # system damage? | 758 | tm __LC_MCCK_CODE,0x80 # system damage? |
774 | bo BASED(mcck_int_main) # yes -> rest of mcck code invalid | 759 | bo BASED(mcck_int_main) # yes -> rest of mcck code invalid |
775 | mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER | 760 | mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA |
776 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA | ||
777 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | 761 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? |
778 | bo BASED(1f) | 762 | bo BASED(1f) |
779 | la %r14,__LC_SYNC_ENTER_TIMER | 763 | la %r14,__LC_SYNC_ENTER_TIMER |
@@ -787,7 +771,7 @@ mcck_int_handler: | |||
787 | bl BASED(0f) | 771 | bl BASED(0f) |
788 | la %r14,__LC_LAST_UPDATE_TIMER | 772 | la %r14,__LC_LAST_UPDATE_TIMER |
789 | 0: spt 0(%r14) | 773 | 0: spt 0(%r14) |
790 | mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) | 774 | mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) |
791 | 1: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? | 775 | 1: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? |
792 | bno BASED(mcck_int_main) # no -> skip cleanup critical | 776 | bno BASED(mcck_int_main) # no -> skip cleanup critical |
793 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit | 777 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit |
@@ -809,9 +793,9 @@ mcck_int_main: | |||
809 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical | 793 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical |
810 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 794 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
811 | bz BASED(mcck_no_vtime) | 795 | bz BASED(mcck_no_vtime) |
812 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 796 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER |
813 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 797 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
814 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 798 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER |
815 | mcck_no_vtime: | 799 | mcck_no_vtime: |
816 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 800 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
817 | la %r2,SP_PTREGS(%r15) # load pt_regs | 801 | la %r2,SP_PTREGS(%r15) # load pt_regs |
@@ -834,7 +818,6 @@ mcck_no_vtime: | |||
834 | mcck_return: | 818 | mcck_return: |
835 | mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW | 819 | mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW |
836 | ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit | 820 | ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit |
837 | mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52 | ||
838 | tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? | 821 | tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? |
839 | bno BASED(0f) | 822 | bno BASED(0f) |
840 | lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 | 823 | lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 |
@@ -918,18 +901,14 @@ stack_overflow: | |||
918 | 901 | ||
919 | cleanup_table_system_call: | 902 | cleanup_table_system_call: |
920 | .long system_call + 0x80000000, sysc_do_svc + 0x80000000 | 903 | .long system_call + 0x80000000, sysc_do_svc + 0x80000000 |
921 | cleanup_table_sysc_return: | 904 | cleanup_table_sysc_tif: |
922 | .long sysc_return + 0x80000000, sysc_leave + 0x80000000 | 905 | .long sysc_tif + 0x80000000, sysc_restore + 0x80000000 |
923 | cleanup_table_sysc_leave: | 906 | cleanup_table_sysc_restore: |
924 | .long sysc_leave + 0x80000000, sysc_done + 0x80000000 | 907 | .long sysc_restore + 0x80000000, sysc_done + 0x80000000 |
925 | cleanup_table_sysc_work_loop: | 908 | cleanup_table_io_tif: |
926 | .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000 | 909 | .long io_tif + 0x80000000, io_restore + 0x80000000 |
927 | cleanup_table_io_return: | 910 | cleanup_table_io_restore: |
928 | .long io_return + 0x80000000, io_leave + 0x80000000 | 911 | .long io_restore + 0x80000000, io_done + 0x80000000 |
929 | cleanup_table_io_leave: | ||
930 | .long io_leave + 0x80000000, io_done + 0x80000000 | ||
931 | cleanup_table_io_work_loop: | ||
932 | .long io_work_loop + 0x80000000, io_work_done + 0x80000000 | ||
933 | 912 | ||
934 | cleanup_critical: | 913 | cleanup_critical: |
935 | clc 4(4,%r12),BASED(cleanup_table_system_call) | 914 | clc 4(4,%r12),BASED(cleanup_table_system_call) |
@@ -937,49 +916,40 @@ cleanup_critical: | |||
937 | clc 4(4,%r12),BASED(cleanup_table_system_call+4) | 916 | clc 4(4,%r12),BASED(cleanup_table_system_call+4) |
938 | bl BASED(cleanup_system_call) | 917 | bl BASED(cleanup_system_call) |
939 | 0: | 918 | 0: |
940 | clc 4(4,%r12),BASED(cleanup_table_sysc_return) | 919 | clc 4(4,%r12),BASED(cleanup_table_sysc_tif) |
941 | bl BASED(0f) | ||
942 | clc 4(4,%r12),BASED(cleanup_table_sysc_return+4) | ||
943 | bl BASED(cleanup_sysc_return) | ||
944 | 0: | ||
945 | clc 4(4,%r12),BASED(cleanup_table_sysc_leave) | ||
946 | bl BASED(0f) | 920 | bl BASED(0f) |
947 | clc 4(4,%r12),BASED(cleanup_table_sysc_leave+4) | 921 | clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4) |
948 | bl BASED(cleanup_sysc_leave) | 922 | bl BASED(cleanup_sysc_tif) |
949 | 0: | 923 | 0: |
950 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop) | 924 | clc 4(4,%r12),BASED(cleanup_table_sysc_restore) |
951 | bl BASED(0f) | 925 | bl BASED(0f) |
952 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) | 926 | clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4) |
953 | bl BASED(cleanup_sysc_return) | 927 | bl BASED(cleanup_sysc_restore) |
954 | 0: | 928 | 0: |
955 | clc 4(4,%r12),BASED(cleanup_table_io_return) | 929 | clc 4(4,%r12),BASED(cleanup_table_io_tif) |
956 | bl BASED(0f) | 930 | bl BASED(0f) |
957 | clc 4(4,%r12),BASED(cleanup_table_io_return+4) | 931 | clc 4(4,%r12),BASED(cleanup_table_io_tif+4) |
958 | bl BASED(cleanup_io_return) | 932 | bl BASED(cleanup_io_tif) |
959 | 0: | 933 | 0: |
960 | clc 4(4,%r12),BASED(cleanup_table_io_leave) | 934 | clc 4(4,%r12),BASED(cleanup_table_io_restore) |
961 | bl BASED(0f) | 935 | bl BASED(0f) |
962 | clc 4(4,%r12),BASED(cleanup_table_io_leave+4) | 936 | clc 4(4,%r12),BASED(cleanup_table_io_restore+4) |
963 | bl BASED(cleanup_io_leave) | 937 | bl BASED(cleanup_io_restore) |
964 | 0: | ||
965 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop) | ||
966 | bl BASED(0f) | ||
967 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4) | ||
968 | bl BASED(cleanup_io_return) | ||
969 | 0: | 938 | 0: |
970 | br %r14 | 939 | br %r14 |
971 | 940 | ||
972 | cleanup_system_call: | 941 | cleanup_system_call: |
973 | mvc __LC_RETURN_PSW(8),0(%r12) | 942 | mvc __LC_RETURN_PSW(8),0(%r12) |
974 | c %r12,BASED(.Lmck_old_psw) | ||
975 | be BASED(0f) | ||
976 | la %r12,__LC_SAVE_AREA+16 | ||
977 | b BASED(1f) | ||
978 | 0: la %r12,__LC_SAVE_AREA+32 | ||
979 | 1: | ||
980 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4) | 943 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4) |
981 | bh BASED(0f) | 944 | bh BASED(0f) |
945 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER | ||
946 | c %r12,BASED(.Lmck_old_psw) | ||
947 | be BASED(0f) | ||
982 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER | 948 | mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER |
949 | 0: c %r12,BASED(.Lmck_old_psw) | ||
950 | la %r12,__LC_SAVE_AREA+32 | ||
951 | be BASED(0f) | ||
952 | la %r12,__LC_SAVE_AREA+16 | ||
983 | 0: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8) | 953 | 0: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8) |
984 | bhe BASED(cleanup_vtime) | 954 | bhe BASED(cleanup_vtime) |
985 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn) | 955 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn) |
@@ -1012,55 +982,54 @@ cleanup_system_call_insn: | |||
1012 | .long sysc_stime + 0x80000000 | 982 | .long sysc_stime + 0x80000000 |
1013 | .long sysc_update + 0x80000000 | 983 | .long sysc_update + 0x80000000 |
1014 | 984 | ||
1015 | cleanup_sysc_return: | 985 | cleanup_sysc_tif: |
1016 | mvc __LC_RETURN_PSW(4),0(%r12) | 986 | mvc __LC_RETURN_PSW(4),0(%r12) |
1017 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_return) | 987 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif) |
1018 | la %r12,__LC_RETURN_PSW | 988 | la %r12,__LC_RETURN_PSW |
1019 | br %r14 | 989 | br %r14 |
1020 | 990 | ||
1021 | cleanup_sysc_leave: | 991 | cleanup_sysc_restore: |
1022 | clc 4(4,%r12),BASED(cleanup_sysc_leave_insn) | 992 | clc 4(4,%r12),BASED(cleanup_sysc_restore_insn) |
1023 | be BASED(2f) | 993 | be BASED(2f) |
994 | mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER | ||
995 | c %r12,BASED(.Lmck_old_psw) | ||
996 | be BASED(0f) | ||
1024 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER | 997 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER |
1025 | clc 4(4,%r12),BASED(cleanup_sysc_leave_insn+4) | 998 | 0: clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) |
1026 | be BASED(2f) | 999 | be BASED(2f) |
1027 | mvc __LC_RETURN_PSW(8),SP_PSW(%r15) | 1000 | mvc __LC_RETURN_PSW(8),SP_PSW(%r15) |
1028 | c %r12,BASED(.Lmck_old_psw) | 1001 | c %r12,BASED(.Lmck_old_psw) |
1029 | bne BASED(0f) | 1002 | la %r12,__LC_SAVE_AREA+32 |
1030 | mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) | 1003 | be BASED(1f) |
1031 | b BASED(1f) | 1004 | la %r12,__LC_SAVE_AREA+16 |
1032 | 0: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15) | 1005 | 1: mvc 0(16,%r12),SP_R12(%r15) |
1033 | 1: lm %r0,%r11,SP_R0(%r15) | 1006 | lm %r0,%r11,SP_R0(%r15) |
1034 | l %r15,SP_R15(%r15) | 1007 | l %r15,SP_R15(%r15) |
1035 | 2: la %r12,__LC_RETURN_PSW | 1008 | 2: la %r12,__LC_RETURN_PSW |
1036 | br %r14 | 1009 | br %r14 |
1037 | cleanup_sysc_leave_insn: | 1010 | cleanup_sysc_restore_insn: |
1038 | .long sysc_done - 4 + 0x80000000 | 1011 | .long sysc_done - 4 + 0x80000000 |
1039 | .long sysc_done - 8 + 0x80000000 | 1012 | .long sysc_done - 8 + 0x80000000 |
1040 | 1013 | ||
1041 | cleanup_io_return: | 1014 | cleanup_io_tif: |
1042 | mvc __LC_RETURN_PSW(4),0(%r12) | 1015 | mvc __LC_RETURN_PSW(4),0(%r12) |
1043 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) | 1016 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif) |
1044 | la %r12,__LC_RETURN_PSW | 1017 | la %r12,__LC_RETURN_PSW |
1045 | br %r14 | 1018 | br %r14 |
1046 | 1019 | ||
1047 | cleanup_io_leave: | 1020 | cleanup_io_restore: |
1048 | clc 4(4,%r12),BASED(cleanup_io_leave_insn) | 1021 | clc 4(4,%r12),BASED(cleanup_io_restore_insn) |
1049 | be BASED(2f) | 1022 | be BASED(1f) |
1050 | mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER | 1023 | mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER |
1051 | clc 4(4,%r12),BASED(cleanup_io_leave_insn+4) | 1024 | clc 4(4,%r12),BASED(cleanup_io_restore_insn+4) |
1052 | be BASED(2f) | 1025 | be BASED(1f) |
1053 | mvc __LC_RETURN_PSW(8),SP_PSW(%r15) | 1026 | mvc __LC_RETURN_PSW(8),SP_PSW(%r15) |
1054 | c %r12,BASED(.Lmck_old_psw) | ||
1055 | bne BASED(0f) | ||
1056 | mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) | 1027 | mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) |
1057 | b BASED(1f) | 1028 | lm %r0,%r11,SP_R0(%r15) |
1058 | 0: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15) | ||
1059 | 1: lm %r0,%r11,SP_R0(%r15) | ||
1060 | l %r15,SP_R15(%r15) | 1029 | l %r15,SP_R15(%r15) |
1061 | 2: la %r12,__LC_RETURN_PSW | 1030 | 1: la %r12,__LC_RETURN_PSW |
1062 | br %r14 | 1031 | br %r14 |
1063 | cleanup_io_leave_insn: | 1032 | cleanup_io_restore_insn: |
1064 | .long io_done - 4 + 0x80000000 | 1033 | .long io_done - 4 + 0x80000000 |
1065 | .long io_done - 8 + 0x80000000 | 1034 | .long io_done - 8 + 0x80000000 |
1066 | 1035 | ||