]> git.saurik.com Git - apple/xnu.git/blob - bsd/dev/ppc/systemcalls.c
xnu-201.19.3.tar.gz
[apple/xnu.git] / bsd / dev / ppc / systemcalls.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * Copyright (c) 1997 Apple Computer, Inc.
24 *
25 * PowerPC Family: System Call handlers.
26 *
27 * HISTORY
28 * 27-July-97 A. Ramesh
29 * Adopted for Common Core.
30 */
31
32 #include <mach/mach_types.h>
33 #include <mach/error.h>
34
35 #include <kern/syscall_sw.h>
36 #include <kern/kdp.h>
37
38 #include <machdep/ppc/frame.h>
39 #include <machdep/ppc/thread.h>
40 #include <machdep/ppc/asm.h>
41 #include <machdep/ppc/proc_reg.h>
42 #include <machdep/ppc/trap.h>
43 #include <machdep/ppc/exception.h>
44
45
46 #define ERESTART -1 /* restart syscall */
47 #define EJUSTRETURN -2 /* don't modify regs, just return */
48
49
50 struct unix_syscallargs {
51 int flavor;
52 int r3;
53 int arg1, arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9;
54 };
55 extern struct sysent { /* system call table */
56 int16_t sy_narg; /* number of args */
57 int16_t sy_parallel;/* can execute in parallel */
58 int32_t (*sy_call)(); /* implementing function */
59 } sysent[];
60
61 /*
62 ** Function: unix_syscall
63 **
64 ** Inputs: pcb - pointer to Process Control Block
65 ** arg1 - arguments to mach system calls
66 ** arg2
67 ** arg3
68 ** arg4
69 ** arg5
70 ** arg6
71 ** arg7
72 **
73 ** Outputs: none
74 */
75 void
76 unix_syscall(
77 struct pcb * pcb,
78 int arg1,
79 int arg2,
80 int arg3,
81 int arg4,
82 int arg5,
83 int arg6,
84 int arg7
85 )
86 {
87 struct ppc_saved_state *regs;
88 thread_t thread;
89 struct proc *p;
90 struct sysent *callp;
91 int nargs, error;
92 unsigned short code;
93 int rval[2];
94 struct unix_syscallargs sarg;
95
96 if (!USERMODE(pcb->ss.srr1))
97 panic("unix_syscall");
98
99 regs = &pcb->ss;
100 thread = current_thread();
101
102
103 /*
104 ** Get index into sysent table
105 */
106 code = regs->r0;
107
108
109 /*
110 ** Set up call pointer
111 */
112 callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
113
114 sarg. flavor = (callp == sysent): 1: 0;
115 sarg. r3 = regs->r3;
116 sarg. arg1 = arg1;
117 sarg. arg2 = arg2;
118 sarg. arg3 = arg3;
119 sarg. arg4 = arg4;
120 sarg. arg5 = arg5;
121 sarg. arg6 = arg6;
122 sarg. arg7 = arg7;
123
124 set_bsduthreadargs(thread,pcb,&sarg);
125
126
127 if (callp->sy_narg > 8)
128 panic("unix_syscall: max arg count exceeded");
129
130 rval[0] = 0;
131
132 /* r4 is volatile, if we set it to regs->r4 here the child
133 * will have parents r4 after execve */
134 rval[1] = 0;
135
136 error = 0; /* Start with a good value */
137
138 /*
139 ** the PPC runtime calls cerror after every unix system call, so
140 ** assume no error and adjust the "pc" to skip this call.
141 ** It will be set back to the cerror call if an error is detected.
142 */
143 regs->srr0 += 4;
144 vt = get_bsduthreadarg(thread);
145 p = ((struct proc *)get_bsdtask_info(current_task()));
146 error = (*(callp->sy_call))(p, (caddr_t)vt, rval);
147
148 if (error == ERESTART) {
149 regs->srr0 -= 8;
150 }
151 else if (error != EJUSTRETURN) {
152 if (error)
153 {
154 regs->r3 = error;
155 /* set the "pc" to execute cerror routine */
156 regs->srr0 -= 4;
157 } else { /* (not error) */
158 regs->r3 = rval[0];
159 regs->r4 = rval[1];
160 }
161 }
162 /* else (error == EJUSTRETURN) { nothing } */
163
164 thread_exception_return();
165 /* NOTREACHED */
166
167 }
168