]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/zynq/main.c
devarch: restrict i/o port access to 64K, disallow msr 32-bit wrap arround (thanks...
[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].npage = (1024*1024*1024 - conf.mem[0].base) >> PGSHIFT;
181
182         ramdiskinit();
183
184         conf.npage = 0;
185         for(i = 0; i < nelem(conf.mem); i++)
186                 conf.npage += conf.mem[i].npage;
187
188         kmem = 200*1024*1024;
189         conf.upages = conf.npage - kmem/BY2PG;
190         kmem -= conf.upages*sizeof(Page)
191                 + conf.nproc*sizeof(Proc)
192                 + conf.nimage*sizeof(Image);
193         mainmem->maxsize = kmem;
194         imagmem->maxsize = kmem - (kmem/10);
195 }
196
197 static void
198 init0(void)
199 {
200         char buf[ERRMAX], **sp;
201         int i;
202
203         up->nerrlab = 0;
204         spllo();
205         
206         up->slash = namec("#/", Atodir, 0, 0);
207         pathclose(up->slash->path);
208         up->slash->path = newpath("/");
209         up->dot = cclone(up->slash);
210         
211         chandevinit();
212         uartconsole();
213         
214         if(!waserror()){
215                 ksetenv("cputype", "arm", 0);
216                 if(cpuserver)
217                         ksetenv("service", "cpu", 0);
218                 else
219                         ksetenv("service", "terminal", 0);
220                 ksetenv("console", "0", 0);
221                 snprint(buf, sizeof(buf), "zynq %s", conffile);
222                 ksetenv("terminal", buf, 0);
223                 for(i = 0; i < nconf; i++){
224                         if(*confname[i] != '*')
225                                 ksetenv(confname[i], confval[i], 0);
226                         ksetenv(confname[i], confval[i], 1);
227                 }
228                 poperror();
229         }
230         kproc("alarm", alarmkproc, 0);
231
232         sp = (char**)(USTKTOP - sizeof(Tos) - 8 - sizeof(sp[0])*4);
233         sp[3] = sp[2] = nil;
234         strcpy(sp[1] = (char*)&sp[4], "boot");
235         sp[0] = nil;
236         touser(sp);
237 }
238
239 void
240 userinit(void)
241 {
242         Proc *p;
243         Segment *s;
244         void *v;
245         Page *pg;
246         
247         p = newproc();
248         p->pgrp = newpgrp();
249         p->egrp = smalloc(sizeof(Egrp));
250         p->egrp->ref = 1;
251         p->fgrp = dupfgrp(nil);
252         p->rgrp = newrgrp();
253         p->procmode = 0640;
254         
255         kstrdup(&eve, "");
256         kstrdup(&p->text, "*init*");
257         kstrdup(&p->user, eve);
258         
259         procsetup(p);
260         
261         p->sched.pc = (ulong)init0;
262         p->sched.sp = (ulong)p->kstack + KSTACK - (sizeof(Sargs) + BY2WD);
263         
264         s = newseg(SG_STACK, USTKTOP - USTKSIZE, USTKSIZE / BY2PG);
265         p->seg[SSEG] = s;
266         pg = newpage(0, 0, USTKTOP - BY2PG);
267         segpage(s, pg);
268         v = tmpmap(pg->pa);
269         memset(v, 0, BY2PG);
270         tmpunmap(v);
271         
272         s = newseg(SG_TEXT, UTZERO, 1);
273         s->flushme++;
274         p->seg[TSEG] = s;
275         pg = newpage(0, 0, UTZERO);
276         pg->txtflush = ~0;
277
278         segpage(s, pg);
279         v = tmpmap(pg->pa);
280         memset(v, 0, BY2PG);
281         memmove(v, initcode, sizeof(initcode));
282         tmpunmap(v);
283         
284         ready(p);
285 }
286
287 void
288 sanity(void)
289 {
290         static int dat = 0xdeadbeef;
291         extern ulong vectors[];
292
293         assert(dat == 0xdeadbeef);
294         assert(((uintptr)vectors & 31) == 0);
295         assert(sizeof(Mach) + KSTACK <= MACHSIZE);
296         assert((KZERO & SECSZ - 1) == 0);
297 }
298
299 char *
300 getconf(char *n)
301 {
302         int i;
303         
304         for(i = 0; i < nconf; i++)
305                 if(cistrcmp(confname[i], n) == 0)
306                         return confval[i];
307         return nil;
308 }
309
310 int
311 isaconfig(char *, int, ISAConf*)
312 {
313         return 0;
314 }
315
316 void
317 cpuidprint(void)
318 {
319         print("cpu%d: %dMHz ARM Cortex-A9\n", m->machno, m->cpumhz);
320 }
321
322 void
323 mpinit(void)
324 {
325         extern void mpbootstrap(void);  /* l.s */
326         Mach *m1;
327         ulong *v;
328         int i;
329
330         if(getconf("*nomp"))
331                 return;
332
333         conf.nmach = 2;
334         conf.copymode = 1;
335
336         m1 = MACHP(1);
337         memset(m1, 0, MACHSIZE);
338         m1->machno = 1;
339         m1->l1.pa = MACHL1(m1->machno)-KZERO;
340         m1->l1.va = KADDR(m1->l1.pa);
341
342         memset(m1->l1.va, 0, L1SZ);
343         for(i=0; i<L1X(VMAPSZ); i++)
344                 m1->l1.va[L1X(VMAP)+i] = m->l1.va[L1X(VMAP)+i];
345         for(i=0; i<L1X(-KZERO); i++)
346                 m1->l1.va[L1X(KZERO)+i] = m->l1.va[L1X(KZERO)+i];
347         coherence();
348         cleandse((uchar*)KZERO, (uchar*)0xFFFFFFFF);
349         invaldse((uchar*)KZERO, (uchar*)0xFFFFFFFF);
350
351         /* ocm is uncached */
352         v = KADDR(0xFFFFF000);
353         v[0xFF0/4] = PADDR(mpbootstrap);
354         coherence();
355
356         sendevent();
357         synccycles();
358 }
359
360 void
361 main(void)
362 {
363         active.machs[m->machno] = 1;
364         if(m->machno != 0){
365                 uartputs("\n", 1);
366                 mmuinit();
367                 intrinit();
368                 timerinit();
369                 cpuidprint();
370                 synccycles();
371                 timersinit();
372                 schedinit();
373                 return;
374         }
375         uartinit();
376         mmuinit();
377         l2init();
378         intrinit();
379         options();
380         confinit();
381         timerinit();
382         uartputs(" from Bell Labs\n", 16);
383         xinit();
384         printinit();
385         quotefmtinstall();
386         cpuidprint();
387         sanity();
388         mpinit();
389         todinit();
390         timersinit();
391         procinit0();
392         initseg(); 
393         if(delaylink)
394                 bootlinks();
395         else
396                 links();
397         archinit();
398         chandevreset();
399         pageinit();
400         screeninit();
401         userinit();
402         schedinit();
403 }
404
405 void
406 setupwatchpts(Proc *, Watchpt *, int n)
407 {
408         if(n > 0)
409                 error("no watchpoints");
410 }