The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/acpica/acpi_wakecode.S

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
    3  * Copyright (c) 2001-2012 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
    4  * Copyright (c) 2003 Peter Wemm
    5  * Copyright (c) 2008-2012 Jung-uk Kim <jkim@FreeBSD.org>
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  * $FreeBSD: releng/10.1/sys/i386/acpica/acpi_wakecode.S 237027 2012-06-13 21:03:01Z jkim $
   30  */
   31 
   32 #include <machine/asmacros.h>
   33 #include <machine/ppireg.h>
   34 #include <machine/specialreg.h>
   35 #include <machine/timerreg.h>
   36 
   37 #include "assym.s"
   38 
   39 /*
   40  * Resume entry point.  The BIOS enters here in real mode after POST with
   41  * CS set to the page where we stored this code.  It should configure the
   42  * segment registers with a flat 4 GB address space and EFLAGS.IF = 0.
   43  * Depending on the previous sleep state, we may need to initialize more
   44  * of the system (i.e., S3 suspend-to-RAM vs. S4 suspend-to-disk).
   45  */
   46 
   47         .data                           /* So we can modify it */
   48 
   49         ALIGN_TEXT
   50         .code16
   51 wakeup_start:
   52         /*
   53          * Set up segment registers for real mode, a small stack for
   54          * any calls we make, and clear any flags.
   55          */
   56         cli                             /* make sure no interrupts */
   57         mov     %cs, %ax                /* copy %cs to %ds.  Remember these */
   58         mov     %ax, %ds                /* are offsets rather than selectors */
   59         mov     %ax, %ss
   60         movw    $PAGE_SIZE, %sp
   61         xorw    %ax, %ax
   62         pushw   %ax
   63         popfw
   64 
   65         /* To debug resume hangs, beep the speaker if the user requested. */
   66         testb   $~0, resume_beep - wakeup_start
   67         jz      1f
   68         movb    $0, resume_beep - wakeup_start
   69 
   70         /* Set PIC timer2 to beep. */
   71         movb    $(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT), %al
   72         outb    %al, $TIMER_MODE
   73 
   74         /* Turn on speaker. */
   75         inb     $IO_PPI, %al
   76         orb     $PIT_SPKR, %al
   77         outb    %al, $IO_PPI
   78 
   79         /* Set frequency. */
   80         movw    $0x4c0, %ax
   81         outb    %al, $TIMER_CNTR2
   82         shrw    $8, %ax
   83         outb    %al, $TIMER_CNTR2
   84 1:
   85 
   86         /* Re-initialize video BIOS if the reset_video tunable is set. */
   87         testb   $~0, reset_video - wakeup_start
   88         jz      1f
   89         movb    $0, reset_video - wakeup_start
   90         lcall   $0xc000, $3
   91 
   92         /* When we reach here, int 0x10 should be ready.  Hide cursor. */
   93         movb    $0x01, %ah
   94         movb    $0x20, %ch
   95         int     $0x10
   96 
   97         /* Re-start in case the previous BIOS call clobbers them. */
   98         jmp     wakeup_start
   99 1:
  100 
  101         /*
  102          * Find relocation base and patch the gdt descript and ljmp targets
  103          */
  104         xorl    %ebx, %ebx
  105         mov     %cs, %bx
  106         sall    $4, %ebx                /* %ebx is now our relocation base */
  107 
  108         /*
  109          * Load the descriptor table pointer.  We'll need it when running
  110          * in 16-bit protected mode.
  111          */
  112         lgdtl   bootgdtdesc - wakeup_start
  113 
  114         /* Enable protected mode */
  115         movl    $CR0_PE, %eax
  116         mov     %eax, %cr0
  117 
  118         /*
  119          * Now execute a far jump to turn on protected mode.  This
  120          * causes the segment registers to turn into selectors and causes
  121          * %cs to be loaded from the gdt.
  122          *
  123          * The following instruction is:
  124          * ljmpl $bootcode32 - bootgdt, $wakeup_32 - wakeup_start
  125          * but gas cannot assemble that.  And besides, we patch the targets
  126          * in early startup and its a little clearer what we are patching.
  127          */
  128 wakeup_sw32:
  129         .byte   0x66                    /* size override to 32 bits */
  130         .byte   0xea                    /* opcode for far jump */
  131         .long   wakeup_32 - wakeup_start /* offset in segment */
  132         .word   bootcode32 - bootgdt    /* index in gdt for 32 bit code */
  133 
  134         /*
  135          * At this point, we are running in 32 bit legacy protected mode.
  136          */
  137         ALIGN_TEXT
  138         .code32
  139 wakeup_32:
  140 
  141         mov     $bootdata32 - bootgdt, %eax
  142         mov     %ax, %ds
  143 
  144         /* Get PCB and return address. */
  145         movl    wakeup_pcb - wakeup_start(%ebx), %ecx
  146         movl    wakeup_ret - wakeup_start(%ebx), %edx
  147 
  148         /* Restore CR4 and CR3. */
  149         movl    wakeup_cr4 - wakeup_start(%ebx), %eax
  150         mov     %eax, %cr4
  151         movl    wakeup_cr3 - wakeup_start(%ebx), %eax
  152         mov     %eax, %cr3
  153 
  154         /*
  155          * Finally, switch to long bit mode by enabling paging.  We have
  156          * to be very careful here because all the segmentation disappears
  157          * out from underneath us.  The spec says we can depend on the
  158          * subsequent pipelined branch to execute, but *only if* everthing
  159          * is still identity mapped.  If any mappings change, the pipeline
  160          * will flush.
  161          */
  162         mov     %cr0, %eax
  163         orl     $CR0_PG, %eax
  164         mov     %eax, %cr0
  165 
  166         jmp     1f
  167 1:
  168         /* Jump to return address. */
  169         jmp     *%edx
  170 
  171         .data
  172 
  173 resume_beep:
  174         .byte   0
  175 reset_video:
  176         .byte   0
  177 
  178         ALIGN_DATA
  179 bootgdt:
  180         .long   0x00000000
  181         .long   0x00000000
  182 
  183 bootcode32:
  184         .long   0x0000ffff
  185         .long   0x00cf9b00
  186 
  187 bootdata32:
  188         .long   0x0000ffff
  189         .long   0x00cf9300
  190 bootgdtend:
  191 
  192 bootgdtdesc:
  193         .word   bootgdtend - bootgdt    /* Length */
  194         .long   bootgdt - wakeup_start  /* Offset plus %ds << 4 */
  195 
  196         ALIGN_DATA
  197 wakeup_cr4:
  198         .long   0
  199 wakeup_cr3:
  200         .long   0
  201 wakeup_pcb:
  202         .long   0
  203 wakeup_ret:
  204         .long   0
  205 wakeup_gdt:             /* not used */
  206         .word   0
  207         .long   0
  208 dummy:

Cache object: ce4437409e69830210dad28b1dd37b4e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.