Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/9/ppc/main.c – Rev 2

Subversion Repositories planix.SVN

Rev

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