1        .file __FILE__
2        .text
3
4#include <xen/multiboot.h>
5#include <public/xen.h>
6#include <asm/asm_defns.h>
7#include <asm/desc.h>
8#include <asm/page.h>
9#include <asm/msr.h>
10
11        .code64
12
13#define GREG(x)         %r##x
14#define SAVED_GREG(x)   saved_r##x(%rip)
15#define DECLARE_GREG(x) saved_r##x:     .quad   0
16#define SAVE_GREG(x)    movq GREG(x), SAVED_GREG(x)
17#define LOAD_GREG(x)    movq SAVED_GREG(x), GREG(x)
18
19#define REF(x)          x(%rip)
20
21ENTRY(do_suspend_lowlevel)
22
23        SAVE_GREG(sp)
24        SAVE_GREG(ax)
25        SAVE_GREG(bx)
26        SAVE_GREG(cx)
27        SAVE_GREG(dx)
28        SAVE_GREG(bp)
29        SAVE_GREG(si)
30        SAVE_GREG(di)
31
32        SAVE_GREG(8)     # save r8...r15
33        SAVE_GREG(9)
34        SAVE_GREG(10)
35        SAVE_GREG(11)
36        SAVE_GREG(12)
37        SAVE_GREG(13)
38        SAVE_GREG(14)
39        SAVE_GREG(15)
40        pushfq;
41        popq    SAVED_GREG(flags)
42
43        mov     %cr8, GREG(ax)
44        mov     GREG(ax), REF(saved_cr8)
45
46        mov     %ss, REF(saved_ss)
47
48        sgdt    REF(saved_gdt)
49        sidt    REF(saved_idt)
50        sldt    REF(saved_ldt)
51
52        mov     %cr0, GREG(ax)
53        mov     GREG(ax), REF(saved_cr0)
54
55        mov     %cr3, GREG(ax)
56        mov     GREG(ax), REF(saved_cr3)
57
58        call    save_rest_processor_state
59
60        mov     $3, %rdi
61        xor     %eax, %eax
62
63        /* enter sleep state physically */
64        call    acpi_enter_sleep_state
65        jmp     __ret_point
66
67
68ENTRY(__ret_point)
69
70        /* mmu_cr4_features contains latest cr4 setting */
71        mov     REF(mmu_cr4_features), GREG(ax)
72        mov     GREG(ax), %cr4
73
74        mov     REF(saved_cr3), GREG(ax)
75        mov     GREG(ax), %cr3
76
77        mov     REF(saved_cr0), GREG(ax)
78        mov     GREG(ax), %cr0
79
80        lgdt    REF(saved_gdt)
81        lidt    REF(saved_idt)
82        lldt    REF(saved_ldt)
83
84        mov     REF(saved_ss), %ss
85        LOAD_GREG(sp)
86
87        /* Reload code selector */
88        pushq   $(__HYPERVISOR_CS64)
89        leaq    1f(%rip),%rax
90        pushq   %rax
91        lretq
921:
93        mov     REF(saved_cr8), %rax
94        mov     %rax, %cr8
95
96        pushq   SAVED_GREG(flags)
97        popfq
98
99        call restore_rest_processor_state
100
101        LOAD_GREG(bp)
102        LOAD_GREG(ax)
103        LOAD_GREG(bx)
104        LOAD_GREG(cx)
105        LOAD_GREG(dx)
106        LOAD_GREG(si)
107        LOAD_GREG(di)
108        LOAD_GREG(8)     # save r8...r15
109        LOAD_GREG(9)
110        LOAD_GREG(10)
111        LOAD_GREG(11)
112        LOAD_GREG(12)
113        LOAD_GREG(13)
114        LOAD_GREG(14)
115        LOAD_GREG(15)
116        ret
117
118.data
119        .align 16
120
121GLOBAL(saved_magic)
122        .long   0x9abcdef0
123
124saved_ss:        .word   0
125
126        .align 8
127DECLARE_GREG(sp)
128DECLARE_GREG(bp)
129DECLARE_GREG(ax)
130DECLARE_GREG(bx)
131DECLARE_GREG(cx)
132DECLARE_GREG(dx)
133DECLARE_GREG(si)
134DECLARE_GREG(di)
135DECLARE_GREG(flags)
136
137DECLARE_GREG(8)
138DECLARE_GREG(9)
139DECLARE_GREG(10)
140DECLARE_GREG(11)
141DECLARE_GREG(12)
142DECLARE_GREG(13)
143DECLARE_GREG(14)
144DECLARE_GREG(15)
145
146saved_gdt:      .quad   0,0
147saved_idt:      .quad   0,0
148saved_ldt:      .quad   0,0
149
150saved_cr0:      .quad   0
151saved_cr3:      .quad   0
152saved_cr8:      .quad   0
153