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