]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/bsd_ppc.c
2 * Copyright (c) 2000 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/kdebug.h>
40 #define ERESTART -1 /* restart syscall */
41 #define EJUSTRETURN -2 /* don't modify regs, just return */
43 struct unix_syscallargs
{
46 int arg1
, arg2
,arg3
,arg4
,arg5
,arg6
,arg7
,arg8
,arg9
;
48 struct sysent
{ /* system call table */
49 unsigned short sy_narg
; /* number of args */
50 char sy_parallel
; /* can execute in parallel */
51 char sy_funnel
; /* funnel type */
52 unsigned long (*sy_call
)(void *, void *, int *); /* implementing function */
55 #define KERNEL_FUNNEL 1
56 #define NETWORK_FUNNEL 2
58 extern funnel_t
* kernel_flock
;
59 extern funnel_t
* network_flock
;
61 extern struct sysent sysent
[];
63 void *get_bsdtask_info(
66 int set_bsduthreadargs (
67 thread_act_t
, struct pcb
*,
68 struct unix_syscallargs
*);
70 void * get_bsduthreadarg(
76 int, int, int, int, int, int, int );
79 * Function: unix_syscall
81 * Inputs: pcb - pointer to Process Control Block
82 * arg1 - arguments to mach system calls
104 struct ppc_saved_state
*regs
;
106 struct sysent
*callp
;
114 struct unix_syscallargs sarg
;
121 thread
= current_act();
122 p
= get_bsdtask_info(current_task());
123 rval
= (int *)get_bsduthreadrval(thread
);
126 ** Get index into sysent table
131 ** Set up call pointer
133 callp
= (code
>= nsysent
) ? &sysent
[63] : &sysent
[code
];
135 sarg
. flavor
= (callp
== sysent
)? 1: 0;
138 callp
= (code
>= nsysent
) ? &sysent
[63] : &sysent
[code
];
146 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_START
,
147 arg1
, arg2
, arg3
, arg4
, 0);
149 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_START
,
150 sarg
.r3
, arg1
, arg2
, arg3
, 0);
160 if(callp
->sy_funnel
== NETWORK_FUNNEL
) {
161 (void) thread_funnel_set(network_flock
, TRUE
);
164 (void) thread_funnel_set(kernel_flock
, TRUE
);
167 set_bsduthreadargs(thread
,pcb
,&sarg
);
170 if (callp
->sy_narg
> 8)
171 panic("unix_syscall: max arg count exceeded");
175 /* r4 is volatile, if we set it to regs->r4 here the child
176 * will have parents r4 after execve */
179 error
= 0; /* Start with a good value */
182 ** the PPC runtime calls cerror after every unix system call, so
183 ** assume no error and adjust the "pc" to skip this call.
184 ** It will be set back to the cerror call if an error is detected.
187 vt
= get_bsduthreadarg(thread
);
188 counter_always(c_syscalls_unix
++);
189 current_task()->syscalls_unix
++;
190 error
= (*(callp
->sy_call
))(p
, (void *)vt
, rval
);
192 if (error
== ERESTART
) {
195 else if (error
!= EJUSTRETURN
) {
199 /* set the "pc" to execute cerror routine */
201 } else { /* (not error) */
206 /* else (error == EJUSTRETURN) { nothing } */
208 (void) thread_funnel_set(current_thread()->funnel_lock
, FALSE
);
211 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_END
,
212 error
, rval
[0], rval
[1], 0, 0);
215 thread_exception_return();
219 unix_syscall_return(error
)
221 struct ppc_saved_state
*regs
;
223 struct sysent
*callp
;
231 struct unix_syscallargs sarg
;
234 thread
= current_act();
235 p
= get_bsdtask_info(current_task());
236 rval
= (int *)get_bsduthreadrval(thread
);
237 pcb
= thread
->mact
.pcb
;
240 if (thread_funnel_get() == THR_FUNNEL_NULL
)
241 panic("Unix syscall return without funnel held");
244 ** Get index into sysent table
248 if (error
== ERESTART
) {
251 else if (error
!= EJUSTRETURN
) {
255 /* set the "pc" to execute cerror routine */
257 } else { /* (not error) */
262 /* else (error == EJUSTRETURN) { nothing } */
264 (void) thread_funnel_set(current_thread()->funnel_lock
, FALSE
);
267 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_END
,
268 error
, rval
[0], rval
[1], 0, 0);
271 thread_exception_return();