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