The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/bitsy/main.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.