xref: /netbsd/sys/arch/i386/acpi/acpi_wakeup_low.S (revision 6550d01e)
1/*	$NetBSD: acpi_wakeup_low.S,v 1.5 2008/05/11 15:32:20 ad 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.5 2008/05/11 15:32:20 ad Exp $");
33
34#include "assym.h"
35#include <machine/segments.h>
36
37	.text
38	.p2align 2, 0x90
39	.globl acpi_md_sleep_exit
40acpi_md_sleep_exit:
41	lgdt	ACPI_SUSPEND_GDT(%edx)
42
43	/* Reload fixed descriptors for new GDT */
44	movw	$GSEL(GDATA_SEL, SEL_KPL),%ax
45	movw	%ax,%ds
46	movw	%ax,%es
47	movw	%ax,%ss
48
49	movw	ACPI_SUSPEND_FS(%edx),%ax
50	movw	%ax,%fs
51	movw	ACPI_SUSPEND_GS(%edx),%ax
52	movw	%ax,%gs
53
54	movl	ACPI_SUSPEND_CR2(%edx),%eax
55	movl	%eax,%cr2
56
57	movl	ACPI_SUSPEND_CR4(%edx),%eax
58	movl	%eax,%cr4
59	movl	ACPI_SUSPEND_CR3(%edx),%eax
60	movl	%eax,%cr3
61
62	jmp 1f
631:
64
65	lidt	ACPI_SUSPEND_IDT(%edx)
66	lldt	ACPI_SUSPEND_LDT(%edx)
67
68	movl	CPUVAR(GDT),%eax
69	movzwl	ACPI_SUSPEND_TR(%edx),%ecx
70	andl	$~0x0200,4(%eax,%ecx, 1)
71	ltr	%cx
72
73	movl	ACPI_SUSPEND_REG+(0*4)(%edx),%ebx
74	movl	ACPI_SUSPEND_REG+(1*4)(%edx),%esi
75	movl	ACPI_SUSPEND_REG+(2*4)(%edx),%edi
76	movl	ACPI_SUSPEND_REG+(3*4)(%edx),%ebp
77	movl	ACPI_SUSPEND_REG+(4*4)(%edx),%esp
78
79	pushl	ACPI_SUSPEND_REG+(5*4)(%edx)
80	popfl
81
82	xorl	%eax,%eax
83
84	ret
85
86	.p2align 2, 0x90
87	.type acpi_md_sleep_prepare, @function
88	.globl acpi_md_sleep_prepare
89acpi_md_sleep_prepare:
90	movl	CPUVAR(SELF),%edx
91	movw	%fs,ACPI_SUSPEND_FS(%edx)
92	movw	%gs,ACPI_SUSPEND_GS(%edx)
93
94	movl	%ebx,ACPI_SUSPEND_REG+(0*4)(%edx)
95	movl	%esi,ACPI_SUSPEND_REG+(1*4)(%edx)
96	movl	%edi,ACPI_SUSPEND_REG+(2*4)(%edx)
97	movl	%ebp,ACPI_SUSPEND_REG+(3*4)(%edx)
98	movl	%esp,ACPI_SUSPEND_REG+(4*4)(%edx)
99
100	movl	%cr0,%eax
101	movl	%eax,ACPI_SUSPEND_CR0(%edx)
102	movl	%cr2,%eax
103	movl	%eax,ACPI_SUSPEND_CR2(%edx)
104	movl	%cr3,%eax
105	movl	%eax,ACPI_SUSPEND_CR3(%edx)
106	movl	%cr4,%eax
107	movl	%eax,ACPI_SUSPEND_CR4(%edx)
108
109	pushfl
110	popl	ACPI_SUSPEND_REG+(5*4)(%edx)
111
112	sgdt	ACPI_SUSPEND_GDT(%edx)
113	sidt	ACPI_SUSPEND_IDT(%edx)
114	sldt	ACPI_SUSPEND_LDT(%edx)
115	str	ACPI_SUSPEND_TR(%edx)
116
117	movl	4(%esp),%eax
118	pushl	%eax
119	call	acpi_md_sleep_enter
120	/* acpi_md_sleep_enter only returns on failure. */
121	popl	%eax
122	movl	$-1,%eax
123	ret
124