ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / s390 / kernel / entry64.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/ptrace.h>
19 #include <asm/thread_info.h>
20 #include <asm/offsets.h>
21 #include <asm/unistd.h>
22
23 /*
24  * Stack layout for the system_call stack entry.
25  * The first few entries are identical to the user_regs_struct.
26  */
27 SP_PTREGS    =  STACK_FRAME_OVERHEAD 
28 SP_PSW       =  STACK_FRAME_OVERHEAD + __PT_PSW
29 SP_R0        =  STACK_FRAME_OVERHEAD + __PT_GPRS
30 SP_R1        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 8
31 SP_R2        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 16
32 SP_R3        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 24
33 SP_R4        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 32
34 SP_R5        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 40
35 SP_R6        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 48
36 SP_R7        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 56
37 SP_R8        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 64
38 SP_R9        =  STACK_FRAME_OVERHEAD + __PT_GPRS + 72
39 SP_R10       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 80
40 SP_R11       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 88
41 SP_R12       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 96
42 SP_R13       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 104
43 SP_R14       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 112
44 SP_R15       =  STACK_FRAME_OVERHEAD + __PT_GPRS + 120
45 SP_ORIG_R2   =  STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46 SP_ILC       =  STACK_FRAME_OVERHEAD + __PT_ILC
47 SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
48 SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
49
50 _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
51 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
52
53 /*
54  * Register usage in interrupt handlers:
55  *    R9  - pointer to current task structure
56  *    R13 - pointer to literal pool
57  *    R14 - return register for function calls
58  *    R15 - kernel stack pointer
59  */
60
61         .macro  SAVE_ALL psworg,savearea,sync
62         stmg    %r13,%r15,\savearea
63         .if     \sync
64         tm      \psworg+1,0x01           # test problem state bit
65         jz      1f                       # skip stack setup save
66         lg      %r15,__LC_KERNEL_STACK   # problem state -> load ksp
67         .else
68         tm      \psworg+1,0x01           # test problem state bit
69         jnz     0f                       # from user -> load kernel stack
70         lg      %r14,__LC_ASYNC_STACK    # are we already on the async. stack ?
71         slgr    %r14,%r15
72         srag    %r14,%r14,14
73         jz      1f
74 0:      lg      %r15,__LC_ASYNC_STACK    # load async stack
75         .endif
76 1:      aghi    %r15,-SP_SIZE            # make room for registers & psw
77         lghi    %r14,\psworg
78         slgr    %r13,%r13
79         icm     %r14,12,__LC_SVC_ILC
80         stmg    %r0,%r12,SP_R0(%r15)     # store gprs 0-13 to kernel stack
81         stg     %r2,SP_ORIG_R2(%r15)     # store original content of gpr 2
82         mvc     SP_R13(24,%r15),\savearea # move r13, r14 and r15 to stack
83         mvc     SP_PSW(16,%r15),\psworg  # move user PSW to stack
84         st      %r14,SP_ILC(%r15)
85         stg     %r13,0(%r15)
86         .endm
87
88         .macro  CLEANUP_SAVE_ALL psworg,savearea,sync
89         lg      %r1,SP_PSW+8(%r15)
90         cli     1(%r1),0xdf
91         jne     2f
92         mvc     \savearea(24),SP_R13(%r15)
93 2:      lg      %r1,\savearea+16
94         .if     \sync
95         tm      \psworg+1,0x01
96         jz      1f
97         lg      %r1,__LC_KERNEL_STACK
98         .else
99         tm      \psworg+1,0x01
100         jnz     0f
101         lg      %r0,__LC_ASYNC_STACK
102         slgr    %r0,%r1
103         srag    %r0,%r0,14
104         jz      1f
105 0:      lg      %r1,__LC_ASYNC_STACK
106         .endif
107 1:      aghi    %r1,-SP_SIZE
108         stg     %r1,SP_R15(%r15)
109         lghi    %r0,\psworg
110         xc      SP_R13(8,%r15),SP_R13(%r15)
111         icm     %r0,12,__LC_SVC_ILC
112         stg     %r0,SP_R14(%r15)
113         mvc     SP_R0(104,%r1),SP_R0(%r15)
114         mvc     SP_ORIG_R2(8,%r1),SP_R2(%r15)
115         mvc     SP_R13(24,%r1),\savearea
116         mvc     SP_PSW(16,%r1),\psworg
117         st      %r0,SP_ILC(%r1)
118         xc      0(8,%r1),0(%r1)
119         .endm
120
121         .macro  RESTORE_ALL              # system exit macro
122         mvc     __LC_RETURN_PSW(16),SP_PSW(%r15) # move user PSW to lowcore
123         ni      __LC_RETURN_PSW+1,0xfd   # clear wait state bit
124         lmg     %r0,%r15,SP_R0(%r15)     # load gprs 0-15 of user
125         lpswe   __LC_RETURN_PSW          # back to caller
126         .endm
127
128         .macro  CLEANUP_RESTORE_ALL
129         lg      %r1,SP_PSW+8(%r15)
130         cli     0(%r1),0xb2
131         jne     0f
132         mvc     SP_PSW(16,%r15),__LC_RETURN_PSW
133         j       1f
134 0:      lg      %r1,SP_R15(%r15)
135         mvc     SP_PSW(16,%r15),SP_PSW(%r1)
136         mvc     SP_R0(128,%r15),SP_R0(%r1)
137 1:
138         .endm
139
140         .macro  GET_THREAD_INFO
141         lg      %r9,__LC_THREAD_INFO     # load pointer to thread_info struct
142         .endm
143
144         .macro  CHECK_CRITICAL
145         tm      SP_PSW+1(%r15),0x01      # test problem state bit
146         jnz     0f                       # from user -> not critical
147         larl    %r1,.Lcritical_start
148         clc     SP_PSW+8(8,%r15),8(%r1)  # compare ip with __critical_end
149         jnl     0f
150         clc     SP_PSW+8(8,%r15),0(%r1)  # compare ip with __critical_start
151         jl      0f
152         brasl   %r14,cleanup_critical
153 0:
154         .endm
155
156 /*
157  * Scheduler resume function, called by switch_to
158  *  gpr2 = (task_struct *) prev
159  *  gpr3 = (task_struct *) next
160  * Returns:
161  *  gpr2 = prev
162  */
163         .globl  __switch_to
164 __switch_to:
165         tm      __THREAD_per+4(%r3),0xe8 # is the new process using per ?
166         jz      __switch_to_noper               # if not we're fine
167         stctg   %c9,%c11,48(%r15)       # We are using per stuff
168         clc     __THREAD_per(24,%r3),48(%r15)
169         je      __switch_to_noper            # we got away without bashing TLB's
170         lctlg   %c9,%c11,__THREAD_per(%r3)      # Nope we didn't
171 __switch_to_noper:
172         stmg    %r6,%r15,48(%r15)       # store __switch_to registers of prev task
173         stg     %r15,__THREAD_ksp(%r2)  # store kernel stack to prev->tss.ksp
174         lg      %r15,__THREAD_ksp(%r3)  # load kernel stack from next->tss.ksp
175         lmg     %r6,%r15,48(%r15)       # load __switch_to registers of next task
176         stg     %r3,__LC_CURRENT        # __LC_CURRENT = current task struct
177         lg      %r3,__THREAD_info(%r3)  # load thread_info from task struct
178         stg     %r3,__LC_THREAD_INFO
179         aghi    %r3,16384
180         stg     %r3,__LC_KERNEL_STACK   # __LC_KERNEL_STACK = new kernel stack
181         br      %r14
182
183 /*
184  * do_softirq calling function. We want to run the softirq functions on the
185  * asynchronous interrupt stack.
186  */
187         .global do_call_softirq
188 do_call_softirq:
189         stnsm   48(%r15),0xfc
190         stmg    %r12,%r15,56(%r15)
191         lgr     %r12,%r15
192         lg      %r0,__LC_ASYNC_STACK
193         slgr    %r0,%r15
194         srag    %r0,%r0,14
195         je      0f
196         lg      %r15,__LC_ASYNC_STACK
197 0:      aghi    %r15,-STACK_FRAME_OVERHEAD
198         stg     %r12,0(%r15)            # store back chain
199         brasl   %r14,do_softirq
200         lmg     %r12,%r15,56(%r12)
201         ssm     48(%r15)
202         br      %r14
203
204 __critical_start:
205 /*
206  * SVC interrupt handler routine. System calls are synchronous events and
207  * are executed with interrupts enabled.
208  */
209
210         .globl  system_call
211 system_call:
212         SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
213         llgh    %r7,__LC_SVC_INT_CODE # get svc number from lowcore
214 sysc_enter:
215         GET_THREAD_INFO           # load pointer to task_struct to R9
216         slag    %r7,%r7,2         # *4 and test for svc 0
217         jnz     sysc_do_restart
218         # svc 0: system call number in %r1
219         lghi    %r0,NR_syscalls
220         clr     %r1,%r0
221         jnl     sysc_do_restart
222         lgfr    %r7,%r1           # clear high word in r1
223         slag    %r7,%r7,2         # svc 0: system call number in %r1
224 sysc_do_restart:
225         larl    %r10,sys_call_table
226 #ifdef CONFIG_S390_SUPPORT
227         tm      SP_PSW+3(%r15),0x01  # are we running in 31 bit mode ?
228         jo      sysc_noemu
229         larl    %r10,sys_call_table_emu  # use 31 bit emulation system calls
230 sysc_noemu:
231 #endif
232         tm      __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
233         lgf     %r8,0(%r7,%r10)   # load address of system call routine
234         jo      sysc_tracesys
235         basr    %r14,%r8          # call sys_xxxx
236         stg     %r2,SP_R2(%r15)   # store return value (change R2 on stack)
237                                   # ATTENTION: check sys_execve_glue before
238                                   # changing anything here !!
239
240 sysc_return:
241         tm      SP_PSW+1(%r15),0x01    # returning to user ?
242         jno     sysc_leave
243         tm      __TI_flags+7(%r9),_TIF_WORK_SVC
244         jnz     sysc_work         # there is work to do (signals etc.)
245 sysc_leave:
246         RESTORE_ALL
247
248 #
249 # recheck if there is more work to do
250 #
251 sysc_work_loop:
252         GET_THREAD_INFO           # load pointer to task_struct to R9
253         tm      __TI_flags+7(%r9),_TIF_WORK_SVC
254         jz      sysc_leave        # there is no work to do
255 #
256 # One of the work bits is on. Find out which one.
257 # Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
258 #
259 sysc_work:
260         tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
261         jo      sysc_reschedule
262         tm      __TI_flags+7(%r9),_TIF_SIGPENDING
263         jo      sysc_sigpending
264         tm      __TI_flags+7(%r9),_TIF_RESTART_SVC
265         jo      sysc_restart
266         j       sysc_leave
267
268 #
269 # _TIF_NEED_RESCHED is set, call schedule
270 #       
271 sysc_reschedule:        
272         larl    %r14,sysc_work_loop
273         jg      schedule            # return point is sysc_return
274
275 #
276 # _TIF_SIGPENDING is set, call do_signal
277 #
278 sysc_sigpending:     
279         la      %r2,SP_PTREGS(%r15) # load pt_regs
280         sgr     %r3,%r3           # clear *oldset
281         brasl   %r14,do_signal    # call do_signal
282         tm      __TI_flags+7(%r9),_TIF_RESTART_SVC
283         jo      sysc_restart
284         j       sysc_leave        # out of here, do NOT recheck
285
286 #
287 # _TIF_RESTART_SVC is set, set up registers and restart svc
288 #
289 sysc_restart:
290         ni      __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
291         lg      %r7,SP_R2(%r15)        # load new svc number
292         slag    %r7,%r7,2              # *4
293         mvc     SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument
294         lmg     %r2,%r6,SP_R2(%r15)    # load svc arguments
295         j       sysc_do_restart        # restart svc
296
297 __critical_end:
298
299 #
300 # call syscall_trace before and after system call
301 # special linkage: %r12 contains the return address for trace_svc
302 #
303 sysc_tracesys:
304         la      %r2,SP_PTREGS(%r15)    # load pt_regs
305         la      %r3,0
306         srl     %r7,2
307         stg     %r7,SP_R2(%r15)
308         brasl   %r14,syscall_trace
309         lghi    %r0,NR_syscalls
310         clg     %r0,SP_R2(%r15)
311         jnh     sysc_tracenogo
312         lg      %r7,SP_R2(%r15)   # strace might have changed the
313         sll     %r7,2             #  system call
314         lgf     %r8,0(%r7,%r10)
315 sysc_tracego:
316         lmg     %r3,%r6,SP_R3(%r15)
317         lg      %r2,SP_ORIG_R2(%r15)
318         basr    %r14,%r8            # call sys_xxx
319         stg     %r2,SP_R2(%r15)     # store return value
320 sysc_tracenogo:
321         tm      __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
322         jno     sysc_return
323         la      %r2,SP_PTREGS(%r15)    # load pt_regs
324         la      %r3,1
325         larl    %r14,sysc_return    # return point is sysc_return
326         jg      syscall_trace
327
328 #
329 # a new process exits the kernel with ret_from_fork
330 #
331         .globl  ret_from_fork
332 ret_from_fork:  
333         GET_THREAD_INFO           # load pointer to task_struct to R9
334         brasl   %r14,schedule_tail
335         stosm   24(%r15),0x03     # reenable interrupts
336         j       sysc_return
337
338 #
339 # clone, fork, vfork, exec and sigreturn need glue,
340 # because they all expect pt_regs as parameter,
341 # but are called with different parameter.
342 # return-address is set up above
343 #
344 sys_clone_glue: 
345         la      %r2,SP_PTREGS(%r15)    # load pt_regs
346         jg      sys_clone              # branch to sys_clone
347
348 #ifdef CONFIG_S390_SUPPORT
349 sys32_clone_glue: 
350         la      %r2,SP_PTREGS(%r15)    # load pt_regs
351         jg      sys32_clone            # branch to sys32_clone
352 #endif
353
354 sys_fork_glue:  
355         la      %r2,SP_PTREGS(%r15)    # load pt_regs
356         jg      sys_fork               # branch to sys_fork
357
358 sys_vfork_glue: 
359         la      %r2,SP_PTREGS(%r15)    # load pt_regs
360         jg      sys_vfork              # branch to sys_vfork
361
362 sys_execve_glue:        
363         la      %r2,SP_PTREGS(%r15)   # load pt_regs
364         lgr     %r12,%r14             # save return address
365         brasl   %r14,sys_execve       # call sys_execve
366         ltgr    %r2,%r2               # check if execve failed
367         bnz     0(%r12)               # it did fail -> store result in gpr2
368         b       6(%r12)               # SKIP STG 2,SP_R2(15) in
369                                       # system_call/sysc_tracesys
370 #ifdef CONFIG_S390_SUPPORT
371 sys32_execve_glue:        
372         la      %r2,SP_PTREGS(%r15)   # load pt_regs
373         lgr     %r12,%r14             # save return address
374         brasl   %r14,sys32_execve     # call sys32_execve
375         ltgr    %r2,%r2               # check if execve failed
376         bnz     0(%r12)               # it did fail -> store result in gpr2
377         b       6(%r12)               # SKIP STG 2,SP_R2(15) in
378                                       # system_call/sysc_tracesys
379 #endif
380
381 sys_sigreturn_glue:     
382         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
383         jg      sys_sigreturn         # branch to sys_sigreturn
384
385 #ifdef CONFIG_S390_SUPPORT
386 sys32_sigreturn_glue:     
387         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
388         jg      sys32_sigreturn       # branch to sys32_sigreturn
389 #endif
390
391 sys_rt_sigreturn_glue:     
392         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
393         jg      sys_rt_sigreturn      # branch to sys_sigreturn
394
395 #ifdef CONFIG_S390_SUPPORT
396 sys32_rt_sigreturn_glue:     
397         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
398         jg      sys32_rt_sigreturn    # branch to sys32_sigreturn
399 #endif
400
401 #
402 # sigsuspend and rt_sigsuspend need pt_regs as an additional
403 # parameter and they have to skip the store of %r2 into the
404 # user register %r2 because the return value was set in 
405 # sigsuspend and rt_sigsuspend already and must not be overwritten!
406 #
407
408 sys_sigsuspend_glue:    
409         lgr     %r5,%r4               # move mask back
410         lgr     %r4,%r3               # move history1 parameter
411         lgr     %r3,%r2               # move history0 parameter
412         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
413         la      %r14,6(%r14)          # skip store of return value
414         jg      sys_sigsuspend        # branch to sys_sigsuspend
415
416 #ifdef CONFIG_S390_SUPPORT
417 sys32_sigsuspend_glue:    
418         llgfr   %r4,%r4               # unsigned long                   
419         lgr     %r5,%r4               # move mask back
420         lgfr    %r3,%r3               # int                     
421         lgr     %r4,%r3               # move history1 parameter
422         lgfr    %r2,%r2               # int                     
423         lgr     %r3,%r2               # move history0 parameter
424         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
425         la      %r14,6(%r14)          # skip store of return value
426         jg      sys32_sigsuspend      # branch to sys32_sigsuspend
427 #endif
428
429 sys_rt_sigsuspend_glue: 
430         lgr     %r4,%r3               # move sigsetsize parameter
431         lgr     %r3,%r2               # move unewset parameter
432         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
433         la      %r14,6(%r14)          # skip store of return value
434         jg      sys_rt_sigsuspend     # branch to sys_rt_sigsuspend
435
436 #ifdef CONFIG_S390_SUPPORT
437 sys32_rt_sigsuspend_glue: 
438         llgfr   %r3,%r3               # size_t                  
439         lgr     %r4,%r3               # move sigsetsize parameter
440         llgtr   %r2,%r2               # sigset_emu31_t *
441         lgr     %r3,%r2               # move unewset parameter
442         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
443         la      %r14,6(%r14)          # skip store of return value
444         jg      sys32_rt_sigsuspend   # branch to sys32_rt_sigsuspend
445 #endif
446
447 sys_sigaltstack_glue:
448         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
449         jg      sys_sigaltstack       # branch to sys_sigreturn
450
451 #ifdef CONFIG_S390_SUPPORT
452 sys32_sigaltstack_glue:
453         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
454         jg      sys32_sigaltstack_wrapper # branch to sys_sigreturn
455 #endif
456
457 /*
458  * Program check handler routine
459  */
460
461         .globl  pgm_check_handler
462 pgm_check_handler:
463 /*
464  * First we need to check for a special case:
465  * Single stepping an instruction that disables the PER event mask will
466  * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
467  * For a single stepped SVC the program check handler gets control after
468  * the SVC new PSW has been loaded. But we want to execute the SVC first and
469  * then handle the PER event. Therefore we update the SVC old PSW to point
470  * to the pgm_check_handler and branch to the SVC handler after we checked
471  * if we have to load the kernel stack register.
472  * For every other possible cause for PER event without the PER mask set
473  * we just ignore the PER event (FIXME: is there anything we have to do
474  * for LPSW?).
475  */
476         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
477         jnz     pgm_per                  # got per exception -> special case
478         SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
479         lgf     %r3,__LC_PGM_ILC         # load program interruption code
480         lghi    %r8,0x7f
481         ngr     %r8,%r3
482         sll     %r8,3
483         GET_THREAD_INFO
484         larl    %r1,pgm_check_table
485         lg      %r1,0(%r8,%r1)           # load address of handler routine
486         la      %r2,SP_PTREGS(%r15)      # address of register-save area
487         larl    %r14,sysc_return
488         br      %r1                      # branch to interrupt-handler
489
490 #
491 # handle per exception
492 #
493 pgm_per:
494         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
495         jnz     pgm_per_std              # ok, normal per event from user space
496 # ok its one of the special cases, now we need to find out which one
497         clc     __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
498         je      pgm_svcper
499 # no interesting special case, ignore PER event
500         lpswe   __LC_PGM_OLD_PSW
501
502 #
503 # Normal per exception
504 #
505 pgm_per_std:
506         SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
507         GET_THREAD_INFO
508         mvc     __THREAD_per+__PER_atmid(2,%r9),__LC_PER_ATMID
509         mvc     __THREAD_per+__PER_address(8,%r9),__LC_PER_ADDRESS
510         mvc     __THREAD_per+__PER_access_id(1,%r9),__LC_PER_ACCESS_ID
511         lghi    %r4,0x7f
512         lgf     %r3,__LC_PGM_ILC         # load program interruption code
513         nr      %r4,%r3                  # clear per-event-bit and ilc
514         je      pgm_per_only             # only per of per+check ?
515         sll     %r4,3
516         larl    %r1,pgm_check_table
517         lg      %r1,0(%r4,%r1)           # load address of handler routine
518         la      %r2,SP_PTREGS(%r15)      # address of register-save area
519         basr    %r14,%r1                 # branch to interrupt-handler
520 pgm_per_only:
521         la      %r2,SP_PTREGS(15)        # address of register-save area
522         larl    %r14,sysc_return         # load adr. of system return
523         jg      do_debugger_trap
524
525 #
526 # it was a single stepped SVC that is causing all the trouble
527 #
528 pgm_svcper:
529         SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
530         llgh    %r7,__LC_SVC_INT_CODE # get svc number from lowcore
531         stosm   48(%r15),0x03     # reenable interrupts
532         GET_THREAD_INFO           # load pointer to task_struct to R9
533         mvc     __THREAD_per+__PER_atmid(2,%r9),__LC_PER_ATMID
534         mvc     __THREAD_per+__PER_address(8,%r9),__LC_PER_ADDRESS
535         mvc     __THREAD_per+__PER_access_id(1,%r9),__LC_PER_ACCESS_ID
536         slag    %r7,%r7,2         # *4 and test for svc 0
537         jnz     pgm_svcstd
538         # svc 0: system call number in %r1
539         lghi    %r0,NR_syscalls
540         clr     %r1,%r0
541         slag    %r7,%r1,2
542 pgm_svcstd:
543         larl    %r10,sys_call_table
544 #ifdef CONFIG_S390_SUPPORT
545         tm      SP_PSW+3(%r15),0x01  # are we running in 31 bit mode ?
546         jo      pgm_svcper_noemu
547         larl    %r10,sys_call_table_emu # use 31 bit emulation system calls
548 pgm_svcper_noemu:
549 #endif
550         tm      __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
551         lgf     %r8,0(%r7,%r10)   # load address of system call routine
552         jo      pgm_tracesys
553         basr    %r14,%r8          # call sys_xxxx
554         stg     %r2,SP_R2(%r15)   # store return value (change R2 on stack)
555                                   # ATTENTION: check sys_execve_glue before
556                                   # changing anything here !!
557
558 pgm_svcret:
559         tm      __TI_flags+7(%r9),_TIF_SIGPENDING
560         jno     pgm_svcper_nosig
561         la      %r2,SP_PTREGS(%r15) # load pt_regs
562         sgr     %r3,%r3             # clear *oldset
563         brasl   %r14,do_signal
564         
565 pgm_svcper_nosig:
566         lhi     %r0,__LC_PGM_OLD_PSW     # set trap indication back to pgm_chk
567         st      %r0,SP_TRAP(%r15)
568         la      %r2,SP_PTREGS(15) # address of register-save area
569         larl    %r14,sysc_return  # load adr. of system return
570         jg      do_debugger_trap
571 #
572 # call trace before and after sys_call
573 #
574 pgm_tracesys:
575         la      %r2,SP_PTREGS(%r15)    # load pt_regs
576         la      %r3,0
577         srlg    %r7,%r7,2
578         stg     %r7,SP_R2(%r15)
579         brasl   %r14,syscall_trace
580         lghi    %r0,NR_syscalls
581         clg     %r0,SP_R2(%r15)
582         jnh     pgm_svc_nogo
583         lg      %r7,SP_R2(%r15)
584         sllg    %r7,%r7,2           # strace wants to change the syscall
585         lgf     %r8,0(%r7,%r10)
586 pgm_svc_go:
587         lmg     %r3,%r6,SP_R3(%r15)
588         lg      %r2,SP_ORIG_R2(%r15)
589         basr    %r14,%r8            # call sys_xxx
590         stg     %r2,SP_R2(%r15)     # store return value
591 pgm_svc_nogo:
592         tm      __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
593         jno     pgm_svcret
594         la      %r2,SP_PTREGS(%r15)    # load pt_regs
595         la      %r3,1
596         larl    %r14,pgm_svcret     # return point is sysc_return
597         jg      syscall_trace
598
599 /*
600  * IO interrupt handler routine
601  */
602         .globl io_int_handler
603 io_int_handler:
604         SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0
605         stck    __LC_INT_CLOCK
606         CHECK_CRITICAL
607         GET_THREAD_INFO                # load pointer to task_struct to R9
608         la      %r2,SP_PTREGS(%r15)    # address of register-save area
609         brasl   %r14,do_IRQ            # call standard irq handler
610
611 io_return:
612         tm      SP_PSW+1(%r15),0x01    # returning to user ?
613 #ifdef CONFIG_PREEMPT
614         jno     io_preempt             # no -> check for preemptive scheduling
615 #else
616         jno     io_leave               # no-> skip resched & signal
617 #endif
618         tm      __TI_flags+7(%r9),_TIF_WORK_INT
619         jnz     io_work                # there is work to do (signals etc.)
620 io_leave:
621         RESTORE_ALL
622
623 #ifdef CONFIG_PREEMPT
624 io_preempt:
625         icm     %r0,15,__TI_precount(%r9)       
626         jnz     io_leave
627         # switch to kernel stack
628         lg      %r1,SP_R15(%r15)
629         aghi    %r1,-SP_SIZE
630         mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
631         xc      0(8,%r1),0(%r1)        # clear back chain
632         lgr     %r15,%r1
633 io_resume_loop:
634         tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
635         jno     io_leave
636         larl    %r1,.Lc_pactive
637         mvc     __TI_precount(4,%r9),0(%r1)
638         stosm   48(%r15),0x03          # reenable interrupts
639         brasl   %r14,schedule          # call schedule
640         stnsm   48(%r15),0xfc          # disable I/O and ext. interrupts
641         GET_THREAD_INFO                # load pointer to task_struct to R9
642         xc      __TI_precount(4,%r9),__TI_precount(%r9)
643         j       io_resume_loop
644 #endif
645
646 #
647 # switch to kernel stack, then check TIF bits
648 #
649 io_work:
650         lg      %r1,__LC_KERNEL_STACK
651         aghi    %r1,-SP_SIZE
652         mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
653         xc      0(8,%r1),0(%r1)        # clear back chain
654         lgr     %r15,%r1
655 #
656 # One of the work bits is on. Find out which one.
657 # Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
658 #
659 io_work_loop:
660         tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
661         jo      io_reschedule
662         tm      __TI_flags+7(%r9),_TIF_SIGPENDING
663         jo      io_sigpending
664         j       io_leave
665
666 #
667 # _TIF_NEED_RESCHED is set, call schedule
668 #       
669 io_reschedule:        
670         stosm   48(%r15),0x03       # reenable interrupts
671         brasl   %r14,schedule       # call scheduler
672         stnsm   48(%r15),0xfc       # disable I/O and ext. interrupts
673         GET_THREAD_INFO             # load pointer to task_struct to R9
674         tm      __TI_flags+7(%r9),_TIF_WORK_INT
675         jz      io_leave               # there is no work to do
676         j       io_work_loop
677
678 #
679 # _TIF_SIGPENDING is set, call do_signal
680 #
681 io_sigpending:     
682         stosm   48(%r15),0x03       # reenable interrupts
683         la      %r2,SP_PTREGS(%r15) # load pt_regs
684         slgr    %r3,%r3             # clear *oldset
685         brasl   %r14,do_signal      # call do_signal
686         stnsm   48(%r15),0xfc       # disable I/O and ext. interrupts
687         j       sysc_leave          # out of here, do NOT recheck
688
689 /*
690  * External interrupt handler routine
691  */
692         .globl  ext_int_handler
693 ext_int_handler:
694         SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0
695         CHECK_CRITICAL
696         GET_THREAD_INFO                # load pointer to task_struct to R9
697         stck    __LC_INT_CLOCK
698         la      %r2,SP_PTREGS(%r15)    # address of register-save area
699         llgh    %r3,__LC_EXT_INT_CODE  # get interruption code
700         brasl   %r14,do_extint
701         j       io_return
702
703 /*
704  * Machine check handler routines
705  */
706         .globl mcck_int_handler
707 mcck_int_handler:
708         SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64,0
709         brasl   %r14,s390_do_machine_check
710 mcck_return:
711         RESTORE_ALL
712
713 #ifdef CONFIG_SMP
714 /*
715  * Restart interruption handler, kick starter for additional CPUs
716  */
717         .globl restart_int_handler
718 restart_int_handler:
719         lg      %r15,__LC_SAVE_AREA+120 # load ksp
720         lghi    %r10,__LC_CREGS_SAVE_AREA
721         lctlg   %c0,%c15,0(%r10) # get new ctl regs
722         lghi    %r10,__LC_AREGS_SAVE_AREA
723         lam     %a0,%a15,0(%r10)
724         stosm   0(%r15),0x04           # now we can turn dat on
725         lmg     %r6,%r15,48(%r15)      # load registers from clone
726         jg      start_secondary
727 #else
728 /*
729  * If we do not run with SMP enabled, let the new CPU crash ...
730  */
731         .globl restart_int_handler
732 restart_int_handler:
733         basr    %r1,0
734 restart_base:
735         lpswe   restart_crash-restart_base(%r1)
736         .align 8
737 restart_crash:
738         .long  0x000a0000,0x00000000,0x00000000,0x00000000
739 restart_go:
740 #endif
741
742 cleanup_table:
743         .quad   system_call, sysc_enter, cleanup_sysc_enter
744         .quad   sysc_return, sysc_leave, cleanup_sysc_return
745         .quad   sysc_leave, sysc_work_loop, cleanup_sysc_leave
746         .quad   sysc_work_loop, sysc_reschedule, cleanup_sysc_return
747 cleanup_table_entries=(.-cleanup_table) / 24
748
749 cleanup_critical:
750         lghi    %r0,cleanup_table_entries
751         larl    %r1,cleanup_table
752         lg      %r2,SP_PSW+8(%r15)
753 cleanup_loop:
754         clg     %r2,0(%r1)
755         jl      cleanup_cont
756         clg     %r2,8(%r1)
757         jl      cleanup_found
758 cleanup_cont:
759         la      %r1,24(%r1)
760         brct    %r0,cleanup_loop
761         br      %r14
762 cleanup_found:
763         lg      %r1,16(%r1)
764         br      %r1
765
766 cleanup_sysc_enter:
767         CLEANUP_SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
768         llgh    %r0,0x8a
769         stg     %r0,SP_R7(%r15)
770         larl    %r1,sysc_enter
771         stg     %r1,SP_PSW+8(%r15)
772         br      %r14
773
774 cleanup_sysc_return:
775         larl    %r1,sysc_return
776         stg     %r1,SP_PSW+8(%r15)
777         br      %r14
778
779 cleanup_sysc_leave:
780         CLEANUP_RESTORE_ALL
781         br      %r14
782
783 /*
784  * Integer constants
785  */
786                .align 4
787 .Lconst:
788 .Lc_pactive:   .long  PREEMPT_ACTIVE
789 .Lcritical_start:
790                .quad  __critical_start
791 .Lcritical_end:
792                .quad  __critical_end
793
794 #define SYSCALL(esa,esame,emu)  .long esame
795         .globl  sys_call_table
796 sys_call_table:
797 #include "syscalls.S"
798 #undef SYSCALL
799
800 #ifdef CONFIG_S390_SUPPORT
801
802 #define SYSCALL(esa,esame,emu)  .long emu
803         .globl  sys_call_table_emu
804 sys_call_table_emu:
805 #include "syscalls.S"
806 #undef SYSCALL
807 #endif