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