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