acpi_wakecode.S revision 1.2 1 /* $NetBSD: acpi_wakecode.S,v 1.2 2007/12/09 20:27:42 jmcneill Exp $ */
2
3 /*-
4 * Copyright (c) 2007 Joerg Sonnenberger <joerg (at) netbsd.org>
5 *
6 * Copyright (c) 2002 The NetBSD Foundation, Inc.
7 * All rights reserved.
8 *
9 * This code is derived from software contributed to The NetBSD Foundation
10 * by Takuya SHIOZAKI.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41
42 /*
43 * This code is derived from FreeBSD. Original copyrights:
44 *
45 * Copyright (c) 2001 Takanori Watanabe <takawata (at) jp.freebsd.org>
46 * Copyright (c) 2001 Mitsuru IWASAKI <iwasaki (at) jp.freebsd.org>
47 * All rights reserved.
48 *
49 * Redistribution and use in source and binary forms, with or without
50 * modification, are permitted provided that the following conditions
51 * are met:
52 * 1. Redistributions of source code must retain the above copyright
53 * notice, this list of conditions and the following disclaimer.
54 * 2. Redistributions in binary form must reproduce the above copyright
55 * notice, this list of conditions and the following disclaimer in the
56 * documentation and/or other materials provided with the distribution.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE.
69 *
70 * FreeBSD: src/sys/i386/acpica/acpi_wakecode.S,v 1.1 2001/07/20 06:07:31 takawata Exp
71 */
72
73 #define _LOCORE
74
75 #include <machine/psl.h>
76 #include <machine/specialreg.h>
77 #include <machine/segments.h>
78
79 #define ACPI_WAKEUP_ADDR 0x3000
80
81 .text
82 .code16
83 .org 0 /* ACPI spec says: cs==(phys>>8), ip==(phys&0x000F) */
84 .globl wakeup_16
85 wakeup_16:
86 nop
87 cli
88 cld
89
90 /* Set up segment registers for real mode */
91 movw %cs,%ax
92 movw %ax,%ds
93 movw %ax,%ss
94
95 /* Small call stack */
96 mov $0x1000,%sp
97
98 /* Clear flags */
99 pushl $0
100 popfl
101
102 /* Only beep on reset if machdep.acpi_beep_on_reset=1 */
103 cmpb $1,WAKEUP_beep_on_reset
104 jne 1f
105 movb $0xc0,%al
106 outb %al,$0x42
107 movb $0x04,%al
108 outb %al,$0x42
109 inb $0x61,%al
110 orb $0x3,%al
111 outb %al,$0x61
112 1:
113
114 /* Only reset the VBIOS if machdep.acpi_vbios_reset=1 */
115 cmpb $1,WAKEUP_vbios_reset
116 jne 1f
117
118 /* Kick the VBIOS. */
119 lcall $0xc000,$3
120
121 /* Reset registers in case the VBIOS changed them. */
122 movw %cs,%ax
123 movw %ax,%ds
124 movw %ax,%ss
125 1:
126
127 /* Disable beep again if machdep.acpi_beep_on_reset=1 */
128 cmpb $1,WAKEUP_beep_on_reset
129 jne 1f
130 inb $0x61,%al
131 andb $0xfc,%al
132 outb %al,$0x61
133 1:
134
135 /* Load temporary 32bit GDT */
136 data32 addr32 lgdt tmp_gdt
137
138 /* Enable protected mode w/o paging */
139 mov %cr0,%eax
140 orl $(CR0_PE),%eax
141 mov %eax,%cr0
142
143 wakeup_sw32:
144 /*
145 * Switch to protected mode by intersegmental jump.
146 * Target and everything else has to compensate for the new origin
147 * as this is using the flat memory model now.
148 */
149
150 ljmpl $0x8,$wakeup_32 + ACPI_WAKEUP_ADDR
151
152 .code32
153 .align 16
154 wakeup_32:
155 /*
156 * Switched to protected mode w/o paging
157 */
158
159 nop
160 /* Set up segment registers and initial stack for protected mode */
161 movw $0x10, %ax
162 movw %ax,%ds
163 movw %ax,%ss
164
165 movl $(ACPI_WAKEUP_ADDR + 4096),%esp
166
167 /* First, reset the PSL. */
168 pushl $PSL_MBO
169 popfl
170
171 /* Enable PAE and potentially PSE */
172 movl $(CR4_PAE|CR4_OSFXSR|CR4_OSXMMEXCPT|CR4_PSE),%eax
173 movl %eax,%cr4
174
175 /* Enable SYSCALL extension and Long Mode */
176 movl $MSR_EFER,%ecx
177 rdmsr
178 xorl %eax,%eax
179 orl $(EFER_LME|EFER_SCE),%eax
180 wrmsr
181
182 /* Load temporary PML4, code will switch to full PML4 later */
183 movl WAKEUP_r_cr3 + ACPI_WAKEUP_ADDR,%eax
184 movl %eax,%cr3
185
186 /* Enable paging */
187 movl %cr0,%eax
188 orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_MP|CR0_WP),%eax
189 movl %eax,%cr0
190 /* Flush prefetch queue */
191 jmp 1f
192 1:
193 /* Switch to temporary 64bit GDT */
194 lgdt tmp_gdt64 + ACPI_WAKEUP_ADDR
195
196 /* Switch to long mode using intersegmental jump. */
197 ljmp $0x8, $wakeup_64 + ACPI_WAKEUP_ADDR
198
199 .code64
200 wakeup_64:
201
202 /* Reload normal segment registers with correct values */
203 movw $GSEL(GDATA_SEL, SEL_KPL),%ax
204 movw %ax,%ds
205 movw %ax,%es
206 movw %ax,%ss
207
208 movq WAKEUP_restorecpu + ACPI_WAKEUP_ADDR,%rbx
209
210 /* Continue with wakeup in the high-level wakeup code */
211 jmp *%rbx
212
213 .align 8
214 tmp_gdt:
215 .word 0xffff
216 .long tmp_gdtable + ACPI_WAKEUP_ADDR
217
218 .align 8, 0
219 tmp_gdtable:
220 /* null */
221 .word 0, 0
222 .byte 0, 0, 0, 0
223 /* code */
224 .word 0xffff, 0
225 .byte 0, 0x9f, 0xcf, 0
226 /* data */
227 .word 0xffff, 0
228 .byte 0, 0x93, 0xcf, 0
229
230 tmp_gdt64:
231 .word 0xffff
232 .long tmp_gdtable64 + ACPI_WAKEUP_ADDR
233
234 tmp_gdtable64:
235 .quad 0x0000000000000000
236 .quad 0x00af9a000000ffff
237 .quad 0x00cf92000000ffff
238
239 .align 16, 0
240 .global WAKEUP_r_cr3
241 WAKEUP_r_cr3: .quad 0
242
243 .global WAKEUP_restorecpu
244 WAKEUP_restorecpu: .quad 0
245
246 .global WAKEUP_vbios_reset
247 WAKEUP_vbios_reset: .byte 0
248 .global WAKEUP_beep_on_reset
249 WAKEUP_beep_on_reset: .byte 0
250