aboutsummaryrefslogtreecommitdiff
path: root/payloads/libpayload/arch/x86/head.S
diff options
context:
space:
mode:
Diffstat (limited to 'payloads/libpayload/arch/x86/head.S')
-rw-r--r--payloads/libpayload/arch/x86/head.S43
1 files changed, 43 insertions, 0 deletions
diff --git a/payloads/libpayload/arch/x86/head.S b/payloads/libpayload/arch/x86/head.S
index 94a4d41167..52504706db 100644
--- a/payloads/libpayload/arch/x86/head.S
+++ b/payloads/libpayload/arch/x86/head.S
@@ -2,6 +2,7 @@
* This file is part of the libpayload project.
*
* Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -89,6 +90,48 @@ _init:
movl $_stack, %esp
pushl %eax
+ /* Enable special x86 functions if present. */
+ pushl %eax
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+
+ movl $0, %eax
+ cpuid
+ /* Test if CPUID(eax=1) is available. */
+ test %eax, %eax
+ je cpuid_done
+
+ /* Get CPU features. */
+ movl $1, %eax
+ cpuid
+
+cpuid_fpu:
+ /* Test if x87 FPU is present */
+ test $1, %edx
+ je cpuid_sse
+
+ fninit
+ movl %cr0, %eax
+ andl $0xFFFFFFFB, %eax /* clear EM */
+ orl $0x00000022, %eax /* set MP, NE */
+ movl %eax, %cr0
+
+cpuid_sse:
+ /* Test if SSE is available */
+ test $0x02000000, %edx
+ je cpuid_done
+
+ movl %cr4, %eax
+ orl $0x00000600, %eax /* set OSFXSR, OSXMMEXCPT */
+ movl %eax, %cr4
+
+cpuid_done:
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %eax
+
/* Let's rock. */
call start_main