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