]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
1. Separated DxeSmmCpuExceptionHandlerLib.inf into 2 instance DxeCpuExceptionHandlerL...
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / X64 / ExceptionHandlerAsm.S
index cd101475a7c11adde5b1d9ffa25341eeb73709f8..7d5672f892b9d7886158d254e72fe4541617272d 100644 (file)
@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------ ;\r
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 #------------------------------------------------------------------------------\r
 \r
 \r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
 \r
 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
 \r
-\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD  # Do far return flag\r
 .text\r
 \r
 #\r
-# point to the external interrupt vector table\r
+# exception handler stub table\r
 #\r
 Exception0Handle:\r
-    pushq   $0\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   0\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception1Handle:\r
-    pushq   $1\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   1\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception2Handle:\r
-    pushq   $2\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   2\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception3Handle:\r
-    pushq   $3\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   3\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception4Handle:\r
-    pushq   $4\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   4\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception5Handle:\r
-    pushq   $5\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   5\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception6Handle:\r
-    pushq   $6\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   6\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception7Handle:\r
-    pushq   $7\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   7\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception8Handle:\r
-    pushq   $8\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   8\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception9Handle:\r
-    pushq   $9\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   9\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception10Handle:\r
-    pushq   $10\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   10\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception11Handle:\r
-    pushq   $11\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   11\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception12Handle:\r
-    pushq   $12\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   12\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception13Handle:\r
-    pushq   $13\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   13\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception14Handle:\r
-    pushq   $14\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   14\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception15Handle:\r
-    pushq   $15\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   15\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception16Handle:\r
-    pushq   $16\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   16\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception17Handle:\r
-    pushq   $17\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   17\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception18Handle:\r
-    pushq   $18\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   18\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception19Handle:\r
-    pushq   $19\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   19\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception20Handle:\r
-    pushq   $20\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   20\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception21Handle:\r
-    pushq   $21\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   21\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception22Handle:\r
-    pushq   $22\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   22\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception23Handle:\r
-    pushq   $23\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   23\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception24Handle:\r
-    pushq   $24\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   24\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception25Handle:\r
-    pushq   $25\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   25\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception26Handle:\r
-    pushq   $26\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   26\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception27Handle:\r
-    pushq   $27\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   27\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception28Handle:\r
-    pushq   $28\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   28\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception29Handle:\r
-    pushq   $29\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   29\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception30Handle:\r
-    pushq   $30\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   30\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception31Handle:\r
-    pushq   $31\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
-\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   31\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
+    \r
+HookAfterStubHeaderBegin:\r
+    .byte   0x6a      # push\r
+VectorNum:\r
+    .byte   0         # 0 will be fixed \r
+    pushq   %rax\r
+    .byte   0x48, 0xB8      # movq    ASM_PFX(HookAfterStubHeaderEnd), %rax\r
+    .quad   ASM_PFX(HookAfterStubHeaderEnd)\r
+    jmp     *%rax\r
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
+ASM_PFX(HookAfterStubHeaderEnd):\r
+    movq    %rsp, %rax\r
+    subq    $8, %rsp\r
+    andl    $0x0fffffff0, %esp\r
+    pushq   %rcx\r
+    movq    8(%rax), %rcx\r
+    bt      %ecx, ASM_PFX(mErrorCodeFlag)\r
+    jc      NoErrorData\r
+    pushq   (%rsp)            # push additional rcx to make stack alignment\r
+NoErrorData:\r
+    xchgq   (%rsp), %rcx      # restore rcx, save Exception Number in stack\r
+    pushq   (%rax)            # push rax into stack to keep code consistence\r
 \r
 #---------------------------------------;\r
 # CommonInterruptEntry                  ;\r
@@ -138,6 +288,7 @@ Exception31Handle:
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
 ASM_PFX(CommonInterruptEntry):\r
     cli\r
+    popq    %rax\r
     #\r
     # All interrupt handlers are invoked through interrupt gates, so\r
     # IF flag automatically cleared at the entry point\r
@@ -145,7 +296,8 @@ ASM_PFX(CommonInterruptEntry):
     #\r
     # Calculate vector number\r
     #\r
-    xchgq   (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.\r
+    xchgq   (%rsp), %rcx       # get the return address of call, actually, it is the address of vector number.\r
+    andq     $0x0FF, %rcx\r
     cmp     $32, %ecx          # Intel reserved vector for exceptions?\r
     jae     NoErrorCode\r
     pushq   %rax\r
@@ -165,6 +317,8 @@ NoErrorCode:
 CommonInterruptEntry_al_0000:\r
     pushq   %rbp\r
     movq    %rsp, %rbp\r
+    pushq   $0          # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    pushq   $0          # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
 \r
     #\r
     # Stack:\r
@@ -385,20 +539,53 @@ CommonInterruptEntry_al_0000:
     movq    %rbp, %rsp\r
     popq    %rbp\r
     addq    $16, %rsp\r
+    cmpq    $0, -32(%rsp)      # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    jz      DoReturn           # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+    cmpb    $1, -40(%rsp)\r
+    jz      ErrorCode\r
+    jmp     *-32(%rsp)\r
+ErrorCode:\r
+    subq    $8, %rsp\r
+    jmp     *-24(%rsp)\r
+\r
+DoReturn:\r
+    cmpq    $0, ASM_PFX(mDoFarReturnFlag)   # Check if need to do far return instead of IRET\r
+    jz      DoIret\r
+    pushq   %rax\r
+    movq    %rsp, %rax        # save old RSP to rax\r
+    movq    0x20(%rsp), %rsp\r
+    pushq   0x10(%rax)        # save CS in new location\r
+    pushq   0x8(%rax)         # save EIP in new location\r
+    pushq   0x18(%rax)        # save EFLAGS in new location\r
+    movq    (%rax), %rax      # restore rax\r
+    popfq                     # restore EFLAGS\r
+    .byte   0x48              # prefix to composite "retq" with next "retf"\r
+    retf                      # far return\r
+DoIret:\r
     iretq\r
 \r
 \r
 #-------------------------------------------------------------------------------------\r
-#  AsmGetAddressMap (&AddressMap);\r
+#  AsmGetTemplateAddressMap (&AddressMap);\r
 #-------------------------------------------------------------------------------------\r
 # comments here for definition of address map\r
-ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)\r
-ASM_PFX(GetTemplateAddressMap):\r
+ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)\r
+ASM_PFX(AsmGetTemplateAddressMap):\r
 \r
         movabsq      $Exception0Handle, %rax\r
         movq         %rax, (%rcx)\r
         movq         $(Exception1Handle - Exception0Handle), 0x08(%rcx)\r
+        movabsq      $HookAfterStubHeaderBegin, %rax\r
+        movq         %rax, 0x10(%rcx)\r
+        ret\r
 \r
+#-------------------------------------------------------------------------------------\r
+#  AsmVectorNumFixup (*VectorBase, VectorNum);\r
+#-------------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)\r
+ASM_PFX(AsmVectorNumFixup):\r
+        movq  %rdx, %rax\r
+        movb  %al, (VectorNum - HookAfterStubHeaderBegin)(%rcx)\r
         ret\r
 \r
 #END\r