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/mtx/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        "init.h"
    8 #include        "pool.h"
    9 
   10 Conf    conf;
   11 FPsave  initfp;
   12 
   13 void
   14 main(void)
   15 {
   16         memset(edata, 0, (ulong)end-(ulong)edata);
   17         conf.nmach = 1;
   18         machinit();
   19         ioinit();
   20         i8250console();
   21         quotefmtinstall();
   22         print("\nPlan 9\n");
   23         confinit();
   24         xinit();
   25         raveninit();
   26         trapinit();
   27         printinit();
   28         cpuidprint();
   29         mmuinit();
   30         hwintrinit();
   31         clockinit();
   32         kbdinit();
   33         procinit0();
   34         initseg();
   35         timersinit();
   36         links();
   37         chandevreset();
   38         pageinit();
   39         swapinit();
   40         fpsave(&initfp);
   41         initfp.fpscr = 0;
   42         userinit();
   43         schedinit();
   44 }
   45 
   46 void
   47 machinit(void)
   48 {
   49         memset(m, 0, sizeof(Mach));
   50         m->cputype = getpvr()>>16;
   51 
   52         /*
   53          * For polled uart output at boot, need
   54          * a default delay constant. 100000 should
   55          * be enough for a while. Cpuidentify will
   56          * calculate the real value later.
   57          */
   58         m->loopconst = 100000;
   59 
   60         /* turn on caches */
   61         puthid0(gethid0() | BIT(16) | BIT(17));
   62 
   63         active.machs = 1;
   64         active.exiting = 0;
   65 }
   66 
   67 void
   68 cpuidprint(void)
   69 {
   70         char *id;
   71 
   72         id = "unknown PowerPC";
   73         switch(m->cputype) {
   74         case 9:
   75                 id = "PowerPC 604e";
   76                 break;
   77         }
   78         print("cpu0: %s\n", id);
   79 }
   80 
   81 static struct
   82 {
   83         char    *name;
   84         char *val;
   85 }
   86 plan9ini[] =
   87 {
   88         { "console", "" },
   89         { "ether0", "type=2114x" },
   90 };
   91 
   92 char*
   93 getconf(char *name)
   94 {
   95         int i;
   96 
   97         for(i = 0; i < nelem(plan9ini); i++)
   98                 if(cistrcmp(name, plan9ini[i].name) == 0)
   99                         return plan9ini[i].val;
  100         return nil;
  101 }
  102 
  103 void
  104 init0(void)
  105 {
  106 //      char **p, *q, name[KNAMELEN];
  107 //      int n;
  108         char buf[2*KNAMELEN];
  109 
  110         up->nerrlab = 0;
  111 
  112         spllo();
  113 
  114         /*
  115          * These are o.k. because rootinit is null.
  116          * Then early kproc's will have a root and dot.
  117          */
  118         up->slash = namec("#/", Atodir, 0, 0);
  119         pathclose(up->slash->path);
  120         up->slash->path = newpath("/");
  121         up->dot = cclone(up->slash);
  122 
  123         chandevinit();
  124 
  125         if(!waserror()){
  126                 snprint(buf, sizeof(buf), "power %s mtx", conffile);
  127                 ksetenv("terminal", buf, 0);
  128                 ksetenv("cputype", "power", 0);
  129                 if(cpuserver)
  130                         ksetenv("service", "cpu", 0);
  131                 else
  132                         ksetenv("service", "terminal", 0);
  133                 
  134 /*
  135                 for(p = confenv; *p; p++) {
  136                         q = strchr(p[0], '=');
  137                         if(q == 0)
  138                                 continue;
  139                         n = q-p[0];
  140                         if(n >= KNAMELEN)
  141                                 n = KNAMELEN-1;
  142                         memmove(name, p[0], n);
  143                         name[n] = 0;
  144                         if(name[0] != '*')
  145                                 ksetenv(name, q+1, 0);
  146                         ksetenv(name, q+1, 1);
  147                 }
  148 */
  149                 poperror();
  150         }
  151         kproc("alarm", alarmkproc, 0);
  152         kproc("mmusweep", mmusweep, 0);
  153         touser((void*)(USTKTOP-8));
  154 }
  155 
  156 void
  157 userinit(void)
  158 {
  159         Proc *p;
  160         Segment *s;
  161         KMap *k;
  162         Page *pg;
  163 
  164         p = newproc();
  165         p->pgrp = newpgrp();
  166         p->egrp = smalloc(sizeof(Egrp));
  167         p->egrp->ref = 1;
  168         p->fgrp = dupfgrp(nil);
  169         p->rgrp = newrgrp();
  170         p->procmode = 0640;
  171 
  172         kstrdup(&eve, "");
  173         kstrdup(&p->text, "*init*");
  174         kstrdup(&p->user, eve);
  175 
  176         p->fpstate = FPinit;
  177 
  178         /*
  179          * Kernel Stack
  180          *
  181          * N.B. The -12 for the stack pointer is important.
  182          *      4 bytes for gotolabel's return PC
  183          */
  184         p->sched.pc = (ulong)init0;
  185         p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
  186 
  187         /*
  188          * User Stack
  189          */
  190         s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
  191         p->seg[SSEG] = s;
  192         pg = newpage(1, 0, USTKTOP-BY2PG);
  193         segpage(s, pg);
  194 
  195         /*
  196          * Text
  197          */
  198         s = newseg(SG_TEXT, UTZERO, 1);
  199         s->flushme++;
  200         p->seg[TSEG] = s;
  201         pg = newpage(1, 0, UTZERO);
  202         memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
  203         segpage(s, pg);
  204         k = kmap(s->map[0]->pages[0]);
  205         memmove((ulong*)VA(k), initcode, sizeof initcode);
  206         kunmap(k);
  207 
  208         ready(p);
  209 }
  210 
  211 /* still to do */
  212 void
  213 reboot(void*, void*, ulong)
  214 {
  215         exit(0);
  216 }
  217 
  218 void
  219 exit(int ispanic)
  220 {
  221         int ms, once;
  222 
  223         lock(&active);
  224         if(ispanic)
  225                 active.ispanic = ispanic;
  226         else if(m->machno == 0 && (active.machs & (1<<m->machno)) == 0)
  227                 active.ispanic = 0;
  228         once = active.machs & (1<<m->machno);
  229         active.machs &= ~(1<<m->machno);
  230         active.exiting = 1;
  231         unlock(&active);
  232 
  233         if(once)
  234                 print("cpu%d: exiting\n", m->machno);
  235         spllo();
  236         for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){
  237                 delay(TK2MS(2));
  238                 if(active.machs == 0 && consactive() == 0)
  239                         break;
  240         }
  241 
  242         if(active.ispanic && m->machno == 0){
  243                 if(cpuserver)
  244                         delay(10000);
  245                 else if(conf.monitor)
  246                         for(;;);
  247         }
  248         else
  249                 delay(1000);
  250 
  251         watchreset();
  252 }
  253 
  254 /*
  255  *  set up floating point for a new process
  256  */
  257 void
  258 procsetup(Proc *p)
  259 {
  260         p->fpstate = FPinit;
  261 }
  262 
  263 /*
  264  *  Save the mach dependent part of the process state.
  265  */
  266 void
  267 procsave(Proc *p)
  268 {
  269         if(p->fpstate == FPactive){
  270                 if(p->state != Moribund)
  271                         fpsave(&up->fpsave);
  272                 p->fpstate = FPinactive;
  273         }
  274 }
  275 
  276 void
  277 confinit(void)
  278 {
  279         char *p;
  280         int userpcnt;
  281         ulong pa, kpages;
  282         extern ulong memsize;   /* passed in from ROM monitor */
  283 
  284         if(p = getconf("*kernelpercent"))
  285                 userpcnt = 100 - strtol(p, 0, 0);
  286         else
  287                 userpcnt = 0;
  288 
  289         pa = PGROUND(PADDR(end));
  290 
  291         conf.mem[0].npage = memsize/BY2PG;
  292         conf.mem[0].base = pa;
  293         conf.npage = conf.mem[0].npage;
  294 
  295         conf.nmach = 1;
  296         conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
  297         if(cpuserver)
  298                 conf.nproc *= 3;
  299         if(conf.nproc > 2000)
  300                 conf.nproc = 2000;
  301         conf.nimage = 200;
  302         conf.nswap = conf.nproc*80;
  303         conf.nswppo = 4096;
  304         conf.copymode = 0;                      /* copy on write */
  305 
  306         if(cpuserver) {
  307                 if(userpcnt < 10)
  308                         userpcnt = 70;
  309                 kpages = conf.npage - (conf.npage*userpcnt)/100;
  310 
  311                 /*
  312                  * Hack for the big boys. Only good while physmem < 4GB.
  313                  * Give the kernel a max. of 16MB + enough to allocate the
  314                  * page pool.
  315                  * This is an overestimate as conf.upages < conf.npages.
  316                  * The patch of nimage is a band-aid, scanning the whole
  317                  * page list in imagereclaim just takes too long.
  318                  */
  319                 if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){
  320                         kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG;
  321                         conf.nimage = 2000;
  322                         kpages += (conf.nproc*KSTACK)/BY2PG;
  323                 }
  324         } else {
  325                 if(userpcnt < 10) {
  326                         if(conf.npage*BY2PG < 16*MB)
  327                                 userpcnt = 40;
  328                         else
  329                                 userpcnt = 60;
  330                 }
  331                 kpages = conf.npage - (conf.npage*userpcnt)/100;
  332 
  333                 /*
  334                  * Make sure terminals with low memory get at least
  335                  * 4MB on the first Image chunk allocation.
  336                  */
  337                 if(conf.npage*BY2PG < 16*MB)
  338                         imagmem->minarena = 4*1024*1024;
  339         }
  340         conf.upages = conf.npage - kpages;
  341         conf.ialloc = (kpages/2)*BY2PG;
  342 
  343         /*
  344          * Guess how much is taken by the large permanent
  345          * datastructures. Mntcache and Mntrpc are not accounted for
  346          * (probably ~300KB).
  347          */
  348         kpages *= BY2PG;
  349         kpages -= conf.upages*sizeof(Page)
  350                 + conf.nproc*sizeof(Proc)
  351                 + conf.nimage*sizeof(Image)
  352                 + conf.nswap
  353                 + conf.nswppo*sizeof(Page);
  354         mainmem->maxsize = kpages;
  355         if(!cpuserver){
  356                 /*
  357                  * give terminals lots of image memory, too; the dynamic
  358                  * allocation will balance the load properly, hopefully.
  359                  * be careful with 32-bit overflow.
  360                  */
  361                 imagmem->maxsize = kpages;
  362         }
  363 
  364 //      conf.monitor = 1;       /* BUG */
  365 }
  366 
  367 static int
  368 getcfields(char* lp, char** fields, int n, char* sep)
  369 {
  370         int i;
  371 
  372         for(i = 0; lp && *lp && i < n; i++){
  373                 while(*lp && strchr(sep, *lp) != 0)
  374                         *lp++ = 0;
  375                 if(*lp == 0)
  376                         break;
  377                 fields[i] = lp;
  378                 while(*lp && strchr(sep, *lp) == 0){
  379                         if(*lp == '\\' && *(lp+1) == '\n')
  380                                 *lp++ = ' ';
  381                         lp++;
  382                 }
  383         }
  384 
  385         return i;
  386 }
  387 
  388 int
  389 isaconfig(char *class, int ctlrno, ISAConf *isa)
  390 {
  391         int i;
  392         char cc[KNAMELEN], *p;
  393 
  394         sprint(cc, "%s%d", class, ctlrno);
  395 
  396         p = getconf(cc);
  397         if(p == 0)
  398                 return 0;
  399         isa->nopt = tokenize(p, isa->opt, NISAOPT);
  400         for(i = 0; i < isa->nopt; i++){
  401                 p = isa->opt[i];
  402                 if(cistrncmp(p, "type=", 5) == 0)
  403                         isa->type = p + 5;
  404                 else if(cistrncmp(p, "port=", 5) == 0)
  405                         isa->port = strtoul(p+5, &p, 0);
  406                 else if(cistrncmp(p, "irq=", 4) == 0)
  407                         isa->irq = strtoul(p+4, &p, 0);
  408                 else if(cistrncmp(p, "dma=", 4) == 0)
  409                         isa->dma = strtoul(p+4, &p, 0);
  410                 else if(cistrncmp(p, "mem=", 4) == 0)
  411                         isa->mem = strtoul(p+4, &p, 0);
  412                 else if(cistrncmp(p, "size=", 5) == 0)
  413                         isa->size = strtoul(p+5, &p, 0);
  414                 else if(cistrncmp(p, "freq=", 5) == 0)
  415                         isa->freq = strtoul(p+5, &p, 0);
  416         }
  417         return 1;
  418 }
  419 
  420 int
  421 cistrcmp(char *a, char *b)
  422 {
  423         int ac, bc;
  424 
  425         for(;;){
  426                 ac = *a++;
  427                 bc = *b++;
  428         
  429                 if(ac >= 'A' && ac <= 'Z')
  430                         ac = 'a' + (ac - 'A');
  431                 if(bc >= 'A' && bc <= 'Z')
  432                         bc = 'a' + (bc - 'A');
  433                 ac -= bc;
  434                 if(ac)
  435                         return ac;
  436                 if(bc == 0)
  437                         break;
  438         }
  439         return 0;
  440 }
  441 
  442 int
  443 cistrncmp(char *a, char *b, int n)
  444 {
  445         unsigned ac, bc;
  446 
  447         while(n > 0){
  448                 ac = *a++;
  449                 bc = *b++;
  450                 n--;
  451 
  452                 if(ac >= 'A' && ac <= 'Z')
  453                         ac = 'a' + (ac - 'A');
  454                 if(bc >= 'A' && bc <= 'Z')
  455                         bc = 'a' + (bc - 'A');
  456 
  457                 ac -= bc;
  458                 if(ac)
  459                         return ac;
  460                 if(bc == 0)
  461                         break;
  462         }
  463 
  464         return 0;
  465 }

Cache object: 54f7aeff570aab640cd81edbcf93f883


[ 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.