Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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	"init.h"
8
#include	"pool.h"
9
 
10
Conf	conf;
11
FPsave	initfp;
12
 
13
void
14
main(void)
15
{
16
	memset(edata, 0, (ulong)end-(ulong)edata);
17
	conf.nmach = 1;
18
	machinit();
19
	ioinit();
20
	i8250console();
21
	quotefmtinstall();
22
	print("\nPlan 9\n");
23
	confinit();
24
	xinit();
25
	raveninit();
26
	trapinit();
27
	printinit();
28
	cpuidprint();
29
	mmuinit();
30
	hwintrinit();
31
	clockinit();
32
	kbdinit();
33
	procinit0();
34
	initseg();
35
	timersinit();
36
	links();
37
	chandevreset();
38
	pageinit();
39
	swapinit();
40
	fpsave(&initfp);
41
	initfp.fpscr = 0;
42
	userinit();
43
	schedinit();
44
}
45
 
46
void
47
machinit(void)
48
{
49
	memset(m, 0, sizeof(Mach));
50
	m->cputype = getpvr()>>16;
51
 
52
	/*
53
	 * For polled uart output at boot, need
54
	 * a default delay constant. 100000 should
55
	 * be enough for a while. Cpuidentify will
56
	 * calculate the real value later.
57
	 */
58
	m->loopconst = 100000;
59
 
60
	/* turn on caches */
61
	puthid0(gethid0() | BIT(16) | BIT(17));
62
 
63
	active.machs = 1;
64
	active.exiting = 0;
65
}
66
 
67
void
68
cpuidprint(void)
69
{
70
	char *id;
71
 
72
	id = "unknown PowerPC";
73
	switch(m->cputype) {
74
	case 9:
75
		id = "PowerPC 604e";
76
		break;
77
	}
78
	print("cpu0: %s\n", id);
79
}
80
 
81
static struct
82
{
83
	char	*name;
84
	char *val;
85
}
86
plan9ini[] =
87
{
88
	{ "console", "0" },
89
	{ "ether0", "type=2114x" },
90
};
91
 
92
char*
93
getconf(char *name)
94
{
95
	int i;
96
 
97
	for(i = 0; i < nelem(plan9ini); i++)
98
		if(cistrcmp(name, plan9ini[i].name) == 0)
99
			return plan9ini[i].val;
100
	return nil;
101
}
102
 
103
void
104
init0(void)
105
{
106
//	char **p, *q, name[KNAMELEN];
107
//	int n;
108
	char buf[2*KNAMELEN];
109
 
110
	up->nerrlab = 0;
111
 
112
	spllo();
113
 
114
	/*
115
	 * These are o.k. because rootinit is null.
116
	 * Then early kproc's will have a root and dot.
117
	 */
118
	up->slash = namec("#/", Atodir, 0, 0);
119
	pathclose(up->slash->path);
120
	up->slash->path = newpath("/");
121
	up->dot = cclone(up->slash);
122
 
123
	chandevinit();
124
 
125
	if(!waserror()){
126
		snprint(buf, sizeof(buf), "power %s mtx", conffile);
127
		ksetenv("terminal", buf, 0);
128
		ksetenv("cputype", "power", 0);
129
		if(cpuserver)
130
			ksetenv("service", "cpu", 0);
131
		else
132
			ksetenv("service", "terminal", 0);
133
 
134
/*
135
		for(p = confenv; *p; p++) {
136
			q = strchr(p[0], '=');
137
			if(q == 0)
138
				continue;
139
			n = q-p[0];
140
			if(n >= KNAMELEN)
141
				n = KNAMELEN-1;
142
			memmove(name, p[0], n);
143
			name[n] = 0;
144
			if(name[0] != '*')
145
				ksetenv(name, q+1, 0);
146
			ksetenv(name, q+1, 1);
147
		}
148
*/
149
		poperror();
150
	}
151
	kproc("alarm", alarmkproc, 0);
152
	kproc("mmusweep", mmusweep, 0);
153
	touser((void*)(USTKTOP-8));
154
}
155
 
156
void
157
userinit(void)
158
{
159
	Proc *p;
160
	Segment *s;
161
	KMap *k;
162
	Page *pg;
163
 
164
	p = newproc();
165
	p->pgrp = newpgrp();
166
	p->egrp = smalloc(sizeof(Egrp));
167
	p->egrp->ref = 1;
168
	p->fgrp = dupfgrp(nil);
169
	p->rgrp = newrgrp();
170
	p->procmode = 0640;
171
 
172
	kstrdup(&eve, "");
173
	kstrdup(&p->text, "*init*");
174
	kstrdup(&p->user, eve);
175
 
176
	p->fpstate = FPinit;
177
 
178
	/*
179
	 * Kernel Stack
180
	 *
181
	 * N.B. The -12 for the stack pointer is important.
182
	 *	4 bytes for gotolabel's return PC
183
	 */
184
	p->sched.pc = (ulong)init0;
185
	p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
186
 
187
	/*
188
	 * User Stack
189
	 */
190
	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
191
	p->seg[SSEG] = s;
192
	pg = newpage(1, 0, USTKTOP-BY2PG);
193
	segpage(s, pg);
194
 
195
	/*
196
	 * Text
197
	 */
198
	s = newseg(SG_TEXT, UTZERO, 1);
199
	s->flushme++;
200
	p->seg[TSEG] = s;
201
	pg = newpage(1, 0, UTZERO);
202
	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
203
	segpage(s, pg);
204
	k = kmap(s->map[0]->pages[0]);
205
	memmove((ulong*)VA(k), initcode, sizeof initcode);
206
	kunmap(k);
207
 
208
	ready(p);
209
}
210
 
211
/* still to do */
212
void
213
reboot(void*, void*, ulong)
214
{
215
	exit(0);
216
}
217
 
218
void
219
exit(int ispanic)
220
{
221
	int ms, once;
222
 
223
	lock(&active);
224
	if(ispanic)
225
		active.ispanic = ispanic;
226
	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
227
		active.ispanic = 0;
228
	once = active.machs & (1<<m->machno);
229
	active.machs &= ~(1<<m->machno);
230
	active.exiting = 1;
231
	unlock(&active);
232
 
233
	if(once)
234
		print("cpu%d: exiting\n", m->machno);
235
	spllo();
236
	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
237
		delay(TK2MS(2));
238
		if(active.machs == 0 && consactive() == 0)
239
			break;
240
	}
241
 
242
	if(active.ispanic && m->machno == 0){
243
		if(cpuserver)
244
			delay(10000);
245
		else if(conf.monitor)
246
			for(;;);
247
	}
248
	else
249
		delay(1000);
250
 
251
	watchreset();
252
}
253
 
254
/*
255
 *  set up floating point for a new process
256
 */
257
void
258
procsetup(Proc *p)
259
{
260
	p->fpstate = FPinit;
261
}
262
 
263
/*
264
 *  Save the mach dependent part of the process state.
265
 */
266
void
267
procsave(Proc *p)
268
{
269
	if(p->fpstate == FPactive){
270
		if(p->state != Moribund)
271
			fpsave(&up->fpsave);
272
		p->fpstate = FPinactive;
273
	}
274
}
275
 
276
void
277
confinit(void)
278
{
279
	char *p;
280
	int userpcnt;
281
	ulong pa, kpages;
282
	extern ulong memsize;	/* passed in from ROM monitor */
283
 
284
	if(p = getconf("*kernelpercent"))
285
		userpcnt = 100 - strtol(p, 0, 0);
286
	else
287
		userpcnt = 0;
288
 
289
	pa = PGROUND(PADDR(end));
290
 
291
	conf.mem[0].npage = memsize/BY2PG;
292
	conf.mem[0].base = pa;
293
	conf.npage = conf.mem[0].npage;
294
 
295
	conf.nmach = 1;
296
	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
297
	if(cpuserver)
298
		conf.nproc *= 3;
299
	if(conf.nproc > 2000)
300
		conf.nproc = 2000;
301
	conf.nimage = 200;
302
	conf.nswap = conf.nproc*80;
303
	conf.nswppo = 4096;
304
	conf.copymode = 0;			/* copy on write */
305
 
306
	if(cpuserver) {
307
		if(userpcnt < 10)
308
			userpcnt = 70;
309
		kpages = conf.npage - (conf.npage*userpcnt)/100;
310
 
311
		/*
312
		 * Hack for the big boys. Only good while physmem < 4GB.
313
		 * Give the kernel a max. of 16MB + enough to allocate the
314
		 * page pool.
315
		 * This is an overestimate as conf.upages < conf.npages.
316
		 * The patch of nimage is a band-aid, scanning the whole
317
		 * page list in imagereclaim just takes too long.
318
		 */
319
		if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
320
			kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
321
			conf.nimage = 2000;
322
			kpages += (conf.nproc*KSTACK)/BY2PG;
323
		}
324
	} else {
325
		if(userpcnt < 10) {
326
			if(conf.npage*BY2PG < 16*MB)
327
				userpcnt = 40;
328
			else
329
				userpcnt = 60;
330
		}
331
		kpages = conf.npage - (conf.npage*userpcnt)/100;
332
 
333
		/*
334
		 * Make sure terminals with low memory get at least
335
		 * 4MB on the first Image chunk allocation.
336
		 */
337
		if(conf.npage*BY2PG < 16*MB)
338
			imagmem->minarena = 4*1024*1024;
339
	}
340
	conf.upages = conf.npage - kpages;
341
	conf.ialloc = (kpages/2)*BY2PG;
342
 
343
	/*
344
	 * Guess how much is taken by the large permanent
345
	 * datastructures. Mntcache and Mntrpc are not accounted for
346
	 * (probably ~300KB).
347
	 */
348
	kpages *= BY2PG;
349
	kpages -= conf.upages*sizeof(Page)
350
		+ conf.nproc*sizeof(Proc)
351
		+ conf.nimage*sizeof(Image)
352
		+ conf.nswap
353
		+ conf.nswppo*sizeof(Page);
354
	mainmem->maxsize = kpages;
355
	if(!cpuserver){
356
		/*
357
		 * give terminals lots of image memory, too; the dynamic
358
		 * allocation will balance the load properly, hopefully.
359
		 * be careful with 32-bit overflow.
360
		 */
361
		imagmem->maxsize = kpages;
362
	}
363
 
364
//	conf.monitor = 1;	/* BUG */
365
}
366
 
367
static int
368
getcfields(char* lp, char** fields, int n, char* sep)
369
{
370
	int i;
371
 
372
	for(i = 0; lp && *lp && i < n; i++){
373
		while(*lp && strchr(sep, *lp) != 0)
374
			*lp++ = 0;
375
		if(*lp == 0)
376
			break;
377
		fields[i] = lp;
378
		while(*lp && strchr(sep, *lp) == 0){
379
			if(*lp == '\\' && *(lp+1) == '\n')
380
				*lp++ = ' ';
381
			lp++;
382
		}
383
	}
384
 
385
	return i;
386
}
387
 
388
int
389
isaconfig(char *class, int ctlrno, ISAConf *isa)
390
{
391
	int i;
392
	char cc[KNAMELEN], *p;
393
 
394
	sprint(cc, "%s%d", class, ctlrno);
395
 
396
	p = getconf(cc);
397
	if(p == 0)
398
		return 0;
399
	isa->nopt = tokenize(p, isa->opt, NISAOPT);
400
	for(i = 0; i < isa->nopt; i++){
401
		p = isa->opt[i];
402
		if(cistrncmp(p, "type=", 5) == 0)
403
			isa->type = p + 5;
404
		else if(cistrncmp(p, "port=", 5) == 0)
405
			isa->port = strtoul(p+5, &p, 0);
406
		else if(cistrncmp(p, "irq=", 4) == 0)
407
			isa->irq = strtoul(p+4, &p, 0);
408
		else if(cistrncmp(p, "dma=", 4) == 0)
409
			isa->dma = strtoul(p+4, &p, 0);
410
		else if(cistrncmp(p, "mem=", 4) == 0)
411
			isa->mem = strtoul(p+4, &p, 0);
412
		else if(cistrncmp(p, "size=", 5) == 0)
413
			isa->size = strtoul(p+5, &p, 0);
414
		else if(cistrncmp(p, "freq=", 5) == 0)
415
			isa->freq = strtoul(p+5, &p, 0);
416
	}
417
	return 1;
418
}
419
 
420
int
421
cistrcmp(char *a, char *b)
422
{
423
	int ac, bc;
424
 
425
	for(;;){
426
		ac = *a++;
427
		bc = *b++;
428
 
429
		if(ac >= 'A' && ac <= 'Z')
430
			ac = 'a' + (ac - 'A');
431
		if(bc >= 'A' && bc <= 'Z')
432
			bc = 'a' + (bc - 'A');
433
		ac -= bc;
434
		if(ac)
435
			return ac;
436
		if(bc == 0)
437
			break;
438
	}
439
	return 0;
440
}
441
 
442
int
443
cistrncmp(char *a, char *b, int n)
444
{
445
	unsigned ac, bc;
446
 
447
	while(n > 0){
448
		ac = *a++;
449
		bc = *b++;
450
		n--;
451
 
452
		if(ac >= 'A' && ac <= 'Z')
453
			ac = 'a' + (ac - 'A');
454
		if(bc >= 'A' && bc <= 'Z')
455
			bc = 'a' + (bc - 'A');
456
 
457
		ac -= bc;
458
		if(ac)
459
			return ac;
460
		if(bc == 0)
461
			break;
462
	}
463
 
464
	return 0;
465
}