xen: use pc/fpu.c
This commit is contained in:
parent
8c1bde46f0
commit
dcdb2bfb9a
4 changed files with 19 additions and 161 deletions
|
@ -83,18 +83,3 @@ void outl(int, ulong) {}
|
||||||
int mtrrprint(char*, long) { return 0; }
|
int mtrrprint(char*, long) { return 0; }
|
||||||
char* mtrr(uvlong, uvlong, char *) { return nil; }
|
char* mtrr(uvlong, uvlong, char *) { return nil; }
|
||||||
void mtrrsync(void) {}
|
void mtrrsync(void) {}
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX until fpsave is debugged
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
fpssesave(FPsave* f)
|
|
||||||
{
|
|
||||||
fpx87save(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fpsserestore(FPsave* f)
|
|
||||||
{
|
|
||||||
fpx87restore(f);
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,18 +17,10 @@ void (*cycles)(uvlong*);
|
||||||
void delay(int);
|
void delay(int);
|
||||||
#define evenaddr(x) /* x86 doesn't care */
|
#define evenaddr(x) /* x86 doesn't care */
|
||||||
void fpclear(void);
|
void fpclear(void);
|
||||||
void fpenv(FPsave*);
|
|
||||||
void fpinit(void);
|
void fpinit(void);
|
||||||
void fpoff(void);
|
void fpoff(void);
|
||||||
void (*fprestore)(FPsave*);
|
void (*fprestore)(FPsave*);
|
||||||
void (*fpsave)(FPsave*);
|
void (*fpsave)(FPsave*);
|
||||||
void fpsserestore(FPsave*);
|
|
||||||
void fpsserestore0(FPsave*);
|
|
||||||
void fpssesave(FPsave*);
|
|
||||||
void fpssesave0(FPsave*);
|
|
||||||
ulong fpstatus(void);
|
|
||||||
void fpx87restore(FPsave*);
|
|
||||||
void fpx87save(FPsave*);
|
|
||||||
ulong getcr4(void);
|
ulong getcr4(void);
|
||||||
char* getconf(char*);
|
char* getconf(char*);
|
||||||
void guesscpuhz(int);
|
void guesscpuhz(int);
|
||||||
|
|
|
@ -163,34 +163,42 @@ TEXT fpinit(SB), $0 /* enable and init */
|
||||||
WAIT
|
WAIT
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT fpx87save(SB), $0 /* save state and disable */
|
TEXT fpx87save0(SB), $0 /* save state and disable */
|
||||||
MOVL p+0(FP), AX
|
MOVL p+0(FP), AX
|
||||||
FSAVE 0(AX) /* no WAIT */
|
FSAVE 0(AX) /* no WAIT */
|
||||||
FPOFF(l2)
|
FPOFF(l2)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT fpx87restore(SB), $0 /* enable and restore state */
|
TEXT fpx87restore0(SB), $0 /* enable and restore state */
|
||||||
FPON
|
FPON
|
||||||
MOVL p+0(FP), AX
|
MOVL p+0(FP), AX
|
||||||
FRSTOR 0(AX)
|
FRSTOR 0(AX)
|
||||||
WAIT
|
WAIT
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT fpstatus(SB), $0 /* get floating point status */
|
|
||||||
FSTSW AX
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT fpenv(SB), $0 /* save state without waiting */
|
|
||||||
MOVL p+0(FP), AX
|
|
||||||
FSTENV 0(AX)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT fpclear(SB), $0 /* clear pending exceptions */
|
TEXT fpclear(SB), $0 /* clear pending exceptions */
|
||||||
FPON
|
FPON
|
||||||
FCLEX /* no WAIT */
|
FCLEX /* no WAIT */
|
||||||
FPOFF(l3)
|
FPOFF(l3)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
TEXT fpssesave(SB), $0 /* save state and disable */
|
||||||
|
MOVL p+0(FP), AX
|
||||||
|
FXSAVE 0(AX) /* no WAIT */
|
||||||
|
FPOFF(l4)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT fpsserestore(SB), $0 /* enable and restore state */
|
||||||
|
FPON
|
||||||
|
MOVL p+0(FP), AX
|
||||||
|
FXRSTOR 0(AX)
|
||||||
|
WAIT
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ldmxcsr(SB), $0 /* Load MXCSR */
|
||||||
|
LDMXCSR mxcsr+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test-And-Set
|
* Test-And-Set
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -322,133 +322,6 @@ confinit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* mathmsg[] =
|
|
||||||
{
|
|
||||||
nil, /* handled below */
|
|
||||||
"denormalized operand",
|
|
||||||
"division by zero",
|
|
||||||
"numeric overflow",
|
|
||||||
"numeric underflow",
|
|
||||||
"precision loss",
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
mathnote(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ulong status;
|
|
||||||
char *msg, note[ERRMAX];
|
|
||||||
|
|
||||||
status = up->fpsave->status;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some attention should probably be paid here to the
|
|
||||||
* exception masks and error summary.
|
|
||||||
*/
|
|
||||||
msg = "unknown exception";
|
|
||||||
for(i = 1; i <= 5; i++){
|
|
||||||
if(!((1<<i) & status))
|
|
||||||
continue;
|
|
||||||
msg = mathmsg[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(status & 0x01){
|
|
||||||
if(status & 0x40){
|
|
||||||
if(status & 0x200)
|
|
||||||
msg = "stack overflow";
|
|
||||||
else
|
|
||||||
msg = "stack underflow";
|
|
||||||
}else
|
|
||||||
msg = "invalid operation";
|
|
||||||
}
|
|
||||||
snprint(note, sizeof note, "sys: fp: %s fppc=0x%lux status=0x%lux",
|
|
||||||
msg, up->fpsave->pc, status);
|
|
||||||
postnote(up, 1, note, NDebug);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* math coprocessor error
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
matherror(Ureg *ur, void*)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* a write cycle to port 0xF0 clears the interrupt latch attached
|
|
||||||
* to the error# line from the 387
|
|
||||||
*/
|
|
||||||
if(!(m->cpuiddx & 0x01))
|
|
||||||
outb(0xF0, 0xFF);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* save floating point state to check out error
|
|
||||||
*/
|
|
||||||
fpenv(up->fpsave);
|
|
||||||
mathnote();
|
|
||||||
|
|
||||||
if(ur->pc & KZERO)
|
|
||||||
panic("fp: status %ux fppc=0x%lux pc=0x%lux",
|
|
||||||
up->fpsave->status, up->fpsave->pc, ur->pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* math coprocessor emulation fault
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
mathemu(Ureg *ureg, void*)
|
|
||||||
{
|
|
||||||
if(up->fpstate & FPillegal){
|
|
||||||
/* someone did floating point in a note handler */
|
|
||||||
postnote(up, 1, "sys: floating point in note handler", NDebug);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch(up->fpstate){
|
|
||||||
case FPinit:
|
|
||||||
fpinit();
|
|
||||||
while(up->fpsave == nil)
|
|
||||||
up->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0);
|
|
||||||
up->fpstate = FPactive;
|
|
||||||
break;
|
|
||||||
case FPinactive:
|
|
||||||
/*
|
|
||||||
* Before restoring the state, check for any pending
|
|
||||||
* exceptions, there's no way to restore the state without
|
|
||||||
* generating an unmasked exception.
|
|
||||||
* More attention should probably be paid here to the
|
|
||||||
* exception masks and error summary.
|
|
||||||
*/
|
|
||||||
if((up->fpsave->status & ~up->fpsave->control) & 0x07F){
|
|
||||||
mathnote();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fprestore(up->fpsave);
|
|
||||||
up->fpstate = FPactive;
|
|
||||||
break;
|
|
||||||
case FPactive:
|
|
||||||
panic("math emu pid %ld %s pc 0x%lux",
|
|
||||||
up->pid, up->text, ureg->pc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* math coprocessor segment overrun
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
mathover(Ureg*, void*)
|
|
||||||
{
|
|
||||||
pexit("math overrun", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mathinit(void)
|
|
||||||
{
|
|
||||||
trapenable(VectorCERR, matherror, 0, "matherror");
|
|
||||||
//if(X86FAMILY(m->cpuidax) == 3)
|
|
||||||
// intrenable(IrqIRQ13, matherror, 0, BUSUNKNOWN, "matherror");
|
|
||||||
trapenable(VectorCNA, mathemu, 0, "mathemu");
|
|
||||||
trapenable(VectorCSO, mathover, 0, "mathover");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set up floating point for a new process
|
* set up floating point for a new process
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue