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