aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-07-03 13:49:45 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-07-03 13:49:45 -0400
commit026477c1141b67e98e3bd8bdedb7d4b88a3ecd09 (patch)
tree2624a44924c625c367f3cebf937853b9da2de282 /arch/s390/kernel/entry.S
parent9f2fa466383ce100b90fe52cb4489d7a26bf72a9 (diff)
parent29454dde27d8e340bb1987bad9aa504af7081eba (diff)
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S90
1 files changed, 65 insertions, 25 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index b2448487854c..d8948c342caf 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -11,7 +11,6 @@
11 11
12#include <linux/sys.h> 12#include <linux/sys.h>
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <linux/config.h>
15#include <asm/cache.h> 14#include <asm/cache.h>
16#include <asm/lowcore.h> 15#include <asm/lowcore.h>
17#include <asm/errno.h> 16#include <asm/errno.h>
@@ -93,13 +92,22 @@ STACK_SIZE = 1 << STACK_SHIFT
93 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 92 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
94 .endm 93 .endm
95 94
96 .macro SAVE_ALL psworg,savearea,sync 95 .macro SAVE_ALL_SYNC psworg,savearea
97 la %r12,\psworg 96 la %r12,\psworg
98 .if \sync
99 tm \psworg+1,0x01 # test problem state bit 97 tm \psworg+1,0x01 # test problem state bit
100 bz BASED(2f) # skip stack setup save 98 bz BASED(2f) # skip stack setup save
101 l %r15,__LC_KERNEL_STACK # problem state -> load ksp 99 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
102 .else 100#ifdef CONFIG_CHECK_STACK
101 b BASED(3f)
1022: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
103 bz BASED(stack_overflow)
1043:
105#endif
1062:
107 .endm
108
109 .macro SAVE_ALL_ASYNC psworg,savearea
110 la %r12,\psworg
103 tm \psworg+1,0x01 # test problem state bit 111 tm \psworg+1,0x01 # test problem state bit
104 bnz BASED(1f) # from user -> load async stack 112 bnz BASED(1f) # from user -> load async stack
105 clc \psworg+4(4),BASED(.Lcritical_end) 113 clc \psworg+4(4),BASED(.Lcritical_end)
@@ -115,7 +123,6 @@ STACK_SIZE = 1 << STACK_SHIFT
115 sra %r14,STACK_SHIFT 123 sra %r14,STACK_SHIFT
116 be BASED(2f) 124 be BASED(2f)
1171: l %r15,__LC_ASYNC_STACK 1251: l %r15,__LC_ASYNC_STACK
118 .endif
119#ifdef CONFIG_CHECK_STACK 126#ifdef CONFIG_CHECK_STACK
120 b BASED(3f) 127 b BASED(3f)
1212: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 1282: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
@@ -196,7 +203,7 @@ system_call:
196 STORE_TIMER __LC_SYNC_ENTER_TIMER 203 STORE_TIMER __LC_SYNC_ENTER_TIMER
197sysc_saveall: 204sysc_saveall:
198 SAVE_ALL_BASE __LC_SAVE_AREA 205 SAVE_ALL_BASE __LC_SAVE_AREA
199 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 206 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
200 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 207 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
201 lh %r7,0x8a # get svc number from lowcore 208 lh %r7,0x8a # get svc number from lowcore
202#ifdef CONFIG_VIRT_CPU_ACCOUNTING 209#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -221,8 +228,9 @@ sysc_do_svc:
221sysc_nr_ok: 228sysc_nr_ok:
222 mvc SP_ARGS(4,%r15),SP_R7(%r15) 229 mvc SP_ARGS(4,%r15),SP_R7(%r15)
223sysc_do_restart: 230sysc_do_restart:
231 l %r8,BASED(.Lsysc_table)
224 tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) 232 tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
225 l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr. 233 l %r8,0(%r7,%r8) # get system call addr.
226 bnz BASED(sysc_tracesys) 234 bnz BASED(sysc_tracesys)
227 basr %r14,%r8 # call sys_xxxx 235 basr %r14,%r8 # call sys_xxxx
228 st %r2,SP_R2(%r15) # store return value (change R2 on stack) 236 st %r2,SP_R2(%r15) # store return value (change R2 on stack)
@@ -323,9 +331,10 @@ sysc_tracesys:
323 basr %r14,%r1 331 basr %r14,%r1
324 clc SP_R2(4,%r15),BASED(.Lnr_syscalls) 332 clc SP_R2(4,%r15),BASED(.Lnr_syscalls)
325 bnl BASED(sysc_tracenogo) 333 bnl BASED(sysc_tracenogo)
334 l %r8,BASED(.Lsysc_table)
326 l %r7,SP_R2(%r15) # strace might have changed the 335 l %r7,SP_R2(%r15) # strace might have changed the
327 sll %r7,2 # system call 336 sll %r7,2 # system call
328 l %r8,sys_call_table-system_call(%r7,%r13) 337 l %r8,0(%r7,%r8)
329sysc_tracego: 338sysc_tracego:
330 lm %r3,%r6,SP_R3(%r15) 339 lm %r3,%r6,SP_R3(%r15)
331 l %r2,SP_ORIG_R2(%r15) 340 l %r2,SP_ORIG_R2(%r15)
@@ -425,7 +434,7 @@ pgm_check_handler:
425 SAVE_ALL_BASE __LC_SAVE_AREA 434 SAVE_ALL_BASE __LC_SAVE_AREA
426 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 435 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
427 bnz BASED(pgm_per) # got per exception -> special case 436 bnz BASED(pgm_per) # got per exception -> special case
428 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 437 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
429 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 438 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
430#ifdef CONFIG_VIRT_CPU_ACCOUNTING 439#ifdef CONFIG_VIRT_CPU_ACCOUNTING
431 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 440 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -464,7 +473,7 @@ pgm_per:
464# Normal per exception 473# Normal per exception
465# 474#
466pgm_per_std: 475pgm_per_std:
467 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 476 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
468 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 477 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
469#ifdef CONFIG_VIRT_CPU_ACCOUNTING 478#ifdef CONFIG_VIRT_CPU_ACCOUNTING
470 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 479 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -490,7 +499,7 @@ pgm_no_vtime2:
490# it was a single stepped SVC that is causing all the trouble 499# it was a single stepped SVC that is causing all the trouble
491# 500#
492pgm_svcper: 501pgm_svcper:
493 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 502 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
494 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 503 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
495#ifdef CONFIG_VIRT_CPU_ACCOUNTING 504#ifdef CONFIG_VIRT_CPU_ACCOUNTING
496 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 505 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -519,7 +528,7 @@ io_int_handler:
519 STORE_TIMER __LC_ASYNC_ENTER_TIMER 528 STORE_TIMER __LC_ASYNC_ENTER_TIMER
520 stck __LC_INT_CLOCK 529 stck __LC_INT_CLOCK
521 SAVE_ALL_BASE __LC_SAVE_AREA+16 530 SAVE_ALL_BASE __LC_SAVE_AREA+16
522 SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 531 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
523 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 532 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
524#ifdef CONFIG_VIRT_CPU_ACCOUNTING 533#ifdef CONFIG_VIRT_CPU_ACCOUNTING
525 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 534 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -631,7 +640,7 @@ ext_int_handler:
631 STORE_TIMER __LC_ASYNC_ENTER_TIMER 640 STORE_TIMER __LC_ASYNC_ENTER_TIMER
632 stck __LC_INT_CLOCK 641 stck __LC_INT_CLOCK
633 SAVE_ALL_BASE __LC_SAVE_AREA+16 642 SAVE_ALL_BASE __LC_SAVE_AREA+16
634 SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 643 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
635 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 644 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
636#ifdef CONFIG_VIRT_CPU_ACCOUNTING 645#ifdef CONFIG_VIRT_CPU_ACCOUNTING
637 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 646 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -657,21 +666,31 @@ __critical_end:
657 .globl mcck_int_handler 666 .globl mcck_int_handler
658mcck_int_handler: 667mcck_int_handler:
659 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer 668 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
660 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
661 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs 669 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
662 SAVE_ALL_BASE __LC_SAVE_AREA+32 670 SAVE_ALL_BASE __LC_SAVE_AREA+32
663 la %r12,__LC_MCK_OLD_PSW 671 la %r12,__LC_MCK_OLD_PSW
664 tm __LC_MCCK_CODE,0x80 # system damage? 672 tm __LC_MCCK_CODE,0x80 # system damage?
665 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid 673 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid
666 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
667 bo BASED(0f)
668 spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer
669#ifdef CONFIG_VIRT_CPU_ACCOUNTING 674#ifdef CONFIG_VIRT_CPU_ACCOUNTING
670 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 675 mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER
671 mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 676 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
672 mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER 677 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
678 bo BASED(1f)
679 la %r14,__LC_SYNC_ENTER_TIMER
680 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
681 bl BASED(0f)
682 la %r14,__LC_ASYNC_ENTER_TIMER
6830: clc 0(8,%r14),__LC_EXIT_TIMER
684 bl BASED(0f)
685 la %r14,__LC_EXIT_TIMER
6860: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
687 bl BASED(0f)
688 la %r14,__LC_LAST_UPDATE_TIMER
6890: spt 0(%r14)
690 mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14)
6911:
673#endif 692#endif
6740: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 693 tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
675 bno BASED(mcck_int_main) # no -> skip cleanup critical 694 bno BASED(mcck_int_main) # no -> skip cleanup critical
676 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 695 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
677 bnz BASED(mcck_int_main) # from user -> load async stack 696 bnz BASED(mcck_int_main) # from user -> load async stack
@@ -691,7 +710,7 @@ mcck_int_main:
691#ifdef CONFIG_VIRT_CPU_ACCOUNTING 710#ifdef CONFIG_VIRT_CPU_ACCOUNTING
692 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? 711 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
693 bno BASED(mcck_no_vtime) # no -> skip cleanup critical 712 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
694 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? 713 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
695 bz BASED(mcck_no_vtime) 714 bz BASED(mcck_no_vtime)
696 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 715 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
697 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 716 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -715,6 +734,20 @@ mcck_no_vtime:
715 l %r1,BASED(.Ls390_handle_mcck) 734 l %r1,BASED(.Ls390_handle_mcck)
716 basr %r14,%r1 # call machine check handler 735 basr %r14,%r1 # call machine check handler
717mcck_return: 736mcck_return:
737 mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
738 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
739#ifdef CONFIG_VIRT_CPU_ACCOUNTING
740 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52
741 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
742 bno BASED(0f)
743 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15
744 stpt __LC_EXIT_TIMER
745 lpsw __LC_RETURN_MCCK_PSW # back to caller
7460:
747#endif
748 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15
749 lpsw __LC_RETURN_MCCK_PSW # back to caller
750
718 RESTORE_ALL __LC_RETURN_MCCK_PSW,0 751 RESTORE_ALL __LC_RETURN_MCCK_PSW,0
719 752
720#ifdef CONFIG_SMP 753#ifdef CONFIG_SMP
@@ -781,6 +814,8 @@ cleanup_table_sysc_leave:
781 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 814 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000
782cleanup_table_sysc_work_loop: 815cleanup_table_sysc_work_loop:
783 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 816 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000
817cleanup_table_io_return:
818 .long io_return + 0x80000000, io_leave + 0x80000000
784cleanup_table_io_leave: 819cleanup_table_io_leave:
785 .long io_leave + 0x80000000, io_done + 0x80000000 820 .long io_leave + 0x80000000, io_done + 0x80000000
786cleanup_table_io_work_loop: 821cleanup_table_io_work_loop:
@@ -807,6 +842,11 @@ cleanup_critical:
807 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) 842 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
808 bl BASED(cleanup_sysc_return) 843 bl BASED(cleanup_sysc_return)
8090: 8440:
845 clc 4(4,%r12),BASED(cleanup_table_io_return)
846 bl BASED(0f)
847 clc 4(4,%r12),BASED(cleanup_table_io_return+4)
848 bl BASED(cleanup_io_return)
8490:
810 clc 4(4,%r12),BASED(cleanup_table_io_leave) 850 clc 4(4,%r12),BASED(cleanup_table_io_leave)
811 bl BASED(0f) 851 bl BASED(0f)
812 clc 4(4,%r12),BASED(cleanup_table_io_leave+4) 852 clc 4(4,%r12),BASED(cleanup_table_io_leave+4)
@@ -839,7 +879,7 @@ cleanup_system_call:
839 mvc __LC_SAVE_AREA(16),0(%r12) 879 mvc __LC_SAVE_AREA(16),0(%r12)
8400: st %r13,4(%r12) 8800: st %r13,4(%r12)
841 st %r12,__LC_SAVE_AREA+48 # argh 881 st %r12,__LC_SAVE_AREA+48 # argh
842 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 882 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
843 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 883 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
844 l %r12,__LC_SAVE_AREA+48 # argh 884 l %r12,__LC_SAVE_AREA+48 # argh
845 st %r15,12(%r12) 885 st %r15,12(%r12)
@@ -971,6 +1011,7 @@ cleanup_io_leave_insn:
971.Ltrace: .long syscall_trace 1011.Ltrace: .long syscall_trace
972.Lvfork: .long sys_vfork 1012.Lvfork: .long sys_vfork
973.Lschedtail: .long schedule_tail 1013.Lschedtail: .long schedule_tail
1014.Lsysc_table: .long sys_call_table
974 1015
975.Lcritical_start: 1016.Lcritical_start:
976 .long __critical_start + 0x80000000 1017 .long __critical_start + 0x80000000
@@ -979,9 +1020,8 @@ cleanup_io_leave_insn:
979.Lcleanup_critical: 1020.Lcleanup_critical:
980 .long cleanup_critical 1021 .long cleanup_critical
981 1022
1023 .section .rodata, "a"
982#define SYSCALL(esa,esame,emu) .long esa 1024#define SYSCALL(esa,esame,emu) .long esa
983 .globl sys_call_table
984sys_call_table: 1025sys_call_table:
985#include "syscalls.S" 1026#include "syscalls.S"
986#undef SYSCALL 1027#undef SYSCALL
987