aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/acpi/wakeup_prot.S
blob: def86d2f45725a8f6ce2608a81497c532c770398 (plain)
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