scall_o32.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
  7.  */
  8. #include <asm/asm.h>
  9. #include <linux/errno.h>
  10. #include <asm/current.h>
  11. #include <asm/mipsregs.h>
  12. #include <asm/regdef.h>
  13. #include <asm/stackframe.h>
  14. #include <asm/isadep.h>
  15. #include <asm/unistd.h>
  16. /* This duplicates the definition from <linux/sched.h> */
  17. #define PT_TRACESYS 0x00000002 /* tracing system calls */
  18. /* This duplicates the definition from <asm/signal.h> */
  19. #define SIGILL 4 /* Illegal instruction (ANSI).  */
  20. /* Highest syscall used of any syscall flavour */
  21. #define MAX_SYSCALL_NO __NR_Linux + __NR_Linux_syscalls
  22. .align  5
  23. NESTED(handle_sys, PT_SIZE, sp)
  24. .set noat
  25. SAVE_SOME
  26. STI
  27. .set at
  28. lw t1, PT_EPC(sp) # skip syscall on return
  29. sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
  30. addiu t1, 4 # skip to next instruction
  31. beqz t0, illegal_syscall
  32. sw t1, PT_EPC(sp)
  33. /* XXX Put both in one cacheline, should save a bit. */
  34. sll t0, v0, 2
  35. lw t2, sys_call_table(t0) # syscall routine
  36. lbu t3, sys_narg_table(v0) # number of arguments
  37. beqz t2, illegal_syscall;
  38. subu t0, t3, 5 # 5 or more arguments?
  39. sw a3, PT_R26(sp) # save a3 for syscall restarting
  40. bgez t0, stackargs
  41. stack_done:
  42.         sw      a3, PT_R26(sp)          # save for syscall restart
  43. lw t0, TASK_PTRACE($28) # syscall tracing enabled?
  44. andi t0, PT_TRACESYS
  45. bnez t0, trace_a_syscall
  46. jalr t2 # Do The Real Thing (TM)
  47. li t0, -EMAXERRNO - 1 # error?
  48. sltu t0, t0, v0
  49. sw t0, PT_R7(sp) # set error flag
  50. beqz t0, 1f
  51. negu v0 # error
  52. sw v0, PT_R0(sp) # set flag for syscall restarting
  53. 1: sw v0, PT_R2(sp) # result
  54. EXPORT(o32_ret_from_sys_call)
  55. mfc0 t0, CP0_STATUS # need_resched and signals atomic test
  56. ori t0, t0, 1
  57. xori t0, t0, 1
  58. mtc0 t0, CP0_STATUS
  59. lw t2, TASK_NEED_RESCHED($28)
  60. bnez t2, o32_reschedule
  61. lw v0, TASK_SIGPENDING($28)
  62. bnez v0, signal_return
  63. restore_all:
  64. RESTORE_SOME
  65. RESTORE_SP_AND_RET
  66. /* Put this behind restore_all for the sake of the branch prediction.  */
  67. signal_return:
  68. .type signal_return, @function
  69. mfc0 t0, CP0_STATUS
  70. ori t0, t0, 1
  71. mtc0 t0, CP0_STATUS
  72. move a0, zero
  73. move a1, sp
  74. jal do_signal
  75. b restore_all
  76. o32_reschedule:
  77. SAVE_STATIC
  78. jal schedule
  79. b o32_ret_from_sys_call
  80. /* ------------------------------------------------------------------------ */
  81. trace_a_syscall:
  82. SAVE_STATIC
  83. sw t2, PT_R1(sp)
  84. jal syscall_trace
  85. lw t2, PT_R1(sp)
  86. lw a0, PT_R4(sp) # Restore argument registers
  87. lw a1, PT_R5(sp)
  88. lw a2, PT_R6(sp)
  89. lw a3, PT_R7(sp)
  90. jalr t2
  91. li t0, -EMAXERRNO - 1 # error?
  92. sltu t0, t0, v0
  93. sw t0, PT_R7(sp) # set error flag
  94. beqz t0, 1f
  95. negu v0 # error
  96. sw v0, PT_R0(sp) # set flag for syscall restarting
  97. 1: sw v0, PT_R2(sp) # result
  98. jal syscall_trace
  99. j ret_from_sys_call
  100. /* ------------------------------------------------------------------------ */
  101. /*
  102.  * More than four arguments.  Try to deal with it by copying the
  103.  * stack arguments from the user stack to the kernel stack.
  104.  * This Sucks (TM).
  105.  */
  106. stackargs:
  107. lw t0, PT_R29(sp) # get old user stack pointer
  108. subu t3, 4
  109. sll t1, t3, 2 # stack valid?
  110. addu t1, t0 # end address
  111. or t0, t1
  112. bltz t0, bad_stack # -> sp is bad
  113. lw t0, PT_R29(sp) # get old user stack pointer
  114. la t1, 3f # copy 1 to 2 arguments
  115. sll t3, t3, 4
  116. subu t1, t3
  117. jr t1
  118. /* Ok, copy the args from the luser stack to the kernel stack */
  119. /*
  120.  * I know Ralf doesn't like nops but this avoids code
  121.  * duplication for R3000 targets (and this is the
  122.  * only place where ".set reorder" doesn't help).
  123.  * Harald.
  124.  */
  125. .set    push
  126. .set    noreorder
  127. 1: lw t1, 20(t0) # argument #6 from usp
  128. nop
  129. sw t1, 20(sp)
  130. nop
  131. 2: lw t1, 16(t0) # argument #5 from usp
  132. nop
  133. sw t1, 16(sp)
  134. nop
  135. .set pop
  136. 3: j stack_done # go back
  137. .section __ex_table,"a"
  138. PTR 1b,bad_stack
  139. PTR 2b,bad_stack
  140. .previous
  141. /*
  142.  * The stackpointer for a call with more than 4 arguments is bad.
  143.  * We probably should handle this case a bit more drastic.
  144.  */
  145. bad_stack:
  146. negu v0 # error
  147. sw v0, PT_R0(sp)
  148. sw v0, PT_R2(sp)
  149. li t0, 1 # set error flag
  150. sw t0, PT_R7(sp)
  151. j ret_from_sys_call
  152. /*
  153.  * The system call does not exist in this kernel
  154.  */
  155. illegal_syscall:
  156. li v0, ENOSYS # error
  157. sw v0, PT_R2(sp)
  158. li t0, 1 # set error flag
  159. sw t0, PT_R7(sp)
  160. j ret_from_sys_call
  161. END(handle_sys)