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