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