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