]> git.saurik.com Git - apple/xnu.git/blame - osfmk/i386/acpi_wakeup.s
xnu-1699.26.8.tar.gz
[apple/xnu.git] / osfmk / i386 / acpi_wakeup.s
CommitLineData
91447636
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
91447636 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
91447636
A
27 */
28
29#include <i386/asm.h>
30#include <i386/proc_reg.h>
31#include <i386/postcode.h>
32#include <i386/acpi.h>
33#include <assym.s>
34
35 .file "acpi_wakeup.s"
36
37 .text
38 .align 12 /* Page align for single bcopy_phys() */
39
0c530ab8 40#define PA(addr) (addr)
91447636 41
b0d623f7
A
42#if CONFIG_SLEEP
43ENTRY(acpi_wake_prot)
91447636
A
44
45 /* protected mode, paging disabled */
46
47 /* setup the protected mode segment registers */
48 mov $0x10, %eax
49 movw %ax, %ds
50 movw %ax, %es
51 movw %ax, %ss
52 movw %ax, %fs
53 movw %ax, %gs
54
55 /* jump back to the sleep function in the kernel */
56 movl PA(saved_eip), %eax
57 jmp *%eax
58
91447636
A
59/*
60 * acpi_sleep_cpu(acpi_sleep_callback func, void * refcon)
61 *
62 * Save CPU state before platform sleep. Restore CPU state
63 * following wake up.
64 */
65
66ENTRY(acpi_sleep_cpu)
67 pushl %ebp
68 movl %esp, %ebp
69
70 /* save flags */
71 pushfl
72
73 /* save general purpose registers */
74 pushal
75 movl %esp, saved_esp
76
0c530ab8
A
77 /* make sure tlb is flushed */
78 movl %cr3,%eax
79 movl %eax,%cr3
80
91447636
A
81 /* save control registers */
82 movl %cr0, %eax
83 movl %eax, saved_cr0
84 movl %cr2, %eax
85 movl %eax, saved_cr2
86 movl %cr3, %eax
87 movl %eax, saved_cr3
88 movl %cr4, %eax
89 movl %eax, saved_cr4
90
91 /* save segment registers */
92 movw %es, saved_es
93 movw %fs, saved_fs
94 movw %gs, saved_gs
95 movw %ss, saved_ss
96
97 /* save descriptor table registers */
98 sgdt saved_gdt
99 sldt saved_ldt
100 sidt saved_idt
101 str saved_tr
102
103 /*
104 * When system wakes up, the real mode wake handler will revert to
105 * protected mode, then jump to the address stored at saved_eip.
106 */
107 movl $(PA(wake_prot)), saved_eip
108
109 /*
110 * Call ACPI function provided by the caller to sleep the platform.
111 * This call will not return on success.
112 */
113 pushl B_ARG1
114 movl B_ARG0, %edi
115 call *%edi
116 popl %edi
117
118 /* sleep failed, no cpu context lost */
119 jmp wake_restore
120
121wake_prot:
91447636
A
122 /* protected mode, paging disabled */
123 POSTCODE(ACPI_WAKE_PROT_ENTRY)
124
0c530ab8
A
125 movl PA(saved_cr3), %ebx
126 movl PA(saved_cr4), %ecx
127 /*
128 * restore cr3, PAE and NXE states in an orderly fashion
129 */
130 movl %ebx, %cr3
131 movl %ecx, %cr4
132
133 movl $(MSR_IA32_EFER), %ecx /* MSR number in ecx */
134 rdmsr /* MSR value return in edx: eax */
135 orl $(MSR_IA32_EFER_NXE), %eax /* Set NXE bit in low 32-bits */
136 wrmsr /* Update Extended Feature Enable reg */
137
91447636
A
138 /* restore kernel GDT */
139 lgdt PA(saved_gdt)
140
91447636
A
141 movl PA(saved_cr2), %eax
142 movl %eax, %cr2
91447636
A
143
144 /* restore CR0, paging enabled */
145 movl PA(saved_cr0), %eax
146 movl %eax, %cr0
147
148 /* switch to kernel code segment */
b0d623f7 149 ljmpl $(KERNEL32_CS), $wake_paged
91447636
A
150
151wake_paged:
152
153 /* protected mode, paging enabled */
154 POSTCODE(ACPI_WAKE_PAGED_ENTRY)
155
156 /* switch to kernel data segment */
157 movw $(KERNEL_DS), %ax
158 movw %ax, %ds
159
91447636
A
160 /* restore local and interrupt descriptor tables */
161 lldt saved_ldt
162 lidt saved_idt
163
164 /* restore segment registers */
165 movw saved_es, %es
166 movw saved_fs, %fs
167 movw saved_gs, %gs
168 movw saved_ss, %ss
169
170 /*
171 * Restore task register. Before doing this, clear the busy flag
172 * in the TSS descriptor set by the CPU.
173 */
174 movl $saved_gdt, %eax
175 movl 2(%eax), %edx /* GDT base, skip limit word */
176 movl $(KERNEL_TSS), %eax /* TSS segment selector */
177 movb $(K_TSS), 5(%edx, %eax) /* clear busy flag */
178 ltr saved_tr /* restore TR */
179
180wake_restore:
181
182 /* restore general purpose registers */
183 movl saved_esp, %esp
184 popal
185
186 /* restore flags */
187 popfl
188
189 leave
190 ret
191
192
193 .section __HIB, __text
194 .align 2
195
196 .globl EXT(acpi_wake_prot_entry)
197ENTRY(acpi_wake_prot_entry)
b0d623f7
A
198 mov %cr0, %eax
199 and $(~CR0_PG), %eax
200 mov %eax, %cr0
201 mov $EXT(IdlePDPT), %eax
202 mov EXT(IdlePTD), %ecx
203 or $(INTEL_PTE_VALID), %ecx
204 mov $0x0, %edx
205 mov %ecx, (0*8+0)(%eax)
206 mov %edx, (0*8+4)(%eax)
207 add $(PAGE_SIZE), %ecx
208 mov %ecx, (1*8+0)(%eax)
209 mov %edx, (1*8+4)(%eax)
210 add $(PAGE_SIZE), %ecx
211 mov %ecx, (2*8+0)(%eax)
212 mov %edx, (2*8+4)(%eax)
213 add $(PAGE_SIZE), %ecx
214 mov %ecx, (3*8+0)(%eax)
215 mov %edx, (3*8+4)(%eax)
216 mov %eax, %cr3
217 mov %cr0, %eax
218 or $(CR0_PG), %eax
219 mov %eax, %cr0
220
91447636 221 /* protected mode, paging enabled */
0c530ab8 222
91447636
A
223 POSTCODE(ACPI_WAKE_PAGED_ENTRY)
224
225 /* restore kernel GDT */
0c530ab8
A
226 lgdt saved_gdt
227
91447636 228 POSTCODE(0x40)
0c530ab8 229
91447636 230 /* restore control registers */
0c530ab8
A
231
232 movl saved_cr0, %eax
233 movl %eax, %cr0
234
91447636
A
235 movl saved_cr2, %eax
236 movl %eax, %cr2
237
238 POSTCODE(0x3E)
91447636 239
91447636
A
240 /* restore real PDE base */
241 movl saved_cr3, %eax
242 movl saved_cr4, %edx
243 movl %eax, %cr3
244 movl %edx, %cr4
0c530ab8 245 movl %eax, %cr3
91447636 246
0c530ab8
A
247 /* switch to kernel data segment */
248 movw $(KERNEL_DS), %ax
249 movw %ax, %ds
250
251 POSTCODE(0x3C)
91447636
A
252 /* restore local and interrupt descriptor tables */
253 lldt saved_ldt
254 lidt saved_idt
255
256 POSTCODE(0x3B)
257 /* restore segment registers */
258 movw saved_es, %es
259 movw saved_fs, %fs
260 movw saved_gs, %gs
261 movw saved_ss, %ss
262
263 POSTCODE(0x3A)
264 /*
265 * Restore task register. Before doing this, clear the busy flag
266 * in the TSS descriptor set by the CPU.
267 */
268 movl $saved_gdt, %eax
269 movl 2(%eax), %edx /* GDT base, skip limit word */
270 movl $(KERNEL_TSS), %eax /* TSS segment selector */
271 movb $(K_TSS), 5(%edx, %eax) /* clear busy flag */
272 ltr saved_tr /* restore TR */
273
274 /* restore general purpose registers */
275 movl saved_esp, %esp
276 popal
277
278 /* restore flags */
279 popfl
280
281 /* make sure interrupts are disabled */
282 cli
283
284 movl $2, %eax
285
286 leave
91447636 287
b0d623f7
A
288 ret
289#endif /* CONFIG_SLEEP */
91447636 290
b0d623f7
A
291.data
292.section __SLEEP, __data
293.align 2
91447636
A
294
295/*
296 * CPU registers saved across sleep/wake.
297 */
0c530ab8 298
91447636
A
299saved_esp: .long 0
300saved_es: .word 0
301saved_fs: .word 0
302saved_gs: .word 0
303saved_ss: .word 0
304saved_cr0: .long 0
305saved_cr2: .long 0
306saved_cr3: .long 0
307saved_cr4: .long 0
308saved_gdt: .word 0
309 .long 0
310saved_idt: .word 0
311 .long 0
312saved_ldt: .word 0
313saved_tr: .word 0
314saved_eip: .long 0
315