2 #include "../port/lib.h"
13 typedef struct Plan9ini Plan9ini;
21 Plan9ini plan9ini[MAXCONF];
28 static void plan9iniinit(void);
35 id = "unknown PowerPC";
58 print("cpu0: %s, rev 0x%lux, cpu hz %lld, bus hz %ld\n",
59 cpuid(), getpvr()&0xffff, m->cpuhz, m->bushz);
65 memset(edata, 0, (ulong)end-(ulong)edata);
80 print("\nPlan 9 from Bell Labs\n");
100 for(i = 0; i < nconf; i++)
101 if(cistrcmp(name, plan9ini[i].name) == 0)
102 return plan9ini[i].val;
111 char *cp, line[MAXCONF], *p, *q;
114 * parse configuration args from dos file plan9.ini
118 for(i = 0; i < MAXCONF; i++){
120 * Strip out '\r', change '\t' -> ' ', test for 0xff which is end of file
123 for(q = cp; c = (uchar)*q; q++){
128 if(c == 0xff || c == '\n')
135 if(*line != '#' && (cp = strchr(line, '='))){
137 kstrdup(&plan9ini[nconf].name, line);
138 kstrdup(&plan9ini[nconf].val, cp);
151 // char **p, *q, name[KNAMELEN];
153 char buf[2*KNAMELEN];
159 * These are o.k. because rootinit is null.
160 * Then early kproc's will have a root and dot.
162 up->slash = namec("#/", Atodir, 0, 0);
163 pathclose(up->slash->path);
164 up->slash->path = newpath("/");
165 up->dot = cclone(up->slash);
170 snprint(buf, sizeof(buf), "power %s mtx", conffile);
171 ksetenv("terminal", buf, 0);
172 ksetenv("cputype", "power", 0);
174 ksetenv("service", "cpu", 0);
176 ksetenv("service", "terminal", 0);
178 for(i = 0; i < nconf; i++){
179 if(plan9ini[i].name[0] != '*')
180 ksetenv(plan9ini[i].name, plan9ini[i].val, 0);
181 ksetenv(plan9ini[i].name, plan9ini[i].val, 1);
185 kproc("alarm", alarmkproc, 0);
186 kproc("mmusweep", mmusweep, 0);
187 touser((void*)(USTKTOP-sizeof(Tos)));
200 p->egrp = smalloc(sizeof(Egrp));
202 p->fgrp = dupfgrp(nil);
207 kstrdup(&p->text, "*init*");
208 kstrdup(&p->user, eve);
215 * N.B. The -12 for the stack pointer is important.
216 * 4 bytes for gotolabel's return PC
218 p->sched.pc = (ulong)init0;
219 p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
224 s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
226 pg = newpage(1, 0, USTKTOP-BY2PG);
232 s = newseg(SG_TEXT, UTZERO, 1);
235 pg = newpage(1, 0, UTZERO);
238 k = kmap(s->map[0]->pages[0]);
239 memmove((ulong*)VA(k), initcode, sizeof initcode);
252 active.ispanic = ispanic;
253 else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
255 once = active.machs & (1<<m->machno);
256 active.machs &= ~(1<<m->machno);
261 print("cpu%d: exiting\n", m->machno);
263 for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
265 if(active.machs == 0 && consactive() == 0)
269 if(active.ispanic && m->machno == 0){
272 else if(conf.monitor)
281 * set up floating point for a new process
289 p->pcycles = -p->kentry;
295 p->kentry = up->kentry;
296 p->pcycles = -p->kentry;
312 * Save the mach dependent part of the process state.
322 if(p->fpstate == FPactive){
323 if(p->state != Moribund)
325 p->fpstate = FPinactive;
335 /* passed in from ROM monitor: */
337 if(p = getconf("service")){
338 if(strcmp(p, "cpu") == 0)
340 else if(strcmp(p,"terminal") == 0)
344 if(p = getconf("*kernelpercent"))
345 userpcnt = 100 - strtol(p, 0, 0);
349 pa = PGROUND(PADDR(end));
351 /* Blast Board specific */
352 conf.mem[0].npage = (MEM1SIZE - pa)/BY2PG;
353 conf.mem[0].base = pa;
355 conf.mem[1].npage = MEM2SIZE/BY2PG;
356 conf.mem[1].base = MEM2BASE;
358 conf.npage = conf.mem[0].npage + conf.mem[1].npage;
361 conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
364 if(conf.nproc > 2000)
367 conf.nswap = conf.nproc*80;
369 conf.copymode = 0; /* copy on write */
374 kpages = conf.npage - (conf.npage*userpcnt)/100;
377 * Hack for the big boys. Only good while physmem < 4GB.
378 * Give the kernel a max. of 16MB + enough to allocate the
380 * This is an overestimate as conf.upages < conf.npages.
381 * The patch of nimage is a band-aid, scanning the whole
382 * page list in imagereclaim just takes too long.
384 if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
385 kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
387 kpages += (conf.nproc*KSTACK)/BY2PG;
391 if(conf.npage*BY2PG < 16*MB)
396 kpages = conf.npage - (conf.npage*userpcnt)/100;
399 * Make sure terminals with low memory get at least
400 * 4MB on the first Image chunk allocation.
402 if(conf.npage*BY2PG < 16*MB)
403 imagmem->minarena = 4*1024*1024;
405 conf.upages = conf.npage - kpages;
406 conf.ialloc = (kpages/2)*BY2PG;
409 * Guess how much is taken by the large permanent
410 * datastructures. Mntcache and Mntrpc are not accounted for.
413 kpages -= conf.upages*sizeof(Page)
414 + conf.nproc*sizeof(Proc)
415 + conf.nimage*sizeof(Image)
417 + conf.nswppo*sizeof(Page*);
418 mainmem->maxsize = kpages;
421 * give terminals lots of image memory, too; the dynamic
422 * allocation will balance the load properly, hopefully.
423 * be careful with 32-bit overflow.
425 imagmem->maxsize = kpages;
428 // conf.monitor = 1; /* BUG */
432 getcfields(char* lp, char** fields, int n, char* sep)
436 for(i = 0; lp && *lp && i < n; i++){
437 while(*lp && strchr(sep, *lp) != 0)
442 while(*lp && strchr(sep, *lp) == 0){
443 if(*lp == '\\' && *(lp+1) == '\n')
453 isaconfig(char *class, int ctlrno, ISAConf *isa)
456 char cc[KNAMELEN], *p;
458 sprint(cc, "%s%d", class, ctlrno);
463 isa->nopt = tokenize(p, isa->opt, NISAOPT);
464 for(i = 0; i < isa->nopt; i++){
466 if(cistrncmp(p, "type=", 5) == 0)
468 else if(cistrncmp(p, "port=", 5) == 0)
469 isa->port = strtoul(p+5, &p, 0);
470 else if(cistrncmp(p, "irq=", 4) == 0)
471 isa->irq = strtoul(p+4, &p, 0);
472 else if(cistrncmp(p, "dma=", 4) == 0)
473 isa->dma = strtoul(p+4, &p, 0);
474 else if(cistrncmp(p, "mem=", 4) == 0)
475 isa->mem = strtoul(p+4, &p, 0);
476 else if(cistrncmp(p, "size=", 5) == 0)
477 isa->size = strtoul(p+5, &p, 0);
478 else if(cistrncmp(p, "freq=", 5) == 0)
479 isa->freq = strtoul(p+5, &p, 0);
485 cistrcmp(char *a, char *b)
493 if(ac >= 'A' && ac <= 'Z')
494 ac = 'a' + (ac - 'A');
495 if(bc >= 'A' && bc <= 'Z')
496 bc = 'a' + (bc - 'A');
507 cistrncmp(char *a, char *b, int n)
516 if(ac >= 'A' && ac <= 'Z')
517 ac = 'a' + (ac - 'A');
518 if(bc >= 'A' && bc <= 'Z')
519 bc = 'a' + (bc - 'A');