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.
This commit is contained in:
cinap_lenrek 2017-11-04 20:08:22 +01:00
parent 04ce485f1b
commit 24057fd4f4
35 changed files with 258 additions and 344 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -241,7 +241,7 @@ procsave(Proc *p)
{
if(p->fpstate == FPactive){
if(p->state != Moribund)
fpsave(&up->fpsave);
fpsave(up->fpsave);
p->fpstate = FPinactive;
}
}

View file

@ -246,7 +246,7 @@ trap(Ureg *ureg)
up->fpstate = FPactive;
break;
case FPinactive:
fprestore(&up->fpsave);
fprestore(up->fpsave);
up->fpstate = FPactive;
break;
default:

View file

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

View file

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

View file

@ -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 {

View file

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

View file

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

View file

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

View file

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

View file

@ -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 {

View file

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

View file

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

View file

@ -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:

View file

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

View file

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

View file

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

View file

@ -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.out xd -1x |
sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
echo '};'} > init.h

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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