]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Port AsmFuncs.s to pass CYGWINGCC build for x64.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 15 Dec 2008 10:05:10 +0000 (10:05 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 15 Dec 2008 10:05:10 +0000 (10:05 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7033 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c
MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c
MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S
MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c

index 24e2cd070003f5fbe7bb89e9a688d242fecde16d..3c96f9b518436089c075e3348426ae5492236258 100644 (file)
@@ -18,7 +18,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 // This the global main table to keep track of the interrupts\r
 //\r
 IDT_ENTRY                 *IdtEntryTable  = NULL;\r
 // This the global main table to keep track of the interrupts\r
 //\r
 IDT_ENTRY                 *IdtEntryTable  = NULL;\r
-IA32_IDT_GATE_DESCRIPTOR  NullDesc        = {0};\r
 \r
 /**\r
   Read IDT Gate Descriptor from IDT Table.\r
 \r
 /**\r
   Read IDT Gate Descriptor from IDT Table.\r
index ff21ed7f2a35c4944876bdd5b50f04347f0e70cb..c75c0401522b8588d0dd3eef98a9380cf8948144 100644 (file)
@@ -14,6 +14,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "DebugSupport.h"\r
 \r
 \r
 #include "DebugSupport.h"\r
 \r
+IA32_IDT_GATE_DESCRIPTOR  NullDesc = {{0}};\r
+\r
 /**\r
   Get Interrupt Handle from IDT Gate Descriptor.\r
 \r
 /**\r
   Get Interrupt Handle from IDT Gate Descriptor.\r
 \r
index 693d26e6e4bbf082289497f350034fc557dda596..864b6e41127126ecb887763668bbfa90dd9df8d3 100644 (file)
@@ -1,7 +1,7 @@
 #/**@file\r
 # Low leve x64 specific debug support functions.\r
 #\r
 #/**@file\r
 # Low leve x64 specific debug support functions.\r
 #\r
-# Copyright (c) 2006, Intel Corporation\r
+# Copyright (c) 2006 - 2008, Intel Corporation\r
 # All rights reserved. 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
 # All rights reserved. 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
 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 #\r
 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 #\r
-#**/\r
+#**/    \r
 \r
 \r
-.globl _OrigVector\r
-.globl _InterruptEntryStub\r
-.globl _StubSize\r
-.globl _CommonIdtEntry\r
-.globl _FxStorSupport\r
+.intel_syntax noprefix\r
 \r
 \r
-_AppEsp:         .long   0x11111111 # ?\r
-_DebugEsp:       .long   0x22222222 # ?\r
-_ExtraPush:      .long   0x33333333 # ?\r
-_ExceptData:     .long   0x44444444 # ?\r
-_Eflags:         .long   0x55555555 # ?\r
-_OrigVector:     .long   0x66666666 # ?\r
-_StubSize:       .long   _InterruptEntryStubEnd - _InterruptEntryStub\r
 \r
 \r
-.globl _FxStorSupport\r
-_FxStorSupport:\r
-        ret\r
+.globl ASM_PFX(OrigVector)\r
+.globl ASM_PFX(InterruptEntryStub)\r
+.globl ASM_PFX(StubSize)\r
+.globl ASM_PFX(CommonIdtEntry)\r
+.globl ASM_PFX(FxStorSupport)\r
+     \r
+.data \r
 \r
 \r
-.globl _Vect2Desc\r
-_Vect2Desc:\r
-        ret\r
+ASM_PFX(StubSize):         .long   ASM_PFX(InterruptEntryStubEnd) - ASM_PFX(InterruptEntryStub)\r
+ASM_PFX(AppRsp):           .long   0x11111111 # ?\r
+                           .long   0x11111111 # ?\r
+ASM_PFX(DebugRsp):         .long   0x22222222 # ?\r
+                           .long   0x22222222 # ?\r
+ASM_PFX(ExtraPush):        .long   0x33333333 # ?\r
+                           .long   0x33333333 # ?\r
+ASM_PFX(ExceptData):       .long   0x44444444 # ?\r
+                           .long   0x44444444 # ?\r
+ASM_PFX(Rflags):           .long   0x55555555 # ?\r
+                           .long   0x55555555 # ?\r
+ASM_PFX(OrigVector):       .long   0x66666666 # ?\r
+                           .long   0x66666666 # ?\r
 \r
 \r
-.globl _InterruptEntryStub\r
-_InterruptEntryStub:\r
-        ret\r
+## The declarations below define the memory region that will be used for the debug stack.\r
+## The context record will be built by pushing register values onto this stack.\r
+## It is imparitive that alignment be carefully managed, since the FXSTOR and\r
+## FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned.\r
+##\r
+## The stub will switch stacks from the application stack to the debuger stack\r
+## and pushes the exception number.\r
+##\r
+## Then we building the context record on the stack. Since the stack grows down,\r
+## we push the fields of the context record from the back to the front.  There\r
+## are 336 bytes of stack used prior allocating the 512 bytes of stack to be\r
+## used as the memory buffer for the fxstor instruction. Therefore address of\r
+## the buffer used for the FXSTOR instruction is &Eax - 336 - 512, which\r
+## must be 16 byte aligned.\r
+##\r
+## We carefully locate the stack to make this happen.\r
+##\r
+## For reference, the context structure looks like this:\r
+##      struct {\r
+##        UINT64            ExceptionData;\r
+##        FX_SAVE_STATE_X64 FxSaveState;    // 512 bytes, must be 16 byte aligned\r
+##        UINT64            Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+##        UINT64            Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+##        UINT64            RFlags;\r
+##        UINT64            Ldtr, Tr;\r
+##        UINT64            Gdtr[2], Idtr[2];\r
+##        UINT64            Rip;\r
+##        UINT64            Gs, Fs, Es, Ds, Cs, Ss;\r
+##        UINT64            Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+##        UINT64            R8, R9, R10, R11, R12, R13, R14, R15;\r
+##      } SYSTEM_CONTEXT_X64;  // 64 bit system context record\r
+\r
+.align          16\r
+DebugStackEnd : .ascii     "DbgStkEnd >>>>>>"    # 16 byte long string - must be 16 bytes to preserve alignment\r
+                .rept  0x1ffc\r
+                  .long    0x00000000  \r
+                .endr\r
+                                                 # 32K should be enough stack\r
+                                                 #   This allocation is coocked to insure\r
+                                                 #   that the the buffer for the FXSTORE instruction\r
+                                                 #   will be 16 byte aligned also.\r
+                                                 #\r
+ASM_PFX(ExceptionNumber):  .long   0x77777777    # first entry will be the vector number pushed by the stub\r
+                           .long   0x77777777    # ?\r
+\r
+DebugStackBegin : .ascii    "<<<< DbgStkBegin"   # initial debug ESP == DebugStackBegin, set in stub\r
+           \r
+\r
+.text\r
+\r
+#------------------------------------------------------------------------------\r
+# BOOLEAN\r
+# FxStorSupport (\r
+#   void\r
+#   )\r
+#\r
+# Abstract: Returns TRUE if FxStor instructions are supported\r
+#\r
+.globl ASM_PFX(FxStorSupport)\r
+ASM_PFX(FxStorSupport):  \r
+#\r
+# cpuid corrupts rbx which must be preserved per the C calling convention\r
+#\r
+                push    rbx\r
+                mov     rax, 1\r
+                cpuid\r
+                mov     eax, edx\r
+                and     rax, 0x01000000\r
+                shr     rax, 24\r
+                pop     rbx\r
+                ret\r
+#------------------------------------------------------------------------------\r
+# void\r
+# Vect2Desc (\r
+#   IA32_IDT_GATE_DESCRIPTOR * DestDesc,  // rcx\r
+#   void (*Vector) (void)   // rdx\r
+#   )\r
+#\r
+# Abstract: Encodes an IDT descriptor with the given physical address\r
+#\r
+.globl ASM_PFX(Vect2Desc)\r
+ASM_PFX(Vect2Desc):\r
+                mov     rax, rdx\r
+                mov     word ptr [rcx], ax                  # write bits 15..0 of offset\r
+                mov     dx, cs\r
+                mov     word ptr [rcx+2], dx                # SYS_CODE_SEL from GDT\r
+                mov     word ptr [rcx+4], 0x0e00 OR 0x8000  # type = 386 interrupt gate, present\r
+                shr     rax, 16\r
+                mov     word ptr [rcx+6], ax                # write bits 31..16 of offset\r
+                shr     rax, 16\r
+                mov     dword ptr [rcx+8], eax              # write bits 63..32 of offset\r
+\r
+                ret\r
+\r
+#------------------------------------------------------------------------------\r
+# InterruptEntryStub\r
+#\r
+# Abstract: This code is not a function, but is a small piece of code that is\r
+#               copied and fixed up once for each IDT entry that is hooked.\r
+#\r
+.globl ASM_PFX(InterruptEntryStub)\r
+ASM_PFX(InterruptEntryStub):\r
+\r
+                push    0                       # push vector number - will be modified before installed\r
+                jmp     ASM_PFX(CommonIdtEntry)\r
+                \r
+.globl ASM_PFX(InterruptEntryStubEnd)\r
+ASM_PFX(InterruptEntryStubEnd):\r
 \r
 \r
-.globl _InterruptEntryStubEnd\r
-_InterruptEntryStubEnd:\r
         ret\r
 \r
         ret\r
 \r
-.globl _CommonIdtEntry\r
-_CommonIdtEntry:\r
+#------------------------------------------------------------------------------\r
+# CommonIdtEntry\r
+#\r
+# Abstract: This code is not a function, but is the common part for all IDT\r
+#               vectors.\r
+#\r
+.globl ASM_PFX(CommonIdtEntry)\r
+##\r
+## At this point, the stub has saved the current application stack esp into AppRsp\r
+## and switched stacks to the debug stack, where it pushed the vector number\r
+##\r
+## The application stack looks like this:\r
+##\r
+##              ...\r
+##              (last application stack entry)\r
+##              [16 bytes alignment, do not care it]\r
+##              SS from interrupted task\r
+##              RSP from interrupted task\r
+##              rflags from interrupted task\r
+##              CS from interrupted task\r
+##              RIP from interrupted task\r
+##              Error code <-------------------- Only present for some exeption types\r
+##\r
+##              Vector Number <----------------- pushed in our IDT Entry\r
+##\r
+\r
+\r
+## The stub switched us to the debug stack and pushed the interrupt number.\r
+##\r
+## Next, construct the context record.  It will be build on the debug stack by\r
+## pushing the registers in the correct order so as to create the context structure\r
+## on the debug stack.  The context record must be built from the end back to the\r
+## beginning because the stack grows down...\r
+#\r
+## For reference, the context record looks like this:\r
+##\r
+## typedef\r
+## struct {\r
+##   UINT64            ExceptionData;\r
+##   FX_SAVE_STATE_X64 FxSaveState;\r
+##   UINT64            Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+##   UINT64            Cr0, Cr2, Cr3, Cr4, Cr8;\r
+##   UINT64            RFlags;\r
+##   UINT64            Ldtr, Tr;\r
+##   UINT64            Gdtr[2], Idtr[2];\r
+##   UINT64            Rip;\r
+##   UINT64            Gs, Fs, Es, Ds, Cs, Ss;\r
+##   UINT64            Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+##   UINT64            R8, R9, R10, R11, R12, R13, R14, R15;\r
+## } SYSTEM_CONTEXT_X64;  // 64\r
+ASM_PFX(CommonIdtEntry):\r
+\r
         ret\r
 \r
         ret\r
 \r
-PhonyIretd:\r
-        iret\r
+## NOTE: we save rsp here to prevent compiler put rip reference cause error AppRsp\r
+                push    rax\r
+                mov     rax, qword ptr [rsp][8]          # save vector number\r
+                mov     ASM_PFX(ExceptionNumber), rax             # save vector number\r
+                pop     rax\r
+                add     rsp, 8                           # pop vector number\r
+                mov     ASM_PFX(AppRsp), rsp                      # save stack top\r
+                mov     rsp, offset DebugStackBegin      # switch to debugger stack\r
+                sub     rsp, 8                           # leave space for vector number\r
+## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+                push    r15\r
+                push    r14\r
+                push    r13\r
+                push    r12\r
+                push    r11\r
+                push    r10\r
+                push    r9\r
+                push    r8\r
+                push    rax\r
+                push    rcx\r
+                push    rdx\r
+                push    rbx\r
+                push    rsp\r
+                push    rbp\r
+                push    rsi\r
+                push    rdi\r
+## Save interrupt state rflags register...\r
+                pushfq\r
+                pop     rax\r
+                mov     qword ptr ASM_PFX(Rflags), rax\r
+## We need to determine if any extra data was pushed by the exception, and if so, save it\r
+## To do this, we check the exception number pushed by the stub, and cache the\r
+## result in a variable since we'll need this again.\r
+                cmp dword ptr ASM_PFX(ExceptionNumber), 0\r
+                jz      ExtraPushOne\r
+                cmp dword ptr     ASM_PFX(ExceptionNumber), 10\r
+                jz      ExtraPushOne\r
+                cmp dword ptr     ASM_PFX(ExceptionNumber), 11\r
+                jz      ExtraPushOne\r
+                cmp dword ptr     ASM_PFX(ExceptionNumber), 12\r
+                jz      ExtraPushOne\r
+                cmp dword ptr     ASM_PFX(ExceptionNumber), 13\r
+                jz      ExtraPushOne\r
+                cmp dword ptr     ASM_PFX(ExceptionNumber), 14\r
+                jz      ExtraPushOne\r
+                cmp dword ptr     ASM_PFX(ExceptionNumber), 17\r
+                jz      ExtraPushOne\r
+                mov dword ptr     ASM_PFX(ExtraPush), 0\r
+                mov dword ptr     ASM_PFX(ExceptData), 0\r
+                jmp     ExtraPushDone\r
+ExtraPushOne:\r
+                mov dword ptr     ASM_PFX(ExtraPush), 1\r
+\r
+## If there's some extra data, save it also, and modify the saved AppRsp to effectively\r
+## pop this value off the application's stack.\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                mov     rbx, [rax]\r
+                mov     ASM_PFX(ExceptData), rbx\r
+                add     rax, 8\r
+                mov     ASM_PFX(AppRsp), rax\r
+\r
+ExtraPushDone:\r
+\r
+## The "push" above pushed the debug stack rsp.  Since what we're actually doing\r
+## is building the context record on the debug stack, we need to save the pushed\r
+## debug RSP, and replace it with the application's last stack entry...\r
+                mov     rax, [rsp + 24]\r
+                mov     ASM_PFX(DebugRsp), rax\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                add     rax, 40\r
+                # application stack has ss, rsp, rflags, cs, & rip, so\r
+                # last actual application stack entry is\r
+                # 40 bytes into the application stack.\r
+                mov     [rsp + 24], rax\r
+## continue building context record\r
+## UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero\r
+                mov     rax, ss\r
+                push    rax\r
+                # CS from application is one entry back in application stack\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                movzx   rax, word ptr [rax + 8]\r
+                push    rax\r
+\r
+                mov     rax, ds\r
+                push    rax\r
+                mov     rax, es\r
+                push    rax\r
+                mov     rax, fs\r
+                push    rax\r
+                mov     rax, gs\r
+                push    rax\r
+## UINT64  Rip;\r
+                # Rip from application is on top of application stack\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                push    qword ptr [rax]\r
+## UINT64  Gdtr[2], Idtr[2];\r
+                push    0\r
+                push    0\r
+                sidt    qword ptr [rsp]\r
+                push    0\r
+                push    0\r
+                sgdt    qword ptr [rsp]\r
+\r
+## UINT64  Ldtr, Tr;\r
+                xor     rax, rax\r
+                str     ax\r
+                push    rax\r
+                sldt    ax\r
+                push    rax\r
+\r
+## UINT64  RFlags;\r
+## Rflags from application is two entries back in application stack\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                push    qword ptr [rax + 16]\r
+## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+## insure FXSAVE/FXRSTOR is enabled in CR4...\r
+## ... while we're at it, make sure DE is also enabled...\r
+                mov     rax, cr8\r
+                push    rax\r
+                mov     rax, cr4\r
+                or      rax, 0x208\r
+                mov     cr4, rax\r
+                push    rax\r
+                mov     rax, cr3\r
+                push    rax\r
+                mov     rax, cr2\r
+                push    rax\r
+                push    0\r
+                mov     rax, cr0\r
+                push    rax\r
+## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+                mov     rax, dr7\r
+                push    rax\r
+## clear Dr7 while executing debugger itself\r
+                xor     rax, rax\r
+                mov     dr7, rax\r
+\r
+                mov     rax, dr6\r
+                push    rax\r
+## insure all status bits in dr6 are clear...\r
+                xor     rax, rax\r
+                mov     dr6, rax\r
+\r
+                mov     rax, dr3\r
+                push    rax\r
+                mov     rax, dr2\r
+                push    rax\r
+                mov     rax, dr1\r
+                push    rax\r
+                mov     rax, dr0\r
+                push    rax\r
+\r
+## FX_SAVE_STATE_X64 FxSaveState;\r
+                sub     rsp, 512\r
+                mov     rdi, rsp\r
+                # IMPORTANT!! The debug stack has been carefully constructed to\r
+                # insure that rsp and rdi are 16 byte aligned when we get here.\r
+                # They MUST be.  If they are not, a GP fault will occur.\r
+           #     FXSTOR_RDI\r
+               .byte       0x0f\r
+               .byte       0xae\r
+               .byte       0x07\r
+\r
+## UINT64  ExceptionData;\r
+                mov     rax, ASM_PFX(ExceptData)\r
+                push    rax\r
+# call to C code which will in turn call registered handler\r
+# pass in the vector number\r
+                mov     rdx, rsp\r
+                mov     rcx, ASM_PFX(ExceptionNumber)\r
+                sub     rsp, 40\r
+                call    ASM_PFX(InterruptDistrubutionHub)\r
+                add     rsp, 40\r
+# restore context...\r
+## UINT64  ExceptionData;\r
+                add     rsp, 8\r
+## FX_SAVE_STATE_X64 FxSaveState;\r
+                mov     rsi, rsp\r
+            #    FXRSTOR_RSI\r
+               .byte       0x0f\r
+               .byte       0xae\r
+               .byte       0x0e\r
+                add     rsp, 512\r
+;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+                pop     rax\r
+                mov     dr0, rax\r
+                pop     rax\r
+                mov     dr1, rax\r
+                pop     rax\r
+                mov     dr2, rax\r
+                pop     rax\r
+                mov     dr3, rax\r
+## skip restore of dr6.  We cleared dr6 during the context save.\r
+                add     rsp, 8\r
+                pop     rax\r
+                mov     dr7, rax\r
+## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+                pop     rax\r
+                mov     cr0, rax\r
+                add     rsp, 8\r
+                pop     rax\r
+                mov     cr2, rax\r
+                pop     rax\r
+                mov     cr3, rax\r
+                pop     rax\r
+                mov     cr4, rax\r
+                pop     rax\r
+                mov     cr8, rax\r
+## UINT64  RFlags;\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                pop     qword ptr [rax + 16]\r
+## UINT64  Ldtr, Tr;\r
+## UINT64  Gdtr[2], Idtr[2];\r
+## Best not let anyone mess with these particular registers...\r
+                add     rsp, 48\r
+## UINT64  Rip;\r
+                pop     qword ptr [rax]\r
+\r
+## UINT64  Gs, Fs, Es, Ds, Cs, Ss;\r
+## NOTE - modified segment registers could hang the debugger...  We\r
+##        could attempt to insulate ourselves against this possibility,\r
+##        but that poses risks as well.\r
+##\r
+\r
+                pop     rax\r
+                # mov     gs, rax\r
+                pop     rax\r
+                # mov     fs, rax\r
+                pop     rax\r
+                mov     es, rax\r
+                pop     rax\r
+                mov     ds, rax\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                pop     qword ptr [rax + 8]\r
+                pop     rax\r
+                mov     ss, rax\r
+## The next stuff to restore is the general purpose registers that were pushed\r
+## using the "push" instruction.\r
+##\r
+## The value of RSP as stored in the context record is the application RSP\r
+## including the 5 entries on the application stack caused by the exception\r
+## itself. It may have been modified by the debug agent, so we need to\r
+## determine if we need to relocate the application stack.\r
+\r
+                mov     rbx, [rsp + 24]  # move the potentially modified AppRsp into rbx\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                add     rax, 40\r
+                cmp     rbx, rax\r
+                je      NoAppStackMove\r
+\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                mov     rcx, [rax]       # RIP\r
+                mov     [rbx], rcx\r
+\r
+                mov     rcx, [rax + 8]   # CS\r
+                mov     [rbx + 8], rcx\r
+\r
+                mov     rcx, [rax + 16]  # RFLAGS\r
+                mov     [rbx + 16], rcx\r
+\r
+                mov     rcx, [rax + 24]  # RSP\r
+                mov     [rbx + 24], rcx\r
+\r
+                mov     rcx, [rax + 32]  # SS\r
+                mov     [rbx + 32], rcx\r
+\r
+                mov     rax, rbx         # modify the saved AppRsp to the new AppRsp\r
+                mov     ASM_PFX(AppRsp), rax\r
+NoAppStackMove:\r
+                mov     rax, ASM_PFX(DebugRsp)    # restore the DebugRsp on the debug stack\r
+                                         # so our "pop" will not cause a stack switch\r
+                mov     [rsp + 24], rax\r
+\r
+                cmp dword ptr ASM_PFX(ExceptionNumber), 0x068\r
+                jne     NoChain\r
+\r
+Chain:\r
+\r
+## Restore rflags so when we chain, the flags will be exactly as if we were never here.\r
+## We gin up the stack to do an iretq so we can get ALL the flags.\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                mov     rbx, [rax + 40]\r
+                push    rbx\r
+                mov     rax, ss\r
+                push    rax\r
+                mov     rax, rsp\r
+                add     rax, 16\r
+                push    rax\r
+                mov     rax, ASM_PFX(AppRsp)\r
+                mov     rbx, [rax + 16]\r
+                and     rbx, NOT 0x300 # special handling for IF and TF\r
+                push    rbx\r
+                mov     rax, cs\r
+                push    rax\r
+                mov     rax, offset PhonyIretq\r
+                push    rax\r
+                iretq\r
+PhonyIretq:\r
+\r
+## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+                pop     rdi\r
+                pop     rsi\r
+                pop     rbp\r
+                pop     rsp\r
+                pop     rbx\r
+                pop     rdx\r
+                pop     rcx\r
+                pop     rax\r
+                pop     r8\r
+                pop     r9\r
+                pop     r10\r
+                pop     r11\r
+                pop     r12\r
+                pop     r13\r
+                pop     r14\r
+                pop     r15\r
+\r
+## Switch back to application stack\r
+                mov     rsp, ASM_PFX(AppRsp)\r
+## Jump to original handler\r
+                jmp     ASM_PFX(OrigVector)\r
+NoChain:\r
+## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+                pop     rdi\r
+                pop     rsi\r
+                pop     rbp\r
+                pop     rsp\r
+                pop     rbx\r
+                pop     rdx\r
+                pop     rcx\r
+                pop     rax\r
+                pop     r8\r
+                pop     r9\r
+                pop     r10\r
+                pop     r11\r
+                pop     r12\r
+                pop     r13\r
+                pop     r14\r
+                pop     r15\r
+\r
+## Switch back to application stack\r
+                mov     rsp, ASM_PFX(AppRsp)\r
+\r
+## We're outa here...\r
+                iret\r
index e898d822719adb133fbf2802b08450b102595928..d6173bb12f3fa5588403d4bccbc983cac6ceb490 100644 (file)
@@ -14,6 +14,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "DebugSupport.h"\r
 \r
 \r
 #include "DebugSupport.h"\r
 \r
+IA32_IDT_GATE_DESCRIPTOR  NullDesc = {{0,0}};\r
+\r
 /**\r
   Get Interrupt Handle from IDT Gate Descriptor.\r
 \r
 /**\r
   Get Interrupt Handle from IDT Gate Descriptor.\r
 \r