From owner-freebsd-audit Tue Jan 22 4:37:27 2002 Delivered-To: freebsd-audit@freebsd.org Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by hub.freebsd.org (Postfix) with SMTP id E658837B402; Tue, 22 Jan 2002 04:37:19 -0800 (PST) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 22 Jan 2002 12:28:39 +0000 (GMT) To: freebsd-audit@freebsd.org Cc: peter@freebsd.org, clemej@alum.rpi.edu Subject: Athlon SSE patch. X-Request-Do: Date: Tue, 22 Jan 2002 12:28:38 +0000 From: David Malone Message-ID: <200201221228.ab83863@salmon.maths.tcd.ie> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG It seems that Athlon processors need the BIOS to enable SSE if it is present on your processor. It also seems that some BIOS writers don't do this for all processors (I have a ASUS A7A266 which claims to support my Athlon XP, but doesn't enable SSE). Based on a description of the problem which I found at: http://www.deater.net/john/PavilionN5430.html I've produced a patch for FreeBSD-current. Since AMD doc 21656 doesn't seem to be publically available I can't really check the patch is exactly right, but it does work on my processor. I'd like to commit this patch in a few days. If someone else has a recent Athlon which doesn't show SSE in the list of features I'd be greatful if they could test the patch for me. (This involved rebuilding your kernel with "option CPU_ATHLON_SSE_HACK" and rebooting). David. Index: conf/options.i386 =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/conf/options.i386,v retrieving revision 1.163 diff -u -r1.163 options.i386 --- conf/options.i386 21 Dec 2001 21:46:55 -0000 1.163 +++ conf/options.i386 22 Jan 2002 11:02:45 -0000 @@ -64,6 +64,7 @@ CYRIX_CACHE_REALLY_WORKS opt_cpu.h NO_MEMORY_HOLE opt_cpu.h CPU_ENABLE_SSE opt_cpu.h +CPU_ATHLON_SSE_HACK opt_cpu.h # The CPU type affects the endian conversion functions all over the kernel. I386_CPU opt_global.h Index: conf/options.pc98 =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/conf/options.pc98,v retrieving revision 1.137 diff -u -r1.137 options.pc98 --- conf/options.pc98 22 Dec 2001 00:48:39 -0000 1.137 +++ conf/options.pc98 22 Jan 2002 11:22:56 -0000 @@ -64,6 +64,7 @@ CYRIX_CACHE_REALLY_WORKS opt_cpu.h NO_MEMORY_HOLE opt_cpu.h CPU_ENABLE_SSE opt_cpu.h +CPU_ATHLON_SSE_HACK opt_cpu.h # The CPU type affects the endian conversion functions all over the kernel. I386_CPU opt_global.h Index: i386/conf/NOTES =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/i386/conf/NOTES,v retrieving revision 1.992 diff -u -r1.992 NOTES --- i386/conf/NOTES 20 Jan 2002 08:51:07 -0000 1.992 +++ i386/conf/NOTES 22 Jan 2002 11:24:44 -0000 @@ -198,6 +198,9 @@ # # CPU_ENABLE_SSE enables SSE/MMX2 instructions support. # +# CPU_ATHLON_SSE_HACK tries of enable SSE instructions when the BIOS has +# forgotten to enable them. +# # CPU_FASTER_5X86_FPU enables faster FPU exception handler. # # CPU_I486_ON_386 enables CPU cache on i486 based CPU upgrade products @@ -262,6 +265,7 @@ options CPU_DIRECT_MAPPED_CACHE options CPU_DISABLE_5X86_LSSER options CPU_ENABLE_SSE +options CPU_ATHLON_SSE_HACK options CPU_FASTER_5X86_FPU options CPU_I486_ON_386 options CPU_IORT Index: i386/i386/identcpu.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/i386/i386/identcpu.c,v retrieving revision 1.97 diff -u -r1.97 identcpu.c --- i386/i386/identcpu.c 16 Jan 2002 02:22:19 -0000 1.97 +++ i386/i386/identcpu.c 20 Jan 2002 18:01:31 -0000 @@ -80,7 +80,6 @@ static void print_AMD_assoc(int i); static void print_transmeta_info(void); static void setup_tmx86_longrun(void); -static void do_cpuid(u_int ax, u_int *p); u_int cyrix_did; /* Device ID of Cyrix CPU */ int cpu_class = CPUCLASS_386; /* least common denominator */ @@ -111,16 +110,6 @@ { "Pentium III", CPUCLASS_686 }, /* CPU_PIII */ { "Pentium 4", CPUCLASS_686 }, /* CPU_P4 */ }; - -static void -do_cpuid(u_int ax, u_int *p) -{ - __asm __volatile( - "cpuid" - : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) - : "0" (ax) - ); -} #if defined(I586_CPU) && !defined(NO_F00F_HACK) int has_f00f_bug = 0; Index: i386/i386/initcpu.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/i386/i386/initcpu.c,v retrieving revision 1.33 diff -u -r1.33 initcpu.c --- i386/i386/initcpu.c 18 Dec 2001 00:27:15 -0000 1.33 +++ i386/i386/initcpu.c 22 Jan 2002 11:26:17 -0000 @@ -575,6 +575,24 @@ init_mendocino(); break; } + } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { +#if defined(I686_CPU) && defined(CPU_ATHLON_SSE_HACK) + /* + * Sometimes the BIOS doesn't enable SSE instructions. + * According to AMD document 20734 these the mobile + * Duron, the (mobile) Athlon 4 and the Athlon MP + * support SSE. These corrispond to cpu_id 0x66X + * or 0x67X. + */ + if ((cpu_feature & CPUID_XMM) == 0 && + ((cpu_id & ~0xf) == 0x660 || + (cpu_id & ~0xf) == 0x670)) { + u_int regs[4]; + wrmsr(0xC0010015, rdmsr(0xC0010015) & ~0x08000); + do_cpuid(1, regs); + cpu_feature = regs[3]; + } +#endif } break; #endif Index: i386/include/cpufunc.h =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/i386/include/cpufunc.h,v retrieving revision 1.107 diff -u -r1.107 cpufunc.h --- i386/include/cpufunc.h 18 Dec 2001 08:54:39 -0000 1.107 +++ i386/include/cpufunc.h 22 Jan 2002 11:56:47 -0000 @@ -365,6 +365,16 @@ return (ef); } +static __inline void +do_cpuid(u_int ax, u_int *p) +{ + __asm __volatile( + "cpuid" + : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) + : "0" (ax) + ); +} + static __inline u_int64_t rdmsr(u_int msr) { @@ -572,6 +582,7 @@ u_int bsfl __P((u_int mask)); u_int bsrl __P((u_int mask)); void disable_intr __P((void)); +void do_cpuid __P((u_int ax, u_int *p)); void enable_intr __P((void)); u_char inb __P((u_int port)); u_int inl __P((u_int port)); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message