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