summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/machine/boot_asm.S24
-rw-r--r--arch/x86/machine/cpu.h2
2 files changed, 26 insertions, 0 deletions
diff --git a/arch/x86/machine/boot_asm.S b/arch/x86/machine/boot_asm.S
index ce377442..85441f70 100644
--- a/arch/x86/machine/boot_asm.S
+++ b/arch/x86/machine/boot_asm.S
@@ -64,6 +64,7 @@ ENTRY(_start)
movl %esp, %ebp
#ifdef __LP64__
+ call boot_check_long_mode
call boot_setup_long_mode
/*
@@ -105,9 +106,32 @@ DATA(boot_gdtr)
END(boot_gdtr)
#ifdef __LP64__
+
/*
* The %eax and %ebx registers must be preserved.
*/
+
+ENTRY(boot_check_long_mode)
+ pushl %eax
+ pushl %ebx
+ movl $0x80000000, %eax
+ cpuid
+ cmpl $0x80000000, %eax
+ jbe boot_no_long_mode
+ movl $0x80000001, %eax
+ cpuid
+ testl $CPU_FEATURE4_LM, %edx
+ jz boot_no_long_mode
+ popl %ebx
+ popl %eax
+ ret
+END(boot_check_long_mode)
+
+ENTRY(boot_no_long_mode)
+ hlt
+ jmp boot_no_long_mode
+END(boot_no_long_mode)
+
ENTRY(boot_setup_long_mode)
/* Set PML4[0] */
movl $boot_pdpt, %edx
diff --git a/arch/x86/machine/cpu.h b/arch/x86/machine/cpu.h
index db847c68..bfb5abe0 100644
--- a/arch/x86/machine/cpu.h
+++ b/arch/x86/machine/cpu.h
@@ -64,6 +64,8 @@
#define CPU_FEATURE2_APIC 0x00000200
#define CPU_FEATURE2_PGE 0x00002000
+#define CPU_FEATURE4_LM 0x20000000
+
/*
* Model specific registers.
*/