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:
parent
04ce485f1b
commit
24057fd4f4
35 changed files with 258 additions and 344 deletions
|
@ -15,13 +15,13 @@ enum {
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef struct FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct PFPU PFPU;
|
||||||
typedef struct ISAConf ISAConf;
|
typedef struct ISAConf ISAConf;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
typedef struct Memcache Memcache;
|
typedef struct Memcache Memcache;
|
||||||
typedef struct MMMU MMMU;
|
typedef struct MMMU MMMU;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct Page Page;
|
typedef struct Page Page;
|
||||||
typedef struct PhysUart PhysUart;
|
typedef struct PhysUart PhysUart;
|
||||||
typedef struct PMMU PMMU;
|
typedef struct PMMU PMMU;
|
||||||
|
@ -56,14 +56,14 @@ struct Label
|
||||||
uintptr pc;
|
uintptr pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* emulated or vfp3 floating point
|
||||||
|
*/
|
||||||
enum {
|
enum {
|
||||||
Maxfpregs = 32, /* could be 16 or 32, see Mach.fpnregs */
|
Maxfpregs = 32, /* could be 16 or 32, see Mach.fpnregs */
|
||||||
Nfpctlregs = 16,
|
Nfpctlregs = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* emulated or vfp3 floating point
|
|
||||||
*/
|
|
||||||
struct FPsave
|
struct FPsave
|
||||||
{
|
{
|
||||||
ulong status;
|
ulong status;
|
||||||
|
@ -78,9 +78,12 @@ struct FPsave
|
||||||
uintptr pc; /* of failed fp instr. */
|
uintptr pc; /* of failed fp instr. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
struct PFPU
|
||||||
* FPsave.fpstate
|
{
|
||||||
*/
|
int fpstate;
|
||||||
|
FPsave fpsave[1];
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FPinit,
|
FPinit,
|
||||||
|
@ -119,13 +122,6 @@ struct Conf
|
||||||
int monitor; /* flag */
|
int monitor; /* flag */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave {
|
|
||||||
int emptiness;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMU stuff in Mach.
|
* MMU stuff in Mach.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -650,7 +650,7 @@ fpiarm(Ureg *ur)
|
||||||
|
|
||||||
if(up == nil)
|
if(up == nil)
|
||||||
panic("fpiarm not in a process");
|
panic("fpiarm not in a process");
|
||||||
ufp = &up->fpsave;
|
ufp = up->fpsave;
|
||||||
/*
|
/*
|
||||||
* because all the emulated fp state is in the proc structure,
|
* because all the emulated fp state is in the proc structure,
|
||||||
* it need not be saved/restored
|
* it need not be saved/restored
|
||||||
|
|
|
@ -222,7 +222,7 @@ void
|
||||||
fpunotify(Ureg*)
|
fpunotify(Ureg*)
|
||||||
{
|
{
|
||||||
if(up->fpstate == FPactive){
|
if(up->fpstate == FPactive){
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
up->fpstate |= FPillegal;
|
up->fpstate |= FPillegal;
|
||||||
|
@ -259,11 +259,11 @@ fprestore(Proc *p)
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
fpon();
|
fpon();
|
||||||
fpwr(Fpscr, p->fpsave.control);
|
fpwr(Fpscr, p->fpsave->control);
|
||||||
m->fpscr = fprd(Fpscr) & ~Allcc;
|
m->fpscr = fprd(Fpscr) & ~Allcc;
|
||||||
assert(m->fpnregs);
|
assert(m->fpnregs);
|
||||||
for (n = 0; n < m->fpnregs; n++)
|
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
|
* until the process runs again and generates an
|
||||||
* emulation fault to activate the FPU.
|
* emulation fault to activate the FPU.
|
||||||
*/
|
*/
|
||||||
fpsave(&p->fpsave);
|
fpsave(p->fpsave);
|
||||||
}
|
}
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
|
@ -317,11 +317,11 @@ fpuprocfork(Proc *p)
|
||||||
s = splhi();
|
s = splhi();
|
||||||
switch(up->fpstate & ~FPillegal){
|
switch(up->fpstate & ~FPillegal){
|
||||||
case FPactive:
|
case FPactive:
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
/* no break */
|
/* no break */
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
p->fpsave = up->fpsave;
|
memmove(p->fpsave, up->fpsave, sizeof(FPsave));
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
splx(s);
|
splx(s);
|
||||||
|
@ -345,7 +345,7 @@ mathnote(void)
|
||||||
ulong status;
|
ulong status;
|
||||||
char *msg, note[ERRMAX];
|
char *msg, note[ERRMAX];
|
||||||
|
|
||||||
status = up->fpsave.status;
|
status = up->fpsave->status;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some attention should probably be paid here to the
|
* Some attention should probably be paid here to the
|
||||||
|
@ -364,7 +364,7 @@ mathnote(void)
|
||||||
else
|
else
|
||||||
msg = "spurious";
|
msg = "spurious";
|
||||||
snprint(note, sizeof note, "sys: fp: %s fppc=%#p status=%#lux",
|
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);
|
postnote(up, 1, note, NDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ mathemu(Ureg *)
|
||||||
* More attention should probably be paid here to the
|
* More attention should probably be paid here to the
|
||||||
* exception masks and error summary.
|
* exception masks and error summary.
|
||||||
*/
|
*/
|
||||||
if(up->fpsave.status & (FPAINEX|FPAUNFL|FPAOVFL|FPAZDIV|FPAINVAL)){
|
if(up->fpsave->status & (FPAINEX|FPAUNFL|FPAOVFL|FPAZDIV|FPAINVAL)){
|
||||||
mathnote();
|
mathnote();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef struct FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct PFPU PFPU;
|
||||||
typedef struct ISAConf ISAConf;
|
typedef struct ISAConf ISAConf;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
typedef struct Memcache Memcache;
|
typedef struct Memcache Memcache;
|
||||||
typedef struct MMMU MMMU;
|
typedef struct MMMU MMMU;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct Page Page;
|
typedef struct Page Page;
|
||||||
typedef struct Pcidev Pcidev;
|
typedef struct Pcidev Pcidev;
|
||||||
typedef struct PhysUart PhysUart;
|
typedef struct PhysUart PhysUart;
|
||||||
|
@ -45,13 +45,13 @@ struct Label
|
||||||
uintptr pc;
|
uintptr pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* emulated floating point
|
||||||
|
*/
|
||||||
enum{
|
enum{
|
||||||
Nfpctlregs = 16,
|
Nfpctlregs = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* emulated floating point
|
|
||||||
*/
|
|
||||||
struct FPsave
|
struct FPsave
|
||||||
{
|
{
|
||||||
ulong status;
|
ulong status;
|
||||||
|
@ -61,9 +61,12 @@ struct FPsave
|
||||||
int fpstate;
|
int fpstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
struct PFPU
|
||||||
* FPsave.status
|
{
|
||||||
*/
|
int fpstate;
|
||||||
|
FPsave fpsave[1];
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FPinit,
|
FPinit,
|
||||||
|
@ -98,13 +101,6 @@ struct Conf
|
||||||
// ulong mhz;
|
// ulong mhz;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave {
|
|
||||||
int emptiness;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMU stuff in Mach.
|
* MMU stuff in Mach.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -726,7 +726,7 @@ fpiarm(Ureg *ur)
|
||||||
|
|
||||||
if(up == nil)
|
if(up == nil)
|
||||||
panic("fpiarm not in a process");
|
panic("fpiarm not in a process");
|
||||||
ufp = &up->fpsave;
|
ufp = up->fpsave;
|
||||||
/*
|
/*
|
||||||
* because all the emulated fp state is in the proc structure,
|
* because all the emulated fp state is in the proc structure,
|
||||||
* it need not be saved/restored
|
* it need not be saved/restored
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef struct FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct PFPU PFPU;
|
||||||
typedef struct ISAConf ISAConf;
|
typedef struct ISAConf ISAConf;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct Page Page;
|
typedef struct Page Page;
|
||||||
typedef struct PCArch PCArch;
|
typedef struct PCArch PCArch;
|
||||||
typedef struct Pcidev Pcidev;
|
typedef struct Pcidev Pcidev;
|
||||||
|
@ -45,16 +45,6 @@ struct Label
|
||||||
ulong pc;
|
ulong pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Proc.fpstate
|
|
||||||
*/
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
FPinit,
|
|
||||||
FPactive,
|
|
||||||
FPinactive,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure must agree with fpsave and fprestore asm routines
|
* 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
|
struct Confmem
|
||||||
{
|
{
|
||||||
ulong base;
|
ulong base;
|
||||||
|
@ -103,14 +106,6 @@ struct PMMU
|
||||||
int mmupid;
|
int mmupid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave
|
|
||||||
{
|
|
||||||
ulong UNUSED;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "../port/portdat.h"
|
#include "../port/portdat.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -241,7 +241,7 @@ procsave(Proc *p)
|
||||||
{
|
{
|
||||||
if(p->fpstate == FPactive){
|
if(p->fpstate == FPactive){
|
||||||
if(p->state != Moribund)
|
if(p->state != Moribund)
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ trap(Ureg *ureg)
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
fprestore(&up->fpsave);
|
fprestore(up->fpsave);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -27,6 +27,7 @@ enum {
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef struct FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct PFPU PFPU;
|
||||||
typedef struct ISAConf ISAConf;
|
typedef struct ISAConf ISAConf;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
|
@ -34,7 +35,6 @@ typedef struct Memcache Memcache;
|
||||||
typedef struct MMMU MMMU;
|
typedef struct MMMU MMMU;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef u32int Mreg; /* Msr - bloody UART */
|
typedef u32int Mreg; /* Msr - bloody UART */
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct Page Page;
|
typedef struct Page Page;
|
||||||
typedef struct PhysUart PhysUart;
|
typedef struct PhysUart PhysUart;
|
||||||
typedef struct PMMU PMMU;
|
typedef struct PMMU PMMU;
|
||||||
|
@ -69,13 +69,13 @@ struct Label
|
||||||
uintptr pc;
|
uintptr pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* emulated floating point
|
||||||
|
*/
|
||||||
enum{
|
enum{
|
||||||
Nfpctlregs = 16,
|
Nfpctlregs = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* emulated floating point
|
|
||||||
*/
|
|
||||||
struct FPsave
|
struct FPsave
|
||||||
{
|
{
|
||||||
ulong status;
|
ulong status;
|
||||||
|
@ -85,9 +85,12 @@ struct FPsave
|
||||||
int fpstate;
|
int fpstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
struct PFPU
|
||||||
* FPsave.status
|
{
|
||||||
*/
|
int fpstate;
|
||||||
|
FPsave fpsave[1];
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FPinit,
|
FPinit,
|
||||||
|
@ -122,13 +125,6 @@ struct Conf
|
||||||
int monitor; /* flag */
|
int monitor; /* flag */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave {
|
|
||||||
int emptiness;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMU stuff in Mach.
|
* MMU stuff in Mach.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -726,7 +726,7 @@ fpiarm(Ureg *ur)
|
||||||
|
|
||||||
if(up == nil)
|
if(up == nil)
|
||||||
panic("fpiarm not in a process");
|
panic("fpiarm not in a process");
|
||||||
ufp = &up->fpsave;
|
ufp = up->fpsave;
|
||||||
/*
|
/*
|
||||||
* because all the emulated fp state is in the proc structure,
|
* because all the emulated fp state is in the proc structure,
|
||||||
* it need not be saved/restored
|
* it need not be saved/restored
|
||||||
|
|
|
@ -3,14 +3,14 @@ typedef struct BIOS32ci BIOS32ci;
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef union FPsave FPsave;
|
typedef union FPsave FPsave;
|
||||||
|
typedef struct FPx87state FPx87state;
|
||||||
typedef struct FPssestate FPssestate;
|
typedef struct FPssestate FPssestate;
|
||||||
typedef struct FPstate FPstate;
|
typedef struct PFPU PFPU;
|
||||||
typedef struct ISAConf ISAConf;
|
typedef struct ISAConf ISAConf;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
typedef struct MMU MMU;
|
typedef struct MMU MMU;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct PCArch PCArch;
|
typedef struct PCArch PCArch;
|
||||||
typedef struct Pcidev Pcidev;
|
typedef struct Pcidev Pcidev;
|
||||||
typedef struct PCMmap PCMmap;
|
typedef struct PCMmap PCMmap;
|
||||||
|
@ -51,22 +51,7 @@ struct Label
|
||||||
ulong pc;
|
ulong pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FPx87state /* x87 fp state */
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
{
|
{
|
||||||
ushort control;
|
ushort control;
|
||||||
ushort r1;
|
ushort r1;
|
||||||
|
@ -98,18 +83,30 @@ struct FPssestate /* SSE fp state */
|
||||||
ulong mxcsr; /* MXCSR register state */
|
ulong mxcsr; /* MXCSR register state */
|
||||||
ulong mxcsr_mask; /* MXCSR mask register */
|
ulong mxcsr_mask; /* MXCSR mask register */
|
||||||
uchar xregs[480]; /* extended registers */
|
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 {
|
union FPsave {
|
||||||
FPstate;
|
FPx87state;
|
||||||
FPssestate;
|
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
|
struct Confmem
|
||||||
{
|
{
|
||||||
ulong base;
|
ulong base;
|
||||||
|
@ -164,16 +161,6 @@ struct PMMU
|
||||||
void *vmx;
|
void *vmx;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave
|
|
||||||
{
|
|
||||||
ulong svflags;
|
|
||||||
ulong svcs;
|
|
||||||
ulong svss;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "../port/portdat.h"
|
#include "../port/portdat.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -40,9 +40,7 @@ void fpoff(void);
|
||||||
void (*fprestore)(FPsave*);
|
void (*fprestore)(FPsave*);
|
||||||
void (*fpsave)(FPsave*);
|
void (*fpsave)(FPsave*);
|
||||||
void fpsserestore(FPsave*);
|
void fpsserestore(FPsave*);
|
||||||
void fpsserestore0(FPsave*);
|
|
||||||
void fpssesave(FPsave*);
|
void fpssesave(FPsave*);
|
||||||
void fpssesave0(FPsave*);
|
|
||||||
void fpx87restore(FPsave*);
|
void fpx87restore(FPsave*);
|
||||||
void fpx87restore0(FPsave*);
|
void fpx87restore0(FPsave*);
|
||||||
void fpx87save(FPsave*);
|
void fpx87save(FPsave*);
|
||||||
|
|
|
@ -622,13 +622,13 @@ TEXT fpclear(SB), $0 /* clear pending exceptions */
|
||||||
FPOFF
|
FPOFF
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT fpssesave0(SB), $0 /* save state and disable */
|
TEXT fpssesave(SB), $0 /* save state and disable */
|
||||||
MOVL p+0(FP), AX
|
MOVL p+0(FP), AX
|
||||||
FXSAVE 0(AX) /* no WAIT */
|
FXSAVE 0(AX) /* no WAIT */
|
||||||
FPOFF
|
FPOFF
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT fpsserestore0(SB), $0 /* enable and restore state */
|
TEXT fpsserestore(SB), $0 /* enable and restore state */
|
||||||
FPON
|
FPON
|
||||||
MOVL p+0(FP), AX
|
MOVL p+0(FP), AX
|
||||||
FXRSTOR 0(AX)
|
FXRSTOR 0(AX)
|
||||||
|
|
|
@ -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.
|
* 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
|
void
|
||||||
fpx87save(FPsave *fps)
|
fpx87save(FPsave *fps)
|
||||||
|
@ -441,32 +437,6 @@ fpx87restore(FPsave *fps)
|
||||||
fpx87restore0(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[] =
|
static char* mathmsg[] =
|
||||||
{
|
{
|
||||||
nil, /* handled below */
|
nil, /* handled below */
|
||||||
|
@ -524,9 +494,9 @@ matherror(Ureg*, void*)
|
||||||
/*
|
/*
|
||||||
* get floating point state to check out error
|
* get floating point state to check out error
|
||||||
*/
|
*/
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
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
|
static void
|
||||||
simderror(Ureg *ureg, void*)
|
simderror(Ureg *ureg, void*)
|
||||||
{
|
{
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
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();
|
fpinit();
|
||||||
if(fpsave == fpssesave)
|
if(fpsave == fpssesave)
|
||||||
ldmxcsr(0); /* no simd exceptions on 386 */
|
ldmxcsr(0); /* no simd exceptions on 386 */
|
||||||
|
while(up->fpsave == nil)
|
||||||
|
up->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
|
@ -568,13 +540,13 @@ mathemu(Ureg *ureg, void*)
|
||||||
* More attention should probably be paid here to the
|
* More attention should probably be paid here to the
|
||||||
* exception masks and error summary.
|
* exception masks and error summary.
|
||||||
*/
|
*/
|
||||||
status = up->fpsave.fsw;
|
status = up->fpsave->fsw;
|
||||||
control = up->fpsave.fcw;
|
control = up->fpsave->fcw;
|
||||||
if((status & ~control) & 0x07F){
|
if((status & ~control) & 0x07F){
|
||||||
mathnote(status, up->fpsave.fpuip);
|
mathnote(status, up->fpsave->fpuip);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprestore(&up->fpsave);
|
fprestore(up->fpsave);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPactive:
|
case FPactive:
|
||||||
|
@ -645,10 +617,12 @@ procfork(Proc *p)
|
||||||
s = splhi();
|
s = splhi();
|
||||||
switch(up->fpstate & ~FPillegal){
|
switch(up->fpstate & ~FPillegal){
|
||||||
case FPactive:
|
case FPactive:
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
case 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;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,7 +682,7 @@ procsave(Proc *p)
|
||||||
* until the process runs again and generates an
|
* until the process runs again and generates an
|
||||||
* emulation fault to activate the FPU.
|
* emulation fault to activate the FPU.
|
||||||
*/
|
*/
|
||||||
fpsave(&p->fpsave);
|
fpsave(p->fpsave);
|
||||||
}
|
}
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
|
|
|
@ -854,7 +854,7 @@ notify(Ureg* ureg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(up->fpstate == FPactive){
|
if(up->fpstate == FPactive){
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
up->fpstate |= FPillegal;
|
up->fpstate |= FPillegal;
|
||||||
|
|
|
@ -2,15 +2,13 @@ typedef struct BIOS32si BIOS32si;
|
||||||
typedef struct BIOS32ci BIOS32ci;
|
typedef struct BIOS32ci BIOS32ci;
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef union FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
typedef struct Fxsave Fxsave;
|
typedef struct PFPU PFPU;
|
||||||
typedef struct FPstate FPstate;
|
|
||||||
typedef struct ISAConf ISAConf;
|
typedef struct ISAConf ISAConf;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
typedef struct MMU MMU;
|
typedef struct MMU MMU;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct PCArch PCArch;
|
typedef struct PCArch PCArch;
|
||||||
typedef struct Pcidev Pcidev;
|
typedef struct Pcidev Pcidev;
|
||||||
typedef struct PCMmap PCMmap;
|
typedef struct PCMmap PCMmap;
|
||||||
|
@ -51,25 +49,8 @@ struct Label
|
||||||
uintptr pc;
|
uintptr pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
struct FPsave
|
||||||
* 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,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fcw; /* x87 control word */
|
||||||
u16int fsw; /* x87 status word */
|
u16int fsw; /* x87 status word */
|
||||||
u8int ftw; /* x87 tag word */
|
u8int ftw; /* x87 tag word */
|
||||||
|
@ -84,9 +65,21 @@ struct Fxsave {
|
||||||
uchar ign[96]; /* reserved, ignored */
|
uchar ign[96]; /* reserved, ignored */
|
||||||
};
|
};
|
||||||
|
|
||||||
union FPsave {
|
struct PFPU
|
||||||
uchar align[512+15];
|
{
|
||||||
Fxsave;
|
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
|
struct Confmem
|
||||||
|
@ -149,16 +142,6 @@ struct PMMU
|
||||||
void *vmx;
|
void *vmx;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave
|
|
||||||
{
|
|
||||||
ulong svflags;
|
|
||||||
ulong svcs;
|
|
||||||
ulong svss;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "../port/portdat.h"
|
#include "../port/portdat.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -392,15 +392,13 @@ reboot(void *entry, void *code, ulong size)
|
||||||
* SIMD Floating Point.
|
* SIMD Floating Point.
|
||||||
* Assembler support to get at the individual instructions
|
* Assembler support to get at the individual instructions
|
||||||
* is in l.s.
|
* 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 _clts(void);
|
||||||
extern void _fldcw(u16int);
|
extern void _fldcw(u16int);
|
||||||
extern void _fnclex(void);
|
extern void _fnclex(void);
|
||||||
extern void _fninit(void);
|
extern void _fninit(void);
|
||||||
extern void _fxrstor(Fxsave*);
|
extern void _fxrstor(void*);
|
||||||
extern void _fxsave(Fxsave*);
|
extern void _fxsave(void*);
|
||||||
extern void _fwait(void);
|
extern void _fwait(void);
|
||||||
extern void _ldmxcsr(u32int);
|
extern void _ldmxcsr(u32int);
|
||||||
extern void _stts(void);
|
extern void _stts(void);
|
||||||
|
@ -418,24 +416,16 @@ fpx87restore(FPsave*)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fpssesave(FPsave *fps)
|
fpssesave(FPsave *s)
|
||||||
{
|
{
|
||||||
Fxsave *fx = (Fxsave*)ROUND(((uintptr)fps), FPalign);
|
_fxsave(s);
|
||||||
|
|
||||||
_fxsave(fx);
|
|
||||||
_stts();
|
_stts();
|
||||||
if(fx != (Fxsave*)fps)
|
|
||||||
memmove((Fxsave*)fps, fx, sizeof(Fxsave));
|
|
||||||
}
|
}
|
||||||
void
|
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();
|
_clts();
|
||||||
_fxrstor(fx);
|
_fxrstor(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* mathmsg[] =
|
static char* mathmsg[] =
|
||||||
|
@ -488,9 +478,9 @@ matherror(Ureg*, void*)
|
||||||
/*
|
/*
|
||||||
* Save FPU state to check out the error.
|
* Save FPU state to check out the error.
|
||||||
*/
|
*/
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
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
|
static void
|
||||||
simderror(Ureg *ureg, void*)
|
simderror(Ureg *ureg, void*)
|
||||||
{
|
{
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
mathnote(up->fpsave.mxcsr & 0x3f, ureg->pc);
|
mathnote(up->fpsave->mxcsr & 0x3f, ureg->pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -538,6 +528,8 @@ mathemu(Ureg *ureg, void*)
|
||||||
switch(up->fpstate){
|
switch(up->fpstate){
|
||||||
case FPinit:
|
case FPinit:
|
||||||
fpinit();
|
fpinit();
|
||||||
|
while(up->fpsave == nil)
|
||||||
|
up->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
|
@ -548,13 +540,13 @@ mathemu(Ureg *ureg, void*)
|
||||||
* More attention should probably be paid here to the
|
* More attention should probably be paid here to the
|
||||||
* exception masks and error summary.
|
* exception masks and error summary.
|
||||||
*/
|
*/
|
||||||
status = up->fpsave.fsw;
|
status = up->fpsave->fsw;
|
||||||
control = up->fpsave.fcw;
|
control = up->fpsave->fcw;
|
||||||
if((status & ~control) & 0x07F){
|
if((status & ~control) & 0x07F){
|
||||||
mathnote(status, up->fpsave.rip);
|
mathnote(status, up->fpsave->rip);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprestore(&up->fpsave);
|
fprestore(up->fpsave);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPactive:
|
case FPactive:
|
||||||
|
@ -605,10 +597,12 @@ procfork(Proc *p)
|
||||||
s = splhi();
|
s = splhi();
|
||||||
switch(up->fpstate & ~FPillegal){
|
switch(up->fpstate & ~FPillegal){
|
||||||
case FPactive:
|
case FPactive:
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
case 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;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
splx(s);
|
splx(s);
|
||||||
|
@ -665,7 +659,7 @@ procsave(Proc *p)
|
||||||
* until the process runs again and generates an
|
* until the process runs again and generates an
|
||||||
* emulation fault to activate the FPU.
|
* emulation fault to activate the FPU.
|
||||||
*/
|
*/
|
||||||
fpsave(&p->fpsave);
|
fpsave(p->fpsave);
|
||||||
}
|
}
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
|
|
|
@ -823,7 +823,7 @@ notify(Ureg* ureg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(up->fpstate == FPactive){
|
if(up->fpstate == FPactive){
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
up->fpstate |= FPillegal;
|
up->fpstate |= FPillegal;
|
||||||
|
|
|
@ -1012,7 +1012,9 @@ procread(Chan *c, void *va, long n, vlong off)
|
||||||
goto regread;
|
goto regread;
|
||||||
|
|
||||||
case Qfpregs:
|
case Qfpregs:
|
||||||
rptr = (uchar*)&p->fpsave;
|
if(p->fpstate != FPinactive)
|
||||||
|
error(Enoreg);
|
||||||
|
rptr = (uchar*)p->fpsave;
|
||||||
rsize = sizeof(FPsave);
|
rsize = sizeof(FPsave);
|
||||||
regread:
|
regread:
|
||||||
if(rptr == nil)
|
if(rptr == nil)
|
||||||
|
@ -1232,7 +1234,9 @@ procwrite(Chan *c, void *va, long n, vlong off)
|
||||||
n = 0;
|
n = 0;
|
||||||
else if(offset+n > sizeof(FPsave))
|
else if(offset+n > sizeof(FPsave))
|
||||||
n = sizeof(FPsave) - offset;
|
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;
|
break;
|
||||||
|
|
||||||
case Qctl:
|
case Qctl:
|
||||||
|
|
|
@ -676,6 +676,8 @@ struct Proc
|
||||||
Fgrp *closingfgrp; /* used during teardown */
|
Fgrp *closingfgrp; /* used during teardown */
|
||||||
|
|
||||||
ulong parentpid;
|
ulong parentpid;
|
||||||
|
|
||||||
|
int insyscall;
|
||||||
ulong time[6]; /* User, Sys, Real; child U, S, R */
|
ulong time[6]; /* User, Sys, Real; child U, S, R */
|
||||||
|
|
||||||
uvlong kentry; /* Kernel entry time stamp (for profiling) */
|
uvlong kentry; /* Kernel entry time stamp (for profiling) */
|
||||||
|
@ -689,9 +691,6 @@ struct Proc
|
||||||
*/
|
*/
|
||||||
vlong pcycles;
|
vlong pcycles;
|
||||||
|
|
||||||
int insyscall;
|
|
||||||
int fpstate;
|
|
||||||
|
|
||||||
QLock debug; /* to access debugging elements of User */
|
QLock debug; /* to access debugging elements of User */
|
||||||
Proc *pdbg; /* the debugging process */
|
Proc *pdbg; /* the debugging process */
|
||||||
ulong procmode; /* proc device default file mode */
|
ulong procmode; /* proc device default file mode */
|
||||||
|
@ -720,9 +719,8 @@ struct Proc
|
||||||
void (*kpfun)(void*);
|
void (*kpfun)(void*);
|
||||||
void *kparg;
|
void *kparg;
|
||||||
|
|
||||||
FPsave fpsave; /* address of this is known by db */
|
int scallnr; /* sys call number */
|
||||||
int scallnr; /* sys call number - known by db */
|
Sargs s; /* syscall arguments */
|
||||||
Sargs s; /* address of this is known by db */
|
|
||||||
int nerrlab;
|
int nerrlab;
|
||||||
Label errlab[NERR];
|
Label errlab[NERR];
|
||||||
char *syserrstr; /* last error from a system call, errbuf0 or 1 */
|
char *syserrstr; /* last error from a system call, errbuf0 or 1 */
|
||||||
|
@ -766,17 +764,14 @@ struct Proc
|
||||||
|
|
||||||
void *ureg; /* User registers for notes */
|
void *ureg; /* User registers for notes */
|
||||||
void *dbgreg; /* User registers for devproc */
|
void *dbgreg; /* User registers for devproc */
|
||||||
Notsave;
|
|
||||||
|
|
||||||
/*
|
PFPU; /* machine specific fpu state */
|
||||||
* machine specific MMU
|
PMMU; /* machine specific mmu state */
|
||||||
*/
|
|
||||||
PMMU;
|
|
||||||
|
|
||||||
char *syscalltrace; /* syscall trace */
|
char *syscalltrace; /* syscall trace */
|
||||||
|
|
||||||
Watchpt *watchpt; /* watchpoints */
|
Watchpt *watchpt; /* watchpoints */
|
||||||
int nwatchpt;
|
int nwatchpt;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
|
typedef struct Confmem Confmem;
|
||||||
typedef struct FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct PFPU PFPU;
|
||||||
typedef struct ISAConf ISAConf;
|
typedef struct ISAConf ISAConf;
|
||||||
typedef struct Imap Imap;
|
typedef struct Imap Imap;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct PCArch PCArch;
|
typedef struct PCArch PCArch;
|
||||||
typedef struct PMMU PMMU;
|
typedef struct PMMU PMMU;
|
||||||
typedef struct Page Page;
|
typedef struct Page Page;
|
||||||
|
@ -14,6 +15,7 @@ typedef struct Proc Proc;
|
||||||
typedef struct Sys Sys;
|
typedef struct Sys Sys;
|
||||||
typedef struct Ureg Ureg;
|
typedef struct Ureg Ureg;
|
||||||
typedef struct Vctl Vctl;
|
typedef struct Vctl Vctl;
|
||||||
|
typedef long Tval;
|
||||||
|
|
||||||
#pragma incomplete Ureg
|
#pragma incomplete Ureg
|
||||||
#pragma incomplete Imap
|
#pragma incomplete Imap
|
||||||
|
@ -45,19 +47,6 @@ struct Label
|
||||||
ulong pc;
|
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
|
* 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
|
struct Conf
|
||||||
{
|
{
|
||||||
ulong nmach; /* processors */
|
ulong nmach; /* processors */
|
||||||
ulong nproc; /* processes */
|
ulong nproc; /* processes */
|
||||||
ulong npage0; /* total physical pages of memory */
|
Confmem mem[2];
|
||||||
ulong npage1; /* total physical pages of memory */
|
|
||||||
ulong npage; /* total physical pages of memory */
|
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 upages; /* user page pool */
|
||||||
ulong nimage; /* number of page cache image headers */
|
ulong nimage; /* number of page cache image headers */
|
||||||
ulong nswap; /* number of swap pages */
|
ulong nswap; /* number of swap pages */
|
||||||
|
@ -102,14 +112,6 @@ struct PMMU
|
||||||
Ureg *mmureg; /* pointer to ureg structure */
|
Ureg *mmureg; /* pointer to ureg structure */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave
|
|
||||||
{
|
|
||||||
ulong UNUSED;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "../port/portdat.h"
|
#include "../port/portdat.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -292,7 +292,7 @@ procsave(Proc *p)
|
||||||
p->kentry -= t;
|
p->kentry -= t;
|
||||||
if(p->fpstate == FPactive){
|
if(p->fpstate == FPactive){
|
||||||
if(p->state != Moribund)
|
if(p->state != Moribund)
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,6 @@ init.h: ../port/initcode.c init9.s
|
||||||
$AS init9.s
|
$AS init9.s
|
||||||
$LD -l -s -R4 -o init.out init9.$O initcode.$O /power/lib/libc.a
|
$LD -l -s -R4 -o init.out init9.$O initcode.$O /power/lib/libc.a
|
||||||
{echo 'uchar initcode[]={'
|
{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'
|
sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
|
||||||
echo '};'} > init.h
|
echo '};'} > init.h
|
||||||
|
|
|
@ -243,7 +243,7 @@ trap(Ureg *ureg)
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
fprestore(&up->fpsave);
|
fprestore(up->fpsave);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPactive:
|
case FPactive:
|
||||||
|
@ -711,7 +711,7 @@ notify(Ureg* ur)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(up->fpstate == FPactive){
|
if(up->fpstate == FPactive){
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
up->fpstate |= FPillegal;
|
up->fpstate |= FPillegal;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef struct FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct PFPU PFPU;
|
||||||
typedef struct KMap KMap;
|
typedef struct KMap KMap;
|
||||||
typedef struct Lance Lance;
|
typedef struct Lance Lance;
|
||||||
typedef struct Lancemem Lancemem;
|
typedef struct Lancemem Lancemem;
|
||||||
|
@ -8,7 +9,6 @@ typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef struct MMU MMU;
|
typedef struct MMU MMU;
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct PMMU PMMU;
|
typedef struct PMMU PMMU;
|
||||||
typedef struct Softtlb Softtlb;
|
typedef struct Softtlb Softtlb;
|
||||||
typedef struct Ureg Ureg;
|
typedef struct Ureg Ureg;
|
||||||
|
@ -73,18 +73,6 @@ struct Conf
|
||||||
/*
|
/*
|
||||||
* floating point registers
|
* floating point registers
|
||||||
*/
|
*/
|
||||||
enum
|
|
||||||
{
|
|
||||||
/* floating point state */
|
|
||||||
FPinit,
|
|
||||||
FPactive,
|
|
||||||
FPinactive,
|
|
||||||
FPemu,
|
|
||||||
|
|
||||||
/* bit meaning floating point illegal */
|
|
||||||
FPillegal= 0x100,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Nfpregs = 32, /* floats; half as many doubles */
|
Nfpregs = 32, /* floats; half as many doubles */
|
||||||
};
|
};
|
||||||
|
@ -111,6 +99,24 @@ struct FPsave
|
||||||
int fpcnt; /* how many consecutive at that addr */
|
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
|
* mmu goo in the Proc structure
|
||||||
*/
|
*/
|
||||||
|
@ -119,14 +125,6 @@ struct PMMU
|
||||||
int pidonmach[MAXMACH];
|
int pidonmach[MAXMACH];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave
|
|
||||||
{
|
|
||||||
ulong nonempty;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "../port/portdat.h"
|
#include "../port/portdat.h"
|
||||||
|
|
||||||
struct Mach
|
struct Mach
|
||||||
|
|
|
@ -29,7 +29,7 @@ fptrap(Ureg *ur)
|
||||||
{
|
{
|
||||||
ulong iw, npc;
|
ulong iw, npc;
|
||||||
|
|
||||||
if((up->fpsave.fpstatus&(1<<17)) == 0)
|
if((up->fpsave->fpstatus&(1<<17)) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ur->cause & (1<<31))
|
if(ur->cause & (1<<31))
|
||||||
|
@ -41,7 +41,7 @@ fptrap(Ureg *ur)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ur->cause & (1<<31)){
|
if(ur->cause & (1<<31)){
|
||||||
npc = branch(ur, up->fpsave.fpstatus);
|
npc = branch(ur, up->fpsave->fpstatus);
|
||||||
if(npc == 0)
|
if(npc == 0)
|
||||||
return;
|
return;
|
||||||
ur->pc = npc;
|
ur->pc = npc;
|
||||||
|
@ -49,7 +49,7 @@ fptrap(Ureg *ur)
|
||||||
else
|
else
|
||||||
ur->pc += 4;
|
ur->pc += 4;
|
||||||
|
|
||||||
up->fpsave.fpstatus &= ~(1<<17);
|
up->fpsave->fpstatus &= ~(1<<17);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -107,8 +107,8 @@ fpunimp(ulong iw)
|
||||||
ft = (iw>>16) & ((1<<5)-1);
|
ft = (iw>>16) & ((1<<5)-1);
|
||||||
fs = (iw>>11) & ((1<<5)-1);
|
fs = (iw>>11) & ((1<<5)-1);
|
||||||
fd = (iw>>6) & ((1<<5)-1);
|
fd = (iw>>6) & ((1<<5)-1);
|
||||||
unpack(&up->fpsave, fmt, fs, &ss, &es);
|
unpack(up->fpsave, fmt, fs, &ss, &es);
|
||||||
unpack(&up->fpsave, fmt, ft, &st, &et);
|
unpack(up->fpsave, fmt, ft, &st, &et);
|
||||||
ed = 0;
|
ed = 0;
|
||||||
maxe = 0;
|
maxe = 0;
|
||||||
maxm = 0;
|
maxm = 0;
|
||||||
|
@ -124,11 +124,11 @@ fpunimp(ulong iw)
|
||||||
}
|
}
|
||||||
switch(op){
|
switch(op){
|
||||||
case ABS:
|
case ABS:
|
||||||
up->fpsave.reg[fd] &= ~0x80000000;
|
up->fpsave->reg[fd] &= ~0x80000000;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case NEG:
|
case NEG:
|
||||||
up->fpsave.reg[fd] ^= 0x80000000;
|
up->fpsave->reg[fd] ^= 0x80000000;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case SUB:
|
case SUB:
|
||||||
|
@ -164,9 +164,9 @@ fpunimp(ulong iw)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(ed <= -(maxe-5)){ /* guess: underflow */
|
if(ed <= -(maxe-5)){ /* guess: underflow */
|
||||||
zeroreg(&up->fpsave, fmt, fd, sd);
|
zeroreg(up->fpsave, fmt, fd, sd);
|
||||||
/* Set underflow exception and sticky */
|
/* Set underflow exception and sticky */
|
||||||
up->fpsave.fpstatus |= (1<<3)|(1<<13);
|
up->fpsave->fpstatus |= (1<<3)|(1<<13);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -396,7 +396,7 @@ void
|
||||||
procsetup(Proc *p)
|
procsetup(Proc *p)
|
||||||
{
|
{
|
||||||
p->fpstate = FPinit;
|
p->fpstate = FPinit;
|
||||||
p->fpsave = initfp;
|
memmove(p->fpsave, &initfp, sizeof(FPsave));
|
||||||
|
|
||||||
cycles(&p->kentry);
|
cycles(&p->kentry);
|
||||||
p->pcycles = -p->kentry;
|
p->pcycles = -p->kentry;
|
||||||
|
@ -413,11 +413,11 @@ procfork(Proc *p)
|
||||||
s = splhi();
|
s = splhi();
|
||||||
switch(up->fpstate & ~FPillegal){
|
switch(up->fpstate & ~FPillegal){
|
||||||
case FPactive:
|
case FPactive:
|
||||||
savefpregs(&up->fpsave);
|
savefpregs(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
/* wet floor */
|
/* wet floor */
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
p->fpsave = up->fpsave;
|
memmove(p->fpsave, up->fpsave, sizeof(FPsave));
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
splx(s);
|
splx(s);
|
||||||
|
@ -430,7 +430,7 @@ procsave(Proc *p)
|
||||||
|
|
||||||
if(p->fpstate == FPactive){
|
if(p->fpstate == FPactive){
|
||||||
if(p->state != Moribund) {
|
if(p->state != Moribund) {
|
||||||
savefpregs(&p->fpsave);
|
savefpregs(p->fpsave);
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ trap(Ureg *ur)
|
||||||
if(!user)
|
if(!user)
|
||||||
goto Default;
|
goto Default;
|
||||||
if(up->fpstate == FPactive){
|
if(up->fpstate == FPactive){
|
||||||
savefpregs(&up->fpsave);
|
savefpregs(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
clrfpintr();
|
clrfpintr();
|
||||||
|
@ -257,7 +257,7 @@ trap(Ureg *ur)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(up->fpstate == FPinit || up->fpstate == FPinactive){
|
if(up->fpstate == FPinit || up->fpstate == FPinactive){
|
||||||
restfpregs(&up->fpsave, up->fpsave.fpstatus&~FPEXPMASK);
|
restfpregs(up->fpsave, up->fpsave->fpstatus&~FPEXPMASK);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
ur->status |= CU1;
|
ur->status |= CU1;
|
||||||
break;
|
break;
|
||||||
|
@ -289,7 +289,7 @@ trap(Ureg *ur)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fpchk) {
|
if(fpchk) {
|
||||||
fpfcr31 = up->fpsave.fpstatus;
|
fpfcr31 = up->fpsave->fpstatus;
|
||||||
if((fpfcr31>>12) & ((fpfcr31>>7)|0x20) & 0x3f) {
|
if((fpfcr31>>12) & ((fpfcr31>>7)|0x20) & 0x3f) {
|
||||||
spllo();
|
spllo();
|
||||||
fpexcep = fpexcname(ur, fpfcr31, buf1, sizeof buf1);
|
fpexcep = fpexcname(ur, fpfcr31, buf1, sizeof buf1);
|
||||||
|
@ -501,7 +501,7 @@ notify(Ureg *ur)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(up->fpstate == FPactive){
|
if(up->fpstate == FPactive){
|
||||||
savefpregs(&up->fpsave);
|
savefpregs(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
up->fpstate |= FPillegal;
|
up->fpstate |= FPillegal;
|
||||||
|
|
|
@ -24,6 +24,7 @@ enum {
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef struct FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct PFPU PFPU;
|
||||||
typedef struct ISAConf ISAConf;
|
typedef struct ISAConf ISAConf;
|
||||||
typedef struct Isolated Isolated;
|
typedef struct Isolated Isolated;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
|
@ -33,7 +34,6 @@ typedef struct Memcache Memcache;
|
||||||
typedef struct MMMU MMMU;
|
typedef struct MMMU MMMU;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef u32int Mreg; /* Msr - bloody UART */
|
typedef u32int Mreg; /* Msr - bloody UART */
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct Page Page;
|
typedef struct Page Page;
|
||||||
typedef struct Pcisiz Pcisiz;
|
typedef struct Pcisiz Pcisiz;
|
||||||
typedef struct Pcidev Pcidev;
|
typedef struct Pcidev Pcidev;
|
||||||
|
@ -72,14 +72,14 @@ struct Label
|
||||||
uintptr pc;
|
uintptr pc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* emulated or vfp3 floating point
|
||||||
|
*/
|
||||||
enum {
|
enum {
|
||||||
Maxfpregs = 32, /* could be 16 or 32, see Mach.fpnregs */
|
Maxfpregs = 32, /* could be 16 or 32, see Mach.fpnregs */
|
||||||
Nfpctlregs = 16,
|
Nfpctlregs = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* emulated or vfp3 floating point
|
|
||||||
*/
|
|
||||||
struct FPsave
|
struct FPsave
|
||||||
{
|
{
|
||||||
ulong status;
|
ulong status;
|
||||||
|
@ -94,9 +94,12 @@ struct FPsave
|
||||||
uintptr pc; /* of failed fp instr. */
|
uintptr pc; /* of failed fp instr. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
struct PFPU
|
||||||
* FPsave.fpstate
|
{
|
||||||
*/
|
int fpstate;
|
||||||
|
FPsave fpsave[1];
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FPinit,
|
FPinit,
|
||||||
|
@ -135,13 +138,6 @@ struct Conf
|
||||||
int monitor; /* flag */
|
int monitor; /* flag */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave {
|
|
||||||
int emptiness;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMU stuff in Mach.
|
* MMU stuff in Mach.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -650,7 +650,7 @@ fpiarm(Ureg *ur)
|
||||||
|
|
||||||
if(up == nil)
|
if(up == nil)
|
||||||
panic("fpiarm not in a process");
|
panic("fpiarm not in a process");
|
||||||
ufp = &up->fpsave;
|
ufp = up->fpsave;
|
||||||
/*
|
/*
|
||||||
* because all the emulated fp state is in the proc structure,
|
* because all the emulated fp state is in the proc structure,
|
||||||
* it need not be saved/restored
|
* it need not be saved/restored
|
||||||
|
|
|
@ -450,7 +450,7 @@ mathnote(void)
|
||||||
ulong status;
|
ulong status;
|
||||||
char *msg, note[ERRMAX];
|
char *msg, note[ERRMAX];
|
||||||
|
|
||||||
status = up->fpsave.status;
|
status = up->fpsave->status;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some attention should probably be paid here to the
|
* Some attention should probably be paid here to the
|
||||||
|
@ -473,7 +473,7 @@ mathnote(void)
|
||||||
msg = "invalid operation";
|
msg = "invalid operation";
|
||||||
}
|
}
|
||||||
snprint(note, sizeof note, "sys: fp: %s fppc=0x%lux status=0x%lux",
|
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);
|
postnote(up, 1, note, NDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,12 +493,12 @@ matherror(Ureg *ur, void*)
|
||||||
/*
|
/*
|
||||||
* save floating point state to check out error
|
* save floating point state to check out error
|
||||||
*/
|
*/
|
||||||
fpenv(&up->fpsave);
|
fpenv(up->fpsave);
|
||||||
mathnote();
|
mathnote();
|
||||||
|
|
||||||
if(ur->pc & KZERO)
|
if(ur->pc & KZERO)
|
||||||
panic("fp: status %ux fppc=0x%lux pc=0x%lux",
|
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){
|
switch(up->fpstate){
|
||||||
case FPinit:
|
case FPinit:
|
||||||
fpinit();
|
fpinit();
|
||||||
|
while(up->fpsave == nil)
|
||||||
|
up->fpsave = mallocalign(sizeof(FPsave), FPalign, 0, 0);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
|
@ -525,11 +527,11 @@ mathemu(Ureg *ureg, void*)
|
||||||
* More attention should probably be paid here to the
|
* More attention should probably be paid here to the
|
||||||
* exception masks and error summary.
|
* exception masks and error summary.
|
||||||
*/
|
*/
|
||||||
if((up->fpsave.status & ~up->fpsave.control) & 0x07F){
|
if((up->fpsave->status & ~up->fpsave->control) & 0x07F){
|
||||||
mathnote();
|
mathnote();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprestore(&up->fpsave);
|
fprestore(up->fpsave);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
break;
|
break;
|
||||||
case FPactive:
|
case FPactive:
|
||||||
|
@ -580,10 +582,12 @@ procfork(Proc *p)
|
||||||
s = splhi();
|
s = splhi();
|
||||||
switch(up->fpstate & ~FPillegal){
|
switch(up->fpstate & ~FPillegal){
|
||||||
case FPactive:
|
case FPactive:
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
case 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;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
splx(s);
|
splx(s);
|
||||||
|
@ -622,7 +626,7 @@ procsave(Proc *p)
|
||||||
* until the process runs again and generates an
|
* until the process runs again and generates an
|
||||||
* emulation fault to activate the FPU.
|
* emulation fault to activate the FPU.
|
||||||
*/
|
*/
|
||||||
fpsave(&p->fpsave);
|
fpsave(p->fpsave);
|
||||||
}
|
}
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
|
|
|
@ -674,7 +674,7 @@ syscall(Ureg* ureg)
|
||||||
scallnr = ureg->ax;
|
scallnr = ureg->ax;
|
||||||
up->scallnr = scallnr;
|
up->scallnr = scallnr;
|
||||||
if(scallnr == RFORK && up->fpstate == FPactive){
|
if(scallnr == RFORK && up->fpstate == FPactive){
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
spllo();
|
spllo();
|
||||||
|
@ -764,7 +764,7 @@ notify(Ureg* ureg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(up->fpstate == FPactive){
|
if(up->fpstate == FPactive){
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
up->fpstate |= FPillegal;
|
up->fpstate |= FPillegal;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
typedef struct Conf Conf;
|
typedef struct Conf Conf;
|
||||||
typedef struct Confmem Confmem;
|
typedef struct Confmem Confmem;
|
||||||
typedef struct FPsave FPsave;
|
typedef struct FPsave FPsave;
|
||||||
|
typedef struct PFPU PFPU;
|
||||||
typedef struct L1 L1;
|
typedef struct L1 L1;
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
typedef struct Lock Lock;
|
typedef struct Lock Lock;
|
||||||
typedef struct KMap KMap;
|
typedef struct KMap KMap;
|
||||||
typedef struct MMMU MMMU;
|
typedef struct MMMU MMMU;
|
||||||
typedef struct Mach Mach;
|
typedef struct Mach Mach;
|
||||||
typedef struct Notsave Notsave;
|
|
||||||
typedef struct Page Page;
|
typedef struct Page Page;
|
||||||
typedef struct Proc Proc;
|
typedef struct Proc Proc;
|
||||||
typedef struct PMMU PMMU;
|
typedef struct PMMU PMMU;
|
||||||
|
@ -43,9 +43,12 @@ struct FPsave
|
||||||
uchar regs[256];
|
uchar regs[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
struct PFPU
|
||||||
* FPsave.status
|
{
|
||||||
*/
|
int fpstate;
|
||||||
|
FPsave fpsave[1];
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FPinit,
|
FPinit,
|
||||||
|
@ -79,13 +82,6 @@ struct Conf
|
||||||
int monitor;
|
int monitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* things saved in the Proc structure during a notify
|
|
||||||
*/
|
|
||||||
struct Notsave {
|
|
||||||
int emptiness;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMU stuff in proc
|
* MMU stuff in proc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -50,10 +50,10 @@ procfork(Proc *p)
|
||||||
s = splhi();
|
s = splhi();
|
||||||
switch(up->fpstate & ~FPillegal){
|
switch(up->fpstate & ~FPillegal){
|
||||||
case FPactive:
|
case FPactive:
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
p->fpsave = up->fpsave;
|
memmove(p->fpsave, up->fpsave, sizeof(FPsave));
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
splx(s);
|
splx(s);
|
||||||
|
|
|
@ -134,7 +134,7 @@ mathtrap(Ureg *, ulong)
|
||||||
break;
|
break;
|
||||||
case FPinactive:
|
case FPinactive:
|
||||||
s = splhi();
|
s = splhi();
|
||||||
fprestore(&up->fpsave);
|
fprestore(up->fpsave);
|
||||||
up->fpstate = FPactive;
|
up->fpstate = FPactive;
|
||||||
splx(s);
|
splx(s);
|
||||||
break;
|
break;
|
||||||
|
@ -304,7 +304,7 @@ notify(Ureg *ureg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(up->fpstate == FPactive){
|
if(up->fpstate == FPactive){
|
||||||
fpsave(&up->fpsave);
|
fpsave(up->fpsave);
|
||||||
up->fpstate = FPinactive;
|
up->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
up->fpstate |= FPillegal;
|
up->fpstate |= FPillegal;
|
||||||
|
@ -517,7 +517,7 @@ procsave(Proc *p)
|
||||||
if(p->state == Moribund)
|
if(p->state == Moribund)
|
||||||
fpclear();
|
fpclear();
|
||||||
else
|
else
|
||||||
fpsave(&p->fpsave);
|
fpsave(p->fpsave);
|
||||||
p->fpstate = FPinactive;
|
p->fpstate = FPinactive;
|
||||||
}
|
}
|
||||||
cycles(&t);
|
cycles(&t);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue