1/* $NetBSD: acpi_wakeup_low.S,v 1.4 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 "assym.h" 32#include <machine/asm.h> 33#include <machine/segments.h> 34#include <machine/specialreg.h> 35 36 .text 37 .p2align 2, 0x90 38 .globl acpi_md_sleep_exit 39acpi_md_sleep_exit: 40 lgdt ACPI_SUSPEND_GDT(%r8) 41 42 /* Reload fixed descriptors for new GDT */ 43 movw $GSEL(GDATA_SEL, SEL_KPL),%ax 44 movw %ax,%ds 45 movw %ax,%es 46 movw %ax,%ss 47 48 /* FS and GS are driven by MSRs, so use NULL for them */ 49 xorw %ax,%ax 50 movw %ax,%fs 51 movw %ax,%gs 52 53 movl $MSR_EFER,%ecx 54 movl ACPI_SUSPEND_EFER(%r8),%eax 55 wrmsr 56 57 movl $MSR_FSBASE,%ecx 58 movl ACPI_SUSPEND_FS(%r8),%eax 59 movl ACPI_SUSPEND_FS+4(%r8),%edx 60 wrmsr 61 62 movl $MSR_GSBASE,%ecx 63 movl ACPI_SUSPEND_GS(%r8),%eax 64 movl ACPI_SUSPEND_GS+4(%r8),%edx 65 wrmsr 66 67 movl $MSR_KERNELGSBASE,%ecx 68 movl ACPI_SUSPEND_KGS(%r8),%eax 69 movl ACPI_SUSPEND_KGS+4(%r8),%edx 70 wrmsr 71 72 movq ACPI_SUSPEND_CR8(%r8),%rax 73 movq %rax,%cr8 74 movq ACPI_SUSPEND_CR4(%r8),%rax 75 movq %rax,%cr4 76 movq ACPI_SUSPEND_CR3(%r8),%rax 77 movq %rax,%cr3 78 movq ACPI_SUSPEND_CR2(%r8),%rax 79 movq %rax,%cr2 80 movq ACPI_SUSPEND_CR0(%r8),%rax 81 movq %rax,%cr0 82 83 jmp 1f 841: 85 86 movq CPUVAR(GDT),%rax 87 movzwq ACPI_SUSPEND_TR(%r8),%rdx 88 andq $~0x0200,4(%rax,%rdx, 1) 89 90 ltr %dx 91 lldt ACPI_SUSPEND_LDT(%r8) 92 lidt ACPI_SUSPEND_IDT(%r8) 93 94 movq ACPI_SUSPEND_REG+(0*8)(%r8),%rsp 95 movq ACPI_SUSPEND_REG+(1*8)(%r8),%rbx 96 movq ACPI_SUSPEND_REG+(2*8)(%r8),%rbp 97 movq ACPI_SUSPEND_REG+(3*8)(%r8),%r12 98 movq ACPI_SUSPEND_REG+(4*8)(%r8),%r13 99 movq ACPI_SUSPEND_REG+(5*8)(%r8),%r14 100 movq ACPI_SUSPEND_REG+(6*8)(%r8),%r15 101 102 xorq %rax,%rax 103 104 pushq ACPI_SUSPEND_REG+(7*8)(%r8) 105 popfq 106 ret 107 108 .p2align 2, 0x90 109 .type acpi_md_sleep_prepare, @function 110 .globl acpi_md_sleep_prepare 111acpi_md_sleep_prepare: 112 movq CPUVAR(SELF),%r8 113 movq %rbx,ACPI_SUSPEND_REG+(1*8)(%r8) 114 movq %rbp,ACPI_SUSPEND_REG+(2*8)(%r8) 115 movq %r12,ACPI_SUSPEND_REG+(3*8)(%r8) 116 movq %r13,ACPI_SUSPEND_REG+(4*8)(%r8) 117 movq %r14,ACPI_SUSPEND_REG+(5*8)(%r8) 118 movq %r15,ACPI_SUSPEND_REG+(6*8)(%r8) 119 120 movq %cr0,%rax 121 movq %rax,ACPI_SUSPEND_CR0(%r8) 122 movq %cr2,%rax 123 movq %rax,ACPI_SUSPEND_CR2(%r8) 124 movq %cr3,%rax 125 movq %rax,ACPI_SUSPEND_CR3(%r8) 126 movq %cr4,%rax 127 movq %rax,ACPI_SUSPEND_CR4(%r8) 128 movq %cr8,%rax 129 movq %rax,ACPI_SUSPEND_CR8(%r8) 130 131 pushfq 132 popq ACPI_SUSPEND_REG+(7*8)(%r8) 133 134 movq %rsp,ACPI_SUSPEND_REG+(0*8)(%r8) 135 136 movl $MSR_FSBASE,%ecx 137 rdmsr 138 movl %eax,ACPI_SUSPEND_FS(%r8) 139 movl %edx,ACPI_SUSPEND_FS+4(%r8) 140 141 movl $MSR_GSBASE,%ecx 142 rdmsr 143 movl %eax,ACPI_SUSPEND_GS(%r8) 144 movl %edx,ACPI_SUSPEND_GS+4(%r8) 145 146 movl $MSR_KERNELGSBASE,%ecx 147 rdmsr 148 movl %eax,ACPI_SUSPEND_KGS(%r8) 149 movl %edx,ACPI_SUSPEND_KGS+4(%r8) 150 151 movl $MSR_EFER,%ecx 152 rdmsr 153 movl %eax,ACPI_SUSPEND_EFER(%r8) 154 155 sgdt ACPI_SUSPEND_GDT(%r8) 156 sidt ACPI_SUSPEND_IDT(%r8) 157 sldt ACPI_SUSPEND_LDT(%r8) 158 str ACPI_SUSPEND_TR(%r8) 159 160 call acpi_md_sleep_enter 161 /* acpi_md_sleep_enter only returns on failure. */ 162 movl $-1,%eax 163 ret 164