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