patch-2.4.21 linux-2.4.21/arch/x86_64/boot/setup.S
Next file: linux-2.4.21/arch/x86_64/config.in
Previous file: linux-2.4.21/arch/x86_64/boot/compressed/misc.c
Back to the patch index
Back to the overall index
- Lines: 98
- Date:
2003-06-13 07:51:32.000000000 -0700
- Orig file:
linux-2.4.20/arch/x86_64/boot/setup.S
- Orig date:
2002-11-28 15:53:12.000000000 -0800
diff -urN linux-2.4.20/arch/x86_64/boot/setup.S linux-2.4.21/arch/x86_64/boot/setup.S
@@ -42,6 +42,7 @@
* if CX/DX have been changed in the e801 call and if so use AX/BX .
* Michael Miller, April 2001 <michaelm@mjmm.org>
*
+ * Added long mode checking and SSE force. March 2003, Andi Kleen.
*/
#include <linux/config.h>
@@ -197,10 +198,10 @@
prtsp2: call prtspc # Print double space
prtspc: movb $0x20, %al # Print single space (note: fall-thru)
-# Part of above routine, this one just prints ascii al
-prtchr: pushw %ax
+prtchr:
+ pushw %ax
pushw %cx
- xorb %bh, %bh
+ movw $0007,%bx
movw $0x01, %cx
movb $0x0e, %ah
int $0x10
@@ -277,6 +278,75 @@
loader_panic_mess: .string "Wrong loader, giving up..."
loader_ok:
+ /* check for long mode. */
+ /* we have to do this before the VESA setup, otherwise the user
+ can't see the error message. */
+
+ pushw %ds
+ movw %cs,%ax
+ movw %ax,%ds
+
+ /* minimum CPUID flags for x86-64 */
+ /* see http://www.x86-64.org/lists/discuss/msg02971.html */
+#define SSE_MASK ((1<<25)|(1<<26))
+#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|(1<<11)| \
+ (1<<13)|(1<<15)|(1<<24)|(1<<29))
+
+ pushfl /* standard way to check for cpuid */
+ popl %eax
+ movl %eax,%ebx
+ xorl $0x200000,%eax
+ pushl %eax
+ popfl
+ pushfl
+ popl %eax
+ cmpl %eax,%ebx
+ jz no_longmode /* cpu has no cpuid */
+ movl $0x80000000,%eax
+ cpuid
+ cmpl $0x80000001,%eax
+ jb no_longmode /* no extended cpuid */
+ xor %di,%di
+ cmpl $0x68747541,%ebx /* AuthenticAMD */
+ jnz noamd
+ cmpl $0x69746e65,%edx
+ jnz noamd
+ cmpl $0x444d4163,%ecx
+ jnz noamd
+ mov $1,%di /* cpu is from AMD */
+noamd:
+ movl $0x80000001,%eax
+ cpuid
+ andl $REQUIRED_MASK1,%edx
+ xorl $REQUIRED_MASK1,%edx
+ jnz no_longmode
+sse_test:
+ movl $1,%eax
+ cpuid
+ andl $SSE_MASK,%edx
+ cmpl $SSE_MASK,%edx
+ je sse_ok
+ test %di,%di
+ jz no_longmode /* only try to force SSE on AMD */
+ movl $0xc0010015,%ecx /* HWCR */
+ rdmsr
+ btr $15,%eax /* enable SSE */
+ wrmsr
+ xor %di,%di /* don't loop */
+ jmp sse_test /* try again */
+no_longmode:
+ call beep
+ lea long_mode_panic,%si
+ call prtstr
+no_longmode_loop:
+ jmp no_longmode_loop
+long_mode_panic:
+ .string "Your CPU does not support long mode. Use a 32bit distribution."
+ .byte 0
+
+sse_ok:
+ popw %ds
+
# Get memory size (extended mem, kB)
xorl %eax, %eax
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)