]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/ppc/main.c
pc/vga*: use 64-bit physical addresses and check pci membar types and sizes
[plan9front.git] / sys / src / 9 / ppc / 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
10 #define MAXCONF         64
11
12 typedef struct Plan9ini Plan9ini;
13 struct Plan9ini
14 {
15         char    *name;
16         char    *val;
17 };
18
19 char *plan9inistr;
20 Plan9ini plan9ini[MAXCONF];
21 int nconf;
22
23 Conf conf;
24 FPsave initfp;
25 Lock testlock;
26
27 static void plan9iniinit(void);
28
29 char *
30 cpuid(void)
31 {
32         char *id;
33
34         id = "unknown PowerPC";
35         switch(m->cputype) {
36         case 8:
37                 id = "PowerPC 750";
38                 break;
39         case 9:
40                 id = "PowerPC 604e";
41                 break;
42         case 0x81:
43                 id = "PowerPC 8260";
44                 break;
45         case 0x8081:
46                 id = "PowerPC 826xA";
47                 break;
48         default:
49                 break;
50         }
51         return id;
52 }
53
54 void
55 cpuidprint(void)
56 {
57         print("cpu0: %s, rev 0x%lux, cpu hz %lld, bus hz %ld\n", 
58                 cpuid(), getpvr()&0xffff, m->cpuhz, m->bushz);
59 }
60
61 void
62 main(void)
63 {
64         memset(edata, 0, (ulong)end-(ulong)edata);
65         conf.nmach = 1;
66         machinit();
67         confinit();
68         xinit();
69         trapinit();
70         mmuinit();
71         plan9iniinit();
72         hwintrinit();
73         clockinit();
74         timerinit();
75         console();
76         quotefmtinstall();
77         printinit();
78         cpuidprint();
79         print("\nPlan 9 from Bell Labs\n");
80         procinit0();
81         initseg();
82         timersinit();
83         links();
84         chandevreset();
85         pageinit();
86         sharedseginit();
87         fpsave(&initfp);
88         initfp.fpscr = 0;
89         userinit();
90         schedinit();
91 }
92
93 char*
94 getconf(char *name)
95 {
96         int i;
97
98         for(i = 0; i < nconf; i++)
99                 if(cistrcmp(name, plan9ini[i].name) == 0)
100                         return plan9ini[i].val;
101         return nil;
102 }
103
104 static void
105 plan9iniinit(void)
106 {
107         long i;
108         int c;
109         char *cp, line[MAXCONF], *p, *q;
110
111         /*
112          *  parse configuration args from dos file plan9.ini
113          */
114
115         cp = plan9inistr;
116         for(i = 0; i < MAXCONF; i++){
117                 /*
118                  * Strip out '\r', change '\t' -> ' ', test for 0xff which is end of file
119                  */
120                 p = line;
121                 for(q = cp; c = (uchar)*q; q++){
122                         if(c == '\r')
123                                 continue;
124                         if(c == '\t')
125                                 c = ' ';
126                         if(c == 0xff || c == '\n')
127                                 break;
128                         *p++ = c;
129                 }
130                 *p = 0;
131                 if (*line == 0)
132                         break;
133                 if(*line != '#' && (cp = strchr(line, '='))){
134                         *cp++ = '\0';
135                         kstrdup(&plan9ini[nconf].name, line);
136                         kstrdup(&plan9ini[nconf].val, cp);
137                         nconf++;
138                 }
139                 if (c == 0xff)
140                         break;
141
142                 cp = q + 1;
143         }
144 }
145
146 void
147 init0(void)
148 {
149         char buf[2*KNAMELEN];
150         int i;
151
152         chandevinit();
153
154         if(!waserror()){
155                 snprint(buf, sizeof(buf), "power %s mtx", conffile);
156                 ksetenv("terminal", buf, 0);
157                 ksetenv("cputype", "power", 0);
158                 if(cpuserver)
159                         ksetenv("service", "cpu", 0);
160                 else
161                         ksetenv("service", "terminal", 0);
162
163                 for(i = 0; i < nconf; i++){
164                         if(plan9ini[i].name[0] != '*')
165                                 ksetenv(plan9ini[i].name, plan9ini[i].val, 0);
166                         ksetenv(plan9ini[i].name, plan9ini[i].val, 1);
167                 }
168                 poperror();
169         }
170         kproc("alarm", alarmkproc, 0);
171         kproc("mmusweep", mmusweep, 0);
172         touser((void*)(USTKTOP - sizeof(Tos)));
173 }
174
175 void
176 exit(int)
177 {
178         cpushutdown();
179         for(;;) idlehands();
180 }
181
182 /*
183  *  set up floating point for a new process
184  */
185 void
186 procsetup(Proc *p)
187 {
188         p->fpstate = FPinit;
189
190         cycles(&p->kentry);
191         p->pcycles = -p->kentry;
192 }
193
194 void
195 procfork(Proc *p)
196 {
197         p->kentry = up->kentry;
198         p->pcycles = -p->kentry;
199 }
200
201 void
202 procrestore(Proc *p)
203 {
204         uvlong t;
205
206         if(p->kp)
207                 return;
208         cycles(&t);
209         p->pcycles -= t;
210         p->kentry += t;
211 }
212
213 /*
214  *  Save the mach dependent part of the process state.
215  */
216 void
217 procsave(Proc *p)
218 {
219         uvlong t;
220
221         cycles(&t);
222         p->pcycles += t;
223         p->kentry -= t;
224         if(p->fpstate == FPactive){
225                 if(p->state != Moribund)
226                         fpsave(up->fpsave);
227                 p->fpstate = FPinactive;
228         }
229 }
230
231 void
232 confinit(void)
233 {
234         char *p;
235         int userpcnt;
236         ulong pa, kpages;
237         /* passed in from ROM monitor: */
238
239         if(p = getconf("service")){
240                 if(strcmp(p, "cpu") == 0)
241                         cpuserver = 1;
242                 else if(strcmp(p,"terminal") == 0)
243                         cpuserver = 0;
244         }
245
246         if(p = getconf("*kernelpercent"))
247                 userpcnt = 100 - strtol(p, 0, 0);
248         else
249                 userpcnt = 0;
250
251         pa = PGROUND(PADDR(end));
252
253         /* Blast Board specific */
254         conf.mem[0].npage = (MEM1SIZE - pa)/BY2PG;
255         conf.mem[0].base = pa;
256         
257         conf.mem[1].npage = MEM2SIZE/BY2PG;
258         conf.mem[1].base = MEM2BASE;
259
260         conf.npage = conf.mem[0].npage + conf.mem[1].npage;
261
262         conf.nmach = 1;
263         conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
264         if(cpuserver)
265                 conf.nproc *= 3;
266         if(conf.nproc > 2000)
267                 conf.nproc = 2000;
268         conf.nimage = 200;
269         conf.nswap = conf.nproc*80;
270         conf.nswppo = 4096;
271         conf.copymode = 0;                      /* copy on write */
272
273         if(cpuserver) {
274                 if(userpcnt < 10)
275                         userpcnt = 70;
276                 kpages = conf.npage - (conf.npage*userpcnt)/100;
277
278                 /*
279                  * Hack for the big boys. Only good while physmem < 4GB.
280                  * Give the kernel a max. of 16MB + enough to allocate the
281                  * page pool.
282                  * This is an overestimate as conf.upages < conf.npages.
283                  * The patch of nimage is a band-aid, scanning the whole
284                  * page list in imagereclaim just takes too long.
285                  */
286                 if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
287                         kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
288                         conf.nimage = 2000;
289                         kpages += (conf.nproc*KSTACK)/BY2PG;
290                 }
291         } else {
292                 if(userpcnt < 10) {
293                         if(conf.npage*BY2PG < 16*MB)
294                                 userpcnt = 40;
295                         else
296                                 userpcnt = 60;
297                 }
298                 kpages = conf.npage - (conf.npage*userpcnt)/100;
299
300                 /*
301                  * Make sure terminals with low memory get at least
302                  * 4MB on the first Image chunk allocation.
303                  */
304                 if(conf.npage*BY2PG < 16*MB)
305                         imagmem->minarena = 4*1024*1024;
306         }
307         conf.upages = conf.npage - kpages;
308         conf.ialloc = (kpages/2)*BY2PG;
309
310         /*
311          * Guess how much is taken by the large permanent
312          * datastructures. Mntcache and Mntrpc are not accounted for.
313          */
314         kpages *= BY2PG;
315         kpages -= conf.upages*sizeof(Page)
316                 + conf.nproc*sizeof(Proc)
317                 + conf.nimage*sizeof(Image)
318                 + conf.nswap
319                 + conf.nswppo*sizeof(Page*);
320         mainmem->maxsize = kpages;
321         if(!cpuserver){
322                 /*
323                  * give terminals lots of image memory, too; the dynamic
324                  * allocation will balance the load properly, hopefully.
325                  * be careful with 32-bit overflow.
326                  */
327                 imagmem->maxsize = kpages;
328         }
329 }
330
331 static int
332 getcfields(char* lp, char** fields, int n, char* sep)
333 {
334         int i;
335
336         for(i = 0; lp && *lp && i < n; i++){
337                 while(*lp && strchr(sep, *lp) != 0)
338                         *lp++ = 0;
339                 if(*lp == 0)
340                         break;
341                 fields[i] = lp;
342                 while(*lp && strchr(sep, *lp) == 0){
343                         if(*lp == '\\' && *(lp+1) == '\n')
344                                 *lp++ = ' ';
345                         lp++;
346                 }
347         }
348
349         return i;
350 }
351
352 int
353 isaconfig(char *class, int ctlrno, ISAConf *isa)
354 {
355         int i;
356         char cc[KNAMELEN], *p;
357
358         sprint(cc, "%s%d", class, ctlrno);
359
360         p = getconf(cc);
361         if(p == 0)
362                 return 0;
363         isa->nopt = tokenize(p, isa->opt, NISAOPT);
364         for(i = 0; i < isa->nopt; i++){
365                 p = isa->opt[i];
366                 if(cistrncmp(p, "type=", 5) == 0)
367                         isa->type = p + 5;
368                 else if(cistrncmp(p, "port=", 5) == 0)
369                         isa->port = strtoul(p+5, &p, 0);
370                 else if(cistrncmp(p, "irq=", 4) == 0)
371                         isa->irq = strtoul(p+4, &p, 0);
372                 else if(cistrncmp(p, "dma=", 4) == 0)
373                         isa->dma = strtoul(p+4, &p, 0);
374                 else if(cistrncmp(p, "mem=", 4) == 0)
375                         isa->mem = strtoul(p+4, &p, 0);
376                 else if(cistrncmp(p, "size=", 5) == 0)
377                         isa->size = strtoul(p+5, &p, 0);
378                 else if(cistrncmp(p, "freq=", 5) == 0)
379                         isa->freq = strtoul(p+5, &p, 0);
380         }
381         return 1;
382 }
383
384 void
385 setupwatchpts(Proc *, Watchpt *, int n)
386 {
387         if(n > 0)
388                 error("no watchpoints");
389 }