1.text
2
3/*
4 * This may not use any stack, nor any variable that is not "NoSave":
5 *
6 * Its rewriting one kernel image with another. What is stack in "old"
7 * image could very well be data page in "new" image, and overwriting
8 * your own stack under you is bad idea.
9 */
10
11#include <linux/linkage.h>
12#include <asm/segment.h>
13#include <asm/page.h>
14#include <asm/asm-offsets.h>
15
16	.text
17
18ENTRY(swsusp_arch_suspend)
19
20	movl %esp, saved_context_esp
21	movl %ebx, saved_context_ebx
22	movl %ebp, saved_context_ebp
23	movl %esi, saved_context_esi
24	movl %edi, saved_context_edi
25	pushfl ; popl saved_context_eflags
26
27	call swsusp_save
28	ret
29
30ENTRY(restore_image)
31	movl	resume_pg_dir, %ecx
32	subl	$__PAGE_OFFSET, %ecx
33	movl	%ecx, %cr3
34
35	movl	restore_pblist, %edx
36	.p2align 4,,7
37
38copy_loop:
39	testl	%edx, %edx
40	jz	done
41
42	movl	pbe_address(%edx), %esi
43	movl	pbe_orig_address(%edx), %edi
44
45	movl	$1024, %ecx
46	rep
47	movsl
48
49	movl	pbe_next(%edx), %edx
50	jmp	copy_loop
51	.p2align 4,,7
52
53done:
54	/* go back to the original page tables */
55	movl	$swapper_pg_dir, %ecx
56	subl	$__PAGE_OFFSET, %ecx
57	movl	%ecx, %cr3
58	/* Flush TLB, including "global" things (vmalloc) */
59	movl	mmu_cr4_features, %eax
60	movl	%eax, %edx
61	andl	$~(1<<7), %edx;  # PGE
62	movl	%edx, %cr4;  # turn off PGE
63	movl	%cr3, %ecx;  # flush TLB
64	movl	%ecx, %cr3
65	movl	%eax, %cr4;  # turn PGE back on
66
67	movl saved_context_esp, %esp
68	movl saved_context_ebp, %ebp
69	movl saved_context_ebx, %ebx
70	movl saved_context_esi, %esi
71	movl saved_context_edi, %edi
72
73	pushl saved_context_eflags ; popfl
74
75	xorl	%eax, %eax
76
77	ret
78