diff --git a/sys/src/9/bcm/dat.h b/sys/src/9/bcm/dat.h index 6f41f4563..20cbf3880 100644 --- a/sys/src/9/bcm/dat.h +++ b/sys/src/9/bcm/dat.h @@ -15,13 +15,13 @@ enum { typedef struct Conf Conf; typedef struct Confmem Confmem; typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct ISAConf ISAConf; typedef struct Label Label; typedef struct Lock Lock; typedef struct Memcache Memcache; typedef struct MMMU MMMU; typedef struct Mach Mach; -typedef struct Notsave Notsave; typedef struct Page Page; typedef struct PhysUart PhysUart; typedef struct PMMU PMMU; @@ -56,14 +56,14 @@ struct Label uintptr pc; }; +/* + * emulated or vfp3 floating point + */ enum { Maxfpregs = 32, /* could be 16 or 32, see Mach.fpnregs */ Nfpctlregs = 16, }; -/* - * emulated or vfp3 floating point - */ struct FPsave { ulong status; @@ -78,9 +78,12 @@ struct FPsave uintptr pc; /* of failed fp instr. */ }; -/* - * FPsave.fpstate - */ +struct PFPU +{ + int fpstate; + FPsave fpsave[1]; +}; + enum { FPinit, @@ -119,13 +122,6 @@ struct Conf int monitor; /* flag */ }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave { - int emptiness; -}; - /* * MMU stuff in Mach. */ diff --git a/sys/src/9/bcm/fpiarm.c b/sys/src/9/bcm/fpiarm.c index d92455328..cefddc3e5 100644 --- a/sys/src/9/bcm/fpiarm.c +++ b/sys/src/9/bcm/fpiarm.c @@ -650,7 +650,7 @@ fpiarm(Ureg *ur) if(up == nil) panic("fpiarm not in a process"); - ufp = &up->fpsave; + ufp = up->fpsave; /* * because all the emulated fp state is in the proc structure, * it need not be saved/restored diff --git a/sys/src/9/bcm/vfp3.c b/sys/src/9/bcm/vfp3.c index 77070ba1c..b1c381274 100644 --- a/sys/src/9/bcm/vfp3.c +++ b/sys/src/9/bcm/vfp3.c @@ -222,7 +222,7 @@ void fpunotify(Ureg*) { if(up->fpstate == FPactive){ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal; @@ -259,11 +259,11 @@ fprestore(Proc *p) int n; fpon(); - fpwr(Fpscr, p->fpsave.control); + fpwr(Fpscr, p->fpsave->control); m->fpscr = fprd(Fpscr) & ~Allcc; assert(m->fpnregs); for (n = 0; n < m->fpnregs; n++) - fprestreg(n, *(uvlong *)p->fpsave.regs[n]); + fprestreg(n, *(uvlong *)p->fpsave->regs[n]); } /* @@ -288,7 +288,7 @@ fpuprocsave(Proc *p) * until the process runs again and generates an * emulation fault to activate the FPU. */ - fpsave(&p->fpsave); + fpsave(p->fpsave); } p->fpstate = FPinactive; } @@ -317,11 +317,11 @@ fpuprocfork(Proc *p) s = splhi(); switch(up->fpstate & ~FPillegal){ case FPactive: - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; /* no break */ case FPinactive: - p->fpsave = up->fpsave; + memmove(p->fpsave, up->fpsave, sizeof(FPsave)); p->fpstate = FPinactive; } splx(s); @@ -345,7 +345,7 @@ mathnote(void) ulong status; char *msg, note[ERRMAX]; - status = up->fpsave.status; + status = up->fpsave->status; /* * Some attention should probably be paid here to the @@ -364,7 +364,7 @@ mathnote(void) else msg = "spurious"; snprint(note, sizeof note, "sys: fp: %s fppc=%#p status=%#lux", - msg, up->fpsave.pc, status); + msg, up->fpsave->pc, status); postnote(up, 1, note, NDebug); } @@ -388,7 +388,7 @@ mathemu(Ureg *) * More attention should probably be paid here to the * exception masks and error summary. */ - if(up->fpsave.status & (FPAINEX|FPAUNFL|FPAOVFL|FPAZDIV|FPAINVAL)){ + if(up->fpsave->status & (FPAINEX|FPAUNFL|FPAOVFL|FPAZDIV|FPAINVAL)){ mathnote(); break; } diff --git a/sys/src/9/kw/dat.h b/sys/src/9/kw/dat.h index ed0f15bcc..84e33ac2d 100644 --- a/sys/src/9/kw/dat.h +++ b/sys/src/9/kw/dat.h @@ -1,13 +1,13 @@ typedef struct Conf Conf; typedef struct Confmem Confmem; typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct ISAConf ISAConf; typedef struct Label Label; typedef struct Lock Lock; typedef struct Memcache Memcache; typedef struct MMMU MMMU; typedef struct Mach Mach; -typedef struct Notsave Notsave; typedef struct Page Page; typedef struct Pcidev Pcidev; typedef struct PhysUart PhysUart; @@ -45,13 +45,13 @@ struct Label uintptr pc; }; +/* + * emulated floating point + */ enum{ Nfpctlregs = 16, }; -/* - * emulated floating point - */ struct FPsave { ulong status; @@ -61,9 +61,12 @@ struct FPsave int fpstate; }; -/* - * FPsave.status - */ +struct PFPU +{ + int fpstate; + FPsave fpsave[1]; +}; + enum { FPinit, @@ -98,13 +101,6 @@ struct Conf // ulong mhz; }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave { - int emptiness; -}; - /* * MMU stuff in Mach. */ diff --git a/sys/src/9/kw/fpiarm.c b/sys/src/9/kw/fpiarm.c index 8735f87ba..80b7ceae0 100644 --- a/sys/src/9/kw/fpiarm.c +++ b/sys/src/9/kw/fpiarm.c @@ -726,7 +726,7 @@ fpiarm(Ureg *ur) if(up == nil) panic("fpiarm not in a process"); - ufp = &up->fpsave; + ufp = up->fpsave; /* * because all the emulated fp state is in the proc structure, * it need not be saved/restored diff --git a/sys/src/9/mtx/dat.h b/sys/src/9/mtx/dat.h index 76bb8c856..8b74eb439 100644 --- a/sys/src/9/mtx/dat.h +++ b/sys/src/9/mtx/dat.h @@ -1,11 +1,11 @@ typedef struct Conf Conf; typedef struct Confmem Confmem; typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct ISAConf ISAConf; typedef struct Label Label; typedef struct Lock Lock; typedef struct Mach Mach; -typedef struct Notsave Notsave; typedef struct Page Page; typedef struct PCArch PCArch; typedef struct Pcidev Pcidev; @@ -45,16 +45,6 @@ struct Label ulong pc; }; -/* - * Proc.fpstate - */ -enum -{ - FPinit, - FPactive, - FPinactive, -}; - /* * This structure must agree with fpsave and fprestore asm routines */ @@ -70,6 +60,19 @@ struct FPsave }; }; +struct PFPU +{ + int fpstate; + FPsave fpsave[1]; +}; + +enum +{ + FPinit, + FPactive, + FPinactive, +}; + struct Confmem { ulong base; @@ -103,14 +106,6 @@ struct PMMU int mmupid; }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave -{ - ulong UNUSED; -}; - #include "../port/portdat.h" /* diff --git a/sys/src/9/mtx/main.c b/sys/src/9/mtx/main.c index 0b1f3401c..4cc7724d9 100644 --- a/sys/src/9/mtx/main.c +++ b/sys/src/9/mtx/main.c @@ -241,7 +241,7 @@ procsave(Proc *p) { if(p->fpstate == FPactive){ if(p->state != Moribund) - fpsave(&up->fpsave); + fpsave(up->fpsave); p->fpstate = FPinactive; } } diff --git a/sys/src/9/mtx/trap.c b/sys/src/9/mtx/trap.c index d9f827216..17c2b7e3d 100644 --- a/sys/src/9/mtx/trap.c +++ b/sys/src/9/mtx/trap.c @@ -246,7 +246,7 @@ trap(Ureg *ureg) up->fpstate = FPactive; break; case FPinactive: - fprestore(&up->fpsave); + fprestore(up->fpsave); up->fpstate = FPactive; break; default: diff --git a/sys/src/9/omap/dat.h b/sys/src/9/omap/dat.h index 466838cf6..c54d03204 100644 --- a/sys/src/9/omap/dat.h +++ b/sys/src/9/omap/dat.h @@ -27,6 +27,7 @@ enum { typedef struct Conf Conf; typedef struct Confmem Confmem; typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct ISAConf ISAConf; typedef struct Label Label; typedef struct Lock Lock; @@ -34,7 +35,6 @@ typedef struct Memcache Memcache; typedef struct MMMU MMMU; typedef struct Mach Mach; typedef u32int Mreg; /* Msr - bloody UART */ -typedef struct Notsave Notsave; typedef struct Page Page; typedef struct PhysUart PhysUart; typedef struct PMMU PMMU; @@ -69,13 +69,13 @@ struct Label uintptr pc; }; +/* + * emulated floating point + */ enum{ Nfpctlregs = 16, }; -/* - * emulated floating point - */ struct FPsave { ulong status; @@ -85,9 +85,12 @@ struct FPsave int fpstate; }; -/* - * FPsave.status - */ +struct PFPU +{ + int fpstate; + FPsave fpsave[1]; +}; + enum { FPinit, @@ -122,13 +125,6 @@ struct Conf int monitor; /* flag */ }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave { - int emptiness; -}; - /* * MMU stuff in Mach. */ diff --git a/sys/src/9/omap/fpiarm.c b/sys/src/9/omap/fpiarm.c index 8735f87ba..80b7ceae0 100644 --- a/sys/src/9/omap/fpiarm.c +++ b/sys/src/9/omap/fpiarm.c @@ -726,7 +726,7 @@ fpiarm(Ureg *ur) if(up == nil) panic("fpiarm not in a process"); - ufp = &up->fpsave; + ufp = up->fpsave; /* * because all the emulated fp state is in the proc structure, * it need not be saved/restored diff --git a/sys/src/9/pc/dat.h b/sys/src/9/pc/dat.h index 50265edb9..34a1841bc 100644 --- a/sys/src/9/pc/dat.h +++ b/sys/src/9/pc/dat.h @@ -3,14 +3,14 @@ typedef struct BIOS32ci BIOS32ci; typedef struct Conf Conf; typedef struct Confmem Confmem; typedef union FPsave FPsave; +typedef struct FPx87state FPx87state; typedef struct FPssestate FPssestate; -typedef struct FPstate FPstate; +typedef struct PFPU PFPU; typedef struct ISAConf ISAConf; typedef struct Label Label; typedef struct Lock Lock; typedef struct MMU MMU; typedef struct Mach Mach; -typedef struct Notsave Notsave; typedef struct PCArch PCArch; typedef struct Pcidev Pcidev; typedef struct PCMmap PCMmap; @@ -51,22 +51,7 @@ struct Label ulong pc; }; - -/* - * FPsave.status - */ -enum -{ - /* this is a state */ - FPinit= 0, - FPactive= 1, - FPinactive= 2, - - /* the following is a bit that can be or'd into the state */ - FPillegal= 0x100, -}; - -struct FPstate +struct FPx87state /* x87 fp state */ { ushort control; ushort r1; @@ -98,18 +83,30 @@ struct FPssestate /* SSE fp state */ ulong mxcsr; /* MXCSR register state */ ulong mxcsr_mask; /* MXCSR mask register */ uchar xregs[480]; /* extended registers */ - uchar alignpad[FPalign]; }; -/* - * the FP regs must be stored here, not somewhere pointed to from here. - * port code assumes this. - */ union FPsave { - FPstate; + FPx87state; FPssestate; }; +struct PFPU +{ + int fpstate; + FPsave *fpsave; +}; + +enum +{ + /* this is a state */ + FPinit= 0, + FPactive= 1, + FPinactive= 2, + + /* the following is a bit that can be or'd into the state */ + FPillegal= 0x100, +}; + struct Confmem { ulong base; @@ -164,16 +161,6 @@ struct PMMU void *vmx; }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave -{ - ulong svflags; - ulong svcs; - ulong svss; -}; - #include "../port/portdat.h" typedef struct { diff --git a/sys/src/9/pc/fns.h b/sys/src/9/pc/fns.h index 01d8fe36f..467cb2684 100644 --- a/sys/src/9/pc/fns.h +++ b/sys/src/9/pc/fns.h @@ -40,9 +40,7 @@ void fpoff(void); void (*fprestore)(FPsave*); void (*fpsave)(FPsave*); void fpsserestore(FPsave*); -void fpsserestore0(FPsave*); void fpssesave(FPsave*); -void fpssesave0(FPsave*); void fpx87restore(FPsave*); void fpx87restore0(FPsave*); void fpx87save(FPsave*); diff --git a/sys/src/9/pc/l.s b/sys/src/9/pc/l.s index e28ef9e95..217088ecb 100644 --- a/sys/src/9/pc/l.s +++ b/sys/src/9/pc/l.s @@ -622,13 +622,13 @@ TEXT fpclear(SB), $0 /* clear pending exceptions */ FPOFF RET -TEXT fpssesave0(SB), $0 /* save state and disable */ +TEXT fpssesave(SB), $0 /* save state and disable */ MOVL p+0(FP), AX FXSAVE 0(AX) /* no WAIT */ FPOFF RET -TEXT fpsserestore0(SB), $0 /* enable and restore state */ +TEXT fpsserestore(SB), $0 /* enable and restore state */ FPON MOVL p+0(FP), AX FXRSTOR 0(AX) diff --git a/sys/src/9/pc/main.c b/sys/src/9/pc/main.c index 5408e6982..6dbf76a3e 100644 --- a/sys/src/9/pc/main.c +++ b/sys/src/9/pc/main.c @@ -311,12 +311,8 @@ confinit(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) @@ -441,32 +437,6 @@ fpx87restore(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 */ @@ -524,9 +494,9 @@ matherror(Ureg*, void*) /* * 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); } /* @@ -535,9 +505,9 @@ matherror(Ureg*, void*) 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); } /* @@ -558,6 +528,8 @@ mathemu(Ureg *ureg, void*) fpinit(); if(fpsave == fpssesave) ldmxcsr(0); /* no simd exceptions on 386 */ + while(up->fpsave == nil) + up->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0); up->fpstate = FPactive; break; case FPinactive: @@ -568,13 +540,13 @@ mathemu(Ureg *ureg, void*) * 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: @@ -645,10 +617,12 @@ procfork(Proc *p) 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; } @@ -708,7 +682,7 @@ procsave(Proc *p) * until the process runs again and generates an * emulation fault to activate the FPU. */ - fpsave(&p->fpsave); + fpsave(p->fpsave); } p->fpstate = FPinactive; } diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c index fbc80024d..60b612d6d 100644 --- a/sys/src/9/pc/trap.c +++ b/sys/src/9/pc/trap.c @@ -854,7 +854,7 @@ notify(Ureg* ureg) return 0; if(up->fpstate == FPactive){ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal; diff --git a/sys/src/9/pc64/dat.h b/sys/src/9/pc64/dat.h index 662e47848..4dde0ec1b 100644 --- a/sys/src/9/pc64/dat.h +++ b/sys/src/9/pc64/dat.h @@ -2,15 +2,13 @@ typedef struct BIOS32si BIOS32si; typedef struct BIOS32ci BIOS32ci; typedef struct Conf Conf; typedef struct Confmem Confmem; -typedef union FPsave FPsave; -typedef struct Fxsave Fxsave; -typedef struct FPstate FPstate; +typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct ISAConf ISAConf; typedef struct Label Label; typedef struct Lock Lock; typedef struct MMU MMU; typedef struct Mach Mach; -typedef struct Notsave Notsave; typedef struct PCArch PCArch; typedef struct Pcidev Pcidev; typedef struct PCMmap PCMmap; @@ -51,25 +49,8 @@ struct Label uintptr pc; }; -/* - * FPsave.status - */ -enum +struct FPsave { - /* this is a state */ - FPinit= 0, - FPactive= 1, - FPinactive= 2, - - /* the following is a bit that can be or'd into the state */ - FPillegal= 0x100, -}; - -/* - * the FP regs must be stored here, not somewhere pointed to from here. - * port code assumes this. - */ -struct Fxsave { u16int fcw; /* x87 control word */ u16int fsw; /* x87 status word */ u8int ftw; /* x87 tag word */ @@ -84,9 +65,21 @@ struct Fxsave { uchar ign[96]; /* reserved, ignored */ }; -union FPsave { - uchar align[512+15]; - Fxsave; +struct PFPU +{ + int fpstate; + FPsave *fpsave; +}; + +enum +{ + /* this is a state */ + FPinit= 0, + FPactive= 1, + FPinactive= 2, + + /* the following is a bit that can be or'd into the state */ + FPillegal= 0x100, }; struct Confmem @@ -149,16 +142,6 @@ struct PMMU void *vmx; }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave -{ - ulong svflags; - ulong svcs; - ulong svss; -}; - #include "../port/portdat.h" typedef struct { diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index cc85fe76e..77a45f396 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -392,15 +392,13 @@ reboot(void *entry, void *code, ulong size) * SIMD Floating Point. * Assembler support to get at the individual instructions * is in l.s. - * There are opportunities to be lazier about saving and - * restoring the state and allocating the storage needed. */ extern void _clts(void); extern void _fldcw(u16int); extern void _fnclex(void); extern void _fninit(void); -extern void _fxrstor(Fxsave*); -extern void _fxsave(Fxsave*); +extern void _fxrstor(void*); +extern void _fxsave(void*); extern void _fwait(void); extern void _ldmxcsr(u32int); extern void _stts(void); @@ -418,24 +416,16 @@ fpx87restore(FPsave*) } void -fpssesave(FPsave *fps) +fpssesave(FPsave *s) { - Fxsave *fx = (Fxsave*)ROUND(((uintptr)fps), FPalign); - - _fxsave(fx); + _fxsave(s); _stts(); - if(fx != (Fxsave*)fps) - memmove((Fxsave*)fps, fx, sizeof(Fxsave)); } void -fpsserestore(FPsave *fps) +fpsserestore(FPsave *s) { - Fxsave *fx = (Fxsave*)ROUND(((uintptr)fps), FPalign); - - if(fx != (Fxsave*)fps) - memmove(fx, (Fxsave*)fps, sizeof(Fxsave)); _clts(); - _fxrstor(fx); + _fxrstor(s); } static char* mathmsg[] = @@ -488,9 +478,9 @@ matherror(Ureg*, void*) /* * Save FPU state to check out the error. */ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; - mathnote(up->fpsave.fsw, up->fpsave.rip); + mathnote(up->fpsave->fsw, up->fpsave->rip); } /* @@ -499,9 +489,9 @@ matherror(Ureg*, void*) 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); } void @@ -538,6 +528,8 @@ mathemu(Ureg *ureg, void*) switch(up->fpstate){ case FPinit: fpinit(); + while(up->fpsave == nil) + up->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0); up->fpstate = FPactive; break; case FPinactive: @@ -548,13 +540,13 @@ mathemu(Ureg *ureg, void*) * 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.rip); + mathnote(status, up->fpsave->rip); break; } - fprestore(&up->fpsave); + fprestore(up->fpsave); up->fpstate = FPactive; break; case FPactive: @@ -605,10 +597,12 @@ procfork(Proc *p) 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; } splx(s); @@ -665,7 +659,7 @@ procsave(Proc *p) * until the process runs again and generates an * emulation fault to activate the FPU. */ - fpsave(&p->fpsave); + fpsave(p->fpsave); } p->fpstate = FPinactive; } diff --git a/sys/src/9/pc64/trap.c b/sys/src/9/pc64/trap.c index 4dec706d5..ced545deb 100644 --- a/sys/src/9/pc64/trap.c +++ b/sys/src/9/pc64/trap.c @@ -823,7 +823,7 @@ notify(Ureg* ureg) return 0; if(up->fpstate == FPactive){ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal; diff --git a/sys/src/9/port/devproc.c b/sys/src/9/port/devproc.c index 85bcbcdee..5fb875f8a 100644 --- a/sys/src/9/port/devproc.c +++ b/sys/src/9/port/devproc.c @@ -1012,7 +1012,9 @@ procread(Chan *c, void *va, long n, vlong off) goto regread; case Qfpregs: - rptr = (uchar*)&p->fpsave; + if(p->fpstate != FPinactive) + error(Enoreg); + rptr = (uchar*)p->fpsave; rsize = sizeof(FPsave); regread: if(rptr == nil) @@ -1232,7 +1234,9 @@ procwrite(Chan *c, void *va, long n, vlong off) n = 0; else if(offset+n > sizeof(FPsave)) n = sizeof(FPsave) - offset; - memmove((uchar*)&p->fpsave+offset, va, n); + if(p->fpstate != FPinactive || p->fpsave == nil) + error(Enoreg); + memmove((uchar*)p->fpsave+offset, va, n); break; case Qctl: diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h index 34e6a7d3f..9cb495128 100644 --- a/sys/src/9/port/portdat.h +++ b/sys/src/9/port/portdat.h @@ -676,6 +676,8 @@ struct Proc Fgrp *closingfgrp; /* used during teardown */ ulong parentpid; + + int insyscall; ulong time[6]; /* User, Sys, Real; child U, S, R */ uvlong kentry; /* Kernel entry time stamp (for profiling) */ @@ -689,9 +691,6 @@ struct Proc */ vlong pcycles; - int insyscall; - int fpstate; - QLock debug; /* to access debugging elements of User */ Proc *pdbg; /* the debugging process */ ulong procmode; /* proc device default file mode */ @@ -720,9 +719,8 @@ struct Proc void (*kpfun)(void*); void *kparg; - FPsave fpsave; /* address of this is known by db */ - int scallnr; /* sys call number - known by db */ - Sargs s; /* address of this is known by db */ + int scallnr; /* sys call number */ + Sargs s; /* syscall arguments */ int nerrlab; Label errlab[NERR]; char *syserrstr; /* last error from a system call, errbuf0 or 1 */ @@ -766,17 +764,14 @@ struct Proc void *ureg; /* User registers for notes */ void *dbgreg; /* User registers for devproc */ - Notsave; - /* - * machine specific MMU - */ - PMMU; + PFPU; /* machine specific fpu state */ + PMMU; /* machine specific mmu state */ char *syscalltrace; /* syscall trace */ - Watchpt *watchpt; /* watchpoints */ - int nwatchpt; + Watchpt *watchpt; /* watchpoints */ + int nwatchpt; }; enum diff --git a/sys/src/9/ppc/dat.h b/sys/src/9/ppc/dat.h index 6589beb44..954ca1f89 100644 --- a/sys/src/9/ppc/dat.h +++ b/sys/src/9/ppc/dat.h @@ -1,11 +1,12 @@ typedef struct Conf Conf; +typedef struct Confmem Confmem; typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct ISAConf ISAConf; typedef struct Imap Imap; typedef struct Label Label; typedef struct Lock Lock; typedef struct Mach Mach; -typedef struct Notsave Notsave; typedef struct PCArch PCArch; typedef struct PMMU PMMU; typedef struct Page Page; @@ -14,6 +15,7 @@ typedef struct Proc Proc; typedef struct Sys Sys; typedef struct Ureg Ureg; typedef struct Vctl Vctl; +typedef long Tval; #pragma incomplete Ureg #pragma incomplete Imap @@ -45,19 +47,6 @@ struct Label ulong pc; }; -/* - * Proc.fpstate - */ -enum -{ - /* Floating point states */ - FPinit = 0, - FPactive = 1, - FPinactive = 2, - /* Bit that's or-ed in during note handling (FP is illegal in note handlers) */ - FPillegal = 0x100, -}; - /* * This structure must agree with fpsave and fprestore asm routines */ @@ -73,15 +62,36 @@ struct FPsave }; }; +struct PFPU +{ + int fpstate; + FPsave fpsave[1]; +}; + +enum +{ + /* Floating point states */ + FPinit = 0, + FPactive = 1, + FPinactive = 2, + /* Bit that's or-ed in during note handling (FP is illegal in note handlers) */ + FPillegal = 0x100, +}; + +struct Confmem +{ + ulong base; + ulong npage; + ulong kbase; + ulong klimit; +}; + struct Conf { ulong nmach; /* processors */ ulong nproc; /* processes */ - ulong npage0; /* total physical pages of memory */ - ulong npage1; /* total physical pages of memory */ + Confmem mem[2]; ulong npage; /* total physical pages of memory */ - ulong base0; /* base of bank 0 */ - ulong base1; /* base of bank 1 */ ulong upages; /* user page pool */ ulong nimage; /* number of page cache image headers */ ulong nswap; /* number of swap pages */ @@ -102,14 +112,6 @@ struct PMMU Ureg *mmureg; /* pointer to ureg structure */ }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave -{ - ulong UNUSED; -}; - #include "../port/portdat.h" /* diff --git a/sys/src/9/ppc/main.c b/sys/src/9/ppc/main.c index 9beb2ed09..5440fedae 100644 --- a/sys/src/9/ppc/main.c +++ b/sys/src/9/ppc/main.c @@ -292,7 +292,7 @@ procsave(Proc *p) p->kentry -= t; if(p->fpstate == FPactive){ if(p->state != Moribund) - fpsave(&up->fpsave); + fpsave(up->fpsave); p->fpstate = FPinactive; } } diff --git a/sys/src/9/ppc/mkfile b/sys/src/9/ppc/mkfile index e18b21b54..50416598d 100644 --- a/sys/src/9/ppc/mkfile +++ b/sys/src/9/ppc/mkfile @@ -101,6 +101,6 @@ init.h: ../port/initcode.c init9.s $AS init9.s $LD -l -s -R4 -o init.out init9.$O initcode.$O /power/lib/libc.a {echo 'uchar initcode[]={' - strip < init.out | xd -1x | + init.h diff --git a/sys/src/9/ppc/trap.c b/sys/src/9/ppc/trap.c index c7a5dac4f..7cc28c101 100644 --- a/sys/src/9/ppc/trap.c +++ b/sys/src/9/ppc/trap.c @@ -243,7 +243,7 @@ trap(Ureg *ureg) up->fpstate = FPactive; break; case FPinactive: - fprestore(&up->fpsave); + fprestore(up->fpsave); up->fpstate = FPactive; break; case FPactive: @@ -711,7 +711,7 @@ notify(Ureg* ur) return 0; if(up->fpstate == FPactive){ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal; diff --git a/sys/src/9/sgi/dat.h b/sys/src/9/sgi/dat.h index 800ed7182..741ca5655 100644 --- a/sys/src/9/sgi/dat.h +++ b/sys/src/9/sgi/dat.h @@ -1,6 +1,7 @@ typedef struct Conf Conf; typedef struct Confmem Confmem; typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct KMap KMap; typedef struct Lance Lance; typedef struct Lancemem Lancemem; @@ -8,7 +9,6 @@ typedef struct Label Label; typedef struct Lock Lock; typedef struct Mach Mach; typedef struct MMU MMU; -typedef struct Notsave Notsave; typedef struct PMMU PMMU; typedef struct Softtlb Softtlb; typedef struct Ureg Ureg; @@ -73,18 +73,6 @@ struct Conf /* * floating point registers */ -enum -{ - /* floating point state */ - FPinit, - FPactive, - FPinactive, - FPemu, - - /* bit meaning floating point illegal */ - FPillegal= 0x100, -}; - enum { Nfpregs = 32, /* floats; half as many doubles */ }; @@ -111,6 +99,24 @@ struct FPsave int fpcnt; /* how many consecutive at that addr */ }; +struct PFPU +{ + int fpstate; + FPsave fpsave[1]; +}; + +enum +{ + /* floating point state */ + FPinit, + FPactive, + FPinactive, + FPemu, + + /* bit meaning floating point illegal */ + FPillegal= 0x100, +}; + /* * mmu goo in the Proc structure */ @@ -119,14 +125,6 @@ struct PMMU int pidonmach[MAXMACH]; }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave -{ - ulong nonempty; -}; - #include "../port/portdat.h" struct Mach diff --git a/sys/src/9/sgi/fptrap.c b/sys/src/9/sgi/fptrap.c index 82c61bbd3..9d1c22aec 100644 --- a/sys/src/9/sgi/fptrap.c +++ b/sys/src/9/sgi/fptrap.c @@ -29,7 +29,7 @@ fptrap(Ureg *ur) { ulong iw, npc; - if((up->fpsave.fpstatus&(1<<17)) == 0) + if((up->fpsave->fpstatus&(1<<17)) == 0) return; if(ur->cause & (1<<31)) @@ -41,7 +41,7 @@ fptrap(Ureg *ur) return; if(ur->cause & (1<<31)){ - npc = branch(ur, up->fpsave.fpstatus); + npc = branch(ur, up->fpsave->fpstatus); if(npc == 0) return; ur->pc = npc; @@ -49,7 +49,7 @@ fptrap(Ureg *ur) else ur->pc += 4; - up->fpsave.fpstatus &= ~(1<<17); + up->fpsave->fpstatus &= ~(1<<17); } static void @@ -107,8 +107,8 @@ fpunimp(ulong iw) ft = (iw>>16) & ((1<<5)-1); fs = (iw>>11) & ((1<<5)-1); fd = (iw>>6) & ((1<<5)-1); - unpack(&up->fpsave, fmt, fs, &ss, &es); - unpack(&up->fpsave, fmt, ft, &st, &et); + unpack(up->fpsave, fmt, fs, &ss, &es); + unpack(up->fpsave, fmt, ft, &st, &et); ed = 0; maxe = 0; maxm = 0; @@ -124,11 +124,11 @@ fpunimp(ulong iw) } switch(op){ case ABS: - up->fpsave.reg[fd] &= ~0x80000000; + up->fpsave->reg[fd] &= ~0x80000000; return 1; case NEG: - up->fpsave.reg[fd] ^= 0x80000000; + up->fpsave->reg[fd] ^= 0x80000000; return 1; case SUB: @@ -164,9 +164,9 @@ fpunimp(ulong iw) return 0; } if(ed <= -(maxe-5)){ /* guess: underflow */ - zeroreg(&up->fpsave, fmt, fd, sd); + zeroreg(up->fpsave, fmt, fd, sd); /* Set underflow exception and sticky */ - up->fpsave.fpstatus |= (1<<3)|(1<<13); + up->fpsave->fpstatus |= (1<<3)|(1<<13); return 1; } return 0; diff --git a/sys/src/9/sgi/main.c b/sys/src/9/sgi/main.c index f1c239e3a..dea690f29 100644 --- a/sys/src/9/sgi/main.c +++ b/sys/src/9/sgi/main.c @@ -396,7 +396,7 @@ void procsetup(Proc *p) { p->fpstate = FPinit; - p->fpsave = initfp; + memmove(p->fpsave, &initfp, sizeof(FPsave)); cycles(&p->kentry); p->pcycles = -p->kentry; @@ -413,11 +413,11 @@ procfork(Proc *p) s = splhi(); switch(up->fpstate & ~FPillegal){ case FPactive: - savefpregs(&up->fpsave); + savefpregs(up->fpsave); up->fpstate = FPinactive; /* wet floor */ case FPinactive: - p->fpsave = up->fpsave; + memmove(p->fpsave, up->fpsave, sizeof(FPsave)); p->fpstate = FPinactive; } splx(s); @@ -430,7 +430,7 @@ procsave(Proc *p) if(p->fpstate == FPactive){ if(p->state != Moribund) { - savefpregs(&p->fpsave); + savefpregs(p->fpsave); p->fpstate = FPinactive; } } diff --git a/sys/src/9/sgi/trap.c b/sys/src/9/sgi/trap.c index 4c59730f6..588e6861d 100644 --- a/sys/src/9/sgi/trap.c +++ b/sys/src/9/sgi/trap.c @@ -212,7 +212,7 @@ trap(Ureg *ur) if(!user) goto Default; if(up->fpstate == FPactive){ - savefpregs(&up->fpsave); + savefpregs(up->fpsave); up->fpstate = FPinactive; } clrfpintr(); @@ -257,7 +257,7 @@ trap(Ureg *ur) break; } if(up->fpstate == FPinit || up->fpstate == FPinactive){ - restfpregs(&up->fpsave, up->fpsave.fpstatus&~FPEXPMASK); + restfpregs(up->fpsave, up->fpsave->fpstatus&~FPEXPMASK); up->fpstate = FPactive; ur->status |= CU1; break; @@ -289,7 +289,7 @@ trap(Ureg *ur) } if(fpchk) { - fpfcr31 = up->fpsave.fpstatus; + fpfcr31 = up->fpsave->fpstatus; if((fpfcr31>>12) & ((fpfcr31>>7)|0x20) & 0x3f) { spllo(); fpexcep = fpexcname(ur, fpfcr31, buf1, sizeof buf1); @@ -501,7 +501,7 @@ notify(Ureg *ur) return 0; if(up->fpstate == FPactive){ - savefpregs(&up->fpsave); + savefpregs(up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal; diff --git a/sys/src/9/teg2/dat.h b/sys/src/9/teg2/dat.h index 0aa54a7d0..30dd4b5eb 100644 --- a/sys/src/9/teg2/dat.h +++ b/sys/src/9/teg2/dat.h @@ -24,6 +24,7 @@ enum { typedef struct Conf Conf; typedef struct Confmem Confmem; typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct ISAConf ISAConf; typedef struct Isolated Isolated; typedef struct Label Label; @@ -33,7 +34,6 @@ typedef struct Memcache Memcache; typedef struct MMMU MMMU; typedef struct Mach Mach; typedef u32int Mreg; /* Msr - bloody UART */ -typedef struct Notsave Notsave; typedef struct Page Page; typedef struct Pcisiz Pcisiz; typedef struct Pcidev Pcidev; @@ -72,14 +72,14 @@ struct Label uintptr pc; }; +/* + * emulated or vfp3 floating point + */ enum { Maxfpregs = 32, /* could be 16 or 32, see Mach.fpnregs */ Nfpctlregs = 16, }; -/* - * emulated or vfp3 floating point - */ struct FPsave { ulong status; @@ -94,9 +94,12 @@ struct FPsave uintptr pc; /* of failed fp instr. */ }; -/* - * FPsave.fpstate - */ +struct PFPU +{ + int fpstate; + FPsave fpsave[1]; +}; + enum { FPinit, @@ -135,13 +138,6 @@ struct Conf int monitor; /* flag */ }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave { - int emptiness; -}; - /* * MMU stuff in Mach. */ diff --git a/sys/src/9/teg2/fpiarm.c b/sys/src/9/teg2/fpiarm.c index d92455328..cefddc3e5 100644 --- a/sys/src/9/teg2/fpiarm.c +++ b/sys/src/9/teg2/fpiarm.c @@ -650,7 +650,7 @@ fpiarm(Ureg *ur) if(up == nil) panic("fpiarm not in a process"); - ufp = &up->fpsave; + ufp = up->fpsave; /* * because all the emulated fp state is in the proc structure, * it need not be saved/restored diff --git a/sys/src/9/xen/main.c b/sys/src/9/xen/main.c index f5e0adf07..e28716a28 100644 --- a/sys/src/9/xen/main.c +++ b/sys/src/9/xen/main.c @@ -450,7 +450,7 @@ mathnote(void) ulong status; char *msg, note[ERRMAX]; - status = up->fpsave.status; + status = up->fpsave->status; /* * Some attention should probably be paid here to the @@ -473,7 +473,7 @@ mathnote(void) msg = "invalid operation"; } snprint(note, sizeof note, "sys: fp: %s fppc=0x%lux status=0x%lux", - msg, up->fpsave.pc, status); + msg, up->fpsave->pc, status); postnote(up, 1, note, NDebug); } @@ -493,12 +493,12 @@ matherror(Ureg *ur, void*) /* * save floating point state to check out error */ - fpenv(&up->fpsave); + 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); + up->fpsave->status, up->fpsave->pc, ur->pc); } /* @@ -515,6 +515,8 @@ mathemu(Ureg *ureg, void*) switch(up->fpstate){ case FPinit: fpinit(); + while(up->fpsave == nil) + up->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0); up->fpstate = FPactive; break; case FPinactive: @@ -525,11 +527,11 @@ mathemu(Ureg *ureg, void*) * More attention should probably be paid here to the * exception masks and error summary. */ - if((up->fpsave.status & ~up->fpsave.control) & 0x07F){ + if((up->fpsave->status & ~up->fpsave->control) & 0x07F){ mathnote(); break; } - fprestore(&up->fpsave); + fprestore(up->fpsave); up->fpstate = FPactive; break; case FPactive: @@ -580,10 +582,12 @@ procfork(Proc *p) 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; } splx(s); @@ -622,7 +626,7 @@ procsave(Proc *p) * until the process runs again and generates an * emulation fault to activate the FPU. */ - fpsave(&p->fpsave); + fpsave(p->fpsave); } p->fpstate = FPinactive; } diff --git a/sys/src/9/xen/trap.c b/sys/src/9/xen/trap.c index d524b403c..1ab080c60 100644 --- a/sys/src/9/xen/trap.c +++ b/sys/src/9/xen/trap.c @@ -674,7 +674,7 @@ syscall(Ureg* ureg) scallnr = ureg->ax; up->scallnr = scallnr; if(scallnr == RFORK && up->fpstate == FPactive){ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; } spllo(); @@ -764,7 +764,7 @@ notify(Ureg* ureg) return 0; if(up->fpstate == FPactive){ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal; diff --git a/sys/src/9/zynq/dat.h b/sys/src/9/zynq/dat.h index 7431ed803..59b60ba19 100644 --- a/sys/src/9/zynq/dat.h +++ b/sys/src/9/zynq/dat.h @@ -1,13 +1,13 @@ typedef struct Conf Conf; typedef struct Confmem Confmem; typedef struct FPsave FPsave; +typedef struct PFPU PFPU; typedef struct L1 L1; typedef struct Label Label; typedef struct Lock Lock; typedef struct KMap KMap; typedef struct MMMU MMMU; typedef struct Mach Mach; -typedef struct Notsave Notsave; typedef struct Page Page; typedef struct Proc Proc; typedef struct PMMU PMMU; @@ -43,9 +43,12 @@ struct FPsave uchar regs[256]; }; -/* - * FPsave.status - */ +struct PFPU +{ + int fpstate; + FPsave fpsave[1]; +}; + enum { FPinit, @@ -79,13 +82,6 @@ struct Conf int monitor; }; -/* - * things saved in the Proc structure during a notify - */ -struct Notsave { - int emptiness; -}; - /* * MMU stuff in proc */ diff --git a/sys/src/9/zynq/main.c b/sys/src/9/zynq/main.c index c281a5330..9056f57d8 100644 --- a/sys/src/9/zynq/main.c +++ b/sys/src/9/zynq/main.c @@ -50,10 +50,10 @@ procfork(Proc *p) s = splhi(); switch(up->fpstate & ~FPillegal){ case FPactive: - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; case FPinactive: - p->fpsave = up->fpsave; + memmove(p->fpsave, up->fpsave, sizeof(FPsave)); p->fpstate = FPinactive; } splx(s); diff --git a/sys/src/9/zynq/trap.c b/sys/src/9/zynq/trap.c index 510860b63..cb35b4a9d 100644 --- a/sys/src/9/zynq/trap.c +++ b/sys/src/9/zynq/trap.c @@ -134,7 +134,7 @@ mathtrap(Ureg *, ulong) break; case FPinactive: s = splhi(); - fprestore(&up->fpsave); + fprestore(up->fpsave); up->fpstate = FPactive; splx(s); break; @@ -304,7 +304,7 @@ notify(Ureg *ureg) return 0; if(up->fpstate == FPactive){ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal; @@ -517,7 +517,7 @@ procsave(Proc *p) if(p->state == Moribund) fpclear(); else - fpsave(&p->fpsave); + fpsave(p->fpsave); p->fpstate = FPinactive; } cycles(&t);