]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
SourceLevelDebugPkg: Remove X86 ASM and S files
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / X64 / ExceptionHandlerAsm.asm
index 1fa7cb8702c57c24fd03828439f07a10b3e8aed6..726c64a14055b0d5342b923ed78b0af4ebab94f9 100644 (file)
@@ -1,5 +1,5 @@
 ;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2012 - 2014, 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
 ; CommonExceptionHandler()\r
 ;\r
-CommonExceptionHandler             PROTO   C\r
+externdef CommonExceptionHandler:near\r
 \r
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
+EXTRN mErrorCodeFlag:DWORD    ; Error code flags for exceptions\r
+EXTRN mDoFarReturnFlag:QWORD  ; Do far return flag\r
 \r
 data SEGMENT\r
 \r
-CommonEntryAddr                dq      CommonInterruptEntry;\r
-\r
 .code\r
 \r
-Exception0Handle:\r
-    push    0\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception1Handle:\r
-    push    1\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception2Handle:\r
-    push    2\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception3Handle:\r
-    push    3\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception4Handle:\r
-    push    4\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception5Handle:\r
-    push    5\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception6Handle:\r
-    push    6\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception7Handle:\r
-    push    7\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception8Handle:\r
-    push    8\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception9Handle:\r
-    push    9\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception10Handle:\r
-    push    10\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception11Handle:\r
-    push    11\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception12Handle:\r
-    push    12\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception13Handle:\r
-    push    13\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception14Handle:\r
-    push    14\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception15Handle:\r
-    push    15\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception16Handle:\r
-    push    16\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception17Handle:\r
-    push    17\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception18Handle:\r
-    push    18\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception19Handle:\r
-    push    19\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception20Handle:\r
-    push    20\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception21Handle:\r
-    push    21\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception22Handle:\r
-    push    22\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception23Handle:\r
-    push    23\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception24Handle:\r
-    push    24\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception25Handle:\r
-    push    25\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception26Handle:\r
-    push    26\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception27Handle:\r
-    push    27\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception28Handle:\r
-    push    28\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception29Handle:\r
-    push    29\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception30Handle:\r
-    push    30\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception31Handle:\r
-    push    31\r
-    jmp     qword ptr [CommonEntryAddr]\r
-\r
-;CommonInterruptEntrypoint:\r
-;---------------------------------------;\r
-; _CommonEntry                  ;\r
-;----------------------------------------------------------------------------;\r
-; The follow algorithm is used for the common interrupt routine.\r
-; Entry from each interrupt with a push eax and eax=interrupt number\r
+ALIGN   8\r
+\r
+AsmIdtVectorBegin:\r
+REPEAT  32\r
+    db      6ah        ; push  #VectorNum\r
+    db      ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum\r
+    push    rax\r
+    mov     rax, CommonInterruptEntry\r
+    jmp     rax\r
+ENDM\r
+AsmIdtVectorEnd:\r
+\r
+HookAfterStubHeaderBegin:\r
+    db      6ah        ; push\r
+@VectorNum:\r
+    db      0          ; 0 will be fixed\r
+    push    rax\r
+    mov     rax, HookAfterStubHeaderEnd\r
+    jmp     rax\r
+HookAfterStubHeaderEnd:\r
+    mov     rax, rsp\r
+    and     sp,  0fff0h        ; make sure 16-byte aligned for exception context\r
+    sub     rsp, 18h           ; reserve room for filling exception data later\r
+    push    rcx\r
+    mov     rcx, [rax + 8]\r
+    bt      mErrorCodeFlag, ecx\r
+    jnc     @F\r
+    push    [rsp]             ; push additional rcx to make stack alignment\r
+@@:\r
+    xchg    rcx, [rsp]        ; restore rcx, save Exception Number in stack\r
+    push    [rax]             ; push rax into stack to keep code consistence\r
 \r
 ;---------------------------------------;\r
 ; CommonInterruptEntry                  ;\r
 ;---------------------------------------;\r
 ; The follow algorithm is used for the common interrupt routine.\r
-\r
-CommonInterruptEntry PROC PUBLIC  \r
+; Entry from each interrupt with a push eax and eax=interrupt number\r
+; Stack frame would be as follows as specified in IA32 manuals:\r
+;\r
+; +---------------------+ <-- 16-byte aligned ensured by processor\r
+; +    Old SS           +\r
+; +---------------------+\r
+; +    Old RSP          +\r
+; +---------------------+\r
+; +    RFlags           +\r
+; +---------------------+\r
+; +    CS               +\r
+; +---------------------+\r
+; +    RIP              +\r
+; +---------------------+\r
+; +    Error Code       +\r
+; +---------------------+\r
+; +   Vector Number     +\r
+; +---------------------+\r
+; +    RBP              +\r
+; +---------------------+ <-- RBP, 16-byte aligned\r
+; The follow algorithm is used for the common interrupt routine.\r
+CommonInterruptEntry PROC PUBLIC\r
     cli\r
+    pop     rax\r
     ;\r
     ; All interrupt handlers are invoked through interrupt gates, so\r
     ; IF flag automatically cleared at the entry point\r
     ;\r
-    ;\r
-    ; Calculate vector number\r
-    ;\r
-    xchg    rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.\r
+    xchg    rcx, [rsp]      ; Save rcx into stack and save vector number into rcx\r
+    and     rcx, 0FFh\r
     cmp     ecx, 32         ; Intel reserved vector for exceptions?\r
     jae     NoErrorCode\r
     bt      mErrorCodeFlag, ecx\r
@@ -165,9 +111,11 @@ NoErrorCode:
     ;\r
     push    [rsp]\r
     mov     qword ptr [rsp + 8], 0\r
-@@:       \r
+@@:\r
     push    rbp\r
     mov     rbp, rsp\r
+    push    0             ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    push    0             ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
 \r
     ;\r
     ; Stack:\r
@@ -389,6 +337,29 @@ NoErrorCode:
     mov     rsp, rbp\r
     pop     rbp\r
     add     rsp, 16\r
+    cmp     qword ptr [rsp - 32], 0  ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    jz      DoReturn\r
+    cmp     qword ptr [rsp - 40], 1  ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+    jz      ErrorCode\r
+    jmp     qword ptr [rsp - 32]\r
+ErrorCode:\r
+    sub     rsp, 8\r
+    jmp     qword ptr [rsp - 24]\r
+\r
+DoReturn:\r
+    cmp     mDoFarReturnFlag, 0   ; Check if need to do far return instead of IRET\r
+    jz      DoIret\r
+    push    rax\r
+    mov     rax, rsp          ; save old RSP to rax\r
+    mov     rsp, [rsp + 20h]\r
+    push    [rax + 10h]       ; save CS in new location\r
+    push    [rax + 8h]        ; save EIP in new location\r
+    push    [rax + 18h]       ; save EFLAGS in new location\r
+    mov     rax, [rax]        ; restore rax\r
+    popfq                     ; restore EFLAGS\r
+    DB      48h               ; prefix to composite "retq" with next "retf"\r
+    retf                      ; far return\r
+DoIret:\r
     iretq\r
 \r
 CommonInterruptEntry ENDP\r
@@ -397,11 +368,22 @@ CommonInterruptEntry ENDP
 ;  GetTemplateAddressMap (&AddressMap);\r
 ;-------------------------------------------------------------------------------------\r
 ; comments here for definition of address map\r
-GetTemplateAddressMap   PROC\r
-        mov         rax, offset Exception0Handle\r
-        mov         qword ptr [rcx], rax\r
-        mov         qword ptr [rcx+8h], Exception1Handle - Exception0Handle\r
-        ret\r
-GetTemplateAddressMap   ENDP\r
+AsmGetTemplateAddressMap   PROC\r
+    mov     rax, offset AsmIdtVectorBegin\r
+    mov     qword ptr [rcx], rax\r
+    mov     qword ptr [rcx + 8h],  (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32\r
+    mov     rax, offset HookAfterStubHeaderBegin\r
+    mov     qword ptr [rcx + 10h], rax\r
+    ret\r
+AsmGetTemplateAddressMap   ENDP\r
+\r
+;-------------------------------------------------------------------------------------\r
+;  AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);\r
+;-------------------------------------------------------------------------------------\r
+AsmVectorNumFixup   PROC\r
+    mov     rax, rdx\r
+    mov     [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al\r
+    ret\r
+AsmVectorNumFixup   ENDP\r
 \r
 END\r