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