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