xen: use pc/fpu.c
parent
8c1bde46f0
commit
dcdb2bfb9a
|
@ -83,18 +83,3 @@ void outl(int, ulong) {}
|
|||
int mtrrprint(char*, long) { return 0; }
|
||||
char* mtrr(uvlong, uvlong, char *) { return nil; }
|
||||
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);
|
||||
#define evenaddr(x) /* x86 doesn't care */
|
||||
void fpclear(void);
|
||||
void fpenv(FPsave*);
|
||||
void fpinit(void);
|
||||
void fpoff(void);
|
||||
void (*fprestore)(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);
|
||||
char* getconf(char*);
|
||||
void guesscpuhz(int);
|
||||
|
|
|
@ -163,34 +163,42 @@ TEXT fpinit(SB), $0 /* enable and init */
|
|||
WAIT
|
||||
RET
|
||||
|
||||
TEXT fpx87save(SB), $0 /* save state and disable */
|
||||
TEXT fpx87save0(SB), $0 /* save state and disable */
|
||||
MOVL p+0(FP), AX
|
||||
FSAVE 0(AX) /* no WAIT */
|
||||
FPOFF(l2)
|
||||
RET
|
||||
|
||||
TEXT fpx87restore(SB), $0 /* enable and restore state */
|
||||
TEXT fpx87restore0(SB), $0 /* enable and restore state */
|
||||
FPON
|
||||
MOVL p+0(FP), AX
|
||||
FRSTOR 0(AX)
|
||||
WAIT
|
||||
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 */
|
||||
FPON
|
||||
FCLEX /* no WAIT */
|
||||
FPOFF(l3)
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue