aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S324
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 800:
82 j 1f 81 .endm
830: l %r1,BASED(.Ltrace_irq_off_caller) 82
84 basr %r14,%r1 83 .macro TRACE_IRQS_CHECK_OFF
851: 84 tm SP_PSW(%r15),0x03 # irqs enabled?
85 bz BASED(0f)
86 TRACE_IRQS_OFF
870:
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
275sysc_return: 278sysc_return:
279 LOCKDEP_SYS_EXIT
280sysc_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.)
278sysc_restore: 283sysc_restore:
279#ifdef CONFIG_TRACE_IRQFLAGS
280 la %r1,BASED(sysc_restore_trace_psw_addr)
281 l %r1,0(%r1)
282 lpsw 0(%r1)
283sysc_restore_trace:
284 TRACE_IRQS_CHECK
285 LOCKDEP_SYS_EXIT
286#endif
287sysc_leave:
288 RESTORE_ALL __LC_RETURN_PSW,1 284 RESTORE_ALL __LC_RETURN_PSW,1
289sysc_done: 285sysc_done:
290 286
291#ifdef CONFIG_TRACE_IRQFLAGS
292sysc_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
298sysc_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#
306sysc_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#
312sysc_work: 290sysc_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#
297sysc_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
328sysc_work_done:
329 311
330# 312#
331# _TIF_NEED_RESCHED is set, call schedule 313# _TIF_NEED_RESCHED is set, call schedule
332# 314#
333sysc_reschedule: 315sysc_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#
341sysc_mcck_pending: 323sysc_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:
363sysc_notify_resume: 345sysc_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.
4600: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 4420: 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
501pgm_no_vtime: 485pgm_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 497pgm_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
539pgm_no_vtime2: 525pgm_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
604io_no_vtime: 590io_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
610io_return: 596io_return:
597 LOCKDEP_SYS_EXIT
598 TRACE_IRQS_ON
599io_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.)
613io_restore: 602io_restore:
614#ifdef CONFIG_TRACE_IRQFLAGS
615 la %r1,BASED(io_restore_trace_psw_addr)
616 l %r1,0(%r1)
617 lpsw 0(%r1)
618io_restore_trace:
619 TRACE_IRQS_CHECK
620 LOCKDEP_SYS_EXIT
621#endif
622io_leave:
623 RESTORE_ALL __LC_RETURN_PSW,0 603 RESTORE_ALL __LC_RETURN_PSW,0
624io_done: 604io_done:
625 605
626#ifdef CONFIG_TRACE_IRQFLAGS
627io_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
633io_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#
641io_work: 613io_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
655io_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#
663io_work_user: 641io_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#
674io_work_loop: 653io_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
684io_work_done:
685 663
686# 664#
687# _TIF_MCCK_PENDING is set, call handler 665# _TIF_MCCK_PENDING is set, call handler
688# 666#
689io_mcck_pending: 667io_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#
697io_reschedule: 677io_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#
711io_sigpending: 689io_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#
724io_notify_resume: 702io_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
766mcck_int_handler: 744mcck_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
7880: spt 0(%r14) 7650: spt 0(%r14)
789 mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) 766 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7901: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 7671: 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
814mcck_no_vtime: 791mcck_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:
833mcck_return: 810mcck_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
918cleanup_table_system_call: 894cleanup_table_system_call:
919 .long system_call + 0x80000000, sysc_do_svc + 0x80000000 895 .long system_call + 0x80000000, sysc_do_svc + 0x80000000
920cleanup_table_sysc_return: 896cleanup_table_sysc_tif:
921 .long sysc_return + 0x80000000, sysc_leave + 0x80000000 897 .long sysc_tif + 0x80000000, sysc_restore + 0x80000000
922cleanup_table_sysc_leave: 898cleanup_table_sysc_restore:
923 .long sysc_leave + 0x80000000, sysc_done + 0x80000000 899 .long sysc_restore + 0x80000000, sysc_done + 0x80000000
924cleanup_table_sysc_work_loop: 900cleanup_table_io_tif:
925 .long sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000 901 .long io_tif + 0x80000000, io_restore + 0x80000000
926cleanup_table_io_return: 902cleanup_table_io_restore:
927 .long io_return + 0x80000000, io_leave + 0x80000000 903 .long io_restore + 0x80000000, io_done + 0x80000000
928cleanup_table_io_leave:
929 .long io_leave + 0x80000000, io_done + 0x80000000
930cleanup_table_io_work_loop:
931 .long io_work_loop + 0x80000000, io_work_done + 0x80000000
932 904
933cleanup_critical: 905cleanup_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)
9380: 9100:
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)
9430:
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)
9480:
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)
9530: 9150:
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)
9580: 9200:
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)
9630: 9250:
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)
9680: 9300:
969 br %r14 931 br %r14
970 932
971cleanup_system_call: 933cleanup_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)
9770: la %r12,__LC_SAVE_AREA+32
9781:
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
9410: c %r12,BASED(.Lmck_old_psw)
942 la %r12,__LC_SAVE_AREA+32
943 be BASED(0f)
944 la %r12,__LC_SAVE_AREA+16
9820: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8) 9450: 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
1014cleanup_sysc_return: 977cleanup_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
1020cleanup_sysc_leave: 983cleanup_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) 9900: 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
10310: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15) 9971: mvc 0(16,%r12),SP_R12(%r15)
10321: 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)
10342: la %r12,__LC_RETURN_PSW 10002: la %r12,__LC_RETURN_PSW
1035 br %r14 1001 br %r14
1036cleanup_sysc_leave_insn: 1002cleanup_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
1040cleanup_io_return: 1006cleanup_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
1046cleanup_io_work_loop: 1012cleanup_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)
1052cleanup_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)
10630: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15)
10641: lm %r0,%r11,SP_R0(%r15)
1065 l %r15,SP_R15(%r15) 1021 l %r15,SP_R15(%r15)
10662: la %r12,__LC_RETURN_PSW 10221: la %r12,__LC_RETURN_PSW
1067 br %r14 1023 br %r14
1068cleanup_io_leave_insn: 1024cleanup_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