xref: /inferno-os/os/cerf250/main.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "../port/lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth #include "../port/error.h"
7*74a4d8c2SCharles.Forsyth #include "io.h"
8*74a4d8c2SCharles.Forsyth #include "version.h"
9*74a4d8c2SCharles.Forsyth 
10*74a4d8c2SCharles.Forsyth #define	MAXCONF		32
11*74a4d8c2SCharles.Forsyth 
12*74a4d8c2SCharles.Forsyth Mach *m = (Mach*)MACHADDR;
13*74a4d8c2SCharles.Forsyth Proc *up = 0;
14*74a4d8c2SCharles.Forsyth Vectorpage	*page0 = (Vectorpage*)KZERO;	/* doubly-mapped to AIVECADDR */
15*74a4d8c2SCharles.Forsyth Conf conf;
16*74a4d8c2SCharles.Forsyth 
17*74a4d8c2SCharles.Forsyth extern ulong kerndate;
18*74a4d8c2SCharles.Forsyth extern int cflag;
19*74a4d8c2SCharles.Forsyth extern int main_pool_pcnt;
20*74a4d8c2SCharles.Forsyth extern int heap_pool_pcnt;
21*74a4d8c2SCharles.Forsyth extern int image_pool_pcnt;
22*74a4d8c2SCharles.Forsyth ulong cpuidlecount;
23*74a4d8c2SCharles.Forsyth 
24*74a4d8c2SCharles.Forsyth char *confname[MAXCONF];
25*74a4d8c2SCharles.Forsyth char *confval[MAXCONF];
26*74a4d8c2SCharles.Forsyth int nconf;
27*74a4d8c2SCharles.Forsyth 
28*74a4d8c2SCharles.Forsyth void addconf(char *, char *);
29*74a4d8c2SCharles.Forsyth void	eepromscan(void);
30*74a4d8c2SCharles.Forsyth char*	getconf(char*);
31*74a4d8c2SCharles.Forsyth 
32*74a4d8c2SCharles.Forsyth void
doc(char * m)33*74a4d8c2SCharles.Forsyth doc(char *m)
34*74a4d8c2SCharles.Forsyth {
35*74a4d8c2SCharles.Forsyth 	USED(m);
36*74a4d8c2SCharles.Forsyth 	print("%s...\n", m);
37*74a4d8c2SCharles.Forsyth }
38*74a4d8c2SCharles.Forsyth 
39*74a4d8c2SCharles.Forsyth void
idoc(char * m)40*74a4d8c2SCharles.Forsyth idoc(char *m)
41*74a4d8c2SCharles.Forsyth {
42*74a4d8c2SCharles.Forsyth 	uartputs(m, strlen(m)); //xdelay(1);
43*74a4d8c2SCharles.Forsyth }
44*74a4d8c2SCharles.Forsyth 
45*74a4d8c2SCharles.Forsyth static void
poolsizeinit(void)46*74a4d8c2SCharles.Forsyth poolsizeinit(void)
47*74a4d8c2SCharles.Forsyth {
48*74a4d8c2SCharles.Forsyth 	ulong nb;
49*74a4d8c2SCharles.Forsyth 
50*74a4d8c2SCharles.Forsyth 	nb = conf.npage*BY2PG;
51*74a4d8c2SCharles.Forsyth 	poolsize(mainmem, (nb*main_pool_pcnt)/100, 0);
52*74a4d8c2SCharles.Forsyth 	poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0);
53*74a4d8c2SCharles.Forsyth 	poolsize(imagmem, (nb*image_pool_pcnt)/100, 1);
54*74a4d8c2SCharles.Forsyth }
55*74a4d8c2SCharles.Forsyth 
56*74a4d8c2SCharles.Forsyth static void
serialconsole(void)57*74a4d8c2SCharles.Forsyth serialconsole(void)
58*74a4d8c2SCharles.Forsyth {
59*74a4d8c2SCharles.Forsyth 	char *p;
60*74a4d8c2SCharles.Forsyth 	int port, baud;
61*74a4d8c2SCharles.Forsyth 
62*74a4d8c2SCharles.Forsyth 	p = getconf("console");
63*74a4d8c2SCharles.Forsyth 	if(p == nil)
64*74a4d8c2SCharles.Forsyth 		p = "0";
65*74a4d8c2SCharles.Forsyth 	if(p != nil){
66*74a4d8c2SCharles.Forsyth 		port = strtol(p, nil, 0);
67*74a4d8c2SCharles.Forsyth 		baud = 38400;
68*74a4d8c2SCharles.Forsyth 		p = getconf("baud");
69*74a4d8c2SCharles.Forsyth 		if(p != nil){
70*74a4d8c2SCharles.Forsyth 			baud = strtol(p, nil, 0);
71*74a4d8c2SCharles.Forsyth 			if(baud < 38400)
72*74a4d8c2SCharles.Forsyth 				baud = 38400;
73*74a4d8c2SCharles.Forsyth 		}
74*74a4d8c2SCharles.Forsyth 		uartspecial(port, baud, &kbdq, &printq, kbdcr2nl);
75*74a4d8c2SCharles.Forsyth 	}
76*74a4d8c2SCharles.Forsyth }
77*74a4d8c2SCharles.Forsyth 
78*74a4d8c2SCharles.Forsyth static char *hello = "Inferno\n";
79*74a4d8c2SCharles.Forsyth 
80*74a4d8c2SCharles.Forsyth void
main(void)81*74a4d8c2SCharles.Forsyth main(void)
82*74a4d8c2SCharles.Forsyth {
83*74a4d8c2SCharles.Forsyth 	memset(edata, 0, end-edata);		/* clear the BSS */
84*74a4d8c2SCharles.Forsyth 	memset(m, 0, sizeof(Mach));	/* clear the mach struct */
85*74a4d8c2SCharles.Forsyth 	conf.nmach = 1;
86*74a4d8c2SCharles.Forsyth 	archreset();
87*74a4d8c2SCharles.Forsyth 	idoc(hello);
88*74a4d8c2SCharles.Forsyth if(0){
89*74a4d8c2SCharles.Forsyth 	putcclkcfg(0);	/* leave turbo mode */
90*74a4d8c2SCharles.Forsyth 	COREREG->cccr = (COREREG->cccr & ~(7<<7)) | (4<<7);	/* turbo mode multiplier=2 */
91*74a4d8c2SCharles.Forsyth 	putcclkcfg(1);	/* enter turbo mode */
92*74a4d8c2SCharles.Forsyth }
93*74a4d8c2SCharles.Forsyth 	quotefmtinstall();
94*74a4d8c2SCharles.Forsyth 	idoc("confinit...\n");
95*74a4d8c2SCharles.Forsyth 	confinit();
96*74a4d8c2SCharles.Forsyth 	idoc("xinit...\n");
97*74a4d8c2SCharles.Forsyth 	xinit();
98*74a4d8c2SCharles.Forsyth 	idoc("mmuinit...\n");
99*74a4d8c2SCharles.Forsyth 	mmuinit();
100*74a4d8c2SCharles.Forsyth 	poolsizeinit();
101*74a4d8c2SCharles.Forsyth 	poolinit();
102*74a4d8c2SCharles.Forsyth 	idoc("trapinit...\n");
103*74a4d8c2SCharles.Forsyth 	trapinit();
104*74a4d8c2SCharles.Forsyth //	dmareset();
105*74a4d8c2SCharles.Forsyth 	idoc("printinit...\n");
106*74a4d8c2SCharles.Forsyth 	printinit();
107*74a4d8c2SCharles.Forsyth 	idoc("uartinstall...\n");
108*74a4d8c2SCharles.Forsyth 	uartinstall();
109*74a4d8c2SCharles.Forsyth 	eepromscan();
110*74a4d8c2SCharles.Forsyth 	doc("clockinit");
111*74a4d8c2SCharles.Forsyth 	clockinit();
112*74a4d8c2SCharles.Forsyth 	doc("screeninit");
113*74a4d8c2SCharles.Forsyth //	screeninit();
114*74a4d8c2SCharles.Forsyth 	doc("procinit");
115*74a4d8c2SCharles.Forsyth 	procinit();
116*74a4d8c2SCharles.Forsyth //	cpuidprint();
117*74a4d8c2SCharles.Forsyth 	doc("links");
118*74a4d8c2SCharles.Forsyth 	links();
119*74a4d8c2SCharles.Forsyth 	doc("chandevreset");
120*74a4d8c2SCharles.Forsyth 	chandevreset();
121*74a4d8c2SCharles.Forsyth 
122*74a4d8c2SCharles.Forsyth 	eve = strdup("inferno");
123*74a4d8c2SCharles.Forsyth 
124*74a4d8c2SCharles.Forsyth 	serialconsole();
125*74a4d8c2SCharles.Forsyth 	kbdinit();
126*74a4d8c2SCharles.Forsyth 
127*74a4d8c2SCharles.Forsyth 	print("%ld MHz id %8.8lux\n", (m->cpuhz+500000)/1000000, getcpuid());
128*74a4d8c2SCharles.Forsyth 	print("\nInferno %s\n", VERSION);
129*74a4d8c2SCharles.Forsyth 	print("Vita Nuova\n");
130*74a4d8c2SCharles.Forsyth 	print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag);
131*74a4d8c2SCharles.Forsyth print("pmcr=%8.8lux pwer=%8.8lux prer=%8.8lux pfer=%8.8lux pedr=%8.8lux pcfr=%8.8lux rcsr=%8.8lux\n",
132*74a4d8c2SCharles.Forsyth 	PMGRREG->pmcr, PMGRREG->pwer, PMGRREG->prer, PMGRREG->pfer, PMGRREG->pedr, PMGRREG->pcfr,
133*74a4d8c2SCharles.Forsyth 	PMGRREG->rcsr);
134*74a4d8c2SCharles.Forsyth print("cccr=%8.8lux cken=%8.8lux oscc=%8.8lux\n", COREREG->cccr, COREREG->cken, COREREG->oscc);
135*74a4d8c2SCharles.Forsyth print("msc0=%8.8lux mcs1=%8.8lux mcs2=%8.8lux\n", MEMCFGREG->msc0, MEMCFGREG->msc1, MEMCFGREG->msc2);
136*74a4d8c2SCharles.Forsyth print("clkcfg=%8.8lux\n", getcclkcfg());
137*74a4d8c2SCharles.Forsyth 
138*74a4d8c2SCharles.Forsyth 	userinit();
139*74a4d8c2SCharles.Forsyth 	schedinit();
140*74a4d8c2SCharles.Forsyth }
141*74a4d8c2SCharles.Forsyth 
142*74a4d8c2SCharles.Forsyth void
reboot(void)143*74a4d8c2SCharles.Forsyth reboot(void)
144*74a4d8c2SCharles.Forsyth {
145*74a4d8c2SCharles.Forsyth 	exit(0);
146*74a4d8c2SCharles.Forsyth }
147*74a4d8c2SCharles.Forsyth 
148*74a4d8c2SCharles.Forsyth void
halt(void)149*74a4d8c2SCharles.Forsyth halt(void)
150*74a4d8c2SCharles.Forsyth {
151*74a4d8c2SCharles.Forsyth 	spllo();
152*74a4d8c2SCharles.Forsyth 	print("cpu halted\n");
153*74a4d8c2SCharles.Forsyth 	for(;;){
154*74a4d8c2SCharles.Forsyth 		/* nothing to do */
155*74a4d8c2SCharles.Forsyth 	}
156*74a4d8c2SCharles.Forsyth }
157*74a4d8c2SCharles.Forsyth 
158*74a4d8c2SCharles.Forsyth Conf	conf;
159*74a4d8c2SCharles.Forsyth 
160*74a4d8c2SCharles.Forsyth void
addconf(char * name,char * val)161*74a4d8c2SCharles.Forsyth addconf(char *name, char *val)
162*74a4d8c2SCharles.Forsyth {
163*74a4d8c2SCharles.Forsyth 	if(nconf >= MAXCONF)
164*74a4d8c2SCharles.Forsyth 		return;
165*74a4d8c2SCharles.Forsyth 	confname[nconf] = name;
166*74a4d8c2SCharles.Forsyth 	confval[nconf] = val;
167*74a4d8c2SCharles.Forsyth 	nconf++;
168*74a4d8c2SCharles.Forsyth }
169*74a4d8c2SCharles.Forsyth 
170*74a4d8c2SCharles.Forsyth char*
getconf(char * name)171*74a4d8c2SCharles.Forsyth getconf(char *name)
172*74a4d8c2SCharles.Forsyth {
173*74a4d8c2SCharles.Forsyth 	int i;
174*74a4d8c2SCharles.Forsyth 
175*74a4d8c2SCharles.Forsyth 	for(i = 0; i < nconf; i++)
176*74a4d8c2SCharles.Forsyth 		if(cistrcmp(confname[i], name) == 0)
177*74a4d8c2SCharles.Forsyth 			return confval[i];
178*74a4d8c2SCharles.Forsyth 	return 0;
179*74a4d8c2SCharles.Forsyth }
180*74a4d8c2SCharles.Forsyth 
181*74a4d8c2SCharles.Forsyth void
confinit(void)182*74a4d8c2SCharles.Forsyth confinit(void)
183*74a4d8c2SCharles.Forsyth {
184*74a4d8c2SCharles.Forsyth 	ulong base;
185*74a4d8c2SCharles.Forsyth 
186*74a4d8c2SCharles.Forsyth 	archconfinit();
187*74a4d8c2SCharles.Forsyth 
188*74a4d8c2SCharles.Forsyth 	base = PGROUND((ulong)end);
189*74a4d8c2SCharles.Forsyth 	conf.base0 = base;
190*74a4d8c2SCharles.Forsyth 
191*74a4d8c2SCharles.Forsyth 	conf.base1 = 0;
192*74a4d8c2SCharles.Forsyth 	conf.npage1 = 0;
193*74a4d8c2SCharles.Forsyth 
194*74a4d8c2SCharles.Forsyth 	conf.npage0 = (conf.topofmem - base)/BY2PG;
195*74a4d8c2SCharles.Forsyth 
196*74a4d8c2SCharles.Forsyth 	conf.npage = conf.npage0 + conf.npage1;
197*74a4d8c2SCharles.Forsyth 	conf.ialloc = (((conf.npage*(main_pool_pcnt))/100)/2)*BY2PG;
198*74a4d8c2SCharles.Forsyth 
199*74a4d8c2SCharles.Forsyth 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
200*74a4d8c2SCharles.Forsyth 	conf.nmach = 1;
201*74a4d8c2SCharles.Forsyth 
202*74a4d8c2SCharles.Forsyth }
203*74a4d8c2SCharles.Forsyth 
204*74a4d8c2SCharles.Forsyth void
init0(void)205*74a4d8c2SCharles.Forsyth init0(void)
206*74a4d8c2SCharles.Forsyth {
207*74a4d8c2SCharles.Forsyth 	Osenv *o;
208*74a4d8c2SCharles.Forsyth 	char buf[2*KNAMELEN];
209*74a4d8c2SCharles.Forsyth 
210*74a4d8c2SCharles.Forsyth 	up->nerrlab = 0;
211*74a4d8c2SCharles.Forsyth 
212*74a4d8c2SCharles.Forsyth 	spllo();
213*74a4d8c2SCharles.Forsyth 
214*74a4d8c2SCharles.Forsyth 	if(waserror())
215*74a4d8c2SCharles.Forsyth 		panic("init0 %r");
216*74a4d8c2SCharles.Forsyth 	/*
217*74a4d8c2SCharles.Forsyth 	 * These are o.k. because rootinit is null.
218*74a4d8c2SCharles.Forsyth 	 * Then early kproc's will have a root and dot.
219*74a4d8c2SCharles.Forsyth 	 */
220*74a4d8c2SCharles.Forsyth 	o = up->env;
221*74a4d8c2SCharles.Forsyth 	o->pgrp->slash = namec("#/", Atodir, 0, 0);
222*74a4d8c2SCharles.Forsyth 	cnameclose(o->pgrp->slash->name);
223*74a4d8c2SCharles.Forsyth 	o->pgrp->slash->name = newcname("/");
224*74a4d8c2SCharles.Forsyth 	o->pgrp->dot = cclone(o->pgrp->slash);
225*74a4d8c2SCharles.Forsyth 
226*74a4d8c2SCharles.Forsyth 	chandevinit();
227*74a4d8c2SCharles.Forsyth 
228*74a4d8c2SCharles.Forsyth 	if(!waserror()){
229*74a4d8c2SCharles.Forsyth 		ksetenv("cputype", "arm", 0);
230*74a4d8c2SCharles.Forsyth 		snprint(buf, sizeof(buf), "arm %s", conffile);
231*74a4d8c2SCharles.Forsyth 		ksetenv("terminal", buf, 0);
232*74a4d8c2SCharles.Forsyth 		poperror();
233*74a4d8c2SCharles.Forsyth 	}
234*74a4d8c2SCharles.Forsyth 
235*74a4d8c2SCharles.Forsyth 	poperror();
236*74a4d8c2SCharles.Forsyth 
237*74a4d8c2SCharles.Forsyth 	disinit("/osinit.dis");
238*74a4d8c2SCharles.Forsyth }
239*74a4d8c2SCharles.Forsyth 
240*74a4d8c2SCharles.Forsyth void
userinit(void)241*74a4d8c2SCharles.Forsyth userinit(void)
242*74a4d8c2SCharles.Forsyth {
243*74a4d8c2SCharles.Forsyth 	Proc *p;
244*74a4d8c2SCharles.Forsyth 	Osenv *o;
245*74a4d8c2SCharles.Forsyth 
246*74a4d8c2SCharles.Forsyth 	p = newproc();
247*74a4d8c2SCharles.Forsyth 	o = p->env;
248*74a4d8c2SCharles.Forsyth 
249*74a4d8c2SCharles.Forsyth 	o->fgrp = newfgrp(nil);
250*74a4d8c2SCharles.Forsyth 	o->pgrp = newpgrp();
251*74a4d8c2SCharles.Forsyth 	o->egrp = newegrp();
252*74a4d8c2SCharles.Forsyth 	kstrdup(&o->user, eve);
253*74a4d8c2SCharles.Forsyth 
254*74a4d8c2SCharles.Forsyth 	strcpy(p->text, "interp");
255*74a4d8c2SCharles.Forsyth 
256*74a4d8c2SCharles.Forsyth 	p->fpstate = FPINIT;
257*74a4d8c2SCharles.Forsyth 
258*74a4d8c2SCharles.Forsyth 	/*
259*74a4d8c2SCharles.Forsyth 	 * Kernel Stack
260*74a4d8c2SCharles.Forsyth 	 *
261*74a4d8c2SCharles.Forsyth 	 * N.B. The -12 for the stack pointer is important.
262*74a4d8c2SCharles.Forsyth 	 *	4 bytes for gotolabel's return PC
263*74a4d8c2SCharles.Forsyth 	 */
264*74a4d8c2SCharles.Forsyth 	p->sched.pc = (ulong)init0;
265*74a4d8c2SCharles.Forsyth 	p->sched.sp = (ulong)p->kstack+KSTACK-8;
266*74a4d8c2SCharles.Forsyth 
267*74a4d8c2SCharles.Forsyth 	ready(p);
268*74a4d8c2SCharles.Forsyth }
269*74a4d8c2SCharles.Forsyth 
270*74a4d8c2SCharles.Forsyth void
exit(int inpanic)271*74a4d8c2SCharles.Forsyth exit(int inpanic)
272*74a4d8c2SCharles.Forsyth {
273*74a4d8c2SCharles.Forsyth 	up = 0;
274*74a4d8c2SCharles.Forsyth 
275*74a4d8c2SCharles.Forsyth 	/* Shutdown running devices */
276*74a4d8c2SCharles.Forsyth 	chandevshutdown();
277*74a4d8c2SCharles.Forsyth 
278*74a4d8c2SCharles.Forsyth 	if(inpanic && 0){
279*74a4d8c2SCharles.Forsyth 		print("Hit the reset button\n");
280*74a4d8c2SCharles.Forsyth 		for(;;)
281*74a4d8c2SCharles.Forsyth 			clockpoll();
282*74a4d8c2SCharles.Forsyth 	}
283*74a4d8c2SCharles.Forsyth 	archreboot();
284*74a4d8c2SCharles.Forsyth }
285*74a4d8c2SCharles.Forsyth 
286*74a4d8c2SCharles.Forsyth static void
linkproc(void)287*74a4d8c2SCharles.Forsyth linkproc(void)
288*74a4d8c2SCharles.Forsyth {
289*74a4d8c2SCharles.Forsyth 	spllo();
290*74a4d8c2SCharles.Forsyth 	if (waserror())
291*74a4d8c2SCharles.Forsyth 		print("error() underflow: %r\n");
292*74a4d8c2SCharles.Forsyth 	else
293*74a4d8c2SCharles.Forsyth 		(*up->kpfun)(up->arg);
294*74a4d8c2SCharles.Forsyth 	pexit("end proc", 1);
295*74a4d8c2SCharles.Forsyth }
296*74a4d8c2SCharles.Forsyth 
297*74a4d8c2SCharles.Forsyth void
kprocchild(Proc * p,void (* func)(void *),void * arg)298*74a4d8c2SCharles.Forsyth kprocchild(Proc *p, void (*func)(void*), void *arg)
299*74a4d8c2SCharles.Forsyth {
300*74a4d8c2SCharles.Forsyth 	p->sched.pc = (ulong)linkproc;
301*74a4d8c2SCharles.Forsyth 	p->sched.sp = (ulong)p->kstack+KSTACK-8;
302*74a4d8c2SCharles.Forsyth 
303*74a4d8c2SCharles.Forsyth 	p->kpfun = func;
304*74a4d8c2SCharles.Forsyth 	p->arg = arg;
305*74a4d8c2SCharles.Forsyth }
306*74a4d8c2SCharles.Forsyth 
307*74a4d8c2SCharles.Forsyth void
idlehands(void)308*74a4d8c2SCharles.Forsyth idlehands(void)
309*74a4d8c2SCharles.Forsyth {
310*74a4d8c2SCharles.Forsyth 	cpuidlecount++;
311*74a4d8c2SCharles.Forsyth 	INTRREG->iccr = 1;	/* only unmasked interrupts will stop idle mode */
312*74a4d8c2SCharles.Forsyth 	idle();
313*74a4d8c2SCharles.Forsyth }
314*74a4d8c2SCharles.Forsyth 
315*74a4d8c2SCharles.Forsyth /* stubs */
316*74a4d8c2SCharles.Forsyth void
setfsr(ulong)317*74a4d8c2SCharles.Forsyth setfsr(ulong)
318*74a4d8c2SCharles.Forsyth {
319*74a4d8c2SCharles.Forsyth }
320*74a4d8c2SCharles.Forsyth 
321*74a4d8c2SCharles.Forsyth ulong
getfsr()322*74a4d8c2SCharles.Forsyth getfsr()
323*74a4d8c2SCharles.Forsyth {
324*74a4d8c2SCharles.Forsyth 	return 0;
325*74a4d8c2SCharles.Forsyth }
326*74a4d8c2SCharles.Forsyth 
327*74a4d8c2SCharles.Forsyth void
setfcr(ulong)328*74a4d8c2SCharles.Forsyth setfcr(ulong)
329*74a4d8c2SCharles.Forsyth {
330*74a4d8c2SCharles.Forsyth }
331*74a4d8c2SCharles.Forsyth 
332*74a4d8c2SCharles.Forsyth ulong
getfcr()333*74a4d8c2SCharles.Forsyth getfcr()
334*74a4d8c2SCharles.Forsyth {
335*74a4d8c2SCharles.Forsyth 	return 0;
336*74a4d8c2SCharles.Forsyth }
337*74a4d8c2SCharles.Forsyth 
338*74a4d8c2SCharles.Forsyth void
fpinit(void)339*74a4d8c2SCharles.Forsyth fpinit(void)
340*74a4d8c2SCharles.Forsyth {
341*74a4d8c2SCharles.Forsyth }
342*74a4d8c2SCharles.Forsyth 
343*74a4d8c2SCharles.Forsyth void
FPsave(void *)344*74a4d8c2SCharles.Forsyth FPsave(void*)
345*74a4d8c2SCharles.Forsyth {
346*74a4d8c2SCharles.Forsyth }
347*74a4d8c2SCharles.Forsyth 
348*74a4d8c2SCharles.Forsyth void
FPrestore(void *)349*74a4d8c2SCharles.Forsyth FPrestore(void*)
350*74a4d8c2SCharles.Forsyth {
351*74a4d8c2SCharles.Forsyth }
352