v2.4.10.4 -> v2.4.10.5
[linux-flexiantxendom0-3.2.10.git] / arch / s390x / kernel / entry.S
1 /*
2  *  arch/s390/kernel/entry.S
3  *    S390 low-level entry points.
4  *
5  *  S390 version
6  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
7  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
8  *               Hartmut Penner (hp@de.ibm.com),
9  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
10  */
11
12 #include <linux/sys.h>
13 #include <linux/linkage.h>
14 #include <linux/config.h>
15 #include <asm/cache.h>
16 #include <asm/lowcore.h>
17 #include <asm/errno.h>
18 #include <asm/smp.h>
19 #include <asm/ptrace.h>
20
21
22 /*
23  * Stack layout for the system_call stack entry.
24  * The first few entries are identical to the user_regs_struct.
25  */
26 SP_PTREGS    =  STACK_FRAME_OVERHEAD 
27 SP_PSW       =  STACK_FRAME_OVERHEAD + PT_PSWMASK
28 SP_R0        =  STACK_FRAME_OVERHEAD + PT_GPR0
29 SP_R1        =  STACK_FRAME_OVERHEAD + PT_GPR1
30 SP_R2        =  STACK_FRAME_OVERHEAD + PT_GPR2
31 SP_R3        =  STACK_FRAME_OVERHEAD + PT_GPR3
32 SP_R4        =  STACK_FRAME_OVERHEAD + PT_GPR4
33 SP_R5        =  STACK_FRAME_OVERHEAD + PT_GPR5
34 SP_R6        =  STACK_FRAME_OVERHEAD + PT_GPR6
35 SP_R7        =  STACK_FRAME_OVERHEAD + PT_GPR7
36 SP_R8        =  STACK_FRAME_OVERHEAD + PT_GPR8
37 SP_R9        =  STACK_FRAME_OVERHEAD + PT_GPR9
38 SP_R10       =  STACK_FRAME_OVERHEAD + PT_GPR10
39 SP_R11       =  STACK_FRAME_OVERHEAD + PT_GPR11
40 SP_R12       =  STACK_FRAME_OVERHEAD + PT_GPR12
41 SP_R13       =  STACK_FRAME_OVERHEAD + PT_GPR13
42 SP_R14       =  STACK_FRAME_OVERHEAD + PT_GPR14
43 SP_R15       =  STACK_FRAME_OVERHEAD + PT_GPR15
44 SP_AREGS     =  STACK_FRAME_OVERHEAD + PT_ACR0
45 SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + PT_ORIGGPR2
46 /* Now the additional entries */
47 SP_TRAP      =  (SP_ORIG_R2+GPR_SIZE)
48 #if CONFIG_REMOTE_DEBUG
49 SP_CRREGS    =  (SP_TRAP+4)
50 /* fpu registers are saved & restored by the gdb stub itself */
51 SP_FPC       =  (SP_CRREGS+(NUM_CRS*CR_SIZE))
52 SP_FPRS      =  (SP_FPC+FPC_SIZE+FPC_PAD_SIZE)
53 SP_PGM_OLD_ILC= (SP_FPRS+(NUM_FPRS*FPR_SIZE))
54 #else
55 SP_PGM_OLD_ILC= (SP_TRAP+4)
56 #endif
57 SP_SIZE      =  (SP_PGM_OLD_ILC+4)
58 /*
59  * these defines are offsets into the thread_struct
60  */
61 _TSS_PTREGS  = 0
62 _TSS_FPRS    = (_TSS_PTREGS+8)
63 _TSS_AR2     = (_TSS_FPRS+136)
64 _TSS_AR4     = (_TSS_AR2+4)
65 _TSS_KSP     = (_TSS_AR4+4)
66 _TSS_USERSEG = (_TSS_KSP+8)
67 _TSS_PROT    = (_TSS_USERSEG+8)
68 _TSS_ERROR   = (_TSS_PROT+8)
69 _TSS_TRAP    = (_TSS_ERROR+4)
70 _TSS_PER     = (_TSS_TRAP+4)
71 _TSS_IEEE    = (_TSS_PER+72)
72 _TSS_FLAGS   = (_TSS_IEEE+8)
73
74 /*
75  * these are offsets into the task-struct.
76  */
77 state        =  0
78 flags        =  8
79 sigpending   = 16
80 need_resched = 32
81 tsk_ptrace   = 40
82 processor    = 92
83
84 /*
85  * Register usage in interrupt handlers:
86  *    R9  - pointer to current task structure
87  *    R13 - pointer to literal pool
88  *    R14 - return register for function calls
89  *    R15 - kernel stack pointer
90  */
91
92         .macro  SAVE_ALL psworg          # system entry macro
93         stmg    %r14,%r15,__LC_SAVE_AREA
94         stam    %a2,%a4,__LC_SAVE_AREA+16
95         tm      \psworg+1,0x01           # test problem state bit
96         jz      0f                       # skip stack setup save
97         lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
98         slr     %r14,%r14
99         sar     %a2,%r14                 # set ac.reg. 2 to primary space
100         lhi     %r14,1
101         sar     %a4,%r14                 # set access reg. 4 to home space
102 0:      aghi    %r15,-SP_SIZE            # make room for registers & psw
103         nill    %r15,0xfff8              # align stack pointer to 8
104         stmg    %r0,%r14,SP_R0(%r15)     # store gprs 0-14 to kernel stack
105         stg     %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
106         mvc     SP_R14(16,%r15),__LC_SAVE_AREA # move R15 to stack
107         stam    %a0,%a15,SP_AREGS(%r15)  # store access registers to kst.
108         mvc     SP_AREGS+8(12,%r15),__LC_SAVE_AREA+16 # store ac. regs
109         mvc     SP_PSW(16,%r15),\psworg  # move user PSW to stack
110         lhi     %r0,\psworg              # store trap indication
111         st      %r0,SP_TRAP(%r15)
112         xc      0(8,%r15),0(%r15)        # clear back chain
113         .endm
114
115         .macro  RESTORE_ALL              # system exit macro
116         mvc     __LC_RETURN_PSW(16),SP_PSW(%r15) # move user PSW to lowcore
117         lam     %a0,%a15,SP_AREGS(%r15)  # load the access registers
118         lmg     %r0,%r15,SP_R0(%r15)     # load gprs 0-15 of user
119         ni      __LC_RETURN_PSW+1,0xfd   # clear wait state bit
120         lpswe   __LC_RETURN_PSW          # back to caller
121         .endm
122
123         .macro  GET_CURRENT
124         lghi    %r9,-16384               # load pointer to task_struct to %r9
125         ngr     %r9,15
126         .endm
127
128
129 /*
130  * Scheduler resume function, called by switch_to
131  *  grp2 = (thread_struct *) prev->tss
132  *  grp3 = (thread_struct *) next->tss
133  * Returns:
134  *  gpr2 = prev
135  */
136         .globl  resume
137 resume:
138         lg      %r4,_TSS_PTREGS(%r3)
139         tm      SP_PSW-SP_PTREGS(%r4),0x40 # is the new process using per ?
140         jz      resume_noper            # if not we're fine
141         stctg   %c9,%c11,48(%r15)       # We are using per stuff
142         clc     _TSS_PER(24,%r3),48(%r15)
143         je      resume_noper            # we got away without bashing TLB's
144         lctlg   %c9,%c11,_TSS_PER(%r3)  # Nope we didn't
145 resume_noper:
146         stmg    %r6,%r15,48(%r15)       # store resume registers of prev task
147         stg     %r15,_TSS_KSP(%r2) # store kernel stack ptr to prev->tss.ksp
148         lghi    %r0,-16384
149         ngr     %r0,%r15
150         lg      %r15,_TSS_KSP(%r3) # load kernel stack ptr from next->tss.ksp
151         lghi    %r1,16383
152         ogr     %r1,%r15
153         aghi    %r1,1
154         stg     %r1,__LC_KERNEL_STACK   # __LC_KERNEL_STACK = new kernel stack
155         stam    %a2,%a2,_TSS_AR2(%r2)   # store kernel access reg. 2
156         stam    %a4,%a4,_TSS_AR4(%r2)   # store kernel access reg. 4
157         lam     %a2,%a2,_TSS_AR2(%r3)   # load kernel access reg. 2
158         lam     %a4,%a4,_TSS_AR4(%r3)   # load kernel access reg. 4
159         lgr     %r2,%r0                 # return task_struct of last task
160         lmg     %r6,%r15,48(%r15)       # load resume registers of next task
161         br      %r14
162
163 /*
164  * SVC interrupt handler routine. System calls are synchronous events and
165  * are executed with interrupts enabled.
166  */
167
168         .globl  system_call
169 system_call:
170         SAVE_ALL __LC_SVC_OLD_PSW
171         mvi     SP_PGM_OLD_ILC(%r15),1  # mark PGM_OLD_ILC as invalid
172 pgm_system_call:
173         GET_CURRENT               # load pointer to task_struct to R9
174         larl    %r7,sys_call_table
175         llgc    %r8,__LC_SVC_INT_CODE+1 # get svc number from lowcore
176         stosm   48(%r15),0x03     # reenable interrupts
177         sll     %r8,3
178         tm      SP_PSW+3(%r15),0x01  # are we running in 31 bit mode ?
179         jo      sysc_noemu
180         la      %r8,4(%r8)        # use 31 bit emulation system calls
181 sysc_noemu:
182         lgf     %r8,0(%r8,%r7)    # load address of system call routine
183         tm      tsk_ptrace+7(%r9),0x02 # PT_TRACESYS
184         jnz     sysc_tracesys
185         basr    %r14,%r8          # call sys_xxxx
186         stg     %r2,SP_R2(%r15)   # store return value (change R2 on stack)
187                                   # ATTENTION: check sys_execve_glue before
188                                   # changing anything here !!
189
190 sysc_return:
191         tm      SP_PSW+1(%r15),0x01 # returning to user ?
192         jno     sysc_leave        # no-> skip bottom half, resched & signal
193 #
194 # check, if reschedule is needed
195 #
196         lg      %r0,need_resched(%r9) # get need_resched from task_struct
197         ltgr    %r0,%r0
198         jnz     sysc_reschedule
199         icm     %r0,15,sigpending(%r9)     # get sigpending from task_struct
200         jnz     sysc_signal_return
201 sysc_leave:
202         tm      SP_PGM_OLD_ILC(%r15),0xff
203         jz      pgm_svcret
204         stnsm   48(%r15),0xfc         # disable I/O and ext. interrupts
205         RESTORE_ALL
206
207 #
208 # call do_signal before return
209 #
210 sysc_signal_return:     
211         la      %r2,SP_PTREGS(%r15) # load pt_regs
212         sgr     %r3,%r3             # clear *oldset
213         larl    %r14,sysc_leave
214         jg      do_signal           # return point is sysc_leave
215
216 #
217 # call trace before and after sys_call
218 #
219 sysc_tracesys:
220         lghi    %r2,-ENOSYS
221         stg     %r2,SP_R2(%r15)     # give sysc_trace an -ENOSYS retval
222         brasl   %r14,syscall_trace
223         lmg     %r3,%r6,SP_R3(%r15)
224         lg      %r2,SP_ORIG_R2(%r15)
225         basr    %r14,%r8            # call sys_xxx
226         stg     %r2,SP_R2(%r15)     # store return value
227         larl    %r14,sysc_return
228         jg      syscall_trace       # return point is sysc_return
229
230 #
231 # call schedule with sysc_return as return-address
232 #
233 sysc_reschedule:        
234         larl    %r14,sysc_return
235         jg      schedule            # return point is sysc_return
236
237 #
238 # a new process exits the kernel with ret_from_fork
239 #
240         .globl  ret_from_fork
241 ret_from_fork:  
242         GET_CURRENT               # load pointer to task_struct to R9
243         stosm   48(%r15),0x03     # reenable interrupts
244         xc      SP_R2(8,%r15),SP_R2(%r15) # child returns 0
245 #ifdef CONFIG_SMP
246         larl    %r14,sysc_return
247         jg      schedule_tail     # return to sysc_return
248 #else
249         j       sysc_return
250 #endif
251
252 #
253 # clone, fork, vfork, exec and sigreturn need glue,
254 # because they all expect pt_regs as parameter,
255 # but are called with different parameter.
256 # return-address is set up above
257 #
258 sys_clone_glue: 
259         la      %r2,SP_PTREGS(%r15)    # load pt_regs
260         jg      sys_clone              # branch to sys_clone
261
262 sys_fork_glue:  
263         la      %r2,SP_PTREGS(%r15)    # load pt_regs
264         jg      sys_fork               # branch to sys_fork
265
266 sys_vfork_glue: 
267         la      %r2,SP_PTREGS(%r15)    # load pt_regs
268         jg      sys_vfork              # branch to sys_vfork
269
270 sys_execve_glue:        
271         la      %r2,SP_PTREGS(%r15)   # load pt_regs
272         lgr     %r12,%r14             # save return address
273         brasl   %r14,sys_execve       # call sys_execve
274         ltgr    %r2,%r2               # check if execve failed
275         bnz     0(%r12)               # it did fail -> store result in gpr2
276         b       6(%r12)               # SKIP STG 2,SP_R2(15) in
277                                       # system_call/sysc_tracesys
278 #ifdef CONFIG_S390_SUPPORT
279 sys32_execve_glue:        
280         la      %r2,SP_PTREGS(%r15)   # load pt_regs
281         lgr     %r12,%r14             # save return address
282         brasl   %r14,sys32_execve     # call sys32_execve
283         ltgr    %r2,%r2               # check if execve failed
284         bnz     0(%r12)               # it did fail -> store result in gpr2
285         b       6(%r12)               # SKIP STG 2,SP_R2(15) in
286                                       # system_call/sysc_tracesys
287 #endif
288
289 sys_sigreturn_glue:     
290         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
291         jg      sys_sigreturn         # branch to sys_sigreturn
292
293 #ifdef CONFIG_S390_SUPPORT
294 sys32_sigreturn_glue:     
295         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
296         jg      sys32_sigreturn       # branch to sys32_sigreturn
297 #endif
298
299 sys_rt_sigreturn_glue:     
300         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
301         jg      sys_rt_sigreturn      # branch to sys_sigreturn
302
303 #ifdef CONFIG_S390_SUPPORT
304 sys32_rt_sigreturn_glue:     
305         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
306         jg      sys32_rt_sigreturn    # branch to sys32_sigreturn
307 #endif
308
309 #
310 # sigsuspend and rt_sigsuspend need pt_regs as an additional
311 # parameter and they have to skip the store of %r2 into the
312 # user register %r2 because the return value was set in 
313 # sigsuspend and rt_sigsuspend already and must not be overwritten!
314 #
315
316 sys_sigsuspend_glue:    
317         lgr     %r5,%r4               # move mask back
318         lgr     %r4,%r3               # move history1 parameter
319         lgr     %r3,%r2               # move history0 parameter
320         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
321         la      %r14,6(%r14)          # skip store of return value
322         jg      sys_sigsuspend        # branch to sys_sigsuspend
323
324 #ifdef CONFIG_S390_SUPPORT
325 sys32_sigsuspend_glue:    
326         llgfr   %r4,%r4               # unsigned long                   
327         lgr     %r5,%r4               # move mask back
328         lgfr    %r3,%r3               # int                     
329         lgr     %r4,%r3               # move history1 parameter
330         lgfr    %r2,%r2               # int                     
331         lgr     %r3,%r2               # move history0 parameter
332         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
333         la      %r14,6(%r14)          # skip store of return value
334         jg      sys32_sigsuspend      # branch to sys32_sigsuspend
335 #endif
336
337 sys_rt_sigsuspend_glue: 
338         lgr     %r4,%r3               # move sigsetsize parameter
339         lgr     %r3,%r2               # move unewset parameter
340         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
341         la      %r14,6(%r14)          # skip store of return value
342         jg      sys_rt_sigsuspend     # branch to sys_rt_sigsuspend
343
344 #ifdef CONFIG_S390_SUPPORT
345 sys32_rt_sigsuspend_glue: 
346         llgfr   %r3,%r3               # size_t                  
347         lgr     %r4,%r3               # move sigsetsize parameter
348         llgtr   %r2,%r2               # sigset_emu31_t *
349         lgr     %r3,%r2               # move unewset parameter
350         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
351         la      %r14,6(%r14)          # skip store of return value
352         jg      sys32_rt_sigsuspend   # branch to sys32_rt_sigsuspend
353 #endif
354
355 sys_sigaltstack_glue:
356         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
357         jg      sys_sigaltstack       # branch to sys_sigreturn
358
359 #ifdef CONFIG_S390_SUPPORT
360 sys32_sigaltstack_glue:
361         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
362         jg      sys32_sigaltstack_wrapper # branch to sys_sigreturn
363 #endif
364
365 #ifdef CONFIG_S390_SUPPORT
366 #define SYSCALL(esame,esa) esame,esa
367 #else
368 #define SYSCALL(esame,esa) esame,sys_ni_syscall
369 #endif
370
371         .globl  sys_call_table  
372 sys_call_table:
373         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 0 */
374         .long  SYSCALL(sys_exit,sys32_exit_wrapper)
375         .long  SYSCALL(sys_fork_glue,sys_fork_glue)
376         .long  SYSCALL(sys_read,sys32_read_wrapper)
377         .long  SYSCALL(sys_write,sys32_write_wrapper)
378         .long  SYSCALL(sys_open,sys32_open_wrapper)             /* 5 */
379         .long  SYSCALL(sys_close,sys32_close_wrapper)
380         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old waitpid syscall */
381         .long  SYSCALL(sys_creat,sys32_creat_wrapper)
382         .long  SYSCALL(sys_link,sys32_link_wrapper)
383         .long  SYSCALL(sys_unlink,sys32_unlink_wrapper)         /* 10 */
384         .long  SYSCALL(sys_execve_glue,sys32_execve_glue)
385         .long  SYSCALL(sys_chdir,sys32_chdir_wrapper)
386         .long  SYSCALL(sys_ni_syscall,sys32_time_wrapper) /* old time syscall */
387         .long  SYSCALL(sys_mknod,sys32_mknod_wrapper)
388         .long  SYSCALL(sys_chmod,sys32_chmod_wrapper)           /* 15 */
389         .long  SYSCALL(sys_ni_syscall,sys32_lchown16_wrapper)   /* old lchown16 syscall*/
390         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old break syscall */
391         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old stat syscall */
392         .long  SYSCALL(sys_lseek,sys32_lseek_wrapper)
393         .long  SYSCALL(sys_getpid,sys_getpid) /* 20 */
394         .long  SYSCALL(sys_mount,sys32_mount_wrapper)
395         .long  SYSCALL(sys_oldumount,sys32_oldumount_wrapper)
396         .long  SYSCALL(sys_ni_syscall,sys32_setuid16_wrapper)   /* old setuid16 syscall*/
397         .long  SYSCALL(sys_ni_syscall,sys32_getuid16)   /* old getuid16 syscall*/
398         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 25 old stime syscall */
399         .long  SYSCALL(sys_ptrace,sys32_ptrace_wrapper)
400         .long  SYSCALL(sys_alarm,sys32_alarm_wrapper)
401         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old fstat syscall */
402         .long  SYSCALL(sys_pause,sys32_pause)
403         .long  SYSCALL(sys_utime,sys32_utime_wrapper)           /* 30 */
404         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old stty syscall */
405         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old gtty syscall */
406         .long  SYSCALL(sys_access,sys32_access_wrapper)
407         .long  SYSCALL(sys_nice,sys32_nice_wrapper)
408         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old ftime syscall */
409         .long  SYSCALL(sys_sync,sys_sync)
410         .long  SYSCALL(sys_kill,sys32_kill_wrapper)
411         .long  SYSCALL(sys_rename,sys32_rename_wrapper)
412         .long  SYSCALL(sys_mkdir,sys32_mkdir_wrapper)
413         .long  SYSCALL(sys_rmdir,sys32_rmdir_wrapper)           /* 40 */
414         .long  SYSCALL(sys_dup,sys32_dup_wrapper)
415         .long  SYSCALL(sys_pipe,sys32_pipe_wrapper)
416         .long  SYSCALL(sys_times,sys32_times_wrapper)
417         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old prof syscall */
418         .long  SYSCALL(sys_brk,sys32_brk_wrapper)               /* 45 */
419         .long  SYSCALL(sys_ni_syscall,sys32_setgid16)   /* old setgid16 syscall*/
420         .long  SYSCALL(sys_ni_syscall,sys32_getgid16)   /* old getgid16 syscall*/
421         .long  SYSCALL(sys_signal,sys32_signal_wrapper)
422         .long  SYSCALL(sys_ni_syscall,sys32_geteuid16)  /* old geteuid16 syscall */
423         .long  SYSCALL(sys_ni_syscall,sys32_getegid16)  /* old getegid16 syscall */
424         .long  SYSCALL(sys_acct,sys32_acct_wrapper)
425         .long  SYSCALL(sys_umount,sys32_umount_wrapper)
426         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old lock syscall */
427         .long  SYSCALL(sys_ioctl,sys32_ioctl_wrapper)
428         .long  SYSCALL(sys_fcntl,sys32_fcntl_wrapper)   /* 55 */
429         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* intel mpx syscall */
430         .long  SYSCALL(sys_setpgid,sys32_setpgid_wrapper)
431         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old ulimit syscall */
432         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old uname syscall */
433         .long  SYSCALL(sys_umask,sys32_umask_wrapper)           /* 60 */
434         .long  SYSCALL(sys_chroot,sys32_chroot_wrapper)
435         .long  SYSCALL(sys_ustat,sys32_ustat_wrapper)
436         .long  SYSCALL(sys_dup2,sys32_dup2_wrapper)
437         .long  SYSCALL(sys_getppid,sys_getppid)
438         .long  SYSCALL(sys_getpgrp,sys_getpgrp)       /* 65 */
439         .long  SYSCALL(sys_setsid,sys_setsid)
440         .long  SYSCALL(sys_sigaction,sys32_sigaction_wrapper)
441         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old sgetmask syscall*/
442         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old ssetmask syscall*/
443         .long  SYSCALL(sys_ni_syscall,sys32_setreuid16_wrapper) /* old setreuid16 syscall */
444         .long  SYSCALL(sys_ni_syscall,sys32_setregid16_wrapper) /* old setregid16 syscall */
445         .long  SYSCALL(sys_sigsuspend_glue,sys32_sigsuspend_glue)
446         .long  SYSCALL(sys_sigpending,sys32_sigpending_wrapper)
447         .long  SYSCALL(sys_sethostname,sys32_sethostname_wrapper)
448         .long  SYSCALL(sys_setrlimit,sys32_setrlimit_wrapper)   /* 75 */
449         .long  SYSCALL(sys_getrlimit,sys32_old_getrlimit_wrapper) 
450         .long  SYSCALL(sys_getrusage,sys32_getrusage_wrapper)
451         .long  SYSCALL(sys_gettimeofday,sys32_gettimeofday_wrapper)
452         .long  SYSCALL(sys_settimeofday,sys32_settimeofday_wrapper)
453         .long  SYSCALL(sys_ni_syscall,sys32_getgroups16_wrapper) /* old getgroups16 syscall */
454         .long  SYSCALL(sys_ni_syscall,sys32_setgroups16_wrapper) /* old setgroups16 syscall */
455         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old select syscall */
456         .long  SYSCALL(sys_symlink,sys32_symlink_wrapper)
457         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old lstat syscall */
458         .long  SYSCALL(sys_readlink,sys32_readlink_wrapper)     /* 85 */
459         .long  SYSCALL(sys_uselib,sys32_uselib_wrapper)
460         .long  SYSCALL(sys_swapon,sys32_swapon_wrapper)
461         .long  SYSCALL(sys_reboot,sys32_reboot_wrapper)
462         .long  SYSCALL(sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */
463         .long  SYSCALL(old_mmap,old32_mmap_wrapper)       /* 90 */
464         .long  SYSCALL(sys_munmap,sys32_munmap_wrapper)
465         .long  SYSCALL(sys_truncate,sys32_truncate_wrapper)
466         .long  SYSCALL(sys_ftruncate,sys32_ftruncate_wrapper)
467         .long  SYSCALL(sys_fchmod,sys32_fchmod_wrapper)
468         .long  SYSCALL(sys_ni_syscall,sys32_fchown16_wrapper)   /* old fchown16 syscall*/
469         .long  SYSCALL(sys_getpriority,sys32_getpriority_wrapper)
470         .long  SYSCALL(sys_setpriority,sys32_setpriority_wrapper)
471         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old profil syscall */
472         .long  SYSCALL(sys_statfs,sys32_statfs_wrapper)
473         .long  SYSCALL(sys_fstatfs,sys32_fstatfs_wrapper)   /* 100 */
474         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
475         .long  SYSCALL(sys_socketcall,sys32_socketcall_wrapper)
476         .long  SYSCALL(sys_syslog,sys32_syslog_wrapper)
477         .long  SYSCALL(sys_setitimer,sys32_setitimer_wrapper)
478         .long  SYSCALL(sys_getitimer,sys32_getitimer_wrapper)   /* 105 */
479         .long  SYSCALL(sys_newstat,sys32_newstat_wrapper)
480         .long  SYSCALL(sys_newlstat,sys32_newlstat_wrapper)
481         .long  SYSCALL(sys_newfstat,sys32_newfstat_wrapper)
482         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old uname syscall */
483         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* iopl for i386 */
484         .long  SYSCALL(sys_vhangup,sys_vhangup)
485         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old "idle" system call */
486         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* vm86old for i386 */
487         .long  SYSCALL(sys_wait4,sys32_wait4_wrapper)
488         .long  SYSCALL(sys_swapoff,sys32_swapoff_wrapper)       /* 115 */
489         .long  SYSCALL(sys_sysinfo,sys32_sysinfo_wrapper)
490         .long  SYSCALL(sys_ipc,sys32_ipc_wrapper)
491         .long  SYSCALL(sys_fsync,sys32_fsync_wrapper)
492         .long  SYSCALL(sys_sigreturn_glue,sys32_sigreturn_glue)
493         .long  SYSCALL(sys_clone_glue,sys_clone_glue) /* 120 */
494         .long  SYSCALL(sys_setdomainname,sys32_setdomainname_wrapper)
495         .long  SYSCALL(sys_newuname,sys32_newuname_wrapper)
496         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* modify_ldt for i386 */
497         .long  SYSCALL(sys_adjtimex,sys32_adjtimex_wrapper)
498         .long  SYSCALL(sys_mprotect,sys32_mprotect_wrapper) /* 125 */
499         .long  SYSCALL(sys_sigprocmask,sys32_sigprocmask_wrapper)
500         .long  SYSCALL(sys_create_module,sys32_create_module_wrapper)
501         .long  SYSCALL(sys_init_module,sys32_init_module_wrapper)
502         .long  SYSCALL(sys_delete_module,sys32_delete_module_wrapper)
503         .long  SYSCALL(sys_get_kernel_syms,sys32_get_kernel_syms_wrapper) /* 130 */
504         .long  SYSCALL(sys_quotactl,sys32_quotactl_wrapper)
505         .long  SYSCALL(sys_getpgid,sys32_getpgid_wrapper)
506         .long  SYSCALL(sys_fchdir,sys32_fchdir_wrapper)
507         .long  SYSCALL(sys_bdflush,sys32_bdflush_wrapper)
508         .long  SYSCALL(sys_sysfs,sys32_sysfs_wrapper)           /* 135 */
509         .long  SYSCALL(sys_personality,sys32_personality_wrapper)
510         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* for afs_syscall */
511         .long  SYSCALL(sys_ni_syscall,sys32_setfsuid16_wrapper) /* old setfsuid16 syscall */
512         .long  SYSCALL(sys_ni_syscall,sys32_setfsgid16_wrapper) /* old setfsgid16 syscall */
513         .long  SYSCALL(sys_llseek,sys32_llseek_wrapper)         /* 140 */
514         .long  SYSCALL(sys_getdents,sys32_getdents_wrapper)
515         .long  SYSCALL(sys_select,sys32_select_wrapper)
516         .long  SYSCALL(sys_flock,sys32_flock_wrapper)
517         .long  SYSCALL(sys_msync,sys32_msync_wrapper)
518         .long  SYSCALL(sys_readv,sys32_readv_wrapper)           /* 145 */
519         .long  SYSCALL(sys_writev,sys32_writev_wrapper)
520         .long  SYSCALL(sys_getsid,sys32_getsid_wrapper)
521         .long  SYSCALL(sys_fdatasync,sys32_fdatasync_wrapper)
522         .long  SYSCALL(sys_sysctl,sys_ni_syscall)
523         .long  SYSCALL(sys_mlock,sys32_mlock_wrapper)           /* 150 */
524         .long  SYSCALL(sys_munlock,sys32_munlock_wrapper)
525         .long  SYSCALL(sys_mlockall,sys32_mlockall_wrapper)
526         .long  SYSCALL(sys_munlockall,sys_munlockall)
527         .long  SYSCALL(sys_sched_setparam,sys32_sched_setparam_wrapper)
528         .long  SYSCALL(sys_sched_getparam,sys32_sched_getparam_wrapper) /* 155 */
529         .long  SYSCALL(sys_sched_setscheduler,sys32_sched_setscheduler_wrapper)
530         .long  SYSCALL(sys_sched_getscheduler,sys32_sched_getscheduler_wrapper)
531         .long  SYSCALL(sys_sched_yield,sys_sched_yield)
532         .long  SYSCALL(sys_sched_get_priority_max,sys32_sched_get_priority_max_wrapper)
533         .long  SYSCALL(sys_sched_get_priority_min,sys32_sched_get_priority_min_wrapper)
534         .long  SYSCALL(sys_sched_rr_get_interval,sys32_sched_rr_get_interval_wrapper)
535         .long  SYSCALL(sys_nanosleep,sys32_nanosleep_wrapper)
536         .long  SYSCALL(sys_mremap,sys32_mremap_wrapper)
537         .long  SYSCALL(sys_ni_syscall,sys32_setresuid16_wrapper) /* old setresuid16 syscall */
538         .long  SYSCALL(sys_ni_syscall,sys32_getresuid16_wrapper) /* old getresuid16 syscall */
539         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* for vm86 */
540         .long  SYSCALL(sys_query_module,sys32_query_module_wrapper)
541         .long  SYSCALL(sys_poll,sys32_poll_wrapper)
542         .long  SYSCALL(sys_nfsservctl,sys32_nfsservctl_wrapper)
543         .long  SYSCALL(sys_ni_syscall,sys32_setresgid16_wrapper) /* old setresgid16 syscall */
544         .long  SYSCALL(sys_ni_syscall,sys32_getresgid16_wrapper) /* old getresgid16 syscall */
545         .long  SYSCALL(sys_prctl,sys32_prctl_wrapper)
546         .long  SYSCALL(sys_rt_sigreturn_glue,sys32_rt_sigreturn_glue)
547         .long  SYSCALL(sys_rt_sigaction,sys32_rt_sigaction_wrapper)
548         .long  SYSCALL(sys_rt_sigprocmask,sys32_rt_sigprocmask_wrapper) /* 175 */
549         .long  SYSCALL(sys_rt_sigpending,sys32_rt_sigpending_wrapper)
550         .long  SYSCALL(sys_rt_sigtimedwait,sys32_rt_sigtimedwait_wrapper)
551         .long  SYSCALL(sys_rt_sigqueueinfo,sys32_rt_sigqueueinfo_wrapper)
552         .long  SYSCALL(sys_rt_sigsuspend_glue,sys32_rt_sigsuspend_glue)
553         .long  SYSCALL(sys_pread,sys32_pread_wrapper)           /* 180 */
554         .long  SYSCALL(sys_pwrite,sys32_pwrite_wrapper)
555         .long  SYSCALL(sys_ni_syscall,sys32_chown16_wrapper)    /* old chown16 syscall */
556         .long  SYSCALL(sys_getcwd,sys32_getcwd_wrapper)
557         .long  SYSCALL(sys_capget,sys32_capget_wrapper)
558         .long  SYSCALL(sys_capset,sys32_capset_wrapper)         /* 185 */
559         .long  SYSCALL(sys_sigaltstack_glue,sys32_sigaltstack_glue)
560         .long  SYSCALL(sys_sendfile,sys32_sendfile_wrapper)
561         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* streams1 */
562         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* streams2 */
563         .long  SYSCALL(sys_vfork_glue,sys_vfork_glue) /* 190 */
564         .long  SYSCALL(sys_getrlimit,sys32_old_getrlimit_wrapper)
565         .long  SYSCALL(sys_mmap2,sys32_mmap2_wrapper)
566         .long  SYSCALL(sys_ni_syscall,sys32_truncate64_wrapper)
567         .long  SYSCALL(sys_ni_syscall,sys32_ftruncate64_wrapper)
568         .long  SYSCALL(sys_ni_syscall,sys32_stat64)     /* 195 */
569         .long  SYSCALL(sys_ni_syscall,sys32_lstat64)   
570         .long  SYSCALL(sys_ni_syscall,sys32_fstat64)    
571         .long  SYSCALL(sys_lchown,sys32_lchown_wrapper)
572         .long  SYSCALL(sys_getuid,sys_getuid)
573         .long  SYSCALL(sys_getgid,sys_getgid)         /* 200 */
574         .long  SYSCALL(sys_geteuid,sys_geteuid)
575         .long  SYSCALL(sys_getegid,sys_getegid)
576         .long  SYSCALL(sys_setreuid,sys32_setreuid_wrapper)
577         .long  SYSCALL(sys_setregid,sys32_setregid_wrapper)
578         .long  SYSCALL(sys_getgroups,sys32_getgroups_wrapper)  /* 205 */
579         .long  SYSCALL(sys_setgroups,sys32_setgroups_wrapper)
580         .long  SYSCALL(sys_fchown,sys32_fchown_wrapper)
581         .long  SYSCALL(sys_setresuid,sys32_setresuid_wrapper)
582         .long  SYSCALL(sys_getresuid,sys32_getresuid_wrapper)
583         .long  SYSCALL(sys_setresgid,sys32_setresgid_wrapper)  /* 210 */
584         .long  SYSCALL(sys_getresgid,sys32_getresgid_wrapper)
585         .long  SYSCALL(sys_chown,sys32_chown_wrapper)
586         .long  SYSCALL(sys_setuid,sys32_setuid_wrapper)
587         .long  SYSCALL(sys_setgid,sys32_setgid_wrapper)
588         .long  SYSCALL(sys_setfsuid,sys32_setfsuid_wrapper)   /* 215 */
589         .long  SYSCALL(sys_setfsgid,sys32_setfsgid_wrapper)
590         .long  SYSCALL(sys_pivot_root,sys32_pivot_root_wrapper)
591         .long  SYSCALL(sys_mincore,sys32_mincore_wrapper)
592         .long  SYSCALL(sys_madvise,sys32_madvise_wrapper)
593         .long  SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
594         .long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
595         .rept  255-221
596         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
597         .endr
598
599 /*
600  * Program check handler routine
601  */
602
603         .globl  pgm_check_handler
604 pgm_check_handler:
605 /*
606  * First we need to check for a special case:
607  * Single stepping an instruction that disables the PER event mask will
608  * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
609  * For a single stepped SVC the program check handler gets control after
610  * the SVC new PSW has been loaded. But we want to execute the SVC first and
611  * then handle the PER event. Therefore we update the SVC old PSW to point
612  * to the pgm_check_handler and branch to the SVC handler after we checked
613  * if we have to load the kernel stack register.
614  * For every other possible cause for PER event without the PER mask set
615  * we just ignore the PER event (FIXME: is there anything we have to do
616  * for LPSW?).
617  */
618         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
619         jz      pgm_sv                   # skip if not
620         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
621         jnz     pgm_sv                   # skip if it is
622 # ok its one of the special cases, now we need to find out which one
623         clc     __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
624         je      pgm_svcper
625 # no interesting special case, ignore PER event
626         lpswe   __LC_PGM_OLD_PSW
627 # it was a single stepped SVC that is causing all the trouble
628 pgm_svcper:
629         SAVE_ALL __LC_SVC_OLD_PSW
630         mvc     SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
631         j       pgm_system_call          # now do the svc
632 pgm_svcret:
633         lhi     %r0,__LC_PGM_OLD_PSW     # set trap indication back to pgm_chk
634         st      %r0,SP_TRAP(%r15)
635         llgh    %r7,SP_PGM_OLD_ILC(%r15) # get ilc from stack
636         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
637         j       pgm_no_sv
638 pgm_sv:
639         SAVE_ALL __LC_PGM_OLD_PSW
640         mvi     SP_PGM_OLD_ILC(%r15),1   # mark PGM_OLD_ILC as invalid
641         llgh    %r7,__LC_PGM_ILC         # load instruction length
642         GET_CURRENT
643 pgm_no_sv:
644         llgh    %r8,__LC_PGM_INT_CODE  # N.B. saved int code used later KEEP it
645         stosm   48(%r15),0x03     # reenable interrupts
646         lghi    %r3,0x7f
647         nr      %r3,%r8           # clear per-event-bit & move to r3
648         je      pgm_dn            # none of Martins exceptions occurred bypass
649         sll     %r3,3
650         larl    %r1,pgm_check_table
651         lg      %r1,0(%r3,%r1)    # load address of handler routine
652         srl     %r3,3
653         la      %r2,SP_PTREGS(%r15) # address of register-save area
654         chi     %r3,0x4           # protection-exception ?
655         jne     pgm_go            # if not,
656         lg      %r5,SP_PSW+8(15)  # load psw addr
657         slgr    %r5,%r7           # substract ilc from psw
658         stg     %r5,SP_PSW+8(15)  # store corrected psw addr
659 pgm_go: basr    %r14,%r1          # branch to interrupt-handler
660 pgm_dn: nill    %r8,0x80          # check for per exception
661         je      sysc_return
662         la      %r2,SP_PTREGS(15) # address of register-save area
663         larl    %r14,sysc_return  # load adr. of system return
664         jg      handle_per_exception
665
666 /*
667  * IO interrupt handler routine
668  */
669         .globl io_int_handler
670 io_int_handler:
671         SAVE_ALL __LC_IO_OLD_PSW
672         GET_CURRENT                    # load pointer to task_struct to R9
673         la      %r2,SP_PTREGS(%r15)    # address of register-save area
674         llgh    %r3,__LC_SUBCHANNEL_NR # load subchannel number
675         llgf    %r4,__LC_IO_INT_PARM   # load interuption parm
676         llgf    %r5,__LC_IO_INT_WORD   # load interuption word
677         brasl   %r14,do_IRQ            # call standard irq handler
678
679 io_return:
680 #
681 # check, if bottom-half has to be done
682 #
683         lgf     %r1,processor(%r9)    # get cpu number from task struture
684         larl    %r2,irq_stat
685         sll     %r1,L1_CACHE_SHIFT
686         la      %r1,0(%r1,%r2)
687         icm     %r0,15,0(%r1)         # test irq_stat[#cpu].__softirq_pending
688         jnz     io_handle_bottom_half
689 io_return_bh:   
690
691         tm      SP_PSW+1(%r15),0x01    # returning to user ?
692         jno     io_leave               # no-> skip resched & signal
693         stosm   48(%r15),0x03          # reenable interrupts
694 #
695 # check, if reschedule is needed
696 #
697         lg      %r0,need_resched(%r9)  # get need_resched from task_struct
698         ltgr    %r0,%r0
699         jnz     io_reschedule
700         icm     %r0,15,sigpending(%r9) # get sigpending from task_struct
701         jnz     io_signal_return
702 io_leave:
703         stnsm   48(%r15),0xfc          # disable I/O and ext. interrupts
704         RESTORE_ALL
705
706 #
707 # call do_softirq and return from syscall, if interrupt-level
708 # is zero
709 #
710 io_handle_bottom_half:        
711         larl    %r14,io_return_bh
712         jg      do_softirq          # return point is io_return_bh
713
714 #
715 # call schedule with io_return as return-address
716 #
717 io_reschedule:        
718         larl    %r14,io_return
719         jg      schedule            # call scheduler, return to io_return
720
721 #
722 # call do_signal before return
723 #
724 io_signal_return:     
725         la      %r2,SP_PTREGS(%r15) # load pt_regs
726         slgr    %r3,%r3             # clear *oldset
727         larl    %r14,io_leave
728         jg      do_signal           # return point is io_leave
729
730 /*
731  * External interrupt handler routine
732  */
733         .globl  ext_int_handler
734 ext_int_handler:
735         SAVE_ALL __LC_EXT_OLD_PSW
736         GET_CURRENT                    # load pointer to task_struct to R9
737         la      %r2,SP_PTREGS(%r15)    # address of register-save area
738         llgh    %r3,__LC_EXT_INT_CODE  # error code
739         lgr     %r1,%r3                # calculate index = code & 0xff
740         nill    %r1,0xff
741         sll     %r1,3
742         larl    %r4,ext_int_hash
743         lg      %r4,0(%r1,%r4)         # get first list entry for hash value
744         ltgr    %r4,%r4                # == NULL ?
745         jz      io_return              # yes, nothing to do, exit
746 ext_int_loop:
747         ch      %r3,16(%r4)            # compare external interrupt code
748         je      ext_int_found
749         lg      %r4,0(%r4)             # next list entry
750         ltgr    %r4,%r4
751         jnz     ext_int_loop
752         j       io_return
753 ext_int_found:
754         lg      %r4,8(%r4)             # get handler address
755         larl    %r14,io_return
756         br      %r4                    # branch to ext call handler
757
758 /*
759  * Machine check handler routines
760  */
761         .globl mcck_int_handler
762 mcck_int_handler:
763         SAVE_ALL __LC_MCK_OLD_PSW
764         brasl   %r14,s390_do_machine_check
765 mcck_return:
766         RESTORE_ALL
767
768 #ifdef CONFIG_SMP
769 /*
770  * Restart interruption handler, kick starter for additional CPUs
771  */
772         .globl restart_int_handler
773 restart_int_handler:
774         lg      %r15,__LC_KERNEL_STACK # load ksp
775         lhi     %r10,__LC_CREGS_SAVE_AREA
776         lctlg   %c0,%c15,0(%r10) # get new ctl regs
777         lhi     %r10,__LC_AREGS_SAVE_AREA
778         lam     %a0,%a15,0(%r10)
779         stosm   0(%r15),0x04           # now we can turn dat on
780         lmg     %r6,%r15,48(%r15)      # load registers from clone
781         jg      start_secondary
782 #else
783 /*
784  * If we do not run with SMP enabled, let the new CPU crash ...
785  */
786         .globl restart_int_handler
787 restart_int_handler:
788         basr    %r1,0
789 restart_base:
790         lpswe   restart_crash-restart_base(%r1)
791         .align 8
792 restart_crash:
793         .long  0x000a0000,0x00000000,0x00000000,0x00000000
794 restart_go:
795 #endif
796