]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc64/main.c
pc64: print "Plan 9" on boot, cleanup pccpu64 files
[plan9front.git] / sys / src / 9 / pc64 / main.c
index 596aa0c4845e89a0f039d47ce2482acb09e32375..63dce3934a8f7fe4a9cacee0620df82f8864fc72 100644 (file)
@@ -8,6 +8,7 @@
 #include       "ureg.h"
 #include       "init.h"
 #include       "pool.h"
+#include       "reboot.h"
 
 /*
  * Where configuration info is left for the loaded programme.
@@ -32,13 +33,62 @@ uchar *sp;  /* user stack of init proc */
 
 extern void (*i8237alloc)(void);
 
+static void
+multibootargs(void)
+{
+       extern ulong multibootptr;
+       ulong *multiboot;
+       char *cp, *ep;
+       ulong *m, l;
+
+       if(multibootptr == 0)
+               return;
+
+       multiboot = (ulong*)KADDR(multibootptr);
+       /* command line */
+       if((multiboot[0] & (1<<2)) != 0)
+               strncpy(BOOTLINE, KADDR(multiboot[4]), BOOTLINELEN-1);
+
+       cp = BOOTARGS;
+       ep = cp + BOOTARGSLEN-1;
+
+       /* memory map */
+       if((multiboot[0] & (1<<6)) != 0 && (l = multiboot[11]) >= 24){
+               cp = seprint(cp, ep, "*e820=");
+               m = KADDR(multiboot[12]);
+               while(m[0] >= 20 && m[0] <= l-4){
+                       uvlong base, size;
+                       m++;
+                       base = ((uvlong)m[0] | (uvlong)m[1]<<32);
+                       size = ((uvlong)m[2] | (uvlong)m[3]<<32);
+                       cp = seprint(cp, ep, "%.1lux %.16llux %.16llux ",
+                               m[4] & 0xF, base, base+size);
+                       l -= m[-1]+4;
+                       m = (ulong*)((uintptr)m + m[-1]);
+               }
+               cp[-1] = '\n';
+       }
+
+       /* plan9.ini passed as the first module */
+       if((multiboot[0] & (1<<3)) != 0 && multiboot[5] > 0){
+               m = KADDR(multiboot[6]);
+               l = m[1] - m[0];
+               m = KADDR(m[0]);
+               if(cp+l > ep)
+                       l = ep - cp;
+               memmove(cp, m, l);
+               cp += l;
+       }
+       *cp = 0;
+}
+
 static void
 options(void)
 {
        long i, n;
        char *cp, *line[MAXCONF], *p, *q;
 
-       // multibootargs();
+       multibootargs();
 
        /*
         *  parse configuration args from dos file plan9.ini
@@ -84,6 +134,35 @@ getconf(char *name)
        return 0;
 }
 
+static void
+writeconf(void)
+{
+       char *p, *q;
+       int n;
+
+       p = getconfenv();
+
+       if(waserror()) {
+               free(p);
+               nexterror();
+       }
+
+       /* convert to name=value\n format */
+       for(q=p; *q; q++) {
+               q += strlen(q);
+               *q = '=';
+               q += strlen(q);
+               *q = '\n';
+       }
+       n = q - p + 1;
+       if(n >= BOOTARGSLEN)
+               error("kernel configuration too large");
+       memset(BOOTLINE, 0, BOOTLINELEN);
+       memmove(BOOTARGS, p, n);
+       poperror();
+       free(p);
+}
+
 void
 confinit(void)
 {
@@ -91,6 +170,13 @@ confinit(void)
        int i, userpcnt;
        ulong kpages;
 
+       if(p = getconf("service")){
+               if(strcmp(p, "cpu") == 0)
+                       cpuserver = 1;
+               else if(strcmp(p,"terminal") == 0)
+                       cpuserver = 0;
+       }
+
        if(p = getconf("*kernelpercent"))
                userpcnt = 100 - strtol(p, 0, 0);
        else
@@ -113,21 +199,6 @@ confinit(void)
                if(userpcnt < 10)
                        userpcnt = 70;
                kpages = conf.npage - (conf.npage*userpcnt)/100;
-
-               /*
-                * Hack for the big boys. Only good while physmem < 4GB.
-                * Give the kernel fixed max + enough to allocate the
-                * page pool.
-                * This is an overestimate as conf.upages < conf.npages.
-                * The patch of nimage is a band-aid, scanning the whole
-                * page list in imagereclaim just takes too long.
-                */
-               if(getconf("*imagemaxmb") == 0)
-               if(kpages > (64*MB + conf.npage*sizeof(Page))/BY2PG){
-                       kpages = (64*MB + conf.npage*sizeof(Page))/BY2PG;
-                       conf.nimage = 2000;
-                       kpages += (conf.nproc*KSTACK)/BY2PG;
-               }
        } else {
                if(userpcnt < 10) {
                        if(conf.npage*BY2PG < 16*MB)
@@ -160,8 +231,7 @@ confinit(void)
         * (probably ~300KB).
         */
        kpages *= BY2PG;
-       kpages -= conf.upages*sizeof(Page)
-               + conf.nproc*sizeof(Proc)
+       kpages -= conf.nproc*sizeof(Proc)
                + conf.nimage*sizeof(Image)
                + conf.nswap
                + conf.nswppo*sizeof(Page*);
@@ -179,6 +249,44 @@ confinit(void)
        }
 }
 
+/*
+ * The palloc.pages array can be a large chunk out of the 2GB
+ * window above KZERO, so we allocate the array from
+ * upages and map in the VMAP window before pageinit()
+ */
+static void
+preallocpages(void)
+{
+       Pallocmem *pm;
+       uintptr va, base, top;
+       vlong size;
+       ulong np;
+       int i;
+
+       np = 0;
+       for(i=0; i<nelem(palloc.mem); i++){
+               pm = &palloc.mem[i];
+               np += pm->npage;
+       }
+       size = (uvlong)np * BY2PG;
+       size += sizeof(Page) + BY2PG;   /* round up */
+       size = (size / (sizeof(Page) + BY2PG)) * sizeof(Page);
+       size = ROUND(size, PGLSZ(1));
+
+       for(i=0; i<nelem(palloc.mem); i++){
+               pm = &palloc.mem[i];
+               base = ROUND(pm->base, PGLSZ(1));
+               top = pm->base + (uvlong)pm->npage * BY2PG;
+               if((base + size) <= VMAPSIZE && (vlong)(top - base) >= size){
+                       va = base + VMAP;
+                       pmap(m->pml4, base | PTEGLOBAL|PTEWRITE|PTEVALID, va, size);
+                       palloc.pages = (Page*)va;
+                       pm->base = base + size;
+                       pm->npage = (top - pm->base)/BY2PG;
+                       break;
+               }
+       }
+}
 
 void
 machinit(void)
@@ -346,6 +454,9 @@ userinit(void)
        p->sched.pc = (uintptr)init0;
        p->sched.sp = (uintptr)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
 
+       /* temporarily set up for kmap() */
+       up = p;
+
        /*
         * User Stack
         */
@@ -372,6 +483,10 @@ userinit(void)
        memmove(v, initcode, sizeof initcode);
        kunmap(v);
 
+       /* free kmap */
+       mmurelease(p);
+       up = nil;
+
        ready(p);
 }
 
@@ -381,9 +496,10 @@ main()
        mach0init();
        options();
        ioinit();
-       // i8250console();
+       i8250console();
        quotefmtinstall();
        screeninit();
+       print("\nPlan 9\n");
        trapinit0();
        kbdinit();
        i8253init();
@@ -414,6 +530,7 @@ main()
                links();
        conf.monitor = 1;
        chandevreset();
+       preallocpages();
        pageinit();
        swapinit();
        userinit();
@@ -462,8 +579,7 @@ shutdown(int ispanic)
                        delay(5*60*1000);
                else
                        delay(10000);
-       }else
-               delay(1000);
+       }
 }
 
 void
@@ -474,9 +590,50 @@ exit(int ispanic)
 }
 
 void
-reboot(void*, void*, ulong)
+reboot(void *entry, void *code, ulong size)
 {
-       exit(0);
+       void (*f)(uintptr, uintptr, ulong);
+
+       writeconf();
+
+       /*
+        * the boot processor is cpu0.  execute this function on it
+        * so that the new kernel has the same cpu0.  this only matters
+        * because the hardware has a notion of which processor was the
+        * boot processor and we look at it at start up.
+        */
+       if (m->machno != 0) {
+               procwired(up, 0);
+               sched();
+       }
+       shutdown(0);
+
+       iprint("shutting down...\n");
+       delay(200);
+
+       splhi();
+
+       /* turn off buffered serial console */
+       serialoq = nil;
+
+       /* shutdown devices */
+       chandevshutdown();
+       arch->introff();
+
+       /*
+        * This allows the reboot code to turn off the page mapping
+        */
+       *mmuwalk(m->pml4, 0, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0);
+       *mmuwalk(m->pml4, 0, 2, 0) = *mmuwalk(m->pml4, KZERO, 2, 0);
+       mmuflushtlb();
+
+       /* setup reboot trampoline function */
+       f = (void*)REBOOTADDR;
+       memmove(f, rebootcode, sizeof(rebootcode));
+
+       /* off we go - never to return */
+       coherence();
+       (*f)((uintptr)entry & ~0xF0000000UL, (uintptr)PADDR(code), size);
 }
 
 /*
@@ -584,6 +741,17 @@ matherror(Ureg*, void*)
        mathnote(up->fpsave.fsw, up->fpsave.rip);
 }
 
+/*
+ *  SIMD error
+ */
+static void
+simderror(Ureg *ureg, void*)
+{
+       fpsave(&up->fpsave);
+       up->fpstate = FPinactive;
+       mathnote(up->fpsave.mxcsr & 0x3f, ureg->pc);
+}
+
 /*
  *  math coprocessor emulation fault
  */
@@ -611,11 +779,7 @@ mathemu(Ureg *ureg, void*)
                _fninit();
                _fwait();
                _fldcw(0x0232);
-               /*
-                * TODO: sse exceptions
-                * _ldmxcsr(m->mxcsr);
-                *
-                */
+               _ldmxcsr(0x1900);
                up->fpstate = FPactive;
                break;
        case FPinactive:
@@ -659,6 +823,7 @@ mathinit(void)
                intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror");
        trapenable(VectorCNA, mathemu, 0, "mathemu");
        trapenable(VectorCSO, mathover, 0, "mathover");
+       trapenable(VectorSIMD, simderror, 0, "simderror");
 }
 
 void