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