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

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.  * Base Address of this Module --- saved in __LC_ENTRY_BASE
  49.  */
  50.        .globl entry_base
  51. entry_base:
  52. #define BASED(name) name-entry_base(%r13)
  53. /*
  54.  * Register usage in interrupt handlers:
  55.  *    R9  - pointer to current task structure
  56.  *    R13 - pointer to literal pool
  57.  *    R14 - return register for function calls
  58.  *    R15 - kernel stack pointer
  59.  */
  60.         .macro  SAVE_ALL_BASE
  61.         stm     %r13,%r15,__LC_SAVE_AREA
  62.         basr    %r13,0                    #  temp base pointer
  63. 0: stam    %a2,%a4,__LC_SAVE_AREA+12
  64.         l       %r13,.Lentry_base-0b(%r13)# load &entry_base to %r13
  65. .endm
  66.         .macro  SAVE_ALL psworg,sync      # system entry macro
  67.         tm      psworg+1,0x01            # test problem state bit
  68. .if sync
  69.         bz      BASED(1f)                 # skip stack setup save
  70. .else
  71.         bnz     BASED(0f)                 # from user -> load kernel stack
  72. l %r14,__LC_ASYNC_STACK   # are we already on the async stack ?
  73. slr     %r14,%r15
  74. sra %r14,13
  75. be BASED(1f)
  76.         l       %r15,__LC_ASYNC_STACK     # load async. stack
  77. b BASED(1f)
  78. .endif
  79. 0:      l       %r15,__LC_KERNEL_STACK    # problem state -> load ksp
  80. lam %a2,%a4,BASED(.Lc_ac)   # set ac.reg. 2 to primary space
  81.   # and ac.reg. 4 to home space
  82. 1:      s       %r15,BASED(.Lc_spsize)    # make room for registers & psw
  83.         n       %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
  84.         stm     %r0,%r12,SP_R0(%r15)      # store gprs 0-12 to kernel stack
  85.         st      %r2,SP_ORIG_R2(%r15)      # store original content of gpr 2
  86.         mvc     SP_R13(12,%r15),__LC_SAVE_AREA  # move R13-R15 to stack
  87.         stam    %a0,%a15,SP_AREGS(%r15)   # store access registers to kst.
  88.         mvc     SP_AREGS+8(12,%r15),__LC_SAVE_AREA+12 # store ac. regs
  89.         mvc     SP_PSW(8,%r15),psworg    # move user PSW to stack
  90.         la      %r0,psworg               # store trap indication
  91.         st      %r0,SP_TRAP(%r15)
  92.         xc      0(4,%r15),0(%r15)         # clear back chain
  93.         .endm
  94.         .macro  RESTORE_ALL sync          # system exit macro
  95.         mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)  # move user PSW to lowcore
  96.         lam     %a0,%a15,SP_AREGS(%r15)   # load the access registers
  97.         lm      %r0,%r15,SP_R0(%r15)      # load gprs 0-15 of user
  98.         ni      __LC_RETURN_PSW+1,0xfd    # clear wait state bit
  99.         lpsw    __LC_RETURN_PSW           # back to caller
  100.         .endm
  101.         .macro  GET_CURRENT
  102. l %r9,BASED(.Lc0xffffe000)  # load pointer to task_struct to %r9
  103. al %r9,__LC_KERNEL_STACK
  104.         .endm
  105. /*
  106.  * Scheduler resume function, called by switch_to
  107.  *  gpr2 = (task_struct *) prev
  108.  *  gpr3 = (task_struct *) next
  109.  * Returns:
  110.  *  gpr2 = prev
  111.  */
  112.         .globl  resume
  113. resume:
  114.         basr    %r1,0
  115. resume_base:
  116. tm __THREAD_per(%r3),0xe8 # new process is using per ?
  117. bz resume_noper-resume_base(%r1) # if not we're fine
  118.         stctl   %c9,%c11,24(%r15) # We are using per stuff
  119.         clc     __THREAD_per(12,%r3),24(%r15)
  120.         be      resume_noper-resume_base(%r1) # we got away w/o bashing TLB's
  121.         lctl    %c9,%c11,__THREAD_per(%r3) # Nope we didn't
  122. resume_noper:
  123.         stm     %r6,%r15,24(%r15)       # store resume registers of prev task
  124. st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp
  125. l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp
  126. stam    %a2,%a2,__THREAD_ar2(%r2) # store kernel access reg. 2
  127. stam    %a4,%a4,__THREAD_ar4(%r2) # store kernel access reg. 4
  128. lam     %a2,%a2,__THREAD_ar2(%r3) # load kernel access reg. 2
  129. lam     %a4,%a4,__THREAD_ar4(%r3) # load kernel access reg. 4
  130. lm %r6,%r15,24(%r15) # load resume registers of next task
  131. ahi %r3,8192
  132. st %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack
  133. br %r14
  134. /*
  135.  * do_softirq calling function. We want to run the softirq functions on the
  136.  * asynchronous interrupt stack.
  137.  */
  138. .global do_call_softirq
  139. do_call_softirq:
  140. stm %r12,%r15,24(%r15)
  141. lr %r12,%r15
  142.         basr    %r13,0
  143. do_call_base:
  144. l %r0,__LC_ASYNC_STACK
  145. slr     %r0,%r15
  146. sra %r0,13
  147. be 0f-do_call_base(%r13)
  148. l %r15,__LC_ASYNC_STACK
  149. 0: sl %r15,.Lc_overhead-do_call_base(%r13)
  150.         st %r12,0(%r15) # store backchain
  151. l %r1,.Ldo_softirq-do_call_base(%r13)
  152. basr %r14,%r1
  153. lm %r12,%r15,24(%r12)
  154. br %r14
  155. /*
  156.  * SVC interrupt handler routine. System calls are synchronous events and
  157.  * are executed with interrupts enabled.
  158.  */
  159. .globl  system_call
  160. system_call:
  161. SAVE_ALL_BASE
  162.         SAVE_ALL __LC_SVC_OLD_PSW,1
  163. lh %r8,0x8a   # get svc number from lowcore
  164.         sll     %r8,2
  165.         GET_CURRENT               # load pointer to task_struct to R9
  166.         stosm   24(%r15),0x03     # reenable interrupts
  167.         l       %r8,sys_call_table-entry_base(%r8,%r13) # get system call addr.
  168.         tm      __TASK_ptrace+3(%r9),0x02 # PT_TRACESYS
  169.         bnz     BASED(sysc_tracesys)
  170.         basr    %r14,%r8          # call sys_xxxx
  171.         st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
  172.                                   # ATTENTION: check sys_execve_glue before
  173.                                   # changing anything here !!
  174. sysc_return:
  175.         tm      SP_PSW+1(%r15),0x01 # returning to user ?
  176.         bno     BASED(sysc_leave) # no-> skip resched & signal
  177. #
  178. # check, if reschedule is needed
  179. #
  180.         icm     %r0,15,__TASK_need_resched(%r9)
  181.         bnz     BASED(sysc_reschedule)
  182.         icm     %r0,15,__TASK_sigpending(%r9)
  183.         bnz     BASED(sysc_signal_return)
  184. sysc_leave:
  185. stnsm   24(%r15),0xfc     # disable I/O and ext. interrupts
  186.         RESTORE_ALL 1
  187. #
  188. # call do_signal before return
  189. #
  190. sysc_signal_return:     
  191.         la      %r2,SP_PTREGS(%r15) # load pt_regs
  192.         sr      %r3,%r3           # clear *oldset
  193.         l       %r1,BASED(.Ldo_signal)
  194. la      %r14,BASED(sysc_leave)
  195.         br      %r1               # return point is sysc_leave
  196. #
  197. # call schedule with sysc_return as return-address
  198. #
  199. sysc_reschedule:        
  200.         l       %r1,BASED(.Lschedule)
  201. la      %r14,BASED(sysc_return)
  202.         br      %r1               # call scheduler, return to sysc_return
  203. #
  204. # call trace before and after sys_call
  205. #
  206. sysc_tracesys:
  207. la %r11,BASED(sysc_return)
  208. #
  209. # call syscall_trace before and after system call
  210. # special linkage: %r11 contains the return address for trace_svc
  211. #
  212. trace_svc:
  213.         l       %r1,BASED(.Ltrace)
  214. l       %r7,BASED(.Lc_ENOSYS)
  215. st      %r7,SP_R2(%r15)   # give sysc_trace an -ENOSYS retval
  216.         basr    %r14,%r1
  217. l       %r2,SP_R2(%r15)
  218. cr      %r2,%r7   # compare with saved -ENOSYS
  219. be      BASED(trace_svc_go) # strace changed the syscall ?
  220. sll     %r2,24
  221. srl     %r2,22
  222.         l       %r8,sys_call_table-entry_base(%r2,%r13) # get system call addr.
  223. trace_svc_go:
  224. lm      %r3,%r6,SP_R3(%r15)
  225. l       %r2,SP_ORIG_R2(%r15)
  226.         basr    %r14,%r8          # call sys_xxx
  227.         st      %r2,SP_R2(%r15)   # store return value
  228.         l       %r1,BASED(.Ltrace)
  229. lr %r14,%r11   # return point is in %r11
  230.         br      %r1
  231. #
  232. # a new process exits the kernel with ret_from_fork
  233. #
  234.         .globl  ret_from_fork
  235. ret_from_fork:  
  236.         basr    %r13,0
  237.         l       %r13,.Lentry_base-.(%r13)  # setup base pointer to &entry_base
  238.         GET_CURRENT               # load pointer to task_struct to R9
  239.         stosm   24(%r15),0x03     # reenable interrupts
  240.         sr      %r0,%r0           # child returns 0
  241.         st      %r0,SP_R2(%r15)   # store return value (change R2 on stack)
  242.         l       %r1,BASED(.Lschedtail)
  243. la      %r14,BASED(sysc_return)
  244.         br      %r1               # call schedule_tail, return to sysc_return
  245. #
  246. # clone, fork, vfork, exec and sigreturn need glue,
  247. # because they all expect pt_regs as parameter,
  248. # but are called with different parameter.
  249. # return-address is set up above
  250. #
  251. sys_clone_glue: 
  252.         la      %r2,SP_PTREGS(%r15)    # load pt_regs
  253.         l       %r1,BASED(.Lclone)
  254.         br      %r1                   # branch to sys_clone
  255. sys_fork_glue:  
  256.         la      %r2,SP_PTREGS(%r15)    # load pt_regs
  257.         l       %r1,BASED(.Lfork)
  258.         br      %r1                   # branch to sys_fork
  259. sys_vfork_glue: 
  260.         la      %r2,SP_PTREGS(%r15)    # load pt_regs
  261.         l       %r1,BASED(.Lvfork)
  262.         br      %r1                   # branch to sys_vfork
  263. sys_execve_glue:        
  264.         la      %r2,SP_PTREGS(%r15)   # load pt_regs
  265.         l       %r1,BASED(.Lexecve)
  266. lr      %r12,%r14             # save return address
  267.         basr    %r14,%r1              # call sys_execve
  268.         ltr     %r2,%r2               # check if execve failed
  269.         bnz     0(%r12)               # it did fail -> store result in gpr2
  270.         b       4(%r12)               # SKIP ST 2,SP_R2(15) after BASR 14,8
  271.                                       # in system_call/sysc_tracesys
  272. sys_sigreturn_glue:     
  273.         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
  274.         l       %r1,BASED(.Lsigreturn)
  275.         br      %r1                   # branch to sys_sigreturn
  276. sys_rt_sigreturn_glue:     
  277.         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
  278.         l       %r1,BASED(.Lrt_sigreturn)
  279.         br      %r1                   # branch to sys_sigreturn
  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.         lr      %r5,%r4               # move mask back
  288.         lr      %r4,%r3               # move history1 parameter
  289.         lr      %r3,%r2               # move history0 parameter
  290.         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
  291.         l       %r1,BASED(.Lsigsuspend)
  292. la      %r14,4(%r14)          # skip store of return value
  293.         br      %r1                   # branch to sys_sigsuspend
  294. sys_rt_sigsuspend_glue: 
  295.         lr      %r4,%r3               # move sigsetsize parameter
  296.         lr      %r3,%r2               # move unewset parameter
  297.         la      %r2,SP_PTREGS(%r15)   # load pt_regs as first parameter
  298.         l       %r1,BASED(.Lrt_sigsuspend)
  299. la      %r14,4(%r14)          # skip store of return value
  300.         br      %r1                   # branch to sys_rt_sigsuspend
  301. sys_sigaltstack_glue:
  302.         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
  303.         l       %r1,BASED(.Lsigaltstack)
  304.         br      %r1                   # branch to sys_sigreturn
  305. .globl  sys_call_table
  306. sys_call_table:
  307.         .long  sys_ni_syscall            /* 0 */
  308.         .long  sys_exit
  309.         .long  sys_fork_glue
  310.         .long  sys_read
  311.         .long  sys_write
  312.         .long  sys_open                  /* 5 */
  313.         .long  sys_close
  314.         .long  sys_ni_syscall           /* old waitpid syscall holder */
  315.         .long  sys_creat
  316.         .long  sys_link
  317.         .long  sys_unlink                /* 10 */
  318.         .long  sys_execve_glue
  319.         .long  sys_chdir
  320.         .long  sys_time
  321.         .long  sys_mknod
  322.         .long  sys_chmod                /* 15 */
  323.         .long  sys_lchown16
  324.         .long  sys_ni_syscall           /* old break syscall holder */
  325.         .long  sys_ni_syscall           /* old stat syscall holder */
  326.         .long  sys_lseek
  327.         .long  sys_getpid               /* 20 */
  328.         .long  sys_mount
  329.         .long  sys_oldumount
  330.         .long  sys_setuid16
  331.         .long  sys_getuid16
  332.         .long  sys_stime                /* 25 */
  333.         .long  sys_ptrace
  334.         .long  sys_alarm
  335.         .long  sys_ni_syscall           /* old fstat syscall holder */
  336.         .long  sys_pause
  337.         .long  sys_utime                /* 30 */
  338.         .long  sys_ni_syscall           /* old stty syscall holder */
  339.         .long  sys_ni_syscall           /* old gtty syscall holder */
  340.         .long  sys_access
  341.         .long  sys_nice
  342.         .long  sys_ni_syscall           /* 35 */  /* old ftime syscall holder */
  343.         .long  sys_sync
  344.         .long  sys_kill
  345.         .long  sys_rename
  346.         .long  sys_mkdir
  347.         .long  sys_rmdir                /* 40 */
  348.         .long  sys_dup
  349.         .long  sys_pipe
  350.         .long  sys_times
  351.         .long  sys_ni_syscall           /* old prof syscall holder */
  352.         .long  sys_brk                  /* 45 */
  353.         .long  sys_setgid16
  354.         .long  sys_getgid16
  355.         .long  sys_signal
  356.         .long  sys_geteuid16
  357.         .long  sys_getegid16            /* 50 */
  358.         .long  sys_acct
  359.         .long  sys_umount
  360.         .long  sys_ni_syscall           /* old lock syscall holder */
  361.         .long  sys_ioctl
  362.         .long  sys_fcntl                /* 55 */
  363.         .long  sys_ni_syscall           /* old mpx syscall holder */
  364.         .long  sys_setpgid
  365.         .long  sys_ni_syscall           /* old ulimit syscall holder */
  366.         .long  sys_ni_syscall           /* old uname syscall holder */
  367.         .long  sys_umask                /* 60 */
  368.         .long  sys_chroot
  369.         .long  sys_ustat
  370.         .long  sys_dup2
  371.         .long  sys_getppid
  372.         .long  sys_getpgrp              /* 65 */
  373.         .long  sys_setsid
  374.         .long  sys_sigaction
  375.         .long  sys_ni_syscall           /* old sgetmask syscall holder */
  376.         .long  sys_ni_syscall           /* old ssetmask syscall holder */
  377.         .long  sys_setreuid16           /* 70 */
  378.         .long  sys_setregid16
  379.         .long  sys_sigsuspend_glue
  380.         .long  sys_sigpending
  381.         .long  sys_sethostname
  382.         .long  sys_setrlimit            /* 75 */
  383.         .long  sys_old_getrlimit
  384.         .long  sys_getrusage
  385.         .long  sys_gettimeofday
  386.         .long  sys_settimeofday
  387.         .long  sys_getgroups16          /* 80 */
  388.         .long  sys_setgroups16
  389.         .long  sys_ni_syscall           /* old select syscall holder */
  390.         .long  sys_symlink
  391.         .long  sys_ni_syscall           /* old lstat syscall holder */
  392.         .long  sys_readlink             /* 85 */
  393.         .long  sys_uselib
  394.         .long  sys_swapon
  395.         .long  sys_reboot
  396.         .long  sys_ni_syscall           /* old readdir syscall holder */
  397.         .long  old_mmap                 /* 90 */
  398.         .long  sys_munmap
  399.         .long  sys_truncate
  400.         .long  sys_ftruncate
  401.         .long  sys_fchmod
  402.         .long  sys_fchown16              /* 95 */
  403.         .long  sys_getpriority
  404.         .long  sys_setpriority
  405.         .long  sys_ni_syscall            /* old profil syscall holder */
  406.         .long  sys_statfs
  407.         .long  sys_fstatfs               /* 100 */
  408.         .long  sys_ioperm
  409.         .long  sys_socketcall
  410.         .long  sys_syslog
  411.         .long  sys_setitimer
  412.         .long  sys_getitimer             /* 105 */
  413.         .long  sys_newstat
  414.         .long  sys_newlstat
  415.         .long  sys_newfstat
  416.         .long  sys_ni_syscall            /* old uname syscall holder */
  417.         .long  sys_ni_syscall            /* 110 */ /* iopl for i386 */
  418.         .long  sys_vhangup
  419.         .long  sys_ni_syscall            /* old "idle" system call */
  420.         .long  sys_ni_syscall            /* vm86old for i386 */
  421.         .long  sys_wait4
  422.         .long  sys_swapoff               /* 115 */
  423.         .long  sys_sysinfo
  424.         .long  sys_ipc
  425.         .long  sys_fsync
  426.         .long  sys_sigreturn_glue
  427.         .long  sys_clone_glue            /* 120 */
  428.         .long  sys_setdomainname
  429.         .long  sys_newuname
  430.         .long  sys_ni_syscall            /* modify_ldt for i386 */
  431.         .long  sys_adjtimex
  432.         .long  sys_mprotect              /* 125 */
  433.         .long  sys_sigprocmask
  434.         .long  sys_create_module
  435.         .long  sys_init_module
  436.         .long  sys_delete_module
  437.         .long  sys_get_kernel_syms       /* 130 */
  438.         .long  sys_quotactl
  439.         .long  sys_getpgid
  440.         .long  sys_fchdir
  441.         .long  sys_bdflush
  442.         .long  sys_sysfs                 /* 135 */
  443.         .long  sys_personality
  444.         .long  sys_ni_syscall            /* for afs_syscall */
  445.         .long  sys_setfsuid16
  446.         .long  sys_setfsgid16
  447.         .long  sys_llseek                /* 140 */
  448.         .long  sys_getdents
  449.         .long  sys_select
  450.         .long  sys_flock
  451.         .long  sys_msync
  452.         .long  sys_readv                 /* 145 */
  453.         .long  sys_writev
  454.         .long  sys_getsid
  455.         .long  sys_fdatasync
  456.         .long  sys_sysctl
  457.         .long  sys_mlock                 /* 150 */
  458.         .long  sys_munlock
  459.         .long  sys_mlockall
  460.         .long  sys_munlockall
  461.         .long  sys_sched_setparam
  462.         .long  sys_sched_getparam        /* 155 */
  463.         .long  sys_sched_setscheduler
  464.         .long  sys_sched_getscheduler
  465.         .long  sys_sched_yield
  466.         .long  sys_sched_get_priority_max
  467.         .long  sys_sched_get_priority_min  /* 160 */
  468.         .long  sys_sched_rr_get_interval
  469.         .long  sys_nanosleep
  470.         .long  sys_mremap
  471.         .long  sys_setresuid16
  472.         .long  sys_getresuid16           /* 165 */
  473.         .long  sys_ni_syscall            /* for vm86 */
  474.         .long  sys_query_module
  475.         .long  sys_poll
  476.         .long  sys_nfsservctl
  477.         .long  sys_setresgid16           /* 170 */
  478.         .long  sys_getresgid16
  479.         .long  sys_prctl
  480.         .long  sys_rt_sigreturn_glue
  481.         .long  sys_rt_sigaction
  482.         .long  sys_rt_sigprocmask        /* 175 */
  483.         .long  sys_rt_sigpending
  484.         .long  sys_rt_sigtimedwait
  485.         .long  sys_rt_sigqueueinfo
  486.         .long  sys_rt_sigsuspend_glue
  487.         .long  sys_pread                 /* 180 */
  488.         .long  sys_pwrite
  489.         .long  sys_chown16
  490.         .long  sys_getcwd
  491.         .long  sys_capget
  492.         .long  sys_capset                /* 185 */
  493.         .long  sys_sigaltstack_glue
  494.         .long  sys_sendfile
  495.         .long  sys_ni_syscall            /* streams1 */
  496.         .long  sys_ni_syscall            /* streams2 */
  497.         .long  sys_vfork_glue            /* 190 */
  498.         .long  sys_getrlimit
  499. .long  sys_mmap2
  500.         .long  sys_truncate64
  501.         .long  sys_ftruncate64
  502.         .long  sys_stat64                /* 195 */
  503.         .long  sys_lstat64
  504.         .long  sys_fstat64
  505. .long  sys_lchown
  506. .long  sys_getuid
  507. .long  sys_getgid  /* 200 */
  508. .long  sys_geteuid
  509. .long  sys_getegid
  510. .long  sys_setreuid
  511. .long  sys_setregid
  512. .long  sys_getgroups             /* 205 */
  513. .long  sys_setgroups
  514. .long  sys_fchown
  515. .long  sys_setresuid
  516. .long  sys_getresuid
  517. .long  sys_setresgid             /* 210 */
  518. .long  sys_getresgid
  519. .long  sys_chown
  520. .long  sys_setuid
  521. .long  sys_setgid
  522. .long  sys_setfsuid              /* 215 */
  523. .long  sys_setfsgid
  524.         .long  sys_pivot_root
  525.         .long  sys_mincore
  526.         .long  sys_madvise
  527. .long  sys_getdents64  /* 220 */
  528.         .long  sys_fcntl64 
  529. .long  sys_ni_syscall
  530. .long  sys_ni_syscall
  531. .long  sys_ni_syscall  /* 224 - reserved for setxattr  */
  532. .long  sys_ni_syscall            /* 225 - reserved for lsetxattr */
  533. .long  sys_ni_syscall  /* 226 - reserved for fsetxattr */
  534. .long  sys_ni_syscall  /* 227 - reserved for getxattr  */
  535. .long  sys_ni_syscall  /* 228 - reserved for lgetxattr */
  536. .long  sys_ni_syscall  /* 229 - reserved for fgetxattr */
  537. .long  sys_ni_syscall  /* 230 - reserved for listxattr */
  538. .long  sys_ni_syscall  /* 231 - reserved for llistxattr */
  539. .long  sys_ni_syscall  /* 232 - reserved for flistxattr */
  540. .long  sys_ni_syscall  /* 233 - reserved for removexattr */
  541. .long  sys_ni_syscall  /* 234 - reserved for lremovexattr */
  542. .long  sys_ni_syscall  /* 235 - reserved for fremovexattr */
  543. .long  sys_gettid
  544. .long  sys_tkill
  545. .rept  255-237
  546. .long  sys_ni_syscall
  547. .endr
  548. /*
  549.  * Program check handler routine
  550.  */
  551.         .globl  pgm_check_handler
  552. pgm_check_handler:
  553. /*
  554.  * First we need to check for a special case:
  555.  * Single stepping an instruction that disables the PER event mask will
  556.  * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
  557.  * For a single stepped SVC the program check handler gets control after
  558.  * the SVC new PSW has been loaded. But we want to execute the SVC first and
  559.  * then handle the PER event. Therefore we update the SVC old PSW to point
  560.  * to the pgm_check_handler and branch to the SVC handler after we checked
  561.  * if we have to load the kernel stack register.
  562.  * For every other possible cause for PER event without the PER mask set
  563.  * we just ignore the PER event (FIXME: is there anything we have to do
  564.  * for LPSW?).
  565.  */
  566. SAVE_ALL_BASE
  567.         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
  568.         bnz     BASED(pgm_per)           # got per exception -> special case
  569. SAVE_ALL __LC_PGM_OLD_PSW,1
  570.         l       %r7,BASED(.Ljump_table)
  571.         lh      %r8,__LC_PGM_INT_CODE
  572.         sll     %r8,2
  573. GET_CURRENT
  574.         l       %r7,0(%r8,%r7)  # load address of handler routine
  575.         la      %r2,SP_PTREGS(%r15)  # address of register-save area
  576.         l       %r3,__LC_PGM_ILC         # load program interruption code
  577. la      %r14,BASED(sysc_return)
  578. br      %r7  # branch to interrupt-handler
  579. #
  580. # handle per exception
  581. #
  582. pgm_per:
  583.         tm      __LC_PGM_OLD_PSW,0x40    # test if per event recording is on
  584.         bnz     BASED(pgm_per_std)       # ok, normal per event from user space
  585. # ok its one of the special cases, now we need to find out which one
  586.         clc     __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
  587.         be      BASED(pgm_svcper)
  588. # no interesting special case, ignore PER event
  589.         lm      %r13,%r15,__LC_SAVE_AREA
  590. lpsw    0x28
  591. #
  592. # Normal per exception
  593. #
  594. pgm_per_std:
  595. SAVE_ALL __LC_PGM_OLD_PSW,1
  596. GET_CURRENT
  597. la %r4,0x7f
  598. l %r3,__LC_PGM_ILC  # load program interruption code
  599.         nr      %r4,%r3                  # clear per-event-bit and ilc
  600.         be      BASED(pgm_per_only)      # only per or per+check ?
  601.         l       %r1,BASED(.Ljump_table)
  602.         sll     %r4,2
  603.         l       %r1,0(%r4,%r1)  # load address of handler routine
  604.         la      %r2,SP_PTREGS(%r15)  # address of register-save area
  605. basr    %r14,%r1  # branch to interrupt-handler
  606. pgm_per_only:
  607. la      %r2,SP_PTREGS(15)  # address of register-save area
  608.         l       %r1,BASED(.Lhandle_per)  # load adr. of per handler
  609.         la      %r14,BASED(sysc_return)  # load adr. of system return
  610.         br      %r1  # branch to handle_per_exception
  611. #
  612. # it was a single stepped SVC that is causing all the trouble
  613. #
  614. pgm_svcper:
  615. SAVE_ALL __LC_SVC_OLD_PSW,1
  616.         GET_CURRENT               # load pointer to task_struct to R9
  617. lh %r8,0x8a   # get svc number from lowcore
  618.         sll     %r8,2
  619.         stosm   24(%r15),0x03     # reenable interrupts
  620.         l       %r8,sys_call_table-entry_base(%r8,%r13) # get system call addr.
  621.         tm      __TASK_ptrace+3(%r9),0x02 # PT_TRACESYS
  622.         bnz     BASED(pgm_tracesys)
  623.         basr    %r14,%r8          # call sys_xxxx
  624.         st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
  625.                                   # ATTENTION: check sys_execve_glue before
  626.                                   # changing anything here !!
  627. pgm_svcret:
  628.         icm     %r0,15,__TASK_sigpending(%r9)
  629.         bz      BASED(pgm_svcper_nosig)
  630. la %r2,SP_PTREGS(%r15) # load pt_regs
  631. sr %r3,%r3   # clear *oldset
  632. l %r1,BASED(.Ldo_signal)
  633. basr %r4,%r1   # call do_signal
  634. pgm_svcper_nosig:
  635.         mvi     SP_TRAP+3(%r15),0x28     # set trap indication to pgm check
  636. la      %r2,SP_PTREGS(15)        # address of register-save area
  637.         l       %r1,BASED(.Lhandle_per)  # load adr. of per handler
  638.         la      %r14,BASED(sysc_return)  # load adr. of system return
  639.         br      %r1                      # branch to handle_per_exception
  640. #
  641. # call trace before and after sys_call
  642. #
  643. pgm_tracesys:
  644. la %r11,BASED(pgm_svcret)
  645. b BASED(trace_svc)
  646. /*
  647.  * IO interrupt handler routine
  648.  */
  649.         .globl io_int_handler
  650. io_int_handler:
  651. SAVE_ALL_BASE
  652.         SAVE_ALL __LC_IO_OLD_PSW,0
  653.         GET_CURRENT               # load pointer to task_struct to R9
  654.         l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ
  655.         la      %r2,SP_PTREGS(%r15) # address of register-save area
  656.         sr      %r3,%r3
  657.         icm     %r3,3,__LC_SUBCHANNEL_NR   # load subchannel nr & extend to int
  658.         l       %r4,__LC_IO_INT_PARM       # load interuption parm
  659. l       %r5,__LC_IO_INT_WORD       # load interuption word
  660.         basr    %r14,%r1          # branch to standard irq handler
  661. io_return:
  662. #
  663. # check, if bottom-half has to be done
  664. #
  665.         l       %r1,__TASK_processor(%r9)
  666.         sll     %r1,L1_CACHE_SHIFT
  667.         al      %r1,BASED(.Lirq_stat) # get address of irq_stat
  668.         icm     %r0,15,0(%r1)         # test irq_stat[#cpu].__softirq_pending
  669.         bnz     BASED(io_handle_bottom_half)
  670. io_return_bh:
  671.         tm      SP_PSW+1(%r15),0x01 # returning to user ?
  672.         bno     BASED(io_leave)   # no-> skip resched & signal
  673.         stosm   24(%r15),0x03     # reenable interrupts
  674. #
  675. # check, if reschedule is needed
  676. #
  677.         icm     %r0,15,__TASK_need_resched(%r9)
  678.         bnz     BASED(io_reschedule)
  679.         icm     %r0,15,__TASK_sigpending(%r9)
  680.         bnz     BASED(io_signal_return)
  681. io_leave:
  682.         stnsm   24(%r15),0xfc            # disable I/O and ext. interrupts
  683.         RESTORE_ALL 0
  684. #
  685. # call do_softirq
  686. #
  687. io_handle_bottom_half:
  688.         l       %r1,BASED(.Ldo_softirq)
  689.         la      %r14,BASED(io_return_bh)
  690.         br      %r1               # call do_softirq
  691. #
  692. # call schedule with io_return as return-address
  693. #
  694. io_reschedule:        
  695.         l       %r1,BASED(.Lschedule)
  696. la      %r14,BASED(io_return)
  697.         br      %r1               # call scheduler, return to io_return
  698. #
  699. # call do_signal before return
  700. #
  701. io_signal_return:     
  702.         la      %r2,SP_PTREGS(%r15) # load pt_regs
  703.         sr      %r3,%r3           # clear *oldset
  704.         l       %r1,BASED(.Ldo_signal)
  705. la      %r14,BASED(io_leave)
  706.         br      %r1               # return point is io_leave
  707. /*
  708.  * External interrupt handler routine
  709.  */
  710.         .globl  ext_int_handler
  711. ext_int_handler:
  712. SAVE_ALL_BASE
  713.         SAVE_ALL __LC_EXT_OLD_PSW,0
  714.         GET_CURRENT                    # load pointer to task_struct to R9
  715. lh %r6,__LC_EXT_INT_CODE  # get interruption code
  716. lr %r1,%r6        # calculate index = code & 0xff
  717. n %r1,BASED(.Lc0xff)
  718. sll %r1,2
  719. l %r7,BASED(.Lext_hash)
  720. l %r7,0(%r1,%r7)        # get first list entry for hash value
  721. ltr %r7,%r7        # == NULL ?
  722. bz BASED(io_return)       # yes, nothing to do, exit
  723. ext_int_loop:
  724. ch %r6,8(%r7)        # compare external interrupt code
  725. bne BASED(ext_int_next)
  726. l %r1,4(%r7)        # get handler address
  727. la %r2,SP_PTREGS(%r15)    # address of register-save area
  728. lr %r3,%r6        # interruption code
  729. basr %r14,%r1        # call handler
  730. ext_int_next:
  731. icm %r7,15,0(%r7)        # next list entry
  732. bnz BASED(ext_int_loop)
  733. b BASED(io_return)
  734. /*
  735.  * Machine check handler routines
  736.  */
  737.         .globl mcck_int_handler
  738. mcck_int_handler:
  739. SAVE_ALL_BASE
  740.         SAVE_ALL __LC_MCK_OLD_PSW,0
  741. l       %r1,BASED(.Ls390_mcck)
  742. basr    %r14,%r1   # call machine check handler
  743. mcck_return:
  744.         RESTORE_ALL 0
  745. #ifdef CONFIG_SMP
  746. /*
  747.  * Restart interruption handler, kick starter for additional CPUs
  748.  */
  749.         .globl restart_int_handler
  750. restart_int_handler:
  751.         l       %r15,__LC_SAVE_AREA+60 # load ksp
  752.         lctl    %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
  753.         lam     %a0,%a15,__LC_AREGS_SAVE_AREA
  754.         stosm   0(%r15),0x04           # now we can turn dat on
  755.         lm      %r6,%r15,24(%r15)      # load registers from clone
  756.         basr    %r14,0
  757.         l       %r14,restart_addr-.(%r14)
  758.         br      %r14                   # branch to start_secondary
  759. restart_addr:
  760.         .long   start_secondary
  761. #else
  762. /*
  763.  * If we do not run with SMP enabled, let the new CPU crash ...
  764.  */
  765.         .globl restart_int_handler
  766. restart_int_handler:
  767.         basr    %r1,0
  768. restart_base:
  769.         lpsw    restart_crash-restart_base(%r1)
  770.         .align 8
  771. restart_crash:
  772.         .long  0x000a0000,0x00000000
  773. restart_go:
  774. #endif
  775. /*
  776.  * Integer constants
  777.  */
  778.                .align 4
  779. .Lc0xfffffff8: .long  -8           # to align stack pointer to 8
  780. .Lc0xffffe000: .long  -8192        # to round stack pointer to &task_struct
  781. .Lc8191:       .long  8191
  782. .Lc_spsize:    .long  SP_SIZE
  783. .Lc_overhead:  .long  STACK_FRAME_OVERHEAD
  784. .Lc_ac:        .long  0,0,1
  785. .Lc_ENOSYS:    .long  -ENOSYS
  786. .Lc4:          .long  4
  787. .Lc20:         .long  20
  788. .Lc0x1202:     .long  0x1202
  789. .Lc0x1004:     .long  0x1004
  790. .Lc0x2401:     .long  0x2401
  791. .Lc0x4000:     .long  0x4000
  792. .Lc0xff:       .long  0xff
  793. .Lc128:        .long  128
  794. /*
  795.  * Symbol constants
  796.  */
  797. .Ls390_mcck:   .long  s390_do_machine_check
  798. .Ldo_IRQ:      .long  do_IRQ
  799. .Ldo_signal:   .long  do_signal
  800. .Ldo_softirq:  .long  do_softirq
  801. .Lentry_base:  .long  entry_base
  802. .Lext_hash:    .long  ext_int_hash
  803. .Lhandle_per:  .long  handle_per_exception
  804. .Lirq_stat:    .long  irq_stat
  805. .Ljump_table:  .long  pgm_check_table
  806. .Lschedule:    .long  schedule
  807. .Lclone:       .long  sys_clone
  808. .Lexecve:      .long  sys_execve
  809. .Lfork:        .long  sys_fork
  810. .Lrt_sigreturn:.long  sys_rt_sigreturn
  811. .Lrt_sigsuspend:
  812.                .long  sys_rt_sigsuspend
  813. .Lsigreturn:   .long  sys_sigreturn
  814. .Lsigsuspend:  .long  sys_sigsuspend
  815. .Lsigaltstack: .long  sys_sigaltstack
  816. .Ltrace:       .long  syscall_trace
  817. .Lvfork:       .long  sys_vfork
  818. .Lschedtail:   .long  schedule_tail