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

Cache object: 42913f8e02e503f3889aa1e2e9a08098


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