1;; @file
2;   This is the assembly code for page fault handler hook.
3;
4; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5;
6; This program and the accompanying materials
7; are licensed and made available under the terms and conditions of the BSD License
8; which accompanies this distribution.  The full text of the license may be found at
9; http://opensource.org/licenses/bsd-license.php
10;
11; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13;
14;;
15
16extern ASM_PFX(PageFaultHandler)
17
18    DEFAULT REL
19    SECTION .text
20
21global ASM_PFX(PageFaultHandlerHook)
22ASM_PFX(PageFaultHandlerHook):
23    add     rsp, -0x10
24    ; save rax
25    mov     [rsp + 0x8], rax
26
27    ;push    rax                         ; save all volatile registers
28    push    rcx
29    push    rdx
30    push    r8
31    push    r9
32    push    r10
33    push    r11
34    ; save volatile fp registers
35    ; 68h + 08h(for alignment)
36    add     rsp, -0x70
37    stmxcsr [rsp + 0x60]
38    movdqa  [rsp + 0x0], xmm0
39    movdqa  [rsp + 0x10], xmm1
40    movdqa  [rsp + 0x20], xmm2
41    movdqa  [rsp + 0x30], xmm3
42    movdqa  [rsp + 0x40], xmm4
43    movdqa  [rsp + 0x50], xmm5
44
45    add     rsp, -0x20
46    call    ASM_PFX(PageFaultHandler)
47    add     rsp, 0x20
48
49    ; load volatile fp registers
50    ldmxcsr [rsp + 0x60]
51    movdqa  xmm0,  [rsp + 0x0]
52    movdqa  xmm1,  [rsp + 0x10]
53    movdqa  xmm2,  [rsp + 0x20]
54    movdqa  xmm3,  [rsp + 0x30]
55    movdqa  xmm4,  [rsp + 0x40]
56    movdqa  xmm5,  [rsp + 0x50]
57    add     rsp, 0x70
58
59    pop     r11
60    pop     r10
61    pop     r9
62    pop     r8
63    pop     rdx
64    pop     rcx
65    ;pop     rax                         ; restore all volatile registers
66
67    add     rsp, 0x10
68
69    ; rax returned from PageFaultHandler is NULL or OriginalHandler address
70    ; NULL if the page fault is handled by PageFaultHandler
71    ; OriginalHandler address if the page fault is not handled by PageFaultHandler
72    test    rax, rax
73
74    ; save OriginalHandler address
75    mov     [rsp - 0x10], rax
76    ; restore rax
77    mov     rax, [rsp - 0x8]
78
79    jz      .0
80
81    ; jump to OriginalHandler
82    jmp     qword [rsp - 0x10]
83
84.0:
85    add     rsp, 0x8                    ; skip error code for PF
86    iretq
87
88