xref: /inferno-os/os/rpcg/main.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1 #include	"u.h"
2 #include	"../port/lib.h"
3 #include	"mem.h"
4 #include	"dat.h"
5 #include	"fns.h"
6 #include	"io.h"
7 #include	"ureg.h"
8 #include "version.h"
9 
10 /* where b.com or qboot leaves configuration info */
11 #define BOOTARGS	((char*)CONFADDR)
12 #define	BOOTARGSLEN	1024
13 #define	MAXCONF		32
14 
15 extern ulong kerndate;
16 extern int cflag;
17 int	remotedebug;
18 
19 extern int main_pool_pcnt;
20 extern int heap_pool_pcnt;
21 extern int image_pool_pcnt;
22 
23 char	bootargs[BOOTARGSLEN+1];
24 char bootdisk[KNAMELEN];
25 char *confname[MAXCONF];
26 char *confval[MAXCONF];
27 int nconf;
28 
29 extern void addconf(char *, char *);
30 
31 /*
32  *  arguments passed to initcode and /boot
33  */
34 char argbuf[128];
35 
36 static void
37 options(void)
38 {
39 	long i, n;
40 	char *cp, *line[MAXCONF], *p, *q;
41 
42 	/*
43 	 *  parse configuration args from bootstrap
44 	 */
45 	memmove(bootargs, BOOTARGS, BOOTARGSLEN);	/* where b.com leaves its config */
46 	cp = bootargs;
47 	cp[BOOTARGSLEN-1] = 0;
48 
49 	/*
50 	 * Strip out '\r', change '\t' -> ' '.
51 	 */
52 	p = cp;
53 	for(q = cp; *q; q++){
54 		if(*q == '\r')
55 			continue;
56 		if(*q == '\t')
57 			*q = ' ';
58 		*p++ = *q;
59 	}
60 	*p = 0;
61 
62 	n = getfields(cp, line, MAXCONF, 1, "\n");
63 	for(i = 0; i < n; i++){
64 		if(*line[i] == '#')
65 			continue;
66 		cp = strchr(line[i], '=');
67 		if(cp == 0)
68 			continue;
69 		*cp++ = 0;
70 		confname[nconf] = line[i];
71 		confval[nconf] = cp;
72 		nconf++;
73 	}
74 }
75 
76 void
77 doc(char *m)
78 {
79 	USED(m);
80 	print("%s...\n", m); uartwait();
81 }
82 
83 static void
84 poolsizeinit(void)
85 {
86 	ulong nb;
87 
88 	nb = conf.npage*BY2PG;
89 	poolsize(mainmem, (nb*main_pool_pcnt)/100, 0);
90 	poolsize(heapmem, (nb*heap_pool_pcnt)/100, 0);
91 	poolsize(imagmem, (nb*image_pool_pcnt)/100, 1);
92 }
93 
94 static void
95 serialconsole(void)
96 {
97 	char *p;
98 	int port, baud;
99 
100 	p = getconf("console");
101 	if(p == nil)
102 		p = "0";
103 	if(p != nil && !remotedebug){
104 		port = strtol(p, nil, 0);
105 		baud = 9600;
106 		p = getconf("baud");
107 		if(p != nil){
108 			baud = strtol(p, nil, 0);
109 			if(baud < 9600)
110 				baud = 9600;
111 		}
112 		uartspecial(port, baud, &kbdq, &printq, kbdcr2nl);
113 	}
114 }
115 
116 void
117 main(void)
118 {
119 	machinit();
120 	options();
121 	archinit();
122 	quotefmtinstall();
123 	confinit();
124 	cpminit();
125 	xinit();
126 	poolsizeinit();
127 	trapinit();
128 	mmuinit();
129 	printinit();
130 	uartinstall();
131 	serialconsole();
132 	doc("screeninit");
133 	screeninit();
134 	doc("kbdinit");
135 	kbdinit();
136 	doc("clockinit");
137 	clockinit();
138 	doc("procinit");
139 	procinit();
140 	cpuidprint();
141 	doc("links");
142 	links();
143 	doc("chandevreset");
144 	chandevreset();
145 
146 	eve = strdup("inferno");
147 
148 	print("\nInferno %s\n", VERSION);
149 	print("Vita Nuova\n");
150 	print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag);
151 
152 	doc("userinit");
153 	userinit();
154 	doc("schedinit");
155 	schedinit();
156 }
157 
158 void
159 machinit(void)
160 {
161 	int n;
162 
163 	n = m->machno;
164 	memset(m, 0, sizeof(Mach));
165 	m->machno = n;
166 	m->mmask = 1<<m->machno;
167 	m->iomem = KADDR(getimmr() & ~0xFFFF);
168 	m->cputype = getpvr()>>16;
169 	m->delayloop = 20000;	/* initial estimate only; set by clockinit */
170 	m->speed = 50;	/* initial estimate only; set by archinit */
171 }
172 
173 void
174 init0(void)
175 {
176 	Osenv *o;
177 	int i;
178 	char buf[2*KNAMELEN];
179 
180 	up->nerrlab = 0;
181 
182 	spllo();
183 
184 	if(waserror())
185 		panic("init0");
186 	/*
187 	 * These are o.k. because rootinit is null.
188 	 * Then early kproc's will have a root and dot.
189 	 */
190 	o = up->env;
191 	o->pgrp->slash = namec("#/", Atodir, 0, 0);
192 	cnameclose(o->pgrp->slash->name);
193 	o->pgrp->slash->name = newcname("/");
194 	o->pgrp->dot = cclone(o->pgrp->slash);
195 
196 	chandevinit();
197 
198 	if(!waserror()){
199 		ksetenv("cputype", "power", 0);
200 		snprint(buf, sizeof(buf), "power %s", conffile);
201 		ksetenv("terminal", buf, 0);
202 		poperror();
203 	}
204 	for(i = 0; i < nconf; i++)
205 		if(confname[i][0] != '*'){
206 			if(!waserror()){
207 				ksetenv(confname[i], confval[i], 0);
208 				poperror();
209 			}
210 		}
211 
212 	poperror();
213 	disinit("/osinit.dis");
214 }
215 
216 void
217 userinit(void)
218 {
219 	Proc *p;
220 	Osenv *o;
221 
222 	p = newproc();
223 	o = p->env;
224 
225 	o->fgrp = newfgrp(nil);
226 
227 	o->pgrp = newpgrp();
228 	o->egrp = newegrp();
229 	kstrdup(&o->user, eve);
230 
231 	strcpy(p->text, "interp");
232 
233 	/*
234 	 * Kernel Stack
235 	 */
236 	p->sched.pc = (ulong)init0;
237 	p->sched.sp = (ulong)p->kstack+KSTACK;
238 
239 	ready(p);
240 }
241 
242 Conf	conf;
243 
244 void
245 addconf(char *name, char *val)
246 {
247 	if(nconf >= MAXCONF)
248 		return;
249 	confname[nconf] = name;
250 	confval[nconf] = val;
251 	nconf++;
252 }
253 
254 char*
255 getconf(char *name)
256 {
257 	int i;
258 
259 	for(i = 0; i < nconf; i++)
260 		if(cistrcmp(confname[i], name) == 0)
261 			return confval[i];
262 	return 0;
263 }
264 
265 void
266 confinit(void)
267 {
268 	char *p;
269 	int pcnt;
270 
271 	if(p = getconf("*kernelpercent"))
272 		pcnt = 100 - strtol(p, 0, 0);
273 	else
274 		pcnt = 0;
275 
276 	conf.nscc = 4;
277 	conf.smcuarts = 1<<0;	/* SMC1 (usual console) */
278 	conf.sccuarts = 0;	/* SCC2 not available by default (it's Ether) */
279 
280 	archconfinit();
281 
282 	conf.npage = conf.npage0 + conf.npage1;
283 	if(pcnt < 10)
284 		pcnt = 70;
285 	conf.ialloc = (((conf.npage*(100-pcnt))/100)/2)*BY2PG;
286 
287 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
288 	conf.nmach = MAXMACH;
289 }
290 
291 void
292 exit(int ispanic)
293 {
294 	up = 0;
295 	spllo();
296 	print("cpu %d exiting\n", m->machno);
297 
298 	/* Shutdown running devices */
299 	chandevshutdown();
300 
301 	delay(1000);
302 	splhi();
303 	if(ispanic)
304 		for(;;);
305 	archreboot();
306 }
307 
308 void
309 reboot(void)
310 {
311 	exit(0);
312 }
313 
314 void
315 halt(void)
316 {
317 	print("cpu halted\n");
318 	microdelay(1000);
319 	for(;;)
320 		;
321 }
322 
323 int
324 isaconfig(char *class, int ctlrno, ISAConf *isa)
325 {
326 	char cc[KNAMELEN], *p;
327 	int i;
328 
329 	snprint(cc, sizeof cc, "%s%d", class, ctlrno);
330 	p = getconf(cc);
331 	if(p == nil)
332 		return 0;
333 
334 	isa->nopt = tokenize(p, isa->opt, NISAOPT);
335 	for(i = 0; i < isa->nopt; i++){
336 		p = isa->opt[i];
337 		if(cistrncmp(p, "type=", 5) == 0)
338 			isa->type = p + 5;
339 		else if(cistrncmp(p, "port=", 5) == 0)
340 			isa->port = strtoul(p+5, &p, 0);
341 		else if(cistrncmp(p, "irq=", 4) == 0)
342 			isa->irq = strtoul(p+4, &p, 0);
343 		else if(cistrncmp(p, "mem=", 4) == 0)
344 			isa->mem = strtoul(p+4, &p, 0);
345 		else if(cistrncmp(p, "size=", 5) == 0)
346 			isa->size = strtoul(p+5, &p, 0);
347 		else if(cistrncmp(p, "freq=", 5) == 0)
348 			isa->freq = strtoul(p+5, &p, 0);
349 		else if(cistrncmp(p, "dma=", 4) == 0)
350 			isa->dma = strtoul(p+4, &p, 0);
351 	}
352 	return 1;
353 }
354 
355 /*
356  *  Save the mach dependent part of the process state.
357  */
358 void
359 procsave(Proc*)
360 {
361 }
362 
363 void
364 uartputs(char *s, int n)
365 {
366 //	screenputs(buf, n);
367 	putstrn(s, n);
368 	uartwait();
369 }
370 
371 /* stubs */
372 void
373 setfsr(ulong)
374 {
375 }
376 
377 ulong
378 getfsr()
379 {
380 	return 0;
381 }
382 
383 void
384 setfcr(ulong)
385 {
386 }
387 
388 ulong
389 getfcr()
390 {
391 	return 0;
392 }
393