]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/sgi/main.c
sgi: new approach for etherseeq
[plan9front.git] / sys / src / 9 / sgi / 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        "../ip/ip.h"
10 #include        <tos.h>
11 #include        <../port/error.h>
12
13 enum {
14         /* space for syscall args, return PC, top-of-stack struct */
15         Stkheadroom     = sizeof(Sargs) + sizeof(uintptr) + sizeof(Tos),
16 };
17
18 static uchar *sp;               /* XXX - must go - user stack of init proc */
19 static FPsave initfp;
20
21 /*
22  * software tlb simulation
23  */
24 static Softtlb stlb[MAXMACH][STLBSIZE];
25
26 Conf    conf;
27
28 char*
29 getconf(char *name)
30 {
31         return (char*)arcs(0x78, name);
32 }
33
34 static void
35 fmtinit(void)
36 {
37         printinit();
38         quotefmtinstall();
39         /* ipreset installs these when chandevreset runs */
40         fmtinstall('i', eipfmt);
41         fmtinstall('I', eipfmt);
42         fmtinstall('E', eipfmt);
43         fmtinstall('V', eipfmt);
44         fmtinstall('M', eipfmt);
45 }
46
47 static int
48 ckpagemask(ulong mask, ulong size)
49 {
50         int s;
51         ulong pm;
52
53         s = splhi();
54         setpagemask(mask);
55         pm = getpagemask();
56         splx(s);
57         if(pm != mask){
58                 iprint("page size %ldK not supported on this cpu; "
59                         "mask %#lux read back as %#lux\n", size/1024, mask, pm);
60                 return -1;
61         }
62         return 0;
63 }
64
65 void
66 addmem(uintptr base, uintptr top)
67 {
68         uintptr s, e;
69         ulong *m;
70         int i;
71
72         if(base >= top)
73                 return;
74
75         /* exclude kernel */
76         s = 0;
77         e = PADDR(PGROUND((uintptr)end));
78         if(s < top && e > base){
79                 if(s > base)
80                         addmem(base, s);
81                 if(e < top)
82                         addmem(e, top);
83                 return;
84         }
85
86         /* exclude reserved firmware memory regions */
87         m = nil;
88         while((m = (ulong*)arcs(0x48, m)) != nil){
89                 s = m[1]<<12;
90                 e = s + (m[2]<<12);
91                 switch(m[0]){
92                 case 2: /* FreeMemory */
93                 case 3: /* BadMemory */
94                         continue;
95                 }
96                 if(s < top && e > base){
97                         if(s > base)
98                                 addmem(base, s);
99                         if(e < top)
100                                 addmem(e, top);
101                         return;
102                 }
103         }
104         for(i=0; i<nelem(conf.mem); i++){
105                 if(conf.mem[i].npage == 0){
106                         conf.mem[i].base = base;
107                         conf.mem[i].npage = (top - base)/BY2PG;
108
109                         conf.npage += conf.mem[i].npage;
110                         return;
111                 }
112         }
113         print("conf.mem[] too small\n");
114 }
115
116 /* 
117  * get memory configuration word for a bank
118  */
119 ulong
120 bank_conf(int bank)
121 {
122         switch(bank){
123         case 0:
124                 return *(ulong *)(KSEG1|MEMCFG0) >> 16;
125         case 1:
126                 return *(ulong *)(KSEG1|MEMCFG0) & 0xffff;
127         case 2:
128                 return *(ulong *)(KSEG1|MEMCFG1) >> 16;
129         case 3:
130                 return *(ulong *)(KSEG1|MEMCFG1) & 0xffff;
131         }
132         return 0;
133 }
134
135 void
136 meminit(void)
137 {
138         uintptr base, size, top;
139         ulong mconf;
140         int i;
141
142         /*
143          *  divide memory twixt user pages and kernel.
144          */
145         conf.npage = 0;
146         for(i=0; i<4; i++){
147                 mconf = bank_conf(i);
148                 if(!(mconf & 0x2000))
149                         continue;
150                 base = (mconf & 0xff) << 22;
151                 size = ((mconf & 0x1f00) + 0x0100) << 14;
152                 top = base + size;
153                 addmem(base, top);
154         }
155 }
156
157 void
158 main(void)
159 {
160         savefpregs(&initfp);
161
162         arcsconsinit();
163
164         meminit();
165         confinit();
166         machinit();                     /* calls clockinit */
167         active.exiting = 0;
168         active.machs = 1;
169         print("\nPlan 9\n");
170
171         kmapinit();
172         xinit();
173         timersinit();
174         fmtinit();
175
176         ckpagemask(PGSZ, BY2PG);
177         tlbinit();
178         pageinit();
179         procinit0();
180         initseg();
181         links();
182         chandevreset();
183
184         swapinit();
185         userinit();
186         schedinit();
187         panic("schedinit returned");
188 }
189
190 /*
191  *  initialize a processor's mach structure.  each processor does this
192  *  for itself.
193  */
194 void
195 machinit(void)
196 {
197         extern void gevector(void);     /* l.s */
198         extern void utlbmiss(void);
199         extern void vector0(void);
200         extern void vector180(void);
201
202         void **sbp = (void*)SPBADDR;
203
204         m->stb = stlb[m->machno];
205
206         /* install exception handlers */
207         sbp[0x18/4] = utlbmiss;
208         sbp[0x14/4] = gevector;
209
210         /* we could install our own vectors directly, but we'll try to play nice */
211         if(0){
212                 memmove((void*)(KSEG0+0x0), (void*)vector0, 0x80);
213                 memmove((void*)(KSEG0+0x180), (void*)vector180, 0x80);
214                 icflush((void*)(KSEG0+0x0), 0x80);
215                 icflush((void*)(KSEG0+0x180), 0x80);
216         }
217
218         /* Ensure CU1 is off */
219         clrfpintr();
220         clockinit();
221 }
222
223 void
224 init0(void)
225 {
226         char buf[128];
227
228         up->nerrlab = 0;
229
230         spllo();
231
232         /*
233          * These are o.k. because rootinit is null.
234          * Then early kproc's will have a root and dot.
235          */
236         up->slash = namec("#/", Atodir, 0, 0);
237         pathclose(up->slash->path);
238         up->slash->path = newpath("/");
239         up->dot = cclone(up->slash);
240
241         chandevinit();
242
243         if(!waserror()){
244                 ksetenv("cputype", "mips", 0);
245                 snprint(buf, sizeof buf, "mips %s", conffile);
246                 ksetenv("terminal", buf, 0);
247                 if(cpuserver)
248                         ksetenv("service", "cpu", 0);
249                 else
250                         ksetenv("service", "terminal", 0);
251
252                 ksetenv("bootargs", "tcp", 0);
253
254                 /* make kbdfs attach to /dev/eia0 arcs console */ 
255                 ksetenv("console", "0", 0);
256
257                 /* no usb */
258                 ksetenv("usbwait", "0", 0);
259                 ksetenv("nousbrc", "1", 0);
260
261                 poperror();
262         }
263
264         /* process input for arcs console */
265         kproc("arcs", arcsproc, 0);
266
267         kproc("alarm", alarmkproc, 0);
268         touser(sp);
269 }
270
271 static uchar *
272 pusharg(char *p)
273 {
274         int n;
275         
276         n = strlen(p) + 1;
277         sp -= n;
278         memmove(sp, p, n);
279         return sp;
280 }
281
282 static void
283 bootargs(uintptr base)
284 {       int i, ac;
285         uchar *av[32];
286         uchar **lsp;
287         
288         sp = (uchar *) base + BY2PG - sizeof(Tos);
289         
290         ac = 0;
291         av[ac++] = pusharg("boot");
292         sp = (uchar *) ((ulong) sp & ~7);
293         sp -= ROUND((ac + 1) * sizeof(sp), 8) + 4;
294         lsp = (uchar **) sp;
295         for(i = 0; i < ac; i++)
296                 lsp[i] = av[i] + ((USTKTOP - BY2PG) - (ulong) base);
297         lsp[i] = 0;
298         sp += (USTKTOP - BY2PG) - (ulong) base;
299 }
300
301 void
302 userinit(void)
303 {
304         Proc *p;
305         KMap *k;
306         Page *pg;
307         Segment *s;
308
309         p = newproc();
310         p->pgrp = newpgrp();
311         p->egrp = smalloc(sizeof(Egrp));
312         p->egrp->ref = 1;
313         p->fgrp = dupfgrp(nil);
314         p->rgrp = newrgrp();
315         p->procmode = 0640;
316
317         kstrdup(&eve, "");
318         kstrdup(&p->text, "*init*");
319         kstrdup(&p->user, eve);
320
321         procsetup(p);
322
323         /*
324          * Kernel Stack
325          */
326         p->sched.pc = (ulong)init0;
327         p->sched.sp = (ulong)p->kstack+KSTACK-Stkheadroom;
328         p->sched.sp = STACKALIGN(p->sched.sp);
329
330         /*
331          * User Stack
332          *
333          * Technically, newpage can't be called here because it
334          * should only be called when in a user context as it may
335          * try to sleep if there are no pages available, but that
336          * shouldn't be the case here.
337          */
338         s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
339         p->seg[SSEG] = s;
340         pg = newpage(1, 0, USTKTOP-BY2PG);
341         segpage(s, pg);
342         k = kmap(pg);
343         bootargs(VA(k));
344         kunmap(k);
345
346         /*
347          * Text
348          */
349         s = newseg(SG_TEXT, UTZERO, 1);
350         s->flushme++;
351         p->seg[TSEG] = s;
352         pg = newpage(1, 0, UTZERO);
353         pg->txtflush = ~0;
354         segpage(s, pg);
355         k = kmap(s->map[0]->pages[0]);
356         memset((void *)VA(k), 0, BY2PG);
357         memmove((ulong*)VA(k), initcode, sizeof initcode);
358         kunmap(k);
359
360         ready(p);
361 }
362
363 void
364 exit(int ispanic)
365 {
366         splhi();
367         while(ispanic);
368         arcs(0x18);     /* reboot */
369 }
370
371 void
372 reboot(void *, void *, ulong)
373 {
374 }
375
376 void
377 evenaddr(uintptr va)
378 {
379         if((va & 3) != 0){
380                 dumpstack();
381                 postnote(up, 1, "sys: odd address", NDebug);
382                 error(Ebadarg);
383         }
384 }
385
386 void
387 procsetup(Proc *p)
388 {
389         p->fpstate = FPinit;
390         p->fpsave = initfp;
391
392         cycles(&p->kentry);
393         p->pcycles = -p->kentry;
394 }
395
396 void
397 procfork(Proc *p)
398 {
399         int s;
400
401         p->kentry = up->kentry;
402         p->pcycles = -p->kentry;
403
404         s = splhi();
405         switch(up->fpstate & ~FPillegal){
406         case FPactive:
407                 savefpregs(&up->fpsave);
408                 up->fpstate = FPinactive;
409                 /* wet floor */
410         case FPinactive:
411                 p->fpsave = up->fpsave;
412                 p->fpstate = FPinactive;
413         }
414         splx(s);
415 }
416
417 void
418 procsave(Proc *p)
419 {
420         uvlong t;
421
422         if(p->fpstate == FPactive){
423                 if(p->state != Moribund) {
424                         savefpregs(&p->fpsave);
425                         p->fpstate = FPinactive;
426                 }
427         }
428         
429         cycles(&t);
430         p->pcycles += t;
431 }
432
433 void
434 procrestore(Proc *p)
435 {
436         uvlong t;
437
438         if(p->kp)
439                 return;
440         cycles(&t);
441         p->pcycles -= t;
442 }
443
444 void
445 idlehands(void)
446 {
447 }
448
449 void
450 confinit(void)
451 {
452         ulong kpages;
453
454         /*
455          *  set up CPU's mach structure
456          *  cpu0's was zeroed in l.s and our stack is in Mach, so don't zero it.
457          */
458         m->machno = 0;
459         m->speed = 150;                 /* initial guess at MHz */
460         m->hz = m->speed * Mhz;
461         conf.nmach = 1;
462
463         /* set up other configuration parameters */
464         conf.nproc = 2000;
465         conf.nswap = 262144;
466         conf.nswppo = 4096;
467         conf.nimage = 200;
468
469         conf.copymode = 0;              /* copy on write */
470
471         kpages = conf.npage - (conf.npage*80)/100;
472         if(kpages > (64*MB + conf.npage*sizeof(Page))/BY2PG){
473                 kpages = (64*MB + conf.npage*sizeof(Page))/BY2PG;
474                 kpages += (conf.nproc*KSTACK)/BY2PG;
475         }
476         conf.upages = conf.npage - kpages;
477         conf.ialloc = (kpages/2)*BY2PG;
478
479         kpages *= BY2PG;
480         kpages -= conf.upages*sizeof(Page)
481                 + conf.nproc*sizeof(Proc)
482                 + conf.nimage*sizeof(Image)
483                 + conf.nswap
484                 + conf.nswppo*sizeof(Page*);
485         mainmem->maxsize = kpages;
486 //      mainmem->flags |= POOL_PARANOIA;
487 }