]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
1. Separated DxeSmmCpuExceptionHandlerLib.inf into 2 instance DxeCpuExceptionHandlerL...
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / Ia32 / ExceptionHandlerAsm.S
index 8b3f6319b68b4e195b26e2c2f617623a4842381d..92c8dcafd47dfaf178a3d4e96a916d81e653c5ec 100644 (file)
@@ -1,6 +1,6 @@
 #------------------------------------------------------------------------------\r
 #*\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
-\r
-\r
-\r
 #.MMX\r
 #.XMM\r
 \r
 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+ASM_GLOBAL ASM_PFX(HookAfterStubEnd)\r
 \r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD           # Error code flags for exceptions\r
+#EXTRN ASM_PFX(mDoFarReturnFlag):DWORD         # Do far return flag\r
 \r
 .text\r
 \r
@@ -35,101 +34,250 @@ ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
 # exception handler stub table\r
 #\r
 Exception0Handle:\r
-    pushl   $0\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   0\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception1Handle:\r
-    pushl   $1\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   1\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception2Handle:\r
-    pushl   $2\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   2\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception3Handle:\r
-    pushl    $3\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   3\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception4Handle:\r
-    pushl    $4\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   4\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception5Handle:\r
-    pushl    $5\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   5\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception6Handle:\r
-    pushl    $6\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   6\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception7Handle:\r
-    pushl    $7\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   7\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception8Handle:\r
-    pushl    $8\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   8\r
+    pushl   %eax\r
+     .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception9Handle:\r
-    pushl    $9\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   9\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception10Handle:\r
-    pushl    $10\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   10\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception11Handle:\r
-    pushl    $11\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   11\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception12Handle:\r
-    pushl    $12\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   12\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception13Handle:\r
-    pushl    $13\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   13\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception14Handle:\r
-    pushl    $14\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   14\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception15Handle:\r
-    pushl    $15\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   15\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception16Handle:\r
-    pushl    $16\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   16\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception17Handle:\r
-    pushl    $17\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   17\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception18Handle:\r
-    pushl    $18\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   18\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception19Handle:\r
-    pushl    $19\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   19\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception20Handle:\r
-    pushl    $20\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   20\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception21Handle:\r
-    pushl    $21\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   21\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception22Handle:\r
-    pushl    $22\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   22\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception23Handle:\r
-    pushl    $23\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   23\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception24Handle:\r
-    pushl    $24\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   24\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception25Handle:\r
-    pushl    $25\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   25\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception26Handle:\r
-    pushl    $26\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   26\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception27Handle:\r
-    pushl    $27\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   27\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception28Handle:\r
-    pushl    $28\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   28\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception29Handle:\r
-    pushl    $29\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   29\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception30Handle:\r
-    pushl    $30\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   30\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception31Handle:\r
-    pushl    $31\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   31\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
+\r
+HookAfterStubBegin:\r
+    .byte   0x6a       # push\r
+VectorNum:\r
+    .byte   0          # 0 will be fixed\r
+    pushl   %eax\r
+    .byte   0xB8       # movl    ASM_PFX(HookAfterStubHeaderEnd), %eax\r
+    .long   ASM_PFX(HookAfterStubHeaderEnd)\r
+    jmp     *%eax\r
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
+HookAfterStubHeaderEnd:\r
+    popl    %eax\r
+    subl    $8, %esp        # reserve room for filling exception data later\r
+    pushl   8(%esp)\r
+    xchgl   (%esp), %ecx    # get vector number\r
+    bt      %ecx, ASM_PFX(mErrorCodeFlag)\r
+    jnc     NoErrorData\r
+    pushl    (%esp)         # addition push if exception data needed\r
+NoErrorData:\r
+    xchg    (%esp), %ecx    # restore ecx\r
+    pushl   %eax\r
 \r
 #---------------------------------------;\r
 # CommonInterruptEntry                  ;\r
@@ -139,19 +287,17 @@ Exception31Handle:
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
 ASM_PFX(CommonInterruptEntry):\r
     cli\r
+    popl    %eax\r
     #\r
     # All interrupt handlers are invoked through interrupt gates, so\r
     # IF flag automatically cleared at the entry point\r
     #\r
 \r
     #\r
-    # Calculate vector number\r
-    #\r
-    # Get the return address of call, actually, it is the\r
-    # address of vector number.\r
+    # Get vector number from top of stack\r
     #\r
     xchgl   (%esp), %ecx\r
-    andl    $0x0FFFF, %ecx\r
+    andl    $0x0FF, %ecx      # Vector number should be less than 256\r
     cmpl    $32, %ecx         # Intel reserved vector for exceptions?\r
     jae     NoErrorCode\r
     bt      %ecx, ASM_PFX(mErrorCodeFlag)\r
@@ -213,13 +359,6 @@ HasErrorCode:
     #\r
     xchgl   (%esp), %ecx \r
 \r
-    #\r
-    # Fall through to join main routine code\r
-    # at ErrorCodeAndVectorOnStack\r
-    #\r
-CommonInterruptEntry_al_0000:\r
-    jmp CommonInterruptEntry_al_0000\r
-\r
 ErrorCodeAndVectorOnStack:\r
     pushl   %ebp\r
     movl    %esp, %ebp\r
@@ -248,6 +387,10 @@ ErrorCodeAndVectorOnStack:
     andl    $0x0fffffff0, %esp \r
     subl    $12, %esp\r
 \r
+    subl    $8, %esp\r
+    pushl   $0         # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    pushl   $0         # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+       \r
 #; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
     pushl   %eax\r
     pushl   %ecx\r
@@ -412,18 +555,41 @@ ErrorCodeAndVectorOnStack:
     popl    %ecx\r
     popl    %eax\r
 \r
+    popl    -8(%ebp)\r
+    popl    -4(%ebp)\r
     movl    %ebp, %esp\r
     popl    %ebp\r
     addl    $8, %esp\r
+    cmpl    $0, -16(%esp)  # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    jz      DoReturn\r
+    cmpl    $1, -20(%esp)  # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+    jz      ErrorCode\r
+    jmp     *-16(%esp)\r
+ErrorCode:\r
+    subl    $4, %esp\r
+    jmp     *-12(%esp)\r
+\r
+DoReturn:\r
+    cmpl    $0, ASM_PFX(mDoFarReturnFlag)\r
+    jz      DoIret\r
+    pushl   8(%esp)       # save EFLAGS\r
+    addl    $16, %esp\r
+    pushl   -8(%esp)      # save CS in new location\r
+    pushl   -8(%esp)      # save EIP in new location\r
+    pushl   -8(%esp)      # save EFLAGS in new location\r
+    popfl                 # restore EFLAGS\r
+    retf                  # far return\r
+\r
+DoIret:\r
     iretl\r
 \r
 \r
 #---------------------------------------;\r
-# _GetTemplateAddressMap                  ;\r
-#----------------------------------------------------------------------------;\r
+# _AsmGetTemplateAddressMap             ;\r
+#---------------------------------------;\r
 # \r
 # Protocol prototype\r
-#   GetTemplateAddressMap (\r
+#   AsmGetTemplateAddressMap (\r
 #     EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
 #   );\r
 #           \r
@@ -450,8 +616,8 @@ ErrorCodeAndVectorOnStack:
 #-------------------------------------------------------------------------------------\r
 #  AsmGetAddressMap (&AddressMap);\r
 #-------------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)\r
-ASM_PFX(GetTemplateAddressMap):\r
+ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)\r
+ASM_PFX(AsmGetTemplateAddressMap):\r
 \r
         pushl       %ebp\r
         movl        %esp,%ebp\r
@@ -460,8 +626,17 @@ ASM_PFX(GetTemplateAddressMap):
         movl        0x8(%ebp), %ebx\r
         movl        $Exception0Handle, (%ebx)\r
         movl        $(Exception1Handle - Exception0Handle), 0x4(%ebx)\r
+        movl        $(HookAfterStubBegin), 0x8(%ebx)\r
 \r
         popal\r
         popl        %ebp\r
         ret\r
-\r
+#-------------------------------------------------------------------------------------\r
+#  AsmVectorNumFixup (*VectorBase, VectorNum);\r
+#-------------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)\r
+ASM_PFX(AsmVectorNumFixup):\r
+        movl  8(%esp), %eax\r
+        movl  4(%esp), %ecx\r
+        movb  %al, (VectorNum - HookAfterStubBegin)(%ecx)\r
+        ret\r