ref: 24057fd4f494a00573d34adeaa7042721c1a06a0
parent: 04ce485f1b4453335db70b4a1b5d2c96458db3c1
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Nov 4 16:08:22 EDT 2017
kernel: introduce per process FPU struct (PFPU) for more flexible machine specific fpu handling introducing the PFPU structue which allows the machine specific code some flexibility on how to handle the FPU process state. for example, in the pc and pc64 kernel, the FPsave structure is arround 512 bytes. with avx512, it could grow up to 2K. instead of embedding that into the Proc strucutre, it is more effective to allocate it on first use of the fpu, as most processes do not use simd or floating point in the first place. also, the FPsave structure has special 16 byte alignment constraint, which further favours dynamic allocation. this gets rid of the memmoves in pc/pc64 kernels for the aligment. there is also devproc, which is now checking if the fpsave area is actually valid before reading it, avoiding debuggers to see garbage data. the Notsave structure is gone now, as it was not used on any machine.
--- a/sys/src/9/bcm/dat.h
+++ b/sys/src/9/bcm/dat.h
@@ -15,6 +15,7 @@
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;
@@ -21,7 +22,6 @@
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 @@
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 @@
uintptr pc; /* of failed fp instr. */
};
-/*
- * FPsave.fpstate
- */
+struct PFPU
+{
+ int fpstate;
+ FPsave fpsave[1];
+};
+
enum
{
FPinit,
@@ -117,13 +120,6 @@
ulong hz; /* processor cycle freq */
ulong mhz;
int monitor; /* flag */
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave {
- int emptiness;
};
/*
--- a/sys/src/9/bcm/fpiarm.c
+++ b/sys/src/9/bcm/fpiarm.c
@@ -650,7 +650,7 @@
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
--- a/sys/src/9/bcm/vfp3.c
+++ b/sys/src/9/bcm/vfp3.c
@@ -222,7 +222,7 @@
fpunotify(Ureg*)
{
if(up->fpstate == FPactive){
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
@@ -259,11 +259,11 @@
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 @@
* 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 @@
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 @@
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 @@
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 @@
* 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;
}
--- a/sys/src/9/kw/dat.h
+++ b/sys/src/9/kw/dat.h
@@ -1,6 +1,7 @@
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;
@@ -7,7 +8,6 @@
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 @@
uintptr pc;
};
+/*
+ * emulated floating point
+ */
enum{
Nfpctlregs = 16,
};
-/*
- * emulated floating point
- */
struct FPsave
{
ulong status;
@@ -61,9 +61,12 @@
int fpstate;
};
-/*
- * FPsave.status
- */
+struct PFPU
+{
+ int fpstate;
+ FPsave fpsave[1];
+};
+
enum
{
FPinit,
@@ -96,13 +99,6 @@
int nswppo; /* max # of pageouts per segment pass */
// ulong hz; /* processor cycle freq */
// ulong mhz;
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave {
- int emptiness;
};
/*
--- a/sys/src/9/kw/fpiarm.c
+++ b/sys/src/9/kw/fpiarm.c
@@ -726,7 +726,7 @@
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
--- 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;
@@ -46,16 +46,6 @@
};
/*
- * Proc.fpstate
- */
-enum
-{
- FPinit,
- FPactive,
- FPinactive,
-};
-
-/*
* This structure must agree with fpsave and fprestore asm routines
*/
struct FPsave
@@ -70,6 +60,19 @@
};
};
+struct PFPU
+{
+ int fpstate;
+ FPsave fpsave[1];
+};
+
+enum
+{
+ FPinit,
+ FPactive,
+ FPinactive,
+};
+
struct Confmem
{
ulong base;
@@ -101,14 +104,6 @@
struct PMMU
{
int mmupid;
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave
-{
- ulong UNUSED;
};
#include "../port/portdat.h"
--- a/sys/src/9/mtx/main.c
+++ b/sys/src/9/mtx/main.c
@@ -241,7 +241,7 @@
{
if(p->fpstate == FPactive){
if(p->state != Moribund)
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
p->fpstate = FPinactive;
}
}
--- a/sys/src/9/mtx/trap.c
+++ b/sys/src/9/mtx/trap.c
@@ -246,7 +246,7 @@
up->fpstate = FPactive;
break;
case FPinactive:
- fprestore(&up->fpsave);
+ fprestore(up->fpsave);
up->fpstate = FPactive;
break;
default:
--- a/sys/src/9/omap/dat.h
+++ b/sys/src/9/omap/dat.h
@@ -27,6 +27,7 @@
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 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 @@
uintptr pc;
};
+/*
+ * emulated floating point
+ */
enum{
Nfpctlregs = 16,
};
-/*
- * emulated floating point
- */
struct FPsave
{
ulong status;
@@ -85,9 +85,12 @@
int fpstate;
};
-/*
- * FPsave.status
- */
+struct PFPU
+{
+ int fpstate;
+ FPsave fpsave[1];
+};
+
enum
{
FPinit,
@@ -120,13 +123,6 @@
ulong hz; /* processor cycle freq */
ulong mhz;
int monitor; /* flag */
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave {
- int emptiness;
};
/*
--- a/sys/src/9/omap/fpiarm.c
+++ b/sys/src/9/omap/fpiarm.c
@@ -726,7 +726,7 @@
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
--- a/sys/src/9/pc/dat.h
+++ b/sys/src/9/pc/dat.h
@@ -3,14 +3,14 @@
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,23 +51,8 @@
ulong pc;
};
-
-/*
- * FPsave.status
- */
-enum
+struct FPx87state /* x87 fp state */
{
- /* 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
-{
ushort control;
ushort r1;
ushort status;
@@ -98,18 +83,30 @@
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;
@@ -162,16 +159,6 @@
u32int dr[8]; /* debug registers */
void *vmx;
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave
-{
- ulong svflags;
- ulong svcs;
- ulong svss;
};
#include "../port/portdat.h"
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -40,9 +40,7 @@
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*);
--- a/sys/src/9/pc/l.s
+++ b/sys/src/9/pc/l.s
@@ -622,13 +622,13 @@
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)
--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -311,12 +311,8 @@
}
/*
- * 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 @@
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 @@
/*
* 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 @@
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 @@
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 @@
* 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 @@
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 @@
* until the process runs again and generates an
* emulation fault to activate the FPU.
*/
- fpsave(&p->fpsave);
+ fpsave(p->fpsave);
}
p->fpstate = FPinactive;
}
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -854,7 +854,7 @@
return 0;
if(up->fpstate == FPactive){
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
--- a/sys/src/9/pc64/dat.h
+++ b/sys/src/9/pc64/dat.h
@@ -2,15 +2,13 @@
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 @@
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,11 +65,23 @@
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
{
uintptr base;
@@ -147,16 +140,6 @@
u64int dr[8];
void *vmx;
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave
-{
- ulong svflags;
- ulong svcs;
- ulong svss;
};
#include "../port/portdat.h"
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -392,15 +392,13 @@
* 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 @@
}
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 @@
/*
* 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 @@
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 @@
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 @@
* 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 @@
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 @@
* until the process runs again and generates an
* emulation fault to activate the FPU.
*/
- fpsave(&p->fpsave);
+ fpsave(p->fpsave);
}
p->fpstate = FPinactive;
}
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -823,7 +823,7 @@
return 0;
if(up->fpstate == FPactive){
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -1012,7 +1012,9 @@
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 @@
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:
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -676,6 +676,8 @@
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 @@
*/
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 @@
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 @@
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
--- 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 Sys Sys;
typedef struct Ureg Ureg;
typedef struct Vctl Vctl;
+typedef long Tval;
#pragma incomplete Ureg
#pragma incomplete Imap
@@ -46,19 +48,6 @@
};
/*
- * 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
*/
struct FPsave
@@ -73,15 +62,36 @@
};
};
+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 */
@@ -100,14 +110,6 @@
{
int mmupid;
Ureg *mmureg; /* pointer to ureg structure */
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave
-{
- ulong UNUSED;
};
#include "../port/portdat.h"
--- a/sys/src/9/ppc/main.c
+++ b/sys/src/9/ppc/main.c
@@ -292,7 +292,7 @@
p->kentry -= t;
if(p->fpstate == FPactive){
if(p->state != Moribund)
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
p->fpstate = FPinactive;
}
}
--- a/sys/src/9/ppc/mkfile
+++ b/sys/src/9/ppc/mkfile
@@ -101,6 +101,6 @@
$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.out xd -1x |
sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
echo '};'} > init.h
--- a/sys/src/9/ppc/trap.c
+++ b/sys/src/9/ppc/trap.c
@@ -243,7 +243,7 @@
up->fpstate = FPactive;
break;
case FPinactive:
- fprestore(&up->fpsave);
+ fprestore(up->fpsave);
up->fpstate = FPactive;
break;
case FPactive:
@@ -711,7 +711,7 @@
return 0;
if(up->fpstate == FPactive){
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
--- 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 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 @@
/*
* 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,20 +99,30 @@
int fpcnt; /* how many consecutive at that addr */
};
-/*
- * mmu goo in the Proc structure
- */
-struct PMMU
+struct PFPU
{
- int pidonmach[MAXMACH];
+ int fpstate;
+ FPsave fpsave[1];
};
+enum
+{
+ /* floating point state */
+ FPinit,
+ FPactive,
+ FPinactive,
+ FPemu,
+
+ /* bit meaning floating point illegal */
+ FPillegal= 0x100,
+};
+
/*
- * things saved in the Proc structure during a notify
+ * mmu goo in the Proc structure
*/
-struct Notsave
+struct PMMU
{
- ulong nonempty;
+ int pidonmach[MAXMACH];
};
#include "../port/portdat.h"
--- a/sys/src/9/sgi/fptrap.c
+++ b/sys/src/9/sgi/fptrap.c
@@ -29,7 +29,7 @@
{
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 @@
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 @@
else
ur->pc += 4;
- up->fpsave.fpstatus &= ~(1<<17);
+ up->fpsave->fpstatus &= ~(1<<17);
}
static void
@@ -107,8 +107,8 @@
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 @@
}
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 @@
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;
--- a/sys/src/9/sgi/main.c
+++ b/sys/src/9/sgi/main.c
@@ -396,7 +396,7 @@
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 @@
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 @@
if(p->fpstate == FPactive){
if(p->state != Moribund) {
- savefpregs(&p->fpsave);
+ savefpregs(p->fpsave);
p->fpstate = FPinactive;
}
}
--- a/sys/src/9/sgi/trap.c
+++ b/sys/src/9/sgi/trap.c
@@ -212,7 +212,7 @@
if(!user)
goto Default;
if(up->fpstate == FPactive){
- savefpregs(&up->fpsave);
+ savefpregs(up->fpsave);
up->fpstate = FPinactive;
}
clrfpintr();
@@ -257,7 +257,7 @@
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 @@
}
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 @@
return 0;
if(up->fpstate == FPactive){
- savefpregs(&up->fpsave);
+ savefpregs(up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
--- a/sys/src/9/teg2/dat.h
+++ b/sys/src/9/teg2/dat.h
@@ -24,6 +24,7 @@
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 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 @@
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 @@
uintptr pc; /* of failed fp instr. */
};
-/*
- * FPsave.fpstate
- */
+struct PFPU
+{
+ int fpstate;
+ FPsave fpsave[1];
+};
+
enum
{
FPinit,
@@ -133,13 +136,6 @@
ulong hz; /* processor cycle freq */
ulong mhz;
int monitor; /* flag */
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave {
- int emptiness;
};
/*
--- a/sys/src/9/teg2/fpiarm.c
+++ b/sys/src/9/teg2/fpiarm.c
@@ -650,7 +650,7 @@
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
--- a/sys/src/9/xen/main.c
+++ b/sys/src/9/xen/main.c
@@ -450,7 +450,7 @@
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 @@
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 @@
/*
* 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 @@
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 @@
* 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 @@
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 @@
* until the process runs again and generates an
* emulation fault to activate the FPU.
*/
- fpsave(&p->fpsave);
+ fpsave(p->fpsave);
}
p->fpstate = FPinactive;
}
--- a/sys/src/9/xen/trap.c
+++ b/sys/src/9/xen/trap.c
@@ -674,7 +674,7 @@
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 @@
return 0;
if(up->fpstate == FPactive){
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
--- a/sys/src/9/zynq/dat.h
+++ b/sys/src/9/zynq/dat.h
@@ -1,6 +1,7 @@
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;
@@ -7,7 +8,6 @@
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 @@
uchar regs[256];
};
-/*
- * FPsave.status
- */
+struct PFPU
+{
+ int fpstate;
+ FPsave fpsave[1];
+};
+
enum
{
FPinit,
@@ -77,13 +80,6 @@
ulong nswap; /* number of swap pages */
int nswppo; /* max # of pageouts per segment pass */
int monitor;
-};
-
-/*
- * things saved in the Proc structure during a notify
- */
-struct Notsave {
- int emptiness;
};
/*
--- a/sys/src/9/zynq/main.c
+++ b/sys/src/9/zynq/main.c
@@ -50,10 +50,10 @@
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);
--- a/sys/src/9/zynq/trap.c
+++ b/sys/src/9/zynq/trap.c
@@ -134,7 +134,7 @@
break;
case FPinactive:
s = splhi();
- fprestore(&up->fpsave);
+ fprestore(up->fpsave);
up->fpstate = FPactive;
splx(s);
break;
@@ -304,7 +304,7 @@
return 0;
if(up->fpstate == FPactive){
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;
@@ -517,7 +517,7 @@
if(p->state == Moribund)
fpclear();
else
- fpsave(&p->fpsave);
+ fpsave(p->fpsave);
p->fpstate = FPinactive;
}
cycles(&t);