]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/bsd_ppc.c
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 #include <mach/mach_types.h>
23 #include <mach/exception_types.h>
24 #include <mach/error.h>
25 #include <kern/counters.h>
26 #include <kern/syscall_sw.h>
27 #include <kern/task.h>
28 #include <kern/thread.h>
29 #include <ppc/thread.h>
30 #include <kern/thread_act.h>
31 #include <ppc/thread_act.h>
33 #include <ppc/proc_reg.h>
35 #include <ppc/exception.h>
36 #include <kern/assert.h>
38 #include <sys/syscall.h>
39 #include <sys/ktrace.h>
40 #include <sys/kdebug.h>
43 #define ERESTART -1 /* restart syscall */
44 #define EJUSTRETURN -2 /* don't modify regs, just return */
46 struct unix_syscallargs
{
49 int arg1
, arg2
,arg3
,arg4
,arg5
,arg6
,arg7
,arg8
,arg9
;
51 struct sysent
{ /* system call table */
52 unsigned short sy_narg
; /* number of args */
53 char sy_parallel
; /* can execute in parallel */
54 char sy_funnel
; /* funnel type */
55 unsigned long (*sy_call
)(void *, void *, int *); /* implementing function */
58 #define KERNEL_FUNNEL 1
59 #define NETWORK_FUNNEL 2
61 extern funnel_t
* kernel_flock
;
62 extern funnel_t
* network_flock
;
64 extern struct sysent sysent
[];
66 void *get_bsdtask_info(
69 int set_bsduthreadargs (
70 thread_act_t
, struct pcb
*,
71 struct unix_syscallargs
*);
73 void * get_bsduthreadarg(
79 int, int, int, int, int, int, int );
82 * Function: unix_syscall
84 * Inputs: pcb - pointer to Process Control Block
85 * arg1 - arguments to mach system calls
107 struct ppc_saved_state
*regs
;
109 struct sysent
*callp
;
117 struct proc
*current_proc();
119 struct unix_syscallargs sarg
;
125 thread
= current_act();
127 rval
= (int *)get_bsduthreadrval(thread
);
130 * Set up call pointer
132 callp
= (code
>= nsysent
) ? &sysent
[63] : &sysent
[code
];
134 sarg
. flavor
= (callp
== sysent
)? 1: 0;
137 callp
= (code
>= nsysent
) ? &sysent
[63] : &sysent
[code
];
143 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_START
,
144 arg1
, arg2
, arg3
, arg4
, 0);
146 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_START
,
147 sarg
.r3
, arg1
, arg2
, arg3
, 0);
157 if(callp
->sy_funnel
== NETWORK_FUNNEL
) {
158 (void) thread_funnel_set(network_flock
, TRUE
);
160 (void) thread_funnel_set(kernel_flock
, TRUE
);
163 set_bsduthreadargs(thread
,pcb
,&sarg
);
165 if (callp
->sy_narg
> 8)
166 panic("unix_syscall: max arg count exceeded");
171 * r4 is volatile, if we set it to regs->r4 here the child
172 * will have parents r4 after execve
176 error
= 0; /* Start with a good value */
179 ** the PPC runtime calls cerror after every unix system call, so
180 ** assume no error and adjust the "pc" to skip this call.
181 ** It will be set back to the cerror call if an error is detected.
184 vt
= get_bsduthreadarg(thread
);
185 counter_always(c_syscalls_unix
++);
186 current_task()->syscalls_unix
++;
188 ktrsyscall(p
, code
, callp
->sy_narg
, vt
);
190 error
= (*(callp
->sy_call
))(p
, (void *)vt
, rval
);
192 regs
= find_user_regs(thread
);
193 if (regs
== (struct ppc_saved_state
*)0)
194 panic("No user savearea while returning from system call");
196 if (error
== ERESTART
) {
198 } else if (error
!= EJUSTRETURN
) {
201 /* set the "pc" to execute cerror routine */
203 } else { /* (not error) */
208 /* else (error == EJUSTRETURN) { nothing } */
210 ktrsysret(p
, code
, error
, rval
[0]);
212 (void) thread_funnel_set(current_thread()->funnel_lock
, FALSE
);
215 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_END
,
216 error
, rval
[0], rval
[1], 0, 0);
219 thread_exception_return();
223 unix_syscall_return(error
)
225 struct ppc_saved_state
*regs
;
227 struct sysent
*callp
;
235 struct proc
*current_proc();
237 struct unix_syscallargs sarg
;
240 thread
= current_act();
242 rval
= (int *)get_bsduthreadrval(thread
);
243 pcb
= thread
->mact
.pcb
;
246 if (thread_funnel_get() == THR_FUNNEL_NULL
)
247 panic("Unix syscall return without funnel held");
250 * Get index into sysent table
254 if (error
== ERESTART
) {
256 } else if (error
!= EJUSTRETURN
) {
259 /* set the "pc" to execute cerror routine */
261 } else { /* (not error) */
266 /* else (error == EJUSTRETURN) { nothing } */
268 ktrsysret(p
, code
, error
, rval
[0]);
270 (void) thread_funnel_set(current_thread()->funnel_lock
, FALSE
);
273 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_END
,
274 error
, rval
[0], rval
[1], 0, 0);
277 thread_exception_return();