xref: /openbmc/linux/arch/x86/kernel/acpi/wakeup_32.S (revision 0883c2c0)
1	.text
2#include <linux/linkage.h>
3#include <asm/segment.h>
4#include <asm/page_types.h>
5
6# Copyright 2003, 2008 Pavel Machek <pavel@suse.cz>, distribute under GPLv2
7
8	.code32
9	ALIGN
10
11ENTRY(wakeup_pmode_return)
12wakeup_pmode_return:
13	movw	$__KERNEL_DS, %ax
14	movw	%ax, %ss
15	movw	%ax, %fs
16	movw	%ax, %gs
17
18	movw	$__USER_DS, %ax
19	movw	%ax, %ds
20	movw	%ax, %es
21
22	# reload the gdt, as we need the full 32 bit address
23	lidt	saved_idt
24	lldt	saved_ldt
25	ljmp	$(__KERNEL_CS), $1f
261:
27	movl	%cr3, %eax
28	movl	%eax, %cr3
29	wbinvd
30
31	# and restore the stack ... but you need gdt for this to work
32	movl	saved_context_esp, %esp
33
34	movl	%cs:saved_magic, %eax
35	cmpl	$0x12345678, %eax
36	jne	bogus_magic
37
38	# jump to place where we left off
39	movl	saved_eip, %eax
40	jmp	*%eax
41
42bogus_magic:
43	jmp	bogus_magic
44
45
46
47save_registers:
48	sidt	saved_idt
49	sldt	saved_ldt
50	str	saved_tss
51
52	leal	4(%esp), %eax
53	movl	%eax, saved_context_esp
54	movl	%ebx, saved_context_ebx
55	movl	%ebp, saved_context_ebp
56	movl	%esi, saved_context_esi
57	movl	%edi, saved_context_edi
58	pushfl
59	popl	saved_context_eflags
60
61	movl	$ret_point, saved_eip
62	ret
63
64
65restore_registers:
66	movl	saved_context_ebp, %ebp
67	movl	saved_context_ebx, %ebx
68	movl	saved_context_esi, %esi
69	movl	saved_context_edi, %edi
70	pushl	saved_context_eflags
71	popfl
72	ret
73
74ENTRY(do_suspend_lowlevel)
75	call	save_processor_state
76	call	save_registers
77	pushl	$3
78	call	x86_acpi_enter_sleep_state
79	addl	$4, %esp
80
81#	In case of S3 failure, we'll emerge here.  Jump
82# 	to ret_point to recover
83	jmp	ret_point
84	.p2align 4,,7
85ret_point:
86	call	restore_registers
87	call	restore_processor_state
88	ret
89
90.data
91ALIGN
92ENTRY(saved_magic)	.long	0
93ENTRY(saved_eip)	.long	0
94
95# saved registers
96saved_idt:	.long	0,0
97saved_ldt:	.long	0
98saved_tss:	.long	0
99
100