Add a small API for in-kernel FPU operations.
fpu_kern_enter(); /* do FPU stuff */ fpu_kern_leave();
This commit is contained in:
parent
9191368464
commit
9684bbd4f4
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.h,v 1.113 2019/11/23 19:40:37 ad Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.114 2019/11/27 06:24:33 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
|
@ -139,6 +139,8 @@ struct cpu_info {
|
|||
uintptr_t ci_pmap_data[64 / sizeof(uintptr_t)];
|
||||
struct kcpuset *ci_tlb_cpuset;
|
||||
|
||||
int ci_kfpu_spl;
|
||||
|
||||
#ifndef XENPV
|
||||
struct intrsource *ci_isources[MAX_INTR_SOURCES];
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu.h,v 1.19 2019/10/12 06:31:03 maxv Exp $ */
|
||||
/* $NetBSD: fpu.h,v 1.20 2019/11/27 06:24:33 maxv Exp $ */
|
||||
|
||||
#ifndef _X86_FPU_H_
|
||||
#define _X86_FPU_H_
|
||||
|
@ -30,6 +30,9 @@ void fpu_sigreset(struct lwp *);
|
|||
void fpu_lwp_fork(struct lwp *, struct lwp *);
|
||||
void fpu_lwp_abandon(struct lwp *l);
|
||||
|
||||
void fpu_kern_enter(void);
|
||||
void fpu_kern_leave(void);
|
||||
|
||||
void process_write_fpregs_xmm(struct lwp *, const struct fxsave *);
|
||||
void process_write_fpregs_s87(struct lwp *, const struct save87 *);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.c,v 1.176 2019/11/23 19:40:37 ad Exp $ */
|
||||
/* $NetBSD: cpu.c,v 1.177 2019/11/27 06:24:33 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2012 NetBSD Foundation, Inc.
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.176 2019/11/23 19:40:37 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.177 2019/11/27 06:24:33 maxv Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_mpbios.h" /* for MPDEBUG */
|
||||
|
@ -376,6 +376,7 @@ cpu_attach(device_t parent, device_t self, void *aux)
|
|||
ci->ci_acpiid = caa->cpu_id;
|
||||
ci->ci_cpuid = caa->cpu_number;
|
||||
ci->ci_func = caa->cpu_func;
|
||||
ci->ci_kfpu_spl = -1;
|
||||
aprint_normal("\n");
|
||||
|
||||
/* Must be before mi_cpu_attach(). */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fpu.c,v 1.59 2019/10/30 16:32:04 maxv Exp $ */
|
||||
/* $NetBSD: fpu.c,v 1.60 2019/11/27 06:24:33 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, 2019 The NetBSD Foundation, Inc. All
|
||||
|
@ -96,7 +96,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.59 2019/10/30 16:32:04 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.60 2019/11/27 06:24:33 maxv Exp $");
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
|
||||
|
@ -146,14 +146,9 @@ fpu_lwp_area(struct lwp *l)
|
|||
return area;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bring curlwp's FPU state in memory. It will get installed back in the CPU
|
||||
* when returning to userland.
|
||||
*/
|
||||
void
|
||||
fpu_save(void)
|
||||
static inline void
|
||||
fpu_save_lwp(struct lwp *l)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
struct pcb *pcb = lwp_getpcb(l);
|
||||
union savefpu *area = &pcb->pcb_savefpu;
|
||||
|
||||
|
@ -166,6 +161,16 @@ fpu_save(void)
|
|||
kpreempt_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Bring curlwp's FPU state in memory. It will get installed back in the CPU
|
||||
* when returning to userland.
|
||||
*/
|
||||
void
|
||||
fpu_save(void)
|
||||
{
|
||||
fpu_save_lwp(curlwp);
|
||||
}
|
||||
|
||||
void
|
||||
fpuinit(struct cpu_info *ci)
|
||||
{
|
||||
|
@ -338,6 +343,45 @@ fpu_lwp_abandon(struct lwp *l)
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
fpu_kern_enter(void)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
struct cpu_info *ci;
|
||||
int s;
|
||||
|
||||
s = splhigh();
|
||||
|
||||
ci = curcpu();
|
||||
KASSERT(ci->ci_kfpu_spl == -1);
|
||||
ci->ci_kfpu_spl = s;
|
||||
|
||||
/*
|
||||
* If we are in a softint and have a pinned lwp, the fpu state is that
|
||||
* of the pinned lwp, so save it there.
|
||||
*/
|
||||
if ((l->l_pflag & LP_INTR) && (l->l_switchto != NULL)) {
|
||||
fpu_save_lwp(l->l_switchto);
|
||||
} else {
|
||||
fpu_save_lwp(l);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fpu_kern_leave(void)
|
||||
{
|
||||
struct cpu_info *ci = curcpu();
|
||||
int s;
|
||||
|
||||
KASSERT(ci->ci_ilevel == IPL_HIGH);
|
||||
KASSERT(ci->ci_kfpu_spl != -1);
|
||||
s = ci->ci_kfpu_spl;
|
||||
ci->ci_kfpu_spl = -1;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The following table is used to ensure that the FPE_... value
|
||||
* that is passed as a trapcode to the signal handler of the user
|
||||
|
|
Loading…
Reference in New Issue