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. .level LEVEL
  30. .text
  31. /* These should probably go in a header file somewhere.
  32. * They are duplicated in kernel/wrappers.S
  33. * Possibly we should consider consolidating these
  34. * register save/restore macros.
  35. */
  36. .macro reg_save regs
  37. #ifdef CONFIG_64BIT
  38. #warning NEEDS WORK for 64-bit
  39. #endif
  40. STREG %r3, PT_GR3(\regs)
  41. STREG %r4, PT_GR4(\regs)
  42. STREG %r5, PT_GR5(\regs)
  43. STREG %r6, PT_GR6(\regs)
  44. STREG %r7, PT_GR7(\regs)
  45. STREG %r8, PT_GR8(\regs)
  46. STREG %r9, PT_GR9(\regs)
  47. STREG %r10,PT_GR10(\regs)
  48. STREG %r11,PT_GR11(\regs)
  49. STREG %r12,PT_GR12(\regs)
  50. STREG %r13,PT_GR13(\regs)
  51. STREG %r14,PT_GR14(\regs)
  52. STREG %r15,PT_GR15(\regs)
  53. STREG %r16,PT_GR16(\regs)
  54. STREG %r17,PT_GR17(\regs)
  55. STREG %r18,PT_GR18(\regs)
  56. .endm
  57. .macro reg_restore regs
  58. LDREG PT_GR3(\regs), %r3
  59. LDREG PT_GR4(\regs), %r4
  60. LDREG PT_GR5(\regs), %r5
  61. LDREG PT_GR6(\regs), %r6
  62. LDREG PT_GR7(\regs), %r7
  63. LDREG PT_GR8(\regs), %r8
  64. LDREG PT_GR9(\regs), %r9
  65. LDREG PT_GR10(\regs),%r10
  66. LDREG PT_GR11(\regs),%r11
  67. LDREG PT_GR12(\regs),%r12
  68. LDREG PT_GR13(\regs),%r13
  69. LDREG PT_GR14(\regs),%r14
  70. LDREG PT_GR15(\regs),%r15
  71. LDREG PT_GR16(\regs),%r16
  72. LDREG PT_GR17(\regs),%r17
  73. LDREG PT_GR18(\regs),%r18
  74. .endm
  75. .import sys_fork
  76. ENTRY(hpux_fork_wrapper)
  77. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  78. ;! pointer in task
  79. reg_save %r1
  80. STREG %r2,-20(%r30)
  81. ldo 64(%r30),%r30
  82. STREG %r2,PT_GR19(%r1) ;! save for child
  83. STREG %r30,PT_GR21(%r1) ;! save for child
  84. LDREG PT_GR30(%r1),%r25
  85. mtctl %r25,%cr29
  86. copy %r1,%r24
  87. bl sys_clone,%r2
  88. ldi SIGCHLD,%r26
  89. LDREG -84(%r30),%r2
  90. fork_return:
  91. ldo -64(%r30),%r30
  92. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  93. reg_restore %r1
  94. /*
  95. * HP-UX wants pid (child gets parent pid, parent gets child pid)
  96. * in r28 and a flag in r29 (r29 == 1 for child, 0 for parent).
  97. * Linux fork returns 0 for child, pid for parent. Since HP-UX
  98. * libc stub throws away parent pid and returns 0 for child,
  99. * we'll just return 0 for parent pid now. Only applications
  100. * that jump directly to the gateway page (not supported) will
  101. * know the difference. We can fix this later if necessary.
  102. */
  103. ldo -1024(%r0),%r1
  104. comb,>>=,n %r28,%r1,fork_exit /* just let the syscall exit handle it */
  105. or,= %r28,%r0,%r0
  106. or,tr %r0,%r0,%r29 /* r28 <> 0, we are parent, set r29 to 0 */
  107. ldo 1(%r0),%r29 /* r28 == 0, we are child, set r29 to 1 */
  108. fork_exit:
  109. bv %r0(%r2)
  110. nop
  111. ENDPROC(hpux_fork_wrapper)
  112. /* Set the return value for the child */
  113. ENTRY(hpux_child_return)
  114. #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
  115. bl,n schedule_tail, %r2
  116. #endif
  117. LDREG TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
  118. b fork_return
  119. copy %r0,%r28
  120. ENDPROC(hpux_child_return)
  121. .import hpux_execve
  122. ENTRY(hpux_execv_wrapper)
  123. copy %r0,%r24 /* NULL environment */
  124. ENTRY(hpux_execve_wrapper)
  125. ldo TASK_REGS-TASK_SZ_ALGN-64(%r30),%r1 ;! get pt regs
  126. /*
  127. * Do we need to save/restore r3-r18 here?
  128. * I don't think so. why would new thread need old
  129. * threads registers?
  130. */
  131. /* Store arg0, arg1 and arg2 so that hpux_execve will find them */
  132. STREG %r26,PT_GR26(%r1)
  133. STREG %r25,PT_GR25(%r1)
  134. STREG %r24,PT_GR24(%r1)
  135. STREG %r2,-20(%r30)
  136. ldo 64(%r30),%r30
  137. bl hpux_execve,%r2
  138. copy %r1,%arg0
  139. ldo -64(%r30),%r30
  140. LDREG -20(%r30),%r2
  141. /* If exec succeeded we need to load the args */
  142. ldo -1024(%r0),%r1
  143. comb,>>= %r28,%r1,exec_error
  144. copy %r2,%r19
  145. ldo -TASK_SZ_ALGN-64(%r30),%r1 ;! get task ptr
  146. LDREG TASK_PT_GR26(%r1),%r26
  147. LDREG TASK_PT_GR25(%r1),%r25
  148. LDREG TASK_PT_GR24(%r1),%r24
  149. LDREG TASK_PT_GR23(%r1),%r23
  150. copy %r0,%r2 /* Flag to syscall_exit not to clear args */
  151. exec_error:
  152. bv %r0(%r19)
  153. nop
  154. ENDPROC(hpux_execv_wrapper)
  155. .import hpux_pipe
  156. /* HP-UX expects pipefd's returned in r28 & r29 */
  157. ENTRY(hpux_pipe_wrapper)
  158. STREG %r2,-20(%r30)
  159. ldo 64(%r30),%r30
  160. bl hpux_pipe,%r2
  161. ldo -56(%r30),%r26 /* pass local array to hpux_pipe */
  162. ldo -1024(%r0),%r1
  163. comb,>>= %r28,%r1,pipe_exit /* let syscall exit handle it */
  164. LDREG -84(%r30),%r2
  165. /* if success, load fd's from stack array */
  166. LDREG -56(%r30),%r28
  167. LDREG -52(%r30),%r29
  168. pipe_exit:
  169. bv %r0(%r2)
  170. ldo -64(%r30),%r30
  171. ENDPROC(hpux_pipe_wrapper)
  172. .import syscall_exit
  173. ENTRY(hpux_syscall_exit)
  174. /*
  175. *
  176. * HP-UX call return conventions:
  177. *
  178. * if error:
  179. * r22 = 1
  180. * r28 = errno value
  181. * r29 = secondary return value
  182. * else
  183. * r22 = 0
  184. * r28 = return value
  185. * r29 = secondary return value
  186. *
  187. * For now, we'll just check to see if r28 is < (unsigned long)-1024
  188. * (to handle addresses > 2 Gb) and if so set r22 to zero. If not,
  189. * we'll complement r28 and set r22 to 1. Wrappers will be
  190. * needed for syscalls that care about the secondary return value.
  191. * The wrapper may also need a way of avoiding the following code,
  192. * but we'll deal with that when it becomes necessary.
  193. */
  194. ldo -1024(%r0),%r1
  195. comb,<< %r28,%r1,no_error
  196. copy %r0,%r22
  197. subi 0,%r28,%r28
  198. ldo 1(%r0),%r22
  199. no_error:
  200. b,n syscall_exit
  201. ENDPROC(hpux_syscall_exit)
  202. .import hpux_unimplemented
  203. ENTRY(hpux_unimplemented_wrapper)
  204. b hpux_unimplemented
  205. STREG %r22,-64(%r30) /* overwrite arg8 with syscall number */
  206. ENDPROC(hpux_unimplemented_wrapper)