]>
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();
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 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
) {
199 else if (error
!= EJUSTRETURN
) {
203 /* set the "pc" to execute cerror routine */
205 } else { /* (not error) */
210 /* else (error == EJUSTRETURN) { nothing } */
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 unix_syscallargs sarg
;
238 thread
= current_act();
240 rval
= (int *)get_bsduthreadrval(thread
);
241 pcb
= thread
->mact
.pcb
;
244 if (thread_funnel_get() == THR_FUNNEL_NULL
)
245 panic("Unix syscall return without funnel held");
248 ** Get index into sysent table
252 if (error
== ERESTART
) {
255 else if (error
!= EJUSTRETURN
) {
259 /* set the "pc" to execute cerror routine */
261 } else { /* (not error) */
266 /* else (error == EJUSTRETURN) { nothing } */
268 (void) thread_funnel_set(current_thread()->funnel_lock
, FALSE
);
271 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC
, code
) | DBG_FUNC_END
,
272 error
, rval
[0], rval
[1], 0, 0);
275 thread_exception_return();