diff options
author | Jonathan Mini <mini@FreeBSD.org> | 2002-09-16 19:25:41 +0000 |
---|---|---|
committer | Jonathan Mini <mini@FreeBSD.org> | 2002-09-16 19:25:41 +0000 |
commit | 9ba15479299f7ead3ea98f04cf0ff46c48160f49 (patch) | |
tree | f68cce90cf752f653302c6c5c0876070f6fff7ab /sys | |
parent | 575525a0005f266a0dee465d9df7127bfeef2c24 (diff) | |
download | src-9ba15479299f7ead3ea98f04cf0ff46c48160f49.tar.gz src-9ba15479299f7ead3ea98f04cf0ff46c48160f49.zip |
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
Notes
Notes:
svn path=/head/; revision=103408
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/include/fpu.h | 11 | ||||
-rw-r--r-- | sys/amd64/include/npx.h | 11 | ||||
-rw-r--r-- | sys/amd64/include/pcb.h | 1 | ||||
-rw-r--r-- | sys/amd64/include/signal.h | 13 | ||||
-rw-r--r-- | sys/amd64/include/ucontext.h | 24 | ||||
-rw-r--r-- | sys/i386/include/npx.h | 11 | ||||
-rw-r--r-- | sys/i386/include/pcb.h | 1 | ||||
-rw-r--r-- | sys/i386/include/signal.h | 13 | ||||
-rw-r--r-- | sys/i386/include/ucontext.h | 24 |
9 files changed, 77 insertions, 32 deletions
diff --git a/sys/amd64/include/fpu.h b/sys/amd64/include/fpu.h index 4746f5cefda3..0b662659cc05 100644 --- a/sys/amd64/include/fpu.h +++ b/sys/amd64/include/fpu.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 diff --git a/sys/amd64/include/npx.h b/sys/amd64/include/npx.h index 4746f5cefda3..0b662659cc05 100644 --- a/sys/amd64/include/npx.h +++ b/sys/amd64/include/npx.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 diff --git a/sys/amd64/include/pcb.h b/sys/amd64/include/pcb.h index 860b3b5143b4..50cff0774718 100644 --- a/sys/amd64/include/pcb.h +++ b/sys/amd64/include/pcb.h @@ -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 */ diff --git a/sys/amd64/include/signal.h b/sys/amd64/include/signal.h index 603a14f70fee..bf76791841d1 100644 --- a/sys/amd64/include/signal.h +++ b/sys/amd64/include/signal.h @@ -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 diff --git a/sys/amd64/include/ucontext.h b/sys/amd64/include/ucontext.h index a84a2cb3fe3b..1739818a1049 100644 --- a/sys/amd64/include/ucontext.h +++ b/sys/amd64/include/ucontext.h @@ -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_ */ diff --git a/sys/i386/include/npx.h b/sys/i386/include/npx.h index 4746f5cefda3..0b662659cc05 100644 --- a/sys/i386/include/npx.h +++ b/sys/i386/include/npx.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 diff --git a/sys/i386/include/pcb.h b/sys/i386/include/pcb.h index 860b3b5143b4..50cff0774718 100644 --- a/sys/i386/include/pcb.h +++ b/sys/i386/include/pcb.h @@ -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 */ diff --git a/sys/i386/include/signal.h b/sys/i386/include/signal.h index 603a14f70fee..bf76791841d1 100644 --- a/sys/i386/include/signal.h +++ b/sys/i386/include/signal.h @@ -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 diff --git a/sys/i386/include/ucontext.h b/sys/i386/include/ucontext.h index a84a2cb3fe3b..1739818a1049 100644 --- a/sys/i386/include/ucontext.h +++ b/sys/i386/include/ucontext.h @@ -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_ */ |