|
|
1.1 root 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.