1 /* $NetBSD: m68k_syscall.c,v 1.37 2009/01/11 20:40:31 martin Exp $ */
4 * Portions Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the NetBSD
18 * Foundation, Inc. and its contributors.
19 * 4. Neither the name of The NetBSD Foundation nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
37 * Copyright (c) 1982, 1986, 1990, 1993
38 * The Regents of the University of California. All rights reserved.
40 * This code is derived from software contributed to Berkeley by
41 * the Systems Programming Group of the University of Utah Computer
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * from: Utah $Hdr: trap.c 1.37 92/12/20$
70 * @(#)trap.c 8.5 (Berkeley) 1/4/94
73 * Copyright (c) 1988 University of Utah.
75 * This code is derived from software contributed to Berkeley by
76 * the Systems Programming Group of the University of Utah Computer
79 * Redistribution and use in source and binary forms, with or without
80 * modification, are permitted provided that the following conditions
82 * 1. Redistributions of source code must retain the above copyright
83 * notice, this list of conditions and the following disclaimer.
84 * 2. Redistributions in binary form must reproduce the above copyright
85 * notice, this list of conditions and the following disclaimer in the
86 * documentation and/or other materials provided with the distribution.
87 * 3. All advertising materials mentioning features or use of this software
88 * must display the following acknowledgement:
89 * This product includes software developed by the University of
90 * California, Berkeley and its contributors.
91 * 4. Neither the name of the University nor the names of its contributors
92 * may be used to endorse or promote products derived from this software
93 * without specific prior written permission.
95 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
96 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
97 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
98 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
99 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
100 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
101 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
102 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
103 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
104 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
107 * from: Utah $Hdr: trap.c 1.37 92/12/20$
109 * @(#)trap.c 8.5 (Berkeley) 1/4/94
112 #include <sys/cdefs.h>
113 __KERNEL_RCSID(0, "$NetBSD: m68k_syscall.c,v 1.37 2009/01/11 20:40:31 martin Exp $");
115 #include "opt_execfmt.h"
116 #include "opt_compat_netbsd.h"
117 #include "opt_compat_aout_m68k.h"
120 #include <sys/param.h>
121 #include <sys/systm.h>
122 #include <sys/proc.h>
123 #include <sys/pool.h>
124 #include <sys/acct.h>
125 #include <sys/kernel.h>
127 #include <sys/savar.h>
128 #include <sys/syscall.h>
129 #include <sys/syscallvar.h>
130 #include <sys/syslog.h>
131 #include <sys/ktrace.h>
133 #include <machine/psl.h>
134 #include <machine/cpu.h>
135 #include <machine/reg.h>
137 #include <uvm/uvm_extern.h>
140 * Defined in machine-specific code (usually trap.c)
141 * XXX: This will disappear when all m68k ports share common trap() code...
143 extern void machine_userret(struct lwp
*, struct frame
*, u_quad_t
);
145 void syscall(register_t
, struct frame
);
147 #ifdef COMPAT_AOUT_M68K
148 void aoutm68k_syscall_intern(struct proc
*);
150 static void syscall_plain(register_t
, struct lwp
*, struct frame
*);
151 static void syscall_fancy(register_t
, struct lwp
*, struct frame
*);
155 * Process a system call.
158 syscall(register_t code
, struct frame frame
)
165 if (!USERMODE(frame
.f_sr
))
170 sticks
= p
->p_sticks
;
171 l
->l_md
.md_regs
= frame
.f_regs
;
172 LWP_CACHE_CREDS(l
, p
);
175 if (__predict_false((l
->l_savp
)
176 && (l
->l_savp
->savp_pflags
& SAVP_FLAG_DELIVERING
)))
177 l
->l_savp
->savp_pflags
&= ~SAVP_FLAG_DELIVERING
;
180 (p
->p_md
.md_syscall
)(code
, l
, &frame
);
182 machine_userret(l
, &frame
, sticks
);
186 syscall_intern(struct proc
*p
)
189 if (trace_is_enabled(p
))
190 p
->p_md
.md_syscall
= syscall_fancy
;
192 p
->p_md
.md_syscall
= syscall_plain
;
195 #ifdef COMPAT_AOUT_M68K
197 * Not worth the effort of a whole new set of syscall_{plain,fancy} functions
200 aoutm68k_syscall_intern(struct proc
*p
)
203 if (trace_is_enabled(p
))
204 p
->p_md
.md_syscall
= syscall_fancy
;
206 p
->p_md
.md_syscall
= syscall_plain
;
211 syscall_plain(register_t code
, struct lwp
*l
, struct frame
*frame
)
214 const struct sysent
*callp
;
217 register_t args
[16], rval
[2];
218 struct proc
*p
= l
->l_proc
;
220 nsys
= p
->p_emul
->e_nsysent
;
221 callp
= p
->p_emul
->e_sysent
;
223 params
= (char *)frame
->f_regs
[SP
] + sizeof(int);
228 * Code is first argument, followed by actual args.
230 code
= fuword(params
);
231 params
+= sizeof(int);
232 #if defined(COMPAT_13) || defined(COMPAT_16)
234 * XXX sigreturn requires special stack manipulation
235 * that is only done if entered via the sigreturn
236 * trap. Cannot allow it here so make sure we fail.
240 case SYS_compat_13_sigreturn13
:
243 case SYS_compat_16___sigreturn14
:
252 * Like syscall, but code is a quad, so as to maintain
253 * quad alignment for the rest of the arguments.
255 code
= fuword(params
+ _QUAD_LOWWORD
* sizeof(int));
256 params
+= sizeof(quad_t
);
262 if (code
< 0 || code
>= nsys
)
263 callp
+= p
->p_emul
->e_nosys
; /* illegal */
267 argsize
= callp
->sy_argsize
;
269 error
= copyin(params
, (void *)args
, argsize
);
275 rval
[1] = frame
->f_regs
[D1
];
276 error
= sy_call(callp
, l
, args
, rval
);
281 * Reinitialize proc pointer `p' as it may be different
282 * if this is a child returning from fork syscall.
286 frame
->f_regs
[D0
] = rval
[0];
287 frame
->f_regs
[D1
] = rval
[1];
288 frame
->f_sr
&= ~PSL_C
; /* carry bit */
291 * Starting with the 5.0 release all libc assembler
292 * stubs properly handle returning pointers in %a0
293 * themselves, so no need to copy the syscall return
294 * value there. However, -current binaries post 4.0
295 * but pre-5.0 might still require this copy, so we
296 * select this behaviour based on COMPAT_50 as we have
297 * no equivvalent for the exact in-between version.
299 #ifdef COMPAT_AOUT_M68K
301 extern struct emul emul_netbsd_aoutm68k
;
304 * Some pre-m68k ELF libc assembler stubs assume
305 * %a0 is preserved across system calls...
307 if (p
->p_emul
!= &emul_netbsd_aoutm68k
)
308 frame
->f_regs
[A0
] = rval
[0];
311 frame
->f_regs
[A0
] = rval
[0];
317 * We always enter through a `trap' instruction, which is 2
318 * bytes, so adjust the pc by that amount.
320 frame
->f_pc
= frame
->f_pc
- 2;
328 * XXX: SVR4 uses this code-path, so we may have
329 * to translate errno.
331 if (p
->p_emul
->e_errno
)
332 error
= p
->p_emul
->e_errno
[error
];
333 frame
->f_regs
[D0
] = error
;
334 frame
->f_sr
|= PSL_C
; /* carry bit */
340 syscall_fancy(register_t code
, struct lwp
*l
, struct frame
*frame
)
343 const struct sysent
*callp
;
346 register_t args
[16], rval
[2];
347 struct proc
*p
= l
->l_proc
;
349 nsys
= p
->p_emul
->e_nsysent
;
350 callp
= p
->p_emul
->e_sysent
;
352 params
= (char *)frame
->f_regs
[SP
] + sizeof(int);
357 * Code is first argument, followed by actual args.
359 code
= fuword(params
);
360 params
+= sizeof(int);
361 #if defined(COMPAT_13) || defined(COMPAT_16)
363 * XXX sigreturn requires special stack manipulation
364 * that is only done if entered via the sigreturn
365 * trap. Cannot allow it here so make sure we fail.
369 case SYS_compat_13_sigreturn13
:
372 case SYS_compat_16___sigreturn14
:
381 * Like syscall, but code is a quad, so as to maintain
382 * quad alignment for the rest of the arguments.
384 code
= fuword(params
+ _QUAD_LOWWORD
* sizeof(int));
385 params
+= sizeof(quad_t
);
391 if (code
< 0 || code
>= nsys
)
392 callp
+= p
->p_emul
->e_nosys
; /* illegal */
396 argsize
= callp
->sy_argsize
;
398 error
= copyin(params
, (void *)args
, argsize
);
403 if ((error
= trace_enter(code
, args
, callp
->sy_narg
)) != 0)
407 rval
[1] = frame
->f_regs
[D1
];
408 error
= sy_call(callp
, l
, args
, rval
);
413 * Reinitialize lwp/proc pointers as they may be different
414 * if this is a child returning from fork syscall.
418 frame
->f_regs
[D0
] = rval
[0];
419 frame
->f_regs
[D1
] = rval
[1];
420 frame
->f_sr
&= ~PSL_C
; /* carry bit */
422 /* see syscall_plain for a comment explaining this */
423 #ifdef COMPAT_AOUT_M68K
425 extern struct emul emul_netbsd_aoutm68k
;
428 * Some pre-m68k ELF libc assembler stubs assume
429 * %a0 is preserved across system calls...
431 if (p
->p_emul
!= &emul_netbsd_aoutm68k
)
432 frame
->f_regs
[A0
] = rval
[0];
435 frame
->f_regs
[A0
] = rval
[0];
441 * We always enter through a `trap' instruction, which is 2
442 * bytes, so adjust the pc by that amount.
444 frame
->f_pc
= frame
->f_pc
- 2;
452 * XXX: SVR4 uses this code-path, so we may have
453 * to translate errno.
455 if (p
->p_emul
->e_errno
)
456 error
= p
->p_emul
->e_errno
[error
];
457 frame
->f_regs
[D0
] = error
;
458 frame
->f_sr
|= PSL_C
; /* carry bit */
462 trace_exit(code
, rval
, error
);
466 child_return(void *arg
)
470 struct frame
*f
= (struct frame
*)l
->l_md
.md_regs
;
476 machine_userret(l
, f
, 0);
477 ktrsysret(SYS_fork
, 0, 0);
487 ucontext_t
*uc
= arg
;
488 struct lwp
*l
= curlwp
;
489 struct frame
*f
= (struct frame
*)l
->l_md
.md_regs
;
495 err
= cpu_setmcontext(l
, &uc
->uc_mcontext
, uc
->uc_flags
);
498 printf("Error %d from cpu_setmcontext.", err
);
501 pool_put(&lwp_uc_pool
, uc
);
503 machine_userret(l
, f
, 0);
507 * XXX This is a terrible name.
510 upcallret(struct lwp
*l
)
512 struct frame
*f
= (struct frame
*)l
->l_md
.md_regs
;
514 machine_userret(l
, f
, 0);