]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/sgi/main.c
pc/pmmc: check pci membar type
[plan9front.git] / sys / src / 9 / sgi / main.c
1 #include        "u.h"
2 #include        "tos.h"
3 #include        "../port/lib.h"
4 #include        "mem.h"
5 #include        "dat.h"
6 #include        "fns.h"
7 #include        "io.h"
8 #include        "pool.h"
9 #include        "../ip/ip.h"
10 #include        <../port/error.h>
11
12 static FPsave initfp;
13
14 /*
15  * software tlb simulation
16  */
17 static Softtlb stlb[MAXMACH][STLBSIZE];
18
19 Conf    conf;
20
21 char*
22 getconf(char *name)
23 {
24         return (char*)arcs(0x78, name);
25 }
26
27 static void
28 fmtinit(void)
29 {
30         printinit();
31         quotefmtinstall();
32         /* ipreset installs these when chandevreset runs */
33         fmtinstall('i', eipfmt);
34         fmtinstall('I', eipfmt);
35         fmtinstall('E', eipfmt);
36         fmtinstall('V', eipfmt);
37         fmtinstall('M', eipfmt);
38 }
39
40 static int
41 ckpagemask(ulong mask, ulong size)
42 {
43         int s;
44         ulong pm;
45
46         s = splhi();
47         setpagemask(mask);
48         pm = getpagemask();
49         splx(s);
50         if(pm != mask){
51                 iprint("page size %ldK not supported on this cpu; "
52                         "mask %#lux read back as %#lux\n", size/1024, mask, pm);
53                 return -1;
54         }
55         return 0;
56 }
57
58 void
59 addmem(uintptr base, uintptr top)
60 {
61         uintptr s, e;
62         ulong *m;
63         int i;
64
65         if(base >= top)
66                 return;
67
68         /* exclude kernel */
69         s = 0;
70         e = PADDR(PGROUND((uintptr)end));
71         if(s < top && e > base){
72                 if(s > base)
73                         addmem(base, s);
74                 if(e < top)
75                         addmem(e, top);
76                 return;
77         }
78
79         /* exclude reserved firmware memory regions */
80         m = nil;
81         while((m = (ulong*)arcs(0x48, m)) != nil){
82                 s = m[1]<<12;
83                 e = s + (m[2]<<12);
84                 switch(m[0]){
85                 case 2: /* FreeMemory */
86                 case 3: /* BadMemory */
87                         continue;
88                 }
89                 if(s < top && e > base){
90                         if(s > base)
91                                 addmem(base, s);
92                         if(e < top)
93                                 addmem(e, top);
94                         return;
95                 }
96         }
97         for(i=0; i<nelem(conf.mem); i++){
98                 if(conf.mem[i].npage == 0){
99                         conf.mem[i].base = base;
100                         conf.mem[i].npage = (top - base)/BY2PG;
101
102                         conf.npage += conf.mem[i].npage;
103                         return;
104                 }
105         }
106         print("conf.mem[] too small\n");
107 }
108
109 /* 
110  * get memory configuration word for a bank
111  */
112 ulong
113 bank_conf(int bank)
114 {
115         switch(bank){
116         case 0:
117                 return *(ulong *)(KSEG1|MEMCFG0) >> 16;
118         case 1:
119                 return *(ulong *)(KSEG1|MEMCFG0) & 0xffff;
120         case 2:
121                 return *(ulong *)(KSEG1|MEMCFG1) >> 16;
122         case 3:
123                 return *(ulong *)(KSEG1|MEMCFG1) & 0xffff;
124         }
125         return 0;
126 }
127
128 void
129 meminit(void)
130 {
131         uintptr base, size, top;
132         ulong mconf;
133         int i;
134
135         /*
136          *  divide memory twixt user pages and kernel.
137          */
138         conf.npage = 0;
139         for(i=0; i<4; i++){
140                 mconf = bank_conf(i);
141                 if(!(mconf & 0x2000))
142                         continue;
143                 base = (mconf & 0xff) << 22;
144                 size = ((mconf & 0x1f00) + 0x0100) << 14;
145                 top = base + size;
146                 addmem(base, top);
147         }
148 }
149
150 static int
151 havegfx(void)
152 {
153         char *s = getconf("ConsoleOut");
154         return s != nil && strstr(s, "video()") != nil;
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[0] = 1;
169         print("\nPlan 9\n");
170
171         kmapinit();
172         xinit();
173         timersinit();
174         fmtinit();
175
176         if(havegfx()){
177                 conf.monitor = 1;
178                 screeninit();
179         }
180
181         ckpagemask(PGSZ, BY2PG);
182         tlbinit();
183         pageinit();
184         procinit0();
185         initseg();
186         links();
187         chandevreset();
188         userinit();
189         schedinit();
190         panic("schedinit returned");
191 }
192
193 /*
194  *  initialize a processor's mach structure.  each processor does this
195  *  for itself.
196  */
197 void
198 machinit(void)
199 {
200         extern void gevector(void);     /* l.s */
201         extern void utlbmiss(void);
202         extern void vector0(void);
203         extern void vector180(void);
204
205         void **sbp = (void*)SPBADDR;
206
207         m->stb = stlb[m->machno];
208
209         /* install exception handlers */
210         sbp[0x18/4] = utlbmiss;
211         sbp[0x14/4] = gevector;
212
213         /* we could install our own vectors directly, but we'll try to play nice */
214         if(0){
215                 memmove((void*)(KSEG0+0x0), (void*)vector0, 0x80);
216                 memmove((void*)(KSEG0+0x180), (void*)vector180, 0x80);
217                 icflush((void*)(KSEG0+0x0), 0x80);
218                 icflush((void*)(KSEG0+0x180), 0x80);
219         }
220
221         /* Ensure CU1 is off */
222         clrfpintr();
223         clockinit();
224 }
225
226 void
227 init0(void)
228 {
229         char buf[128], **sp;
230
231         chandevinit();
232
233         if(!waserror()){
234                 ksetenv("cputype", "mips", 0);
235                 snprint(buf, sizeof buf, "mips %s", conffile);
236                 ksetenv("terminal", buf, 0);
237                 if(cpuserver)
238                         ksetenv("service", "cpu", 0);
239                 else
240                         ksetenv("service", "terminal", 0);
241
242                 ksetenv("bootargs", "tcp", 0);
243                 ksetenv("console", "0", 0);
244
245                 /* no usb */
246                 ksetenv("usbwait", "0", 0);
247                 ksetenv("nousbrc", "1", 0);
248
249                 poperror();
250         }
251
252         /* process input for arcs console */
253         if(!conf.keyboard)
254                 kproc("arcs", arcsproc, 0);
255
256         kproc("alarm", alarmkproc, 0);
257
258         sp = (char**)(USTKTOP-sizeof(Tos) - 8 - sizeof(sp[0])*4);
259         sp[3] = sp[2] = sp[1] = nil;
260         strcpy(sp[0] = (char*)&sp[4], "boot");
261         touser(sp);
262 }
263
264 void
265 exit(int)
266 {
267         cpushutdown();
268         splhi();
269         arcs(0x18);     /* reboot */
270 }
271
272 void
273 reboot(void *, void *, ulong)
274 {
275 }
276
277 void
278 evenaddr(uintptr va)
279 {
280         if((va & 3) != 0){
281                 dumpstack();
282                 postnote(up, 1, "sys: odd address", NDebug);
283                 error(Ebadarg);
284         }
285 }
286
287 void
288 procsetup(Proc *p)
289 {
290         p->fpstate = FPinit;
291         memmove(p->fpsave, &initfp, sizeof(FPsave));
292
293         cycles(&p->kentry);
294         p->pcycles = -p->kentry;
295 }
296
297 void
298 procfork(Proc *p)
299 {
300         int s;
301
302         p->kentry = up->kentry;
303         p->pcycles = -p->kentry;
304
305         s = splhi();
306         switch(up->fpstate & ~FPillegal){
307         case FPactive:
308                 savefpregs(up->fpsave);
309                 up->fpstate = FPinactive;
310                 /* wet floor */
311         case FPinactive:
312                 memmove(p->fpsave, up->fpsave, sizeof(FPsave));
313                 p->fpstate = FPinactive;
314         }
315         splx(s);
316 }
317
318 void
319 procsave(Proc *p)
320 {
321         uvlong t;
322
323         if(p->fpstate == FPactive){
324                 if(p->state != Moribund) {
325                         savefpregs(p->fpsave);
326                         p->fpstate = FPinactive;
327                 }
328         }
329         
330         cycles(&t);
331         p->pcycles += t;
332 }
333
334 void
335 procrestore(Proc *p)
336 {
337         uvlong t;
338
339         if(p->kp)
340                 return;
341         cycles(&t);
342         p->pcycles -= t;
343 }
344
345 void
346 idlehands(void)
347 {
348 }
349
350 void
351 confinit(void)
352 {
353         ulong kpages;
354
355         /*
356          *  set up CPU's mach structure
357          *  cpu0's was zeroed in l.s and our stack is in Mach, so don't zero it.
358          */
359         m->machno = 0;
360         m->speed = 150;                 /* initial guess at MHz */
361         m->hz = m->speed * Mhz;
362         conf.nmach = 1;
363
364         /* set up other configuration parameters */
365         conf.nproc = 2000;
366         conf.nswap = 262144;
367         conf.nswppo = 4096;
368         conf.nimage = 200;
369
370         conf.copymode = 0;              /* copy on write */
371
372         kpages = conf.npage - (conf.npage*80)/100;
373         if(kpages > (64*MB + conf.npage*sizeof(Page))/BY2PG){
374                 kpages = (64*MB + conf.npage*sizeof(Page))/BY2PG;
375                 kpages += (conf.nproc*KSTACK)/BY2PG;
376         }
377         conf.upages = conf.npage - kpages;
378         conf.ialloc = (kpages/2)*BY2PG;
379
380         kpages *= BY2PG;
381         kpages -= conf.upages*sizeof(Page)
382                 + conf.nproc*sizeof(Proc)
383                 + conf.nimage*sizeof(Image)
384                 + conf.nswap
385                 + conf.nswppo*sizeof(Page*);
386         mainmem->maxsize = kpages;
387         imagmem->maxsize = kpages;
388 //      mainmem->flags |= POOL_PARANOIA;
389 }
390
391 void
392 setupwatchpts(Proc *, Watchpt *, int n)
393 {
394         if(n > 0)
395                 error("no watchpoints");
396 }
397
398 int
399 isaconfig(char *, int, ISAConf*)
400 {
401         return 0;
402 }