#------------------------------------------------------------------------------\r
#*\r
-#* Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+#* Copyright (c) 2012 - 2015, 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(HookAfterStubHeaderEnd)\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
# 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
+ASM_PFX(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
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
#\r
# Put Vector Number on stack and restore ECX\r
#\r
- xchgl (%esp), %ecx \r
+ xchgl (%esp), %ecx\r
\r
ErrorCodeAndVectorOnStack:\r
pushl %ebp\r
# Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
# is 16-byte aligned\r
#\r
- andl $0x0fffffff0, %esp \r
+ 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
#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
movl %ss, %eax\r
pushl %eax\r
- movzwl 16(%ebp), %eax \r
+ movzwl 16(%ebp), %eax\r
pushl %eax\r
movl %ds, %eax\r
pushl %eax\r
sidt (%esp)\r
movl 2(%esp), %eax\r
xchgl (%esp), %eax\r
- andl $0x0FFFF, %eax \r
+ andl $0x0FFFF, %eax\r
movl %eax, 4(%esp)\r
\r
subl $8, %esp\r
sgdt (%esp)\r
movl 2(%esp), %eax\r
xchgl (%esp), %eax\r
- andl $0x0FFFF, %eax \r
+ andl $0x0FFFF, %eax\r
movl %eax, 4(%esp)\r
\r
#; UINT32 Ldtr, Tr;\r
pushl %eax\r
\r
#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
+## insure FXSAVE/FXRSTOR is enabled in CR4...\r
+## ... while we're at it, make sure DE is also enabled...\r
+ mov $1, %eax\r
+ pushl %ebx # temporarily save value of ebx on stack\r
+ cpuid # use CPUID to determine if FXSAVE/FXRESTOR\r
+ # and DE are supported\r
+ popl %ebx # retore value of ebx that was overwritten\r
+ # by CPUID\r
movl %cr4, %eax\r
- orl $0x208, %eax\r
+ pushl %eax # push cr4 firstly\r
+ testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support\r
+ jz L1\r
+ orl $BIT9, %eax # Set CR4.OSFXSR\r
+L1:\r
+ testl $BIT2, %edx # Test for Debugging Extensions support\r
+ jz L2\r
+ orl $BIT3, %eax # Set CR4.DE\r
+L2:\r
movl %eax, %cr4\r
- pushl %eax\r
movl %cr3, %eax\r
pushl %eax\r
movl %cr2, %eax\r
#; FX_SAVE_STATE_IA32 FxSaveState;\r
subl $512, %esp\r
movl %esp, %edi\r
+ testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support.\r
+ # edx still contains result from CPUID above\r
+ jz L3\r
.byte 0x0f, 0x0ae, 0x07 #fxsave [edi]\r
+L3:\r
\r
#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
cld\r
\r
#; FX_SAVE_STATE_IA32 FxSaveState;\r
movl %esp, %esi\r
+ movl $1, %eax\r
+ cpuid # use CPUID to determine if FXSAVE/FXRESTOR\r
+ # are supported\r
+ testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support\r
+ jz L4\r
.byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]\r
+L4:\r
addl $512, %esp\r
\r
#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
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
+ lret # far return\r
+\r
+DoIret:\r
iretl\r
\r
\r
#---------------------------------------;\r
-# _GetTemplateAddressMap ;\r
-#----------------------------------------------------------------------------;\r
-# \r
+# _AsmGetTemplateAddressMap ;\r
+#---------------------------------------;\r
+#\r
# Protocol prototype\r
-# GetTemplateAddressMap (\r
+# AsmGetTemplateAddressMap (\r
# EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
# );\r
-# \r
+#\r
# Routine Description:\r
-# \r
+#\r
# Return address map of interrupt handler template so that C code can generate\r
# interrupt table.\r
-# \r
+#\r
# Arguments:\r
-# \r
-# \r
-# Returns: \r
-# \r
+#\r
+#\r
+# Returns:\r
+#\r
# Nothing\r
#\r
-# \r
+#\r
# Input: [ebp][0] = Original ebp\r
# [ebp][4] = Return address\r
-# \r
+#\r
# Output: Nothing\r
-# \r
+#\r
# Destroys: Nothing\r
#-----------------------------------------------------------------------------;\r
#-------------------------------------------------------------------------------------\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
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 (*NewVectorAddr, VectorNum, *OldVectorAddr);\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