xen: use pc/fpu.c

front
cinap_lenrek 2020-12-06 21:28:11 +01:00
parent 8c1bde46f0
commit dcdb2bfb9a
4 changed files with 19 additions and 161 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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
*/

View File

@ -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
*/