xref: /plan9/sys/src/9/mtx/main.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
19a747e4fSDavid du Colombier #include	"u.h"
29a747e4fSDavid du Colombier #include	"../port/lib.h"
39a747e4fSDavid du Colombier #include	"mem.h"
49a747e4fSDavid du Colombier #include	"dat.h"
59a747e4fSDavid du Colombier #include	"fns.h"
69a747e4fSDavid du Colombier #include	"io.h"
79a747e4fSDavid du Colombier #include	"init.h"
89a747e4fSDavid du Colombier #include	"pool.h"
99a747e4fSDavid du Colombier 
109a747e4fSDavid du Colombier Conf	conf;
119a747e4fSDavid du Colombier FPsave	initfp;
129a747e4fSDavid du Colombier 
139a747e4fSDavid du Colombier void
main(void)149a747e4fSDavid du Colombier main(void)
159a747e4fSDavid du Colombier {
169a747e4fSDavid du Colombier 	memset(edata, 0, (ulong)end-(ulong)edata);
179a747e4fSDavid du Colombier 	conf.nmach = 1;
189a747e4fSDavid du Colombier 	machinit();
199a747e4fSDavid du Colombier 	ioinit();
209a747e4fSDavid du Colombier 	i8250console();
219a747e4fSDavid du Colombier 	quotefmtinstall();
229a747e4fSDavid du Colombier 	print("\nPlan 9\n");
239a747e4fSDavid du Colombier 	confinit();
249a747e4fSDavid du Colombier 	xinit();
259a747e4fSDavid du Colombier 	raveninit();
269a747e4fSDavid du Colombier 	trapinit();
279a747e4fSDavid du Colombier 	printinit();
289a747e4fSDavid du Colombier 	cpuidprint();
299a747e4fSDavid du Colombier 	mmuinit();
309a747e4fSDavid du Colombier 	hwintrinit();
319a747e4fSDavid du Colombier 	clockinit();
329a747e4fSDavid du Colombier 	kbdinit();
339a747e4fSDavid du Colombier 	procinit0();
349a747e4fSDavid du Colombier 	initseg();
359a747e4fSDavid du Colombier 	timersinit();
369a747e4fSDavid du Colombier 	links();
379a747e4fSDavid du Colombier 	chandevreset();
389a747e4fSDavid du Colombier 	pageinit();
399a747e4fSDavid du Colombier 	swapinit();
409a747e4fSDavid du Colombier 	fpsave(&initfp);
419a747e4fSDavid du Colombier 	initfp.fpscr = 0;
429a747e4fSDavid du Colombier 	userinit();
439a747e4fSDavid du Colombier 	schedinit();
449a747e4fSDavid du Colombier }
459a747e4fSDavid du Colombier 
469a747e4fSDavid du Colombier void
machinit(void)479a747e4fSDavid du Colombier machinit(void)
489a747e4fSDavid du Colombier {
499a747e4fSDavid du Colombier 	memset(m, 0, sizeof(Mach));
509a747e4fSDavid du Colombier 	m->cputype = getpvr()>>16;
519a747e4fSDavid du Colombier 
529a747e4fSDavid du Colombier 	/*
539a747e4fSDavid du Colombier 	 * For polled uart output at boot, need
549a747e4fSDavid du Colombier 	 * a default delay constant. 100000 should
559a747e4fSDavid du Colombier 	 * be enough for a while. Cpuidentify will
569a747e4fSDavid du Colombier 	 * calculate the real value later.
579a747e4fSDavid du Colombier 	 */
589a747e4fSDavid du Colombier 	m->loopconst = 100000;
599a747e4fSDavid du Colombier 
609a747e4fSDavid du Colombier 	/* turn on caches */
619a747e4fSDavid du Colombier 	puthid0(gethid0() | BIT(16) | BIT(17));
629a747e4fSDavid du Colombier 
639a747e4fSDavid du Colombier 	active.machs = 1;
649a747e4fSDavid du Colombier 	active.exiting = 0;
659a747e4fSDavid du Colombier }
669a747e4fSDavid du Colombier 
679a747e4fSDavid du Colombier void
cpuidprint(void)689a747e4fSDavid du Colombier cpuidprint(void)
699a747e4fSDavid du Colombier {
709a747e4fSDavid du Colombier 	char *id;
719a747e4fSDavid du Colombier 
729a747e4fSDavid du Colombier 	id = "unknown PowerPC";
739a747e4fSDavid du Colombier 	switch(m->cputype) {
749a747e4fSDavid du Colombier 	case 9:
759a747e4fSDavid du Colombier 		id = "PowerPC 604e";
769a747e4fSDavid du Colombier 		break;
779a747e4fSDavid du Colombier 	}
789a747e4fSDavid du Colombier 	print("cpu0: %s\n", id);
799a747e4fSDavid du Colombier }
809a747e4fSDavid du Colombier 
819a747e4fSDavid du Colombier static struct
829a747e4fSDavid du Colombier {
839a747e4fSDavid du Colombier 	char	*name;
849a747e4fSDavid du Colombier 	char *val;
859a747e4fSDavid du Colombier }
869a747e4fSDavid du Colombier plan9ini[] =
879a747e4fSDavid du Colombier {
889a747e4fSDavid du Colombier 	{ "console", "0" },
899a747e4fSDavid du Colombier 	{ "ether0", "type=2114x" },
909a747e4fSDavid du Colombier };
919a747e4fSDavid du Colombier 
929a747e4fSDavid du Colombier char*
getconf(char * name)939a747e4fSDavid du Colombier getconf(char *name)
949a747e4fSDavid du Colombier {
959a747e4fSDavid du Colombier 	int i;
969a747e4fSDavid du Colombier 
979a747e4fSDavid du Colombier 	for(i = 0; i < nelem(plan9ini); i++)
989a747e4fSDavid du Colombier 		if(cistrcmp(name, plan9ini[i].name) == 0)
999a747e4fSDavid du Colombier 			return plan9ini[i].val;
1009a747e4fSDavid du Colombier 	return nil;
1019a747e4fSDavid du Colombier }
1029a747e4fSDavid du Colombier 
1039a747e4fSDavid du Colombier void
init0(void)1049a747e4fSDavid du Colombier init0(void)
1059a747e4fSDavid du Colombier {
1069a747e4fSDavid du Colombier //	char **p, *q, name[KNAMELEN];
1079a747e4fSDavid du Colombier //	int n;
1089a747e4fSDavid du Colombier 	char buf[2*KNAMELEN];
1099a747e4fSDavid du Colombier 
1109a747e4fSDavid du Colombier 	up->nerrlab = 0;
1119a747e4fSDavid du Colombier 
1129a747e4fSDavid du Colombier 	spllo();
1139a747e4fSDavid du Colombier 
1149a747e4fSDavid du Colombier 	/*
1159a747e4fSDavid du Colombier 	 * These are o.k. because rootinit is null.
1169a747e4fSDavid du Colombier 	 * Then early kproc's will have a root and dot.
1179a747e4fSDavid du Colombier 	 */
1189a747e4fSDavid du Colombier 	up->slash = namec("#/", Atodir, 0, 0);
1194afe124fSDavid du Colombier 	pathclose(up->slash->path);
1204afe124fSDavid du Colombier 	up->slash->path = newpath("/");
1219a747e4fSDavid du Colombier 	up->dot = cclone(up->slash);
1229a747e4fSDavid du Colombier 
1239a747e4fSDavid du Colombier 	chandevinit();
1249a747e4fSDavid du Colombier 
1259a747e4fSDavid du Colombier 	if(!waserror()){
1269a747e4fSDavid du Colombier 		snprint(buf, sizeof(buf), "power %s mtx", conffile);
1279a747e4fSDavid du Colombier 		ksetenv("terminal", buf, 0);
1289a747e4fSDavid du Colombier 		ksetenv("cputype", "power", 0);
1299a747e4fSDavid du Colombier 		if(cpuserver)
1309a747e4fSDavid du Colombier 			ksetenv("service", "cpu", 0);
1319a747e4fSDavid du Colombier 		else
1329a747e4fSDavid du Colombier 			ksetenv("service", "terminal", 0);
1339a747e4fSDavid du Colombier 
1349a747e4fSDavid du Colombier /*
1359a747e4fSDavid du Colombier 		for(p = confenv; *p; p++) {
1369a747e4fSDavid du Colombier 			q = strchr(p[0], '=');
1379a747e4fSDavid du Colombier 			if(q == 0)
1389a747e4fSDavid du Colombier 				continue;
1399a747e4fSDavid du Colombier 			n = q-p[0];
1409a747e4fSDavid du Colombier 			if(n >= KNAMELEN)
1419a747e4fSDavid du Colombier 				n = KNAMELEN-1;
1429a747e4fSDavid du Colombier 			memmove(name, p[0], n);
1439a747e4fSDavid du Colombier 			name[n] = 0;
1449a747e4fSDavid du Colombier 			if(name[0] != '*')
1459a747e4fSDavid du Colombier 				ksetenv(name, q+1, 0);
1469a747e4fSDavid du Colombier 			ksetenv(name, q+1, 1);
1479a747e4fSDavid du Colombier 		}
1489a747e4fSDavid du Colombier */
1499a747e4fSDavid du Colombier 		poperror();
1509a747e4fSDavid du Colombier 	}
1519a747e4fSDavid du Colombier 	kproc("alarm", alarmkproc, 0);
1529a747e4fSDavid du Colombier 	kproc("mmusweep", mmusweep, 0);
1539a747e4fSDavid du Colombier 	touser((void*)(USTKTOP-8));
1549a747e4fSDavid du Colombier }
1559a747e4fSDavid du Colombier 
1569a747e4fSDavid du Colombier void
userinit(void)1579a747e4fSDavid du Colombier userinit(void)
1589a747e4fSDavid du Colombier {
1599a747e4fSDavid du Colombier 	Proc *p;
1609a747e4fSDavid du Colombier 	Segment *s;
1619a747e4fSDavid du Colombier 	KMap *k;
1629a747e4fSDavid du Colombier 	Page *pg;
1639a747e4fSDavid du Colombier 
1649a747e4fSDavid du Colombier 	p = newproc();
1659a747e4fSDavid du Colombier 	p->pgrp = newpgrp();
1669a747e4fSDavid du Colombier 	p->egrp = smalloc(sizeof(Egrp));
1679a747e4fSDavid du Colombier 	p->egrp->ref = 1;
1689a747e4fSDavid du Colombier 	p->fgrp = dupfgrp(nil);
1699a747e4fSDavid du Colombier 	p->rgrp = newrgrp();
1709a747e4fSDavid du Colombier 	p->procmode = 0640;
1719a747e4fSDavid du Colombier 
1729a747e4fSDavid du Colombier 	kstrdup(&eve, "");
1739a747e4fSDavid du Colombier 	kstrdup(&p->text, "*init*");
1749a747e4fSDavid du Colombier 	kstrdup(&p->user, eve);
1759a747e4fSDavid du Colombier 
1769a747e4fSDavid du Colombier 	p->fpstate = FPinit;
1779a747e4fSDavid du Colombier 
1789a747e4fSDavid du Colombier 	/*
1799a747e4fSDavid du Colombier 	 * Kernel Stack
1809a747e4fSDavid du Colombier 	 *
1819a747e4fSDavid du Colombier 	 * N.B. The -12 for the stack pointer is important.
1829a747e4fSDavid du Colombier 	 *	4 bytes for gotolabel's return PC
1839a747e4fSDavid du Colombier 	 */
1849a747e4fSDavid du Colombier 	p->sched.pc = (ulong)init0;
1859a747e4fSDavid du Colombier 	p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
1869a747e4fSDavid du Colombier 
1879a747e4fSDavid du Colombier 	/*
1889a747e4fSDavid du Colombier 	 * User Stack
1899a747e4fSDavid du Colombier 	 */
1909a747e4fSDavid du Colombier 	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
1919a747e4fSDavid du Colombier 	p->seg[SSEG] = s;
1929a747e4fSDavid du Colombier 	pg = newpage(1, 0, USTKTOP-BY2PG);
1939a747e4fSDavid du Colombier 	segpage(s, pg);
1949a747e4fSDavid du Colombier 
1959a747e4fSDavid du Colombier 	/*
1969a747e4fSDavid du Colombier 	 * Text
1979a747e4fSDavid du Colombier 	 */
1989a747e4fSDavid du Colombier 	s = newseg(SG_TEXT, UTZERO, 1);
1999a747e4fSDavid du Colombier 	s->flushme++;
2009a747e4fSDavid du Colombier 	p->seg[TSEG] = s;
2019a747e4fSDavid du Colombier 	pg = newpage(1, 0, UTZERO);
2029a747e4fSDavid du Colombier 	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
2039a747e4fSDavid du Colombier 	segpage(s, pg);
2049a747e4fSDavid du Colombier 	k = kmap(s->map[0]->pages[0]);
2059a747e4fSDavid du Colombier 	memmove((ulong*)VA(k), initcode, sizeof initcode);
2069a747e4fSDavid du Colombier 	kunmap(k);
2079a747e4fSDavid du Colombier 
2089a747e4fSDavid du Colombier 	ready(p);
2099a747e4fSDavid du Colombier }
2109a747e4fSDavid du Colombier 
2119a747e4fSDavid du Colombier /* still to do */
2129a747e4fSDavid du Colombier void
reboot(void *,void *,ulong)2139a747e4fSDavid du Colombier reboot(void*, void*, ulong)
2149a747e4fSDavid du Colombier {
2159a747e4fSDavid du Colombier 	exit(0);
2169a747e4fSDavid du Colombier }
2179a747e4fSDavid du Colombier 
2189a747e4fSDavid du Colombier void
exit(int ispanic)2199a747e4fSDavid du Colombier exit(int ispanic)
2209a747e4fSDavid du Colombier {
2219a747e4fSDavid du Colombier 	int ms, once;
2229a747e4fSDavid du Colombier 
2239a747e4fSDavid du Colombier 	lock(&active);
2249a747e4fSDavid du Colombier 	if(ispanic)
2259a747e4fSDavid du Colombier 		active.ispanic = ispanic;
2269a747e4fSDavid du Colombier 	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
2279a747e4fSDavid du Colombier 		active.ispanic = 0;
2289a747e4fSDavid du Colombier 	once = active.machs & (1<<m->machno);
2299a747e4fSDavid du Colombier 	active.machs &= ~(1<<m->machno);
2309a747e4fSDavid du Colombier 	active.exiting = 1;
2319a747e4fSDavid du Colombier 	unlock(&active);
2329a747e4fSDavid du Colombier 
2339a747e4fSDavid du Colombier 	if(once)
2349a747e4fSDavid du Colombier 		print("cpu%d: exiting\n", m->machno);
2359a747e4fSDavid du Colombier 	spllo();
2369a747e4fSDavid du Colombier 	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
2379a747e4fSDavid du Colombier 		delay(TK2MS(2));
2389a747e4fSDavid du Colombier 		if(active.machs == 0 && consactive() == 0)
2399a747e4fSDavid du Colombier 			break;
2409a747e4fSDavid du Colombier 	}
2419a747e4fSDavid du Colombier 
2429a747e4fSDavid du Colombier 	if(active.ispanic && m->machno == 0){
2439a747e4fSDavid du Colombier 		if(cpuserver)
2449a747e4fSDavid du Colombier 			delay(10000);
2459a747e4fSDavid du Colombier 		else if(conf.monitor)
2469a747e4fSDavid du Colombier 			for(;;);
2479a747e4fSDavid du Colombier 	}
2489a747e4fSDavid du Colombier 	else
2499a747e4fSDavid du Colombier 		delay(1000);
2509a747e4fSDavid du Colombier 
2519a747e4fSDavid du Colombier 	watchreset();
2529a747e4fSDavid du Colombier }
2539a747e4fSDavid du Colombier 
2549a747e4fSDavid du Colombier /*
2559a747e4fSDavid du Colombier  *  set up floating point for a new process
2569a747e4fSDavid du Colombier  */
2579a747e4fSDavid du Colombier void
procsetup(Proc * p)2589a747e4fSDavid du Colombier procsetup(Proc *p)
2599a747e4fSDavid du Colombier {
2609a747e4fSDavid du Colombier 	p->fpstate = FPinit;
2619a747e4fSDavid du Colombier }
2629a747e4fSDavid du Colombier 
2639a747e4fSDavid du Colombier /*
2649a747e4fSDavid du Colombier  *  Save the mach dependent part of the process state.
2659a747e4fSDavid du Colombier  */
2669a747e4fSDavid du Colombier void
procsave(Proc * p)2679a747e4fSDavid du Colombier procsave(Proc *p)
2689a747e4fSDavid du Colombier {
2699a747e4fSDavid du Colombier 	if(p->fpstate == FPactive){
2709a747e4fSDavid du Colombier 		if(p->state != Moribund)
2719a747e4fSDavid du Colombier 			fpsave(&up->fpsave);
2729a747e4fSDavid du Colombier 		p->fpstate = FPinactive;
2739a747e4fSDavid du Colombier 	}
2749a747e4fSDavid du Colombier }
2759a747e4fSDavid du Colombier 
2769a747e4fSDavid du Colombier void
confinit(void)2779a747e4fSDavid du Colombier confinit(void)
2789a747e4fSDavid du Colombier {
2799a747e4fSDavid du Colombier 	char *p;
2809a747e4fSDavid du Colombier 	int userpcnt;
2819a747e4fSDavid du Colombier 	ulong pa, kpages;
2829a747e4fSDavid du Colombier 	extern ulong memsize;	/* passed in from ROM monitor */
2839a747e4fSDavid du Colombier 
2849a747e4fSDavid du Colombier 	if(p = getconf("*kernelpercent"))
2859a747e4fSDavid du Colombier 		userpcnt = 100 - strtol(p, 0, 0);
2869a747e4fSDavid du Colombier 	else
2879a747e4fSDavid du Colombier 		userpcnt = 0;
2889a747e4fSDavid du Colombier 
2899a747e4fSDavid du Colombier 	pa = PGROUND(PADDR(end));
2909a747e4fSDavid du Colombier 
291*4de34a7eSDavid du Colombier 	conf.mem[0].npage = memsize/BY2PG;
292*4de34a7eSDavid du Colombier 	conf.mem[0].base = pa;
293*4de34a7eSDavid du Colombier 	conf.npage = conf.mem[0].npage;
2949a747e4fSDavid du Colombier 
2959a747e4fSDavid du Colombier 	conf.nmach = 1;
2969a747e4fSDavid du Colombier 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
2979a747e4fSDavid du Colombier 	if(cpuserver)
2989a747e4fSDavid du Colombier 		conf.nproc *= 3;
2999a747e4fSDavid du Colombier 	if(conf.nproc > 2000)
3009a747e4fSDavid du Colombier 		conf.nproc = 2000;
3019a747e4fSDavid du Colombier 	conf.nimage = 200;
3029a747e4fSDavid du Colombier 	conf.nswap = conf.nproc*80;
3039a747e4fSDavid du Colombier 	conf.nswppo = 4096;
3049a747e4fSDavid du Colombier 	conf.copymode = 0;			/* copy on write */
3059a747e4fSDavid du Colombier 
3069a747e4fSDavid du Colombier 	if(cpuserver) {
3079a747e4fSDavid du Colombier 		if(userpcnt < 10)
3089a747e4fSDavid du Colombier 			userpcnt = 70;
3099a747e4fSDavid du Colombier 		kpages = conf.npage - (conf.npage*userpcnt)/100;
3109a747e4fSDavid du Colombier 
3119a747e4fSDavid du Colombier 		/*
3129a747e4fSDavid du Colombier 		 * Hack for the big boys. Only good while physmem < 4GB.
3139a747e4fSDavid du Colombier 		 * Give the kernel a max. of 16MB + enough to allocate the
3149a747e4fSDavid du Colombier 		 * page pool.
3159a747e4fSDavid du Colombier 		 * This is an overestimate as conf.upages < conf.npages.
3169a747e4fSDavid du Colombier 		 * The patch of nimage is a band-aid, scanning the whole
3179a747e4fSDavid du Colombier 		 * page list in imagereclaim just takes too long.
3189a747e4fSDavid du Colombier 		 */
3199a747e4fSDavid du Colombier 		if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
3209a747e4fSDavid du Colombier 			kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
3219a747e4fSDavid du Colombier 			conf.nimage = 2000;
3229a747e4fSDavid du Colombier 			kpages += (conf.nproc*KSTACK)/BY2PG;
3239a747e4fSDavid du Colombier 		}
3249a747e4fSDavid du Colombier 	} else {
3259a747e4fSDavid du Colombier 		if(userpcnt < 10) {
3269a747e4fSDavid du Colombier 			if(conf.npage*BY2PG < 16*MB)
3279a747e4fSDavid du Colombier 				userpcnt = 40;
3289a747e4fSDavid du Colombier 			else
3299a747e4fSDavid du Colombier 				userpcnt = 60;
3309a747e4fSDavid du Colombier 		}
3319a747e4fSDavid du Colombier 		kpages = conf.npage - (conf.npage*userpcnt)/100;
3329a747e4fSDavid du Colombier 
3339a747e4fSDavid du Colombier 		/*
3349a747e4fSDavid du Colombier 		 * Make sure terminals with low memory get at least
3359a747e4fSDavid du Colombier 		 * 4MB on the first Image chunk allocation.
3369a747e4fSDavid du Colombier 		 */
3379a747e4fSDavid du Colombier 		if(conf.npage*BY2PG < 16*MB)
3389a747e4fSDavid du Colombier 			imagmem->minarena = 4*1024*1024;
3399a747e4fSDavid du Colombier 	}
3409a747e4fSDavid du Colombier 	conf.upages = conf.npage - kpages;
3419a747e4fSDavid du Colombier 	conf.ialloc = (kpages/2)*BY2PG;
3429a747e4fSDavid du Colombier 
3439a747e4fSDavid du Colombier 	/*
3449a747e4fSDavid du Colombier 	 * Guess how much is taken by the large permanent
3459a747e4fSDavid du Colombier 	 * datastructures. Mntcache and Mntrpc are not accounted for
3469a747e4fSDavid du Colombier 	 * (probably ~300KB).
3479a747e4fSDavid du Colombier 	 */
3489a747e4fSDavid du Colombier 	kpages *= BY2PG;
3499a747e4fSDavid du Colombier 	kpages -= conf.upages*sizeof(Page)
3509a747e4fSDavid du Colombier 		+ conf.nproc*sizeof(Proc)
3519a747e4fSDavid du Colombier 		+ conf.nimage*sizeof(Image)
3529a747e4fSDavid du Colombier 		+ conf.nswap
3539a747e4fSDavid du Colombier 		+ conf.nswppo*sizeof(Page);
3549a747e4fSDavid du Colombier 	mainmem->maxsize = kpages;
3559a747e4fSDavid du Colombier 	if(!cpuserver){
3569a747e4fSDavid du Colombier 		/*
3579a747e4fSDavid du Colombier 		 * give terminals lots of image memory, too; the dynamic
3589a747e4fSDavid du Colombier 		 * allocation will balance the load properly, hopefully.
3599a747e4fSDavid du Colombier 		 * be careful with 32-bit overflow.
3609a747e4fSDavid du Colombier 		 */
3619a747e4fSDavid du Colombier 		imagmem->maxsize = kpages;
3629a747e4fSDavid du Colombier 	}
3639a747e4fSDavid du Colombier 
3649a747e4fSDavid du Colombier //	conf.monitor = 1;	/* BUG */
3659a747e4fSDavid du Colombier }
3669a747e4fSDavid du Colombier 
3679a747e4fSDavid du Colombier static int
getcfields(char * lp,char ** fields,int n,char * sep)3689a747e4fSDavid du Colombier getcfields(char* lp, char** fields, int n, char* sep)
3699a747e4fSDavid du Colombier {
3709a747e4fSDavid du Colombier 	int i;
3719a747e4fSDavid du Colombier 
3729a747e4fSDavid du Colombier 	for(i = 0; lp && *lp && i < n; i++){
3739a747e4fSDavid du Colombier 		while(*lp && strchr(sep, *lp) != 0)
3749a747e4fSDavid du Colombier 			*lp++ = 0;
3759a747e4fSDavid du Colombier 		if(*lp == 0)
3769a747e4fSDavid du Colombier 			break;
3779a747e4fSDavid du Colombier 		fields[i] = lp;
3789a747e4fSDavid du Colombier 		while(*lp && strchr(sep, *lp) == 0){
3799a747e4fSDavid du Colombier 			if(*lp == '\\' && *(lp+1) == '\n')
3809a747e4fSDavid du Colombier 				*lp++ = ' ';
3819a747e4fSDavid du Colombier 			lp++;
3829a747e4fSDavid du Colombier 		}
3839a747e4fSDavid du Colombier 	}
3849a747e4fSDavid du Colombier 
3859a747e4fSDavid du Colombier 	return i;
3869a747e4fSDavid du Colombier }
3879a747e4fSDavid du Colombier 
3889a747e4fSDavid du Colombier int
isaconfig(char * class,int ctlrno,ISAConf * isa)3899a747e4fSDavid du Colombier isaconfig(char *class, int ctlrno, ISAConf *isa)
3909a747e4fSDavid du Colombier {
3919a747e4fSDavid du Colombier 	int i;
3929a747e4fSDavid du Colombier 	char cc[KNAMELEN], *p;
3939a747e4fSDavid du Colombier 
3949a747e4fSDavid du Colombier 	sprint(cc, "%s%d", class, ctlrno);
3959a747e4fSDavid du Colombier 
3969a747e4fSDavid du Colombier 	p = getconf(cc);
3979a747e4fSDavid du Colombier 	if(p == 0)
3989a747e4fSDavid du Colombier 		return 0;
3999a747e4fSDavid du Colombier 	isa->nopt = tokenize(p, isa->opt, NISAOPT);
4009a747e4fSDavid du Colombier 	for(i = 0; i < isa->nopt; i++){
4019a747e4fSDavid du Colombier 		p = isa->opt[i];
4029a747e4fSDavid du Colombier 		if(cistrncmp(p, "type=", 5) == 0)
4039a747e4fSDavid du Colombier 			isa->type = p + 5;
4049a747e4fSDavid du Colombier 		else if(cistrncmp(p, "port=", 5) == 0)
4059a747e4fSDavid du Colombier 			isa->port = strtoul(p+5, &p, 0);
4069a747e4fSDavid du Colombier 		else if(cistrncmp(p, "irq=", 4) == 0)
4079a747e4fSDavid du Colombier 			isa->irq = strtoul(p+4, &p, 0);
4089a747e4fSDavid du Colombier 		else if(cistrncmp(p, "dma=", 4) == 0)
4099a747e4fSDavid du Colombier 			isa->dma = strtoul(p+4, &p, 0);
4109a747e4fSDavid du Colombier 		else if(cistrncmp(p, "mem=", 4) == 0)
4119a747e4fSDavid du Colombier 			isa->mem = strtoul(p+4, &p, 0);
4129a747e4fSDavid du Colombier 		else if(cistrncmp(p, "size=", 5) == 0)
4139a747e4fSDavid du Colombier 			isa->size = strtoul(p+5, &p, 0);
4149a747e4fSDavid du Colombier 		else if(cistrncmp(p, "freq=", 5) == 0)
4159a747e4fSDavid du Colombier 			isa->freq = strtoul(p+5, &p, 0);
4169a747e4fSDavid du Colombier 	}
4179a747e4fSDavid du Colombier 	return 1;
4189a747e4fSDavid du Colombier }
4199a747e4fSDavid du Colombier 
4209a747e4fSDavid du Colombier int
cistrcmp(char * a,char * b)4219a747e4fSDavid du Colombier cistrcmp(char *a, char *b)
4229a747e4fSDavid du Colombier {
4239a747e4fSDavid du Colombier 	int ac, bc;
4249a747e4fSDavid du Colombier 
4259a747e4fSDavid du Colombier 	for(;;){
4269a747e4fSDavid du Colombier 		ac = *a++;
4279a747e4fSDavid du Colombier 		bc = *b++;
4289a747e4fSDavid du Colombier 
4299a747e4fSDavid du Colombier 		if(ac >= 'A' && ac <= 'Z')
4309a747e4fSDavid du Colombier 			ac = 'a' + (ac - 'A');
4319a747e4fSDavid du Colombier 		if(bc >= 'A' && bc <= 'Z')
4329a747e4fSDavid du Colombier 			bc = 'a' + (bc - 'A');
4339a747e4fSDavid du Colombier 		ac -= bc;
4349a747e4fSDavid du Colombier 		if(ac)
4359a747e4fSDavid du Colombier 			return ac;
4369a747e4fSDavid du Colombier 		if(bc == 0)
4379a747e4fSDavid du Colombier 			break;
4389a747e4fSDavid du Colombier 	}
4399a747e4fSDavid du Colombier 	return 0;
4409a747e4fSDavid du Colombier }
4419a747e4fSDavid du Colombier 
4429a747e4fSDavid du Colombier int
cistrncmp(char * a,char * b,int n)4439a747e4fSDavid du Colombier cistrncmp(char *a, char *b, int n)
4449a747e4fSDavid du Colombier {
4459a747e4fSDavid du Colombier 	unsigned ac, bc;
4469a747e4fSDavid du Colombier 
4479a747e4fSDavid du Colombier 	while(n > 0){
4489a747e4fSDavid du Colombier 		ac = *a++;
4499a747e4fSDavid du Colombier 		bc = *b++;
4509a747e4fSDavid du Colombier 		n--;
4519a747e4fSDavid du Colombier 
4529a747e4fSDavid du Colombier 		if(ac >= 'A' && ac <= 'Z')
4539a747e4fSDavid du Colombier 			ac = 'a' + (ac - 'A');
4549a747e4fSDavid du Colombier 		if(bc >= 'A' && bc <= 'Z')
4559a747e4fSDavid du Colombier 			bc = 'a' + (bc - 'A');
4569a747e4fSDavid du Colombier 
4579a747e4fSDavid du Colombier 		ac -= bc;
4589a747e4fSDavid du Colombier 		if(ac)
4599a747e4fSDavid du Colombier 			return ac;
4609a747e4fSDavid du Colombier 		if(bc == 0)
4619a747e4fSDavid du Colombier 			break;
4629a747e4fSDavid du Colombier 	}
4639a747e4fSDavid du Colombier 
4649a747e4fSDavid du Colombier 	return 0;
4659a747e4fSDavid du Colombier }
466