]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/mtx/main.c
kernel: change active.machs from bitmap to char array to support up to 64 cpus on...
[plan9front.git] / sys / src / 9 / mtx / main.c
1 #include        "u.h"
2 #include        "../port/lib.h"
3 #include        "mem.h"
4 #include        "dat.h"
5 #include        "fns.h"
6 #include        "io.h"
7 #include        "init.h"
8 #include        "pool.h"
9
10 Conf    conf;
11 FPsave  initfp;
12
13 void
14 main(void)
15 {
16         memset(edata, 0, (ulong)end-(ulong)edata);
17         conf.nmach = 1;
18         machinit();
19         ioinit();
20         i8250console();
21         quotefmtinstall();
22         print("\nPlan 9\n");
23         confinit();
24         xinit();
25         raveninit();
26         trapinit();
27         printinit();
28         cpuidprint();
29         mmuinit();
30         hwintrinit();
31         clockinit();
32         procinit0();
33         initseg();
34         timersinit();
35         links();
36         chandevreset();
37         pageinit();
38         swapinit();
39         fpsave(&initfp);
40         initfp.fpscr = 0;
41         userinit();
42         schedinit();
43 }
44
45 void
46 machinit(void)
47 {
48         memset(m, 0, sizeof(Mach));
49         m->cputype = getpvr()>>16;
50
51         /*
52          * For polled uart output at boot, need
53          * a default delay constant. 100000 should
54          * be enough for a while. Cpuidentify will
55          * calculate the real value later.
56          */
57         m->loopconst = 100000;
58
59         /* turn on caches */
60         puthid0(gethid0() | BIT(16) | BIT(17));
61
62         active.machs[0] = 1;
63         active.exiting = 0;
64 }
65
66 void
67 cpuidprint(void)
68 {
69         char *id;
70
71         id = "unknown PowerPC";
72         switch(m->cputype) {
73         case 9:
74                 id = "PowerPC 604e";
75                 break;
76         }
77         print("cpu0: %s\n", id);
78 }
79
80 static struct
81 {
82         char    *name;
83         char *val;
84 }
85 plan9ini[] =
86 {
87         { "console", "0" },
88         { "ether0", "type=2114x" },
89 };
90
91 char*
92 getconf(char *name)
93 {
94         int i;
95
96         for(i = 0; i < nelem(plan9ini); i++)
97                 if(cistrcmp(name, plan9ini[i].name) == 0)
98                         return plan9ini[i].val;
99         return nil;
100 }
101
102 void
103 init0(void)
104 {
105 //      char **p, *q, name[KNAMELEN];
106 //      int n;
107         char buf[2*KNAMELEN];
108
109         up->nerrlab = 0;
110
111         spllo();
112
113         /*
114          * These are o.k. because rootinit is null.
115          * Then early kproc's will have a root and dot.
116          */
117         up->slash = namec("#/", Atodir, 0, 0);
118         pathclose(up->slash->path);
119         up->slash->path = newpath("/");
120         up->dot = cclone(up->slash);
121
122         chandevinit();
123
124         if(!waserror()){
125                 snprint(buf, sizeof(buf), "power %s mtx", conffile);
126                 ksetenv("terminal", buf, 0);
127                 ksetenv("cputype", "power", 0);
128                 if(cpuserver)
129                         ksetenv("service", "cpu", 0);
130                 else
131                         ksetenv("service", "terminal", 0);
132                 
133 /*
134                 for(p = confenv; *p; p++) {
135                         q = strchr(p[0], '=');
136                         if(q == 0)
137                                 continue;
138                         n = q-p[0];
139                         if(n >= KNAMELEN)
140                                 n = KNAMELEN-1;
141                         memmove(name, p[0], n);
142                         name[n] = 0;
143                         if(name[0] != '*')
144                                 ksetenv(name, q+1, 0);
145                         ksetenv(name, q+1, 1);
146                 }
147 */
148                 poperror();
149         }
150         kproc("alarm", alarmkproc, 0);
151         kproc("mmusweep", mmusweep, 0);
152         touser((void*)(USTKTOP-8));
153 }
154
155 void
156 userinit(void)
157 {
158         Proc *p;
159         Segment *s;
160         KMap *k;
161         Page *pg;
162
163         p = newproc();
164         p->pgrp = newpgrp();
165         p->egrp = smalloc(sizeof(Egrp));
166         p->egrp->ref = 1;
167         p->fgrp = dupfgrp(nil);
168         p->rgrp = newrgrp();
169         p->procmode = 0640;
170
171         kstrdup(&eve, "");
172         kstrdup(&p->text, "*init*");
173         kstrdup(&p->user, eve);
174
175         p->fpstate = FPinit;
176
177         /*
178          * Kernel Stack
179          *
180          * N.B. The -12 for the stack pointer is important.
181          *      4 bytes for gotolabel's return PC
182          */
183         p->sched.pc = (ulong)init0;
184         p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
185
186         /*
187          * User Stack
188          */
189         s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
190         p->seg[SSEG] = s;
191         pg = newpage(1, 0, USTKTOP-BY2PG);
192         segpage(s, pg);
193
194         /*
195          * Text
196          */
197         s = newseg(SG_TEXT, UTZERO, 1);
198         s->flushme++;
199         p->seg[TSEG] = s;
200         pg = newpage(1, 0, UTZERO);
201         pg->txtflush = ~0;
202         segpage(s, pg);
203         k = kmap(s->map[0]->pages[0]);
204         memmove((ulong*)VA(k), initcode, sizeof initcode);
205         kunmap(k);
206
207         ready(p);
208 }
209
210 /* still to do */
211 void
212 reboot(void*, void*, ulong)
213 {
214 }
215
216 void
217 exit(int)
218 {
219         cpushutdown();
220         watchreset();
221 }
222
223 /*
224  *  set up floating point for a new process
225  */
226 void
227 procsetup(Proc *p)
228 {
229         p->fpstate = FPinit;
230 }
231
232 void
233 procfork(Proc *)
234 {
235 }
236
237 /*
238  *  Save the mach dependent part of the process state.
239  */
240 void
241 procsave(Proc *p)
242 {
243         if(p->fpstate == FPactive){
244                 if(p->state != Moribund)
245                         fpsave(&up->fpsave);
246                 p->fpstate = FPinactive;
247         }
248 }
249
250 void
251 confinit(void)
252 {
253         char *p;
254         int userpcnt;
255         ulong pa, kpages;
256         extern ulong memsize;   /* passed in from ROM monitor */
257
258         if(p = getconf("*kernelpercent"))
259                 userpcnt = 100 - strtol(p, 0, 0);
260         else
261                 userpcnt = 0;
262
263         pa = PGROUND(PADDR(end));
264
265         conf.mem[0].npage = memsize/BY2PG;
266         conf.mem[0].base = pa;
267         conf.npage = conf.mem[0].npage;
268
269         conf.nmach = 1;
270         conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
271         if(cpuserver)
272                 conf.nproc *= 3;
273         if(conf.nproc > 2000)
274                 conf.nproc = 2000;
275         conf.nimage = 200;
276         conf.nswap = conf.nproc*80;
277         conf.nswppo = 4096;
278         conf.copymode = 0;                      /* copy on write */
279
280         if(cpuserver) {
281                 if(userpcnt < 10)
282                         userpcnt = 70;
283                 kpages = conf.npage - (conf.npage*userpcnt)/100;
284
285                 /*
286                  * Hack for the big boys. Only good while physmem < 4GB.
287                  * Give the kernel a max. of 16MB + enough to allocate the
288                  * page pool.
289                  * This is an overestimate as conf.upages < conf.npages.
290                  * The patch of nimage is a band-aid, scanning the whole
291                  * page list in imagereclaim just takes too long.
292                  */
293                 if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
294                         kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
295                         conf.nimage = 2000;
296                         kpages += (conf.nproc*KSTACK)/BY2PG;
297                 }
298         } else {
299                 if(userpcnt < 10) {
300                         if(conf.npage*BY2PG < 16*MB)
301                                 userpcnt = 40;
302                         else
303                                 userpcnt = 60;
304                 }
305                 kpages = conf.npage - (conf.npage*userpcnt)/100;
306
307                 /*
308                  * Make sure terminals with low memory get at least
309                  * 4MB on the first Image chunk allocation.
310                  */
311                 if(conf.npage*BY2PG < 16*MB)
312                         imagmem->minarena = 4*1024*1024;
313         }
314         conf.upages = conf.npage - kpages;
315         conf.ialloc = (kpages/2)*BY2PG;
316
317         /*
318          * Guess how much is taken by the large permanent
319          * datastructures. Mntcache and Mntrpc are not accounted for.
320          */
321         kpages *= BY2PG;
322         kpages -= conf.upages*sizeof(Page)
323                 + conf.nproc*sizeof(Proc)
324                 + conf.nimage*sizeof(Image)
325                 + conf.nswap
326                 + conf.nswppo*sizeof(Page*);
327         mainmem->maxsize = kpages;
328         if(!cpuserver){
329                 /*
330                  * give terminals lots of image memory, too; the dynamic
331                  * allocation will balance the load properly, hopefully.
332                  * be careful with 32-bit overflow.
333                  */
334                 imagmem->maxsize = kpages;
335         }
336
337 //      conf.monitor = 1;       /* BUG */
338 }
339
340 static int
341 getcfields(char* lp, char** fields, int n, char* sep)
342 {
343         int i;
344
345         for(i = 0; lp && *lp && i < n; i++){
346                 while(*lp && strchr(sep, *lp) != 0)
347                         *lp++ = 0;
348                 if(*lp == 0)
349                         break;
350                 fields[i] = lp;
351                 while(*lp && strchr(sep, *lp) == 0){
352                         if(*lp == '\\' && *(lp+1) == '\n')
353                                 *lp++ = ' ';
354                         lp++;
355                 }
356         }
357
358         return i;
359 }
360
361 int
362 isaconfig(char *class, int ctlrno, ISAConf *isa)
363 {
364         int i;
365         char cc[KNAMELEN], *p;
366
367         sprint(cc, "%s%d", class, ctlrno);
368
369         p = getconf(cc);
370         if(p == 0)
371                 return 0;
372         isa->nopt = tokenize(p, isa->opt, NISAOPT);
373         for(i = 0; i < isa->nopt; i++){
374                 p = isa->opt[i];
375                 if(cistrncmp(p, "type=", 5) == 0)
376                         isa->type = p + 5;
377                 else if(cistrncmp(p, "port=", 5) == 0)
378                         isa->port = strtoul(p+5, &p, 0);
379                 else if(cistrncmp(p, "irq=", 4) == 0)
380                         isa->irq = strtoul(p+4, &p, 0);
381                 else if(cistrncmp(p, "dma=", 4) == 0)
382                         isa->dma = strtoul(p+4, &p, 0);
383                 else if(cistrncmp(p, "mem=", 4) == 0)
384                         isa->mem = strtoul(p+4, &p, 0);
385                 else if(cistrncmp(p, "size=", 5) == 0)
386                         isa->size = strtoul(p+5, &p, 0);
387                 else if(cistrncmp(p, "freq=", 5) == 0)
388                         isa->freq = strtoul(p+5, &p, 0);
389         }
390         return 1;
391 }
392
393 int
394 cistrcmp(char *a, char *b)
395 {
396         int ac, bc;
397
398         for(;;){
399                 ac = *a++;
400                 bc = *b++;
401         
402                 if(ac >= 'A' && ac <= 'Z')
403                         ac = 'a' + (ac - 'A');
404                 if(bc >= 'A' && bc <= 'Z')
405                         bc = 'a' + (bc - 'A');
406                 ac -= bc;
407                 if(ac)
408                         return ac;
409                 if(bc == 0)
410                         break;
411         }
412         return 0;
413 }
414
415 int
416 cistrncmp(char *a, char *b, int n)
417 {
418         unsigned ac, bc;
419
420         while(n > 0){
421                 ac = *a++;
422                 bc = *b++;
423                 n--;
424
425                 if(ac >= 'A' && ac <= 'Z')
426                         ac = 'a' + (ac - 'A');
427                 if(bc >= 'A' && bc <= 'Z')
428                         bc = 'a' + (bc - 'A');
429
430                 ac -= bc;
431                 if(ac)
432                         return ac;
433                 if(bc == 0)
434                         break;
435         }
436
437         return 0;
438 }