• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
17ASM_GLOBAL ASM_PFX(AsmTransferControl)
18ASM_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
50jmp_addr:
51    .long    0
52
53ASM_GLOBAL ASM_PFX(AsmTransferControl32)
54ASM_PFX(AsmTransferControl32):
55    # S3WakingVector    :DWORD
56    # AcpiLowMemoryBase :DWORD
57    pushq %rbp
58    movl  %esp,%ebp
59    .byte 0x8d, 0x05        #  lea   eax, AsmTransferControl16
60ASM_GLOBAL ASM_PFX(AsmFixAddress16)
61ASM_PFX(AsmFixAddress16):
62    .long    0
63    pushq $0x28             # CS
64    pushq %rax
65    lret
66
67ASM_GLOBAL ASM_PFX(AsmTransferControl16)
68ASM_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
80ASM_GLOBAL ASM_PFX(AsmJmpAddr32)
81ASM_PFX(AsmJmpAddr32):
82    .long    0
83
84ASM_GLOBAL ASM_PFX(PageFaultHandlerHook)
85ASM_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)
128L1:
129    addq     $0x08, %rsp                  # skip error code for PF
130    iretq
131