xref: /plan9/sys/src/9/ppc/main.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
1458db832SDavid du Colombier #include	"u.h"
2458db832SDavid du Colombier #include	"../port/lib.h"
3458db832SDavid du Colombier #include	"mem.h"
4458db832SDavid du Colombier #include	"dat.h"
5458db832SDavid du Colombier #include	"fns.h"
6458db832SDavid du Colombier #include	"io.h"
7458db832SDavid du Colombier #include	"init.h"
8458db832SDavid du Colombier #include	"pool.h"
9fe853e23SDavid du Colombier #include	"tos.h"
10458db832SDavid du Colombier 
11458db832SDavid du Colombier #define	MAXCONF		64
12458db832SDavid du Colombier 
13458db832SDavid du Colombier typedef struct Plan9ini Plan9ini;
14458db832SDavid du Colombier struct Plan9ini
15458db832SDavid du Colombier {
16458db832SDavid du Colombier 	char	*name;
17458db832SDavid du Colombier 	char	*val;
18458db832SDavid du Colombier };
19458db832SDavid du Colombier 
20458db832SDavid du Colombier char *plan9inistr;
21458db832SDavid du Colombier Plan9ini plan9ini[MAXCONF];
22458db832SDavid du Colombier int nconf;
23458db832SDavid du Colombier 
24458db832SDavid du Colombier Conf conf;
25458db832SDavid du Colombier FPsave initfp;
26458db832SDavid du Colombier Lock testlock;
27458db832SDavid du Colombier 
28458db832SDavid du Colombier static void plan9iniinit(void);
29458db832SDavid du Colombier 
30fe853e23SDavid du Colombier char *
cpuid(void)31fe853e23SDavid du Colombier cpuid(void)
32fe853e23SDavid du Colombier {
33fe853e23SDavid du Colombier 	char *id;
34fe853e23SDavid du Colombier 
35fe853e23SDavid du Colombier 	id = "unknown PowerPC";
36fe853e23SDavid du Colombier 	switch(m->cputype) {
37fe853e23SDavid du Colombier 	case 8:
38fe853e23SDavid du Colombier 		id = "PowerPC 750";
39fe853e23SDavid du Colombier 		break;
40fe853e23SDavid du Colombier 	case 9:
41fe853e23SDavid du Colombier 		id = "PowerPC 604e";
42fe853e23SDavid du Colombier 		break;
43fe853e23SDavid du Colombier 	case 0x81:
44fe853e23SDavid du Colombier 		id = "PowerPC 8260";
45fe853e23SDavid du Colombier 		break;
46fe853e23SDavid du Colombier 	case 0x8081:
47fe853e23SDavid du Colombier 		id = "PowerPC 826xA";
48fe853e23SDavid du Colombier 		break;
49fe853e23SDavid du Colombier 	default:
50fe853e23SDavid du Colombier 		break;
51fe853e23SDavid du Colombier 	}
52fe853e23SDavid du Colombier 	return id;
53fe853e23SDavid du Colombier }
54fe853e23SDavid du Colombier 
55fe853e23SDavid du Colombier void
cpuidprint(void)56fe853e23SDavid du Colombier cpuidprint(void)
57fe853e23SDavid du Colombier {
58fe853e23SDavid du Colombier 	print("cpu0: %s, rev 0x%lux, cpu hz %lld, bus hz %ld\n",
59fe853e23SDavid du Colombier 		cpuid(), getpvr()&0xffff, m->cpuhz, m->bushz);
60fe853e23SDavid du Colombier }
61458db832SDavid du Colombier 
62458db832SDavid du Colombier void
main(void)63458db832SDavid du Colombier main(void)
64458db832SDavid du Colombier {
65458db832SDavid du Colombier 	memset(edata, 0, (ulong)end-(ulong)edata);
66458db832SDavid du Colombier 	conf.nmach = 1;
67458db832SDavid du Colombier 	machinit();
68458db832SDavid du Colombier 	confinit();
69458db832SDavid du Colombier 	xinit();
70458db832SDavid du Colombier 	trapinit();
71458db832SDavid du Colombier 	mmuinit();
72458db832SDavid du Colombier 	plan9iniinit();
73458db832SDavid du Colombier 	hwintrinit();
74458db832SDavid du Colombier 	clockinit();
75458db832SDavid du Colombier 	timerinit();
76458db832SDavid du Colombier 	console();
77458db832SDavid du Colombier 	quotefmtinstall();
78458db832SDavid du Colombier 	printinit();
79458db832SDavid du Colombier 	cpuidprint();
80458db832SDavid du Colombier 	print("\nPlan 9 from Bell Labs\n");
81458db832SDavid du Colombier 	procinit0();
82458db832SDavid du Colombier 	initseg();
83458db832SDavid du Colombier 	timersinit();
84458db832SDavid du Colombier 	links();
85458db832SDavid du Colombier 	chandevreset();
86458db832SDavid du Colombier 	pageinit();
87458db832SDavid du Colombier 	swapinit();
88458db832SDavid du Colombier 	sharedseginit();
89458db832SDavid du Colombier 	fpsave(&initfp);
90458db832SDavid du Colombier 	initfp.fpscr = 0;
91458db832SDavid du Colombier 	userinit();
92458db832SDavid du Colombier 	schedinit();
93458db832SDavid du Colombier }
94458db832SDavid du Colombier 
95458db832SDavid du Colombier char*
getconf(char * name)96458db832SDavid du Colombier getconf(char *name)
97458db832SDavid du Colombier {
98458db832SDavid du Colombier 	int i;
99458db832SDavid du Colombier 
100458db832SDavid du Colombier 	for(i = 0; i < nconf; i++)
101458db832SDavid du Colombier 		if(cistrcmp(name, plan9ini[i].name) == 0)
102458db832SDavid du Colombier 			return plan9ini[i].val;
103458db832SDavid du Colombier 	return nil;
104458db832SDavid du Colombier }
105458db832SDavid du Colombier 
106458db832SDavid du Colombier static void
plan9iniinit(void)107458db832SDavid du Colombier plan9iniinit(void)
108458db832SDavid du Colombier {
109458db832SDavid du Colombier 	long i;
110458db832SDavid du Colombier 	int c;
111458db832SDavid du Colombier 	char *cp, line[MAXCONF], *p, *q;
112458db832SDavid du Colombier 
113458db832SDavid du Colombier 	/*
114458db832SDavid du Colombier 	 *  parse configuration args from dos file plan9.ini
115458db832SDavid du Colombier 	 */
116458db832SDavid du Colombier 
117458db832SDavid du Colombier 	cp = plan9inistr;
118458db832SDavid du Colombier 	for(i = 0; i < MAXCONF; i++){
119458db832SDavid du Colombier 		/*
120458db832SDavid du Colombier 		 * Strip out '\r', change '\t' -> ' ', test for 0xff which is end of file
121458db832SDavid du Colombier 		 */
122458db832SDavid du Colombier 		p = line;
123458db832SDavid du Colombier 		for(q = cp; c = (uchar)*q; q++){
124458db832SDavid du Colombier 			if(c == '\r')
125458db832SDavid du Colombier 				continue;
126458db832SDavid du Colombier 			if(c == '\t')
127458db832SDavid du Colombier 				c = ' ';
128458db832SDavid du Colombier 			if(c == 0xff || c == '\n')
129458db832SDavid du Colombier 				break;
130458db832SDavid du Colombier 			*p++ = c;
131458db832SDavid du Colombier 		}
132458db832SDavid du Colombier 		*p = 0;
133458db832SDavid du Colombier 		if (*line == 0)
134458db832SDavid du Colombier 			break;
135458db832SDavid du Colombier 		if(*line != '#' && (cp = strchr(line, '='))){
136458db832SDavid du Colombier 			*cp++ = '\0';
137458db832SDavid du Colombier 			kstrdup(&plan9ini[nconf].name, line);
138458db832SDavid du Colombier 			kstrdup(&plan9ini[nconf].val, cp);
139458db832SDavid du Colombier 			nconf++;
140458db832SDavid du Colombier 		}
141458db832SDavid du Colombier 		if (c == 0xff)
142458db832SDavid du Colombier 			break;
143458db832SDavid du Colombier 
144458db832SDavid du Colombier 		cp = q + 1;
145458db832SDavid du Colombier 	}
146458db832SDavid du Colombier }
147458db832SDavid du Colombier 
148458db832SDavid du Colombier void
init0(void)149458db832SDavid du Colombier init0(void)
150458db832SDavid du Colombier {
151458db832SDavid du Colombier //	char **p, *q, name[KNAMELEN];
152458db832SDavid du Colombier 	int i;
153458db832SDavid du Colombier 	char buf[2*KNAMELEN];
154458db832SDavid du Colombier 
155458db832SDavid du Colombier 	up->nerrlab = 0;
156458db832SDavid du Colombier 	spllo();
157458db832SDavid du Colombier 
158458db832SDavid du Colombier 	/*
159458db832SDavid du Colombier 	 * These are o.k. because rootinit is null.
160458db832SDavid du Colombier 	 * Then early kproc's will have a root and dot.
161458db832SDavid du Colombier 	 */
162458db832SDavid du Colombier 	up->slash = namec("#/", Atodir, 0, 0);
1634afe124fSDavid du Colombier 	pathclose(up->slash->path);
1644afe124fSDavid du Colombier 	up->slash->path = newpath("/");
165458db832SDavid du Colombier 	up->dot = cclone(up->slash);
166458db832SDavid du Colombier 
167458db832SDavid du Colombier 	chandevinit();
168458db832SDavid du Colombier 
169458db832SDavid du Colombier 	if(!waserror()){
170458db832SDavid du Colombier 		snprint(buf, sizeof(buf), "power %s mtx", conffile);
171458db832SDavid du Colombier 		ksetenv("terminal", buf, 0);
172458db832SDavid du Colombier 		ksetenv("cputype", "power", 0);
173458db832SDavid du Colombier 		if(cpuserver)
174458db832SDavid du Colombier 			ksetenv("service", "cpu", 0);
175458db832SDavid du Colombier 		else
176458db832SDavid du Colombier 			ksetenv("service", "terminal", 0);
177458db832SDavid du Colombier 
178458db832SDavid du Colombier 		for(i = 0; i < nconf; i++){
179458db832SDavid du Colombier 			if(plan9ini[i].name[0] != '*')
180458db832SDavid du Colombier 				ksetenv(plan9ini[i].name, plan9ini[i].val, 0);
181458db832SDavid du Colombier 			ksetenv(plan9ini[i].name, plan9ini[i].val, 1);
182458db832SDavid du Colombier 		}
183458db832SDavid du Colombier 		poperror();
184458db832SDavid du Colombier 	}
185458db832SDavid du Colombier 	kproc("alarm", alarmkproc, 0);
186458db832SDavid du Colombier 	kproc("mmusweep", mmusweep, 0);
187fe853e23SDavid du Colombier 	touser((void*)(USTKTOP-sizeof(Tos)));
188458db832SDavid du Colombier }
189458db832SDavid du Colombier 
190458db832SDavid du Colombier void
userinit(void)191458db832SDavid du Colombier userinit(void)
192458db832SDavid du Colombier {
193458db832SDavid du Colombier 	Proc *p;
194458db832SDavid du Colombier 	Segment *s;
195458db832SDavid du Colombier 	KMap *k;
196458db832SDavid du Colombier 	Page *pg;
197458db832SDavid du Colombier 
198458db832SDavid du Colombier 	p = newproc();
199458db832SDavid du Colombier 	p->pgrp = newpgrp();
200458db832SDavid du Colombier 	p->egrp = smalloc(sizeof(Egrp));
201458db832SDavid du Colombier 	p->egrp->ref = 1;
202458db832SDavid du Colombier 	p->fgrp = dupfgrp(nil);
203458db832SDavid du Colombier 	p->rgrp = newrgrp();
204458db832SDavid du Colombier 	p->procmode = 0640;
205458db832SDavid du Colombier 
206458db832SDavid du Colombier 	kstrdup(&eve, "");
207458db832SDavid du Colombier 	kstrdup(&p->text, "*init*");
208458db832SDavid du Colombier 	kstrdup(&p->user, eve);
209458db832SDavid du Colombier 
210458db832SDavid du Colombier 	p->fpstate = FPinit;
211458db832SDavid du Colombier 
212458db832SDavid du Colombier 	/*
213458db832SDavid du Colombier 	 *  Stack
214458db832SDavid du Colombier 	 *
215458db832SDavid du Colombier 	 * N.B. The -12 for the stack pointer is important.
216458db832SDavid du Colombier 	 *	4 bytes for gotolabel's return PC
217458db832SDavid du Colombier 	 */
218458db832SDavid du Colombier 	p->sched.pc = (ulong)init0;
219458db832SDavid du Colombier 	p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
220458db832SDavid du Colombier 
221458db832SDavid du Colombier 	/*
222458db832SDavid du Colombier 	 * User Stack
223458db832SDavid du Colombier 	 */
224458db832SDavid du Colombier 	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
225458db832SDavid du Colombier 	p->seg[SSEG] = s;
226458db832SDavid du Colombier 	pg = newpage(1, 0, USTKTOP-BY2PG);
227458db832SDavid du Colombier 	segpage(s, pg);
228458db832SDavid du Colombier 
229458db832SDavid du Colombier 	/*
230458db832SDavid du Colombier 	 * Text
231458db832SDavid du Colombier 	 */
232458db832SDavid du Colombier 	s = newseg(SG_TEXT, UTZERO, 1);
233458db832SDavid du Colombier 	s->flushme++;
234458db832SDavid du Colombier 	p->seg[TSEG] = s;
235458db832SDavid du Colombier 	pg = newpage(1, 0, UTZERO);
236458db832SDavid du Colombier 	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
237458db832SDavid du Colombier 	segpage(s, pg);
238458db832SDavid du Colombier 	k = kmap(s->map[0]->pages[0]);
239458db832SDavid du Colombier 	memmove((ulong*)VA(k), initcode, sizeof initcode);
240458db832SDavid du Colombier 	kunmap(k);
241458db832SDavid du Colombier 
242458db832SDavid du Colombier 	ready(p);
243458db832SDavid du Colombier }
244458db832SDavid du Colombier 
245458db832SDavid du Colombier void
exit(int ispanic)246458db832SDavid du Colombier exit(int ispanic)
247458db832SDavid du Colombier {
248458db832SDavid du Colombier 	int ms, once;
249458db832SDavid du Colombier 
250458db832SDavid du Colombier 	lock(&active);
251458db832SDavid du Colombier 	if(ispanic)
252458db832SDavid du Colombier 		active.ispanic = ispanic;
253458db832SDavid du Colombier 	else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
254458db832SDavid du Colombier 		active.ispanic = 0;
255458db832SDavid du Colombier 	once = active.machs & (1<<m->machno);
256458db832SDavid du Colombier 	active.machs &= ~(1<<m->machno);
257458db832SDavid du Colombier 	active.exiting = 1;
258458db832SDavid du Colombier 	unlock(&active);
259458db832SDavid du Colombier 
260458db832SDavid du Colombier 	if(once)
261458db832SDavid du Colombier 		print("cpu%d: exiting\n", m->machno);
262458db832SDavid du Colombier 	spllo();
263458db832SDavid du Colombier 	for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
264458db832SDavid du Colombier 		delay(TK2MS(2));
265458db832SDavid du Colombier 		if(active.machs == 0 && consactive() == 0)
266458db832SDavid du Colombier 			break;
267458db832SDavid du Colombier 	}
268458db832SDavid du Colombier 
269458db832SDavid du Colombier 	if(active.ispanic && m->machno == 0){
270458db832SDavid du Colombier 		if(cpuserver)
271458db832SDavid du Colombier 			delay(10000);
272458db832SDavid du Colombier 		else if(conf.monitor)
273458db832SDavid du Colombier 			for(;;);
274458db832SDavid du Colombier 	}
275458db832SDavid du Colombier 	else
276458db832SDavid du Colombier 		delay(1000);
277458db832SDavid du Colombier 
278458db832SDavid du Colombier }
279458db832SDavid du Colombier 
280458db832SDavid du Colombier /*
281458db832SDavid du Colombier  *  set up floating point for a new process
282458db832SDavid du Colombier  */
283458db832SDavid du Colombier void
procsetup(Proc * p)284458db832SDavid du Colombier procsetup(Proc *p)
285458db832SDavid du Colombier {
286458db832SDavid du Colombier 	p->fpstate = FPinit;
287458db832SDavid du Colombier }
288458db832SDavid du Colombier 
289fe853e23SDavid du Colombier void
procrestore(Proc * p)290fe853e23SDavid du Colombier procrestore(Proc *p)
291fe853e23SDavid du Colombier {
292fe853e23SDavid du Colombier 	uvlong t;
293fe853e23SDavid du Colombier 
294fe853e23SDavid du Colombier 	if(p->kp)
295fe853e23SDavid du Colombier 		return;
296fe853e23SDavid du Colombier 	cycles(&t);
297fe853e23SDavid du Colombier 	p->pcycles -= t;
298fe853e23SDavid du Colombier }
299fe853e23SDavid du Colombier 
300458db832SDavid du Colombier /*
301458db832SDavid du Colombier  *  Save the mach dependent part of the process state.
302458db832SDavid du Colombier  */
303458db832SDavid du Colombier void
procsave(Proc * p)304458db832SDavid du Colombier procsave(Proc *p)
305458db832SDavid du Colombier {
306fe853e23SDavid du Colombier 	uvlong t;
307fe853e23SDavid du Colombier 
308fe853e23SDavid du Colombier 	cycles(&t);
309fe853e23SDavid du Colombier 	p->pcycles += t;
310458db832SDavid du Colombier 	if(p->fpstate == FPactive){
311458db832SDavid du Colombier 		if(p->state != Moribund)
312458db832SDavid du Colombier 			fpsave(&up->fpsave);
313458db832SDavid du Colombier 		p->fpstate = FPinactive;
314458db832SDavid du Colombier 	}
315458db832SDavid du Colombier }
316458db832SDavid du Colombier 
317458db832SDavid du Colombier void
confinit(void)318458db832SDavid du Colombier confinit(void)
319458db832SDavid du Colombier {
320458db832SDavid du Colombier 	char *p;
321458db832SDavid du Colombier 	int userpcnt;
322458db832SDavid du Colombier 	ulong pa, kpages;
323458db832SDavid du Colombier 	/* passed in from ROM monitor: */
324458db832SDavid du Colombier 
325458db832SDavid du Colombier 	if(p = getconf("*kernelpercent"))
326458db832SDavid du Colombier 		userpcnt = 100 - strtol(p, 0, 0);
327458db832SDavid du Colombier 	else
328458db832SDavid du Colombier 		userpcnt = 0;
329458db832SDavid du Colombier 
330458db832SDavid du Colombier 	pa = PGROUND(PADDR(end));
331458db832SDavid du Colombier 
332458db832SDavid du Colombier 	/* Blast Board specific */
333*4de34a7eSDavid du Colombier 	conf.mem[0].npage = (MEM1SIZE - pa)/BY2PG;
334*4de34a7eSDavid du Colombier 	conf.mem[0].base = pa;
335458db832SDavid du Colombier 
336*4de34a7eSDavid du Colombier 	conf.mem[1].npage = MEM2SIZE/BY2PG;
337*4de34a7eSDavid du Colombier 	conf.mem[1].base = MEM2BASE;
338458db832SDavid du Colombier 
339*4de34a7eSDavid du Colombier 	conf.npage = conf.mem[0].npage + conf.mem[1].npage;
340458db832SDavid du Colombier 
341458db832SDavid du Colombier 	conf.nmach = 1;
342458db832SDavid du Colombier 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
343458db832SDavid du Colombier 	if(cpuserver)
344458db832SDavid du Colombier 		conf.nproc *= 3;
345458db832SDavid du Colombier 	if(conf.nproc > 2000)
346458db832SDavid du Colombier 		conf.nproc = 2000;
347458db832SDavid du Colombier 	conf.nimage = 200;
348458db832SDavid du Colombier 	conf.nswap = conf.nproc*80;
349458db832SDavid du Colombier 	conf.nswppo = 4096;
350458db832SDavid du Colombier 	conf.copymode = 0;			/* copy on write */
351458db832SDavid du Colombier 
352458db832SDavid du Colombier 	if(cpuserver) {
353458db832SDavid du Colombier 		if(userpcnt < 10)
354458db832SDavid du Colombier 			userpcnt = 70;
355458db832SDavid du Colombier 		kpages = conf.npage - (conf.npage*userpcnt)/100;
356458db832SDavid du Colombier 
357458db832SDavid du Colombier 		/*
358458db832SDavid du Colombier 		 * Hack for the big boys. Only good while physmem < 4GB.
359458db832SDavid du Colombier 		 * Give the kernel a max. of 16MB + enough to allocate the
360458db832SDavid du Colombier 		 * page pool.
361458db832SDavid du Colombier 		 * This is an overestimate as conf.upages < conf.npages.
362458db832SDavid du Colombier 		 * The patch of nimage is a band-aid, scanning the whole
363458db832SDavid du Colombier 		 * page list in imagereclaim just takes too long.
364458db832SDavid du Colombier 		 */
365458db832SDavid du Colombier 		if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
366458db832SDavid du Colombier 			kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
367458db832SDavid du Colombier 			conf.nimage = 2000;
368458db832SDavid du Colombier 			kpages += (conf.nproc*KSTACK)/BY2PG;
369458db832SDavid du Colombier 		}
370458db832SDavid du Colombier 	} else {
371458db832SDavid du Colombier 		if(userpcnt < 10) {
372458db832SDavid du Colombier 			if(conf.npage*BY2PG < 16*MB)
373458db832SDavid du Colombier 				userpcnt = 40;
374458db832SDavid du Colombier 			else
375458db832SDavid du Colombier 				userpcnt = 60;
376458db832SDavid du Colombier 		}
377458db832SDavid du Colombier 		kpages = conf.npage - (conf.npage*userpcnt)/100;
378458db832SDavid du Colombier 
379458db832SDavid du Colombier 		/*
380458db832SDavid du Colombier 		 * Make sure terminals with low memory get at least
381458db832SDavid du Colombier 		 * 4MB on the first Image chunk allocation.
382458db832SDavid du Colombier 		 */
383458db832SDavid du Colombier 		if(conf.npage*BY2PG < 16*MB)
384458db832SDavid du Colombier 			imagmem->minarena = 4*1024*1024;
385458db832SDavid du Colombier 	}
386458db832SDavid du Colombier 	conf.upages = conf.npage - kpages;
387458db832SDavid du Colombier 	conf.ialloc = (kpages/2)*BY2PG;
388458db832SDavid du Colombier 
389458db832SDavid du Colombier 	/*
390458db832SDavid du Colombier 	 * Guess how much is taken by the large permanent
391458db832SDavid du Colombier 	 * datastructures. Mntcache and Mntrpc are not accounted for
392458db832SDavid du Colombier 	 * (probably ~300KB).
393458db832SDavid du Colombier 	 */
394458db832SDavid du Colombier 	kpages *= BY2PG;
395458db832SDavid du Colombier 	kpages -= conf.upages*sizeof(Page)
396458db832SDavid du Colombier 		+ conf.nproc*sizeof(Proc)
397458db832SDavid du Colombier 		+ conf.nimage*sizeof(Image)
398458db832SDavid du Colombier 		+ conf.nswap
399458db832SDavid du Colombier 		+ conf.nswppo*sizeof(Page);
400458db832SDavid du Colombier 	mainmem->maxsize = kpages;
401458db832SDavid du Colombier 	if(!cpuserver){
402458db832SDavid du Colombier 		/*
403458db832SDavid du Colombier 		 * give terminals lots of image memory, too; the dynamic
404458db832SDavid du Colombier 		 * allocation will balance the load properly, hopefully.
405458db832SDavid du Colombier 		 * be careful with 32-bit overflow.
406458db832SDavid du Colombier 		 */
407458db832SDavid du Colombier 		imagmem->maxsize = kpages;
408458db832SDavid du Colombier 	}
409458db832SDavid du Colombier 
410458db832SDavid du Colombier //	conf.monitor = 1;	/* BUG */
411458db832SDavid du Colombier }
412458db832SDavid du Colombier 
413458db832SDavid du Colombier static int
getcfields(char * lp,char ** fields,int n,char * sep)414458db832SDavid du Colombier getcfields(char* lp, char** fields, int n, char* sep)
415458db832SDavid du Colombier {
416458db832SDavid du Colombier 	int i;
417458db832SDavid du Colombier 
418458db832SDavid du Colombier 	for(i = 0; lp && *lp && i < n; i++){
419458db832SDavid du Colombier 		while(*lp && strchr(sep, *lp) != 0)
420458db832SDavid du Colombier 			*lp++ = 0;
421458db832SDavid du Colombier 		if(*lp == 0)
422458db832SDavid du Colombier 			break;
423458db832SDavid du Colombier 		fields[i] = lp;
424458db832SDavid du Colombier 		while(*lp && strchr(sep, *lp) == 0){
425458db832SDavid du Colombier 			if(*lp == '\\' && *(lp+1) == '\n')
426458db832SDavid du Colombier 				*lp++ = ' ';
427458db832SDavid du Colombier 			lp++;
428458db832SDavid du Colombier 		}
429458db832SDavid du Colombier 	}
430458db832SDavid du Colombier 
431458db832SDavid du Colombier 	return i;
432458db832SDavid du Colombier }
433458db832SDavid du Colombier 
434458db832SDavid du Colombier int
isaconfig(char * class,int ctlrno,ISAConf * isa)435458db832SDavid du Colombier isaconfig(char *class, int ctlrno, ISAConf *isa)
436458db832SDavid du Colombier {
437458db832SDavid du Colombier 	int i;
438458db832SDavid du Colombier 	char cc[KNAMELEN], *p;
439458db832SDavid du Colombier 
440458db832SDavid du Colombier 	sprint(cc, "%s%d", class, ctlrno);
441458db832SDavid du Colombier 
442458db832SDavid du Colombier 	p = getconf(cc);
443458db832SDavid du Colombier 	if(p == 0)
444458db832SDavid du Colombier 		return 0;
445458db832SDavid du Colombier 	isa->nopt = tokenize(p, isa->opt, NISAOPT);
446458db832SDavid du Colombier 	for(i = 0; i < isa->nopt; i++){
447458db832SDavid du Colombier 		p = isa->opt[i];
448458db832SDavid du Colombier 		if(cistrncmp(p, "type=", 5) == 0)
449458db832SDavid du Colombier 			isa->type = p + 5;
450458db832SDavid du Colombier 		else if(cistrncmp(p, "port=", 5) == 0)
451458db832SDavid du Colombier 			isa->port = strtoul(p+5, &p, 0);
452458db832SDavid du Colombier 		else if(cistrncmp(p, "irq=", 4) == 0)
453458db832SDavid du Colombier 			isa->irq = strtoul(p+4, &p, 0);
454458db832SDavid du Colombier 		else if(cistrncmp(p, "dma=", 4) == 0)
455458db832SDavid du Colombier 			isa->dma = strtoul(p+4, &p, 0);
456458db832SDavid du Colombier 		else if(cistrncmp(p, "mem=", 4) == 0)
457458db832SDavid du Colombier 			isa->mem = strtoul(p+4, &p, 0);
458458db832SDavid du Colombier 		else if(cistrncmp(p, "size=", 5) == 0)
459458db832SDavid du Colombier 			isa->size = strtoul(p+5, &p, 0);
460458db832SDavid du Colombier 		else if(cistrncmp(p, "freq=", 5) == 0)
461458db832SDavid du Colombier 			isa->freq = strtoul(p+5, &p, 0);
462458db832SDavid du Colombier 	}
463458db832SDavid du Colombier 	return 1;
464458db832SDavid du Colombier }
465458db832SDavid du Colombier 
466458db832SDavid du Colombier int
cistrcmp(char * a,char * b)467458db832SDavid du Colombier cistrcmp(char *a, char *b)
468458db832SDavid du Colombier {
469458db832SDavid du Colombier 	int ac, bc;
470458db832SDavid du Colombier 
471458db832SDavid du Colombier 	for(;;){
472458db832SDavid du Colombier 		ac = *a++;
473458db832SDavid du Colombier 		bc = *b++;
474458db832SDavid du Colombier 
475458db832SDavid du Colombier 		if(ac >= 'A' && ac <= 'Z')
476458db832SDavid du Colombier 			ac = 'a' + (ac - 'A');
477458db832SDavid du Colombier 		if(bc >= 'A' && bc <= 'Z')
478458db832SDavid du Colombier 			bc = 'a' + (bc - 'A');
479458db832SDavid du Colombier 		ac -= bc;
480458db832SDavid du Colombier 		if(ac)
481458db832SDavid du Colombier 			return ac;
482458db832SDavid du Colombier 		if(bc == 0)
483458db832SDavid du Colombier 			break;
484458db832SDavid du Colombier 	}
485458db832SDavid du Colombier 	return 0;
486458db832SDavid du Colombier }
487458db832SDavid du Colombier 
488458db832SDavid du Colombier int
cistrncmp(char * a,char * b,int n)489458db832SDavid du Colombier cistrncmp(char *a, char *b, int n)
490458db832SDavid du Colombier {
491458db832SDavid du Colombier 	unsigned ac, bc;
492458db832SDavid du Colombier 
493458db832SDavid du Colombier 	while(n > 0){
494458db832SDavid du Colombier 		ac = *a++;
495458db832SDavid du Colombier 		bc = *b++;
496458db832SDavid du Colombier 		n--;
497458db832SDavid du Colombier 
498458db832SDavid du Colombier 		if(ac >= 'A' && ac <= 'Z')
499458db832SDavid du Colombier 			ac = 'a' + (ac - 'A');
500458db832SDavid du Colombier 		if(bc >= 'A' && bc <= 'Z')
501458db832SDavid du Colombier 			bc = 'a' + (bc - 'A');
502458db832SDavid du Colombier 
503458db832SDavid du Colombier 		ac -= bc;
504458db832SDavid du Colombier 		if(ac)
505458db832SDavid du Colombier 			return ac;
506458db832SDavid du Colombier 		if(bc == 0)
507458db832SDavid du Colombier 			break;
508458db832SDavid du Colombier 	}
509458db832SDavid du Colombier 
510458db832SDavid du Colombier 	return 0;
511458db832SDavid du Colombier }
512