aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorStefan Reinauer <reinauer@chromium.org>2015-07-31 16:46:28 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2015-10-30 18:52:45 +0100
commitac901e6bedc98d115ebb8089afd8f67aef39c000 (patch)
tree738cf22657ee0636097a3cd384b2be44ee3067cf /src/arch
parentf79d05b7789feced96fc2fb71a30f3b2214c7b1c (diff)
wakeup: Switch back to 32bit mode first
On x86_64 we need to leave long mode before we can switch to 16bit mode. Oh joy! When's my 64bit resume pointer coming? Why didn't this get caught earlier? Seems the Asrock E350M2 didn't do Suspend/Resume? Yes, I know it's Intel syntax. Will be converted to AT&T syntax as soon as the whole thing actually works.. 8) Change-Id: Ic51869cf67d842041f8842cd9964d72a024c335f Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Reviewed-on: http://review.coreboot.org/11106 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/wakeup.S28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/arch/x86/wakeup.S b/src/arch/x86/wakeup.S
index 38d6ea43ae..acc8737550 100644
--- a/src/arch/x86/wakeup.S
+++ b/src/arch/x86/wakeup.S
@@ -32,6 +32,34 @@
.globl __wakeup
__wakeup:
+#ifdef __x86_64__
+ .intel_syntax noprefix
+ xor rax,rax
+ mov ax, ss
+ push rax
+ mov rax, rsp
+ add rax, 8
+ push rax
+ pushfq
+ push 0x10
+ lea rax,[rip+3]
+ push rax
+ iretq
+
+ .code32
+
+ /* disable paging */
+ mov eax, cr0
+ btc eax, 31
+ mov cr0, eax
+
+ /* disable long mode */
+ mov ecx, 0xC0000080
+ rdmsr
+ btc eax, 8
+ wrmsr
+ .att_syntax prefix
+#endif
/* First prepare the jmp to the resume vector */
mov 0x4(%esp), %eax /* vector */
/* last 4 bits of linear addr are taken as offset */