diff options
author | John Baldwin <jhb@FreeBSD.org> | 2014-11-02 22:58:30 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2014-11-02 22:58:30 +0000 |
commit | 824fc46089a4b86003cef4fcbfa8493591e87719 (patch) | |
tree | 42bdf4fc68fe06b5bb16808009a36a866b42ab0c /sys/i386/i386/sys_machdep.c | |
parent | da1304cb4234a13133414351922bbd7297793988 (diff) | |
download | src-824fc46089a4b86003cef4fcbfa8493591e87719.tar.gz src-824fc46089a4b86003cef4fcbfa8493591e87719.zip |
MFamd64: Add support for extended FPU states on i386. This includes
support for AVX on i386.
- Similar to amd64, move the FPU save area out of the PCB and instead
store saved FPU state in a variable-sized buffer after the PCB on the
stack.
- To support the variable PCB location, alter the locore code to only use
the bottom-most page of proc0stack for init386(). init386() returns
the correct stack pointer to locore which adjusts the stack for thread0
before calling mi_startup().
- Don't bother setting cr3 in thread0's pcb in locore before calling
init386(). It wasn't used (init386() overwrote it at the end) and
it doesn't work with the variable-sized FPU save area.
- Remove the new-bus attachment from npx. This was only ever useful for
external co-processors using IRQ13, but those have not been supported
for several years. npxinit() is now called much earlier during boot
(init386()) similar to amd64.
- Implement PT_{GET,SET}XSTATE and I386_GET_XFPUSTATE.
- npxsave() is now only called from context switch contexts so it can
use XSAVEOPT.
Differential Revision: https://reviews.freebsd.org/D1058
Reviewed by: kib
Tested on: FreeBSD/i386 VM under bhyve on Intel i5-2520
Notes
Notes:
svn path=/head/; revision=273995
Diffstat (limited to 'sys/i386/i386/sys_machdep.c')
-rw-r--r-- | sys/i386/i386/sys_machdep.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c index 4245748efa4b..951886273107 100644 --- a/sys/i386/i386/sys_machdep.c +++ b/sys/i386/i386/sys_machdep.c @@ -105,6 +105,7 @@ sysarch(td, uap) union { struct i386_ldt_args largs; struct i386_ioperm_args iargs; + struct i386_get_xfpustate xfpu; } kargs; uint32_t base; struct segment_descriptor sd, *sdp; @@ -126,6 +127,7 @@ sysarch(td, uap) case I386_SET_FSBASE: case I386_GET_GSBASE: case I386_SET_GSBASE: + case I386_GET_XFPUSTATE: break; case I386_SET_IOPERM: @@ -154,6 +156,11 @@ sysarch(td, uap) if (kargs.largs.num > MAX_LD || kargs.largs.num <= 0) return (EINVAL); break; + case I386_GET_XFPUSTATE: + if ((error = copyin(uap->parms, &kargs.xfpu, + sizeof(struct i386_get_xfpustate))) != 0) + return (error); + break; default: break; } @@ -270,6 +277,14 @@ sysarch(td, uap) load_gs(GSEL(GUGS_SEL, SEL_UPL)); } break; + case I386_GET_XFPUSTATE: + if (kargs.xfpu.len > cpu_max_ext_state_size - + sizeof(union savefpu)) + return (EINVAL); + npxgetregs(td); + error = copyout((char *)(get_pcb_user_save_td(td) + 1), + kargs.xfpu.addr, kargs.xfpu.len); + break; default: error = EINVAL; break; |