123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "io.h"
- #include "ureg.h"
- #include "init.h"
- #include "pool.h"
- Mach *m;
- Proc *up;
- Conf conf;
- int noprint;
- void
- main(void)
- {
- mmuinvalidate();
- /* zero out bss */
- memset(edata, 0, end-edata);
- /* point to Mach structure */
- m = (Mach*)MACHADDR;
- memset(m, 0, sizeof(Mach));
- m->ticks = 1;
- active.machs = 1;
- rs232power(1);
- quotefmtinstall();
- iprint("\nPlan 9 bitsy kernel\n");
- confinit();
- xinit();
- mmuinit();
- machinit();
- trapinit();
- sa1110_uartsetup(1);
- dmainit();
- screeninit();
- printinit(); /* from here on, print works, before this we need iprint */
- clockinit();
- procinit0();
- initseg();
- links();
- chandevreset();
- pageinit();
- swapinit();
- userinit();
- powerinit();
- schedinit();
- }
- /* need to do better */
- void
- reboot(void*, void*, ulong)
- {
- exit(0);
- }
- /*
- * exit kernel either on a panic or user request
- */
- void
- exit(int ispanic)
- {
- void (*f)(void);
- USED(ispanic);
- delay(1000);
- iprint("it's a wonderful day to die\n");
- cacheflush();
- mmuinvalidate();
- mmudisable();
- f = nil;
- (*f)();
- }
- static uchar *sp;
- /*
- * starting place for first process
- */
- void
- init0(void)
- {
- up->nerrlab = 0;
- spllo();
- /*
- * These are o.k. because rootinit is null.
- * Then early kproc's will have a root and dot.
- */
- up->slash = namec("#/", Atodir, 0, 0);
- pathclose(up->slash->path);
- up->slash->path = newpath("/");
- up->dot = cclone(up->slash);
- chandevinit();
- if(!waserror()){
- ksetenv("terminal", "bitsy", 0);
- ksetenv("cputype", "arm", 0);
- if(cpuserver)
- ksetenv("service", "cpu", 0);
- else
- ksetenv("service", "terminal", 0);
- poperror();
- }
- kproc("alarm", alarmkproc, 0);
- kproc("power", powerkproc, 0);
- touser(sp);
- }
- /*
- * pass boot arguments to /boot
- */
- static uchar *
- pusharg(char *p)
- {
- int n;
- n = strlen(p)+1;
- sp -= n;
- memmove(sp, p, n);
- return sp;
- }
- static void
- bootargs(ulong base)
- {
- int i, ac;
- uchar *av[32];
- uchar *bootpath;
- uchar **lsp;
- /*
- * the sizeof(Sargs) is to make the validaddr check in
- * trap.c's syscall() work even when we have less than the
- * max number of args.
- */
- sp = (uchar*)base + BY2PG - sizeof(Sargs);
- bootpath = pusharg("/boot/boot");
- ac = 0;
- av[ac++] = pusharg("boot");
- /* 4 byte word align stack */
- sp = (uchar*)((ulong)sp & ~3);
- /* build argc, argv on stack */
- sp -= (ac+1)*sizeof(sp);
- lsp = (uchar**)sp;
- for(i = 0; i < ac; i++)
- *lsp++ = av[i] + ((USTKTOP - BY2PG) - base);
- *lsp = 0;
- /* push argv onto stack */
- sp -= BY2WD;
- lsp = (uchar**)sp;
- *lsp = sp + BY2WD + ((USTKTOP - BY2PG) - base);
- /* push pointer to "/boot" */
- sp -= BY2WD;
- lsp = (uchar**)sp;
- *lsp = bootpath + ((USTKTOP - BY2PG) - base);
- /* leave space for where the initcode's caller's return PC would normally reside */
- sp -= BY2WD;
- /* relocate stack to user's virtual addresses */
- sp += (USTKTOP - BY2PG) - base;
- }
- /*
- * create the first process
- */
- void
- userinit(void)
- {
- Proc *p;
- Segment *s;
- KMap *k;
- Page *pg;
- /* no processes yet */
- up = nil;
- p = newproc();
- p->pgrp = newpgrp();
- p->egrp = smalloc(sizeof(Egrp));
- p->egrp->ref = 1;
- p->fgrp = dupfgrp(nil);
- p->rgrp = newrgrp();
- p->procmode = 0640;
- kstrdup(&eve, "");
- kstrdup(&p->text, "*init*");
- kstrdup(&p->user, eve);
- /*
- * Kernel Stack
- */
- p->sched.pc = (ulong)init0;
- p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
- /*
- * User Stack
- */
- s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
- p->seg[SSEG] = s;
- pg = newpage(1, 0, USTKTOP-BY2PG);
- segpage(s, pg);
- k = kmap(pg);
- bootargs(VA(k));
- kunmap(k);
- /*
- * Text
- */
- s = newseg(SG_TEXT, UTZERO, 1);
- p->seg[TSEG] = s;
- pg = newpage(1, 0, UTZERO);
- memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
- segpage(s, pg);
- k = kmap(s->map[0]->pages[0]);
- memmove((ulong*)VA(k), initcode, sizeof initcode);
- kunmap(k);
- ready(p);
- }
- /*
- * set mach dependent process state for a new process
- */
- void
- procsetup(Proc *p)
- {
- p->fpstate = FPinit;
- }
- /*
- * Save the mach dependent part of the process state.
- */
- void
- procsave(Proc *p)
- {
- USED(p);
- }
- /* place holder */
- /*
- * dummy since rdb is not included
- */
- void
- rdb(void)
- {
- }
- /*
- * probe the last location in a meg of memory, make sure it's not
- * reflected into something else we've already found.
- */
- int
- probemem(ulong addr)
- {
- int i;
- ulong *p;
- ulong a;
- addr += OneMeg - sizeof(ulong);
- p = (ulong*)addr;
- *p = addr;
- for(i=0; i<nelem(conf.mem); i++){
- for(a = conf.mem[i].base+OneMeg-sizeof(ulong); a < conf.mem[i].limit; a += OneMeg){
- p = (ulong*)a;
- *p = 0;
- }
- }
- p = (ulong*)addr;
- if(*p != addr)
- return -1;
- return 0;
- }
- /*
- * we assume that the kernel is at the beginning of one of the
- * contiguous chunks of memory.
- */
- void
- confinit(void)
- {
- int i, j;
- ulong addr;
- ulong ktop;
- /* find first two contiguous sections of available memory */
- addr = PHYSDRAM0;
- for(i=0; i<nelem(conf.mem); i++){
- conf.mem[i].base = addr;
- conf.mem[i].limit = addr;
- }
- for(j=0; j<nelem(conf.mem); j++){
- conf.mem[j].base = addr;
- conf.mem[j].limit = addr;
-
- for(i = 0; i < 512; i++){
- if(probemem(addr) == 0)
- break;
- addr += OneMeg;
- }
- for(; i < 512; i++){
- if(probemem(addr) < 0)
- break;
- addr += OneMeg;
- conf.mem[j].limit = addr;
- }
- }
-
- conf.npage = 0;
- for(i=0; i<nelem(conf.mem); i++){
- /* take kernel out of allocatable space */
- ktop = PGROUND((ulong)end);
- if(ktop >= conf.mem[i].base && ktop <= conf.mem[i].limit)
- conf.mem[i].base = ktop;
-
- /* zero memory */
- memset((void*)conf.mem[i].base, 0, conf.mem[i].limit - conf.mem[i].base);
- conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
- conf.npage += conf.mem[i].npage;
- }
- if(conf.npage > 16*MB/BY2PG){
- conf.upages = (conf.npage*60)/100;
- imagmem->minarena = 4*1024*1024;
- }else
- conf.upages = (conf.npage*40)/100;
- conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
- /* only one processor */
- conf.nmach = 1;
- /* set up other configuration parameters */
- conf.nproc = 100;
- conf.nswap = conf.npage*3;
- conf.nswppo = 4096;
- conf.nimage = 200;
- conf.monitor = 1;
- conf.copymode = 0; /* copy on write */
- }
- GPIOregs *gpioregs;
- ulong *egpioreg = (ulong*)EGPIOREGS;
- PPCregs *ppcregs;
- MemConfRegs *memconfregs;
- PowerRegs *powerregs;
- ResetRegs *resetregs;
- /*
- * configure the machine
- */
- void
- machinit(void)
- {
- /* set direction of SA1110 io pins and select alternate functions for some */
- gpioregs = mapspecial(GPIOREGS, sizeof(GPIOregs));
- gpioregs->direction =
- GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
- |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
- |GPIO_CLK_SET0_o|GPIO_CLK_SET1_o
- |GPIO_L3_SDA_io|GPIO_L3_MODE_o|GPIO_L3_SCLK_o
- |GPIO_COM_RTS_o;
- gpioregs->rising = 0;
- gpioregs->falling = 0;
- gpioregs->altfunc |=
- GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
- |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
- |GPIO_SSP_CLK_i;
- /* map in special H3650 io pins */
- egpioreg = mapspecial(EGPIOREGS, sizeof(ulong));
- /* map in peripheral pin controller (ssp will need it) */
- ppcregs = mapspecial(PPCREGS, sizeof(PPCregs));
- /* SA1110 power management */
- powerregs = mapspecial(POWERREGS, sizeof(PowerRegs));
- /* memory configuraton */
- memconfregs = mapspecial(MEMCONFREGS, sizeof(MemConfRegs));
- /* reset controller */
- resetregs = mapspecial(RESETREGS, sizeof(ResetRegs));
- }
- /*
- * manage egpio bits
- */
- static ulong egpiosticky;
- void
- egpiobits(ulong bits, int on)
- {
- if(on)
- egpiosticky |= bits;
- else
- egpiosticky &= ~bits;
- *egpioreg = egpiosticky;
- }
- void
- rs232power(int on)
- {
- egpiobits(EGPIO_rs232_power, on);
- delay(50);
- }
- void
- audioamppower(int on)
- {
- egpiobits(EGPIO_audio_power, on);
- delay(50);
- }
- void
- audioicpower(int on)
- {
- egpiobits(EGPIO_audio_ic_power, on);
- delay(50);
- }
- void
- irpower(int on)
- {
- egpiobits(EGPIO_ir_power, on);
- delay(50);
- }
- void
- lcdpower(int on)
- {
- egpiobits(EGPIO_lcd_3v|EGPIO_lcd_ic_power|EGPIO_lcd_5v|EGPIO_lcd_9v, on);
- delay(50);
- }
- void
- flashprogpower(int on)
- {
- egpiobits(EGPIO_prog_flash, on);
- }
- /* here on hardware reset */
- void
- resettrap(void)
- {
- }
- /*
- * for drivers that used to run on x86's
- */
- void
- outb(ulong a, uchar v)
- {
- *(uchar*)a = v;
- }
- void
- outs(ulong a, ushort v)
- {
- *(ushort*)a = v;
- }
- void
- outss(ulong a, void *p, int n)
- {
- ushort *sp = p;
- while(n-- > 0)
- *(ushort*)a = *sp++;
- }
- void
- outl(ulong a, ulong v)
- {
- *(ulong*)a = v;
- }
- uchar
- inb(ulong a)
- {
- return *(uchar*)a;
- }
- ushort
- ins(ulong a)
- {
- return *(ushort*)a;
- }
- void
- inss(ulong a, void *p, int n)
- {
- ushort *sp = p;
- while(n-- > 0)
- *sp++ = *(ushort*)a;
- }
- ulong
- inl(ulong a)
- {
- return *(ulong*)a;
- }
- char*
- getconf(char*)
- {
- return nil;
- }
- long
- _xdec(long *p)
- {
- int s;
- long v;
- s = splhi();
- v = --*p;
- splx(s);
- return v;
- }
- void
- _xinc(long *p)
- {
- int s;
- s = splhi();
- ++*p;
- splx(s);
- }
- int
- cmpswap(long *addr, long old, long new)
- {
- int r, s;
-
- s = splhi();
- if(r = (*addr==old))
- *addr = new;
- splx(s);
- return r;
- }
|