wrappers.S 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * Linux/PARISC Project (http://www.parisc-linux.org/)
  3. *
  4. * HP-UX System Call Wrapper routines and System Call Return Path
  5. *
  6. * Copyright (C) 2000 Hewlett-Packard (John Marvin)
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2, or (at your option)
  11. * any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. #ifdef CONFIG_64BIT
  23. #warning PA64 support needs more work...did first cut
  24. #endif
  25. #include <asm/asm-offsets.h>
  26. #include <asm/assembly.h>
  27. #include <asm/signal.h>
  28. #include <linux/linkage.h>
  29. #include <linux/init.h>
  30. .level LEVEL
  31. __HEAD
  32. /* These should probably go in a header file somewhere.
  33. * They are duplicated in kernel/wrappers.S
  34. * Possibly we should consider consolidating these
  35. * register save/restore macros.
  36. */
  37. .macro reg_save regs
  38. #ifdef CONFIG_64BIT
  39. #warning NEEDS WORK for 64-bit
  40. #endif
  41. STREG %r3, PT_GR3(\regs)
  42. STREG %r4, PT_GR4(\regs)
  43. STREG %r5, PT_GR5(\regs)
  44. STREG %r6, PT_GR6(\regs)
  45. STREG %r7, PT_GR7(\regs)
  46. STREG %r8, PT_GR8(\regs)
  47. STREG %r9, PT_GR9(\regs)
  48. STREG %r10,PT_GR10(\regs)
  49. STREG %r11,PT_GR11(\regs)
  50. STREG %r12,PT_GR12(\regs)
  51. STREG %r13,PT_GR13(\regs)
  52. STREG %r14,PT_GR14(\regs)
  53. STREG %r15,PT_GR15(\regs)
  54. STREG %r16,PT_GR16(\regs)
  55. STREG %r17,PT_GR17(\regs)
  56. STREG %r18,PT_GR18(\regs)
  57. .endm
  58. .macro reg_restore regs
  59. LDREG PT_GR3(\regs), %r3
  60. LDREG PT_GR4(\regs), %r4
  61. LDREG PT_GR5(\regs), %r5
  62. LDREG PT_GR6(\regs), %r6
  63. LDREG PT_GR7(\regs), %r7
  64. LDREG PT_GR8(\regs), %r8
  65. LDREG PT_GR9(\regs), %r9
  66. LDREG PT_GR10(\regs),%r10
  67. LDREG PT_GR11(\regs),%r11
  68. LDREG PT_GR12(\regs),%r12
  69. LDREG PT_GR13(\regs),%r13
  70. LDREG PT_GR14(\regs),%r14
  71. LDREG PT_GR15(\regs),%r15
  72. LDREG PT_GR16(\regs),%r16
  73. LDREG PT_GR17(\regs),%r17
  74. LDREG PT_GR18(\regs),%r18
  75. .endm
  76. .import sys_fork
  77. ENTRY(hpux_fork_wrapper)
  78. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  79. ;! pointer in task
  80. reg_save %r1
  81. STREG %r2,-20(%r30)
  82. ldo 64(%r30),%r30
  83. STREG %r2,PT_GR19(%r1) ;! save for child
  84. STREG %r30,PT_GR21(%r1) ;! save for child
  85. LDREG PT_GR30(%r1),%r25
  86. mtctl %r25,%cr29
  87. copy %r1,%r24
  88. bl sys_clone,%r2
  89. ldi SIGCHLD,%r26
  90. LDREG -84(%r30),%r2
  91. fork_return:
  92. ldo -64(%r30),%r30
  93. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  94. reg_restore %r1
  95. /*
  96. * HP-UX wants pid (child gets parent pid, parent gets child pid)
  97. * in r28 and a flag in r29 (r29 == 1 for child, 0 for parent).
  98. * Linux fork returns 0 for child, pid for parent. Since HP-UX
  99. * libc stub throws away parent pid and returns 0 for child,
  100. * we'll just return 0 for parent pid now. Only applications
  101. * that jump directly to the gateway page (not supported) will
  102. * know the difference. We can fix this later if necessary.
  103. */
  104. ldo -1024(%r0),%r1
  105. comb,>>=,n %r28,%r1,fork_exit /* just let the syscall exit handle it */
  106. or,= %r28,%r0,%r0
  107. or,tr %r0,%r0,%r29 /* r28 <> 0, we are parent, set r29 to 0 */
  108. ldo 1(%r0),%r29 /* r28 == 0, we are child, set r29 to 1 */
  109. fork_exit:
  110. bv %r0(%r2)
  111. nop
  112. ENDPROC(hpux_fork_wrapper)
  113. /* Set the return value for the child */
  114. ENTRY(hpux_child_return)
  115. #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
  116. bl,n schedule_tail, %r2
  117. #endif
  118. LDREG TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
  119. b fork_return
  120. copy %r0,%r28
  121. ENDPROC(hpux_child_return)
  122. .import hpux_execve
  123. ENTRY(hpux_execv_wrapper)
  124. copy %r0,%r24 /* NULL environment */
  125. ENTRY(hpux_execve_wrapper)
  126. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  127. /*
  128. * Do we need to save/restore r3-r18 here?
  129. * I don't think so. why would new thread need old
  130. * threads registers?
  131. */
  132. /* Store arg0, arg1 and arg2 so that hpux_execve will find them */
  133. STREG %r26,PT_GR26(%r1)
  134. STREG %r25,PT_GR25(%r1)
  135. STREG %r24,PT_GR24(%r1)
  136. STREG %r2,-20(%r30)
  137. ldo 64(%r30),%r30
  138. bl hpux_execve,%r2
  139. copy %r1,%arg0
  140. ldo -64(%r30),%r30
  141. LDREG -20(%r30),%r2
  142. /* If exec succeeded we need to load the args */
  143. ldo -1024(%r0),%r1
  144. comb,>>= %r28,%r1,exec_error
  145. copy %r2,%r19
  146. ldo -TASK_SZ_ALGN-64(%r30),%r1 ;! get task ptr
  147. LDREG TASK_PT_GR26(%r1),%r26
  148. LDREG TASK_PT_GR25(%r1),%r25
  149. LDREG TASK_PT_GR24(%r1),%r24
  150. LDREG TASK_PT_GR23(%r1),%r23
  151. copy %r0,%r2 /* Flag to syscall_exit not to clear args */
  152. exec_error:
  153. bv %r0(%r19)
  154. nop
  155. ENDPROC(hpux_execv_wrapper)
  156. .import hpux_pipe
  157. /* HP-UX expects pipefd's returned in r28 & r29 */
  158. ENTRY(hpux_pipe_wrapper)
  159. STREG %r2,-20(%r30)
  160. ldo 64(%r30),%r30
  161. bl hpux_pipe,%r2
  162. ldo -56(%r30),%r26 /* pass local array to hpux_pipe */
  163. ldo -1024(%r0),%r1
  164. comb,>>= %r28,%r1,pipe_exit /* let syscall exit handle it */
  165. LDREG -84(%r30),%r2
  166. /* if success, load fd's from stack array */
  167. LDREG -56(%r30),%r28
  168. LDREG -52(%r30),%r29
  169. pipe_exit:
  170. bv %r0(%r2)
  171. ldo -64(%r30),%r30
  172. ENDPROC(hpux_pipe_wrapper)
  173. .import syscall_exit
  174. ENTRY(hpux_syscall_exit)
  175. /*
  176. *
  177. * HP-UX call return conventions:
  178. *
  179. * if error:
  180. * r22 = 1
  181. * r28 = errno value
  182. * r29 = secondary return value
  183. * else
  184. * r22 = 0
  185. * r28 = return value
  186. * r29 = secondary return value
  187. *
  188. * For now, we'll just check to see if r28 is < (unsigned long)-1024
  189. * (to handle addresses > 2 Gb) and if so set r22 to zero. If not,
  190. * we'll complement r28 and set r22 to 1. Wrappers will be
  191. * needed for syscalls that care about the secondary return value.
  192. * The wrapper may also need a way of avoiding the following code,
  193. * but we'll deal with that when it becomes necessary.
  194. */
  195. ldo -1024(%r0),%r1
  196. comb,<< %r28,%r1,no_error
  197. copy %r0,%r22
  198. subi 0,%r28,%r28
  199. ldo 1(%r0),%r22
  200. no_error:
  201. b,n syscall_exit
  202. ENDPROC(hpux_syscall_exit)
  203. .import hpux_unimplemented
  204. ENTRY(hpux_unimplemented_wrapper)
  205. b hpux_unimplemented
  206. STREG %r22,-64(%r30) /* overwrite arg8 with syscall number */
  207. ENDPROC(hpux_unimplemented_wrapper)