- Rename cpu_use_fxsave to i386_use_fxsave.

- If we detect SSE/SSE2 support in the CPU, enable SSE exceptions
  and set i386_has_{sse,sse2} as appropriate.
- Expose i386_use_fxsave and i386_has_{sse,sse2} through sysctl
  as machdep.{osfsxr,sse,sse2}.
This commit is contained in:
thorpej 2001-08-02 22:04:28 +00:00
parent 99a7f640fe
commit f0449fd933
4 changed files with 47 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.450 2001/08/02 21:04:43 thorpej Exp $ */ /* $NetBSD: machdep.c,v 1.451 2001/08/02 22:04:28 thorpej Exp $ */
/*- /*-
* Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
@ -200,7 +200,9 @@ int i386_fpu_present;
int i386_fpu_exception; int i386_fpu_exception;
int i386_fpu_fdivbug; int i386_fpu_fdivbug;
int cpu_use_fxsave; int i386_use_fxsave;
int i386_has_sse;
int i386_has_sse2;
#define CPUID2MODEL(cpuid) (((cpuid) >> 4) & 15) #define CPUID2MODEL(cpuid) (((cpuid) >> 4) & 15)
@ -1523,10 +1525,22 @@ identifycpu(struct cpu_info *ci)
* If we have FXSAVE/FXRESTOR, use them. * If we have FXSAVE/FXRESTOR, use them.
*/ */
if (cpu_feature & CPUID_FXSR) { if (cpu_feature & CPUID_FXSR) {
cpu_use_fxsave = 1; i386_use_fxsave = 1;
lcr4(rcr4() | CR4_OSFXSR); lcr4(rcr4() | CR4_OSFXSR);
/*
* If we have SSE/SSE2, enable XMM exceptions, and
* notify userland.
*/
if (cpu_feature & (CPUID_SSE|CPUID_SSE2)) {
if (cpu_feature & CPUID_SSE)
i386_has_sse = 1;
if (cpu_feature & CPUID_SSE2)
i386_has_sse2 = 1;
lcr4(rcr4() | CR4_OSXMMEXCPT);
}
} else } else
cpu_use_fxsave = 0; i386_use_fxsave = 0;
#endif /* I686_CPU */ #endif /* I686_CPU */
} }
@ -1582,6 +1596,13 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
return (sysctl_rdstruct(oldp, oldlenp, newp, i386_alldisks, return (sysctl_rdstruct(oldp, oldlenp, newp, i386_alldisks,
sizeof (struct disklist) + sizeof (struct disklist) +
(i386_ndisks - 1) * sizeof (struct nativedisk_info))); (i386_ndisks - 1) * sizeof (struct nativedisk_info)));
case CPU_OSFXSR:
return (sysctl_rdint(oldp, oldlenp, newp, i386_use_fxsave));
case CPU_SSE:
return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse));
case CPU_SSE2:
return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse2));
default: default:
return (EOPNOTSUPP); return (EOPNOTSUPP);
} }
@ -2145,7 +2166,7 @@ setregs(p, pack, stack)
p->p_md.md_flags &= ~MDP_USEDFPU; p->p_md.md_flags &= ~MDP_USEDFPU;
pcb->pcb_flags = 0; pcb->pcb_flags = 0;
if (cpu_use_fxsave) if (i386_use_fxsave)
pcb->pcb_savefpu.sv_xmm.sv_env.en_cw = __NetBSD_NPXCW__; pcb->pcb_savefpu.sv_xmm.sv_env.en_cw = __NetBSD_NPXCW__;
else else
pcb->pcb_savefpu.sv_87.sv_env.en_cw = __NetBSD_NPXCW__; pcb->pcb_savefpu.sv_87.sv_env.en_cw = __NetBSD_NPXCW__;

View File

@ -1,4 +1,4 @@
/* $NetBSD: process_machdep.c,v 1.35 2001/08/02 21:04:44 thorpej Exp $ */ /* $NetBSD: process_machdep.c,v 1.36 2001/08/02 22:04:28 thorpej Exp $ */
/*- /*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@ -222,7 +222,7 @@ process_read_fpregs(p, regs)
* The initial control word was already set by setregs(), so * The initial control word was already set by setregs(), so
* save it temporarily. * save it temporarily.
*/ */
if (cpu_use_fxsave) { if (i386_use_fxsave) {
cw = frame->sv_xmm.sv_env.en_cw; cw = frame->sv_xmm.sv_env.en_cw;
/* XXX Don't zero XMM regs? */ /* XXX Don't zero XMM regs? */
memset(&frame->sv_xmm, 0, sizeof(frame->sv_xmm)); memset(&frame->sv_xmm, 0, sizeof(frame->sv_xmm));
@ -239,7 +239,7 @@ process_read_fpregs(p, regs)
p->p_md.md_flags |= MDP_USEDFPU; p->p_md.md_flags |= MDP_USEDFPU;
} }
if (cpu_use_fxsave) { if (i386_use_fxsave) {
struct save87 s87; struct save87 s87;
/* XXX Yuck */ /* XXX Yuck */
@ -320,7 +320,7 @@ process_write_fpregs(p, regs)
p->p_md.md_flags |= MDP_USEDFPU; p->p_md.md_flags |= MDP_USEDFPU;
} }
if (cpu_use_fxsave) { if (i386_use_fxsave) {
struct save87 s87; struct save87 s87;
/* XXX Yuck. */ /* XXX Yuck. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.74 2001/08/02 21:04:44 thorpej Exp $ */ /* $NetBSD: cpu.h,v 1.75 2001/08/02 22:04:29 thorpej Exp $ */
/*- /*-
* Copyright (c) 1990 The Regents of the University of California. * Copyright (c) 1990 The Regents of the University of California.
@ -181,7 +181,9 @@ extern int cpuid_level;
extern const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[]; extern const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[];
extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[]; extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[];
extern int cpu_use_fxsave; extern int i386_use_fxsave;
extern int i386_has_sse;
extern int i386_has_sse2;
/* machdep.c */ /* machdep.c */
void delay __P((int)); void delay __P((int));
@ -259,7 +261,10 @@ void i386_bus_space_mallocok __P((void));
#define CPU_BOOTED_KERNEL 5 /* string: booted kernel name */ #define CPU_BOOTED_KERNEL 5 /* string: booted kernel name */
#define CPU_DISKINFO 6 /* disk geometry information */ #define CPU_DISKINFO 6 /* disk geometry information */
#define CPU_FPU_PRESENT 7 /* FPU is present */ #define CPU_FPU_PRESENT 7 /* FPU is present */
#define CPU_MAXID 8 /* number of valid machdep ids */ #define CPU_OSFXSR 8 /* OS uses FXSAVE/FXRSTOR */
#define CPU_SSE 9 /* OS/CPU supports SSE */
#define CPU_SSE2 10 /* OS/CPU supports SSE2 */
#define CPU_MAXID 11 /* number of valid machdep ids */
#define CTL_MACHDEP_NAMES { \ #define CTL_MACHDEP_NAMES { \
{ 0, 0 }, \ { 0, 0 }, \
@ -270,6 +275,9 @@ void i386_bus_space_mallocok __P((void));
{ "booted_kernel", CTLTYPE_STRING }, \ { "booted_kernel", CTLTYPE_STRING }, \
{ "diskinfo", CTLTYPE_STRUCT }, \ { "diskinfo", CTLTYPE_STRUCT }, \
{ "fpu_present", CTLTYPE_INT }, \ { "fpu_present", CTLTYPE_INT }, \
{ "osfxsr", CTLTYPE_INT }, \
{ "sse", CTLTYPE_INT }, \
{ "sse2", CTLTYPE_INT }, \
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: npx.c,v 1.77 2001/08/02 21:04:45 thorpej Exp $ */ /* $NetBSD: npx.c,v 1.78 2001/08/02 22:04:29 thorpej Exp $ */
#if 0 #if 0
#define IPRINTF(x) printf x #define IPRINTF(x) printf x
@ -114,7 +114,7 @@ fpu_save(union savefpu *addr)
{ {
#ifdef I686_CPU #ifdef I686_CPU
if (cpu_use_fxsave) { if (i386_use_fxsave) {
fxsave(&addr->sv_xmm); fxsave(&addr->sv_xmm);
/* FXSAVE doesn't FNINIT like FNSAVE does -- so do it here. */ /* FXSAVE doesn't FNINIT like FNSAVE does -- so do it here. */
fwait(); /* XXX needed? */ fwait(); /* XXX needed? */
@ -271,7 +271,7 @@ npxattach(struct npx_softc *sc)
i386_fpu_present = 1; i386_fpu_present = 1;
#ifdef I686_CPU #ifdef I686_CPU
if (cpu_use_fxsave) if (i386_use_fxsave)
npxdna_func = npxdna_xmm; npxdna_func = npxdna_xmm;
else else
#endif /* I686_CPU */ #endif /* I686_CPU */
@ -348,7 +348,7 @@ npxintr(void *arg)
/* /*
* Restore control word (was clobbered by fpu_save). * Restore control word (was clobbered by fpu_save).
*/ */
if (cpu_use_fxsave) if (i386_use_fxsave)
fldcw(&addr->sv_xmm.sv_env.en_cw); fldcw(&addr->sv_xmm.sv_env.en_cw);
else else
fldcw(&addr->sv_87.sv_env.en_cw); fldcw(&addr->sv_87.sv_env.en_cw);
@ -361,7 +361,7 @@ npxintr(void *arg)
* preserved the control word and will copy the status and tag * preserved the control word and will copy the status and tag
* words, so the complete exception state can be recovered. * words, so the complete exception state can be recovered.
*/ */
if (cpu_use_fxsave) { if (i386_use_fxsave) {
addr->sv_xmm.sv_ex_sw = addr->sv_xmm.sv_env.en_sw; addr->sv_xmm.sv_ex_sw = addr->sv_xmm.sv_env.en_sw;
addr->sv_xmm.sv_ex_tw = addr->sv_xmm.sv_env.en_tw; addr->sv_xmm.sv_ex_tw = addr->sv_xmm.sv_env.en_tw;
} else { } else {
@ -514,7 +514,7 @@ npxdna_s87(struct proc *p)
npxproc = p; npxproc = p;
if ((p->p_md.md_flags & MDP_USEDFPU) == 0) { if ((p->p_md.md_flags & MDP_USEDFPU) == 0) {
if (cpu_use_fxsave) if (i386_use_fxsave)
fldcw(&p->p_addr->u_pcb.pcb_savefpu.sv_xmm.sv_env.en_cw); fldcw(&p->p_addr->u_pcb.pcb_savefpu.sv_xmm.sv_env.en_cw);
else else
fldcw(&p->p_addr->u_pcb.pcb_savefpu.sv_87.sv_env.en_cw); fldcw(&p->p_addr->u_pcb.pcb_savefpu.sv_87.sv_env.en_cw);