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

嵌入式Linux

开发平台:

Unix_Linux

  1. #include <asm/asmmacro.h>
  2. #include <asm/offsets.h>
  3. #include <asm/signal.h>
  4. #include "../kernel/minstate.h"
  5. /*
  6.  * execve() is special because in case of success, we need to
  7.  * setup a null register window frame (in case an IA-32 process
  8.  * is exec'ing an IA-64 program).
  9.  */
  10. ENTRY(ia32_execve)
  11. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
  12. alloc loc1=ar.pfs,3,2,4,0
  13. mov loc0=rp
  14. .body
  15. zxt4 out0=in0 // filename
  16. ;; // stop bit between alloc and call
  17. zxt4 out1=in1 // argv
  18. zxt4 out2=in2 // envp
  19. add out3=16,sp // regs
  20. br.call.sptk.few rp=sys32_execve
  21. 1: cmp.ge p6,p0=r8,r0
  22. mov ar.pfs=loc1 // restore ar.pfs
  23. ;;
  24. (p6) mov ar.pfs=r0 // clear ar.pfs in case of success
  25. sxt4 r8=r8 // return 64-bit result
  26. mov rp=loc0
  27. br.ret.sptk.few rp
  28. END(ia32_execve)
  29. ENTRY(ia32_clone)
  30. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
  31. alloc r16=ar.pfs,2,2,4,0
  32. DO_SAVE_SWITCH_STACK
  33. mov loc0=rp
  34. mov loc1=r16 // save ar.pfs across do_fork
  35. .body
  36. zxt4 out1=in1 // newsp
  37. mov out3=0 // stacksize
  38. adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
  39. zxt4 out0=in0 // out0 = clone_flags
  40. br.call.sptk.many rp=do_fork
  41. .ret0: .restore sp
  42. adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
  43. mov ar.pfs=loc1
  44. mov rp=loc0
  45. br.ret.sptk.many rp
  46. END(ia32_clone)
  47. ENTRY(sys32_rt_sigsuspend)
  48. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  49. alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs
  50. mov loc0=rp
  51. mov out0=in0 // mask
  52. mov out1=in1 // sigsetsize
  53. mov out2=sp // out2 = &sigscratch
  54. .fframe 16
  55. adds sp=-16,sp // allocate dummy "sigscratch"
  56. ;;
  57. .body
  58. br.call.sptk.many rp=ia32_rt_sigsuspend
  59. 1: .restore sp
  60. adds sp=16,sp
  61. mov rp=loc0
  62. mov ar.pfs=loc1
  63. br.ret.sptk.many rp
  64. END(sys32_rt_sigsuspend)
  65. ENTRY(sys32_sigsuspend)
  66. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
  67. alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs
  68. mov loc0=rp
  69. mov out0=in2 // mask (first two args are ignored)
  70. ;;
  71. mov out1=sp // out1 = &sigscratch
  72. .fframe 16
  73. adds sp=-16,sp // allocate dummy "sigscratch"
  74. .body
  75. br.call.sptk.many rp=ia32_sigsuspend
  76. 1: .restore sp
  77. adds sp=16,sp
  78. mov rp=loc0
  79. mov ar.pfs=loc1
  80. br.ret.sptk.many rp
  81. END(sys32_sigsuspend)
  82. GLOBAL_ENTRY(ia32_ret_from_clone)
  83. PT_REGS_UNWIND_INFO(0)
  84. /*
  85.  * We need to call schedule_tail() to complete the scheduling process.
  86.  * Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the
  87.  * address of the previously executing task.
  88.  */
  89. br.call.sptk.many rp=ia64_invoke_schedule_tail
  90. .ret1: adds r2=IA64_TASK_PTRACE_OFFSET,r13
  91. ;;
  92. ld8 r2=[r2]
  93. ;;
  94. mov r8=0
  95. tbit.nz p6,p0=r2,PT_TRACESYS_BIT
  96. (p6) br.cond.spnt .ia32_strace_check_retval
  97. ;; // prevent RAW on r8
  98. END(ia32_ret_from_clone)
  99. // fall thrugh
  100. GLOBAL_ENTRY(ia32_ret_from_syscall)
  101. PT_REGS_UNWIND_INFO(0)
  102. cmp.ge p6,p7=r8,r0                      // syscall executed successfully?
  103. adds r2=IA64_PT_REGS_R8_OFFSET+16,sp    // r2 = &pt_regs.r8
  104. ;;
  105. alloc r3=ar.pfs,0,0,0,0 // drop the syscall argument frame
  106. st8 [r2]=r8                             // store return value in slot for r8
  107. br.cond.sptk.many ia64_leave_kernel
  108. END(ia32_ret_from_syscall)
  109. //
  110. // Invoke a system call, but do some tracing before and after the call.
  111. // We MUST preserve the current register frame throughout this routine
  112. // because some system calls (such as ia64_execve) directly
  113. // manipulate ar.pfs.
  114. //
  115. // Input:
  116. // r8 = syscall number
  117. // b6 = syscall entry point
  118. //
  119. GLOBAL_ENTRY(ia32_trace_syscall)
  120. PT_REGS_UNWIND_INFO(0)
  121. mov r3=-38
  122. adds r2=IA64_PT_REGS_R8_OFFSET+16,sp
  123. ;;
  124. st8 [r2]=r3 // initialize return code to -ENOSYS
  125. br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args
  126. .ret2: br.call.sptk.few rp=b6 // do the syscall
  127. .ia32_strace_check_retval:
  128. cmp.lt p6,p0=r8,r0 // syscall failed?
  129. adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
  130. ;;
  131. st8.spill [r2]=r8 // store return value in slot for r8
  132. br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value
  133. .ret4: alloc r2=ar.pfs,0,0,0,0 // drop the syscall argument frame
  134. br.cond.sptk.many ia64_leave_kernel
  135. END(ia32_trace_syscall)
  136. GLOBAL_ENTRY(sys32_vfork)
  137. alloc r16=ar.pfs,2,2,4,0;;
  138. mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD // out0 = clone_flags
  139. br.cond.sptk.few .fork1 // do the work
  140. END(sys32_vfork)
  141. GLOBAL_ENTRY(sys32_fork)
  142. .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
  143. alloc r16=ar.pfs,2,2,4,0
  144. mov out0=SIGCHLD // out0 = clone_flags
  145. ;;
  146. .fork1:
  147. mov loc0=rp
  148. mov loc1=r16 // save ar.pfs across do_fork
  149. DO_SAVE_SWITCH_STACK
  150. .body
  151. mov out1=0
  152. mov out3=0
  153. adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
  154. br.call.sptk.few rp=do_fork
  155. .ret5: mov ar.pfs=loc1
  156. .restore sp
  157. adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
  158. mov rp=loc0
  159. br.ret.sptk.many rp
  160. END(sys32_fork)
  161. .rodata
  162. .align 8
  163. .globl ia32_syscall_table
  164. ia32_syscall_table:
  165. data8 sys32_ni_syscall   /* 0 -  old "setup(" system call*/
  166. data8 sys_exit
  167. data8 sys32_fork
  168. data8 sys_read
  169. data8 sys_write
  170. data8 sys_open   /* 5 */
  171. data8 sys_close
  172. data8 sys32_waitpid
  173. data8 sys_creat
  174. data8 sys_link
  175. data8 sys_unlink   /* 10 */
  176. data8 ia32_execve
  177. data8 sys_chdir
  178. data8 sys32_time
  179. data8 sys_mknod
  180. data8 sys_chmod   /* 15 */
  181. data8 sys_lchown /* 16-bit version */
  182. data8 sys32_ni_syscall   /* old break syscall holder */
  183. data8 sys32_ni_syscall
  184. data8 sys32_lseek
  185. data8 sys_getpid   /* 20 */
  186. data8 sys_mount
  187. data8 sys_oldumount
  188. data8 sys_setuid /* 16-bit version */
  189. data8 sys_getuid /* 16-bit version */
  190. data8 sys32_ni_syscall /* sys_stime is not supported on IA64 */  /* 25 */
  191. data8 sys32_ptrace
  192. data8 sys32_alarm
  193. data8 sys32_ni_syscall
  194. data8 sys32_pause
  195. data8 sys32_utime   /* 30 */
  196. data8 sys32_ni_syscall   /* old stty syscall holder */
  197. data8 sys32_ni_syscall   /* old gtty syscall holder */
  198. data8 sys_access
  199. data8 sys_nice
  200. data8 sys32_ni_syscall   /* 35 */   /* old ftime syscall holder */
  201. data8 sys_sync
  202. data8 sys_kill
  203. data8 sys_rename
  204. data8 sys_mkdir
  205. data8 sys_rmdir   /* 40 */
  206. data8 sys_dup
  207. data8 sys32_pipe
  208. data8 sys32_times
  209. data8 sys32_ni_syscall   /* old prof syscall holder */
  210. data8 sys_brk   /* 45 */
  211. data8 sys_setgid /* 16-bit version */
  212. data8 sys_getgid /* 16-bit version */
  213. data8 sys32_signal
  214. data8 sys_geteuid /* 16-bit version */
  215. data8 sys_getegid /* 16-bit version */   /* 50 */
  216. data8 sys_acct
  217. data8 sys_umount   /* recycled never used phys( */
  218. data8 sys32_ni_syscall   /* old lock syscall holder */
  219. data8 sys32_ioctl
  220. data8 sys32_fcntl   /* 55 */
  221. data8 sys32_ni_syscall   /* old mpx syscall holder */
  222. data8 sys_setpgid
  223. data8 sys32_ni_syscall   /* old ulimit syscall holder */
  224. data8 sys32_ni_syscall
  225. data8 sys_umask   /* 60 */
  226. data8 sys_chroot
  227. data8 sys_ustat
  228. data8 sys_dup2
  229. data8 sys_getppid
  230. data8 sys_getpgrp   /* 65 */
  231. data8 sys_setsid
  232. data8 sys32_sigaction
  233. data8 sys32_ni_syscall
  234. data8 sys32_ni_syscall
  235. data8 sys_setreuid /* 16-bit version */   /* 70 */
  236. data8 sys_setregid /* 16-bit version */
  237. data8 sys32_sigsuspend
  238. data8 sys32_sigpending
  239. data8 sys_sethostname
  240. data8 sys32_setrlimit   /* 75 */
  241. data8 sys32_old_getrlimit
  242. data8 sys32_getrusage
  243. data8 sys32_gettimeofday
  244. data8 sys32_settimeofday
  245. data8 sys32_getgroups16   /* 80 */
  246. data8 sys32_setgroups16
  247. data8 sys32_old_select
  248. data8 sys_symlink
  249. data8 sys32_ni_syscall
  250. data8 sys_readlink   /* 85 */
  251. data8 sys_uselib
  252. data8 sys_swapon
  253. data8 sys_reboot
  254. data8 sys32_readdir
  255. data8 sys32_mmap   /* 90 */
  256. data8 sys32_munmap
  257. data8 sys_truncate
  258. data8 sys_ftruncate
  259. data8 sys_fchmod
  260. data8 sys_fchown /* 16-bit version */   /* 95 */
  261. data8 sys_getpriority
  262. data8 sys_setpriority
  263. data8 sys32_ni_syscall   /* old profil syscall holder */
  264. data8 sys32_statfs
  265. data8 sys32_fstatfs   /* 100 */
  266. data8 sys32_ioperm
  267. data8 sys32_socketcall
  268. data8 sys_syslog
  269. data8 sys32_setitimer
  270. data8 sys32_getitimer   /* 105 */
  271. data8 sys32_newstat
  272. data8 sys32_newlstat
  273. data8 sys32_newfstat
  274. data8 sys32_ni_syscall
  275. data8 sys32_iopl   /* 110 */
  276. data8 sys_vhangup
  277. data8 sys32_ni_syscall /* used to be sys_idle */
  278. data8 sys32_ni_syscall
  279. data8 sys32_wait4
  280. data8 sys_swapoff   /* 115 */
  281. data8 sys32_sysinfo
  282. data8 sys32_ipc
  283. data8 sys_fsync
  284. data8 sys32_sigreturn
  285. data8 ia32_clone   /* 120 */
  286. data8 sys_setdomainname
  287. data8 sys32_newuname
  288. data8 sys32_modify_ldt
  289. data8 sys32_ni_syscall /* adjtimex */
  290. data8 sys32_mprotect   /* 125 */
  291. data8 sys32_sigprocmask
  292. data8 sys32_ni_syscall /* create_module */
  293. data8 sys32_ni_syscall /* init_module */
  294. data8 sys32_ni_syscall /* delete_module */
  295. data8 sys32_ni_syscall /* get_kernel_syms */  /* 130 */
  296. data8 sys32_quotactl
  297. data8 sys_getpgid
  298. data8 sys_fchdir
  299. data8 sys32_ni_syscall /* sys_bdflush */
  300. data8 sys_sysfs /* 135 */
  301. data8 sys32_personality
  302. data8 sys32_ni_syscall   /* for afs_syscall */
  303. data8 sys_setfsuid /* 16-bit version */
  304. data8 sys_setfsgid /* 16-bit version */
  305. data8 sys_llseek   /* 140 */
  306. data8 sys32_getdents
  307. data8 sys32_select
  308. data8 sys_flock
  309. data8 sys32_msync
  310. data8 sys32_readv   /* 145 */
  311. data8 sys32_writev
  312. data8 sys_getsid
  313. data8 sys_fdatasync
  314. data8 sys32_sysctl
  315. data8 sys_mlock   /* 150 */
  316. data8 sys_munlock
  317. data8 sys_mlockall
  318. data8 sys_munlockall
  319. data8 sys_sched_setparam
  320. data8 sys_sched_getparam  /* 155 */
  321. data8 sys_sched_setscheduler
  322. data8 sys_sched_getscheduler
  323. data8 sys_sched_yield
  324. data8 sys_sched_get_priority_max
  325. data8 sys_sched_get_priority_min  /* 160 */
  326. data8 sys32_sched_rr_get_interval
  327. data8 sys32_nanosleep
  328. data8 sys_mremap
  329. data8 sys_setresuid /* 16-bit version */
  330. data8 sys32_getresuid16 /* 16-bit version */   /* 165 */
  331. data8 sys32_ni_syscall /* vm86 */
  332. data8 sys32_ni_syscall /* sys_query_module */
  333. data8 sys_poll
  334. data8 sys32_ni_syscall /* nfsservctl */
  335. data8 sys_setresgid   /* 170 */
  336. data8 sys32_getresgid16
  337. data8 sys_prctl
  338. data8 sys32_rt_sigreturn
  339. data8 sys32_rt_sigaction
  340. data8 sys32_rt_sigprocmask /* 175 */
  341. data8 sys_rt_sigpending
  342. data8 sys32_rt_sigtimedwait
  343. data8 sys32_rt_sigqueueinfo
  344. data8 sys32_rt_sigsuspend
  345. data8 sys32_pread   /* 180 */
  346. data8 sys32_pwrite
  347. data8 sys_chown /* 16-bit version */
  348. data8 sys_getcwd
  349. data8 sys_capget
  350. data8 sys_capset   /* 185 */
  351. data8 sys32_sigaltstack
  352. data8 sys32_sendfile
  353. data8 sys32_ni_syscall   /* streams1 */
  354. data8 sys32_ni_syscall   /* streams2 */
  355. data8 sys32_vfork   /* 190 */
  356. data8 sys32_getrlimit
  357. data8 sys32_mmap2
  358. data8 sys32_truncate64
  359. data8 sys32_ftruncate64
  360. data8 sys32_stat64   /* 195 */
  361. data8 sys32_lstat64
  362. data8 sys32_fstat64
  363. data8 sys_lchown
  364. data8 sys_getuid
  365. data8 sys_getgid   /* 200 */
  366. data8 sys_geteuid
  367. data8 sys_getegid
  368. data8 sys_setreuid
  369. data8 sys_setregid
  370. data8 sys_getgroups   /* 205 */
  371. data8 sys_setgroups
  372. data8 sys_fchown
  373. data8 sys_setresuid
  374. data8 sys_getresuid
  375. data8 sys_setresgid   /* 210 */
  376. data8 sys_getresgid
  377. data8 sys_chown
  378. data8 sys_setuid
  379. data8 sys_setgid
  380. data8 sys_setfsuid   /* 215 */
  381. data8 sys_setfsgid
  382. data8 sys_pivot_root
  383. data8 sys_mincore
  384. data8 sys_madvise
  385. data8 sys_getdents64   /* 220 */
  386. data8 sys32_fcntl64
  387. data8 sys_ni_syscall /* reserved for TUX */
  388. data8 sys_ni_syscall /* reserved for Security */
  389. data8 sys_gettid
  390. data8 sys_readahead   /* 225 */
  391. data8 sys_ni_syscall
  392. data8 sys_ni_syscall
  393. data8 sys_ni_syscall
  394. data8 sys_ni_syscall
  395. /*
  396.  *  CAUTION: If any system calls are added beyond this point
  397.  * then the check in `arch/ia64/kernel/ivt.S' will have
  398.  * to be modified also.  You've been warned.
  399.  */