Home | History | Annotate | Download | only in X64
      1 ## @file
      2 #   This is the assembly code for transferring to control to OS S3 waking vector
      3 #   for X64 platform
      4 #
      5 # Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
      6 #
      7 # This program and the accompanying materials are
      8 # licensed and made available under the terms and conditions of the BSD License
      9 # which accompanies this distribution.  The full text of the license may be found at
     10 # http://opensource.org/licenses/bsd-license.php
     11 #
     12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 #
     15 ##
     16 
     17 ASM_GLOBAL ASM_PFX(AsmTransferControl)
     18 ASM_PFX(AsmTransferControl):
     19     # rcx S3WakingVector    :DWORD
     20     # rdx AcpiLowMemoryBase :DWORD
     21     lea   _AsmTransferControl_al_0000(%rip), %eax
     22     movq  $0x2800000000, %r8
     23     orq   %r8, %rax
     24     pushq %rax
     25     shrd  $20, %ecx, %ebx
     26     andl  $0x0f, %ecx
     27     movw  %cx, %bx
     28     movl  %ebx, jmp_addr(%rip)
     29     lret
     30 _AsmTransferControl_al_0000:
     31     .byte    0x0b8, 0x30, 0      # mov ax, 30h as selector
     32     movl  %eax, %ds
     33     movl  %eax, %es
     34     movl  %eax, %fs
     35     movl  %eax, %gs
     36     movl  %eax, %ss
     37     movq  %cr0, %rax
     38     movq  %cr4, %rbx
     39     .byte    0x66
     40     andl  $0x7ffffffe, %eax
     41     andb  $0xdf, %bl
     42     movq  %rax, %cr0
     43     .byte    0x66
     44     movl  $0x0c0000080, %ecx
     45     rdmsr
     46     andb  $0xfe, %ah
     47     wrmsr
     48     movq  %rbx, %cr4
     49     .byte    0x0ea              # jmp far jmp_addr
     50 jmp_addr:
     51     .long    0
     52 
     53 ASM_GLOBAL ASM_PFX(AsmTransferControl32)
     54 ASM_PFX(AsmTransferControl32):
     55     # S3WakingVector    :DWORD
     56     # AcpiLowMemoryBase :DWORD
     57     pushq %rbp
     58     movl  %esp,%ebp
     59     .byte 0x8d, 0x05        #  lea   eax, AsmTransferControl16
     60 ASM_GLOBAL ASM_PFX(AsmFixAddress16)
     61 ASM_PFX(AsmFixAddress16):
     62     .long    0
     63     pushq $0x28             # CS
     64     pushq %rax
     65     lret
     66 
     67 ASM_GLOBAL ASM_PFX(AsmTransferControl16)
     68 ASM_PFX(AsmTransferControl16):
     69     .byte 0xb8,0x30,0       # mov ax, 30h as selector
     70     movw  %ax,%ds
     71     movw  %ax,%es
     72     movw  %ax,%fs
     73     movw  %ax,%gs
     74     movw  %ax,%ss
     75     movq  %cr0, %rax        # Get control register 0
     76     .byte 0x66
     77     .byte 0x83,0xe0,0xfe    # and    eax, 0fffffffeh  ; Clear PE bit (bit #0)
     78     .byte 0xf,0x22,0xc0     # mov    cr0, eax         ; Activate real mode
     79     .byte 0xea              # jmp far AsmJmpAddr32
     80 ASM_GLOBAL ASM_PFX(AsmJmpAddr32)
     81 ASM_PFX(AsmJmpAddr32):
     82     .long    0
     83 
     84 ASM_GLOBAL ASM_PFX(PageFaultHandlerHook)
     85 ASM_PFX(PageFaultHandlerHook):
     86     pushq    %rax                         # save all volatile registers
     87     pushq    %rcx
     88     pushq    %rdx
     89     pushq    %r8
     90     pushq    %r9
     91     pushq    %r10
     92     pushq    %r11
     93     # save volatile fp registers
     94     addq     $-0x68, %rsp
     95     stmxcsr  0x60(%rsp)
     96     movdqa   %xmm0, 0x0(%rsp)
     97     movdqa   %xmm1, 0x10(%rsp)
     98     movdqa   %xmm2, 0x20(%rsp)
     99     movdqa   %xmm3, 0x30(%rsp)
    100     movdqa   %xmm4, 0x40(%rsp)
    101     movdqa   %xmm5, 0x50(%rsp)
    102 
    103     addq     $-0x20, %rsp
    104     call     ASM_PFX(PageFaultHandler)
    105     addq     $0x20, %rsp
    106 
    107     # load volatile fp registers
    108     ldmxcsr  0x60(%rsp)
    109     movdqa   0x0(%rsp), %xmm0
    110     movdqa   0x10(%rsp), %xmm1
    111     movdqa   0x20(%rsp), %xmm2
    112     movdqa   0x30(%rsp), %xmm3
    113     movdqa   0x40(%rsp), %xmm4
    114     movdqa   0x50(%rsp), %xmm5
    115     addq     $0x68, %rsp
    116 
    117     testb    %al, %al
    118 
    119     popq     %r11
    120     popq     %r10
    121     popq     %r9
    122     popq     %r8
    123     popq     %rdx
    124     popq     %rcx
    125     popq     %rax                         # restore all volatile registers
    126     jnz      L1
    127     jmpq     *ASM_PFX(mOriginalHandler)(%rip)
    128 L1:
    129     addq     $0x08, %rsp                  # skip error code for PF
    130     iretq
    131