Index: common/kernel.c @@ -1240,6 +1240,11 @@ case MON_REQ_EXCEPTION: exec_exception(s->arg0); break; +#ifdef __FreeBSD__ + case MON_REQ_LOADFPUCONTEXT: + kqemu_loadfpucontext(s->arg0); + break; +#endif default: kqemu_log("invalid mon request: %d\n", s->mon_req); break; Index: common/kqemu_int.h @@ -523,6 +523,7 @@ MON_REQ_LOCK_USER_PAGE, MON_REQ_UNLOCK_USER_PAGE, MON_REQ_EXCEPTION, + MON_REQ_LOADFPUCONTEXT, } MonitorRequest; #define INTERRUPT_ENTRY_SIZE 16 Index: common/monitor.c @@ -1995,8 +1995,13 @@ raise_exception_err(s, EXCP07_PREX, 0); } else { /* the host needs to restore the FPU state for us */ +#ifndef __FreeBSD__ s->mon_req = MON_REQ_EXCEPTION; s->arg0 = 0x07; +#else + s->mon_req = MON_REQ_LOADFPUCONTEXT; + s->arg0 = (unsigned long)s->cpu_state.cpl; +#endif monitor2kernel1(s); } } Index: kqemu-freebsd.c @@ -33,6 +33,11 @@ #include #include +#ifdef __x86_64__ +#include +#else +#include +#endif #include "kqemu-kernel.h" @@ -172,6 +177,15 @@ { } +void CDECL kqemu_loadfpucontext(unsigned long cpl) +{ +#ifdef __x86_64__ + fpudna(); +#else + npxdna(); +#endif +} + #if __FreeBSD_version < 500000 static int curpriority_cmp(struct proc *p) Index: kqemu-kernel.h @@ -40,6 +40,10 @@ void * CDECL kqemu_io_map(unsigned long page_index, unsigned int size); void CDECL kqemu_io_unmap(void *ptr, unsigned int size); +#ifdef __FreeBSD__ +void CDECL kqemu_loadfpucontext(unsigned long cpl); +#endif + int CDECL kqemu_schedule(void); void CDECL kqemu_log(const char *fmt, ...);