#include "u.h"
+#include "tos.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
-#include "tos.h"
#include "ureg.h"
-#include "init.h"
#include "pool.h"
-#include "reboot.h"
+#include "rebootcode.i"
Mach *m;
Conf conf;
-char *sp; /* user stack of init proc */
int delaylink;
int idle_spin;
trapinit0();
i8253init();
cpuidentify();
+ meminit0();
+ archinit();
meminit();
+ ramdiskinit();
confinit();
xinit();
- archinit();
bootscreeninit();
if(i8237alloc != nil)
i8237alloc();
}else
links();
chandevreset();
- netconsole();
pageinit();
- swapinit();
userinit();
schedinit();
}
void
init0(void)
{
- char buf[2*KNAMELEN];
-
- 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);
+ char buf[2*KNAMELEN], **sp;
chandevinit();
poperror();
}
kproc("alarm", alarmkproc, 0);
- touser(sp);
-}
-
-void
-userbootargs(void *base)
-{
- char *argv[8];
- int i, argc;
-
-#define UA(ka) ((char*)(ka) + ((uintptr)(USTKTOP - BY2PG) - (uintptr)base))
- sp = (char*)base + BY2PG - sizeof(Tos);
-
- /* push boot command line onto the stack */
- sp -= BOOTLINELEN;
- sp[BOOTLINELEN-1] = '\0';
- memmove(sp, BOOTLINE, BOOTLINELEN-1);
-
- /* parse boot command line */
- argc = tokenize(sp, argv, nelem(argv));
- if(argc < 1){
- strcpy(sp, "boot");
- argc = 0;
- argv[argc++] = sp;
- }
-
- /* 4 byte word align stack */
- sp = (char*)((uintptr)sp & ~3);
-
- /* build argv on stack */
- sp -= (argc+1)*BY2WD;
- for(i=0; i<argc; i++)
- ((char**)sp)[i] = UA(argv[i]);
- ((char**)sp)[i] = nil;
-
- sp = UA(sp);
-#undef UA
- sp -= BY2WD;
-}
-
-void
-userinit(void)
-{
- void *v;
- Proc *p;
- Segment *s;
- Page *pg;
-
- 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);
-
- procsetup(p);
-
- /*
- * Kernel Stack
- *
- * N.B. make sure there's enough space for syscall to check
- * for valid args and
- * 4 bytes for gotolabel's return PC
- */
- p->sched.pc = (ulong)init0;
- p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD);
-
- /*
- * User Stack
- *
- * N.B. cannot call newpage() with clear=1, because pc kmap
- * requires up != nil. use tmpmap instead.
- */
- s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
- p->seg[SSEG] = s;
- pg = newpage(0, 0, USTKTOP-BY2PG);
- v = tmpmap(pg);
- memset(v, 0, BY2PG);
- segpage(s, pg);
- userbootargs(v);
- tmpunmap(v);
- /*
- * Text
- */
- s = newseg(SG_TEXT, UTZERO, 1);
- s->flushme++;
- p->seg[TSEG] = s;
- pg = newpage(0, 0, UTZERO);
- pg->txtflush = ~0;
- segpage(s, pg);
- v = tmpmap(pg);
- memset(v, 0, BY2PG);
- memmove(v, initcode, sizeof initcode);
- tmpunmap(v);
-
- ready(p);
+ sp = (char**)(USTKTOP - sizeof(Tos) - 8 - sizeof(sp[0])*4);
+ sp[3] = sp[2] = nil;
+ strcpy(sp[1] = (char*)&sp[4], "boot");
+ sp[0] = nil;
+ touser(sp);
}
void
}
/*
- * we keep FPsave structure in sse format emulating FXSAVE / FXRSTOR
+ * we keep FPsave structure in SSE format emulating FXSAVE / FXRSTOR
* instructions for legacy x87 fpu.
- *
- * Note that fpx87restore() and fpxsserestore() do modify the FPsave
- * data structure for conversion / realignment shuffeling. this means
- * that p->fpsave is only valid when p->fpstate == FPinactive.
*/
void
fpx87save(FPsave *fps)
fpx87restore0(fps);
}
-/*
- * sse fp save and restore buffers have to be 16-byte (FPalign) aligned,
- * so we shuffle the data up and down as needed or make copies.
- */
-void
-fpssesave(FPsave *fps)
-{
- FPsave *afps;
-
- afps = (FPsave *)ROUND(((uintptr)fps), FPalign);
- fpssesave0(afps);
- if(fps != afps) /* not aligned? shuffle down from aligned buffer */
- memmove(fps, afps, sizeof(FPssestate) - FPalign);
-}
-
-void
-fpsserestore(FPsave *fps)
-{
- FPsave *afps;
-
- afps = (FPsave *)ROUND(((uintptr)fps), FPalign);
- if(fps != afps) /* shuffle up to make aligned */
- memmove(afps, fps, sizeof(FPssestate) - FPalign);
- fpsserestore0(afps);
-}
-
static char* mathmsg[] =
{
nil, /* handled below */
/*
* get floating point state to check out error
*/
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
- mathnote(up->fpsave.fsw, up->fpsave.fpuip);
+ mathnote(up->fpsave->fsw, up->fpsave->fpuip);
}
/*
static void
simderror(Ureg *ureg, void*)
{
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
- mathnote(up->fpsave.mxcsr & 0x3f, ureg->pc);
+ mathnote(up->fpsave->mxcsr & 0x3f, ureg->pc);
}
/*
case FPinit:
fpinit();
if(fpsave == fpssesave)
- ldmxcsr(0); /* no simd exceptions on 386 */
+ ldmxcsr(0x1f80); /* no simd exceptions on 386 */
+ while(up->fpsave == nil)
+ up->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0);
up->fpstate = FPactive;
break;
case FPinactive:
* More attention should probably be paid here to the
* exception masks and error summary.
*/
- status = up->fpsave.fsw;
- control = up->fpsave.fcw;
+ status = up->fpsave->fsw;
+ control = up->fpsave->fcw;
if((status & ~control) & 0x07F){
- mathnote(status, up->fpsave.fpuip);
+ mathnote(status, up->fpsave->fpuip);
break;
}
- fprestore(&up->fpsave);
+ fprestore(up->fpsave);
up->fpstate = FPactive;
break;
case FPactive:
mathinit(void)
{
trapenable(VectorCERR, matherror, 0, "matherror");
- if(X86FAMILY(m->cpuidax) == 3)
+ if(m->cpuidfamily == 3)
intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror");
trapenable(VectorCNA, mathemu, 0, "mathemu");
trapenable(VectorCSO, mathover, 0, "mathover");
p->fpstate = FPinit;
fpoff();
- cycles(&p->kentry);
- p->pcycles = -p->kentry;
-
memset(p->gdt, 0, sizeof(p->gdt));
- p->ldt = nil;
p->nldt = 0;
+ /* clear debug registers */
memset(p->dr, 0, sizeof(p->dr));
+ if(m->dr7 != 0){
+ m->dr7 = 0;
+ putdr7(0);
+ }
+
+ cycles(&p->kentry);
+ p->pcycles = -p->kentry;
}
void
s = splhi();
switch(up->fpstate & ~FPillegal){
case FPactive:
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
case FPinactive:
- p->fpsave = up->fpsave;
+ while(p->fpsave == nil)
+ p->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0);
+ memmove(p->fpsave, up->fpsave, sizeof(FPsave));
p->fpstate = FPinactive;
}
-
- /* clear debug registers */
- memset(p->dr, 0, sizeof(p->dr));
splx(s);
}
m->dr7 = p->dr[7];
putdr(p->dr);
}
+
+ if(p->vmx != nil)
+ vmxprocrestore(p);
if(p->kp)
return;
{
uvlong t;
+ cycles(&t);
+ p->kentry -= t;
+ p->pcycles += t;
+
/* we could just always putdr7(0) but accessing DR7 might be slow in a VM */
if(m->dr7 != 0){
m->dr7 = 0;
putdr7(0);
}
-
- cycles(&t);
- p->kentry -= t;
- p->pcycles += t;
+ if(p->state == Moribund)
+ p->dr[7] = 0;
if(p->fpstate == FPactive){
if(p->state == Moribund)
* until the process runs again and generates an
* emulation fault to activate the FPU.
*/
- fpsave(&p->fpsave);
+ fpsave(p->fpsave);
}
p->fpstate = FPinactive;
}
mmuflushtlb(PADDR(m->pdb));
}
-void
-reboot(void *entry, void *code, ulong size)
+static void
+rebootjump(uintptr entry, uintptr code, ulong size)
{
- void (*f)(ulong, ulong, ulong);
+ void (*f)(uintptr, uintptr, ulong);
ulong *pdb;
- 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();
- }
- cpushutdown();
-
splhi();
-
- /* turn off buffered serial console */
- serialoq = nil;
-
- /* shutdown devices */
- chandevshutdown();
arch->introff();
/*
/* off we go - never to return */
coherence();
- (*f)((ulong)entry & ~0xF0000000UL, PADDR(code), size);
+ (*f)(entry, code, size);
+ for(;;);
}
exit(int)
{
cpushutdown();
+ if(m->machno)
+ rebootjump(0, 0, 0);
arch->reset();
}
+
+void
+reboot(void *entry, void *code, ulong size)
+{
+ writeconf();
+ vmxshutdown();
+
+ /*
+ * 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();
+ }
+ cpushutdown();
+ delay(1000);
+ splhi();
+
+ /* turn off buffered serial console */
+ serialoq = nil;
+
+ /* shutdown devices */
+ chandevshutdown();
+
+ rebootjump((ulong)entry & ~0xF0000000UL, PADDR(code), size);
+}