xref: /netbsd-src/sys/arch/i386/acpi/acpi_wakecode.S (revision d93fe1fd9b23768d4a9fe8fd1576f43a97b86958)
1*d93fe1fdSmaxv/*	$NetBSD: acpi_wakecode.S,v 1.18 2016/07/24 14:09:22 maxv Exp $	*/
2834397e5Stshiozak
3834397e5Stshiozak/*-
4834397e5Stshiozak * Copyright (c) 2002 The NetBSD Foundation, Inc.
5834397e5Stshiozak * All rights reserved.
6834397e5Stshiozak *
7834397e5Stshiozak * This code is derived from software contributed to The NetBSD Foundation
8834397e5Stshiozak * by Takuya SHIOZAKI.
9834397e5Stshiozak *
10834397e5Stshiozak * Redistribution and use in source and binary forms, with or without
11834397e5Stshiozak * modification, are permitted provided that the following conditions
12834397e5Stshiozak * are met:
13834397e5Stshiozak * 1. Redistributions of source code must retain the above copyright
14834397e5Stshiozak *    notice, this list of conditions and the following disclaimer.
15834397e5Stshiozak * 2. Redistributions in binary form must reproduce the above copyright
16834397e5Stshiozak *    notice, this list of conditions and the following disclaimer in the
17834397e5Stshiozak *    documentation and/or other materials provided with the distribution.
18834397e5Stshiozak *
19834397e5Stshiozak * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20834397e5Stshiozak * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21834397e5Stshiozak * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22834397e5Stshiozak * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23834397e5Stshiozak * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24834397e5Stshiozak * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25834397e5Stshiozak * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26834397e5Stshiozak * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27834397e5Stshiozak * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28834397e5Stshiozak * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29834397e5Stshiozak * POSSIBILITY OF SUCH DAMAGE.
30834397e5Stshiozak */
31834397e5Stshiozak
32834397e5Stshiozak/*
33834397e5Stshiozak * This code is derived from FreeBSD.  Original copyrights:
34834397e5Stshiozak *
35834397e5Stshiozak * Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
36834397e5Stshiozak * Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
37834397e5Stshiozak * All rights reserved.
38834397e5Stshiozak *
39834397e5Stshiozak * Redistribution and use in source and binary forms, with or without
40834397e5Stshiozak * modification, are permitted provided that the following conditions
41834397e5Stshiozak * are met:
42834397e5Stshiozak * 1. Redistributions of source code must retain the above copyright
43834397e5Stshiozak *    notice, this list of conditions and the following disclaimer.
44834397e5Stshiozak * 2. Redistributions in binary form must reproduce the above copyright
45834397e5Stshiozak *    notice, this list of conditions and the following disclaimer in the
46834397e5Stshiozak *    documentation and/or other materials provided with the distribution.
47834397e5Stshiozak *
48834397e5Stshiozak * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
49834397e5Stshiozak * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50834397e5Stshiozak * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51834397e5Stshiozak * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
52834397e5Stshiozak * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53834397e5Stshiozak * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54834397e5Stshiozak * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55834397e5Stshiozak * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56834397e5Stshiozak * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57834397e5Stshiozak * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58834397e5Stshiozak * SUCH DAMAGE.
59834397e5Stshiozak *
60834397e5Stshiozak *	FreeBSD: src/sys/i386/acpica/acpi_wakecode.S,v 1.1 2001/07/20 06:07:31 takawata Exp
61834397e5Stshiozak */
62834397e5Stshiozak
6310921999Sjmcneill#define _LOCORE
64834397e5Stshiozak
65834397e5Stshiozak#include <machine/specialreg.h>
66e58c050cSjunyoung#include <machine/segments.h>
67834397e5Stshiozak
684c1d81b2Sjmcneill#define	ACPI_WAKEUP_ADDR	0x3000
694c1d81b2Sjmcneill
704c1d81b2Sjmcneill	.text
71834397e5Stshiozak	.code16
72834397e5Stshiozak	.org 0	/* ACPI spec says: cs==(phys>>8), ip==(phys&0x000F) */
734c1d81b2Sjmcneill	.globl wakeup_16
74834397e5Stshiozakwakeup_16:
75834397e5Stshiozak	nop
76834397e5Stshiozak	cli
7710921999Sjmcneill	cld
78834397e5Stshiozak
79834397e5Stshiozak	/* Set up segment registers for real mode */
80834397e5Stshiozak	movw	%cs,%ax
81834397e5Stshiozak	movw	%ax,%ds
82834397e5Stshiozak	movw	%ax,%ss
83834397e5Stshiozak
84e1b37110Sjmcneill	/* Small call stack */
854c1d81b2Sjmcneill	mov	$0x1000,%sp
86e1b37110Sjmcneill
87e1b37110Sjmcneill	/* Clear flags */
88e1b37110Sjmcneill	pushl	$0
89e1b37110Sjmcneill	popfl
90e1b37110Sjmcneill
9122ee755aSjoerg	/* Only beep on reset if machdep.acpi_beep_on_reset=1 */
924c1d81b2Sjmcneill	cmpb	$1,WAKEUP_beep_on_reset
934c1d81b2Sjmcneill	jne	1f
944c1d81b2Sjmcneill	movb	$0xc0,%al
954c1d81b2Sjmcneill	outb	%al,$0x42
964c1d81b2Sjmcneill	movb	$0x04,%al
974c1d81b2Sjmcneill	outb	%al,$0x42
984c1d81b2Sjmcneill	inb	$0x61,%al
994c1d81b2Sjmcneill	orb	$0x3,%al
1004c1d81b2Sjmcneill	outb	%al,$0x61
1014c1d81b2Sjmcneill1:
102e1b37110Sjmcneill
10393305d7bSjmcneill	/* Only reset the VBIOS if machdep.acpi_vbios_reset=1 */
1044c1d81b2Sjmcneill	cmpb	$1,WAKEUP_vbios_reset
1054c1d81b2Sjmcneill	jne	1f
10693305d7bSjmcneill
10710921999Sjmcneill	/* Kick the VBIOS. */
10810921999Sjmcneill	lcall	$0xc000,$3
10910921999Sjmcneill
11010921999Sjmcneill	movw	%cs,%ax
11110921999Sjmcneill	movw	%ax,%ds
11210921999Sjmcneill	movw	%ax,%ss
113834397e5Stshiozak
114b585cf85Sjmcneill	/* If we need to restore a VESA VBE mode, do it now */
115b585cf85Sjmcneill	cmpb	$0,WAKEUP_vesa_modenum
116b585cf85Sjmcneill	je	1f
117b585cf85Sjmcneill	movw	WAKEUP_vesa_modenum,%bx
118b585cf85Sjmcneill	orw	$0x4000,%bx
119b585cf85Sjmcneill	movw	$0x4f02,%ax
120b585cf85Sjmcneill	int	$0x10
121b585cf85Sjmcneill
122b585cf85Sjmcneill	movw	%cs,%ax
123b585cf85Sjmcneill	movw	%ax,%ds
124b585cf85Sjmcneill	movw	%ax,%ss
125b585cf85Sjmcneill1:
126b585cf85Sjmcneill
127e1f40929Sjmcneill	/* Disable beep again if machdep.acpi_beep_on_reset=1 */
128e1f40929Sjmcneill	cmpb	$1,WAKEUP_beep_on_reset
129e1f40929Sjmcneill	jne	1f
130e1f40929Sjmcneill	inb	$0x61,%al
131e1f40929Sjmcneill	andb	$0xfc,%al
132e1f40929Sjmcneill	outb	%al,$0x61
133e1f40929Sjmcneill1:
134e1f40929Sjmcneill
135834397e5Stshiozak	/* Load GDT while non-paging */
136834397e5Stshiozak	lgdt	tmp_gdt
137834397e5Stshiozak
138ee1c6cfcSmaxv	/* Enable protected mode without paging */
139834397e5Stshiozak	mov	%cr0,%eax
140834397e5Stshiozak	orl	$(CR0_PE),%eax
141834397e5Stshiozak	mov	%eax,%cr0
142834397e5Stshiozak
143834397e5Stshiozak	/* Switch to protected mode by intersegmental jump */
1444c1d81b2Sjmcneill	ljmpl	$0x8,$wakeup_32 + ACPI_WAKEUP_ADDR
145834397e5Stshiozak
146834397e5Stshiozak	.code32
147834397e5Stshiozak	.align	16
148834397e5Stshiozakwakeup_32:
149834397e5Stshiozak	/*
150834397e5Stshiozak	 * Switched to protected mode w/o paging
151834397e5Stshiozak	 */
152834397e5Stshiozak	nop
153ee1c6cfcSmaxv
154834397e5Stshiozak	/* Set up segment registers for protected mode */
155e58c050cSjunyoung	movw	$GSEL(GDATA_SEL,SEL_KPL),%ax
156834397e5Stshiozak	movw	%ax,%ds
157834397e5Stshiozak
158ee1c6cfcSmaxv	/* Enable potentially PSE and PAE */
1594c1d81b2Sjmcneill	movl	WAKEUP_r_cr4 + ACPI_WAKEUP_ADDR,%eax
1604c1d81b2Sjmcneill	movl	%eax,%cr4
161834397e5Stshiozak
162*d93fe1fdSmaxv	/*
163*d93fe1fdSmaxv	 * Load the correct MSR EFER value now to not depend on the
164*d93fe1fdSmaxv	 * data segment register. After this point, no instruction is
165*d93fe1fdSmaxv	 * allowed to clobber %ebx until wrmsr.
166*d93fe1fdSmaxv	 */
167*d93fe1fdSmaxv	movl	WAKEUP_efer + ACPI_WAKEUP_ADDR,%ebx
168*d93fe1fdSmaxv
169ee1c6cfcSmaxv	/* Load temporary page table, we will switch to full page table later */
1704c1d81b2Sjmcneill	movl	WAKEUP_r_cr3 + ACPI_WAKEUP_ADDR,%eax
171834397e5Stshiozak	movl	%eax,%cr3
172ee1c6cfcSmaxv
173ee1c6cfcSmaxv	/* Enable paging */
174870cffb0Sjoerg	movl	%cr0,%eax
17552252605Sdsl	orl	$(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_MP|CR0_WP|CR0_AM),%eax
176834397e5Stshiozak	movl	%eax,%cr0
177834397e5Stshiozak
178834397e5Stshiozak	/* Flush the prefetch queue */
179834397e5Stshiozak	jmp	1f
180834397e5Stshiozak1:	jmp	1f
181834397e5Stshiozak1:
182834397e5Stshiozak
183e1b37110Sjmcneill	nop
184e1b37110Sjmcneill
185*d93fe1fdSmaxv	/*
186*d93fe1fdSmaxv	 * Load the normal system value of MSR EFER.  This includes
187*d93fe1fdSmaxv	 * enabling NXE (if supported).
188*d93fe1fdSmaxv	 */
189*d93fe1fdSmaxv	movl	%ebx,%eax
190*d93fe1fdSmaxv	movl	$0,%edx
191*d93fe1fdSmaxv	movl	$MSR_EFER,%ecx
192*d93fe1fdSmaxv	wrmsr
193*d93fe1fdSmaxv
194834397e5Stshiozak	/* Restore registers */
195870cffb0Sjoerg	movl	WAKEUP_curcpu + ACPI_WAKEUP_ADDR,%edx
1964c1d81b2Sjmcneill	movl	WAKEUP_restorecpu + ACPI_WAKEUP_ADDR,%ebx
197870cffb0Sjoerg
198ee1c6cfcSmaxv	/* Continue with wakeup in the high-level wakeup code */
199834397e5Stshiozak	jmp	*%ebx
200834397e5Stshiozak
201834397e5Stshiozak	.align	8
202834397e5Stshiozaktmp_gdt:
203834397e5Stshiozak	.word	0xffff
2044c1d81b2Sjmcneill	.long	tmp_gdtable + ACPI_WAKEUP_ADDR
205834397e5Stshiozak
206834397e5Stshiozak	.align	8, 0
207834397e5Stshiozaktmp_gdtable:
208834397e5Stshiozak	/* null */
209834397e5Stshiozak	.word	0, 0
210834397e5Stshiozak	.byte	0, 0, 0, 0
211834397e5Stshiozak	/* code */
212834397e5Stshiozak	.word	0xffff, 0
213834397e5Stshiozak	.byte	0, 0x9f, 0xcf, 0
214834397e5Stshiozak	/* data */
215834397e5Stshiozak	.word	0xffff, 0
216834397e5Stshiozak	.byte	0, 0x93, 0xcf, 0
217834397e5Stshiozak
218834397e5Stshiozak	.align	16, 0
2194c1d81b2Sjmcneill	.global WAKEUP_r_cr3
2204c1d81b2SjmcneillWAKEUP_r_cr3:		.long 0
2214c1d81b2Sjmcneill	.global WAKEUP_r_cr4
2224c1d81b2SjmcneillWAKEUP_r_cr4:		.long 0
2234c1d81b2Sjmcneill
224870cffb0Sjoerg	.global WAKEUP_curcpu
225870cffb0SjoergWAKEUP_curcpu:		.long 0
2264c1d81b2Sjmcneill	.global WAKEUP_restorecpu
2274c1d81b2SjmcneillWAKEUP_restorecpu:	.long 0
228*d93fe1fdSmaxv	.global WAKEUP_efer
229*d93fe1fdSmaxvWAKEUP_efer:		.long 0
2304c1d81b2Sjmcneill
2314c1d81b2Sjmcneill	.global WAKEUP_vbios_reset
2324c1d81b2SjmcneillWAKEUP_vbios_reset:	.byte 0
233b585cf85Sjmcneill	.global WAKEUP_vesa_modenum
234b585cf85SjmcneillWAKEUP_vesa_modenum:	.word 0
2354c1d81b2Sjmcneill	.global WAKEUP_beep_on_reset
2364c1d81b2SjmcneillWAKEUP_beep_on_reset:	.byte 0
237