acpi_wakecode.S revision 235622
180028Stakawata/*- 280028Stakawata * Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org> 3235622Siwasaki * Copyright (c) 2001-2012 Mitsuru IWASAKI <iwasaki@jp.freebsd.org> 4235622Siwasaki * Copyright (c) 2003 Peter Wemm 5235622Siwasaki * Copyright (c) 2008-2012 Jung-uk Kim <jkim@FreeBSD.org> 680028Stakawata * All rights reserved. 780028Stakawata * 880028Stakawata * Redistribution and use in source and binary forms, with or without 980028Stakawata * modification, are permitted provided that the following conditions 1080028Stakawata * are met: 1180028Stakawata * 1. Redistributions of source code must retain the above copyright 1280028Stakawata * notice, this list of conditions and the following disclaimer. 1380028Stakawata * 2. Redistributions in binary form must reproduce the above copyright 1480028Stakawata * notice, this list of conditions and the following disclaimer in the 1580028Stakawata * documentation and/or other materials provided with the distribution. 1680028Stakawata * 1780028Stakawata * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1880028Stakawata * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1980028Stakawata * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2080028Stakawata * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2180028Stakawata * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2280028Stakawata * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2380028Stakawata * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2480028Stakawata * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2580028Stakawata * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2680028Stakawata * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2780028Stakawata * SUCH DAMAGE. 28124051Snjl * 29124051Snjl * $FreeBSD: head/sys/i386/acpica/acpi_wakecode.S 235622 2012-05-18 18:55:58Z iwasaki $ 3080028Stakawata */ 3180028Stakawata 32124051Snjl#include <machine/asmacros.h> 33235622Siwasaki#include <machine/ppireg.h> 3480028Stakawata#include <machine/specialreg.h> 35235622Siwasaki#include <machine/timerreg.h> 3680028Stakawata 37145397Siedowse#include "assym.s" 38145397Siedowse 39159478Snjl/* 40159478Snjl * Resume entry point. The BIOS enters here in real mode after POST with 41159478Snjl * CS set to the page where we stored this code. It should configure the 42159478Snjl * segment registers with a flat 4 GB address space and EFLAGS.IF = 0. 43159478Snjl * Depending on the previous sleep state, we may need to initialize more 44159478Snjl * of the system (i.e., S3 suspend-to-RAM vs. S4 suspend-to-disk). 45159478Snjl */ 46235622Siwasaki 47235622Siwasaki .data /* So we can modify it */ 48235622Siwasaki 49235622Siwasaki ALIGN_TEXT 5080028Stakawata .code16 51235622Siwasakiwakeup_start: 52121830Snjl /* 53159478Snjl * Set up segment registers for real mode, a small stack for 54159478Snjl * any calls we make, and clear any flags. 55121830Snjl */ 56235622Siwasaki cli /* make sure no interrupts */ 57235622Siwasaki mov %cs, %ax /* copy %cs to %ds. Remember these */ 58235622Siwasaki mov %ax, %ds /* are offsets rather than selectors */ 59235622Siwasaki mov %ax, %ss 60235622Siwasaki movw $PAGE_SIZE, %sp 61235622Siwasaki xorw %ax, %ax 62235622Siwasaki pushw %ax 63235622Siwasaki popfw 64121830Snjl 65159409Snjl /* To debug resume hangs, beep the speaker if the user requested. */ 66235622Siwasaki testb $~0, resume_beep - wakeup_start 67235622Siwasaki jz 1f 68235622Siwasaki movb $0, resume_beep - wakeup_start 69159409Snjl 70235622Siwasaki /* Set PIC timer2 to beep. */ 71235622Siwasaki movb $(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT), %al 72235622Siwasaki outb %al, $TIMER_MODE 73121830Snjl 74235622Siwasaki /* Turn on speaker. */ 75235622Siwasaki inb $IO_PPI, %al 76235622Siwasaki orb $PIT_SPKR, %al 77235622Siwasaki outb %al, $IO_PPI 7880028Stakawata 79235622Siwasaki /* Set frequency. */ 80235622Siwasaki movw $0x4c0, %ax 81235622Siwasaki outb %al, $TIMER_CNTR2 82235622Siwasaki shrw $8, %ax 83235622Siwasaki outb %al, $TIMER_CNTR2 84235622Siwasaki1: 8580028Stakawata 86235622Siwasaki /* Re-initialize video BIOS if the reset_video tunable is set. */ 87235622Siwasaki testb $~0, reset_video - wakeup_start 88235622Siwasaki jz 1f 89235622Siwasaki movb $0, reset_video - wakeup_start 90235622Siwasaki lcall $0xc000, $3 9180028Stakawata 92235622Siwasaki /* When we reach here, int 0x10 should be ready. Hide cursor. */ 93235622Siwasaki movb $0x01, %ah 94235622Siwasaki movb $0x20, %ch 95235622Siwasaki int $0x10 9680028Stakawata 97235622Siwasaki /* Re-start in case the previous BIOS call clobbers them. */ 98235622Siwasaki jmp wakeup_start 99235622Siwasaki1: 10080028Stakawata 101235622Siwasaki /* 102235622Siwasaki * Find relocation base and patch the gdt descript and ljmp targets 103235622Siwasaki */ 104235622Siwasaki xorl %ebx, %ebx 105235622Siwasaki mov %cs, %bx 106235622Siwasaki sall $4, %ebx /* %ebx is now our relocation base */ 10780028Stakawata 108235622Siwasaki /* 109235622Siwasaki * Load the descriptor table pointer. We'll need it when running 110235622Siwasaki * in 16-bit protected mode. 111235622Siwasaki */ 112235622Siwasaki lgdtl bootgdtdesc - wakeup_start 113235622Siwasaki 11480028Stakawata /* Enable protected mode */ 115235622Siwasaki movl $CR0_PE, %eax 116235622Siwasaki mov %eax, %cr0 11780028Stakawata 118235622Siwasaki /* 119235622Siwasaki * Now execute a far jump to turn on protected mode. This 120235622Siwasaki * causes the segment registers to turn into selectors and causes 121235622Siwasaki * %cs to be loaded from the gdt. 122235622Siwasaki * 123235622Siwasaki * The following instruction is: 124235622Siwasaki * ljmpl $bootcode32 - bootgdt, $wakeup_32 - wakeup_start 125235622Siwasaki * but gas cannot assemble that. And besides, we patch the targets 126235622Siwasaki * in early startup and its a little clearer what we are patching. 127235622Siwasaki */ 12880028Stakawatawakeup_sw32: 129235622Siwasaki .byte 0x66 /* size override to 32 bits */ 130235622Siwasaki .byte 0xea /* opcode for far jump */ 131235622Siwasaki .long wakeup_32 - wakeup_start /* offset in segment */ 132235622Siwasaki .word bootcode32 - bootgdt /* index in gdt for 32 bit code */ 13380028Stakawata 134159478Snjl /* 135235622Siwasaki * At this point, we are running in 32 bit legacy protected mode. 136159478Snjl */ 137235622Siwasaki ALIGN_TEXT 13880028Stakawata .code32 13980028Stakawatawakeup_32: 14080028Stakawata 141235622Siwasaki mov $bootdata32 - bootgdt, %eax 142235622Siwasaki mov %ax, %ds 14380028Stakawata 144235622Siwasaki /* Get PCB and return address. */ 145235622Siwasaki movl wakeup_pcb - wakeup_start(%ebx), %esi 146235622Siwasaki movl wakeup_ret - wakeup_start(%ebx), %edi 14780028Stakawata 148235622Siwasaki /* Restore CR4 and CR3. */ 149235622Siwasaki movl wakeup_cr4 - wakeup_start(%ebx), %eax 150235622Siwasaki mov %eax, %cr4 151235622Siwasaki movl wakeup_cr3 - wakeup_start(%ebx), %eax 152235622Siwasaki mov %eax, %cr3 15380028Stakawata 154235622Siwasaki /* 155235622Siwasaki * Finally, switch to long bit mode by enabling paging. We have 156235622Siwasaki * to be very careful here because all the segmentation disappears 157235622Siwasaki * out from underneath us. The spec says we can depend on the 158235622Siwasaki * subsequent pipelined branch to execute, but *only if* everthing 159235622Siwasaki * is still identity mapped. If any mappings change, the pipeline 160235622Siwasaki * will flush. 161235622Siwasaki */ 162235622Siwasaki mov %cr0, %eax 163235622Siwasaki orl $CR0_PG, %eax 164235622Siwasaki mov %eax, %cr0 16580028Stakawata 16680028Stakawata jmp 1f 16780028Stakawata1: 168235622Siwasaki /* Jump to return address. */ 169235622Siwasaki jmp *%edi 170159478Snjl 171235622Siwasaki .data 17280028Stakawata 173235622Siwasakiresume_beep: 174235622Siwasaki .byte 0 175235622Siwasakireset_video: 176235622Siwasaki .byte 0 17780028Stakawata 178235622Siwasaki ALIGN_DATA 179235622Siwasakibootgdt: 180235622Siwasaki .long 0x00000000 181235622Siwasaki .long 0x00000000 18280028Stakawata 183235622Siwasakibootcode32: 184235622Siwasaki .long 0x0000ffff 185235622Siwasaki .long 0x00cf9b00 18680028Stakawata 187235622Siwasakibootdata32: 188235622Siwasaki .long 0x0000ffff 189235622Siwasaki .long 0x00cf9300 190235622Siwasakibootgdtend: 19180028Stakawata 192235622Siwasakibootgdtdesc: 193235622Siwasaki .word bootgdtend - bootgdt /* Length */ 194235622Siwasaki .long bootgdt - wakeup_start /* Offset plus %ds << 4 */ 195235622Siwasaki 196235622Siwasaki ALIGN_DATA 197235622Siwasakiwakeup_cr4: 198235622Siwasaki .long 0 199235622Siwasakiwakeup_cr3: 200235622Siwasaki .long 0 201235622Siwasakiwakeup_pcb: 202235622Siwasaki .long 0 203235622Siwasakiwakeup_ret: 204235622Siwasaki .long 0 205235622Siwasakidummy: 206