Add kernel support needed for the KSE-aware libpthread:
- Maintain fpu state across signals. - Save and restore FPU state properly in ucontext_t's. Reviewed by: deischen, julian Approved by: -arch
This commit is contained in:
parent
d0ffcf396d
commit
62e41a5a7c
@ -73,7 +73,7 @@ struct fpacc87 {
|
||||
struct save87 {
|
||||
struct env87 sv_env; /* floating point control/status */
|
||||
struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */
|
||||
u_long sv_ex_sw; /* status word for last exception */
|
||||
u_char sv_pad0[4]; /* padding for (now unused) saved status word */
|
||||
/*
|
||||
* Bogus padding for emulators. Emulators should use their own
|
||||
* struct and arrange to store into this struct (ending here)
|
||||
@ -112,8 +112,7 @@ struct savexmm {
|
||||
u_char fp_pad[6]; /* padding */
|
||||
} sv_fp[8];
|
||||
struct xmmacc sv_xmm[8];
|
||||
u_long sv_ex_sw; /* status word for last exception */
|
||||
u_char sv_pad[220];
|
||||
u_char sv_pad[224];
|
||||
} __attribute__((aligned(16)));
|
||||
|
||||
union savefpu {
|
||||
@ -142,9 +141,13 @@ union savefpu {
|
||||
|
||||
#ifdef _KERNEL
|
||||
int npxdna(void);
|
||||
void npxdrop(void);
|
||||
void npxexit(struct thread *td);
|
||||
void npxinit(int control);
|
||||
int npxformat(void);
|
||||
int npxgetregs(struct thread *td, union savefpu *addr);
|
||||
void npxinit(u_short control);
|
||||
void npxsave(union savefpu *addr);
|
||||
void npxsetregs(struct thread *td, union savefpu *addr);
|
||||
int npxtrap(void);
|
||||
#endif
|
||||
|
||||
|
@ -73,7 +73,7 @@ struct fpacc87 {
|
||||
struct save87 {
|
||||
struct env87 sv_env; /* floating point control/status */
|
||||
struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */
|
||||
u_long sv_ex_sw; /* status word for last exception */
|
||||
u_char sv_pad0[4]; /* padding for (now unused) saved status word */
|
||||
/*
|
||||
* Bogus padding for emulators. Emulators should use their own
|
||||
* struct and arrange to store into this struct (ending here)
|
||||
@ -112,8 +112,7 @@ struct savexmm {
|
||||
u_char fp_pad[6]; /* padding */
|
||||
} sv_fp[8];
|
||||
struct xmmacc sv_xmm[8];
|
||||
u_long sv_ex_sw; /* status word for last exception */
|
||||
u_char sv_pad[220];
|
||||
u_char sv_pad[224];
|
||||
} __attribute__((aligned(16)));
|
||||
|
||||
union savefpu {
|
||||
@ -142,9 +141,13 @@ union savefpu {
|
||||
|
||||
#ifdef _KERNEL
|
||||
int npxdna(void);
|
||||
void npxdrop(void);
|
||||
void npxexit(struct thread *td);
|
||||
void npxinit(int control);
|
||||
int npxformat(void);
|
||||
int npxgetregs(struct thread *td, union savefpu *addr);
|
||||
void npxinit(u_short control);
|
||||
void npxsave(union savefpu *addr);
|
||||
void npxsetregs(struct thread *td, union savefpu *addr);
|
||||
int npxtrap(void);
|
||||
#endif
|
||||
|
||||
|
@ -66,6 +66,7 @@ struct pcb {
|
||||
#define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */
|
||||
#define PCB_DBREGS 0x02 /* process using debug registers */
|
||||
#define PCB_NPXTRAP 0x04 /* npx trap pending */
|
||||
#define PCB_NPXINITDONE 0x08 /* fpu state is initialized */
|
||||
caddr_t pcb_onfault; /* copyin/out fault recovery */
|
||||
int pcb_gs;
|
||||
struct pcb_ext *pcb_ext; /* optional pcb extension */
|
||||
|
@ -117,13 +117,16 @@ struct sigcontext {
|
||||
int sc_efl;
|
||||
int sc_esp;
|
||||
int sc_ss;
|
||||
int sc_len; /* sizeof(struct mcontext_t) */
|
||||
/*
|
||||
* XXX FPU state is 27 * 4 bytes h/w, 1 * 4 bytes s/w (probably not
|
||||
* needed here), or that + 16 * 4 bytes for emulators (probably all
|
||||
* needed here). The "spare" bytes are mostly not spare.
|
||||
* XXX - See <machine/ucontext.h> and <machine/npx.h> for
|
||||
* the following fields.
|
||||
*/
|
||||
int sc_fpregs[28]; /* machine state (FPU): */
|
||||
int sc_spare[17];
|
||||
int sc_fpformat;
|
||||
int sc_ownedfp;
|
||||
int sc_spare1[1];
|
||||
int sc_fpregs[128];
|
||||
int sc_spare2[8];
|
||||
};
|
||||
|
||||
#define sc_sp sc_esp
|
||||
|
@ -58,11 +58,25 @@ typedef struct __mcontext {
|
||||
int mc_esp; /* machine state */
|
||||
int mc_ss;
|
||||
|
||||
int mc_fpregs[28]; /* env87 + fpacc87 + u_long */
|
||||
#define __UC_MC_VALID 0x0001 /* mcontext register state is valid */
|
||||
#define __UC_FP_VALID 0x0002 /* FP registers have been saved */
|
||||
int mc_flags;
|
||||
int __spare__[16];
|
||||
int mc_len; /* sizeof(mcontext_t) */
|
||||
#define _MC_FPFMT_NODEV 0 /* device not present or configured */
|
||||
#define _MC_FPFMT_387 1
|
||||
#define _MC_FPFMT_XMM 2
|
||||
int mc_fpformat;
|
||||
#define _MC_FPOWNED_NONE 0 /* FP state not used */
|
||||
#define _MC_FPOWNED_FPU 1 /* FP state came from FPU */
|
||||
#define _MC_FPOWNED_PCB 2 /* FP state came from PCB */
|
||||
int mc_ownedfp;
|
||||
int mc_spare1[1]; /* align next field to 16 bytes */
|
||||
int mc_fpstate[128]; /* must be multiple of 16 bytes */
|
||||
int mc_spare2[8];
|
||||
} mcontext_t;
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct thread;
|
||||
|
||||
void get_mcontext(struct thread *td, mcontext_t *mcp);
|
||||
int set_mcontext(struct thread *td, const mcontext_t *mcp);
|
||||
#endif
|
||||
|
||||
#endif /* !_MACHINE_UCONTEXT_H_ */
|
||||
|
@ -73,7 +73,7 @@ struct fpacc87 {
|
||||
struct save87 {
|
||||
struct env87 sv_env; /* floating point control/status */
|
||||
struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */
|
||||
u_long sv_ex_sw; /* status word for last exception */
|
||||
u_char sv_pad0[4]; /* padding for (now unused) saved status word */
|
||||
/*
|
||||
* Bogus padding for emulators. Emulators should use their own
|
||||
* struct and arrange to store into this struct (ending here)
|
||||
@ -112,8 +112,7 @@ struct savexmm {
|
||||
u_char fp_pad[6]; /* padding */
|
||||
} sv_fp[8];
|
||||
struct xmmacc sv_xmm[8];
|
||||
u_long sv_ex_sw; /* status word for last exception */
|
||||
u_char sv_pad[220];
|
||||
u_char sv_pad[224];
|
||||
} __attribute__((aligned(16)));
|
||||
|
||||
union savefpu {
|
||||
@ -142,9 +141,13 @@ union savefpu {
|
||||
|
||||
#ifdef _KERNEL
|
||||
int npxdna(void);
|
||||
void npxdrop(void);
|
||||
void npxexit(struct thread *td);
|
||||
void npxinit(int control);
|
||||
int npxformat(void);
|
||||
int npxgetregs(struct thread *td, union savefpu *addr);
|
||||
void npxinit(u_short control);
|
||||
void npxsave(union savefpu *addr);
|
||||
void npxsetregs(struct thread *td, union savefpu *addr);
|
||||
int npxtrap(void);
|
||||
#endif
|
||||
|
||||
|
@ -66,6 +66,7 @@ struct pcb {
|
||||
#define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */
|
||||
#define PCB_DBREGS 0x02 /* process using debug registers */
|
||||
#define PCB_NPXTRAP 0x04 /* npx trap pending */
|
||||
#define PCB_NPXINITDONE 0x08 /* fpu state is initialized */
|
||||
caddr_t pcb_onfault; /* copyin/out fault recovery */
|
||||
int pcb_gs;
|
||||
struct pcb_ext *pcb_ext; /* optional pcb extension */
|
||||
|
@ -117,13 +117,16 @@ struct sigcontext {
|
||||
int sc_efl;
|
||||
int sc_esp;
|
||||
int sc_ss;
|
||||
int sc_len; /* sizeof(struct mcontext_t) */
|
||||
/*
|
||||
* XXX FPU state is 27 * 4 bytes h/w, 1 * 4 bytes s/w (probably not
|
||||
* needed here), or that + 16 * 4 bytes for emulators (probably all
|
||||
* needed here). The "spare" bytes are mostly not spare.
|
||||
* XXX - See <machine/ucontext.h> and <machine/npx.h> for
|
||||
* the following fields.
|
||||
*/
|
||||
int sc_fpregs[28]; /* machine state (FPU): */
|
||||
int sc_spare[17];
|
||||
int sc_fpformat;
|
||||
int sc_ownedfp;
|
||||
int sc_spare1[1];
|
||||
int sc_fpregs[128];
|
||||
int sc_spare2[8];
|
||||
};
|
||||
|
||||
#define sc_sp sc_esp
|
||||
|
@ -58,11 +58,25 @@ typedef struct __mcontext {
|
||||
int mc_esp; /* machine state */
|
||||
int mc_ss;
|
||||
|
||||
int mc_fpregs[28]; /* env87 + fpacc87 + u_long */
|
||||
#define __UC_MC_VALID 0x0001 /* mcontext register state is valid */
|
||||
#define __UC_FP_VALID 0x0002 /* FP registers have been saved */
|
||||
int mc_flags;
|
||||
int __spare__[16];
|
||||
int mc_len; /* sizeof(mcontext_t) */
|
||||
#define _MC_FPFMT_NODEV 0 /* device not present or configured */
|
||||
#define _MC_FPFMT_387 1
|
||||
#define _MC_FPFMT_XMM 2
|
||||
int mc_fpformat;
|
||||
#define _MC_FPOWNED_NONE 0 /* FP state not used */
|
||||
#define _MC_FPOWNED_FPU 1 /* FP state came from FPU */
|
||||
#define _MC_FPOWNED_PCB 2 /* FP state came from PCB */
|
||||
int mc_ownedfp;
|
||||
int mc_spare1[1]; /* align next field to 16 bytes */
|
||||
int mc_fpstate[128]; /* must be multiple of 16 bytes */
|
||||
int mc_spare2[8];
|
||||
} mcontext_t;
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct thread;
|
||||
|
||||
void get_mcontext(struct thread *td, mcontext_t *mcp);
|
||||
int set_mcontext(struct thread *td, const mcontext_t *mcp);
|
||||
#endif
|
||||
|
||||
#endif /* !_MACHINE_UCONTEXT_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user