1#------------------------------------------------------------------------------
2#
3# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
4# This program and the accompanying materials
5# are licensed and made available under the terms and conditions of the BSD License
6# which accompanies this distribution.  The full text of the license may be found at
7# http://opensource.org/licenses/bsd-license.php
8#
9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11#
12# Module Name:
13#
14#   PageFaultHandler.S
15#
16# Abstract:
17#
18#   Defines page fault handler used to hook SMM IDT
19#
20#------------------------------------------------------------------------------
21
22ASM_GLOBAL ASM_PFX(PageFaultHandlerHook)
23ASM_PFX(PageFaultHandlerHook):
24    pushq    %rax                         # save all volatile registers
25    pushq    %rcx
26    pushq    %rdx
27    pushq    %r8
28    pushq    %r9
29    pushq    %r10
30    pushq    %r11
31
32    addq     $-0x68, %rsp                 # reserve memory to store XMM registers and make address 16-byte alignment
33    movdqa   %xmm0, 0(%rsp)
34    movdqa   %xmm1, 0x10(%rsp)
35    movdqa   %xmm2, 0x20(%rsp)
36    movdqa   %xmm3, 0x30(%rsp)
37    movdqa   %xmm4, 0x40(%rsp)
38    movdqa   %xmm5, 0x50(%rsp)
39
40    addq     $-0x20, %rsp
41    call     ASM_PFX(PageFaultHandler)
42    addq     $0x20, %rsp
43
44    movdqa   0(%rsp), %xmm0
45    movdqa   0x10(%rsp), %xmm1
46    movdqa   0x20(%rsp), %xmm2
47    movdqa   0x30(%rsp), %xmm3
48    movdqa   0x40(%rsp), %xmm4
49    movdqa   0x50(%rsp), %xmm5
50    addq     $0x68, %rsp
51
52    testb    %al, %al                     # set ZF flag
53    popq     %r11
54    popq     %r10
55    popq     %r9
56    popq     %r8
57    popq     %rdx
58    popq     %rcx
59    popq     %rax                         # restore all volatile registers
60    jnz      L1                           # check ZF flag
61#ifdef __APPLE__
62    int      $3
63#else
64    jmpq     *ASM_PFX(mOriginalHandler)
65#endif
66L1:
67    addq     $0x08, %rsp                  # skip error code for PF
68    iretq
69