entry.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:36k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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