2 #include "../port/lib.h"
22 memset(edata, 0, end-edata);
24 /* point to Mach structure */
26 memset(m, 0, sizeof(Mach));
33 iprint("\nPlan 9 bitsy kernel\n");
42 printinit(); /* from here on, print works, before this we need iprint */
55 /* need to do better */
57 reboot(void*, void*, ulong)
64 * exit kernel either on a panic or user request
74 iprint("it's a wonderful day to die\n");
85 * starting place for first process
95 * These are o.k. because rootinit is null.
96 * Then early kproc's will have a root and dot.
98 up->slash = namec("#/", Atodir, 0, 0);
99 pathclose(up->slash->path);
100 up->slash->path = newpath("/");
101 up->dot = cclone(up->slash);
106 ksetenv("terminal", "bitsy", 0);
107 ksetenv("cputype", "arm", 0);
109 ksetenv("service", "cpu", 0);
111 ksetenv("service", "terminal", 0);
114 kproc("alarm", alarmkproc, 0);
115 kproc("power", powerkproc, 0);
121 * pass boot arguments to /boot
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.
146 sp = (uchar*)base + BY2PG - sizeof(Sargs);
148 bootpath = pusharg("/boot/boot");
150 av[ac++] = pusharg("boot");
152 /* 4 byte word align stack */
153 sp = (uchar*)((ulong)sp & ~3);
155 /* build argc, argv on stack */
156 sp -= (ac+1)*sizeof(sp);
158 for(i = 0; i < ac; i++)
159 *lsp++ = av[i] + ((USTKTOP - BY2PG) - base);
162 /* push argv onto stack */
165 *lsp = sp + BY2WD + ((USTKTOP - BY2PG) - base);
167 /* push pointer to "/boot" */
170 *lsp = bootpath + ((USTKTOP - BY2PG) - base);
172 /* leave space for where the initcode's caller's return PC would normally reside */
175 /* relocate stack to user's virtual addresses */
176 sp += (USTKTOP - BY2PG) - base;
180 * create the first process
190 /* no processes yet */
195 p->egrp = smalloc(sizeof(Egrp));
197 p->fgrp = dupfgrp(nil);
202 kstrdup(&p->text, "*init*");
203 kstrdup(&p->user, eve);
208 p->sched.pc = (ulong)init0;
209 p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
214 s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
216 pg = newpage(1, 0, USTKTOP-BY2PG);
225 s = newseg(SG_TEXT, UTZERO, 1);
227 pg = newpage(1, 0, UTZERO);
228 memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
230 k = kmap(s->map[0]->pages[0]);
231 memmove((ulong*)VA(k), initcode, sizeof initcode);
238 * set mach dependent process state for a new process
252 * Save the mach dependent part of the process state.
262 * dummy since rdb is not included
270 * probe the last location in a meg of memory, make sure it's not
271 * reflected into something else we've already found.
280 addr += OneMeg - sizeof(ulong);
283 for(i=0; i<nelem(conf.mem); i++){
284 for(a = conf.mem[i].base+OneMeg-sizeof(ulong); a < conf.mem[i].limit; a += OneMeg){
296 * we assume that the kernel is at the beginning of one of the
297 * contiguous chunks of memory.
306 /* find first two contiguous sections of available memory */
308 for(i=0; i<nelem(conf.mem); i++){
309 conf.mem[i].base = addr;
310 conf.mem[i].limit = addr;
312 for(j=0; j<nelem(conf.mem); j++){
313 conf.mem[j].base = addr;
314 conf.mem[j].limit = addr;
316 for(i = 0; i < 512; i++){
317 if(probemem(addr) == 0)
322 if(probemem(addr) < 0)
325 conf.mem[j].limit = addr;
330 for(i=0; i<nelem(conf.mem); i++){
331 /* take kernel out of allocatable space */
332 ktop = PGROUND((ulong)end);
333 if(ktop >= conf.mem[i].base && ktop <= conf.mem[i].limit)
334 conf.mem[i].base = ktop;
337 memset((void*)conf.mem[i].base, 0, conf.mem[i].limit - conf.mem[i].base);
339 conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
340 conf.npage += conf.mem[i].npage;
343 if(conf.npage > 16*MB/BY2PG){
344 conf.upages = (conf.npage*60)/100;
345 imagmem->minarena = 4*1024*1024;
347 conf.upages = (conf.npage*40)/100;
348 conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
350 /* only one processor */
353 /* set up other configuration parameters */
355 conf.nswap = conf.npage*3;
361 conf.copymode = 0; /* copy on write */
365 ulong *egpioreg = (ulong*)EGPIOREGS;
367 MemConfRegs *memconfregs;
368 PowerRegs *powerregs;
369 ResetRegs *resetregs;
372 * configure the machine
377 /* set direction of SA1110 io pins and select alternate functions for some */
378 gpioregs = mapspecial(GPIOREGS, sizeof(GPIOregs));
379 gpioregs->direction =
380 GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
381 |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
382 |GPIO_CLK_SET0_o|GPIO_CLK_SET1_o
383 |GPIO_L3_SDA_io|GPIO_L3_MODE_o|GPIO_L3_SCLK_o
385 gpioregs->rising = 0;
386 gpioregs->falling = 0;
388 GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
389 |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
392 /* map in special H3650 io pins */
393 egpioreg = mapspecial(EGPIOREGS, sizeof(ulong));
395 /* map in peripheral pin controller (ssp will need it) */
396 ppcregs = mapspecial(PPCREGS, sizeof(PPCregs));
398 /* SA1110 power management */
399 powerregs = mapspecial(POWERREGS, sizeof(PowerRegs));
401 /* memory configuraton */
402 memconfregs = mapspecial(MEMCONFREGS, sizeof(MemConfRegs));
404 /* reset controller */
405 resetregs = mapspecial(RESETREGS, sizeof(ResetRegs));
412 static ulong egpiosticky;
415 egpiobits(ulong bits, int on)
420 egpiosticky &= ~bits;
421 *egpioreg = egpiosticky;
427 egpiobits(EGPIO_rs232_power, on);
432 audioamppower(int on)
434 egpiobits(EGPIO_audio_power, on);
441 egpiobits(EGPIO_audio_ic_power, on);
448 egpiobits(EGPIO_ir_power, on);
455 egpiobits(EGPIO_lcd_3v|EGPIO_lcd_ic_power|EGPIO_lcd_5v|EGPIO_lcd_9v, on);
460 flashprogpower(int on)
462 egpiobits(EGPIO_prog_flash, on);
465 /* here on hardware reset */
472 * for drivers that used to run on x86's
475 outb(ulong a, uchar v)
480 outs(ulong a, ushort v)
485 outss(ulong a, void *p, int n)
493 outl(ulong a, ulong v)
508 inss(ulong a, void *p, int n)
550 cmpswap(long *addr, long old, long new)