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

嵌入式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) 1995 - 2000, 2001 by Ralf Baechle
  7.  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  8.  * Copyright (C) 2001 MIPS Technologies, Inc.
  9.  *
  10.  * Hairy, the userspace application uses a different argument passing
  11.  * convention than the kernel, so we have to translate things from o32
  12.  * to ABI64 calling convention.  64-bit syscalls are also processed
  13.  * here for now.
  14.  */
  15. #include <asm/asm.h>
  16. #include <linux/errno.h>
  17. #include <asm/current.h>
  18. #include <asm/mipsregs.h>
  19. #include <asm/regdef.h>
  20. #include <asm/stackframe.h>
  21. #include <asm/unistd.h>
  22. #include <asm/sysmips.h>
  23. /* This duplicates the definition from <linux/sched.h> */
  24. #define PT_TRACESYS 0x00000002 /* tracing system calls */
  25. /* This duplicates the definition from <asm/signal.h> */
  26. #define SIGILL 4 /* Illegal instruction (ANSI).  */
  27. /* Highest syscall used of any syscall flavour */
  28. #define MAX_SYSCALL_NO __NR_Linux32 + __NR_Linux32_syscalls
  29. .align  5
  30. NESTED(handle_sys, PT_SIZE, sp)
  31. .set noat
  32. SAVE_SOME
  33. STI
  34. .set at
  35. ld t1, PT_EPC(sp) # skip syscall on return
  36. subu t0, v0, __NR_Linux32 # check syscall number
  37. sltiu t0, t0, __NR_Linux32_syscalls + 1
  38. daddiu t1, 4 # skip to next instruction
  39. beqz t0, not_o32_scall
  40. sd t1, PT_EPC(sp)
  41. /* XXX Put both in one cacheline, should save a bit. */
  42. dsll t0, v0, 3 # offset into table
  43. ld t2, (sys_call_table - (__NR_Linux32 * 8))(t0) # syscall routine
  44. lbu t3, (sys_narg_table - __NR_Linux32)(v0) # number of arguments
  45. subu t0, t3, 5 # 5 or more arguments?
  46. sd a3, PT_R26(sp) # save a3 for syscall restarting
  47. bgez t0, stackargs
  48. stack_done:
  49. ld t0, TASK_PTRACE($28) # syscall tracing enabled?
  50. andi t0, PT_TRACESYS
  51. bnez t0, trace_a_syscall
  52. jalr t2 # Do The Real Thing (TM)
  53. li t0, -EMAXERRNO - 1 # error?
  54. sltu t0, t0, v0
  55. sd t0, PT_R7(sp) # set error flag
  56. beqz t0, 1f
  57. negu v0 # error
  58. sd v0, PT_R0(sp) # flag for syscall restarting
  59. 1: sd v0, PT_R2(sp) # result
  60. FEXPORT(o32_ret_from_sys_call)
  61. mfc0 t0, CP0_STATUS # need_resched and signals atomic test
  62. ori t0, t0, 1
  63. xori t0, t0, 1
  64. mtc0 t0, CP0_STATUS
  65. ld t2, TASK_NEED_RESCHED($28)
  66. bnez t2, o32_reschedule
  67. lw v0, TASK_SIGPENDING($28)
  68. bnez v0, signal_return
  69. restore_all: RESTORE_SOME
  70. RESTORE_SP
  71. .set mips3
  72. eret
  73. .set mips0
  74. signal_return: mfc0 t0, CP0_STATUS # need_resched and signals atomic test
  75. ori t0, t0, 1
  76. mtc0 t0, CP0_STATUS
  77. move a0, zero
  78. move a1, sp
  79. SAVE_STATIC
  80. jal do_signal
  81. o32_reschedule:
  82. SAVE_STATIC
  83. jal schedule
  84. b o32_ret_from_sys_call
  85. /* ------------------------------------------------------------------------ */
  86. trace_a_syscall:
  87. SAVE_STATIC
  88. sd a4, PT_R8(sp)
  89. sd a5, PT_R9(sp)
  90. sd a6, PT_R10(sp)
  91. sd a7, PT_R11(sp)
  92. sd t2,PT_R1(sp)
  93. jal syscall_trace
  94. ld t2,PT_R1(sp)
  95. ld a0, PT_R4(sp) # Restore argument registers
  96. ld a1, PT_R5(sp)
  97. ld a2, PT_R6(sp)
  98. ld a3, PT_R7(sp)
  99. ld a4, PT_R8(sp)
  100. ld a5, PT_R9(sp)
  101. jalr t2
  102. li t0, -EMAXERRNO - 1 # error?
  103. sltu t0, t0, v0
  104. sd t0, PT_R7(sp) # set error flag
  105. beqz t0, 1f
  106. negu v0 # error
  107. sd v0, PT_R0(sp) # set flag for syscall restarting
  108. 1: sd v0, PT_R2(sp) # result
  109. jal syscall_trace
  110. j o32_ret_from_sys_call
  111. /* ------------------------------------------------------------------------ */
  112. /*
  113.  * More than four arguments.  Try to deal with it by copying the
  114.  * stack arguments from the user stack to the kernel stack.
  115.  * This Sucks (TM).
  116.  */
  117. stackargs:
  118. ld t0, PT_R29(sp) # get old user stack pointer
  119. subu t3, 4
  120. sll t1, t3, 2 # stack valid?
  121. addu t1, t0 # end address
  122. or t0, t1
  123. bltz t0, bad_stack # -> sp is bad
  124. ld t0, PT_R29(sp) # get old user stack pointer
  125. la t1, 3f # copy 1 to 2 arguments
  126. sll t3, t3, 2
  127. subu t1, t3
  128. jr t1
  129. /* Ok, copy the args from the luser stack to the kernel stack */
  130. 1: lw a5, 20(t0) # argument #6 from usp
  131. 2: lw a4, 16(t0) # argument #5 from usp
  132. 3: j stack_done # go back
  133. .section __ex_table,"a"
  134. PTR 1b, bad_stack
  135. PTR 2b, bad_stack
  136. .previous
  137. /*
  138.  * The stackpointer for a call with more than 4 arguments is bad.
  139.  */
  140. bad_stack:
  141. negu v0 # error
  142. sd v0, PT_R0(sp)
  143. sd v0, PT_R2(sp)
  144. li t0, 1 # set error flag
  145. sd t0, PT_R7(sp)
  146. j ret_from_sys_call
  147. not_o32_scall:
  148. /* This is not an 32-bit compatibility syscall, pass it on to
  149.    the 64-bit syscall handlers.  */
  150. j handle_sys64
  151. illegal_syscall:
  152. /* This also isn't a 64-bit syscall, throw an error.  */
  153. li v0, ENOSYS # error
  154. sd v0, PT_R2(sp)
  155. li t0, 1 # set error flag
  156. sd t0, PT_R7(sp)
  157. j ret_from_sys_call
  158. END(handle_sys)
  159. LEAF(mips_atomic_set)
  160. ld v1, THREAD_CURDS($28)
  161. daddiu a0, a1, 4
  162. or a0, a0, a1
  163. li v0, -EFAULT
  164. and a0, a0, v1
  165. bltz a0, 9f
  166. /* Ok, this is the ll/sc case.  World is sane :-)  */
  167. 1: ll v0, (a1)
  168. move a0, a2
  169. 2: sc a0, (a1)
  170. beqz a0, 1b
  171. .section __ex_table,"a"
  172. PTR 1b, bad_stack
  173. PTR 2b, bad_stack
  174. .previous
  175. 1: sd v0, PT_R2(sp) # result
  176. /* Success, so skip usual error handling garbage.  */
  177. ld t0, TASK_PTRACE($28) # syscall tracing enabled?
  178. andi t0, PT_TRACESYS
  179. bnez t0, 1f
  180. b o32_ret_from_sys_call
  181. 1: SAVE_STATIC
  182. jal syscall_trace
  183. li a3, 0 # success
  184. j ret_from_sys_call
  185. 9: li v0, -EFAULT
  186. jr ra
  187. END(mips_atomic_set)
  188. LEAF(sys_sysmips)
  189. beq a0, MIPS_ATOMIC_SET, mips_atomic_set
  190. j _sys_sysmips
  191. END(sys_sysmips)
  192. .macro syscalltable
  193. sys sys_syscall 0 /* 4000 */
  194. sys sys_exit 1
  195. sys sys_fork 0
  196. sys sys_read 3
  197. sys sys_write 3
  198. sys sys_open 3 /* 4005 */
  199. sys sys_close 1
  200. sys sys_waitpid 3
  201. sys sys_creat 2
  202. sys sys_link 2
  203. sys sys_unlink 1 /* 4010 */
  204. sys sys32_execve 0
  205. sys sys_chdir 1
  206. sys sys_time 1
  207. sys sys_mknod 3
  208. sys sys_chmod 2 /* 4015 */
  209. sys sys_lchown 3
  210. sys sys_ni_syscall 0
  211. sys sys_stat 2
  212. sys sys_lseek 3
  213. sys sys_getpid 0 /* 4020 */
  214. sys sys_mount 5
  215. sys sys_oldumount 1
  216. sys sys_setuid 1
  217. sys sys_getuid 0
  218. sys sys_stime 1 /* 4025 */
  219. sys sys32_ptrace 4
  220. sys sys32_alarm 1
  221. sys sys_fstat 2
  222. sys sys_pause 0
  223. sys sys32_utime 2 /* 4030 */
  224. sys sys_ni_syscall 0
  225. sys sys_ni_syscall 0
  226. sys sys_access 2
  227. sys sys_nice 1
  228. sys sys_ni_syscall 0 /* 4035 */
  229. sys sys_sync 0
  230. sys sys_kill 2
  231. sys sys_rename 2
  232. sys sys_mkdir 2
  233. sys sys_rmdir 1 /* 4040 */
  234. sys sys_dup 1
  235. sys sys_pipe 0
  236. sys sys32_times 1
  237. sys sys_ni_syscall 0
  238. sys sys_brk 1 /* 4045 */
  239. sys sys_setgid 1
  240. sys sys_getgid 0
  241. sys sys_ni_syscall 0 /* was signal 2 */
  242. sys sys_geteuid 0
  243. sys sys_getegid 0 /* 4050 */
  244. sys sys_acct 0
  245. sys sys_umount 2
  246. sys sys_ni_syscall 0
  247. sys sys32_ioctl 3
  248. sys sys32_fcntl 3 /* 4055 */
  249. sys sys_ni_syscall 2
  250. sys sys_setpgid 2
  251. sys sys_ni_syscall, 0
  252. sys sys_ni_syscall 0 /* was sys_olduname  */
  253. sys sys_umask 1 /* 4060 */
  254. sys sys_chroot 1
  255. sys sys_ustat 2
  256. sys sys_dup2 2
  257. sys sys_getppid 0
  258. sys sys_getpgrp 0 /* 4065 */
  259. sys sys_setsid 0
  260. sys sys32_sigaction 3
  261. sys sys_sgetmask 0
  262. sys sys_ssetmask 1
  263. sys sys_setreuid 2 /* 4070 */
  264. sys sys_setregid 2
  265. sys sys32_sigsuspend 0
  266. sys sys32_sigpending 1
  267. sys sys_sethostname 2
  268. sys sys32_setrlimit 2 /* 4075 */
  269. sys sys32_getrlimit 2
  270. sys sys32_getrusage 2
  271. sys sys32_gettimeofday 2
  272. sys sys32_settimeofday 2
  273. sys sys_getgroups 2 /* 4080 */
  274. sys sys_setgroups 2
  275. sys sys_ni_syscall 0 /* old_select */
  276. sys sys_symlink 2
  277. sys sys_lstat 2
  278. sys sys_readlink 3 /* 4085 */
  279. sys sys_uselib 1
  280. sys sys_swapon 2
  281. sys sys_reboot 3
  282. sys sys32_readdir 3
  283. sys sys_mmap 6 /* 4090 */
  284. sys sys_munmap 2
  285. sys sys_truncate 2
  286. sys sys_ftruncate 2
  287. sys sys_fchmod 2
  288. sys sys_fchown 3 /* 4095 */
  289. sys sys_getpriority 2
  290. sys sys_setpriority 3
  291. sys sys_ni_syscall 0
  292. sys sys32_statfs 2
  293. sys sys32_fstatfs 2 /* 4100 */
  294. sys sys_ni_syscall 0 /* sys_ioperm */
  295. sys sys_socketcall 2
  296. sys sys_syslog 3
  297. sys sys32_setitimer 3
  298. sys sys32_getitimer 2 /* 4105 */
  299. sys sys32_newstat 2
  300. sys sys32_newlstat 2
  301. sys sys32_newfstat 2
  302. sys sys_ni_syscall 0 /* was sys_uname */
  303. sys sys_ni_syscall 0 /* sys_ioperm  *//* 4110 */
  304. sys sys_vhangup 0
  305. sys sys_ni_syscall 0 /* was sys_idle  */
  306. sys sys_ni_syscall 0 /* sys_vm86 */
  307. sys sys32_wait4 4
  308. sys sys_swapoff 1 /* 4115 */
  309. sys sys_sysinfo 1
  310. sys sys32_ipc 6
  311. sys sys_fsync 1
  312. sys sys32_sigreturn 0
  313. sys sys_clone 0 /* 4120 */
  314. sys sys_setdomainname 2
  315. sys sys32_newuname 1
  316. sys sys_ni_syscall 0 /* sys_modify_ldt */
  317. sys sys32_adjtimex 1
  318. sys sys_mprotect 3 /* 4125 */
  319. sys sys32_sigprocmask 3
  320. sys sys_create_module 2
  321. sys sys_init_module 5
  322. sys sys_delete_module 1
  323. sys sys_get_kernel_syms 1 /* 4130 */
  324. sys sys_quotactl 0
  325. sys sys_getpgid 1
  326. sys sys_fchdir 1
  327. sys sys_bdflush 2
  328. sys sys_sysfs 3 /* 4135 */
  329. sys sys32_personality 1
  330. sys sys_ni_syscall 0 /* for afs_syscall */
  331. sys sys_setfsuid 1
  332. sys sys_setfsgid 1
  333. sys sys32_llseek 5 /* 4140 */
  334. sys sys32_getdents 3
  335. sys sys32_select 5
  336. sys sys_flock 2
  337. sys sys_msync 3
  338. sys sys32_readv 3 /* 4145 */
  339. sys sys32_writev 3
  340. sys sys_cacheflush 3
  341. sys sys_cachectl 3
  342. sys sys_sysmips 4
  343. sys sys_ni_syscall 0 /* 4150 */
  344. sys sys_getsid 1
  345. sys sys_fdatasync 0
  346. sys sys32_sysctl 1
  347. sys sys_mlock 2
  348. sys sys_munlock 2 /* 4155 */
  349. sys sys_mlockall 1
  350. sys sys_munlockall 0
  351. sys sys_sched_setparam 2
  352. sys sys_sched_getparam 2
  353. sys sys_sched_setscheduler 3 /* 4160 */
  354. sys sys_sched_getscheduler 1
  355. sys sys_sched_yield 0
  356. sys sys_sched_get_priority_max 1
  357. sys sys_sched_get_priority_min 1
  358. sys sys32_sched_rr_get_interval 2 /* 4165 */
  359. sys sys32_nanosleep 2
  360. sys sys_mremap 4
  361. sys sys_accept 3
  362. sys sys_bind 3
  363. sys sys_connect 3 /* 4170 */
  364. sys sys_getpeername 3
  365. sys sys_getsockname 3
  366. sys sys_getsockopt 5
  367. sys sys_listen 2
  368. sys sys_recv 4 /* 4175 */
  369. sys sys_recvfrom 6
  370. sys sys32_recvmsg 3
  371. sys sys_send 4
  372. sys sys32_sendmsg 3
  373. sys sys_sendto 6 /* 4180 */
  374. sys sys32_setsockopt 5
  375. sys sys_shutdown 2
  376. sys sys_socket 3
  377. sys sys_socketpair 4
  378. sys sys_setresuid 3 /* 4185 */
  379. sys sys_getresuid 3
  380. sys sys_query_module 5
  381. sys sys_poll 3
  382. sys sys_nfsservctl 3
  383. sys sys_setresgid 3 /* 4190 */
  384. sys sys_getresgid 3
  385. sys sys_prctl 5
  386. sys sys32_rt_sigreturn 0
  387. sys sys32_rt_sigaction 4
  388. sys sys32_rt_sigprocmask 4 /* 4195 */
  389. sys sys32_rt_sigpending 2
  390. sys sys32_rt_sigtimedwait 4
  391. sys sys32_rt_sigqueueinfo 3
  392. sys sys32_rt_sigsuspend 0
  393. sys sys32_pread 6 /* 4200 */
  394. sys sys32_pwrite 6
  395. sys sys_chown 3
  396. sys sys_getcwd 2
  397. sys sys_capget 2
  398. sys sys_capset 2 /* 4205 */
  399. sys sys32_sigaltstack 0
  400. sys sys_sendfile 3
  401. sys sys_ni_syscall 0
  402. sys sys_ni_syscall 0
  403. sys sys_mmap2 6 /* 4210 */
  404. sys sys_truncate64 2
  405. sys sys_ftruncate64 2
  406. sys sys_newstat 2
  407. sys sys_newlstat 2
  408. sys sys_newfstat 2 /* 4215 */
  409. sys sys_pivot_root 2
  410. sys sys_mincore 3
  411. sys sys_madvise 3
  412. sys sys_getdents64 3
  413. sys sys32_fcntl64 3 /* 4220 */
  414. .endm
  415. .macro sys function, nargs
  416. PTR function
  417. .endm
  418. sys_call_table:
  419. syscalltable
  420. .macro sys function, nargs
  421. .byte nargs
  422. .endm
  423. sys_narg_table:
  424. syscalltable