FreeBSD/Linux Kernel Cross Reference
sys/bitsy/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 "io.h"
7 #include "ureg.h"
8 #include "init.h"
9 #include "pool.h"
10
11 Mach *m;
12 Proc *up;
13 Conf conf;
14 int noprint;
15
16 void
17 main(void)
18 {
19 mmuinvalidate();
20
21 /* zero out bss */
22 memset(edata, 0, end-edata);
23
24 /* point to Mach structure */
25 m = (Mach*)MACHADDR;
26 memset(m, 0, sizeof(Mach));
27 m->ticks = 1;
28
29 active.machs = 1;
30
31 rs232power(1);
32 quotefmtinstall();
33 iprint("\nPlan 9 bitsy kernel\n");
34 confinit();
35 xinit();
36 mmuinit();
37 machinit();
38 trapinit();
39 sa1110_uartsetup(1);
40 dmainit();
41 screeninit();
42 printinit(); /* from here on, print works, before this we need iprint */
43 clockinit();
44 procinit0();
45 initseg();
46 links();
47 chandevreset();
48 pageinit();
49 swapinit();
50 userinit();
51 powerinit();
52 schedinit();
53 }
54
55 /* need to do better */
56 void
57 reboot(void*, void*, ulong)
58 {
59 exit(0);
60 }
61
62
63 /*
64 * exit kernel either on a panic or user request
65 */
66 void
67 exit(int ispanic)
68 {
69 void (*f)(void);
70
71 USED(ispanic);
72 delay(1000);
73
74 iprint("it's a wonderful day to die\n");
75 cacheflush();
76 mmuinvalidate();
77 mmudisable();
78 f = nil;
79 (*f)();
80 }
81
82 static uchar *sp;
83
84 /*
85 * starting place for first process
86 */
87 void
88 init0(void)
89 {
90 up->nerrlab = 0;
91
92 spllo();
93
94 /*
95 * These are o.k. because rootinit is null.
96 * Then early kproc's will have a root and dot.
97 */
98 up->slash = namec("#/", Atodir, 0, 0);
99 pathclose(up->slash->path);
100 up->slash->path = newpath("/");
101 up->dot = cclone(up->slash);
102
103 chandevinit();
104
105 if(!waserror()){
106 ksetenv("terminal", "bitsy", 0);
107 ksetenv("cputype", "arm", 0);
108 if(cpuserver)
109 ksetenv("service", "cpu", 0);
110 else
111 ksetenv("service", "terminal", 0);
112 poperror();
113 }
114 kproc("alarm", alarmkproc, 0);
115 kproc("power", powerkproc, 0);
116
117 touser(sp);
118 }
119
120 /*
121 * pass boot arguments to /boot
122 */
123 static uchar *
124 pusharg(char *p)
125 {
126 int n;
127
128 n = strlen(p)+1;
129 sp -= n;
130 memmove(sp, p, n);
131 return sp;
132 }
133 static void
134 bootargs(ulong base)
135 {
136 int i, ac;
137 uchar *av[32];
138 uchar *bootpath;
139 uchar **lsp;
140
141 /*
142 * the sizeof(Sargs) is to make the validaddr check in
143 * trap.c's syscall() work even when we have less than the
144 * max number of args.
145 */
146 sp = (uchar*)base + BY2PG - sizeof(Sargs);
147
148 bootpath = pusharg("/boot/boot");
149 ac = 0;
150 av[ac++] = pusharg("boot");
151
152 /* 4 byte word align stack */
153 sp = (uchar*)((ulong)sp & ~3);
154
155 /* build argc, argv on stack */
156 sp -= (ac+1)*sizeof(sp);
157 lsp = (uchar**)sp;
158 for(i = 0; i < ac; i++)
159 *lsp++ = av[i] + ((USTKTOP - BY2PG) - base);
160 *lsp = 0;
161
162 /* push argv onto stack */
163 sp -= BY2WD;
164 lsp = (uchar**)sp;
165 *lsp = sp + BY2WD + ((USTKTOP - BY2PG) - base);
166
167 /* push pointer to "/boot" */
168 sp -= BY2WD;
169 lsp = (uchar**)sp;
170 *lsp = bootpath + ((USTKTOP - BY2PG) - base);
171
172 /* leave space for where the initcode's caller's return PC would normally reside */
173 sp -= BY2WD;
174
175 /* relocate stack to user's virtual addresses */
176 sp += (USTKTOP - BY2PG) - base;
177 }
178
179 /*
180 * create the first process
181 */
182 void
183 userinit(void)
184 {
185 Proc *p;
186 Segment *s;
187 KMap *k;
188 Page *pg;
189
190 /* no processes yet */
191 up = nil;
192
193 p = newproc();
194 p->pgrp = newpgrp();
195 p->egrp = smalloc(sizeof(Egrp));
196 p->egrp->ref = 1;
197 p->fgrp = dupfgrp(nil);
198 p->rgrp = newrgrp();
199 p->procmode = 0640;
200
201 kstrdup(&eve, "");
202 kstrdup(&p->text, "*init*");
203 kstrdup(&p->user, eve);
204
205 /*
206 * Kernel Stack
207 */
208 p->sched.pc = (ulong)init0;
209 p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
210
211 /*
212 * User Stack
213 */
214 s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
215 p->seg[SSEG] = s;
216 pg = newpage(1, 0, USTKTOP-BY2PG);
217 segpage(s, pg);
218 k = kmap(pg);
219 bootargs(VA(k));
220 kunmap(k);
221
222 /*
223 * Text
224 */
225 s = newseg(SG_TEXT, UTZERO, 1);
226 p->seg[TSEG] = s;
227 pg = newpage(1, 0, UTZERO);
228 memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
229 segpage(s, pg);
230 k = kmap(s->map[0]->pages[0]);
231 memmove((ulong*)VA(k), initcode, sizeof initcode);
232 kunmap(k);
233
234 ready(p);
235 }
236
237 /*
238 * set mach dependent process state for a new process
239 */
240 void
241 procsetup(Proc *p)
242 {
243 p->fpstate = FPinit;
244 }
245
246 /*
247 * Save the mach dependent part of the process state.
248 */
249 void
250 procsave(Proc *p)
251 {
252 USED(p);
253 }
254
255 /* place holder */
256 /*
257 * dummy since rdb is not included
258 */
259 void
260 rdb(void)
261 {
262 }
263
264 /*
265 * probe the last location in a meg of memory, make sure it's not
266 * reflected into something else we've already found.
267 */
268 int
269 probemem(ulong addr)
270 {
271 int i;
272 ulong *p;
273 ulong a;
274
275 addr += OneMeg - sizeof(ulong);
276 p = (ulong*)addr;
277 *p = addr;
278 for(i=0; i<nelem(conf.mem); i++){
279 for(a = conf.mem[i].base+OneMeg-sizeof(ulong); a < conf.mem[i].limit; a += OneMeg){
280 p = (ulong*)a;
281 *p = 0;
282 }
283 }
284 p = (ulong*)addr;
285 if(*p != addr)
286 return -1;
287 return 0;
288 }
289
290 /*
291 * we assume that the kernel is at the beginning of one of the
292 * contiguous chunks of memory.
293 */
294 void
295 confinit(void)
296 {
297 int i, j;
298 ulong addr;
299 ulong ktop;
300
301 /* find first two contiguous sections of available memory */
302 addr = PHYSDRAM0;
303 for(i=0; i<nelem(conf.mem); i++){
304 conf.mem[i].base = addr;
305 conf.mem[i].limit = addr;
306 }
307 for(j=0; j<nelem(conf.mem); j++){
308 conf.mem[j].base = addr;
309 conf.mem[j].limit = addr;
310
311 for(i = 0; i < 512; i++){
312 if(probemem(addr) == 0)
313 break;
314 addr += OneMeg;
315 }
316 for(; i < 512; i++){
317 if(probemem(addr) < 0)
318 break;
319 addr += OneMeg;
320 conf.mem[j].limit = addr;
321 }
322 }
323
324 conf.npage = 0;
325 for(i=0; i<nelem(conf.mem); i++){
326 /* take kernel out of allocatable space */
327 ktop = PGROUND((ulong)end);
328 if(ktop >= conf.mem[i].base && ktop <= conf.mem[i].limit)
329 conf.mem[i].base = ktop;
330
331 /* zero memory */
332 memset((void*)conf.mem[i].base, 0, conf.mem[i].limit - conf.mem[i].base);
333
334 conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
335 conf.npage += conf.mem[i].npage;
336 }
337
338 if(conf.npage > 16*MB/BY2PG){
339 conf.upages = (conf.npage*60)/100;
340 imagmem->minarena = 4*1024*1024;
341 }else
342 conf.upages = (conf.npage*40)/100;
343 conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
344
345 /* only one processor */
346 conf.nmach = 1;
347
348 /* set up other configuration parameters */
349 conf.nproc = 100;
350 conf.nswap = conf.npage*3;
351 conf.nswppo = 4096;
352 conf.nimage = 200;
353
354 conf.monitor = 1;
355
356 conf.copymode = 0; /* copy on write */
357 }
358
359 GPIOregs *gpioregs;
360 ulong *egpioreg = (ulong*)EGPIOREGS;
361 PPCregs *ppcregs;
362 MemConfRegs *memconfregs;
363 PowerRegs *powerregs;
364 ResetRegs *resetregs;
365
366 /*
367 * configure the machine
368 */
369 void
370 machinit(void)
371 {
372 /* set direction of SA1110 io pins and select alternate functions for some */
373 gpioregs = mapspecial(GPIOREGS, sizeof(GPIOregs));
374 gpioregs->direction =
375 GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
376 |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
377 |GPIO_CLK_SET0_o|GPIO_CLK_SET1_o
378 |GPIO_L3_SDA_io|GPIO_L3_MODE_o|GPIO_L3_SCLK_o
379 |GPIO_COM_RTS_o;
380 gpioregs->rising = 0;
381 gpioregs->falling = 0;
382 gpioregs->altfunc |=
383 GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
384 |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
385 |GPIO_SSP_CLK_i;
386
387 /* map in special H3650 io pins */
388 egpioreg = mapspecial(EGPIOREGS, sizeof(ulong));
389
390 /* map in peripheral pin controller (ssp will need it) */
391 ppcregs = mapspecial(PPCREGS, sizeof(PPCregs));
392
393 /* SA1110 power management */
394 powerregs = mapspecial(POWERREGS, sizeof(PowerRegs));
395
396 /* memory configuraton */
397 memconfregs = mapspecial(MEMCONFREGS, sizeof(MemConfRegs));
398
399 /* reset controller */
400 resetregs = mapspecial(RESETREGS, sizeof(ResetRegs));
401 }
402
403
404 /*
405 * manage egpio bits
406 */
407 static ulong egpiosticky;
408
409 void
410 egpiobits(ulong bits, int on)
411 {
412 if(on)
413 egpiosticky |= bits;
414 else
415 egpiosticky &= ~bits;
416 *egpioreg = egpiosticky;
417 }
418
419 void
420 rs232power(int on)
421 {
422 egpiobits(EGPIO_rs232_power, on);
423 delay(50);
424 }
425
426 void
427 audioamppower(int on)
428 {
429 egpiobits(EGPIO_audio_power, on);
430 delay(50);
431 }
432
433 void
434 audioicpower(int on)
435 {
436 egpiobits(EGPIO_audio_ic_power, on);
437 delay(50);
438 }
439
440 void
441 irpower(int on)
442 {
443 egpiobits(EGPIO_ir_power, on);
444 delay(50);
445 }
446
447 void
448 lcdpower(int on)
449 {
450 egpiobits(EGPIO_lcd_3v|EGPIO_lcd_ic_power|EGPIO_lcd_5v|EGPIO_lcd_9v, on);
451 delay(50);
452 }
453
454 void
455 flashprogpower(int on)
456 {
457 egpiobits(EGPIO_prog_flash, on);
458 }
459
460 /* here on hardware reset */
461 void
462 resettrap(void)
463 {
464 }
465
466 /*
467 * for drivers that used to run on x86's
468 */
469 void
470 outb(ulong a, uchar v)
471 {
472 *(uchar*)a = v;
473 }
474 void
475 outs(ulong a, ushort v)
476 {
477 *(ushort*)a = v;
478 }
479 void
480 outss(ulong a, void *p, int n)
481 {
482 ushort *sp = p;
483
484 while(n-- > 0)
485 *(ushort*)a = *sp++;
486 }
487 void
488 outl(ulong a, ulong v)
489 {
490 *(ulong*)a = v;
491 }
492 uchar
493 inb(ulong a)
494 {
495 return *(uchar*)a;
496 }
497 ushort
498 ins(ulong a)
499 {
500 return *(ushort*)a;
501 }
502 void
503 inss(ulong a, void *p, int n)
504 {
505 ushort *sp = p;
506
507 while(n-- > 0)
508 *sp++ = *(ushort*)a;
509 }
510 ulong
511 inl(ulong a)
512 {
513 return *(ulong*)a;
514 }
515
516 char*
517 getconf(char*)
518 {
519 return nil;
520 }
521
522 long
523 _xdec(long *p)
524 {
525 int s;
526 long v;
527
528 s = splhi();
529 v = --*p;
530 splx(s);
531 return v;
532 }
533
534 void
535 _xinc(long *p)
536 {
537 int s;
538
539 s = splhi();
540 ++*p;
541 splx(s);
542 }
543
544 int
545 cmpswap(long *addr, long old, long new)
546 {
547 int r, s;
548
549 s = splhi();
550 if(r = (*addr==old))
551 *addr = new;
552 splx(s);
553 return r;
554 }
555
Cache object: 07134abe94cd413c41f59c33c7c93867
|