summaryrefslogtreecommitdiffstats
path: root/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
diff options
context:
space:
mode:
Diffstat (limited to 'SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S')
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S360
1 files changed, 360 insertions, 0 deletions
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
new file mode 100644
index 0000000000..365947f4d5
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
@@ -0,0 +1,360 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# AsmFuncs.S
+#
+# Abstract:
+#
+# Debug interrupt handle functions.
+#
+#------------------------------------------------------------------------------
+
+#include "DebugException.h"
+
+ASM_GLOBAL ASM_PFX(InterruptProcess)
+ASM_GLOBAL ASM_PFX(Exception0Handle)
+ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)
+ASM_GLOBAL ASM_PFX(TimerInterruptHandle)
+ASM_GLOBAL ASM_PFX(CommonEntry)
+
+.data
+
+ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
+
+.text
+
+ASM_PFX(Exception0Handle):
+ cli
+ pushl %eax
+ mov $0, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception1Handle):
+ cli
+ pushl %eax
+ mov $1, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception2Handle):
+ cli
+ pushl %eax
+ mov $2, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception3Handle):
+ cli
+ pushl %eax
+ mov $3, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception4Handle):
+ cli
+ pushl %eax
+ mov $4, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception5Handle):
+ cli
+ pushl %eax
+ mov $5, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception6Handle):
+ cli
+ pushl %eax
+ mov $6, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception7Handle):
+ cli
+ pushl %eax
+ mov $7, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception8Handle):
+ cli
+ pushl %eax
+ mov $8, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception9Handle):
+ cli
+ pushl %eax
+ mov $9, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception10Handle):
+ cli
+ pushl %eax
+ mov $10, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception11Handle):
+ cli
+ pushl %eax
+ mov $11, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception12Handle):
+ cli
+ pushl %eax
+ mov $12, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception13Handle):
+ cli
+ pushl %eax
+ mov $13, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception14Handle):
+ cli
+ pushl %eax
+ mov $14, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception15Handle):
+ cli
+ pushl %eax
+ mov $15, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception16Handle):
+ cli
+ pushl %eax
+ mov $16, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception17Handle):
+ cli
+ pushl %eax
+ mov $17, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception18Handle):
+ cli
+ pushl %eax
+ mov $18, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception19Handle):
+ cli
+ pushl %eax
+ mov $19, %eax
+ jmp ASM_PFX(CommonEntry)
+
+ASM_PFX(TimerInterruptHandle):
+ cli
+ pushl %eax
+ mov $32, %eax
+ jmp ASM_PFX(CommonEntry)
+
+
+ASM_PFX(CommonEntry):
+
+#---------------------------------------;
+# _CommonEntry ;
+#----------------------------------------------------------------------------;
+# The follow algorithm is used for the common interrupt routine.
+# Entry from each interrupt with a push eax and eax=interrupt number
+#
+# +---------------------+
+# + EFlags +
+# +---------------------+
+# + CS +
+# +---------------------+
+# + EIP +
+# +---------------------+
+# + Error Code +
+# +---------------------+
+# + EAX / Vector Number +
+# +---------------------+
+# + EBP +
+# +---------------------+ <-- EBP
+#
+
+# We need to determine if any extra data was pushed by the exception
+ cmpl $DEBUG_EXCEPT_DOUBLE_FAULT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_INVALID_TSS, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_SEG_NOT_PRESENT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_STACK_FAULT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_GP_FAULT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_PAGE_FAULT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_ALIGNMENT_CHECK, %eax
+ je NoExtrPush
+
+ pushl (%esp)
+ movl $0, 4(%esp)
+
+NoExtrPush:
+
+ pushl %ebp
+ movl %esp,%ebp
+
+ #
+ # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
+ # is 16-byte aligned
+ #
+ andl $0xfffffff0,%esp
+ subl $12,%esp
+
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ pushl 0x4(%ebp)
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ mov %eax, %ebx # save vector in ebx
+ leal 24(%ebp),%ecx
+ pushl %ecx # save original ESP
+ pushl (%ebp)
+ pushl %esi
+ pushl %edi
+
+## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ movl %cr4, %eax
+ orl $0x208,%eax
+ movl %eax, %cr4
+ pushl %eax
+ movl %cr3, %eax
+ pushl %eax
+ movl %cr2, %eax
+ pushl %eax
+ xorl %eax,%eax
+ pushl %eax
+ movl %cr0, %eax
+ pushl %eax
+
+## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+ movl %ss,%eax
+ pushl %eax
+ movzwl 16(%ebp), %eax
+ pushl %eax
+ movl %ds,%eax
+ pushl %eax
+ movl %es,%eax
+ pushl %eax
+ movl %fs,%eax
+ pushl %eax
+ movl %gs,%eax
+ pushl %eax
+
+## UINT32 Eip;
+ pushl 12(%ebp)
+
+## UINT32 Gdtr[2], Idtr[2];
+ subl $8,%esp
+ sidt (%esp)
+ subl $8,%esp
+ sgdt (%esp)
+
+## UINT32 Ldtr, Tr;
+ xorl %eax,%eax
+ strl %eax
+ pushl %eax
+ sldtl %eax
+ pushl %eax
+
+## UINT32 EFlags;
+ pushl 20(%ebp)
+
+## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ movl %dr7, %eax
+ pushl %eax
+## clear Dr7 while executing debugger itself
+ xorl %eax,%eax
+# movl %eax, %dr7
+
+ movl %dr6, %eax
+ pushl %eax
+## insure all status bits in dr6 are clear...
+ xorl %eax,%eax
+ movl %eax, %dr6
+
+ movl %dr3, %eax
+ pushl %eax
+ movl %dr2, %eax
+ pushl %eax
+ movl %dr1, %eax
+ pushl %eax
+ movl %dr0, %eax
+ pushl %eax
+
+## FX_SAVE_STATE_IA32 FxSaveState;
+ subl $512,%esp
+ movl %esp,%edi
+ .byte 0x0f, 0xae, 0x07 # fxsave [edi]
+
+## Clear Direction Flag
+ cld
+
+## Prepare parameter and call C function
+ pushl %esp
+ pushl %ebx
+ call ASM_PFX(InterruptProcess)
+ addl $8,%esp
+
+## FX_SAVE_STATE_IA32 FxSaveState;
+ movl %esp,%esi
+ .byte 0x0f, 0xae, 0x0e # fxrstor [esi]
+ addl $512,%esp
+
+## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ popl %eax
+ movl %eax, %dr0
+ popl %eax
+ movl %eax, %dr1
+ popl %eax
+ movl %eax, %dr2
+ popl %eax
+ movl %eax, %dr3
+## skip restore of dr6. We cleared dr6 during the context save.
+ addl $4,%esp
+ popl %eax
+ movl %eax, %dr7
+
+## UINT32 EFlags;
+ popl 20(%ebp)
+
+## UINT32 Ldtr, Tr;
+## UINT32 Gdtr[2], Idtr[2];
+## Best not let anyone mess with these particular registers...
+ addl $24,%esp
+
+## UINT32 Eip;
+ pop 12(%ebp)
+
+## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+## NOTE - modified segment registers could hang the debugger... We
+## could attempt to insulate ourselves against this possibility,
+## but that poses risks as well.
+##
+ popl %gs
+ popl %fs
+ popl %es
+ popl %ds
+ popl 16(%ebp)
+ popl %ss
+
+## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ popl %eax
+ movl %eax, %cr0
+ addl $4,%esp # not for Cr1
+ popl %eax
+ movl %eax, %cr2
+ popl %eax
+ movl %eax, %cr3
+ popl %eax
+ movl %eax, %cr4
+
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ popl %edi
+ popl %esi
+ addl $4,%esp # not for ebp
+ addl $4,%esp # not for esp
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %eax
+
+ movl %ebp,%esp
+ popl %ebp
+ addl $8,%esp # skip eax
+ iretl
+