xref: /plan9-contrib/sys/src/9/vt4/syscall.c (revision f80d550d5bc48502e65b5d8bc4e8aaf82d4c6b0f)
1d6dfd9efSDavid du Colombier #include "u.h"
2d6dfd9efSDavid du Colombier #include "../port/lib.h"
3d6dfd9efSDavid du Colombier #include "mem.h"
4d6dfd9efSDavid du Colombier #include "dat.h"
5d6dfd9efSDavid du Colombier #include "fns.h"
6d6dfd9efSDavid du Colombier #include "../port/error.h"
7d6dfd9efSDavid du Colombier #include "../port/systab.h"
8d6dfd9efSDavid du Colombier 
9d6dfd9efSDavid du Colombier #include <tos.h>
10d6dfd9efSDavid du Colombier #include "ureg.h"
11d6dfd9efSDavid du Colombier 
12d6dfd9efSDavid du Colombier typedef struct {
13d6dfd9efSDavid du Colombier 	uintptr	pc;
14d6dfd9efSDavid du Colombier 	Ureg*	arg0;
15d6dfd9efSDavid du Colombier 	char*	arg1;
16d6dfd9efSDavid du Colombier 	char	msg[ERRMAX];
17d6dfd9efSDavid du Colombier 	Ureg*	old;
18d6dfd9efSDavid du Colombier 	Ureg	ureg;
19d6dfd9efSDavid du Colombier } NFrame;
20d6dfd9efSDavid du Colombier 
21d6dfd9efSDavid du Colombier /*
22d6dfd9efSDavid du Colombier  *   Return user to state before notify()
23d6dfd9efSDavid du Colombier  */
24d6dfd9efSDavid du Colombier static void
noted(Ureg * cur,uintptr arg0)25d6dfd9efSDavid du Colombier noted(Ureg* cur, uintptr arg0)
26d6dfd9efSDavid du Colombier {
27d6dfd9efSDavid du Colombier 	Ureg *nur;
28d6dfd9efSDavid du Colombier 	NFrame *nf;
29d6dfd9efSDavid du Colombier 
30d6dfd9efSDavid du Colombier 	qlock(&up->debug);
31d6dfd9efSDavid du Colombier 	if(arg0 != NRSTR && !up->notified){
32d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
33d6dfd9efSDavid du Colombier 		pprint("call to noted() when not notified\n");
34d6dfd9efSDavid du Colombier 		pexit("Suicide", 0);
35d6dfd9efSDavid du Colombier 	}
36d6dfd9efSDavid du Colombier 	up->notified = 0;
37d6dfd9efSDavid du Colombier 	fpunoted();
38d6dfd9efSDavid du Colombier 
39d6dfd9efSDavid du Colombier 	nf = up->ureg;
40d6dfd9efSDavid du Colombier 
41d6dfd9efSDavid du Colombier 	/* sanity clause */
42d6dfd9efSDavid du Colombier 	if(!okaddr(PTR2UINT(nf), sizeof(NFrame), 0)){
43d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
44d6dfd9efSDavid du Colombier 		pprint("bad ureg in noted %#p\n", nf);
45d6dfd9efSDavid du Colombier 		pexit("Suicide", 0);
46d6dfd9efSDavid du Colombier 	}
47d6dfd9efSDavid du Colombier 
48d6dfd9efSDavid du Colombier 	/* don't let user change system status */
49d6dfd9efSDavid du Colombier 	nur = &nf->ureg;
50d6dfd9efSDavid du Colombier 	nur->status = cur->status;
51d6dfd9efSDavid du Colombier 
52d6dfd9efSDavid du Colombier 	memmove(cur, nur, sizeof(Ureg));
53d6dfd9efSDavid du Colombier 
54d6dfd9efSDavid du Colombier 	switch((int)arg0){
55d6dfd9efSDavid du Colombier 	case NCONT:
56d6dfd9efSDavid du Colombier 	case NRSTR:
57d6dfd9efSDavid du Colombier 		if(!okaddr(nur->pc, BY2SE, 0) || !okaddr(nur->usp, BY2SE, 0)){
58d6dfd9efSDavid du Colombier 			qunlock(&up->debug);
59d6dfd9efSDavid du Colombier 			pprint("suicide: trap in noted\n");
60d6dfd9efSDavid du Colombier 			pexit("Suicide", 0);
61d6dfd9efSDavid du Colombier 		}
62d6dfd9efSDavid du Colombier 		up->ureg = nf->old;
63d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
64d6dfd9efSDavid du Colombier 		break;
65d6dfd9efSDavid du Colombier 
66d6dfd9efSDavid du Colombier 	case NSAVE:
67d6dfd9efSDavid du Colombier 		if(!okaddr(nur->pc, BY2SE, 0) || !okaddr(nur->usp, BY2SE, 0)){
68d6dfd9efSDavid du Colombier 			qunlock(&up->debug);
69d6dfd9efSDavid du Colombier 			pprint("suicide: trap in noted\n");
70d6dfd9efSDavid du Colombier 			pexit("Suicide", 0);
71d6dfd9efSDavid du Colombier 		}
72d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
73d6dfd9efSDavid du Colombier 
74d6dfd9efSDavid du Colombier 		splhi();
75d6dfd9efSDavid du Colombier 		nf->arg1 = nf->msg;
76d6dfd9efSDavid du Colombier 		nf->arg0 = &nf->ureg;
77d6dfd9efSDavid du Colombier 		cur->r3 = PTR2UINT(nf->arg0);
78d6dfd9efSDavid du Colombier 		nf->pc = 0;
79d6dfd9efSDavid du Colombier 		cur->sp = PTR2UINT(nf);
80d6dfd9efSDavid du Colombier 		break;
81d6dfd9efSDavid du Colombier 
82d6dfd9efSDavid du Colombier 	default:
83d6dfd9efSDavid du Colombier 		pprint("unknown noted arg %#p\n", arg0);
84d6dfd9efSDavid du Colombier 		up->lastnote.flag = NDebug;
85d6dfd9efSDavid du Colombier 		/* fall through */
86d6dfd9efSDavid du Colombier 	case NDFLT:
87d6dfd9efSDavid du Colombier 		if(up->lastnote.flag == NDebug){
88d6dfd9efSDavid du Colombier 			qunlock(&up->debug);
89d6dfd9efSDavid du Colombier 			pprint("suicide: %s\n", up->lastnote.msg);
90d6dfd9efSDavid du Colombier 		}
91d6dfd9efSDavid du Colombier 		else
92d6dfd9efSDavid du Colombier 			qunlock(&up->debug);
93d6dfd9efSDavid du Colombier 		pexit(up->lastnote.msg, up->lastnote.flag != NDebug);
94d6dfd9efSDavid du Colombier 	}
95d6dfd9efSDavid du Colombier }
96d6dfd9efSDavid du Colombier 
97d6dfd9efSDavid du Colombier /*
98d6dfd9efSDavid du Colombier  *  Call user, if necessary, with note.
99d6dfd9efSDavid du Colombier  *  Pass user the Ureg struct and the note on his stack.
100d6dfd9efSDavid du Colombier  */
101d6dfd9efSDavid du Colombier int
notify(Ureg * ureg)102d6dfd9efSDavid du Colombier notify(Ureg* ureg)
103d6dfd9efSDavid du Colombier {
104d6dfd9efSDavid du Colombier 	int l;
105d6dfd9efSDavid du Colombier 	Note *n;
106d6dfd9efSDavid du Colombier 	ulong s;
107d6dfd9efSDavid du Colombier 	uintptr sp;
108d6dfd9efSDavid du Colombier 	NFrame *nf;
109d6dfd9efSDavid du Colombier 
110d6dfd9efSDavid du Colombier 	if(up->procctl)
111d6dfd9efSDavid du Colombier 		procctl(up);
112d6dfd9efSDavid du Colombier 	if(up->nnote == 0)
113d6dfd9efSDavid du Colombier 		return 0;
114d6dfd9efSDavid du Colombier 
115d6dfd9efSDavid du Colombier 	fpunotify(ureg);
116d6dfd9efSDavid du Colombier 
117d6dfd9efSDavid du Colombier 	s = spllo();
118d6dfd9efSDavid du Colombier 	qlock(&up->debug);
119d6dfd9efSDavid du Colombier 	up->notepending = 0;
120d6dfd9efSDavid du Colombier 	n = &up->note[0];
121d6dfd9efSDavid du Colombier 	if(strncmp(n->msg, "sys:", 4) == 0){
122d6dfd9efSDavid du Colombier 		l = strlen(n->msg);
123d6dfd9efSDavid du Colombier 		if(l > ERRMAX-15)	/* " pc=0x12345678\0" */
124d6dfd9efSDavid du Colombier 			l = ERRMAX-15;
125d6dfd9efSDavid du Colombier 		sprint(n->msg+l, " pc=%#.8lux", ureg->pc);
126d6dfd9efSDavid du Colombier 	}
127d6dfd9efSDavid du Colombier 
128d6dfd9efSDavid du Colombier 	if(n->flag!=NUser && (up->notified || up->notify==0)){
129d6dfd9efSDavid du Colombier 		if(n->flag == NDebug)
130d6dfd9efSDavid du Colombier 			pprint("suicide: %s\n", n->msg);
131d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
132d6dfd9efSDavid du Colombier 		pexit(n->msg, n->flag!=NDebug);
133d6dfd9efSDavid du Colombier 	}
134d6dfd9efSDavid du Colombier 
135d6dfd9efSDavid du Colombier 	if(up->notified) {
136d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
137d6dfd9efSDavid du Colombier 		splhi();
138d6dfd9efSDavid du Colombier 		return 0;
139d6dfd9efSDavid du Colombier 	}
140d6dfd9efSDavid du Colombier 
141d6dfd9efSDavid du Colombier 	if(up->notify == nil){
142d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
143d6dfd9efSDavid du Colombier 		pexit(n->msg, n->flag!=NDebug);
144d6dfd9efSDavid du Colombier 	}
145d6dfd9efSDavid du Colombier 	if(!okaddr(PTR2UINT(up->notify), BY2WD, 0)){
146d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
147d6dfd9efSDavid du Colombier 		pprint("suicide: notify function address %#p\n", up->notify);
148d6dfd9efSDavid du Colombier 		pexit("Suicide", 0);
149d6dfd9efSDavid du Colombier 	}
150d6dfd9efSDavid du Colombier 
151d6dfd9efSDavid du Colombier 	sp = ureg->usp & ~(BY2V-1);
152d6dfd9efSDavid du Colombier 	sp -= (sizeof(NFrame)+BY2V-1) & ~(BY2V-1);
153d6dfd9efSDavid du Colombier 
154d6dfd9efSDavid du Colombier 	if(!okaddr(sp, sizeof(NFrame), 1)){
155d6dfd9efSDavid du Colombier 		qunlock(&up->debug);
156d6dfd9efSDavid du Colombier 		pprint("suicide: notify stack address %#p\n", sp);
157d6dfd9efSDavid du Colombier 		pexit("Suicide", 0);
158d6dfd9efSDavid du Colombier 	}
159d6dfd9efSDavid du Colombier 
160d6dfd9efSDavid du Colombier 	nf = UINT2PTR(sp);
161d6dfd9efSDavid du Colombier 	memmove(&nf->ureg, ureg, sizeof(Ureg));
162d6dfd9efSDavid du Colombier 	nf->old = up->ureg;
163d6dfd9efSDavid du Colombier 	up->ureg = nf;
164d6dfd9efSDavid du Colombier 	memmove(nf->msg, up->note[0].msg, ERRMAX);
165d6dfd9efSDavid du Colombier 	nf->arg1 = nf->msg;
166d6dfd9efSDavid du Colombier 	nf->arg0 = up->ureg;
167d6dfd9efSDavid du Colombier 	ureg->r3 = PTR2UINT(up->ureg);
168d6dfd9efSDavid du Colombier 	nf->pc = 0;
169d6dfd9efSDavid du Colombier 
170d6dfd9efSDavid du Colombier 	ureg->usp = sp;
171d6dfd9efSDavid du Colombier 	ureg->pc = PTR2UINT(up->notify);
172d6dfd9efSDavid du Colombier 	up->notified = 1;
173d6dfd9efSDavid du Colombier 	up->nnote--;
174d6dfd9efSDavid du Colombier 	memmove(&up->lastnote, &up->note[0], sizeof(Note));
175d6dfd9efSDavid du Colombier 	memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
176d6dfd9efSDavid du Colombier 
177d6dfd9efSDavid du Colombier 	qunlock(&up->debug);
178d6dfd9efSDavid du Colombier 	splx(s);
179d6dfd9efSDavid du Colombier 	return 1;
180d6dfd9efSDavid du Colombier }
181d6dfd9efSDavid du Colombier 
182d6dfd9efSDavid du Colombier /*
183d6dfd9efSDavid du Colombier  *  system calls and 'orrible notes
184d6dfd9efSDavid du Colombier  */
185d6dfd9efSDavid du Colombier 
186d6dfd9efSDavid du Colombier /* TO DO: make this trap a separate asm entry point, as on some other RISC architectures */
187d6dfd9efSDavid du Colombier void
syscall(Ureg * ureg)188d6dfd9efSDavid du Colombier syscall(Ureg* ureg)
189d6dfd9efSDavid du Colombier {
190d6dfd9efSDavid du Colombier 	char *e;
191d6dfd9efSDavid du Colombier 	u32int s;
192d6dfd9efSDavid du Colombier 	uintptr sp;
193d6dfd9efSDavid du Colombier 	long ret;
194d6dfd9efSDavid du Colombier 	int i, scallnr;
195d6dfd9efSDavid du Colombier 
196d6dfd9efSDavid du Colombier 	cycles(&up->kentry);
197d6dfd9efSDavid du Colombier 
198d6dfd9efSDavid du Colombier 	m->syscall++;
199d6dfd9efSDavid du Colombier 	up->insyscall = 1;
200d6dfd9efSDavid du Colombier 	up->pc = ureg->pc;
201d6dfd9efSDavid du Colombier 	up->dbgreg = ureg;
202d6dfd9efSDavid du Colombier 
203d6dfd9efSDavid du Colombier 	if(up->procctl == Proc_tracesyscall){
204d6dfd9efSDavid du Colombier 		up->procctl = Proc_stopme;
205d6dfd9efSDavid du Colombier 		procctl(up);
206d6dfd9efSDavid du Colombier 	}
207d6dfd9efSDavid du Colombier 
208d6dfd9efSDavid du Colombier 	scallnr = ureg->r3;
209d6dfd9efSDavid du Colombier 	up->scallnr = scallnr;
210d6dfd9efSDavid du Colombier 	if(scallnr == RFORK)
211d6dfd9efSDavid du Colombier 		fpusysrfork(ureg);
212d6dfd9efSDavid du Colombier 	spllo();
213d6dfd9efSDavid du Colombier 
214d6dfd9efSDavid du Colombier 	sp = ureg->sp;
215d6dfd9efSDavid du Colombier 	up->nerrlab = 0;
216d6dfd9efSDavid du Colombier 	ret = -1;
217d6dfd9efSDavid du Colombier 	if(!waserror()){
218d6dfd9efSDavid du Colombier 		if(scallnr >= nsyscall){
219d6dfd9efSDavid du Colombier 			pprint("bad sys call number %d pc %lux\n",
220d6dfd9efSDavid du Colombier 				scallnr, ureg->pc);
221d6dfd9efSDavid du Colombier 			postnote(up, 1, "sys: bad sys call", NDebug);
222d6dfd9efSDavid du Colombier 			error(Ebadarg);
223d6dfd9efSDavid du Colombier 		}
224d6dfd9efSDavid du Colombier 
225d6dfd9efSDavid du Colombier 		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
226d6dfd9efSDavid du Colombier 			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
227d6dfd9efSDavid du Colombier 
228d6dfd9efSDavid du Colombier 		up->s = *((Sargs*)(sp+BY2WD));
229d6dfd9efSDavid du Colombier 		up->psstate = sysctab[scallnr];
230d6dfd9efSDavid du Colombier 
231d6dfd9efSDavid du Colombier 		ret = systab[scallnr](up->s.args);
232d6dfd9efSDavid du Colombier 		poperror();
233d6dfd9efSDavid du Colombier 	}else{
234d6dfd9efSDavid du Colombier 		/* failure: save the error buffer for errstr */
235d6dfd9efSDavid du Colombier 		e = up->syserrstr;
236d6dfd9efSDavid du Colombier 		up->syserrstr = up->errstr;
237d6dfd9efSDavid du Colombier 		up->errstr = e;
238d6dfd9efSDavid du Colombier 	}
239d6dfd9efSDavid du Colombier 	if(up->nerrlab){
240d6dfd9efSDavid du Colombier 		print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);
241d6dfd9efSDavid du Colombier 		for(i = 0; i < NERR; i++)
242d6dfd9efSDavid du Colombier 			print("sp=%#p pc=%#p\n",
243d6dfd9efSDavid du Colombier 				up->errlab[i].sp, up->errlab[i].pc);
244d6dfd9efSDavid du Colombier 		panic("error stack");
245d6dfd9efSDavid du Colombier 	}
246d6dfd9efSDavid du Colombier 
247d6dfd9efSDavid du Colombier 	/*
248d6dfd9efSDavid du Colombier 	 * Put return value in frame.
249d6dfd9efSDavid du Colombier 	 */
250d6dfd9efSDavid du Colombier 	ureg->r3 = ret;
251d6dfd9efSDavid du Colombier 
252d6dfd9efSDavid du Colombier 	if(up->procctl == Proc_tracesyscall){
253d6dfd9efSDavid du Colombier 		up->procctl = Proc_stopme;
254d6dfd9efSDavid du Colombier 		s = splhi();
255d6dfd9efSDavid du Colombier 		procctl(up);
256d6dfd9efSDavid du Colombier 		splx(s);
257d6dfd9efSDavid du Colombier 	}
258d6dfd9efSDavid du Colombier 
259d6dfd9efSDavid du Colombier 	up->insyscall = 0;
260d6dfd9efSDavid du Colombier 	up->psstate = 0;
261d6dfd9efSDavid du Colombier 
262d6dfd9efSDavid du Colombier 	if(scallnr == NOTED)
263d6dfd9efSDavid du Colombier 		noted(ureg, *(uintptr*)(sp+BY2SE));
264d6dfd9efSDavid du Colombier 
265d6dfd9efSDavid du Colombier 	splhi();
266d6dfd9efSDavid du Colombier 	if(scallnr != RFORK && (up->procctl || up->nnote))
267d6dfd9efSDavid du Colombier 		notify(ureg);
268d6dfd9efSDavid du Colombier 
269d6dfd9efSDavid du Colombier 	/* if we delayed sched because we held a lock, sched now */
270d6dfd9efSDavid du Colombier 	if(up->delaysched){
271d6dfd9efSDavid du Colombier 		sched();
272d6dfd9efSDavid du Colombier 		splhi();
273d6dfd9efSDavid du Colombier 	}
274d6dfd9efSDavid du Colombier 	kexit(ureg);
275d6dfd9efSDavid du Colombier }
276d6dfd9efSDavid du Colombier 
277d6dfd9efSDavid du Colombier /*
278*f80d550dSDavid du Colombier  * called in syscallfmt.c, sysfile.c, sysproc.c
279d6dfd9efSDavid du Colombier  */
280d6dfd9efSDavid du Colombier void
validalign(uintptr addr,unsigned align)281*f80d550dSDavid du Colombier validalign(uintptr addr, unsigned align)
282d6dfd9efSDavid du Colombier {
283*f80d550dSDavid du Colombier 	/*
284*f80d550dSDavid du Colombier 	 * Plan 9 is a 32-bit O/S, and the hardware it runs on
285*f80d550dSDavid du Colombier 	 * does not usually have instructions which move 64-bit
286*f80d550dSDavid du Colombier 	 * quantities directly, synthesizing the operations
287*f80d550dSDavid du Colombier 	 * with 32-bit move instructions. Therefore, the compiler
288*f80d550dSDavid du Colombier 	 * (and hardware) usually only enforce 32-bit alignment,
289*f80d550dSDavid du Colombier 	 * if at all.
290*f80d550dSDavid du Colombier 	 *
291*f80d550dSDavid du Colombier 	 * Take this out if the architecture warrants it.
292*f80d550dSDavid du Colombier 	 */
293*f80d550dSDavid du Colombier 	if(align == sizeof(vlong))
294*f80d550dSDavid du Colombier 		align = sizeof(long);
295*f80d550dSDavid du Colombier 
296*f80d550dSDavid du Colombier 	/*
297*f80d550dSDavid du Colombier 	 * Check align is a power of 2, then addr alignment.
298*f80d550dSDavid du Colombier 	 */
299*f80d550dSDavid du Colombier 	if((align != 0 && !(align & (align-1))) && !(addr & (align-1)))
300*f80d550dSDavid du Colombier 		return;
301*f80d550dSDavid du Colombier 	postnote(up, 1, "sys: odd address", NDebug);
302d6dfd9efSDavid du Colombier 	error(Ebadarg);
303*f80d550dSDavid du Colombier 	/*NOTREACHED*/
304d6dfd9efSDavid du Colombier }
305d6dfd9efSDavid du Colombier 
306d6dfd9efSDavid du Colombier uintptr
sysexecstack(uintptr stack,int argc)307d6dfd9efSDavid du Colombier sysexecstack(uintptr stack, int argc)
308d6dfd9efSDavid du Colombier {
309d6dfd9efSDavid du Colombier 	/*
310d6dfd9efSDavid du Colombier 	 * Given a current bottom-of-stack and a count
311d6dfd9efSDavid du Colombier 	 * of pointer arguments to be pushed onto it followed
312d6dfd9efSDavid du Colombier 	 * by an integer argument count, return a suitably
313d6dfd9efSDavid du Colombier 	 * aligned new bottom-of-stack which will satisfy any
314d6dfd9efSDavid du Colombier 	 * hardware stack-alignment contraints.
315d6dfd9efSDavid du Colombier 	 * Rounding the stack down to be aligned with the
316d6dfd9efSDavid du Colombier 	 * natural size of a pointer variable usually suffices,
317d6dfd9efSDavid du Colombier 	 * but some architectures impose further restrictions,
318d6dfd9efSDavid du Colombier 	 * e.g. 32-bit SPARC, where the stack must be 8-byte
319d6dfd9efSDavid du Colombier 	 * aligned although pointers and integers are 32-bits.
320d6dfd9efSDavid du Colombier 	 */
321d6dfd9efSDavid du Colombier 	USED(argc);
322d6dfd9efSDavid du Colombier 
323d6dfd9efSDavid du Colombier 	return STACKALIGN(stack);
324d6dfd9efSDavid du Colombier }
325d6dfd9efSDavid du Colombier 
326d6dfd9efSDavid du Colombier long
execregs(ulong entry,ulong ssize,ulong nargs)327d6dfd9efSDavid du Colombier execregs(ulong entry, ulong ssize, ulong nargs)
328d6dfd9efSDavid du Colombier {
329d6dfd9efSDavid du Colombier 	ulong *sp;
330d6dfd9efSDavid du Colombier 	Ureg *ureg;
331d6dfd9efSDavid du Colombier 
332d6dfd9efSDavid du Colombier 	fpusysprocsetup(up);			/* up is a guess */
333d6dfd9efSDavid du Colombier 
334d6dfd9efSDavid du Colombier 	sp = (ulong*)(USTKTOP - ssize);
335d6dfd9efSDavid du Colombier 	*--sp = nargs;
336d6dfd9efSDavid du Colombier 
337d6dfd9efSDavid du Colombier 	ureg = up->dbgreg;
338d6dfd9efSDavid du Colombier //	memset(ureg, 0, 31*sizeof(ulong));
339d6dfd9efSDavid du Colombier 	ureg->usp = (ulong)sp;
340d6dfd9efSDavid du Colombier 	ureg->pc = entry;
341d6dfd9efSDavid du Colombier 	ureg->srr1 &= ~MSR_FP;			/* disable floating point */
342d6dfd9efSDavid du Colombier 
343d6dfd9efSDavid du Colombier 	/*
344d6dfd9efSDavid du Colombier 	 * return the address of kernel/user shared data
345d6dfd9efSDavid du Colombier 	 * (e.g. clock stuff)
346d6dfd9efSDavid du Colombier 	 */
347d6dfd9efSDavid du Colombier 	return USTKTOP-sizeof(Tos);
348d6dfd9efSDavid du Colombier }
349d6dfd9efSDavid du Colombier 
350d6dfd9efSDavid du Colombier void
sysprocsetup(Proc * p)351d6dfd9efSDavid du Colombier sysprocsetup(Proc* p)
352d6dfd9efSDavid du Colombier {
353d6dfd9efSDavid du Colombier 	fpusysprocsetup(p);
354d6dfd9efSDavid du Colombier }
355d6dfd9efSDavid du Colombier 
356d6dfd9efSDavid du Colombier /*
357d6dfd9efSDavid du Colombier  *  Craft a return frame which will cause the child to pop out of
358d6dfd9efSDavid du Colombier  *  the scheduler in user mode with the return register zero.  Set
359d6dfd9efSDavid du Colombier  *  pc to point to a l.s return function.
360d6dfd9efSDavid du Colombier  */
361d6dfd9efSDavid du Colombier void
forkchild(Proc * p,Ureg * ureg)362d6dfd9efSDavid du Colombier forkchild(Proc *p, Ureg *ureg)
363d6dfd9efSDavid du Colombier {
364d6dfd9efSDavid du Colombier 	Ureg *cureg;
365d6dfd9efSDavid du Colombier 
366d6dfd9efSDavid du Colombier //print("%lud setting up for forking child %lud\n", up->pid, p->pid);
367d6dfd9efSDavid du Colombier 	p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Ureg)+2*BY2SE);
368d6dfd9efSDavid du Colombier 	p->sched.pc = (ulong)forkret;
369d6dfd9efSDavid du Colombier 
370d6dfd9efSDavid du Colombier 	cureg = (Ureg*)(p->sched.sp+2*BY2SE);
371d6dfd9efSDavid du Colombier 	memmove(cureg, ureg, sizeof(Ureg));
372d6dfd9efSDavid du Colombier 
373d6dfd9efSDavid du Colombier 	/* syscall returns 0 for child */
374d6dfd9efSDavid du Colombier 	cureg->r3 = 0;
375d6dfd9efSDavid du Colombier 
376d6dfd9efSDavid du Colombier 	/* Things from bottom of syscall which were never executed */
377d6dfd9efSDavid du Colombier 	p->psstate = 0;
378d6dfd9efSDavid du Colombier 	p->insyscall = 0;
379d6dfd9efSDavid du Colombier 
380d6dfd9efSDavid du Colombier 	fpusysrforkchild(p, cureg, up);
381d6dfd9efSDavid du Colombier }
382