]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/zynq/main.c
ip: add some primitive rate limiting knobs to counteract bufferbloat
[plan9front.git] / sys / src / 9 / zynq / 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 "init.h"
7 #include "pool.h"
8 #include "io.h"
9 #include "../port/error.h"
10 #include "tos.h"
11
12 Conf conf;
13 int normalprint, delaylink;
14
15 enum { MAXCONF = 64 };
16
17 char *confname[MAXCONF], *confval[MAXCONF];
18 int nconf;
19
20 void
21 exit(int)
22 {
23         cpushutdown();
24         for(;;) idlehands();
25 }
26
27 void
28 reboot(void *, void *, ulong)
29 {
30 }
31
32 void
33 evenaddr(uintptr va)
34 {
35         if((va & 3) != 0){
36                 dumpstack();
37                 postnote(up, 1, "sys: odd address", NDebug);
38                 error(Ebadarg);
39         }
40 }
41
42 void
43 procfork(Proc *p)
44 {
45         ulong s;
46
47         p->kentry = up->kentry;
48         p->pcycles = -p->kentry;
49         
50         s = splhi();
51         switch(up->fpstate & ~FPillegal){
52         case FPactive:
53                 fpsave(up->fpsave);
54                 up->fpstate = FPinactive;
55         case FPinactive:
56                 memmove(p->fpsave, up->fpsave, sizeof(FPsave));
57                 p->fpstate = FPinactive;
58         }
59         splx(s);
60 }
61
62 void
63 procsetup(Proc *p)
64 {
65         p->fpstate = FPinit;
66         fpoff();
67         
68         cycles(&p->kentry);
69         p->pcycles = -p->kentry;
70 }
71
72 void
73 kexit(Ureg *)
74 {
75         Tos *tos;
76         uvlong t;
77
78         tos = (Tos*)(USTKTOP-sizeof(Tos));
79         cycles(&t);
80         tos->kcycles += t - up->kentry;
81         tos->pcycles = t + up->pcycles;
82         tos->pid = up->pid;
83 }
84
85 ulong *l2;
86
87 void
88 l2init(void)
89 {
90         enum {
91                 CTRL = 0x100/4,
92                 AUX,
93                 TAGRAM,
94                 DATARAM,
95                 INVPA = 0x770/4,
96                 INVWAY = 0x77C/4,
97                 PREFETCH = 0xF60/4,
98         };
99
100         mpcore[0] |= 1;
101         slcr[0xa1c/4] = 0x020202;
102         l2 = vmap(L2_BASE, BY2PG);
103         l2[CTRL] &= ~1;
104         l2[TAGRAM] = l2[TAGRAM] & ~0x777 | 0x111;
105         l2[DATARAM] = l2[DATARAM] & ~0x777 | 0x121;
106         l2[PREFETCH] |= 3<<28 | 1<<24;
107         l2[AUX] |= 3<<28 | 1<<20;
108         l2[INVWAY] = 0xff;
109         while((l2[INVPA] & 1) != 0)
110                 ;
111         l2[CTRL] = 1;
112 }
113
114 void
115 clean2pa(uintptr start, uintptr end)
116 {
117         uintptr pa;
118         
119         start &= ~31;
120         end = (end + 31) & ~31;
121         for(pa = start; pa < end; pa += 32)
122                 l2[0x7b0/4] = pa;
123 }
124
125 void
126 inval2pa(uintptr start, uintptr end)
127 {
128         uintptr pa;
129         
130         start &= ~31;
131         end = (end + 31) & ~31;
132         for(pa = start; pa < end; pa += 32)
133                 l2[0x770/4] = pa;
134 }
135
136 static void
137 options(void)
138 {
139         long i, n;
140         char *cp, *line[MAXCONF], *p, *q;
141
142         cp = (char *) CONFADDR;
143
144         p = cp;
145         for(q = cp; *q; q++){
146                 if(*q == '\r')
147                         continue;
148                 if(*q == '\t')
149                         *q = ' ';
150                 *p++ = *q;
151         }
152         *p = 0;
153
154         n = getfields(cp, line, MAXCONF, 1, "\n");
155         for(i = 0; i < n; i++){
156                 if(*line[i] == '#')
157                         continue;
158                 cp = strchr(line[i], '=');
159                 if(cp == nil)
160                         continue;
161                 *cp++ = '\0';
162                 confname[nconf] = line[i];
163                 confval[nconf] = cp;
164                 nconf++;
165         }
166
167 }
168
169 void
170 confinit(void)
171 {
172         ulong kmem;
173         int i;
174
175         conf.nmach = 1;
176         conf.nproc = 2000;
177         conf.ialloc = 16*1024*1024;
178         conf.nimage = 200;
179         conf.mem[0].base = PGROUND((ulong)end - KZERO);
180         conf.mem[0].limit = 1024*1024*1024;
181         conf.npage = 0;
182         for(i = 0; i < nelem(conf.mem); i++)
183                 conf.npage += conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base) >> PGSHIFT;
184         kmem = 200*1024*1024;
185         conf.upages = conf.npage - kmem/BY2PG;
186         kmem -= conf.upages*sizeof(Page)
187                 + conf.nproc*sizeof(Proc)
188                 + conf.nimage*sizeof(Image);
189         mainmem->maxsize = kmem;
190         imagmem->maxsize = kmem - (kmem/10);
191 }
192
193 static void
194 init0(void)
195 {
196         char buf[ERRMAX], **sp;
197         int i;
198
199         up->nerrlab = 0;
200         spllo();
201         
202         up->slash = namec("#/", Atodir, 0, 0);
203         pathclose(up->slash->path);
204         up->slash->path = newpath("/");
205         up->dot = cclone(up->slash);
206         
207         chandevinit();
208         uartconsole();
209         
210         if(!waserror()){
211                 ksetenv("cputype", "arm", 0);
212                 if(cpuserver)
213                         ksetenv("service", "cpu", 0);
214                 else
215                         ksetenv("service", "terminal", 0);
216                 ksetenv("console", "0", 0);
217                 snprint(buf, sizeof(buf), "zynq %s", conffile);
218                 ksetenv("terminal", buf, 0);
219                 for(i = 0; i < nconf; i++){
220                         if(*confname[i] != '*')
221                                 ksetenv(confname[i], confval[i], 0);
222                         ksetenv(confname[i], confval[i], 1);
223                 }
224                 poperror();
225         }
226         kproc("alarm", alarmkproc, 0);
227
228         sp = (char**)(USTKTOP - sizeof(Tos) - 8 - sizeof(sp[0])*4);
229         sp[3] = sp[2] = nil;
230         strcpy(sp[1] = (char*)&sp[4], "boot");
231         sp[0] = nil;
232         touser(sp);
233 }
234
235 void
236 userinit(void)
237 {
238         Proc *p;
239         Segment *s;
240         void *v;
241         Page *pg;
242         
243         p = newproc();
244         p->pgrp = newpgrp();
245         p->egrp = smalloc(sizeof(Egrp));
246         p->egrp->ref = 1;
247         p->fgrp = dupfgrp(nil);
248         p->rgrp = newrgrp();
249         p->procmode = 0640;
250         
251         kstrdup(&eve, "");
252         kstrdup(&p->text, "*init*");
253         kstrdup(&p->user, eve);
254         
255         procsetup(p);
256         
257         p->sched.pc = (ulong)init0;
258         p->sched.sp = (ulong)p->kstack + KSTACK - (sizeof(Sargs) + BY2WD);
259         
260         s = newseg(SG_STACK, USTKTOP - USTKSIZE, USTKSIZE / BY2PG);
261         p->seg[SSEG] = s;
262         pg = newpage(0, 0, USTKTOP - BY2PG);
263         segpage(s, pg);
264         v = tmpmap(pg->pa);
265         memset(v, 0, BY2PG);
266         tmpunmap(v);
267         
268         s = newseg(SG_TEXT, UTZERO, 1);
269         s->flushme++;
270         p->seg[TSEG] = s;
271         pg = newpage(0, 0, UTZERO);
272         pg->txtflush = ~0;
273
274         segpage(s, pg);
275         v = tmpmap(pg->pa);
276         memset(v, 0, BY2PG);
277         memmove(v, initcode, sizeof(initcode));
278         tmpunmap(v);
279         
280         ready(p);
281 }
282
283 void
284 sanity(void)
285 {
286         static int dat = 0xdeadbeef;
287         extern ulong vectors[];
288
289         assert(dat == 0xdeadbeef);
290         assert(((uintptr)vectors & 31) == 0);
291         assert(sizeof(Mach) + KSTACK <= MACHSIZE);
292         assert((KZERO & SECSZ - 1) == 0);
293 }
294
295 char *
296 getconf(char *n)
297 {
298         int i;
299         
300         for(i = 0; i < nconf; i++)
301                 if(cistrcmp(confname[i], n) == 0)
302                         return confval[i];
303         return nil;
304 }
305
306 int
307 isaconfig(char *, int, ISAConf*)
308 {
309         return 0;
310 }
311
312 void
313 cpuidprint(void)
314 {
315         print("cpu%d: %dMHz ARM Cortex-A9\n", m->machno, m->cpumhz);
316 }
317
318 void
319 mpinit(void)
320 {
321         extern void mpbootstrap(void);  /* l.s */
322         Mach *m1;
323         ulong *v;
324         int i;
325
326         if(getconf("*nomp"))
327                 return;
328
329         conf.nmach = 2;
330         conf.copymode = 1;
331
332         m1 = MACHP(1);
333         memset(m1, 0, MACHSIZE);
334         m1->machno = 1;
335         m1->l1.pa = MACHL1(m1->machno)-KZERO;
336         m1->l1.va = KADDR(m1->l1.pa);
337
338         memset(m1->l1.va, 0, L1SZ);
339         for(i=0; i<L1X(VMAPSZ); i++)
340                 m1->l1.va[L1X(VMAP)+i] = m->l1.va[L1X(VMAP)+i];
341         for(i=0; i<L1X(-KZERO); i++)
342                 m1->l1.va[L1X(KZERO)+i] = m->l1.va[L1X(KZERO)+i];
343         coherence();
344         cleandse((uchar*)KZERO, (uchar*)0xFFFFFFFF);
345         invaldse((uchar*)KZERO, (uchar*)0xFFFFFFFF);
346
347         /* ocm is uncached */
348         v = KADDR(0xFFFFF000);
349         v[0xFF0/4] = PADDR(mpbootstrap);
350         coherence();
351
352         sendevent();
353         synccycles();
354 }
355
356 void
357 main(void)
358 {
359         active.machs[m->machno] = 1;
360         if(m->machno != 0){
361                 uartputs("\n", 1);
362                 mmuinit();
363                 intrinit();
364                 timerinit();
365                 cpuidprint();
366                 synccycles();
367                 timersinit();
368                 schedinit();
369                 return;
370         }
371         uartinit();
372         mmuinit();
373         l2init();
374         intrinit();
375         options();
376         confinit();
377         timerinit();
378         uartputs(" from Bell Labs\n", 16);
379         xinit();
380         printinit();
381         quotefmtinstall();
382         cpuidprint();
383         sanity();
384         mpinit();
385         todinit();
386         timersinit();
387         procinit0();
388         initseg(); 
389         if(delaylink)
390                 bootlinks();
391         else
392                 links();
393         archinit();
394         chandevreset();
395         pageinit();
396         screeninit();
397         userinit();
398         schedinit();
399 }
400
401 void
402 setupwatchpts(Proc *, Watchpt *, int n)
403 {
404         if(n > 0)
405                 error("no watchpoints");
406 }