1
2
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
.text
#include <xen/config.h>
#include <xen/multiboot.h>
#include <public/xen.h>
#include <asm/asm_defns.h>
#include <asm/desc.h>
#include <asm/page.h>
#include <asm/msr.h>
.code64
#define GREG(x) %r##x
#define SAVED_GREG(x) saved_r##x(%rip)
#define DECLARE_GREG(x) saved_r##x: .quad 0
#define SAVE_GREG(x) movq GREG(x), SAVED_GREG(x)
#define LOAD_GREG(x) movq SAVED_GREG(x), GREG(x)
#define REF(x) x(%rip)
ENTRY(do_suspend_lowlevel)
SAVE_GREG(sp)
SAVE_GREG(ax)
SAVE_GREG(bx)
SAVE_GREG(cx)
SAVE_GREG(dx)
SAVE_GREG(bp)
SAVE_GREG(si)
SAVE_GREG(di)
SAVE_GREG(8) # save r8...r15
SAVE_GREG(9)
SAVE_GREG(10)
SAVE_GREG(11)
SAVE_GREG(12)
SAVE_GREG(13)
SAVE_GREG(14)
SAVE_GREG(15)
pushfq;
popq SAVED_GREG(flags)
mov %cr8, GREG(ax)
mov GREG(ax), REF(saved_cr8)
mov %ss, REF(saved_ss)
sgdt REF(saved_gdt)
sidt REF(saved_idt)
sldt REF(saved_ldt)
mov %cr0, GREG(ax)
mov GREG(ax), REF(saved_cr0)
mov %cr3, GREG(ax)
mov GREG(ax), REF(saved_cr3)
call save_rest_processor_state
mov $3, %rdi
xor %eax, %eax
/* enter sleep state physically */
call acpi_enter_sleep_state
jmp __ret_point
ENTRY(__ret_point)
/* mmu_cr4_features contains latest cr4 setting */
mov REF(mmu_cr4_features), GREG(ax)
mov GREG(ax), %cr4
mov REF(saved_cr3), GREG(ax)
mov GREG(ax), %cr3
mov REF(saved_cr0), GREG(ax)
mov GREG(ax), %cr0
lgdt REF(saved_gdt)
lidt REF(saved_idt)
lldt REF(saved_ldt)
mov REF(saved_ss), %ss
LOAD_GREG(sp)
/* Reload code selector */
pushq $(__HYPERVISOR_CS64)
leaq 1f(%rip),%rax
pushq %rax
lretq
1:
mov REF(saved_cr8), %rax
mov %rax, %cr8
pushq SAVED_GREG(flags)
popfq
call restore_rest_processor_state
LOAD_GREG(bp)
LOAD_GREG(ax)
LOAD_GREG(bx)
LOAD_GREG(cx)
LOAD_GREG(dx)
LOAD_GREG(si)
LOAD_GREG(di)
LOAD_GREG(8) # save r8...r15
LOAD_GREG(9)
LOAD_GREG(10)
LOAD_GREG(11)
LOAD_GREG(12)
LOAD_GREG(13)
LOAD_GREG(14)
LOAD_GREG(15)
ret
.data
.align 16
GLOBAL(saved_magic)
.long 0x9abcdef0
saved_ss: .word 0
.align 8
DECLARE_GREG(sp)
DECLARE_GREG(bp)
DECLARE_GREG(ax)
DECLARE_GREG(bx)
DECLARE_GREG(cx)
DECLARE_GREG(dx)
DECLARE_GREG(si)
DECLARE_GREG(di)
DECLARE_GREG(flags)
DECLARE_GREG(8)
DECLARE_GREG(9)
DECLARE_GREG(10)
DECLARE_GREG(11)
DECLARE_GREG(12)
DECLARE_GREG(13)
DECLARE_GREG(14)
DECLARE_GREG(15)
saved_gdt: .quad 0,0
saved_idt: .quad 0,0
saved_ldt: .quad 0,0
saved_cr0: .quad 0
saved_cr3: .quad 0
saved_cr8: .quad 0
|