aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.nasm
blob: 713fd7b2e561a1ddb8c4a2c2dad29554a0c52619 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
;; @file
;   This is the assembly code for transferring to control to OS S3 waking vector
;   for X64 platform
;
; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
;
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
;;

extern ASM_PFX(mOriginalHandler)
extern ASM_PFX(PageFaultHandler)

    DEFAULT REL
    SECTION .text

global ASM_PFX(AsmFixAddress16)
global ASM_PFX(AsmJmpAddr32)

global ASM_PFX(AsmTransferControl)
ASM_PFX(AsmTransferControl):
    ; rcx S3WakingVector    :DWORD
    ; rdx AcpiLowMemoryBase :DWORD
    lea   eax, [.0]
    mov   r8, 0x2800000000
    or    rax, r8
    push  rax
    shrd  ebx, ecx, 20
    and   ecx, 0xf
    mov   bx, cx
    mov   [@jmp_addr + 1], ebx
    retf
BITS 16
.0:
    mov ax, 0x30
    mov   ds, ax
    mov   es, ax
    mov   fs, ax
    mov   gs, ax
    mov   ss, ax
    mov   eax, cr0
    mov   ebx, cr4
    and   eax, ((~ 0x80000001) & 0xffffffff)
    and   bl, ~ (1 << 5)
    mov   cr0, eax
    mov   ecx, 0xc0000080
    rdmsr
    and   ah, ~ 1
    wrmsr
    mov   cr4, ebx
@jmp_addr:
    jmp   0x0:0x0

global ASM_PFX(AsmTransferControl32)
ASM_PFX(AsmTransferControl32):
BITS 32
    ; S3WakingVector    :DWORD
    ; AcpiLowMemoryBase :DWORD
    push  ebp
    mov   ebp, esp
    DB    0x8d, 0x5          ;  lea   eax, AsmTransferControl16
ASM_PFX(AsmFixAddress16): DD 0
    push  0x28               ; CS
    push  eax
    retf

global ASM_PFX(AsmTransferControl16)
ASM_PFX(AsmTransferControl16):
BITS 16
    mov   ax, 0x30
o32 mov   ds, eax
o32 mov   es, eax
o32 mov   fs, eax
o32 mov   gs, eax
o32 mov   ss, eax
    mov   eax, cr0          ; Get control register 0
    and   eax, 0fffffffeh  ; Clear PE bit (bit #0)
    mov   cr0, eax         ; Activate real mode
    DB    0xea              ; jmp far AsmJmpAddr32
ASM_PFX(AsmJmpAddr32): DD 0

global ASM_PFX(PageFaultHandlerHook)
ASM_PFX(PageFaultHandlerHook):
BITS 64
    push    rax                         ; save all volatile registers
    push    rcx
    push    rdx
    push    r8
    push    r9
    push    r10
    push    r11
    ; save volatile fp registers
    add     rsp, -0x68
    stmxcsr [rsp + 0x60]
    movdqa  [rsp + 0x0], xmm0
    movdqa  [rsp + 0x10], xmm1
    movdqa  [rsp + 0x20], xmm2
    movdqa  [rsp + 0x30], xmm3
    movdqa  [rsp + 0x40], xmm4
    movdqa  [rsp + 0x50], xmm5

    add     rsp, -0x20
    call    ASM_PFX(PageFaultHandler)
    add     rsp, 0x20

    ; load volatile fp registers
    ldmxcsr [rsp + 0x60]
    movdqa  xmm0,  [rsp + 0x0]
    movdqa  xmm1,  [rsp + 0x10]
    movdqa  xmm2,  [rsp + 0x20]
    movdqa  xmm3,  [rsp + 0x30]
    movdqa  xmm4,  [rsp + 0x40]
    movdqa  xmm5,  [rsp + 0x50]
    add     rsp, 0x68

    test    al, al

    pop     r11
    pop     r10
    pop     r9
    pop     r8
    pop     rdx
    pop     rcx
    pop     rax                         ; restore all volatile registers
    jnz     .1
    jmp     qword [ASM_PFX(mOriginalHandler)]
.1:
    add     rsp, 0x8                    ; skip error code for PF
    iretq