xref: /netbsd-src/sys/arch/i386/acpi/acpi_wakeup_low.S (revision 333882dfd5e5c51d23e8d107cf27cdbcbb1152b1)
1/*	$NetBSD: acpi_wakeup_low.S,v 1.8 2016/08/06 14:54:25 maxv Exp $	*/
2
3/*-
4 * Copyright (c) 2007 Joerg Sonnenberger <joerg@netbsd.org>
5 * Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
6 * Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <machine/asm.h>
32__KERNEL_RCSID(0, "$NetBSD: acpi_wakeup_low.S,v 1.8 2016/08/06 14:54:25 maxv Exp $");
33
34#include "assym.h"
35#include <machine/segments.h>
36#include <machine/specialreg.h>
37
38	.text
39	.p2align 2, 0x90
40	.globl acpi_md_sleep_exit
41acpi_md_sleep_exit:
42	lgdt	ACPI_SUSPEND_GDT(%edx)
43
44	/* Reload fixed descriptors for new GDT */
45	movw	$GSEL(GDATA_SEL, SEL_KPL),%ax
46	movw	%ax,%ds
47	movw	%ax,%es
48	movw	%ax,%ss
49
50	movw	ACPI_SUSPEND_FS(%edx),%ax
51	movw	%ax,%fs
52	movw	ACPI_SUSPEND_GS(%edx),%ax
53	movw	%ax,%gs
54
55	movl	$MSR_EFER,%ecx
56	movl	ACPI_SUSPEND_EFER(%edx),%eax
57	movl	%edx,%esi
58	movl	$0,%edx
59	wrmsr
60	movl	%esi,%edx
61
62	movl	ACPI_SUSPEND_CR2(%edx),%eax
63	movl	%eax,%cr2
64	movl	ACPI_SUSPEND_CR4(%edx),%eax
65	movl	%eax,%cr4
66	movl	ACPI_SUSPEND_CR3(%edx),%eax
67	movl	%eax,%cr3
68
69	jmp	1f
701:
71
72	lidt	ACPI_SUSPEND_IDT(%edx)
73	lldt	ACPI_SUSPEND_LDT(%edx)
74
75	movl	CPUVAR(GDT),%eax
76	movzwl	ACPI_SUSPEND_TR(%edx),%ecx
77	andl	$~0x0200,4(%eax,%ecx, 1)
78	ltr	%cx
79
80	movl	ACPI_SUSPEND_REG+(0*4)(%edx),%ebx
81	movl	ACPI_SUSPEND_REG+(1*4)(%edx),%esi
82	movl	ACPI_SUSPEND_REG+(2*4)(%edx),%edi
83	movl	ACPI_SUSPEND_REG+(3*4)(%edx),%ebp
84	movl	ACPI_SUSPEND_REG+(4*4)(%edx),%esp
85
86	pushl	ACPI_SUSPEND_REG+(5*4)(%edx)
87	popfl
88
89	xorl	%eax,%eax
90
91	ret
92
93	.p2align 2, 0x90
94	.type acpi_md_sleep_prepare, @function
95	.globl acpi_md_sleep_prepare
96acpi_md_sleep_prepare:
97	movl	CPUVAR(SELF),%edx
98	movw	%fs,ACPI_SUSPEND_FS(%edx)
99	movw	%gs,ACPI_SUSPEND_GS(%edx)
100
101	movl	%ebx,ACPI_SUSPEND_REG+(0*4)(%edx)
102	movl	%esi,ACPI_SUSPEND_REG+(1*4)(%edx)
103	movl	%edi,ACPI_SUSPEND_REG+(2*4)(%edx)
104	movl	%ebp,ACPI_SUSPEND_REG+(3*4)(%edx)
105	movl	%esp,ACPI_SUSPEND_REG+(4*4)(%edx)
106
107	movl	$MSR_EFER,%ecx
108	pushl	%edx
109	rdmsr	/* overwrites %edx */
110	popl	%edx
111	movl	%eax,ACPI_SUSPEND_EFER(%edx)
112
113	movl	%cr0,%eax
114	movl	%eax,ACPI_SUSPEND_CR0(%edx)
115	movl	%cr2,%eax
116	movl	%eax,ACPI_SUSPEND_CR2(%edx)
117	movl	%cr3,%eax
118	movl	%eax,ACPI_SUSPEND_CR3(%edx)
119	movl	%cr4,%eax
120	movl	%eax,ACPI_SUSPEND_CR4(%edx)
121
122	pushfl
123	popl	ACPI_SUSPEND_REG+(5*4)(%edx)
124
125	sgdt	ACPI_SUSPEND_GDT(%edx)
126	sidt	ACPI_SUSPEND_IDT(%edx)
127	sldt	ACPI_SUSPEND_LDT(%edx)
128	str	ACPI_SUSPEND_TR(%edx)
129
130	movl	4(%esp),%eax
131	pushl	%eax
132	call	acpi_md_sleep_enter
133	/* acpi_md_sleep_enter only returns on failure. */
134	popl	%eax
135	movl	$-1,%eax
136	ret
137